diff options
author | Chris Lattner <sabre@nondot.org> | 2004-02-01 06:32:28 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-02-01 06:32:28 +0000 |
commit | c23396e8de5d28b964b0d3cd74c7e3681853445e (patch) | |
tree | 971c10e66d166336403c31d1f61d1a3038e85464 /lib | |
parent | d4baf0f74ca54dcbb61d199f4b184d6012d7179f (diff) | |
download | external_llvm-c23396e8de5d28b964b0d3cd74c7e3681853445e.zip external_llvm-c23396e8de5d28b964b0d3cd74c7e3681853445e.tar.gz external_llvm-c23396e8de5d28b964b0d3cd74c7e3681853445e.tar.bz2 |
Disable tail duplication in any "hard" cases, where it might break SSA form.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11052 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/Scalar/TailDuplication.cpp | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/lib/Transforms/Scalar/TailDuplication.cpp b/lib/Transforms/Scalar/TailDuplication.cpp index 95226a2..52552d5 100644 --- a/lib/Transforms/Scalar/TailDuplication.cpp +++ b/lib/Transforms/Scalar/TailDuplication.cpp @@ -41,6 +41,7 @@ namespace { bool runOnFunction(Function &F); private: inline bool shouldEliminateUnconditionalBranch(TerminatorInst *TI); + inline bool canEliminateUnconditionalBranch(TerminatorInst *TI); inline void eliminateUnconditionalBranch(BranchInst *BI); inline void InsertPHINodesIfNecessary(Instruction *OrigInst, Value *NewInst, BasicBlock *NewBlock); @@ -63,7 +64,8 @@ Pass *llvm::createTailDuplicationPass() { return new TailDup(); } bool TailDup::runOnFunction(Function &F) { bool Changed = false; for (Function::iterator I = F.begin(), E = F.end(); I != E; ) - if (shouldEliminateUnconditionalBranch(I->getTerminator())) { + if (shouldEliminateUnconditionalBranch(I->getTerminator()) && + canEliminateUnconditionalBranch(I->getTerminator())) { eliminateUnconditionalBranch(cast<BranchInst>(I->getTerminator())); Changed = true; } else { @@ -111,6 +113,30 @@ bool TailDup::shouldEliminateUnconditionalBranch(TerminatorInst *TI) { return true; } +/// canEliminateUnconditionalBranch - Unfortunately, the general form of tail +/// duplication can do very bad things to SSA form, by destroying arbitrary +/// relationships between dominators and dominator frontiers as it processes the +/// program. The right solution for this is to have an incrementally updating +/// dominator data structure, which can gracefully react to arbitrary +/// "addEdge/removeEdge" changes to the CFG. Implementing this is nontrivial, +/// however, so we just disable the transformation in cases where it is not +/// currently safe. +/// +bool TailDup::canEliminateUnconditionalBranch(TerminatorInst *TI) { + // Basically, we refuse to make the transformation if any of the values + // computed in the 'tail' are used in any other basic blocks. + BasicBlock *Tail = TI->getSuccessor(0); + + for (BasicBlock::iterator I = Tail->begin(), E = Tail->end(); I != E; ++I) + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; + ++UI) { + Instruction *User = cast<Instruction>(*UI); + if (User->getParent() != Tail || isa<PHINode>(User)) + return false; + } + return true; +} + /// eliminateUnconditionalBranch - Clone the instructions from the destination /// block into the source block, eliminating the specified unconditional branch. |