X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FGlobalOpt.cpp;h=b995a3d2864da9726a336449dfa994d092a4744c;hb=80bdc967e946b5d68646ffdee857400f9a120cca;hp=82af99a7f999c9b76d7f1369d66282840da3ac4f;hpb=4ae5126d041768ab9665cf2f11c024becd76c41f;p=oota-llvm.git diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 82af99a7f99..b995a3d2864 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -58,7 +58,6 @@ STATISTIC(NumAliasesRemoved, "Number of global aliases eliminated"); namespace { struct VISIBILITY_HIDDEN GlobalOpt : public ModulePass { virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); } static char ID; // Pass identification, replacement for typeid GlobalOpt() : ModulePass(&ID) {} @@ -427,13 +426,18 @@ static bool IsUserOfGlobalSafeForSRA(User *U, GlobalValue *GV) { // Scalar replacing *just* the outer index of the array is probably not // going to be a win anyway, so just give up. for (++GEPI; // Skip array index. - GEPI != E && (isa(*GEPI) || isa(*GEPI)); + GEPI != E; ++GEPI) { uint64_t NumElements; if (const ArrayType *SubArrayTy = dyn_cast(*GEPI)) NumElements = SubArrayTy->getNumElements(); - else - NumElements = cast(*GEPI)->getNumElements(); + else if (const VectorType *SubVectorTy = dyn_cast(*GEPI)) + NumElements = SubVectorTy->getNumElements(); + else { + assert(isa(*GEPI) && + "Indexed GEP type is not array, vector, or struct!"); + continue; + } ConstantInt *IdxVal = dyn_cast(GEPI.getOperand()); if (!IdxVal || IdxVal->getZExtValue() >= NumElements) @@ -488,7 +492,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD, const StructLayout &Layout = *TD.getStructLayout(STy); for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { Constant *In = getAggregateConstantElement(Init, - ConstantInt::get(Type::Int32Ty, i), + ConstantInt::get(Type::getInt32Ty(Context), i), Context); assert(In && "Couldn't get element of initializer?"); GlobalVariable *NGV = new GlobalVariable(Context, @@ -523,7 +527,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD, unsigned EltAlign = TD.getABITypeAlignment(STy->getElementType()); for (unsigned i = 0, e = NumElements; i != e; ++i) { Constant *In = getAggregateConstantElement(Init, - ConstantInt::get(Type::Int32Ty, i), + ConstantInt::get(Type::getInt32Ty(Context), i), Context); assert(In && "Couldn't get element of initializer?"); @@ -548,9 +552,9 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD, if (NewGlobals.empty()) return 0; - DOUT << "PERFORMING GLOBAL SRA ON: " << *GV; + DEBUG(errs() << "PERFORMING GLOBAL SRA ON: " << *GV); - Constant *NullInt = Constant::getNullValue(Type::Int32Ty); + Constant *NullInt = Constant::getNullValue(Type::getInt32Ty(Context)); // Loop over all of the uses of the global, replacing the constantexpr geps, // with smaller constantexpr geps or direct references. @@ -777,14 +781,14 @@ static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV, } if (Changed) { - DOUT << "OPTIMIZED LOADS FROM STORED ONCE POINTER: " << *GV; + DEBUG(errs() << "OPTIMIZED LOADS FROM STORED ONCE POINTER: " << *GV); ++NumGlobUses; } // If we nuked all of the loads, then none of the stores are needed either, // nor is the global. if (AllNonStoreUsesGone) { - DOUT << " *** GLOBAL NOW DEAD!\n"; + DEBUG(errs() << " *** GLOBAL NOW DEAD!\n"); CleanupConstantGlobalUsers(GV, 0, Context); if (GV->use_empty()) { GV->eraseFromParent(); @@ -819,7 +823,7 @@ static void ConstantPropUsersOf(Value *V, LLVMContext &Context) { static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, MallocInst *MI, LLVMContext &Context) { - DOUT << "PROMOTING MALLOC GLOBAL: " << *GV << " MALLOC = " << *MI; + DEBUG(errs() << "PROMOTING MALLOC GLOBAL: " << *GV << " MALLOC = " << *MI); ConstantInt *NElements = cast(MI->getArraySize()); if (NElements->getZExtValue() != 1) { @@ -828,10 +832,10 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, Type *NewTy = ArrayType::get(MI->getAllocatedType(), NElements->getZExtValue()); MallocInst *NewMI = - new MallocInst(NewTy, Constant::getNullValue(Type::Int32Ty), + new MallocInst(NewTy, Constant::getNullValue(Type::getInt32Ty(Context)), MI->getAlignment(), MI->getName(), MI); Value* Indices[2]; - Indices[0] = Indices[1] = Constant::getNullValue(Type::Int32Ty); + Indices[0] = Indices[1] = Constant::getNullValue(Type::getInt32Ty(Context)); Value *NewGEP = GetElementPtrInst::Create(NewMI, Indices, Indices + 2, NewMI->getName()+".el0", MI); MI->replaceAllUsesWith(NewGEP); @@ -863,7 +867,7 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, // If there is a comparison against null, we will insert a global bool to // keep track of whether the global was initialized yet or not. GlobalVariable *InitBool = - new GlobalVariable(Context, Type::Int1Ty, false, + new GlobalVariable(Context, Type::getInt1Ty(Context), false, GlobalValue::InternalLinkage, ConstantInt::getFalse(Context), GV->getName()+".init", GV->isThreadLocal()); @@ -1265,7 +1269,7 @@ static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Load, /// it up into multiple allocations of arrays of the fields. static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI, LLVMContext &Context){ - DOUT << "SROA HEAP ALLOC: " << *GV << " MALLOC = " << *MI; + DEBUG(errs() << "SROA HEAP ALLOC: " << *GV << " MALLOC = " << *MI); const StructType *STy = cast(MI->getAllocatedType()); // There is guaranteed to be at least one use of the malloc (storing @@ -1326,7 +1330,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI, // Create the block to check the first condition. Put all these blocks at the // end of the function as they are unlikely to be executed. - BasicBlock *NullPtrBlock = BasicBlock::Create("malloc_ret_null", + BasicBlock *NullPtrBlock = BasicBlock::Create(Context, "malloc_ret_null", OrigBB->getParent()); // Remove the uncond branch from OrigBB to ContBB, turning it into a cond @@ -1341,8 +1345,10 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI, Value *Cmp = new ICmpInst(*NullPtrBlock, ICmpInst::ICMP_NE, GVVal, Constant::getNullValue(GVVal->getType()), "tmp"); - BasicBlock *FreeBlock = BasicBlock::Create("free_it", OrigBB->getParent()); - BasicBlock *NextBlock = BasicBlock::Create("next", OrigBB->getParent()); + BasicBlock *FreeBlock = BasicBlock::Create(Context, "free_it", + OrigBB->getParent()); + BasicBlock *NextBlock = BasicBlock::Create(Context, "next", + OrigBB->getParent()); BranchInst::Create(FreeBlock, NextBlock, Cmp, NullPtrBlock); // Fill in FreeBlock. @@ -1444,7 +1450,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI, static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, MallocInst *MI, Module::global_iterator &GVI, - TargetData &TD, + TargetData *TD, LLVMContext &Context) { // If this is a malloc of an abstract type, don't touch it. if (!MI->getAllocatedType()->isSized()) @@ -1479,8 +1485,9 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, // Restrict this transformation to only working on small allocations // (2048 bytes currently), as we don't want to introduce a 16M global or // something. - if (NElements->getZExtValue()* - TD.getTypeAllocSize(MI->getAllocatedType()) < 2048) { + if (TD && + NElements->getZExtValue()* + TD->getTypeAllocSize(MI->getAllocatedType()) < 2048) { GVI = OptimizeGlobalAddressOfMalloc(GV, MI, Context); return true; } @@ -1508,7 +1515,8 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, if (const ArrayType *AT = dyn_cast(MI->getAllocatedType())) { MallocInst *NewMI = new MallocInst(AllocSTy, - ConstantInt::get(Type::Int32Ty, AT->getNumElements()), + ConstantInt::get(Type::getInt32Ty(Context), + AT->getNumElements()), "", MI); NewMI->takeName(MI); Value *Cast = new BitCastInst(NewMI, MI->getType(), "tmp", MI); @@ -1529,7 +1537,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, // that only one value (besides its initializer) is ever stored to the global. static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal, Module::global_iterator &GVI, - TargetData &TD, LLVMContext &Context) { + TargetData *TD, LLVMContext &Context) { // Ignore no-op GEPs and bitcasts. StoredOnceVal = StoredOnceVal->stripPointerCasts(); @@ -1569,7 +1577,7 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal, // between them is very expensive and unlikely to lead to later // simplification. In these cases, we typically end up with "cond ? v1 : v2" // where v1 and v2 both require constant pool loads, a big loss. - if (GVElType == Type::Int1Ty || GVElType->isFloatingPoint() || + if (GVElType == Type::getInt1Ty(Context) || GVElType->isFloatingPoint() || isa(GVElType) || isa(GVElType)) return false; @@ -1579,17 +1587,19 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal, if (!isa(I) && !isa(I)) return false; - DOUT << " *** SHRINKING TO BOOL: " << *GV; + DEBUG(errs() << " *** SHRINKING TO BOOL: " << *GV); // Create the new global, initializing it to false. - GlobalVariable *NewGV = new GlobalVariable(Context, Type::Int1Ty, false, + GlobalVariable *NewGV = new GlobalVariable(Context, + Type::getInt1Ty(Context), false, GlobalValue::InternalLinkage, ConstantInt::getFalse(Context), GV->getName()+".b", GV->isThreadLocal()); GV->getParent()->getGlobalList().insert(GV, NewGV); Constant *InitVal = GV->getInitializer(); - assert(InitVal->getType() != Type::Int1Ty && "No reason to shrink to bool!"); + assert(InitVal->getType() != Type::getInt1Ty(Context) && + "No reason to shrink to bool!"); // If initialized to zero and storing one into the global, we can use a cast // instead of a select to synthesize the desired value. @@ -1605,7 +1615,7 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal, // Only do this if we weren't storing a loaded value. Value *StoreVal; if (StoringOther || SI->getOperand(0) == InitVal) - StoreVal = ConstantInt::get(Type::Int1Ty, StoringOther); + StoreVal = ConstantInt::get(Type::getInt1Ty(Context), StoringOther); else { // Otherwise, we are storing a previously loaded copy. To do this, // change the copy from copying the original value to just copying the @@ -1656,7 +1666,7 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV, GV->removeDeadConstantUsers(); if (GV->use_empty()) { - DOUT << "GLOBAL DEAD: " << *GV; + DEBUG(errs() << "GLOBAL DEAD: " << *GV); GV->eraseFromParent(); ++NumDeleted; return true; @@ -1699,7 +1709,7 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV, GS.AccessingFunction->getName() == "main" && GS.AccessingFunction->hasExternalLinkage() && GV->getType()->getAddressSpace() == 0) { - DOUT << "LOCALIZING GLOBAL: " << *GV; + DEBUG(errs() << "LOCALIZING GLOBAL: " << *GV); Instruction* FirstI = GS.AccessingFunction->getEntryBlock().begin(); const Type* ElemTy = GV->getType()->getElementType(); // FIXME: Pass Global's alignment when globals have alignment @@ -1716,7 +1726,7 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV, // If the global is never loaded (but may be stored to), it is dead. // Delete it now. if (!GS.isLoaded) { - DOUT << "GLOBAL NEVER LOADED: " << *GV; + DEBUG(errs() << "GLOBAL NEVER LOADED: " << *GV); // Delete any stores we can find to the global. We may not be able to // make it completely dead though. @@ -1732,7 +1742,7 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV, return Changed; } else if (GS.StoredType <= GlobalStatus::isInitializerStored) { - DOUT << "MARKING CONSTANT: " << *GV; + DEBUG(errs() << "MARKING CONSTANT: " << *GV); GV->setConstant(true); // Clean up any obviously simplifiable users now. @@ -1740,8 +1750,8 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV, // If the global is dead now, just nuke it. if (GV->use_empty()) { - DOUT << " *** Marking constant allowed us to simplify " - << "all users and delete global!\n"; + DEBUG(errs() << " *** Marking constant allowed us to simplify " + << "all users and delete global!\n"); GV->eraseFromParent(); ++NumDeleted; } @@ -1749,12 +1759,12 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV, ++NumMarked; return true; } else if (!GV->getInitializer()->getType()->isSingleValueType()) { - if (GlobalVariable *FirstNewGV = SRAGlobal(GV, - getAnalysis(), - GV->getContext())) { - GVI = FirstNewGV; // Don't skip the newly produced globals! - return true; - } + if (TargetData *TD = getAnalysisIfAvailable()) + if (GlobalVariable *FirstNewGV = SRAGlobal(GV, *TD, + GV->getContext())) { + GVI = FirstNewGV; // Don't skip the newly produced globals! + return true; + } } else if (GS.StoredType == GlobalStatus::isStoredOnce) { // If the initial value for the global was an undef value, and if only // one other value was stored into it, we can just change the @@ -1770,8 +1780,8 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV, GV->getContext()); if (GV->use_empty()) { - DOUT << " *** Substituting initializer allowed us to " - << "simplify all users and delete global!\n"; + DEBUG(errs() << " *** Substituting initializer allowed us to " + << "simplify all users and delete global!\n"); GV->eraseFromParent(); ++NumDeleted; } else { @@ -1784,7 +1794,8 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV, // Try to optimize globals based on the knowledge that only one value // (besides its initializer) is ever stored to the global. if (OptimizeOnceStoredGlobal(GV, GS.StoredOnceValue, GVI, - getAnalysis(), GV->getContext())) + getAnalysisIfAvailable(), + GV->getContext())) return true; // Otherwise, if the global was not a boolean, we can shrink it to be a @@ -1893,16 +1904,16 @@ GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) { if (!ATy) return 0; const StructType *STy = dyn_cast(ATy->getElementType()); if (!STy || STy->getNumElements() != 2 || - STy->getElementType(0) != Type::Int32Ty) return 0; + STy->getElementType(0) != Type::getInt32Ty(M.getContext())) return 0; const PointerType *PFTy = dyn_cast(STy->getElementType(1)); if (!PFTy) return 0; const FunctionType *FTy = dyn_cast(PFTy->getElementType()); - if (!FTy || FTy->getReturnType() != Type::VoidTy || FTy->isVarArg() || - FTy->getNumParams() != 0) + if (!FTy || FTy->getReturnType() != Type::getVoidTy(M.getContext()) || + FTy->isVarArg() || FTy->getNumParams() != 0) return 0; // Verify that the initializer is simple enough for us to handle. - if (!I->hasInitializer()) return 0; + if (!I->hasDefinitiveInitializer()) return 0; ConstantArray *CA = dyn_cast(I->getInitializer()); if (!CA) return 0; for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) @@ -1947,7 +1958,7 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL, LLVMContext &Context) { // If we made a change, reassemble the initializer list. std::vector CSVals; - CSVals.push_back(ConstantInt::get(Type::Int32Ty, 65535)); + CSVals.push_back(ConstantInt::get(Type::getInt32Ty(Context), 65535)); CSVals.push_back(0); // Create the new init list. @@ -1956,10 +1967,10 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL, if (Ctors[i]) { CSVals[1] = Ctors[i]; } else { - const Type *FTy = FunctionType::get(Type::VoidTy, false); + const Type *FTy = FunctionType::get(Type::getVoidTy(Context), false); const PointerType *PFTy = PointerType::getUnqual(FTy); CSVals[1] = Constant::getNullValue(PFTy); - CSVals[0] = ConstantInt::get(Type::Int32Ty, 2147483647); + CSVals[0] = ConstantInt::get(Type::getInt32Ty(Context), 2147483647); } CAList.push_back(ConstantStruct::get(Context, CSVals)); } @@ -2013,20 +2024,48 @@ static Constant *getVal(DenseMap &ComputedValues, /// we punt. We basically just support direct accesses to globals and GEP's of /// globals. This should be kept up to date with CommitValueTo. static bool isSimpleEnoughPointerToCommit(Constant *C, LLVMContext &Context) { - if (GlobalVariable *GV = dyn_cast(C)) { - if (!GV->hasExternalLinkage() && !GV->hasLocalLinkage()) - return false; // do not allow weak/linkonce/dllimport/dllexport linkage. - return !GV->isDeclaration(); // reject external globals. - } + // Conservatively, avoid aggregate types. This is because we don't + // want to worry about them partially overlapping other stores. + if (!cast(C->getType())->getElementType()->isSingleValueType()) + return false; + + if (GlobalVariable *GV = dyn_cast(C)) + // Do not allow weak/linkonce/dllimport/dllexport linkage or + // external globals. + return GV->hasDefinitiveInitializer(); + if (ConstantExpr *CE = dyn_cast(C)) // Handle a constantexpr gep. if (CE->getOpcode() == Instruction::GetElementPtr && - isa(CE->getOperand(0))) { + isa(CE->getOperand(0)) && + cast(CE)->isInBounds()) { GlobalVariable *GV = cast(CE->getOperand(0)); - if (!GV->hasExternalLinkage() && !GV->hasLocalLinkage()) - return false; // do not allow weak/linkonce/dllimport/dllexport linkage. - return GV->hasInitializer() && - ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE, + // Do not allow weak/linkonce/dllimport/dllexport linkage or + // external globals. + if (!GV->hasDefinitiveInitializer()) + return false; + + gep_type_iterator GEPI = gep_type_begin(CE), E = gep_type_end(CE); + User::op_iterator OI = next(CE->op_begin()); + + // The first index must be zero. + ConstantInt *CI = dyn_cast(*OI); + if (!CI || !CI->isZero()) return false; + ++GEPI; + ++OI; + + // The remaining indices must be compile-time known integers within the + // bounds of the corresponding static array types. + for (; GEPI != E; ++GEPI, ++OI) { + CI = dyn_cast(*OI); + if (!CI) return false; + if (const ArrayType *ATy = dyn_cast(*GEPI)) + if (CI->getValue().getActiveBits() > 64 || + CI->getZExtValue() >= ATy->getNumElements()) + return false; + } + + return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE, Context); } return false; @@ -2128,7 +2167,7 @@ static Constant *ComputeLoadResult(Constant *P, // Access it. if (GlobalVariable *GV = dyn_cast(P)) { - if (GV->hasInitializer()) + if (GV->hasDefinitiveInitializer()) return GV->getInitializer(); return 0; } @@ -2138,7 +2177,7 @@ static Constant *ComputeLoadResult(Constant *P, if (CE->getOpcode() == Instruction::GetElementPtr && isa(CE->getOperand(0))) { GlobalVariable *GV = cast(CE->getOperand(0)); - if (GV->hasInitializer()) + if (GV->hasDefinitiveInitializer()) return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE, Context); } @@ -2150,7 +2189,7 @@ static Constant *ComputeLoadResult(Constant *P, /// successful, false if we can't evaluate it. ActualArgs contains the formal /// arguments for the function. static bool EvaluateFunction(Function *F, Constant *&RetVal, - const std::vector &ActualArgs, + const SmallVectorImpl &ActualArgs, std::vector &CallStack, DenseMap &MutatedMemory, std::vector &AllocaTmps) { @@ -2215,8 +2254,9 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal, for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; ++i) GEPOps.push_back(getVal(Values, *i)); - InstResult = - ConstantExpr::getGetElementPtr(P, &GEPOps[0], GEPOps.size()); + InstResult = cast(GEP)->isInBounds() ? + ConstantExpr::getInBoundsGetElementPtr(P, &GEPOps[0], GEPOps.size()) : + ConstantExpr::getGetElementPtr(P, &GEPOps[0], GEPOps.size()); } else if (LoadInst *LI = dyn_cast(CurInst)) { if (LI->isVolatile()) return false; // no volatile accesses. InstResult = ComputeLoadResult(getVal(Values, LI->getOperand(0)), @@ -2245,14 +2285,14 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal, Function *Callee = dyn_cast(getVal(Values, CI->getOperand(0))); if (!Callee) return false; // Cannot resolve. - std::vector Formals; + SmallVector Formals; for (User::op_iterator i = CI->op_begin() + 1, e = CI->op_end(); i != e; ++i) Formals.push_back(getVal(Values, *i)); - + if (Callee->isDeclaration()) { // If this is a function we can constant fold, do it. - if (Constant *C = ConstantFoldCall(Callee, &Formals[0], + if (Constant *C = ConstantFoldCall(Callee, Formals.data(), Formals.size())) { InstResult = C; } else { @@ -2347,8 +2387,9 @@ static bool EvaluateStaticConstructor(Function *F) { // Call the function. Constant *RetValDummy; - bool EvalSuccess = EvaluateFunction(F, RetValDummy, std::vector(), - CallStack, MutatedMemory, AllocaTmps); + bool EvalSuccess = EvaluateFunction(F, RetValDummy, + SmallVector(), CallStack, + MutatedMemory, AllocaTmps); if (EvalSuccess) { // We succeeded at evaluation: commit the result. DEBUG(errs() << "FULLY EVALUATED GLOBAL CTOR FUNCTION '"