25 using namespace llvm::PatternMatch;
27 #define DEBUG_TYPE "structurizecfg"
33 typedef std::pair<BasicBlock *, Value *> BBValuePair;
53 static const char *
const FlowBlockName =
"Flow";
59 class NearestCommonDominator {
62 DTN2UnsignedMap IndexMap;
66 bool ExplicitMentioned;
76 void addBlock(
BasicBlock *BB,
bool Remember =
true) {
80 unsigned Numbering = 0;
81 for (;Node;Node = Node->
getIDom())
82 IndexMap[Node] = ++Numbering;
85 ExplicitMentioned = Remember;
89 for (;Node;Node = Node->
getIDom())
90 if (IndexMap.count(Node))
95 assert(Node &&
"Dominator tree invalid!");
97 unsigned Numbering = IndexMap[Node];
98 if (Numbering > ResultIndex) {
100 ResultIndex = Numbering;
101 ExplicitMentioned = Remember && (Result == BB);
102 }
else if (Numbering == ResultIndex) {
103 ExplicitMentioned |= Remember;
108 bool wasResultExplicitMentioned() {
109 return ExplicitMentioned;
178 BBPhiMap DeletedPhis;
179 BB2BBVecMap AddedPhis;
182 BranchVector Conditions;
186 BranchVector LoopConds;
202 void insertConditions(
bool Loops);
213 bool IncludeDominator);
227 void wireFlow(
bool ExitUseAllowed,
BasicBlock *LoopEnd);
229 void handleLoops(
bool ExitUseAllowed,
BasicBlock *LoopEnd);
248 const char *getPassName()
const override {
249 return "Structurize control flow";
275 LLVMContext &Context = R->getEntry()->getContext();
286 void StructurizeCFG::orderNodes() {
289 TempOrder.append(RPOT.begin(), RPOT.end());
291 std::map<Loop*, unsigned> LoopBlocks;
300 if (!LoopBlocks.count(Loop)) {
301 LoopBlocks[Loop] = 1;
307 unsigned CurrentLoopDepth = 0;
308 Loop *CurrentLoop =
nullptr;
310 for (RNVector::iterator
I = TempOrder.begin(), E = TempOrder.end();
I != E; ++
I) {
312 unsigned LoopDepth = LI->getLoopDepth(BB);
314 if (std::find(Order.begin(), Order.end(), *
I) != Order.end())
317 if (LoopDepth < CurrentLoopDepth) {
321 RNVector::iterator LoopI =
I;
322 while(LoopBlocks[CurrentLoop]) {
325 if (LI->getLoopFor(LoopBB) == CurrentLoop) {
326 LoopBlocks[CurrentLoop]--;
327 Order.push_back(*LoopI);
332 CurrentLoop = LI->getLoopFor(BB);
334 LoopBlocks[CurrentLoop]--;
337 CurrentLoopDepth = LoopDepth;
345 std::reverse(Order.begin(), Order.end());
353 if (Visited.count(Exit))
361 for (
unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
364 if (Visited.count(Succ)) {
372 Value *StructurizeCFG::invert(
Value *Condition) {
374 if (Condition == BoolTrue)
377 if (Condition == BoolFalse)
380 if (Condition == BoolUndef)
387 if (
Instruction *Inst = dyn_cast<Instruction>(Condition)) {
399 if (
Argument *Arg = dyn_cast<Argument>(Condition)) {
412 Value *Cond = Invert ? BoolFalse : BoolTrue;
416 if (Idx != (
unsigned)Invert)
423 void StructurizeCFG::gatherPredicates(
RegionNode *N) {
424 RegionInfo *RI = ParentRegion->getRegionInfo();
426 BBPredicates &Pred = Predicates[BB];
427 BBPredicates &LPred = LoopPreds[BB];
433 if (!ParentRegion->contains(*PI))
437 if (R == ParentRegion) {
440 BranchInst *Term = cast<BranchInst>((*PI)->getTerminator());
446 if (Visited.count(*PI)) {
451 if (Visited.count(Other) && !
Loops.count(Other) &&
452 !Pred.count(Other) && !Pred.count(*PI)) {
454 Pred[
Other] = BoolFalse;
455 Pred[*PI] = BoolTrue;
459 Pred[*PI] = buildCondition(Term, i,
false);
463 LPred[*PI] = buildCondition(Term, i,
true);
478 if (Visited.count(Entry))
479 Pred[Entry] = BoolTrue;
481 LPred[Entry] = BoolFalse;
487 void StructurizeCFG::collectInfos() {
498 for (RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend();
502 ((*OI)->isSubRegion() ?
"SubRegion with entry: " :
"") <<
503 (*OI)->getEntry()->getName() <<
" Loop Depth: " << LI->getLoopDepth((*OI)->getEntry()) <<
"\n");
506 gatherPredicates(*OI);
509 Visited.insert((*OI)->getEntry());
517 void StructurizeCFG::insertConditions(
bool Loops) {
518 BranchVector &Conds = Loops ? LoopConds : Conditions;
533 BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue];
535 NearestCommonDominator Dominator(DT);
536 Dominator.addBlock(Parent,
false);
538 Value *ParentValue =
nullptr;
539 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
542 if (PI->first == Parent) {
543 ParentValue = PI->second;
547 Dominator.addBlock(PI->first);
553 if (!Dominator.wasResultExplicitMentioned())
564 PhiMap &Map = DeletedPhis[To];
566 I != E && isa<PHINode>(*I);) {
568 PHINode &Phi = cast<PHINode>(*I++);
571 Map[&Phi].push_back(std::make_pair(From, Deleted));
579 I != E && isa<PHINode>(*I);) {
581 PHINode &Phi = cast<PHINode>(*I++);
585 AddedPhis[To].push_back(From);
589 void StructurizeCFG::setPhiValues() {
591 for (BB2BBVecMap::iterator AI = AddedPhis.begin(), AE = AddedPhis.end();
595 BBVector &From = AI->second;
597 if (!DeletedPhis.count(To))
600 PhiMap &Map = DeletedPhis[To];
601 for (PhiMap::iterator PI = Map.begin(), PE = Map.end();
610 NearestCommonDominator Dominator(DT);
611 Dominator.addBlock(To,
false);
612 for (BBValueVector::iterator
VI = PI->second.begin(),
613 VE = PI->second.end();
VI != VE; ++
VI) {
616 Dominator.addBlock(
VI->first);
619 if (!Dominator.wasResultExplicitMentioned())
622 for (BBVector::iterator FI = From.begin(), FE = From.end();
631 DeletedPhis.erase(To);
633 assert(DeletedPhis.empty());
637 void StructurizeCFG::killTerminator(
BasicBlock *BB) {
645 delPhiValues(BB, *SI);
653 bool IncludeDominator) {
668 delPhiValues(BB, OldExit);
670 addPhiValues(BB, NewExit);
673 if (IncludeDominator) {
677 Dominator = DT->findNearestCommonDominator(Dominator, BB);
683 DT->changeImmediateDominator(NewExit, Dominator);
692 addPhiValues(BB, NewExit);
693 if (IncludeDominator)
694 DT->changeImmediateDominator(NewExit, BB);
702 Order.back()->getEntry();
705 DT->addNewBlock(Flow, Dominator);
706 ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
711 BasicBlock *StructurizeCFG::needPrefix(
bool NeedEmpty) {
714 if (!PrevNode->isSubRegion()) {
715 killTerminator(Entry);
725 changeExit(PrevNode, Flow,
true);
726 PrevNode = ParentRegion->getBBNode(Flow);
732 bool ExitUseAllowed) {
733 if (Order.empty() && ExitUseAllowed) {
735 DT->changeImmediateDominator(Exit, Flow);
736 addPhiValues(Flow, Exit);
739 return getNextFlow(Flow);
743 void StructurizeCFG::setPrevNode(
BasicBlock *BB) {
744 PrevNode = ParentRegion->contains(BB) ? ParentRegion->getBBNode(BB)
750 BBPredicates &Preds = Predicates[Node->
getEntry()];
751 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
754 if (!DT->dominates(BB, PI->first))
761 bool StructurizeCFG::isPredictableTrue(
RegionNode *Node) {
762 BBPredicates &Preds = Predicates[Node->
getEntry()];
763 bool Dominated =
false;
769 for (BBPredicates::iterator I = Preds.begin(), E = Preds.end();
772 if (I->second != BoolTrue)
775 if (!Dominated && DT->dominates(I->first, PrevNode->getEntry()))
784 void StructurizeCFG::wireFlow(
bool ExitUseAllowed,
789 if (isPredictableTrue(Node)) {
792 changeExit(PrevNode, Node->
getEntry(),
true);
802 BasicBlock *Next = needPostfix(Flow, ExitUseAllowed);
806 addPhiValues(Flow, Entry);
807 DT->changeImmediateDominator(Entry, Flow);
810 while (!Order.empty() && !Visited.count(LoopEnd) &&
811 dominatesPredicates(Entry, Order.
back())) {
812 handleLoops(
false, LoopEnd);
815 changeExit(PrevNode, Next,
false);
820 void StructurizeCFG::handleLoops(
bool ExitUseAllowed,
825 if (!Loops.count(LoopStart)) {
826 wireFlow(ExitUseAllowed, LoopEnd);
830 if (!isPredictableTrue(Node))
831 LoopStart = needPrefix(
true);
834 wireFlow(
false, LoopEnd);
835 while (!Visited.count(LoopEnd)) {
836 handleLoops(
false, LoopEnd);
843 LoopStart->
setName(
"entry.orig");
854 LoopEnd = needPrefix(
false);
855 BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed);
857 BoolUndef, LoopEnd));
858 addPhiValues(LoopEnd, LoopStart);
864 void StructurizeCFG::createFlow() {
866 bool EntryDominatesExit = DT->dominates(ParentRegion->getEntry(), Exit);
876 while (!Order.empty()) {
877 handleLoops(EntryDominatesExit,
nullptr);
881 changeExit(PrevNode, Exit, EntryDominatesExit);
883 assert(EntryDominatesExit);
888 void StructurizeCFG::rebuildSSA() {
890 for (
auto *BB : ParentRegion->blocks())
894 bool Initialized =
false;
895 for (
auto I = II->use_begin(), E = II->use_end(); I != E;) {
901 }
else if (
PHINode *UserPN = dyn_cast<PHINode>(User)) {
902 if (UserPN->getIncomingBlock(U) == BB)
906 if (DT->dominates(II, User))
929 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
930 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
935 insertConditions(
false);
936 insertConditions(
true);
956 return new StructurizeCFG();
Pass interface - Implemented by all 'passes'.
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
static ConstantInt * getFalse(LLVMContext &Context)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static IntegerType * getInt1Ty(LLVMContext &C)
Helper class for SSA formation on a set of values defined in multiple blocks.
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVM Argument representation.
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=nullptr)
const Instruction & back() const
void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
This class implements a map that also provides access to all stored values in a deterministic order...
const Function * getParent() const
Return the enclosing method, or null if none.
BlockT * getEntry() const
Get the entry BasicBlock of this RegionNode.
bool isSubRegion() const
Is this RegionNode a subregion?
T * getNodeAs() const
Get the content of this RegionNode.
The pass manager to schedule RegionPasses.
RegionT * getRegionFor(BlockT *BB) const
Get the smallest region that contains a BasicBlock.
StringRef getName() const
Return a constant reference to the value's name.
iterator begin()
Instruction iterator methods.
bool match(Val *V, const Pattern &P)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
removeIncomingValue - Remove an incoming value.
UndefValue - 'undef' values are things that do not have specified contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A Use represents the edge between a Value definition and its users.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
RegionT * getParent() const
Get the parent of the Region.
void setName(const Twine &Name)
Change the name of the value.
INITIALIZE_PASS_BEGIN(StructurizeCFG,"structurizecfg","Structurize the CFG", false, false) INITIALIZE_PASS_END(StructurizeCFG
not_match< LHS > m_Not(const LHS &L)
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
BasicBlock * getSuccessor(unsigned i) const
Base class for the actual dominator tree node.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
virtual bool doInitialization(Module &)
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
Interval::succ_iterator succ_end(Interval *I)
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * GetValueInMiddleOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block...
Subclasses of this class are all able to terminate a basic block.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
void RewriteUseAfterInsertions(Use &U)
Rewrite a use like RewriteUse but handling in-block definitions.
BranchInst - Conditional or Unconditional Branch instruction.
A pass that runs on each Region in a function.
void replaceExit(BlockT *BB)
Replace the exit basic block of the region with the new basic block.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
Represent the analysis usage information of a pass.
User * getUser() const
Returns the User that contains this Use.
Interval::pred_iterator pred_end(Interval *I)
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
void initializeStructurizeCFGPass(PassRegistry &)
bool isConditional() const
DomTreeNodeBase< NodeT > * getIDom() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
AnalysisUsage & addRequiredID(const void *ID)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
const BasicBlock & getEntryBlock() const
static ConstantInt * getTrue(LLVMContext &Context)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
iterator_range< user_iterator > users()
Value * getCondition() const
unsigned getNumSuccessors() const
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
void setCondition(Value *V)
BlockT * getExit() const
Get the exit BasicBlock of the Region.
LLVMContext & getContext() const
Get the context in which this basic block lives.
LLVM Value Representation.
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
bool contains(const BlockT *BB) const
Check if the region contains a BasicBlock.
Pass * createStructurizeCFGPass()
Create the pass.
The legacy pass manager's analysis pass to compute loop information.
Legacy analysis pass which computes a DominatorTree.
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Value * GetValueAtEndOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live at the end of the specified block...
void setIncomingValue(unsigned i, Value *V)
int getBasicBlockIndex(const BasicBlock *BB) const
getBasicBlockIndex - Return the first index of the specified basic block in the value list for this P...
const BasicBlock * getParent() const
bool isTopLevelRegion() const
Check if a Region is the TopLevel region.