Do not form ldrd / strd if the two dests / srcs are the same. Code clean up.
[oota-llvm.git] / lib / Analysis / ConstantFolding.cpp
index 7601aeb2f4f7785d13fb75de970ae54e01c4aa98..261c635feb4a2db8c3edd86d51bcd83cfbb7cbf6 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
 #include "llvm/Instructions.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/ADT/SmallVector.h"
@@ -65,8 +66,9 @@ static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
     
     // Otherwise, add any offset that our operands provide.
     gep_type_iterator GTI = gep_type_begin(CE);
-    for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i, ++GTI) {
-      ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(i));
+    for (User::const_op_iterator i = CE->op_begin() + 1, e = CE->op_end();
+         i != e; ++i, ++GTI) {
+      ConstantInt *CI = dyn_cast<ConstantInt>(*i);
       if (!CI) return false;  // Index isn't a simple constant?
       if (CI->getZExtValue() == 0) continue;  // Not adding anything.
       
@@ -75,7 +77,7 @@ static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
         Offset += TD.getStructLayout(ST)->getElementOffset(CI->getZExtValue());
       } else {
         const SequentialType *SQT = cast<SequentialType>(*GTI);
-        Offset += TD.getABITypeSize(SQT->getElementType())*CI->getSExtValue();
+        Offset += TD.getTypeAllocSize(SQT->getElementType())*CI->getSExtValue();
       }
     }
     return true;
@@ -86,7 +88,7 @@ static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
 
 
 /// SymbolicallyEvaluateBinop - One of Op0/Op1 is a constant expression.
-/// Attempt to symbolically evaluate the result of  a binary operator merging
+/// Attempt to symbolically evaluate the result of a binary operator merging
 /// these together.  If target data info is available, it is provided as TD, 
 /// otherwise TD is null.
 static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
@@ -112,7 +114,6 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
       }
   }
     
-  // TODO: Fold icmp setne/seteq as well.
   return 0;
 }
 
@@ -259,7 +260,7 @@ static Constant *FoldBitCast(Constant *C, const Type *DestTy,
         }
       }
       
-      return ConstantVector::get(&Result[0], Result.size());
+      return ConstantVector::get(Result.data(), Result.size());
     }
   }
   
@@ -280,7 +281,7 @@ static Constant *FoldBitCast(Constant *C, const Type *DestTy,
 Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
   if (PHINode *PN = dyn_cast<PHINode>(I)) {
     if (PN->getNumIncomingValues() == 0)
-      return Constant::getNullValue(PN->getType());
+      return UndefValue::get(PN->getType());
 
     Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
     if (Result == 0) return 0;
@@ -297,18 +298,35 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
   // Scan the operand list, checking to see if they are all constants, if so,
   // hand off to ConstantFoldInstOperands.
   SmallVector<Constant*, 8> Ops;
-  for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
-    if (Constant *Op = dyn_cast<Constant>(I->getOperand(i)))
+  for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i)
+    if (Constant *Op = dyn_cast<Constant>(*i))
       Ops.push_back(Op);
     else
       return 0;  // All operands not constant!
 
   if (const CmpInst *CI = dyn_cast<CmpInst>(I))
     return ConstantFoldCompareInstOperands(CI->getPredicate(),
-                                           &Ops[0], Ops.size(), TD);
+                                           Ops.data(), Ops.size(), TD);
   else
     return ConstantFoldInstOperands(I->getOpcode(), I->getType(),
-                                    &Ops[0], Ops.size(), TD);
+                                    Ops.data(), Ops.size(), TD);
+}
+
+/// ConstantFoldConstantExpression - Attempt to fold the constant expression
+/// using the specified TargetData.  If successful, the constant result is
+/// result is returned, if not, null is returned.
+Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE,
+                                               const TargetData *TD) {
+  SmallVector<Constant*, 8> Ops;
+  for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i)
+    Ops.push_back(cast<Constant>(*i));
+
+  if (CE->isCompare())
+    return ConstantFoldCompareInstOperands(CE->getPredicate(),
+                                           Ops.data(), Ops.size(), TD);
+  else 
+    return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(),
+                                    Ops.data(), Ops.size(), TD);
 }
 
 /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
@@ -338,6 +356,8 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
     return 0;
   case Instruction::ICmp:
   case Instruction::FCmp:
+  case Instruction::VICmp:
+  case Instruction::VFCmp:
     assert(0 &&"This function is invalid for compares: no predicate specified");
   case Instruction::PtrToInt:
     // If the input is a inttoptr, eliminate the pair.  This requires knowing
@@ -346,16 +366,62 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
       if (TD && CE->getOpcode() == Instruction::IntToPtr) {
         Constant *Input = CE->getOperand(0);
         unsigned InWidth = Input->getType()->getPrimitiveSizeInBits();
-        Constant *Mask = 
-          ConstantInt::get(APInt::getLowBitsSet(InWidth,
-                                                TD->getPointerSizeInBits()));
-        Input = ConstantExpr::getAnd(Input, Mask);
+        if (TD->getPointerSizeInBits() < InWidth) {
+          Constant *Mask = 
+            ConstantInt::get(APInt::getLowBitsSet(InWidth,
+                                                  TD->getPointerSizeInBits()));
+          Input = ConstantExpr::getAnd(Input, Mask);
+        }
         // Do a zext or trunc to get to the dest size.
         return ConstantExpr::getIntegerCast(Input, DestTy, false);
       }
     }
     return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
   case Instruction::IntToPtr:
+    // If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if
+    // the int size is >= the ptr size.  This requires knowing the width of a
+    // pointer, so it can't be done in ConstantExpr::getCast.
+    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
+      if (TD &&
+          TD->getPointerSizeInBits() <=
+          CE->getType()->getPrimitiveSizeInBits()) {
+        if (CE->getOpcode() == Instruction::PtrToInt) {
+          Constant *Input = CE->getOperand(0);
+          Constant *C = FoldBitCast(Input, DestTy, *TD);
+          return C ? C : ConstantExpr::getBitCast(Input, DestTy);
+        }
+        // If there's a constant offset added to the integer value before
+        // it is casted back to a pointer, see if the expression can be
+        // converted into a GEP.
+        if (CE->getOpcode() == Instruction::Add)
+          if (ConstantInt *L = dyn_cast<ConstantInt>(CE->getOperand(0)))
+            if (ConstantExpr *R = dyn_cast<ConstantExpr>(CE->getOperand(1)))
+              if (R->getOpcode() == Instruction::PtrToInt)
+                if (GlobalVariable *GV =
+                      dyn_cast<GlobalVariable>(R->getOperand(0))) {
+                  const PointerType *GVTy = cast<PointerType>(GV->getType());
+                  if (const ArrayType *AT =
+                        dyn_cast<ArrayType>(GVTy->getElementType())) {
+                    const Type *ElTy = AT->getElementType();
+                    uint64_t AllocSize = TD->getTypeAllocSize(ElTy);
+                    APInt PSA(L->getValue().getBitWidth(), AllocSize);
+                    if (ElTy == cast<PointerType>(DestTy)->getElementType() &&
+                        L->getValue().urem(PSA) == 0) {
+                      APInt ElemIdx = L->getValue().udiv(PSA);
+                      if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(),
+                                            AT->getNumElements()))) {
+                        Constant *Index[] = {
+                          Constant::getNullValue(CE->getType()),
+                          ConstantInt::get(ElemIdx)
+                        };
+                        return ConstantExpr::getGetElementPtr(GV, &Index[0], 2);
+                      }
+                    }
+                  }
+                }
+      }
+    }
+    return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
   case Instruction::Trunc:
   case Instruction::ZExt:
   case Instruction::SExt:
@@ -397,7 +463,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
                                                 const TargetData *TD) {
   // fold: icmp (inttoptr x), null         -> icmp x, 0
   // fold: icmp (ptrtoint x), 0            -> icmp x, null
-  // fold: icmp (inttoptr x), (inttoptr y) -> icmp x, y
+  // fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y
   // fold: icmp (ptrtoint x), (ptrtoint y) -> icmp x, y
   //
   // ConstantExpr::getCompare cannot do this, because it doesn't have TD
@@ -425,25 +491,35 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
       }
     }
     
-    if (TD && isa<ConstantExpr>(Ops[1]) &&
-        cast<ConstantExpr>(Ops[1])->getOpcode() == CE0->getOpcode()) {
-      const Type *IntPtrTy = TD->getIntPtrType();
-      // Only do this transformation if the int is intptrty in size, otherwise
-      // there is a truncation or extension that we aren't modeling.
-      if ((CE0->getOpcode() == Instruction::IntToPtr &&
-           CE0->getOperand(0)->getType() == IntPtrTy &&
-           Ops[1]->getOperand(0)->getType() == IntPtrTy) ||
-          (CE0->getOpcode() == Instruction::PtrToInt &&
-           CE0->getType() == IntPtrTy &&
-           CE0->getOperand(0)->getType() == Ops[1]->getOperand(0)->getType())) {
-        Constant *NewOps[] = { 
-          CE0->getOperand(0), cast<ConstantExpr>(Ops[1])->getOperand(0) 
-        };
-        return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
+    if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(Ops[1])) {
+      if (TD && CE0->getOpcode() == CE1->getOpcode()) {
+        const Type *IntPtrTy = TD->getIntPtrType();
+
+        if (CE0->getOpcode() == Instruction::IntToPtr) {
+          // Convert the integer value to the right size to ensure we get the
+          // proper extension or truncation.
+          Constant *C0 = ConstantExpr::getIntegerCast(CE0->getOperand(0),
+                                                      IntPtrTy, false);
+          Constant *C1 = ConstantExpr::getIntegerCast(CE1->getOperand(0),
+                                                      IntPtrTy, false);
+          Constant *NewOps[] = { C0, C1 };
+          return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
+        }
+
+        // Only do this transformation if the int is intptrty in size, otherwise
+        // there is a truncation or extension that we aren't modeling.
+        if ((CE0->getOpcode() == Instruction::PtrToInt &&
+             CE0->getType() == IntPtrTy &&
+             CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType())) {
+          Constant *NewOps[] = { 
+            CE0->getOperand(0), CE1->getOperand(0) 
+          };
+          return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
+        }
       }
     }
   }
-  return ConstantExpr::getCompare(Predicate, Ops[0], Ops[1]); 
+  return ConstantExpr::getCompare(Predicate, Ops[0], Ops[1]);
 }
 
 
@@ -525,10 +601,9 @@ llvm::canConstantFoldCallTo(const Function *F) {
   default: break;
   }
 
-  const ValueName *NameVal = F->getValueName();
-  if (NameVal == 0) return false;
-  const char *Str = NameVal->getKeyData();
-  unsigned Len = NameVal->getKeyLength();
+  if (!F->hasName()) return false;
+  const char *Str = F->getNameStart();
+  unsigned Len = F->getNameLen();
   
   // In these cases, the check of the length is required.  We don't want to
   // return true for a name like "cos\0blah" which strcmp would return equal to
@@ -629,10 +704,9 @@ static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
 Constant *
 llvm::ConstantFoldCall(Function *F, 
                        Constant* const* Operands, unsigned NumOperands) {
-  const ValueName *NameVal = F->getValueName();
-  if (NameVal == 0) return 0;
-  const char *Str = NameVal->getKeyData();
-  unsigned Len = NameVal->getKeyLength();
+  if (!F->hasName()) return 0;
+  const char *Str = F->getNameStart();
+  unsigned Len = F->getNameLen();
   
   const Type *Ty = F->getReturnType();
   if (NumOperands == 1) {