diff options
author | Chris Lattner <sabre@nondot.org> | 2004-04-13 19:43:54 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-04-13 19:43:54 +0000 |
commit | 58b7b08ad77efd3fee62d8bc559432cf840beac0 (patch) | |
tree | 0ea006495e64ec27f7775a609358d6afc123cefa /lib/Transforms/Scalar | |
parent | 3d78b23d24f25b769facecc889f4b4a31bf93907 (diff) | |
download | external_llvm-58b7b08ad77efd3fee62d8bc559432cf840beac0.zip external_llvm-58b7b08ad77efd3fee62d8bc559432cf840beac0.tar.gz external_llvm-58b7b08ad77efd3fee62d8bc559432cf840beac0.tar.bz2 |
Add SCCP support for constant folding calls, implementing:
test/Regression/Transforms/SCCP/calltest.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12921 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/SCCP.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 8d550b8..38a403b 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -29,6 +29,7 @@ #include "llvm/Pass.h" #include "llvm/Type.h" #include "llvm/Support/InstVisitor.h" +#include "llvm/Transforms/Utils/Local.h" #include "Support/Debug.h" #include "Support/Statistic.h" #include "Support/STLExtras.h" @@ -220,7 +221,7 @@ private: void visitStoreInst (Instruction &I) { /*returns void*/ } void visitLoadInst (LoadInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); - void visitCallInst (Instruction &I) { markOverdefined(&I); } + void visitCallInst (CallInst &I); void visitInvokeInst (TerminatorInst &I) { if (I.getType() != Type::VoidTy) markOverdefined(&I); visitTerminatorInst(I); @@ -777,3 +778,34 @@ void SCCP::visitLoadInst(LoadInst &I) { // Bail out. markOverdefined(IV, &I); } + +void SCCP::visitCallInst(CallInst &I) { + InstVal &IV = ValueState[&I]; + if (IV.isOverdefined()) return; + + Function *F = I.getCalledFunction(); + if (F == 0 || !canConstantFoldCallTo(F)) { + markOverdefined(IV, &I); + return; + } + + std::vector<Constant*> Operands; + Operands.reserve(I.getNumOperands()-1); + + for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) { + InstVal &State = getValueState(I.getOperand(i)); + if (State.isUndefined()) + return; // Operands are not resolved yet... + else if (State.isOverdefined()) { + markOverdefined(IV, &I); + return; + } + assert(State.isConstant() && "Unknown state!"); + Operands.push_back(State.getConstant()); + } + + if (Constant *C = ConstantFoldCall(F, Operands)) + markConstant(IV, &I, C); + else + markOverdefined(IV, &I); +} |