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<ProcessOp>(operation) &&
43 "TemporalRegionAnalysis: operation needs to be llhd::ProcessOp");
44 auto proc = cast<ProcessOp>(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.at(block);
121 SmallVector<Block *, 8>
123 if (!trMap.count(tr))
124 return SmallVector<Block *, 8>();
128 SmallVector<Block *, 8>
130 SmallVector<Block *, 8> blocks = getBlocksInTR(tr);
131 SmallVector<Block *, 8> exitingBlocks;
132 for (Block *block : blocks) {
133 for (
auto *succ : block->getSuccessors()) {
134 if (blockMap.at(succ) != blockMap.at(block) ||
135 isa<WaitOp>(block->getTerminator())) {
136 exitingBlocks.push_back(block);
141 return exitingBlocks;
145 SmallVector<int, 8> res;
146 for (Block *block : getExitingBlocksInTR(tr)) {
147 for (Block *succ : block->getSuccessors()) {
148 if (getBlockTR(succ) != tr || isa<llhd::WaitOp>(block->getTerminator()))
149 res.push_back(getBlockTR(succ));
152 res.erase(std::unique(res.begin(), res.end()), res.end());
157 for (Block *block : getBlocksInTR(tr)) {
161 for (Block *pred : block->getPredecessors()) {
162 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)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
int getBlockTR(Block *) const
void recalculate(Operation *)
SmallVector< Block *, 8 > getExitingBlocksInTR(int) const
SmallVector< Block *, 8 > getBlocksInTR(int) const
SmallVector< int, 8 > getTRSuccessors(int)
Block * getTREntryBlock(int)