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; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits