7 #include <llvm/ADT/PostOrderIterator.h>
14 enum class Direction {
22 template <
typename FlowSet,
typename GenSet,
typename KillSet, Direction Dir>
49 virtual void Traverse(
Inst *inst,
const FlowSet &set) = 0;
54 return blocks_[blockToIndex_[I->
getParent()]].Insts.emplace_back(I);
63 llvm::SmallVector<uint64_t, 5> Preds;
65 llvm::SmallVector<uint64_t, 5> Succs;
67 std::vector<InstInfo> Insts;
75 BlockInfo(
Block *B) : B(B) {}
84 std::vector<BlockInfo> blocks_;
86 std::unordered_map<const Block *, uint64_t> blockToIndex_;
89 template <
typename FlowSet,
typename GenSet,
typename KillSet, Direction Dir>
94 for (
Block &block : func) {
95 blockToIndex_.insert({ &block, blocks_.size() });
96 blocks_.push_back(&block);
100 for (
Block &block : func) {
101 BlockInfo &blockInfo = blocks_[blockToIndex_[&block]];
104 for (
const Block *pred : block.predecessors()) {
105 blockInfo.Preds.push_back(blockToIndex_[pred]);
107 for (
const Block *succ : block.successors()) {
108 blockInfo.Succs.push_back(blockToIndex_[succ]);
113 template <
typename FlowSet,
typename GenSet,
typename KillSet, Direction Dir>
117 for (
Block &block : func_) {
118 for (
Inst &inst : block) {
124 for (BlockInfo &block : blocks_) {
125 auto Step = [&block](
InstInfo &inst) {
127 block.Kill.Union(inst.Kill);
129 block.Gen.Minus(inst.Kill);
130 block.Gen.Union(inst.Gen);
134 case Direction::FORWARD: {
135 for (
auto it = block.Insts.begin(); it != block.Insts.end(); ++it) {
140 case Direction::BACKWARD: {
141 for (
auto it = block.Insts.rbegin(); it != block.Insts.rend(); ++it) {
150 std::queue<BlockInfo *> queue_;
151 std::set<BlockInfo *> inQueue_;
152 std::vector<llvm::GraphTraits<Func *>::NodeRef> blockOrder_;
154 auto Add = [&queue_, &inQueue_] (BlockInfo *info) {
155 inQueue_.insert(info);
160 auto Entry = llvm::GraphTraits<Func *>::getEntryNode(&func_);
161 std::copy(po_begin(Entry), po_end(Entry), std::back_inserter(blockOrder_));
165 case Direction::FORWARD: {
166 for (
auto it = blockOrder_.rbegin(); it != blockOrder_.rend(); ++it) {
167 auto *block = &blocks_[blockToIndex_[*it]];
169 std::optional<FlowSet> init;
170 for (
unsigned index : block->Preds) {
171 auto *pred = &blocks_[index];
173 FlowSet out = pred->Flow;
174 out.Minus(pred->Kill);
175 out.Union(pred->Gen);
191 case Direction::BACKWARD: {
192 for (
auto it = blockOrder_.begin(); it != blockOrder_.end(); ++it) {
193 auto *block = &blocks_[blockToIndex_[*it]];
195 std::optional<FlowSet> init;
196 for (
unsigned index : block->Preds) {
197 auto *succ = &blocks_[index];
199 FlowSet out = succ->Flow;
200 out.Minus(succ->Kill);
201 out.Union(succ->Gen);
221 while (!queue_.empty()) {
222 BlockInfo *block = queue_.front();
224 inQueue_.erase(block);
227 FlowSet out = block->Flow;
228 out.Minus(block->Kill);
229 out.Union(block->Gen);
232 auto Transfer = [&out, &inQueue_, &queue_] (BlockInfo *next) {
233 FlowSet in = next->Flow;
235 if (!(in == next->Flow)) {
237 if (inQueue_.count(next) == 0) {
245 case Direction::FORWARD: {
246 for (
unsigned succ : block->Succs) {
247 Transfer(&blocks_[succ]);
251 case Direction::BACKWARD: {
252 for (
unsigned pred : block->Preds) {
253 Transfer(&blocks_[pred]);
261 for (
Block *block : blockOrder_) {
262 BlockInfo &info = blocks_[blockToIndex_[block]];
264 FlowSet set = info.Flow;
266 auto Step = [
this, &set] (
InstInfo &i) {
273 case Direction::FORWARD: {
274 for (
auto it = info.Insts.begin(); it != info.Insts.end(); ++it) {
279 case Direction::BACKWARD: {
280 for (
auto it = info.Insts.rbegin(); it != info.Insts.rend(); ++it) {