void AstBackEnd::runOnFunction(llvm::Function& fn) { grapher.reset(new AstGrapher); // Before doing anything, create statements for blocks in reverse post-order. This ensures that values exist // before they are used. (Post-order would try to use statements before they were created.) for (BasicBlock* block : ReversePostOrderTraversal<BasicBlock*>(&fn.getEntryBlock())) { grapher->createRegion(*block, *output->basicBlockToStatement(*block)); } // Identify loops, then visit basic blocks in post-order. If the basic block if the head // of a cyclic region, process the loop. Otherwise, if the basic block is the start of a single-entry-single-exit // region, process that region. auto& domTreeWrapper = getAnalysis<DominatorTreeWrapperPass>(fn); domTree = &domTreeWrapper.getDomTree(); postDomTree->recalculate(fn); RootedPostDominatorTree::treeFromIncompleteTree(fn, postDomTree); // Traverse graph in post-order. Try to detect regions with the post-dominator tree. // Cycles are only considered once. for (BasicBlock* entry : post_order(&fn.getEntryBlock())) { BasicBlock* postDominator = entry; while (postDominator != nullptr) { AstGraphNode* graphNode = grapher->getGraphNodeFromEntry(postDominator); BasicBlock* exit = graphNode->hasExit() ? graphNode->getExit() : postDominatorOf(*postDomTree, *postDominator); RegionType region = isRegion(*entry, exit); if (region == Acyclic) { runOnRegion(fn, *entry, exit); } else if (region == Cyclic) { runOnLoop(fn, *entry, exit); } if (!domTree->dominates(entry, exit)) { break; } postDominator = exit; } } Statement* bodyStatement = grapher->getGraphNodeFromEntry(&fn.getEntryBlock())->node; output->setBody(bodyStatement); }
bool IndependentBlocks::runOnFunction(llvm::Function &F) { bool Changed = false; RI = &getAnalysis<RegionInfoPass>().getRegionInfo(); LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); SD = &getAnalysis<ScopDetection>(); SE = &getAnalysis<ScalarEvolution>(); AllocaBlock = &F.getEntryBlock(); DEBUG(dbgs() << "Run IndepBlock on " << F.getName() << '\n'); for (const Region *R : *SD) { Changed |= createIndependentBlocks(R); Changed |= eliminateDeadCode(R); // This may change the RegionTree. if (!DisableIntraScopScalarToArray || !PollyModelPHINodes) Changed |= splitExitBlock(const_cast<Region *>(R)); } DEBUG(dbgs() << "Before Scalar to Array------->\n"); DEBUG(F.dump()); if (!DisableIntraScopScalarToArray || !PollyModelPHINodes) for (const Region *R : *SD) Changed |= translateScalarToArray(R); DEBUG(dbgs() << "After Independent Blocks------------->\n"); DEBUG(F.dump()); verifyAnalysis(); return Changed; }
std::vector<llvm::BasicBlock*> BasicBlockSorter::sortBasicBlocks(llvm::Function &function) { std::vector<llvm::BasicBlock*> ret; std::set<llvm::BasicBlock*> visited; llvm::BasicBlock &entryBlock = function.getEntryBlock(); visitBasicBlock(ret, visited, &entryBlock); return ret; }