CIRCT  20.0.0git
DeviceDB.h
Go to the documentation of this file.
1 //===- DeviceDB.h - Device database -----------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Represent the placements of primitives on an FPGA.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef CIRCT_DIALECT_MSFT_DEVICEDB_H
14 #define CIRCT_DIALECT_MSFT_DEVICEDB_H
15 
18 
19 #include "mlir/IR/Operation.h"
20 #include "llvm/ADT/DenseMap.h"
21 
22 namespace circt {
23 namespace msft {
24 
25 /// A data structure to contain locations of the primitives on the
26 /// device.
27 class PrimitiveDB {
28 public:
29  /// Create a DB treating 'top' as the root module.
30  PrimitiveDB(MLIRContext *);
31 
32  /// Place a primitive at a location.
33  LogicalResult addPrimitive(PhysLocationAttr);
34  /// Check to see if a primitive exists.
35  bool isValidLocation(PhysLocationAttr);
36 
37  /// Iterate over all the primitive locations, executing 'callback' on each
38  /// one.
39  void foreach (function_ref<void(PhysLocationAttr)> callback) const;
40 
41 private:
42  using DimPrimitiveType = DenseSet<PrimitiveType>;
43  using DimNumMap = DenseMap<size_t, DimPrimitiveType>;
44  using DimYMap = DenseMap<size_t, DimNumMap>;
45  using DimXMap = DenseMap<size_t, DimYMap>;
46 
47  /// Get the leaf node. Abstract this out to make it easier to change the
48  /// underlying data structure.
49  DimPrimitiveType &getLeaf(PhysLocationAttr);
50  // TODO: Create read-only version of getLeaf.
51 
53  MLIRContext *ctxt;
54 };
55 
56 /// A data structure to contain both the locations of the primitives on the
57 /// device and instance assignments to said primitives locations, aka
58 /// placements.
59 ///
60 /// Holds pointers into the IR, which may become invalid as a result of IR
61 /// transforms. As a result, this class is intended to be short-lived -- created
62 /// just before loading placements and destroyed immediatetly after things are
63 /// placed.
64 class PlacementDB {
65 public:
66  /// Create a placement db containing all the placements in 'topMod'.
67  PlacementDB(mlir::ModuleOp topMod);
68  PlacementDB(mlir::ModuleOp topMod, const PrimitiveDB &seed);
69 
70  /// Contains the order to iterate in each dimension for walkPlacements. The
71  /// dimensions are visited with columns first, then rows, then numbers within
72  /// a cell.
73  enum Direction { NONE = 0, ASC = 1, DESC = 2 };
74  struct WalkOrder {
77  };
78 
79  /// Assign an instance to a primitive. Return null if another instance is
80  /// already placed at that location.
81  PDPhysLocationOp place(DynamicInstanceOp inst, PhysLocationAttr,
82  StringRef subpath, Location srcLoc);
83  PDRegPhysLocationOp place(DynamicInstanceOp inst, LocationVectorAttr,
84  Location srcLoc);
85  /// Assign an operation to a physical region. Return false on failure.
86  PDPhysRegionOp placeIn(DynamicInstanceOp inst, DeclPhysicalRegionOp,
87  StringRef subPath, Location srcLoc);
88 
89  /// Remove the placement from the DB and IR. Erases the op.
90  void removePlacement(PDPhysLocationOp);
91  /// Move a placement location to a new location. Returns failure if something
92  /// is already placed at the new location.
93  LogicalResult movePlacement(PDPhysLocationOp, PhysLocationAttr);
94 
95  /// Remove the placement from the DB and IR. Erases the op.
96  void removePlacement(PDRegPhysLocationOp);
97  /// Move a placement location to a new location. Returns failure if something
98  /// is already placed at the new location.
99  LogicalResult movePlacement(PDRegPhysLocationOp, LocationVectorAttr);
100 
101  /// Lookup the instance at a particular location.
102  DynInstDataOpInterface getInstanceAt(PhysLocationAttr);
103 
104  /// Find the nearest unoccupied primitive location to 'nearestToY' in
105  /// 'column'.
106  PhysLocationAttr getNearestFreeInColumn(PrimitiveType prim, uint64_t column,
107  uint64_t nearestToY);
108 
109  /// Walk the placement information in some sort of reasonable order. Bounds
110  /// restricts the walk to a rectangle of [xmin, xmax, ymin, ymax] (inclusive),
111  /// with -1 meaning unbounded.
112  void
113  walkPlacements(function_ref<void(PhysLocationAttr, DynInstDataOpInterface)>,
114  std::tuple<int64_t, int64_t, int64_t, int64_t> bounds =
115  std::make_tuple(-1, -1, -1, -1),
116  std::optional<PrimitiveType> primType = {},
117  std::optional<WalkOrder> = {});
118 
119  /// Walk the region placement information.
120  void walkRegionPlacements(function_ref<void(PDPhysRegionOp)>);
121 
122 private:
123  /// A memory slot. Useful to distinguish the memory location from the
124  /// reference stored there.
125  struct PlacementCell {
126  DynInstDataOpInterface locOp;
127  };
128 
129  MLIRContext *ctxt;
130  mlir::ModuleOp topMod;
131 
132  using DimDevType = DenseMap<PrimitiveType, PlacementCell>;
133  using DimNumMap = DenseMap<size_t, DimDevType>;
134  using DimYMap = DenseMap<size_t, DimNumMap>;
135  using DimXMap = DenseMap<size_t, DimYMap>;
136  using RegionPlacements = SmallVector<PDPhysRegionOp>;
137 
138  /// Get the leaf node. Abstract this out to make it easier to change the
139  /// underlying data structure.
140  PlacementCell *getLeaf(PhysLocationAttr);
141 
144  bool seeded;
145 
146  /// Load the placements from `inst`. Return the number of placements which
147  /// weren't added due to conflicts.
148  size_t addPlacements(DynamicInstanceOp inst);
149  LogicalResult insertPlacement(DynInstDataOpInterface op, PhysLocationAttr);
150 
151  /// Load the database from the IR. Return the number of placements which
152  /// failed to load due to invalid specifications.
153  size_t addDesignPlacements();
154 
155  /// Remove the placement from the DB.
156  void removePlacement(DynInstDataOpInterface, PhysLocationAttr);
157 
158  /// Check to make sure the move is going to succeed.
159  LogicalResult movePlacementCheck(DynInstDataOpInterface op,
160  PhysLocationAttr from, PhysLocationAttr to);
161  /// Move it.
162  void movePlacement(DynInstDataOpInterface op, PhysLocationAttr from,
163  PhysLocationAttr to);
164 };
165 
166 } // namespace msft
167 } // namespace circt
168 
169 #endif // CIRCT_DIALECT_MSFT_DEVICEDB_H
A data structure to contain both the locations of the primitives on the device and instance assignmen...
Definition: DeviceDB.h:64
void removePlacement(PDRegPhysLocationOp)
Remove the placement from the DB and IR. Erases the op.
LogicalResult movePlacementCheck(DynInstDataOpInterface op, PhysLocationAttr from, PhysLocationAttr to)
Check to make sure the move is going to succeed.
Definition: DeviceDB.cpp:259
void removePlacement(PDPhysLocationOp)
Remove the placement from the DB and IR. Erases the op.
Direction
Contains the order to iterate in each dimension for walkPlacements.
Definition: DeviceDB.h:73
DynInstDataOpInterface getInstanceAt(PhysLocationAttr)
Lookup the instance at a particular location.
size_t addPlacements(DynamicInstanceOp inst)
Load the placements from inst.
Definition: DeviceDB.cpp:149
SmallVector< PDPhysRegionOp > RegionPlacements
Definition: DeviceDB.h:136
LogicalResult movePlacement(PDPhysLocationOp, PhysLocationAttr)
Move a placement location to a new location.
DenseMap< size_t, DimNumMap > DimYMap
Definition: DeviceDB.h:134
PDPhysLocationOp place(DynamicInstanceOp inst, PhysLocationAttr, StringRef subpath, Location srcLoc)
Assign an instance to a primitive.
size_t addDesignPlacements()
Load the database from the IR.
Definition: DeviceDB.cpp:177
DenseMap< size_t, DimYMap > DimXMap
Definition: DeviceDB.h:135
PlacementCell * getLeaf(PhysLocationAttr)
Get the leaf node.
Definition: DeviceDB.cpp:331
DenseMap< PrimitiveType, PlacementCell > DimDevType
Definition: DeviceDB.h:132
PlacementDB(mlir::ModuleOp topMod)
Create a placement db containing all the placements in 'topMod'.
Definition: DeviceDB.cpp:72
void walkRegionPlacements(function_ref< void(PDPhysRegionOp)>)
Walk the region placement information.
Definition: DeviceDB.cpp:421
MLIRContext * ctxt
Definition: DeviceDB.h:129
PhysLocationAttr getNearestFreeInColumn(PrimitiveType prim, uint64_t column, uint64_t nearestToY)
Find the nearest unoccupied primitive location to 'nearestToY' in 'column'.
PDPhysRegionOp placeIn(DynamicInstanceOp inst, DeclPhysicalRegionOp, StringRef subPath, Location srcLoc)
Assign an operation to a physical region. Return false on failure.
Definition: DeviceDB.cpp:133
mlir::ModuleOp topMod
Definition: DeviceDB.h:130
void removePlacement(DynInstDataOpInterface, PhysLocationAttr)
Remove the placement from the DB.
LogicalResult movePlacement(PDRegPhysLocationOp, LocationVectorAttr)
Move a placement location to a new location.
PDRegPhysLocationOp place(DynamicInstanceOp inst, LocationVectorAttr, Location srcLoc)
void walkPlacements(function_ref< void(PhysLocationAttr, DynInstDataOpInterface)>, std::tuple< int64_t, int64_t, int64_t, int64_t > bounds=std::make_tuple(-1, -1, -1, -1), std::optional< PrimitiveType > primType={}, std::optional< WalkOrder >={})
Walk the placement information in some sort of reasonable order.
DenseMap< size_t, DimDevType > DimNumMap
Definition: DeviceDB.h:133
LogicalResult insertPlacement(DynInstDataOpInterface op, PhysLocationAttr)
Definition: DeviceDB.cpp:115
RegionPlacements regionPlacements
Definition: DeviceDB.h:143
A data structure to contain locations of the primitives on the device.
Definition: DeviceDB.h:27
DimPrimitiveType & getLeaf(PhysLocationAttr)
Get the leaf node.
Definition: DeviceDB.cpp:49
DenseMap< size_t, DimYMap > DimXMap
Definition: DeviceDB.h:45
MLIRContext * ctxt
Definition: DeviceDB.h:53
LogicalResult addPrimitive(PhysLocationAttr)
Place a primitive at a location.
DenseMap< size_t, DimNumMap > DimYMap
Definition: DeviceDB.h:44
bool isValidLocation(PhysLocationAttr)
Check to see if a primitive exists.
DenseSet< PrimitiveType > DimPrimitiveType
Definition: DeviceDB.h:42
DenseMap< size_t, DimPrimitiveType > DimNumMap
Definition: DeviceDB.h:43
PrimitiveDB(MLIRContext *)
Create a DB treating 'top' as the root module.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
Definition: msft.py:1
DynInstDataOpInterface locOp
Definition: DeviceDB.h:126