[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