Add entry points to instsimplify for simplifying calls. The entry points
authorChandler Carruth <chandlerc@gmail.com>
Fri, 28 Dec 2012 11:30:55 +0000 (11:30 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Fri, 28 Dec 2012 11:30:55 +0000 (11:30 +0000)
are nice and decomposed so that we can simplify synthesized calls as
easily as actually call instructions. The internal utility still has the
same behavior, it just now operates on a more generic interface so that
I can extend the set of call simplifications that instsimplify knows
about.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171189 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/InstructionSimplify.h
lib/Analysis/InstructionSimplify.cpp

index 721f0ddd2eaf6bf4eea46458d1be5238a98a18e3..dd643a0469387c603da5d93783071dd2d9355017 100644 (file)
@@ -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,
index 0b88f4576272a6bcc59543c6c443f1ee87300efd..f0696f070d89947f8ca29ee65eb6f9a33c824740 100644 (file)
@@ -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;