10 #define DEBUG_TYPE "structurizecfg"
22 using namespace llvm::PatternMatch;
28 typedef std::pair<BasicBlock *, Value *> BBValuePair;
48 static const char *
const FlowBlockName =
"Flow";
54 class NearestCommonDominator {
57 DTN2UnsignedMap IndexMap;
61 bool ExplicitMentioned;
71 void addBlock(
BasicBlock *BB,
bool Remember =
true) {
75 unsigned Numbering = 0;
76 for (;Node;Node = Node->
getIDom())
77 IndexMap[Node] = ++Numbering;
80 ExplicitMentioned = Remember;
84 for (;Node;Node = Node->
getIDom())
85 if (IndexMap.count(Node))
90 assert(Node &&
"Dominator tree invalid!");
92 unsigned Numbering = IndexMap[Node];
93 if (Numbering > ResultIndex) {
95 ResultIndex = Numbering;
96 ExplicitMentioned = Remember && (Result == BB);
97 }
else if (Numbering == ResultIndex) {
98 ExplicitMentioned |= Remember;
103 bool wasResultExplicitMentioned() {
104 return ExplicitMentioned;
172 BBPhiMap DeletedPhis;
173 BB2BBVecMap AddedPhis;
176 BranchVector Conditions;
180 BranchVector LoopConds;
196 void insertConditions(
bool Loops);
207 bool IncludeDominator);
221 void wireFlow(
bool ExitUseAllowed,
BasicBlock *LoopEnd);
223 void handleLoops(
bool ExitUseAllowed,
BasicBlock *LoopEnd);
242 virtual const char *getPassName()
const {
243 return "Structurize control flow";
268 LLVMContext &Context = R->getEntry()->getContext();
279 void StructurizeCFG::orderNodes() {
282 for (Order.clear(); I != E; ++
I) {
283 std::vector<RegionNode *> &Nodes = *
I;
284 Order.append(Nodes.begin(), Nodes.end());
293 if (Visited.count(Exit))
301 for (
unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
304 if (Visited.count(Succ))
311 Value *StructurizeCFG::invert(
Value *Condition) {
313 if (Condition == BoolTrue)
316 if (Condition == BoolFalse)
319 if (Condition == BoolUndef)
326 if (
Instruction *Inst = dyn_cast<Instruction>(Condition)) {
330 E = Condition->
use_end(); I != E; ++
I) {
333 if (!User || User->
getParent() != Parent)
344 if (
Argument *Arg = dyn_cast<Argument>(Condition)) {
357 Value *Cond = Invert ? BoolFalse : BoolTrue;
361 if (Idx != (
unsigned)Invert)
368 void StructurizeCFG::gatherPredicates(
RegionNode *N) {
369 RegionInfo *RI = ParentRegion->getRegionInfo();
371 BBPredicates &Pred = Predicates[BB];
372 BBPredicates &LPred = LoopPreds[BB];
378 if (!ParentRegion->contains(*PI))
382 if (R == ParentRegion) {
385 BranchInst *Term = cast<BranchInst>((*PI)->getTerminator());
391 if (Visited.count(*PI)) {
396 if (Visited.count(Other) && !
Loops.count(Other) &&
397 !Pred.count(Other) && !Pred.count(*PI)) {
399 Pred[Other] = BoolFalse;
400 Pred[*PI] = BoolTrue;
404 Pred[*PI] = buildCondition(Term, i,
false);
408 LPred[*PI] = buildCondition(Term, i,
true);
423 if (Visited.count(Entry))
424 Pred[Entry] = BoolTrue;
426 LPred[Entry] = BoolFalse;
432 void StructurizeCFG::collectInfos() {
447 gatherPredicates(*OI);
450 Visited.insert((*OI)->getEntry());
458 void StructurizeCFG::insertConditions(
bool Loops) {
459 BranchVector &Conds = Loops ? LoopConds : Conditions;
463 for (BranchVector::iterator I = Conds.begin(),
464 E = Conds.end(); I != E; ++
I) {
477 BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue];
479 NearestCommonDominator Dominator(DT);
480 Dominator.addBlock(Parent,
false);
482 Value *ParentValue = 0;
483 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
486 if (PI->first == Parent) {
487 ParentValue = PI->second;
491 Dominator.addBlock(PI->first);
497 if (!Dominator.wasResultExplicitMentioned())
508 PhiMap &Map = DeletedPhis[To];
510 I != E && isa<PHINode>(*I);) {
512 PHINode &Phi = cast<PHINode>(*I++);
515 Map[&Phi].push_back(std::make_pair(From, Deleted));
523 I != E && isa<PHINode>(*I);) {
525 PHINode &Phi = cast<PHINode>(*I++);
529 AddedPhis[To].push_back(From);
533 void StructurizeCFG::setPhiValues() {
535 for (BB2BBVecMap::iterator AI = AddedPhis.begin(), AE = AddedPhis.end();
539 BBVector &From = AI->second;
541 if (!DeletedPhis.count(To))
544 PhiMap &Map = DeletedPhis[To];
545 for (PhiMap::iterator PI = Map.begin(), PE = Map.end();
554 NearestCommonDominator Dominator(DT);
555 Dominator.addBlock(To,
false);
556 for (BBValueVector::iterator VI = PI->second.begin(),
557 VE = PI->second.end(); VI != VE; ++VI) {
560 Dominator.addBlock(VI->first);
563 if (!Dominator.wasResultExplicitMentioned())
566 for (BBVector::iterator FI = From.begin(), FE = From.end();
575 DeletedPhis.erase(To);
577 assert(DeletedPhis.empty());
581 void StructurizeCFG::killTerminator(
BasicBlock *BB) {
589 delPhiValues(BB, *SI);
597 bool IncludeDominator) {
612 delPhiValues(BB, OldExit);
614 addPhiValues(BB, NewExit);
617 if (IncludeDominator) {
621 Dominator = DT->findNearestCommonDominator(Dominator, BB);
627 DT->changeImmediateDominator(NewExit, Dominator);
636 addPhiValues(BB, NewExit);
637 if (IncludeDominator)
638 DT->changeImmediateDominator(NewExit, BB);
646 Order.back()->getEntry();
649 DT->addNewBlock(Flow, Dominator);
650 ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
655 BasicBlock *StructurizeCFG::needPrefix(
bool NeedEmpty) {
658 if (!PrevNode->isSubRegion()) {
659 killTerminator(Entry);
669 changeExit(PrevNode, Flow,
true);
670 PrevNode = ParentRegion->getBBNode(Flow);
676 bool ExitUseAllowed) {
677 if (Order.empty() && ExitUseAllowed) {
679 DT->changeImmediateDominator(Exit, Flow);
680 addPhiValues(Flow, Exit);
683 return getNextFlow(Flow);
687 void StructurizeCFG::setPrevNode(
BasicBlock *BB) {
688 PrevNode = ParentRegion->contains(BB) ? ParentRegion->getBBNode(BB) : 0;
693 BBPredicates &Preds = Predicates[Node->
getEntry()];
694 for (BBPredicates::iterator PI = Preds.begin(), PE = Preds.end();
697 if (!DT->dominates(BB, PI->first))
704 bool StructurizeCFG::isPredictableTrue(
RegionNode *Node) {
705 BBPredicates &Preds = Predicates[Node->
getEntry()];
706 bool Dominated =
false;
712 for (BBPredicates::iterator I = Preds.begin(), E = Preds.end();
715 if (I->second != BoolTrue)
718 if (!Dominated && DT->dominates(I->first, PrevNode->getEntry()))
727 void StructurizeCFG::wireFlow(
bool ExitUseAllowed,
732 if (isPredictableTrue(Node)) {
735 changeExit(PrevNode, Node->
getEntry(),
true);
745 BasicBlock *Next = needPostfix(Flow, ExitUseAllowed);
749 addPhiValues(Flow, Entry);
750 DT->changeImmediateDominator(Entry, Flow);
753 while (!Order.empty() && !Visited.count(LoopEnd) &&
754 dominatesPredicates(Entry, Order.
back())) {
755 handleLoops(
false, LoopEnd);
758 changeExit(PrevNode, Next,
false);
763 void StructurizeCFG::handleLoops(
bool ExitUseAllowed,
768 if (!Loops.count(LoopStart)) {
769 wireFlow(ExitUseAllowed, LoopEnd);
773 if (!isPredictableTrue(Node))
774 LoopStart = needPrefix(
true);
777 wireFlow(
false, LoopEnd);
778 while (!Visited.count(LoopEnd)) {
779 handleLoops(
false, LoopEnd);
786 LoopStart->
setName(
"entry.orig");
797 LoopEnd = needPrefix(
false);
798 BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed);
800 BoolUndef, LoopEnd));
801 addPhiValues(LoopEnd, LoopStart);
807 void StructurizeCFG::createFlow() {
809 bool EntryDominatesExit = DT->dominates(ParentRegion->getEntry(), Exit);
819 while (!Order.empty()) {
820 handleLoops(EntryDominatesExit, 0);
824 changeExit(PrevNode, Exit, EntryDominatesExit);
826 assert(EntryDominatesExit);
831 void StructurizeCFG::rebuildSSA() {
834 E = ParentRegion->block_end();
841 bool Initialized =
false;
846 Instruction *User = cast<Instruction>(I->getUser());
850 }
else if (
PHINode *UserPN = dyn_cast<PHINode>(User)) {
851 if (UserPN->getIncomingBlock(*I) == BB)
855 if (DT->dominates(II, User))
879 DT = &getAnalysis<DominatorTree>();
884 insertConditions(
false);
885 insertConditions(
true);
905 return new StructurizeCFG();
bool contains(const BasicBlock *BB) const
Check if the region contains a BasicBlock.
static ConstantInt * getFalse(LLVMContext &Context)
class_match< Value > m_Value()
m_Value() - Match an arbitrary value and ignore it.
AnalysisUsage & addPreserved()
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)
static PassRegistry * getPassRegistry()
LLVM Argument representation.
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'.
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value...
Region * getRegionFor(BasicBlock *BB) const
Get the smallest region that contains a BasicBlock.
virtual void getAnalysisUsage(AnalysisUsage &) const
BasicBlock * getEntry() const
Get the entry BasicBlock of the Region.
const Function * getParent() const
Return the enclosing method, or null if none.
A RegionNode represents a subregion or a BasicBlock that is part of a Region.
bool isTopLevelRegion() const
Check if a Region is the TopLevel region.
The pass manager to schedule RegionPasses.
StringRef getName() const
DomTreeNodeBase< NodeT > * getIDom() const
bool match(Val *V, const Pattern &P)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
void replaceExit(BasicBlock *BB)
Replace the exit basic block of the region with the new basic block.
#define llvm_unreachable(msg)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=0)
void setName(const Twine &Name)
INITIALIZE_PASS_BEGIN(StructurizeCFG,"structurizecfg","Structurize the CFG", false, false) INITIALIZE_PASS_END(StructurizeCFG
ID
LLVM Calling Convention Representation.
not_match< LHS > m_Not(const LHS &L)
Interval::succ_iterator succ_begin(Interval *I)
scc_iterator< T > scc_begin(const T &G)
BasicBlock * getSuccessor(unsigned i) const
Region * getParent() const
Get the parent of the Region.
virtual bool doInitialization(Module &)
Interval::succ_iterator succ_end(Interval *I)
void replaceUsesOfWith(Value *From, Value *To)
BasicBlock * getEntry() const
Get the entry BasicBlock of this RegionNode.
Value * GetValueInMiddleOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block...
LLVM Basic Block Representation.
void RewriteUseAfterInsertions(Use &U)
Rewrite a use like RewriteUse but handling in-block definitions.
scc_iterator< T > scc_end(const T &G)
A pass that runs on each Region in a function.
A single entry single exit Region.
Interval::pred_iterator pred_begin(Interval *I)
specificval_ty m_Specific(const Value *V)
m_Specific - Match if we have a specific specified value.
Interval::pred_iterator pred_end(Interval *I)
static UndefValue * get(Type *T)
void initializeStructurizeCFGPass(PassRegistry &)
BasicBlock * getExit() const
Get the exit BasicBlock of the Region.
bool isConditional() const
Class for constant integers.
AnalysisUsage & addRequiredID(const void *ID)
const BasicBlock & getEntryBlock() const
static ConstantInt * getTrue(LLVMContext &Context)
Value * getCondition() const
unsigned getNumSuccessors() const
std::reverse_iterator< const_iterator > reverse_iterator
bool isSubRegion() const
Is this RegionNode a subregion?
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=0, BasicBlock *InsertBefore=0)
Creates a new BasicBlock.
void setCondition(Value *V)
LLVMContext & getContext() const
Get the context in which this basic block lives.
LLVM Value Representation.
T * getNodeAs() const
Get the content of this RegionNode.
Pass * createStructurizeCFGPass()
Create the pass.
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)
static BinaryOperator * CreateNot(Value *Op, const Twine &Name="", Instruction *InsertBefore=0)
int getBasicBlockIndex(const BasicBlock *BB) const
const BasicBlock * getParent() const
Analysis that detects all canonical Regions.