aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h20
-rw-r--r--lib/Analysis/InstructionSimplify.cpp35
2 files changed, 50 insertions, 5 deletions
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index 721f0ddd2e..dd643a0469 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -19,6 +19,8 @@
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
+#include "llvm/User.h"
+
namespace llvm {
template<typename T>
class ArrayRef;
@@ -205,6 +207,24 @@ namespace llvm {
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
+ /// \brief Given a function and iterators over arguments, see if we can fold
+ /// the result.
+ ///
+ /// If this call could not be simplified returns null.
+ Value *SimplifyCall(Value *F, User::op_iterator ArgBegin,
+ User::op_iterator ArgEnd, const DataLayout *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
+ /// \brief Given a function and set of arguments, see if we can fold the
+ /// result.
+ ///
+ /// If this call could not be simplified returns null.
+ Value *SimplifyCall(Value *F, ArrayRef<Value *> Args,
+ const DataLayout *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 0b88f45762..f0696f070d 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -2869,14 +2869,36 @@ Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
RecursionLimit);
}
-static Value *SimplifyCallInst(CallInst *CI, const Query &) {
+template <typename IterTy>
+static Value *SimplifyCall(Value *F, IterTy ArgBegin, IterTy ArgEnd,
+ const Query &Q, unsigned MaxRecurse) {
+ Type *Ty = F->getType();
+ if (PointerType *PTy = dyn_cast<PointerType>(Ty))
+ Ty = PTy->getElementType();
+ FunctionType *FTy = cast<FunctionType>(Ty);
+
// call undef -> undef
- if (isa<UndefValue>(CI->getCalledValue()))
- return UndefValue::get(CI->getType());
+ if (isa<UndefValue>(F))
+ return UndefValue::get(FTy->getReturnType());
return 0;
}
+Value *llvm::SimplifyCall(Value *F, User::op_iterator ArgBegin,
+ User::op_iterator ArgEnd, const DataLayout *TD,
+ const TargetLibraryInfo *TLI,
+ const DominatorTree *DT) {
+ return ::SimplifyCall(F, ArgBegin, ArgEnd, Query(TD, TLI, DT),
+ RecursionLimit);
+}
+
+Value *llvm::SimplifyCall(Value *F, ArrayRef<Value *> Args,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
+ const DominatorTree *DT) {
+ return ::SimplifyCall(F, Args.begin(), Args.end(), Query(TD, TLI, DT),
+ RecursionLimit);
+}
+
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout *TD,
@@ -2985,9 +3007,12 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout *TD,
case Instruction::PHI:
Result = SimplifyPHINode(cast<PHINode>(I), Query (TD, TLI, DT));
break;
- case Instruction::Call:
- Result = SimplifyCallInst(cast<CallInst>(I), Query (TD, TLI, DT));
+ case Instruction::Call: {
+ CallSite CS(cast<CallInst>(I));
+ Result = SimplifyCall(CS.getCalledValue(), CS.arg_begin(), CS.arg_end(),
+ TD, TLI, DT);
break;
+ }
case Instruction::Trunc:
Result = SimplifyTruncInst(I->getOperand(0), I->getType(), TD, TLI, DT);
break;