aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-10-31 05:07:57 +0000
committerChris Lattner <sabre@nondot.org>2001-10-31 05:07:57 +0000
commit37aabf28b3ae64356b58d7e0bed2c6764bc52334 (patch)
treec63fdee814535adbe92a5ed801f44527d744f94d
parent11c862cf4661708bf4a52fe8a6b630bb844d76bd (diff)
downloadexternal_llvm-37aabf28b3ae64356b58d7e0bed2c6764bc52334.zip
external_llvm-37aabf28b3ae64356b58d7e0bed2c6764bc52334.tar.gz
external_llvm-37aabf28b3ae64356b58d7e0bed2c6764bc52334.tar.bz2
Implemented constant propogation of cast instructions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1064 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/ChrisNotes.txt1
-rw-r--r--include/llvm/ConstantHandling.h6
-rw-r--r--lib/Transforms/Scalar/ConstantProp.cpp27
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp7
-rw-r--r--lib/VMCore/ConstantFold.h6
-rw-r--r--lib/VMCore/ConstantFolding.h6
6 files changed, 49 insertions, 4 deletions
diff --git a/docs/ChrisNotes.txt b/docs/ChrisNotes.txt
index 735e2b4..158c5be 100644
--- a/docs/ChrisNotes.txt
+++ b/docs/ChrisNotes.txt
@@ -5,7 +5,6 @@
arrays and multidim arrays
* Rewrite the llvm parser/lexer in http://www.antlr.org when time permits.
They actually do C++. Imagine that.
-* Need to implement constant propogation of cast instructions!
* Fix DCE to elminate br <c>, %L1, %L1 so that it can optimize the main of
fib.ll better. Currently I have to do this to get best results:
as < fib.ll | opt -inline -sccp -dce -sccp -dce |dis
diff --git a/include/llvm/ConstantHandling.h b/include/llvm/ConstantHandling.h
index 9ce1b2c..d3af1bd 100644
--- a/include/llvm/ConstantHandling.h
+++ b/include/llvm/ConstantHandling.h
@@ -175,10 +175,16 @@ inline ConstPoolBool *operator<=(const ConstPoolVal &V1,
// Implement higher level instruction folding type instructions
//===----------------------------------------------------------------------===//
+inline ConstPoolVal *ConstantFoldCastInstruction(ConstPoolVal *V,
+ const Type *DestTy) {
+ return ConstRules::get(*V)->castTo(V, DestTy);
+}
+
inline ConstPoolVal *ConstantFoldUnaryInstruction(unsigned Opcode,
ConstPoolVal *V) {
switch (Opcode) {
case Instruction::Not: return !*V;
+ // TODO: Handle get element ptr instruction here in the future? GEP null?
}
return 0;
}
diff --git a/lib/Transforms/Scalar/ConstantProp.cpp b/lib/Transforms/Scalar/ConstantProp.cpp
index 6ab9780..babcde0 100644
--- a/lib/Transforms/Scalar/ConstantProp.cpp
+++ b/lib/Transforms/Scalar/ConstantProp.cpp
@@ -54,6 +54,29 @@ ConstantFoldUnaryInst(Method *M, Method::inst_iterator &DI,
}
inline static bool
+ConstantFoldCast(Method *M, Method::inst_iterator &DI,
+ CastInst *CI, ConstPoolVal *D) {
+ ConstPoolVal *ReplaceWith =
+ opt::ConstantFoldCastInstruction(D, CI->getType());
+
+ if (!ReplaceWith) return false; // Nothing new to change...
+
+ // Replaces all of the uses of a variable with uses of the constant.
+ CI->replaceAllUsesWith(ReplaceWith);
+
+ // Remove the cast from the list of definitions...
+ CI->getParent()->getInstList().remove(DI.getInstructionIterator());
+
+ // The new constant inherits the old name of the cast...
+ if (CI->hasName())
+ ReplaceWith->setName(CI->getName(), M->getSymbolTableSure());
+
+ // Delete the cast now...
+ delete CI;
+ return true;
+}
+
+inline static bool
ConstantFoldBinaryInst(Method *M, Method::inst_iterator &DI,
BinaryOperator *Op,
ConstPoolVal *D1, ConstPoolVal *D2) {
@@ -142,6 +165,10 @@ ConstantFoldInstruction(Method *M, Method::inst_iterator &II) {
if (D1 && D2)
return ConstantFoldBinaryInst(M, II, cast<BinaryOperator>(Inst), D1, D2);
+ } else if (CastInst *CI = dyn_cast<CastInst>(Inst)) {
+ ConstPoolVal *D = dyn_cast<ConstPoolVal>(CI->getOperand(0));
+ if (D) return ConstantFoldCast(M, II, CI, D);
+
} else if (UnaryOperator *UInst = dyn_cast<UnaryOperator>(Inst)) {
ConstPoolVal *D = dyn_cast<ConstPoolVal>(UInst->getOperand(0));
if (D) return ConstantFoldUnaryInst(M, II, UInst, D);
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp
index 101e892..70d52a6 100644
--- a/lib/Transforms/Scalar/SCCP.cpp
+++ b/lib/Transforms/Scalar/SCCP.cpp
@@ -442,9 +442,10 @@ void SCCP::UpdateInstruction(Instruction *I) {
if (VState.isOverdefined()) { // Inherit overdefinedness of operand
markOverdefined(I);
} else if (VState.isConstant()) { // Propogate constant value
- ConstPoolVal *Result =
- opt::ConstantFoldUnaryInstruction(I->getOpcode(),
- VState.getConstant());
+ ConstPoolVal *Result = isa<CastInst>(I)
+ ? opt::ConstantFoldCastInstruction(VState.getConstant(), I->getType())
+ : opt::ConstantFoldUnaryInstruction(I->getOpcode(),
+ VState.getConstant());
if (Result) {
// This instruction constant folds!
diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h
index 9ce1b2c..d3af1bd 100644
--- a/lib/VMCore/ConstantFold.h
+++ b/lib/VMCore/ConstantFold.h
@@ -175,10 +175,16 @@ inline ConstPoolBool *operator<=(const ConstPoolVal &V1,
// Implement higher level instruction folding type instructions
//===----------------------------------------------------------------------===//
+inline ConstPoolVal *ConstantFoldCastInstruction(ConstPoolVal *V,
+ const Type *DestTy) {
+ return ConstRules::get(*V)->castTo(V, DestTy);
+}
+
inline ConstPoolVal *ConstantFoldUnaryInstruction(unsigned Opcode,
ConstPoolVal *V) {
switch (Opcode) {
case Instruction::Not: return !*V;
+ // TODO: Handle get element ptr instruction here in the future? GEP null?
}
return 0;
}
diff --git a/lib/VMCore/ConstantFolding.h b/lib/VMCore/ConstantFolding.h
index 9ce1b2c..d3af1bd 100644
--- a/lib/VMCore/ConstantFolding.h
+++ b/lib/VMCore/ConstantFolding.h
@@ -175,10 +175,16 @@ inline ConstPoolBool *operator<=(const ConstPoolVal &V1,
// Implement higher level instruction folding type instructions
//===----------------------------------------------------------------------===//
+inline ConstPoolVal *ConstantFoldCastInstruction(ConstPoolVal *V,
+ const Type *DestTy) {
+ return ConstRules::get(*V)->castTo(V, DestTy);
+}
+
inline ConstPoolVal *ConstantFoldUnaryInstruction(unsigned Opcode,
ConstPoolVal *V) {
switch (Opcode) {
case Instruction::Not: return !*V;
+ // TODO: Handle get element ptr instruction here in the future? GEP null?
}
return 0;
}