[llvm-commits] [vector_llvm] CVS: llvm/lib/Transforms/Scalar/ADCE.cpp InstructionCombining.cpp LoopStrengthReduce.cpp LowerAllocations.cpp LowerConstantExprs.cpp LowerGC.cpp LowerInvoke.cpp Makefile Reg2Mem.cpp ScalarReplAggregates.cpp TailRecursionElimination.cpp

Robert Bocchino bocchino at cs.uiuc.edu
Wed Nov 16 10:33:12 PST 2005



Changes in directory llvm/lib/Transforms/Scalar:

ADCE.cpp updated: 1.93 -> 1.93.4.1
InstructionCombining.cpp updated: 1.388.2.1 -> 1.388.2.2
LoopStrengthReduce.cpp updated: 1.68 -> 1.68.2.1
LowerAllocations.cpp updated: 1.54 -> 1.54.4.1
LowerConstantExprs.cpp (r1.4.4.1) removed
LowerGC.cpp updated: 1.8 -> 1.8.4.1
LowerInvoke.cpp updated: 1.33 -> 1.33.2.1
Makefile updated: 1.4 -> 1.4.6.1
Reg2Mem.cpp added (r1.3.2.2)
ScalarReplAggregates.cpp updated: 1.31 -> 1.31.4.1
TailRecursionElimination.cpp updated: 1.21 -> 1.21.2.1
---
Log message:

Merged mainline into Vector LLVM branch


---
Diffs of the changes:  (+323 -63)

 ADCE.cpp                     |    2 
 InstructionCombining.cpp     |  257 +++++++++++++++++++++++++++++++++++--------
 LoopStrengthReduce.cpp       |    3 
 LowerAllocations.cpp         |    2 
 LowerGC.cpp                  |    5 
 LowerInvoke.cpp              |   29 ++--
 Makefile                     |    1 
 Reg2Mem.cpp                  |   81 +++++++++++++
 ScalarReplAggregates.cpp     |    5 
 TailRecursionElimination.cpp |    1 
 10 files changed, 323 insertions(+), 63 deletions(-)


Index: llvm/lib/Transforms/Scalar/ADCE.cpp
diff -u llvm/lib/Transforms/Scalar/ADCE.cpp:1.93 llvm/lib/Transforms/Scalar/ADCE.cpp:1.93.4.1
--- llvm/lib/Transforms/Scalar/ADCE.cpp:1.93	Sat May 14 07:25:31 2005
+++ llvm/lib/Transforms/Scalar/ADCE.cpp	Wed Nov 16 12:32:53 2005
@@ -29,6 +29,8 @@
 #include <algorithm>
 using namespace llvm;
 
+static IncludeFile X((void*)createUnifyFunctionExitNodesPass);
+
 namespace {
   Statistic<> NumBlockRemoved("adce", "Number of basic blocks removed");
   Statistic<> NumInstRemoved ("adce", "Number of instructions removed");


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.388.2.1 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.388.2.2
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.388.2.1	Tue Oct 18 14:21:57 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Wed Nov 16 12:32:53 2005
@@ -227,6 +227,7 @@
                               bool isSub, Instruction &I);
     Instruction *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
                                  bool Inside, Instruction &IB);
+    Instruction *PromoteCastOfAllocation(CastInst &CI, AllocationInst &AI);
   };
 
   RegisterOpt<InstCombiner> X("instcombine", "Combine redundant instructions");
@@ -388,7 +389,8 @@
 /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero.  We use
 /// this predicate to simplify operations downstream.  V and Mask are known to
 /// be the same type.
-static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) {
+static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask, 
+                              unsigned Depth = 0) {
   // Note, we cannot consider 'undef' to be "IsZero" here.  The problem is that
   // we cannot optimize based on the assumption that it is zero without changing
   // to to an explicit zero.  If we don't change it to zero, other code could
@@ -399,6 +401,8 @@
     return true;
   if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(V))
     return ConstantExpr::getAnd(CI, Mask)->isNullValue();
+
+  if (Depth == 6) return false;  // Limit search depth.
   
   if (Instruction *I = dyn_cast<Instruction>(V)) {
     switch (I->getOpcode()) {
@@ -407,21 +411,21 @@
       if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1))) {
         ConstantIntegral *C1C2 = 
           cast<ConstantIntegral>(ConstantExpr::getAnd(CI, Mask));
-        if (MaskedValueIsZero(I->getOperand(0), C1C2))
+        if (MaskedValueIsZero(I->getOperand(0), C1C2, Depth+1))
           return true;
       }
       // If either the LHS or the RHS are MaskedValueIsZero, the result is zero.
-      return MaskedValueIsZero(I->getOperand(1), Mask) ||
-             MaskedValueIsZero(I->getOperand(0), Mask);
+      return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) ||
+             MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
     case Instruction::Or:
     case Instruction::Xor:
       // If the LHS and the RHS are MaskedValueIsZero, the result is also zero.
-      return MaskedValueIsZero(I->getOperand(1), Mask) &&
-             MaskedValueIsZero(I->getOperand(0), Mask);
+      return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) &&
+             MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
     case Instruction::Select:
       // If the T and F values are MaskedValueIsZero, the result is also zero.
-      return MaskedValueIsZero(I->getOperand(2), Mask) &&
-             MaskedValueIsZero(I->getOperand(1), Mask);
+      return MaskedValueIsZero(I->getOperand(2), Mask, Depth+1) &&
+             MaskedValueIsZero(I->getOperand(1), Mask, Depth+1);
     case Instruction::Cast: {
       const Type *SrcTy = I->getOperand(0)->getType();
       if (SrcTy == Type::BoolTy)
@@ -439,7 +443,7 @@
           Constant *NewMask =
           ConstantExpr::getCast(Mask, I->getOperand(0)->getType());
           return MaskedValueIsZero(I->getOperand(0),
-                                   cast<ConstantIntegral>(NewMask));
+                                   cast<ConstantIntegral>(NewMask), Depth+1);
         }
       }
       break;
@@ -448,7 +452,8 @@
       // (shl X, C1) & C2 == 0   iff   (X & C2 >>u C1) == 0
       if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
         return MaskedValueIsZero(I->getOperand(0),
-                    cast<ConstantIntegral>(ConstantExpr::getUShr(Mask, SA)));
+                    cast<ConstantIntegral>(ConstantExpr::getUShr(Mask, SA)), 
+                                 Depth+1);
       break;
     case Instruction::Shr:
       // (ushr X, C1) & C2 == 0   iff  (-1 >> C1) & C2 == 0
@@ -705,7 +710,7 @@
     // X + (signbit) --> X ^ signbit
     if (ConstantInt *CI = dyn_cast<ConstantInt>(RHSC)) {
       unsigned NumBits = CI->getType()->getPrimitiveSizeInBits();
-      uint64_t Val = CI->getRawValue() & (1ULL << NumBits)-1;
+      uint64_t Val = CI->getRawValue() & (~0ULL >> (64- NumBits));
       if (Val == (1ULL << (NumBits-1)))
         return BinaryOperator::createXor(LHS, RHS);
     }
@@ -1235,13 +1240,32 @@
     if (LHS->equalsInt(0))
       return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
 
+  if (I.getType()->isSigned()) {
+    // If the top bits of both operands are zero (i.e. we can prove they are
+    // unsigned inputs), turn this into a udiv.
+    ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType());
+    if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) {
+      const Type *NTy = Op0->getType()->getUnsignedVersion();
+      Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
+      InsertNewInstBefore(LHS, I);
+      Value *RHS;
+      if (Constant *R = dyn_cast<Constant>(Op1))
+        RHS = ConstantExpr::getCast(R, NTy);
+      else
+        RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I);
+      Instruction *Div = BinaryOperator::createDiv(LHS, RHS, I.getName());
+      InsertNewInstBefore(Div, I);
+      return new CastInst(Div, I.getType());
+    }      
+  }
+  
   return 0;
 }
 
 
 Instruction *InstCombiner::visitRem(BinaryOperator &I) {
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-  if (I.getType()->isSigned())
+  if (I.getType()->isSigned()) {
     if (Value *RHSNeg = dyn_castNegVal(Op1))
       if (!isa<ConstantSInt>(RHSNeg) ||
           cast<ConstantSInt>(RHSNeg)->getValue() > 0) {
@@ -1250,6 +1274,24 @@
         I.setOperand(1, RHSNeg);
         return &I;
       }
+   
+    // If the top bits of both operands are zero (i.e. we can prove they are
+    // unsigned inputs), turn this into a urem.
+    ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType());
+    if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) {
+      const Type *NTy = Op0->getType()->getUnsignedVersion();
+      Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
+      InsertNewInstBefore(LHS, I);
+      Value *RHS;
+      if (Constant *R = dyn_cast<Constant>(Op1))
+        RHS = ConstantExpr::getCast(R, NTy);
+      else
+        RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I);
+      Instruction *Rem = BinaryOperator::createRem(LHS, RHS, I.getName());
+      InsertNewInstBefore(Rem, I);
+      return new CastInst(Rem, I.getType());
+    }
+  }
 
   if (isa<UndefValue>(Op0))              // undef % X -> 0
     return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
@@ -1708,7 +1750,6 @@
   return InsertNewInstBefore(New, I);
 }
 
-
 Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
   bool Changed = SimplifyCommutative(I);
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@@ -1724,6 +1765,15 @@
     // and X, -1 == X
     if (AndRHS->isAllOnesValue())
       return ReplaceInstUsesWith(I, Op0);
+    
+    // and (and X, c1), c2 -> and (x, c1&c2).  Handle this case here, before
+    // calling MaskedValueIsZero, to avoid inefficient cases where we traipse
+    // through many levels of ands.
+    {
+      Value *X; ConstantInt *C1;
+      if (match(Op0, m_And(m_Value(X), m_ConstantInt(C1))))
+        return BinaryOperator::createAnd(X, ConstantExpr::getAnd(C1, AndRHS));
+    }
 
     if (MaskedValueIsZero(Op0, AndRHS))        // LHS & RHS == 0
       return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
@@ -3762,6 +3812,149 @@
   return CI;
 }
 
+/// DecomposeSimpleLinearExpr - Analyze 'Val', seeing if it is a simple linear
+/// expression.  If so, decompose it, returning some value X, such that Val is
+/// X*Scale+Offset.
+///
+static Value *DecomposeSimpleLinearExpr(Value *Val, unsigned &Scale,
+                                        unsigned &Offset) {
+  assert(Val->getType() == Type::UIntTy && "Unexpected allocation size type!");
+  if (ConstantUInt *CI = dyn_cast<ConstantUInt>(Val)) {
+    Offset = CI->getValue();
+    Scale  = 1;
+    return ConstantUInt::get(Type::UIntTy, 0);
+  } else if (Instruction *I = dyn_cast<Instruction>(Val)) {
+    if (I->getNumOperands() == 2) {
+      if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(I->getOperand(1))) {
+        if (I->getOpcode() == Instruction::Shl) {
+          // This is a value scaled by '1 << the shift amt'.
+          Scale = 1U << CUI->getValue();
+          Offset = 0;
+          return I->getOperand(0);
+        } else if (I->getOpcode() == Instruction::Mul) {
+          // This value is scaled by 'CUI'.
+          Scale = CUI->getValue();
+          Offset = 0;
+          return I->getOperand(0);
+        } else if (I->getOpcode() == Instruction::Add) {
+          // We have X+C.  Check to see if we really have (X*C2)+C1, where C1 is
+          // divisible by C2.
+          unsigned SubScale;
+          Value *SubVal = DecomposeSimpleLinearExpr(I->getOperand(0), SubScale,
+                                                    Offset);
+          Offset += CUI->getValue();
+          if (SubScale > 1 && (Offset % SubScale == 0)) {
+            Scale = SubScale;
+            return SubVal;
+          }
+        }
+      }
+    }
+  }
+
+  // Otherwise, we can't look past this.
+  Scale = 1;
+  Offset = 0;
+  return Val;
+}
+
+
+/// PromoteCastOfAllocation - If we find a cast of an allocation instruction,
+/// try to eliminate the cast by moving the type information into the alloc.
+Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,
+                                                   AllocationInst &AI) {
+  const PointerType *PTy = dyn_cast<PointerType>(CI.getType());
+  if (!PTy) return 0;   // Not casting the allocation to a pointer type.
+  
+  // Remove any uses of AI that are dead.
+  assert(!CI.use_empty() && "Dead instructions should be removed earlier!");
+  std::vector<Instruction*> DeadUsers;
+  for (Value::use_iterator UI = AI.use_begin(), E = AI.use_end(); UI != E; ) {
+    Instruction *User = cast<Instruction>(*UI++);
+    if (isInstructionTriviallyDead(User)) {
+      while (UI != E && *UI == User)
+        ++UI; // If this instruction uses AI more than once, don't break UI.
+      
+      // Add operands to the worklist.
+      AddUsesToWorkList(*User);
+      ++NumDeadInst;
+      DEBUG(std::cerr << "IC: DCE: " << *User);
+      
+      User->eraseFromParent();
+      removeFromWorkList(User);
+    }
+  }
+  
+  // Get the type really allocated and the type casted to.
+  const Type *AllocElTy = AI.getAllocatedType();
+  const Type *CastElTy = PTy->getElementType();
+  if (!AllocElTy->isSized() || !CastElTy->isSized()) return 0;
+
+  unsigned AllocElTyAlign = TD->getTypeSize(AllocElTy);
+  unsigned CastElTyAlign = TD->getTypeSize(CastElTy);
+  if (CastElTyAlign < AllocElTyAlign) return 0;
+
+  // If the allocation has multiple uses, only promote it if we are strictly
+  // increasing the alignment of the resultant allocation.  If we keep it the
+  // same, we open the door to infinite loops of various kinds.
+  if (!AI.hasOneUse() && CastElTyAlign == AllocElTyAlign) return 0;
+
+  uint64_t AllocElTySize = TD->getTypeSize(AllocElTy);
+  uint64_t CastElTySize = TD->getTypeSize(CastElTy);
+  if (CastElTySize == 0 || AllocElTySize == 0) return 0;
+
+  // See if we can satisfy the modulus by pulling a scale out of the array
+  // size argument.
+  unsigned ArraySizeScale, ArrayOffset;
+  Value *NumElements = // See if the array size is a decomposable linear expr.
+    DecomposeSimpleLinearExpr(AI.getOperand(0), ArraySizeScale, ArrayOffset);
+ 
+  // If we can now satisfy the modulus, by using a non-1 scale, we really can
+  // do the xform.
+  if ((AllocElTySize*ArraySizeScale) % CastElTySize != 0 ||
+      (AllocElTySize*ArrayOffset   ) % CastElTySize != 0) return 0;
+
+  unsigned Scale = (AllocElTySize*ArraySizeScale)/CastElTySize;
+  Value *Amt = 0;
+  if (Scale == 1) {
+    Amt = NumElements;
+  } else {
+    Amt = ConstantUInt::get(Type::UIntTy, Scale);
+    if (ConstantUInt *CI = dyn_cast<ConstantUInt>(NumElements))
+      Amt = ConstantExpr::getMul(CI, cast<ConstantUInt>(Amt));
+    else if (Scale != 1) {
+      Instruction *Tmp = BinaryOperator::createMul(Amt, NumElements, "tmp");
+      Amt = InsertNewInstBefore(Tmp, AI);
+    }
+  }
+  
+  if (unsigned Offset = (AllocElTySize*ArrayOffset)/CastElTySize) {
+    Value *Off = ConstantUInt::get(Type::UIntTy, Offset);
+    Instruction *Tmp = BinaryOperator::createAdd(Amt, Off, "tmp");
+    Amt = InsertNewInstBefore(Tmp, AI);
+  }
+  
+  std::string Name = AI.getName(); AI.setName("");
+  AllocationInst *New;
+  if (isa<MallocInst>(AI))
+    New = new MallocInst(CastElTy, Amt, AI.getAlignment(), Name);
+  else
+    New = new AllocaInst(CastElTy, Amt, AI.getAlignment(), Name);
+  InsertNewInstBefore(New, AI);
+  
+  // If the allocation has multiple uses, insert a cast and change all things
+  // that used it to use the new cast.  This will also hack on CI, but it will
+  // die soon.
+  if (!AI.hasOneUse()) {
+    AddUsesToWorkList(AI);
+    CastInst *NewCast = new CastInst(New, AI.getType(), "tmpcast");
+    InsertNewInstBefore(NewCast, AI);
+    AI.replaceAllUsesWith(NewCast);
+  }
+  return ReplaceInstUsesWith(CI, New);
+}
+
+
 // CastInst simplification
 //
 Instruction *InstCombiner::visitCastInst(CastInst &CI) {
@@ -3840,30 +4033,8 @@
   // size, rewrite the allocation instruction to allocate the "right" type.
   //
   if (AllocationInst *AI = dyn_cast<AllocationInst>(Src))
-    if (AI->hasOneUse() && !AI->isArrayAllocation())
-      if (const PointerType *PTy = dyn_cast<PointerType>(CI.getType())) {
-        // Get the type really allocated and the type casted to...
-        const Type *AllocElTy = AI->getAllocatedType();
-        const Type *CastElTy = PTy->getElementType();
-        if (AllocElTy->isSized() && CastElTy->isSized()) {
-          uint64_t AllocElTySize = TD->getTypeSize(AllocElTy);
-          uint64_t CastElTySize = TD->getTypeSize(CastElTy);
-
-          // If the allocation is for an even multiple of the cast type size
-          if (CastElTySize && (AllocElTySize % CastElTySize == 0)) {
-            Value *Amt = ConstantUInt::get(Type::UIntTy,
-                                         AllocElTySize/CastElTySize);
-            std::string Name = AI->getName(); AI->setName("");
-            AllocationInst *New;
-            if (isa<MallocInst>(AI))
-              New = new MallocInst(CastElTy, Amt, Name);
-            else
-              New = new AllocaInst(CastElTy, Amt, Name);
-            InsertNewInstBefore(New, *AI);
-            return ReplaceInstUsesWith(CI, New);
-          }
-        }
-      }
+    if (Instruction *V = PromoteCastOfAllocation(CI, *AI))
+      return V;
 
   if (SelectInst *SI = dyn_cast<SelectInst>(Src))
     if (Instruction *NV = FoldOpIntoSelect(CI, SI, this))
@@ -4005,6 +4176,7 @@
         break;
       }
     }
+      
   return 0;
 }
 
@@ -5095,10 +5267,10 @@
 
       // Create and insert the replacement instruction...
       if (isa<MallocInst>(AI))
-        New = new MallocInst(NewTy, 0, AI.getName());
+        New = new MallocInst(NewTy, 0, AI.getAlignment(), AI.getName());
       else {
         assert(isa<AllocaInst>(AI) && "Unknown type of allocation inst!");
-        New = new AllocaInst(NewTy, 0, AI.getName());
+        New = new AllocaInst(NewTy, 0, AI.getAlignment(), AI.getName());
       }
 
       InsertNewInstBefore(New, AI);
@@ -5597,7 +5769,6 @@
   return 0;
 }
 
-
 void InstCombiner::removeFromWorkList(Instruction *I) {
   WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I),
                  WorkList.end());
@@ -5611,8 +5782,8 @@
 static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
   assert(I->hasOneUse() && "Invariants didn't hold!");
 
-  // Cannot move control-flow-involving instructions.
-  if (isa<PHINode>(I) || isa<InvokeInst>(I) || isa<CallInst>(I)) return false;
+  // Cannot move control-flow-involving, volatile loads, vaarg, etc.
+  if (isa<PHINode>(I) || I->mayWriteToMemory()) return false;
 
   // Do not sink alloca instructions out of the entry block.
   if (isa<AllocaInst>(I) && I->getParent() == &DestBlock->getParent()->front())
@@ -5621,8 +5792,6 @@
   // We can only sink load instructions if there is nothing between the load and
   // the end of block that could change the value.
   if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
-    if (LI->isVolatile()) return false;  // Don't sink volatile loads.
-
     for (BasicBlock::iterator Scan = LI, E = LI->getParent()->end();
          Scan != E; ++Scan)
       if (Scan->mayWriteToMemory())


Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.68 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.68.2.1
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.68	Tue Oct 11 13:41:04 2005
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp	Wed Nov 16 12:32:53 2005
@@ -372,7 +372,8 @@
 /// return true.  Otherwise, return false.
 bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L,
                                             std::set<Instruction*> &Processed) {
-  if (I->getType() == Type::VoidTy) return false;
+  if (!I->getType()->isInteger() && !isa<PointerType>(I->getType()))
+      return false;   // Void and FP expressions cannot be reduced.
   if (!Processed.insert(I).second)
     return true;    // Instruction already handled.
   


Index: llvm/lib/Transforms/Scalar/LowerAllocations.cpp
diff -u llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.54 llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.54.4.1
--- llvm/lib/Transforms/Scalar/LowerAllocations.cpp:1.54	Fri May  6 01:48:21 2005
+++ llvm/lib/Transforms/Scalar/LowerAllocations.cpp	Wed Nov 16 12:32:53 2005
@@ -83,7 +83,7 @@
     MallocFunc = M.getOrInsertFunction("malloc", FT);
   }
   if (FreeFunc == 0)
-    FreeFunc = M.getOrInsertFunction("free"  , Type::VoidTy, SBPTy, 0);
+    FreeFunc = M.getOrInsertFunction("free"  , Type::VoidTy, SBPTy, (Type *)0);
 
   return true;
 }


Index: llvm/lib/Transforms/Scalar/LowerGC.cpp
diff -u llvm/lib/Transforms/Scalar/LowerGC.cpp:1.8 llvm/lib/Transforms/Scalar/LowerGC.cpp:1.8.4.1
--- llvm/lib/Transforms/Scalar/LowerGC.cpp:1.8	Thu Apr 21 18:45:12 2005
+++ llvm/lib/Transforms/Scalar/LowerGC.cpp	Wed Nov 16 12:32:53 2005
@@ -109,10 +109,11 @@
   // If the program is using read/write barriers, find the implementations of
   // them from the GC runtime library.
   if (GCReadInt)        // Make:  sbyte* %llvm_gc_read(sbyte**)
-    GCRead = M.getOrInsertFunction("llvm_gc_read", VoidPtr, VoidPtr, VoidPtrPtr, 0);
+    GCRead = M.getOrInsertFunction("llvm_gc_read", VoidPtr, VoidPtr, VoidPtrPtr,
+                                   (Type *)0);
   if (GCWriteInt)       // Make:  void %llvm_gc_write(sbyte*, sbyte**)
     GCWrite = M.getOrInsertFunction("llvm_gc_write", Type::VoidTy,
-                                    VoidPtr, VoidPtr, VoidPtrPtr, 0);
+                                    VoidPtr, VoidPtr, VoidPtrPtr, (Type *)0);
 
   // If the program has GC roots, get or create the global root list.
   if (GCRootInt) {


Index: llvm/lib/Transforms/Scalar/LowerInvoke.cpp
diff -u llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.33 llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.33.2.1
--- llvm/lib/Transforms/Scalar/LowerInvoke.cpp:1.33	Fri Sep 30 22:57:14 2005
+++ llvm/lib/Transforms/Scalar/LowerInvoke.cpp	Wed Nov 16 12:32:53 2005
@@ -67,6 +67,8 @@
     GlobalVariable *JBListHead;
     Function *SetJmpFn, *LongJmpFn;
   public:
+    LowerInvoke(unsigned Size = 200, unsigned Align = 0) : JumpBufSize(Size),
+      JumpBufAlign(Align) {}
     bool doInitialization(Module &M);
     bool runOnFunction(Function &F);
     
@@ -78,6 +80,9 @@
     void rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo,
                                 AllocaInst *InvokeNum, SwitchInst *CatchSwitch);
     bool insertExpensiveEHSupport(Function &F);
+    
+    unsigned JumpBufSize;
+    unsigned JumpBufAlign;
   };
 
   RegisterOpt<LowerInvoke>
@@ -87,7 +92,10 @@
 const PassInfo *llvm::LowerInvokePassID = X.getPassInfo();
 
 // Public Interface To the LowerInvoke pass.
-FunctionPass *llvm::createLowerInvokePass() { return new LowerInvoke(); }
+FunctionPass *llvm::createLowerInvokePass(unsigned JumpBufSize, 
+                                          unsigned JumpBufAlign) { 
+  return new LowerInvoke(JumpBufSize, JumpBufAlign); 
+}
 
 // doInitialization - Make sure that there is a prototype for abort in the
 // current module.
@@ -95,13 +103,8 @@
   const Type *VoidPtrTy = PointerType::get(Type::SByteTy);
   AbortMessage = 0;
   if (ExpensiveEHSupport) {
-    // Insert a type for the linked list of jump buffers.  Unfortunately, we
-    // don't know the size of the target's setjmp buffer, so we make a guess.
-    // If this guess turns out to be too small, bad stuff could happen.
-    unsigned JmpBufSize = 200;  // PPC has 192 words
-    assert(sizeof(jmp_buf) <= JmpBufSize*sizeof(void*) &&
-       "LowerInvoke doesn't know about targets with jmp_buf size > 200 words!");
-    const Type *JmpBufTy = ArrayType::get(VoidPtrTy, JmpBufSize);
+    // Insert a type for the linked list of jump buffers.
+    const Type *JmpBufTy = ArrayType::get(VoidPtrTy, JumpBufSize);
 
     { // The type is recursive, so use a type holder.
       std::vector<const Type*> Elements;
@@ -124,14 +127,14 @@
                                       Constant::getNullValue(PtrJBList),
                                       "llvm.sjljeh.jblist", &M);
     SetJmpFn = M.getOrInsertFunction("llvm.setjmp", Type::IntTy,
-                                     PointerType::get(JmpBufTy), NULL);
+                                     PointerType::get(JmpBufTy), (Type *)0);
     LongJmpFn = M.getOrInsertFunction("llvm.longjmp", Type::VoidTy,
                                       PointerType::get(JmpBufTy),
-                                      Type::IntTy, NULL);
+                                      Type::IntTy, (Type *)0);
   }
 
   // We need the 'write' and 'abort' functions for both models.
-  AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, NULL);
+  AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, (Type *)0);
 
   // Unfortunately, 'write' can end up being prototyped in several different
   // ways.  If the user defines a three (or more) operand function named 'write'
@@ -148,7 +151,7 @@
       WriteFn = 0;
   } else {
     WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy,
-                                    VoidPtrTy, Type::IntTy, NULL);
+                                    VoidPtrTy, Type::IntTy, (Type *)0);
   }
   return true;
 }
@@ -441,7 +444,7 @@
     // that needs to be restored on all exits from the function.  This is an
     // alloca because the value needs to be live across invokes.
     AllocaInst *JmpBuf = 
-      new AllocaInst(JBLinkTy, 0, "jblink", F.begin()->begin());
+      new AllocaInst(JBLinkTy, 0, JumpBufAlign, "jblink", F.begin()->begin());
     
     std::vector<Value*> Idx;
     Idx.push_back(Constant::getNullValue(Type::IntTy));


Index: llvm/lib/Transforms/Scalar/Makefile
diff -u llvm/lib/Transforms/Scalar/Makefile:1.4 llvm/lib/Transforms/Scalar/Makefile:1.4.6.1
--- llvm/lib/Transforms/Scalar/Makefile:1.4	Wed Oct 27 18:18:45 2004
+++ llvm/lib/Transforms/Scalar/Makefile	Wed Nov 16 12:32:53 2005
@@ -6,6 +6,7 @@
 # the University of Illinois Open Source License. See LICENSE.TXT for details.
 # 
 ##===----------------------------------------------------------------------===##
+
 LEVEL = ../../..
 LIBRARYNAME = LLVMScalarOpts
 BUILD_ARCHIVE = 1


Index: llvm/lib/Transforms/Scalar/Reg2Mem.cpp
diff -c /dev/null llvm/lib/Transforms/Scalar/Reg2Mem.cpp:1.3.2.2
*** /dev/null	Wed Nov 16 12:33:05 2005
--- llvm/lib/Transforms/Scalar/Reg2Mem.cpp	Wed Nov 16 12:32:53 2005
***************
*** 0 ****
--- 1,81 ----
+ //===- Reg2Mem.cpp - Convert registers to allocas -------------------------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file demotes all registers to memory references.  It is intented to be
+ // the inverse of PromoteMemoryToRegister.  By converting to loads, the only
+ // values live accross basic blocks are allocas and loads before phi nodes.
+ // It is intended that this should make CFG hacking much easier.
+ // To make later hacking easier, the entry block is split into two, such that
+ // all introduced allocas and nothing else are in the entry block.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/Transforms/Scalar.h"
+ #include "llvm/Transforms/Utils/Local.h"
+ #include "llvm/Pass.h"
+ #include "llvm/Function.h"
+ #include "llvm/Module.h"
+ #include "llvm/BasicBlock.h"
+ #include "llvm/Instructions.h"
+ #include "llvm/ADT/Statistic.h"
+ 
+ #include <list>
+ 
+ using namespace llvm;
+ 
+ namespace {
+   Statistic<> NumDemoted("reg2mem", "Number of registers demoted");
+   
+   struct RegToMem : public FunctionPass {
+ 
+    bool valueEscapes(Instruction* i) {
+       BasicBlock* bb = i->getParent();
+       for(Value::use_iterator ii = i->use_begin(), ie = i->use_end();
+           ii != ie; ++ii)
+         if (cast<Instruction>(*ii)->getParent() != bb ||
+ 	    isa<PHINode>(*ii))
+           return true;
+       return false;
+     }
+ 
+     virtual bool runOnFunction(Function &F) {
+       if (!F.isExternal()) {
+         //give us a clean block
+ 	BasicBlock* bbold = &F.getEntryBlock();
+ 	BasicBlock* bbnew = new BasicBlock("allocablock", &F, &F.getEntryBlock());
+ 	new BranchInst(bbold, bbnew);
+ 
+         //find the instructions
+         std::list<Instruction*> worklist;
+         for (Function::iterator ibb = F.begin(), ibe = F.end();
+              ibb != ibe; ++ibb)
+           for (BasicBlock::iterator iib = ibb->begin(), iie = ibb->end();
+                iib != iie; ++iib) {
+             if(valueEscapes(iib))
+               worklist.push_front(&*iib);
+           }
+         //demote escaped instructions
+         NumDemoted += worklist.size();
+         for (std::list<Instruction*>::iterator ilb = worklist.begin(), 
+                ile = worklist.end(); ilb != ile; ++ilb)
+           DemoteRegToStack(**ilb, false);
+         return true;
+       }
+       return false;
+     }
+   };
+   
+   RegisterOpt<RegToMem> X("reg2mem", "Demote all values to stack slots");
+ }
+ 
+ // createDemoteRegisterToMemory - Provide an entry point to create this pass.
+ //
+ FunctionPass *llvm::createDemoteRegisterToMemoryPass() {
+   return new RegToMem();
+ }


Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.31 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.31.4.1
--- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.31	Thu Apr 21 18:45:12 2005
+++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp	Wed Nov 16 12:32:53 2005
@@ -159,7 +159,8 @@
     if (const StructType *ST = dyn_cast<StructType>(AI->getAllocatedType())) {
       ElementAllocas.reserve(ST->getNumContainedTypes());
       for (unsigned i = 0, e = ST->getNumContainedTypes(); i != e; ++i) {
-        AllocaInst *NA = new AllocaInst(ST->getContainedType(i), 0,
+        AllocaInst *NA = new AllocaInst(ST->getContainedType(i), 0, 
+                                        AI->getAlignment(),
                                         AI->getName() + "." + utostr(i), AI);
         ElementAllocas.push_back(NA);
         WorkList.push_back(NA);  // Add to worklist for recursive processing
@@ -169,7 +170,7 @@
       ElementAllocas.reserve(AT->getNumElements());
       const Type *ElTy = AT->getElementType();
       for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
-        AllocaInst *NA = new AllocaInst(ElTy, 0,
+        AllocaInst *NA = new AllocaInst(ElTy, 0, AI->getAlignment(),
                                         AI->getName() + "." + utostr(i), AI);
         ElementAllocas.push_back(NA);
         WorkList.push_back(NA);  // Add to worklist for recursive processing


Index: llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
diff -u llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp:1.21 llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp:1.21.2.1
--- llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp:1.21	Mon Aug  8 14:11:57 2005
+++ llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp	Wed Nov 16 12:32:53 2005
@@ -342,6 +342,7 @@
   // constant, return the value returned by the tail call, or that are being
   // accumulator recursion variable eliminated.
   if (Ret->getNumOperands() != 0 && Ret->getReturnValue() != CI &&
+      !isa<UndefValue>(Ret->getReturnValue()) &&
       AccumulatorRecursionEliminationInitVal == 0 &&
       !getCommonReturnValue(Ret, CI))
     return false;






More information about the llvm-commits mailing list