diff options
Diffstat (limited to 'lib/Transforms/IPO/GlobalOpt.cpp')
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 174 |
1 files changed, 81 insertions, 93 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index df060eb..7b1e9c0 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -303,7 +303,7 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) { SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE); Changed |= CleanupConstantGlobalUsers(CE, SubInit); } else if (CE->getOpcode() == Instruction::BitCast && - isa<PointerType>(CE->getType())) { + CE->getType()->isPointerTy()) { // Pointer cast, delete any stores and memsets to the global. Changed |= CleanupConstantGlobalUsers(CE, 0); } @@ -431,7 +431,7 @@ static bool IsUserOfGlobalSafeForSRA(User *U, GlobalValue *GV) { else if (const VectorType *SubVectorTy = dyn_cast<VectorType>(*GEPI)) NumElements = SubVectorTy->getNumElements(); else { - assert(isa<StructType>(*GEPI) && + assert((*GEPI)->isStructTy() && "Indexed GEP type is not array, vector, or struct!"); continue; } @@ -543,7 +543,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD) { if (NewGlobals.empty()) return 0; - + DEBUG(dbgs() << "PERFORMING GLOBAL SRA ON: " << *GV); Constant *NullInt =Constant::getNullValue(Type::getInt32Ty(GV->getContext())); @@ -642,7 +642,7 @@ static bool AllUsesOfValueWillTrapIfNull(Value *V, return false; } else if (isa<ICmpInst>(*UI) && isa<ConstantPointerNull>(UI->getOperand(1))) { - // Ignore setcc X, null + // Ignore icmp X, null } else { //cerr << "NONTRAPPING USE: " << **UI; return false; @@ -813,57 +813,47 @@ static void ConstantPropUsersOf(Value *V) { 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, + GlobalType, false, + GlobalValue::InternalLinkage, + UndefValue::get(GlobalType), GV->getName()+".body", GV, GV->isThreadLocal()); - // Anything that used the malloc or its bitcast now uses the global directly. - if (BCI) BCI->replaceAllUsesWith(NewGV); - CI->replaceAllUsesWith(new BitCastInst(NewGV, CI->getType(), "newgv", CI)); - + // 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); + } + } + Constant *RepValue = NewGV; if (NewGV->getType() != GV->getType()->getElementType()) RepValue = ConstantExpr::getBitCast(RepValue, @@ -879,60 +869,60 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, 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 @@ -1303,9 +1293,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI, ConstantInt::get(IntPtrTy, TypeSize), NElems, CI->getName() + ".f" + Twine(FieldNo)); - CallInst *NCI = dyn_cast<BitCastInst>(NMI) ? - extractMallocCallFromBitCast(NMI) : cast<CallInst>(NMI); - FieldMallocs.push_back(NCI); + FieldMallocs.push_back(NMI); new StoreInst(NMI, NGV, CI); } @@ -1497,7 +1485,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, // 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; } @@ -1556,7 +1544,7 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal, // only has one (non-null) value stored into it, then we can optimize any // users of the loaded value (often calls and loads) that would trap if the // value was null. - if (isa<PointerType>(GV->getInitializer()->getType()) && + if (GV->getInitializer()->getType()->isPointerTy() && GV->getInitializer()->isNullValue()) { if (Constant *SOVC = dyn_cast<Constant>(StoredOnceVal)) { if (GV->getInitializer()->getType() != SOVC->getType()) @@ -1591,7 +1579,7 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) { // where v1 and v2 both require constant pool loads, a big loss. if (GVElType == Type::getInt1Ty(GV->getContext()) || GVElType->isFloatingPointTy() || - isa<PointerType>(GVElType) || isa<VectorType>(GVElType)) + GVElType->isPointerTy() || GVElType->isVectorTy()) return false; // Walk the use list of the global seeing if all the uses are load or store. @@ -2148,7 +2136,7 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, Elts[CI->getZExtValue()] = EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1); - if (isa<ArrayType>(Init->getType())) + if (Init->getType()->isArrayTy()) return ConstantArray::get(cast<ArrayType>(InitTy), Elts); else return ConstantVector::get(&Elts[0], Elts.size()); |