16 #include "llvm/ADT/SmallPtrSet.h"
18 using namespace circt;
20 static void addBlockToTR(Block *block,
int tr, DenseMap<Block *, int> &blockMap,
21 DenseMap<
int, SmallVector<Block *, 8>> &trMap) {
22 blockMap.insert(std::make_pair(block, tr));
23 SmallVector<Block *, 8> b;
25 trMap.insert(std::make_pair(tr, b));
29 return std::any_of(block->pred_begin(), block->pred_end(), [](Block *pred) {
30 return isa<llhd::WaitOp>(pred->getTerminator());
35 SmallPtrSetImpl<Block *> &known) {
36 return std::all_of(block->pred_begin(), block->pred_end(), [&](Block *pred) {
37 return std::find(known.begin(), known.end(), pred) != known.end();
42 assert(isa<ProcOp>(operation) &&
43 "TemporalRegionAnalysis: operation needs to be llhd::ProcOp");
44 ProcOp proc = cast<ProcOp>(operation);
49 SmallPtrSet<Block *, 32> workQueue;
50 SmallPtrSet<Block *, 32> workDone;
54 workQueue.insert(&proc.getBody().front());
55 proc.walk([&](WaitOp wait) { workQueue.insert(wait.getDest()); });
57 while (!workQueue.empty()) {
61 std::find_if(workQueue.begin(), workQueue.end(), [&](Block *block) {
62 return allPredecessorTRsKnown(block, workDone) ||
63 anyPredecessorHasWait(block);
69 if (iter == workQueue.end())
70 iter = workQueue.begin();
77 workQueue.erase(block);
78 workDone.insert(block);
82 for (Block *succ : block->getSuccessors()) {
83 if (!workDone.count(succ))
84 workQueue.insert(succ);
89 if (block->isEntryBlock()) {
96 !(std::adjacent_find(block->pred_begin(), block->pred_end(),
97 [&](Block *pred1, Block *pred2) {
98 return blockMap[pred1] != blockMap[pred2];
99 }) == block->pred_end())) {
104 int tr =
blockMap[*block->pred_begin()];
105 blockMap.insert(std::make_pair(block, tr));
106 trMap[tr].push_back(block);
116 assert(blockMap.count(block) &&
117 "This block is not present in the temporal regions map.");
118 return blockMap[block];
122 if (!trMap.count(tr))
123 return SmallVector<Block *, 8>();
127 SmallVector<Block *, 8>
129 SmallVector<Block *, 8> blocks = getBlocksInTR(tr);
130 SmallVector<Block *, 8> exitingBlocks;
131 for (Block *block : blocks) {
132 for (
auto succ : block->getSuccessors()) {
133 if (blockMap[succ] != blockMap[block] ||
134 isa<WaitOp>(block->getTerminator())) {
135 exitingBlocks.push_back(block);
140 return exitingBlocks;
144 SmallVector<int, 8> res;
145 for (Block *block : getExitingBlocksInTR(tr)) {
146 for (Block *succ : block->getSuccessors()) {
147 if (getBlockTR(succ) != tr || isa<llhd::WaitOp>(block->getTerminator()))
148 res.push_back(getBlockTR(succ));
151 res.erase(std::unique(res.begin(), res.end()), res.end());
156 for (Block *block : getBlocksInTR(tr)) {
160 for (Block *pred : block->getPredecessors()) {
161 if (getBlockTR(pred) != tr)
assert(baseType &&"element must be base type")
static bool allPredecessorTRsKnown(Block *block, SmallPtrSetImpl< Block * > &known)
static bool anyPredecessorHasWait(Block *block)
static void addBlockToTR(Block *block, int tr, DenseMap< Block *, int > &blockMap, DenseMap< int, SmallVector< Block *, 8 >> &trMap)
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
SmallVector< Block *, 8 > getExitingBlocksInTR(int)
SmallVector< Block *, 8 > getBlocksInTR(int)
void recalculate(Operation *)
SmallVector< int, 8 > getTRSuccessors(int)
Block * getTREntryBlock(int)