diff options
author | Chris Lattner <sabre@nondot.org> | 2004-02-16 05:07:08 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-02-16 05:07:08 +0000 |
commit | 7059f2e76baaa70b0b940a038b55810590fc2d20 (patch) | |
tree | cda636727ef23ba7473ca32931073492b3cb95e8 /lib/Transforms/Scalar | |
parent | d8bed768ab0ec2491484aaa700c436672d3d570f (diff) | |
download | external_llvm-7059f2e76baaa70b0b940a038b55810590fc2d20.zip external_llvm-7059f2e76baaa70b0b940a038b55810590fc2d20.tar.gz external_llvm-7059f2e76baaa70b0b940a038b55810590fc2d20.tar.bz2 |
Fold PHI nodes of constants which are only used by a single cast. This implements
phi.ll:test4
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11494 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 4deb4ed..b89785d 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1968,6 +1968,35 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { Instruction *InstCombiner::visitPHINode(PHINode &PN) { if (Value *V = hasConstantValue(&PN)) return ReplaceInstUsesWith(PN, V); + + // If the only user of this instruction is a cast instruction, and all of the + // incoming values are constants, change this PHI to merge together the casted + // constants. + if (PN.hasOneUse()) + if (CastInst *CI = dyn_cast<CastInst>(PN.use_back())) + if (CI->getType() != PN.getType()) { // noop casts will be folded + bool AllConstant = true; + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) + if (!isa<Constant>(PN.getIncomingValue(i))) { + AllConstant = false; + break; + } + if (AllConstant) { + // Make a new PHI with all casted values. + PHINode *New = new PHINode(CI->getType(), PN.getName(), &PN); + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { + Constant *OldArg = cast<Constant>(PN.getIncomingValue(i)); + New->addIncoming(ConstantExpr::getCast(OldArg, New->getType()), + PN.getIncomingBlock(i)); + } + + // Update the cast instruction. + CI->setOperand(0, New); + WorkList.push_back(CI); // revisit the cast instruction to fold. + WorkList.push_back(New); // Make sure to revisit the new Phi + return &PN; // PN is now dead! + } + } return 0; } |