diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2012-03-24 21:11:24 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2012-03-24 21:11:24 +0000 |
commit | 6b980541df5846ad335c377c8803b517968daee2 (patch) | |
tree | 6ef17d963870d48a74d9c700576fcc8701eaf530 /include/llvm/Analysis | |
parent | afe629dba136cf4ede364946c082490e9c69d4bc (diff) | |
download | external_llvm-6b980541df5846ad335c377c8803b517968daee2.zip external_llvm-6b980541df5846ad335c377c8803b517968daee2.tar.gz external_llvm-6b980541df5846ad335c377c8803b517968daee2.tar.bz2 |
Refactor the interface to recursively simplifying instructions to be tad
bit simpler by handling a common case explicitly.
Also, refactor the implementation to use a worklist based walk of the
recursive users, rather than trying to use value handles to detect and
recover from RAUWs during the recursive descent. This fixes a very
subtle bug in the previous implementation where degenerate control flow
structures could cause mutually recursive instructions (PHI nodes) to
collapse in just such a way that From became equal to To after some
amount of recursion. At that point, we hit the inf-loop that the assert
at the top attempted to guard against. This problem is defined away when
not using value handles in this manner. There are lots of comments
claiming that the WeakVH will protect against just this sort of error,
but they're not accurate about the actual implementation of WeakVHs,
which do still track RAUWs.
I don't have any test case for the bug this fixes because it requires
running the recursive simplification on unreachable phi nodes. I've no
way to either run this or easily write an input that triggers it. It was
found when using instruction simplification inside the inliner when
running over the nightly test-suite.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153393 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/Analysis')
-rw-r--r-- | include/llvm/Analysis/InstructionSimplify.h | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index fb07b03..152e885 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -189,16 +189,29 @@ namespace llvm { const DominatorTree *DT = 0); - /// ReplaceAndSimplifyAllUses - Perform From->replaceAllUsesWith(To) and then - /// delete the From instruction. In addition to a basic RAUW, this does a - /// recursive simplification of the updated instructions. This catches - /// things where one simplification exposes other opportunities. This only - /// simplifies and deletes scalar operations, it does not change the CFG. + /// \brief Replace all uses of 'I' with 'SimpleV' and simplify the uses + /// recursively. /// - void ReplaceAndSimplifyAllUses(Instruction *From, Value *To, - const TargetData *TD = 0, - const TargetLibraryInfo *TLI = 0, - const DominatorTree *DT = 0); + /// This first performs a normal RAUW of I with SimpleV. It then recursively + /// attempts to simplify those users updated by the operation. The 'I' + /// instruction must not be equal to the simplified value 'SimpleV'. + /// + /// The function returns true if any simplifications were performed. + bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV, + const TargetData *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); + + /// \brief Recursively attempt to simplify an instruction. + /// + /// This routine uses SimplifyInstruction to simplify 'I', and if successful + /// replaces uses of 'I' with the simplified value. It then recurses on each + /// of the users impacted. It returns true if any simplifications were + /// performed. + bool recursivelySimplifyInstruction(Instruction *I, + const TargetData *TD = 0, + const TargetLibraryInfo *TLI = 0, + const DominatorTree *DT = 0); } // end namespace llvm #endif |