[llvm-commits] [llvm] r97178 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll
Daniel Dunbar
daniel at zuster.org
Thu Feb 25 17:23:49 PST 2010
This test is missing a RUN line.
On Thu, Feb 25, 2010 at 2:33 PM, Chris Lattner <sabre at nondot.org> wrote:
> Author: lattner
> Date: Thu Feb 25 16:33:52 2010
> New Revision: 97178
>
> URL: http://llvm.org/viewvc/llvm-project?rev=97178&view=rev
> Log:
> rewrite OptimizeGlobalAddressOfMalloc to fix PR6422, some bugs
> introduced when mallocinst was eliminated.
>
> Added:
> llvm/trunk/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll
> Modified:
> llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
>
> Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=97178&r1=97177&r2=97178&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
> +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Feb 25 16:33:52 2010
> @@ -813,55 +813,49 @@
> static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
> CallInst *CI,
> const Type *AllocTy,
> - Value* NElems,
> + ConstantInt *NElements,
> TargetData* TD) {
> - DEBUG(dbgs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI << '\n');
> -
> - const Type *IntPtrTy = TD->getIntPtrType(GV->getContext());
> + DEBUG(errs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI << '\n');
>
> - // CI has either 0 or 1 bitcast uses (getMallocType() would otherwise have
> - // returned NULL and we would not be here).
> - BitCastInst *BCI = NULL;
> - for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end(); UI != E; )
> - if ((BCI = dyn_cast<BitCastInst>(cast<Instruction>(*UI++))))
> - break;
> -
> - ConstantInt *NElements = cast<ConstantInt>(NElems);
> - if (NElements->getZExtValue() != 1) {
> - // If we have an array allocation, transform it to a single element
> - // allocation to make the code below simpler.
> - Type *NewTy = ArrayType::get(AllocTy, NElements->getZExtValue());
> - unsigned TypeSize = TD->getTypeAllocSize(NewTy);
> - if (const StructType *ST = dyn_cast<StructType>(NewTy))
> - TypeSize = TD->getStructLayout(ST)->getSizeInBytes();
> - Instruction *NewCI = CallInst::CreateMalloc(CI, IntPtrTy, NewTy,
> - ConstantInt::get(IntPtrTy, TypeSize));
> - Value* Indices[2];
> - Indices[0] = Indices[1] = Constant::getNullValue(IntPtrTy);
> - Value *NewGEP = GetElementPtrInst::Create(NewCI, Indices, Indices + 2,
> - NewCI->getName()+".el0", CI);
> - Value *Cast = new BitCastInst(NewGEP, CI->getType(), "el0", CI);
> - if (BCI) BCI->replaceAllUsesWith(NewGEP);
> - CI->replaceAllUsesWith(Cast);
> - if (BCI) BCI->eraseFromParent();
> - CI->eraseFromParent();
> - BCI = dyn_cast<BitCastInst>(NewCI);
> - CI = BCI ? extractMallocCallFromBitCast(BCI) : cast<CallInst>(NewCI);
> - }
> + const Type *GlobalType;
> + if (NElements->getZExtValue() == 1)
> + GlobalType = AllocTy;
> + else
> + // If we have an array allocation, the global variable is of an array.
> + GlobalType = ArrayType::get(AllocTy, NElements->getZExtValue());
>
> // Create the new global variable. The contents of the malloc'd memory is
> // undefined, so initialize with an undef value.
> const Type *MAT = getMallocAllocatedType(CI);
> - Constant *Init = UndefValue::get(MAT);
> GlobalVariable *NewGV = new GlobalVariable(*GV->getParent(),
> MAT, false,
> - GlobalValue::InternalLinkage, Init,
> + GlobalValue::InternalLinkage,
> + UndefValue::get(MAT),
> GV->getName()+".body",
> GV,
> GV->isThreadLocal());
>
> - // Anything that used the malloc or its bitcast now uses the global directly.
> - if (BCI) BCI->replaceAllUsesWith(NewGV);
> + // If there are bitcast users of the malloc (which is typical, usually we have
> + // a malloc + bitcast) then replace them with uses of the new global. Update
> + // other users to use the global as well.
> + BitCastInst *TheBC = 0;
> + while (!CI->use_empty()) {
> + Instruction *User = cast<Instruction>(CI->use_back());
> + if (BitCastInst *BCI = dyn_cast<BitCastInst>(User)) {
> + if (BCI->getType() == NewGV->getType()) {
> + BCI->replaceAllUsesWith(NewGV);
> + BCI->eraseFromParent();
> + } else {
> + BCI->setOperand(0, NewGV);
> + }
> + } else {
> + if (TheBC == 0)
> + TheBC = new BitCastInst(NewGV, CI->getType(), "newgv", CI);
> + User->replaceUsesOfWith(CI, TheBC);
> + }
> + }
> +
> + // Update Anything else that used the malloc or its bitcast now uses the global directly.
> CI->replaceAllUsesWith(new BitCastInst(NewGV, CI->getType(), "newgv", CI));
>
> Constant *RepValue = NewGV;
> @@ -879,60 +873,60 @@
> bool InitBoolUsed = false;
>
> // Loop over all uses of GV, processing them in turn.
> - std::vector<StoreInst*> Stores;
> - while (!GV->use_empty())
> - if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
> - while (!LI->use_empty()) {
> - Use &LoadUse = LI->use_begin().getUse();
> - if (!isa<ICmpInst>(LoadUse.getUser()))
> - LoadUse = RepValue;
> - else {
> - ICmpInst *ICI = cast<ICmpInst>(LoadUse.getUser());
> - // Replace the cmp X, 0 with a use of the bool value.
> - Value *LV = new LoadInst(InitBool, InitBool->getName()+".val", ICI);
> - InitBoolUsed = true;
> - switch (ICI->getPredicate()) {
> - default: llvm_unreachable("Unknown ICmp Predicate!");
> - case ICmpInst::ICMP_ULT:
> - case ICmpInst::ICMP_SLT: // X < null -> always false
> - LV = ConstantInt::getFalse(GV->getContext());
> - break;
> - case ICmpInst::ICMP_ULE:
> - case ICmpInst::ICMP_SLE:
> - case ICmpInst::ICMP_EQ:
> - LV = BinaryOperator::CreateNot(LV, "notinit", ICI);
> - break;
> - case ICmpInst::ICMP_NE:
> - case ICmpInst::ICMP_UGE:
> - case ICmpInst::ICMP_SGE:
> - case ICmpInst::ICMP_UGT:
> - case ICmpInst::ICMP_SGT:
> - break; // no change.
> - }
> - ICI->replaceAllUsesWith(LV);
> - ICI->eraseFromParent();
> - }
> - }
> - LI->eraseFromParent();
> - } else {
> - StoreInst *SI = cast<StoreInst>(GV->use_back());
> + while (!GV->use_empty()) {
> + if (StoreInst *SI = dyn_cast<StoreInst>(GV->use_back())) {
> // The global is initialized when the store to it occurs.
> new StoreInst(ConstantInt::getTrue(GV->getContext()), InitBool, SI);
> SI->eraseFromParent();
> + continue;
> }
> +
> + LoadInst *LI = cast<LoadInst>(GV->use_back());
> + while (!LI->use_empty()) {
> + Use &LoadUse = LI->use_begin().getUse();
> + if (!isa<ICmpInst>(LoadUse.getUser())) {
> + LoadUse = RepValue;
> + continue;
> + }
> +
> + ICmpInst *ICI = cast<ICmpInst>(LoadUse.getUser());
> + // Replace the cmp X, 0 with a use of the bool value.
> + Value *LV = new LoadInst(InitBool, InitBool->getName()+".val", ICI);
> + InitBoolUsed = true;
> + switch (ICI->getPredicate()) {
> + default: llvm_unreachable("Unknown ICmp Predicate!");
> + case ICmpInst::ICMP_ULT:
> + case ICmpInst::ICMP_SLT: // X < null -> always false
> + LV = ConstantInt::getFalse(GV->getContext());
> + break;
> + case ICmpInst::ICMP_ULE:
> + case ICmpInst::ICMP_SLE:
> + case ICmpInst::ICMP_EQ:
> + LV = BinaryOperator::CreateNot(LV, "notinit", ICI);
> + break;
> + case ICmpInst::ICMP_NE:
> + case ICmpInst::ICMP_UGE:
> + case ICmpInst::ICMP_SGE:
> + case ICmpInst::ICMP_UGT:
> + case ICmpInst::ICMP_SGT:
> + break; // no change.
> + }
> + ICI->replaceAllUsesWith(LV);
> + ICI->eraseFromParent();
> + }
> + LI->eraseFromParent();
> + }
>
> // If the initialization boolean was used, insert it, otherwise delete it.
> if (!InitBoolUsed) {
> while (!InitBool->use_empty()) // Delete initializations
> - cast<Instruction>(InitBool->use_back())->eraseFromParent();
> + cast<StoreInst>(InitBool->use_back())->eraseFromParent();
> delete InitBool;
> } else
> GV->getParent()->getGlobalList().insert(GV, InitBool);
>
> -
> - // Now the GV is dead, nuke it and the malloc (both CI and BCI).
> + // Now the GV is dead, nuke it and the malloc..
> GV->eraseFromParent();
> - if (BCI) BCI->eraseFromParent();
> CI->eraseFromParent();
>
> // To further other optimizations, loop over all users of NewGV and try to
> @@ -1497,7 +1491,7 @@
> // something.
> if (TD &&
> NElements->getZExtValue() * TD->getTypeAllocSize(AllocTy) < 2048) {
> - GVI = OptimizeGlobalAddressOfMalloc(GV, CI, AllocTy, NElems, TD);
> + GVI = OptimizeGlobalAddressOfMalloc(GV, CI, AllocTy, NElements, TD);
> return true;
> }
>
>
> Added: llvm/trunk/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll?rev=97178&view=auto
> ==============================================================================
> --- llvm/trunk/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll (added)
> +++ llvm/trunk/test/Transforms/GlobalOpt/2010-02-25-MallocPromote.ll Thu Feb 25 16:33:52 2010
> @@ -0,0 +1,17 @@
> +; PR6422
> +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
> +target triple = "x86_64-unknown-linux-gnu"
> +
> + at fixLRBT = internal global i32* null ; <i32**> [#uses=2]
> +
> +declare noalias i8* @malloc(i32)
> +
> +define i32 @parser() nounwind {
> +bb918:
> + %malloccall.i10 = call i8* @malloc(i32 16) nounwind ; <i8*> [#uses=1]
> + %0 = bitcast i8* %malloccall.i10 to i32* ; <i32*> [#uses=1]
> + store i32* %0, i32** @fixLRBT, align 8
> + %1 = load i32** @fixLRBT, align 8 ; <i32*> [#uses=0]
> + %A = load i32* %1
> + ret i32 %A
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list