Implement a new method, CloneAndPruneFunctionInto, as documented.
[oota-llvm.git] / lib / Transforms / Utils / Local.cpp
index 915c6676abc53c08c40159c58c8eb2a5789b3ad7..3d1faff0184f8aaed2440cad93e75ef566811cc2 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Support/MathExtras.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
 #include "llvm/Intrinsics.h"
+#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/MathExtras.h"
 #include <cerrno>
 #include <cmath>
 using namespace llvm;
@@ -61,18 +64,6 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I) {
 
     // If we reach here, all incoming values are the same constant.
     return Result;
-  } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
-    if (Function *F = CI->getCalledFunction())
-      if (canConstantFoldCallTo(F)) {
-        std::vector<Constant*> Args;
-        for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
-          if (Constant *Op = dyn_cast<Constant>(CI->getOperand(i)))
-            Args.push_back(Op);
-          else
-            return 0;
-        return ConstantFoldCall(F, Args);
-      }
-    return 0;
   }
 
   Constant *Op0 = 0, *Op1 = 0;
@@ -88,27 +79,63 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I) {
   case 0: return 0;
   }
 
-  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I))
-    return ConstantExpr::get(I->getOpcode(), Op0, Op1);
+  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) {
+    if (Constant *Op0 = dyn_cast<Constant>(I->getOperand(0)))
+      if (Constant *Op1 = dyn_cast<Constant>(I->getOperand(1)))
+        return ConstantExpr::get(I->getOpcode(), Op0, Op1);
+    return 0;  // Operands not constants.
+  }
+
+  // Scan the operand list, checking to see if the are all constants, if so,
+  // hand off to ConstantFoldInstOperands.
+  std::vector<Constant*> Ops;
+  for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+    if (Constant *Op = dyn_cast<Constant>(I->getOperand(i)))
+      Ops.push_back(Op);
+    else
+      return 0;  // All operands not constant!
 
-  switch (I->getOpcode()) {
+  return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops);
+}
+
+/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
+/// specified opcode and operands.  If successful, the constant result is
+/// returned, if not, null is returned.  Note that this function can fail when
+/// attempting to fold instructions like loads and stores, which have no
+/// constant expression form.
+///
+Constant *llvm::ConstantFoldInstOperands(unsigned Opc, const Type *DestTy,
+                                         const std::vector<Constant*> &Ops) {
+  if (Opc >= Instruction::BinaryOpsBegin && Opc < Instruction::BinaryOpsEnd)
+    return ConstantExpr::get(Opc, Ops[0], Ops[1]);
+  
+  switch (Opc) {
   default: return 0;
+  case Instruction::Call:
+    if (Function *F = dyn_cast<Function>(Ops[0])) {
+      if (canConstantFoldCallTo(F)) {
+        std::vector<Constant*> Args(Ops.begin()+1, Ops.end());
+        return ConstantFoldCall(F, Args);
+      }
+    }
+    return 0;
+  case Instruction::Shl:
+  case Instruction::Shr:
+    return ConstantExpr::get(Opc, Ops[0], Ops[1]);
   case Instruction::Cast:
-    return ConstantExpr::getCast(Op0, I->getType());
+    return ConstantExpr::getCast(Ops[0], DestTy);
   case Instruction::Select:
-    if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2)))
-      return ConstantExpr::getSelect(Op0, Op1, Op2);
-    return 0;
+    return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]);
+  case Instruction::ExtractElement:
+    return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
+  case Instruction::InsertElement:
+    return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);
+  case Instruction::ShuffleVector:
+    return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
   case Instruction::GetElementPtr:
-    std::vector<Constant*> IdxList;
-    IdxList.reserve(I->getNumOperands()-1);
-    if (Op1) IdxList.push_back(Op1);
-    for (unsigned i = 2, e = I->getNumOperands(); i != e; ++i)
-      if (Constant *C = dyn_cast<Constant>(I->getOperand(i)))
-        IdxList.push_back(C);
-      else
-        return 0;  // Non-constant operand
-    return ConstantExpr::getGetElementPtr(Op0, IdxList);
+    return ConstantExpr::getGetElementPtr(Ops[0],
+                                          std::vector<Constant*>(Ops.begin()+1, 
+                                                                 Ops.end()));
   }
 }
 
@@ -232,94 +259,82 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB) {
   return false;
 }
 
-/// canConstantFoldCallTo - Return true if its even possible to fold a call to
-/// the specified function.
-bool llvm::canConstantFoldCallTo(Function *F) {
-  const std::string &Name = F->getName();
-
-  switch (F->getIntrinsicID()) {
-  case Intrinsic::isunordered: return true;
-  default: break;
-  }
-
-  return Name == "sin" || Name == "cos" || Name == "tan" || Name == "sqrt" ||
-         Name == "log" || Name == "log10" || Name == "exp" || Name == "pow" ||
-         Name == "acos" || Name == "asin" || Name == "atan" || Name == "fmod";
-}
-
-static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
-                                const Type *Ty) {
-  errno = 0;
-  V = NativeFP(V);
-  if (errno == 0)
-    return ConstantFP::get(Ty, V);
-  return 0;
-}
-
-/// ConstantFoldCall - Attempt to constant fold a call to the specified function
-/// with the specified arguments, returning null if unsuccessful.
-Constant *llvm::ConstantFoldCall(Function *F,
-                                 const std::vector<Constant*> &Operands) {
-  const std::string &Name = F->getName();
-  const Type *Ty = F->getReturnType();
-
-  if (Operands.size() == 1) {
-    if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) {
-      double V = Op->getValue();
-      if (Name == "sin")
-        return ConstantFP::get(Ty, sin(V));
-      else if (Name == "cos")
-        return ConstantFP::get(Ty, cos(V));
-      else if (Name == "tan")
-        return ConstantFP::get(Ty, tan(V));
-      else if (Name == "sqrt" && V >= 0)
-        return ConstantFP::get(Ty, sqrt(V));
-      else if (Name == "exp")
-        return ConstantFP::get(Ty, exp(V));
-      else if (Name == "log" && V > 0)
-        return ConstantFP::get(Ty, log(V));
-      else if (Name == "log10")
-        return ConstantFoldFP(log10, V, Ty);
-      else if (Name == "acos")
-        return ConstantFoldFP(acos, V, Ty);
-      else if (Name == "asin")
-        return ConstantFoldFP(asin, V, Ty);
-      else if (Name == "atan")
-        return ConstantFP::get(Ty, atan(V));
-    }
-  } else if (Operands.size() == 2) {
-    if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0]))
-      if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
-        double Op1V = Op1->getValue(), Op2V = Op2->getValue();
-
-        if (Name == "llvm.isunordered")
-          return ConstantBool::get(IsNAN(Op1V) || IsNAN(Op2V));
+/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
+/// getelementptr constantexpr, return the constant value being addressed by the
+/// constant expression, or null if something is funny and we can't decide.
+Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C, 
+                                                       ConstantExpr *CE) {
+  if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
+    return 0;  // Do not allow stepping over the value!
+  
+  // Loop over all of the operands, tracking down which value we are
+  // addressing...
+  gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
+  for (++I; I != E; ++I)
+    if (const StructType *STy = dyn_cast<StructType>(*I)) {
+      ConstantUInt *CU = cast<ConstantUInt>(I.getOperand());
+      assert(CU->getValue() < STy->getNumElements() &&
+             "Struct index out of range!");
+      unsigned El = (unsigned)CU->getValue();
+      if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
+        C = CS->getOperand(El);
+      } else if (isa<ConstantAggregateZero>(C)) {
+        C = Constant::getNullValue(STy->getElementType(El));
+      } else if (isa<UndefValue>(C)) {
+        C = UndefValue::get(STy->getElementType(El));
+      } else {
+        return 0;
+      }
+    } else if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand())) {
+      if (const ArrayType *ATy = dyn_cast<ArrayType>(*I)) {
+        if ((uint64_t)CI->getRawValue() >= ATy->getNumElements())
+         return 0;
+        if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
+          C = CA->getOperand((unsigned)CI->getRawValue());
+        else if (isa<ConstantAggregateZero>(C))
+          C = Constant::getNullValue(ATy->getElementType());
+        else if (isa<UndefValue>(C))
+          C = UndefValue::get(ATy->getElementType());
         else
-        if (Name == "pow") {
-          errno = 0;
-          double V = pow(Op1V, Op2V);
-          if (errno == 0)
-            return ConstantFP::get(Ty, V);
-        } else if (Name == "fmod") {
-          errno = 0;
-          double V = fmod(Op1V, Op2V);
-          if (errno == 0)
-            return ConstantFP::get(Ty, V);
-        }
+          return 0;
+      } else if (const PackedType *PTy = dyn_cast<PackedType>(*I)) {
+        if ((uint64_t)CI->getRawValue() >= PTy->getNumElements())
+          return 0;
+        if (ConstantPacked *CP = dyn_cast<ConstantPacked>(C))
+          C = CP->getOperand((unsigned)CI->getRawValue());
+        else if (isa<ConstantAggregateZero>(C))
+          C = Constant::getNullValue(PTy->getElementType());
+        else if (isa<UndefValue>(C))
+          C = UndefValue::get(PTy->getElementType());
+        else
+          return 0;
+      } else {
+        return 0;
       }
-  }
-  return 0;
+    } else {
+      return 0;
+    }
+  return C;
 }
 
 
-
-
 //===----------------------------------------------------------------------===//
 //  Local dead code elimination...
 //
 
 bool llvm::isInstructionTriviallyDead(Instruction *I) {
-  return I->use_empty() && !I->mayWriteToMemory() && !isa<TerminatorInst>(I);
+  if (!I->use_empty() || isa<TerminatorInst>(I)) return false;
+
+  if (!I->mayWriteToMemory()) return true;
+
+  if (CallInst *CI = dyn_cast<CallInst>(I))
+    if (Function *F = CI->getCalledFunction()) {
+      unsigned IntrinsicID = F->getIntrinsicID();
+#define GET_SIDE_EFFECT_INFO
+#include "llvm/Intrinsics.gen"
+#undef GET_SIDE_EFFECT_INFO
+    }
+  return false;
 }
 
 // dceInstruction - Inspect the instruction at *BBI and figure out if it's
@@ -335,37 +350,3 @@ bool llvm::dceInstruction(BasicBlock::iterator &BBI) {
   }
   return false;
 }
-
-//===----------------------------------------------------------------------===//
-//  PHI Instruction Simplification
-//
-
-/// hasConstantValue - If the specified PHI node always merges together the same
-/// value, return the value, otherwise return null.
-///
-Value *llvm::hasConstantValue(PHINode *PN) {
-  // If the PHI node only has one incoming value, eliminate the PHI node...
-  if (PN->getNumIncomingValues() == 1)
-    return PN->getIncomingValue(0);
-
-  // Otherwise if all of the incoming values are the same for the PHI, replace
-  // the PHI node with the incoming value.
-  //
-  Value *InVal = 0;
-  for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
-    if (PN->getIncomingValue(i) != PN &&  // Not the PHI node itself...
-        !isa<UndefValue>(PN->getIncomingValue(i)))
-      if (InVal && PN->getIncomingValue(i) != InVal)
-        return 0;  // Not the same, bail out.
-      else
-        InVal = PN->getIncomingValue(i);
-
-  // The only case that could cause InVal to be null is if we have a PHI node
-  // that only has entries for itself.  In this case, there is no entry into the
-  // loop, so kill the PHI.
-  //
-  if (InVal == 0) InVal = UndefValue::get(PN->getType());
-
-  // All of the incoming values are the same, return the value now.
-  return InVal;
-}