diff options
author | Duncan Sands <baldrick@free.fr> | 2010-11-17 04:30:22 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2010-11-17 04:30:22 +0000 |
commit | ff10341183adf74760e6118a55cbd1debf50f90f (patch) | |
tree | 8ddc7145851c25d25499846ae47e84636c2660b6 /lib/Analysis/InstructionSimplify.cpp | |
parent | a0c5244e8575ae91af318af09353ff34ac6bca1e (diff) |
Fix a layering violation: hasConstantValue, which is part of the PHINode
class, uses DominatorTree which is an analysis. This change moves all of
the tricky hasConstantValue logic to SimplifyInstruction, and replaces it
with a very simple literal implementation. I already taught users of
hasConstantValue that need tricky stuff to use SimplifyInstruction instead.
I didn't update InlineFunction because the IR looks like it might be in a
funky state at the point it calls hasConstantValue, which makes calling
SimplifyInstruction dangerous since it can in theory do a lot of tricky
reasoning. This may be a pessimization, for example in the case where
all phi node operands are either undef or a fixed constant.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119459 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | lib/Analysis/InstructionSimplify.cpp | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index cf1548eeb8..c540d6fd2c 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -173,7 +173,7 @@ static Value *ThreadBinOpOverPHI(unsigned Opcode, Value *LHS, Value *RHS, Value *CommonValue = 0; for (unsigned i = 0, e = PI->getNumIncomingValues(); i != e; ++i) { Value *Incoming = PI->getIncomingValue(i); - // If the incoming value is the phi node itself, it can be safely skipped. + // If the incoming value is the phi node itself, it can safely be skipped. if (Incoming == PI) continue; Value *V = PI == LHS ? SimplifyBinOp(Opcode, Incoming, RHS, TD, DT, MaxRecurse) : @@ -211,7 +211,7 @@ static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS, Value *CommonValue = 0; for (unsigned i = 0, e = PI->getNumIncomingValues(); i != e; ++i) { Value *Incoming = PI->getIncomingValue(i); - // If the incoming value is the phi node itself, it can be safely skipped. + // If the incoming value is the phi node itself, it can safely be skipped. if (Incoming == PI) continue; Value *V = SimplifyCmpInst(Pred, Incoming, RHS, TD, DT, MaxRecurse); // If the operation failed to simplify, or simplified to a different value @@ -663,6 +663,40 @@ Value *llvm::SimplifyGEPInst(Value *const *Ops, unsigned NumOps, (Constant *const*)Ops+1, NumOps-1); } +/// SimplifyPHINode - See if we can fold the given phi. If not, returns null. +static Value *SimplifyPHINode(PHINode *PN, const DominatorTree *DT) { + // If all of the PHI's incoming values are the same then replace the PHI node + // with the common value. + Value *CommonValue = 0; + bool HasUndefInput = false; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + Value *Incoming = PN->getIncomingValue(i); + // If the incoming value is the phi node itself, it can safely be skipped. + if (Incoming == PN) continue; + if (isa<UndefValue>(Incoming)) { + // Remember that we saw an undef value, but otherwise ignore them. + HasUndefInput = true; + continue; + } + if (CommonValue && Incoming != CommonValue) + return 0; // Not the same, bail out. + CommonValue = Incoming; + } + + // If CommonValue is null then all of the incoming values were either undef or + // equal to the phi node itself. + if (!CommonValue) + return UndefValue::get(PN->getType()); + + // If we have a PHI node like phi(X, undef, X), where X is defined by some + // instruction, we cannot return X as the result of the PHI node unless it + // dominates the PHI block. + if (HasUndefInput) + return ValueDominatesPHI(CommonValue, PN, DT) ? CommonValue : 0; + + return CommonValue; +} + //=== Helper functions for higher up the class hierarchy. @@ -748,7 +782,7 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD, return SimplifyGEPInst(&Ops[0], Ops.size(), TD, DT); } case Instruction::PHI: - return cast<PHINode>(I)->hasConstantValue(DT); + return SimplifyPHINode(cast<PHINode>(I), DT); } } |