From 58b7b08ad77efd3fee62d8bc559432cf840beac0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 13 Apr 2004 19:43:54 +0000 Subject: [PATCH] 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 --- lib/Transforms/Scalar/SCCP.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 8d550b82797..38a403b1a5d 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 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); +}