aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-02-16 05:07:08 +0000
committerChris Lattner <sabre@nondot.org>2004-02-16 05:07:08 +0000
commit7059f2e76baaa70b0b940a038b55810590fc2d20 (patch)
treecda636727ef23ba7473ca32931073492b3cb95e8 /lib/Transforms/Scalar
parentd8bed768ab0ec2491484aaa700c436672d3d570f (diff)
downloadexternal_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.cpp29
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;
}