summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/GlobalOpt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/IPO/GlobalOpt.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/GlobalOpt.cpp364
1 files changed, 208 insertions, 156 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index 8750eb9ecc4e..b2c2efed7db8 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -208,9 +208,7 @@ CleanupPointerRootUsers(GlobalVariable *GV,
SmallVector<std::pair<Instruction *, Instruction *>, 32> Dead;
// Constants can't be pointers to dynamically allocated memory.
- for (Value::user_iterator UI = GV->user_begin(), E = GV->user_end();
- UI != E;) {
- User *U = *UI++;
+ for (User *U : llvm::make_early_inc_range(GV->users())) {
if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
Value *V = SI->getValueOperand();
if (isa<Constant>(V)) {
@@ -703,8 +701,9 @@ static bool AllUsesOfValueWillTrapIfNull(const Value *V,
!ICmpInst::isSigned(cast<ICmpInst>(U)->getPredicate()) &&
isa<LoadInst>(U->getOperand(0)) &&
isa<ConstantPointerNull>(U->getOperand(1))) {
- assert(isa<GlobalValue>(
- cast<LoadInst>(U->getOperand(0))->getPointerOperand()) &&
+ assert(isa<GlobalValue>(cast<LoadInst>(U->getOperand(0))
+ ->getPointerOperand()
+ ->stripPointerCasts()) &&
"Should be GlobalVariable");
// This and only this kind of non-signed ICmpInst is to be replaced with
// the comparing of the value of the created global init bool later in
@@ -720,22 +719,55 @@ static bool AllUsesOfValueWillTrapIfNull(const Value *V,
/// Return true if all uses of any loads from GV will trap if the loaded value
/// is null. Note that this also permits comparisons of the loaded value
/// against null, as a special case.
-static bool AllUsesOfLoadedValueWillTrapIfNull(const GlobalVariable *GV) {
- for (const User *U : GV->users())
- if (const LoadInst *LI = dyn_cast<LoadInst>(U)) {
- SmallPtrSet<const PHINode*, 8> PHIs;
- if (!AllUsesOfValueWillTrapIfNull(LI, PHIs))
+static bool allUsesOfLoadedValueWillTrapIfNull(const GlobalVariable *GV) {
+ SmallVector<const Value *, 4> Worklist;
+ Worklist.push_back(GV);
+ while (!Worklist.empty()) {
+ const Value *P = Worklist.pop_back_val();
+ for (auto *U : P->users()) {
+ if (auto *LI = dyn_cast<LoadInst>(U)) {
+ SmallPtrSet<const PHINode *, 8> PHIs;
+ if (!AllUsesOfValueWillTrapIfNull(LI, PHIs))
+ return false;
+ } else if (auto *SI = dyn_cast<StoreInst>(U)) {
+ // Ignore stores to the global.
+ if (SI->getPointerOperand() != P)
+ return false;
+ } else if (auto *CE = dyn_cast<ConstantExpr>(U)) {
+ if (CE->stripPointerCasts() != GV)
+ return false;
+ // Check further the ConstantExpr.
+ Worklist.push_back(CE);
+ } else {
+ // We don't know or understand this user, bail out.
return false;
- } else if (isa<StoreInst>(U)) {
- // Ignore stores to the global.
- } else {
- // We don't know or understand this user, bail out.
- //cerr << "UNKNOWN USER OF GLOBAL!: " << *U;
- return false;
+ }
}
+ }
+
return true;
}
+/// Get all the loads/store uses for global variable \p GV.
+static void allUsesOfLoadAndStores(GlobalVariable *GV,
+ SmallVector<Value *, 4> &Uses) {
+ SmallVector<Value *, 4> Worklist;
+ Worklist.push_back(GV);
+ while (!Worklist.empty()) {
+ auto *P = Worklist.pop_back_val();
+ for (auto *U : P->users()) {
+ if (auto *CE = dyn_cast<ConstantExpr>(U)) {
+ Worklist.push_back(CE);
+ continue;
+ }
+
+ assert((isa<LoadInst>(U) || isa<StoreInst>(U)) &&
+ "Expect only load or store instructions");
+ Uses.push_back(U);
+ }
+ }
+}
+
static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
bool Changed = false;
for (auto UI = V->user_begin(), E = V->user_end(); UI != E; ) {
@@ -817,8 +849,7 @@ static bool OptimizeAwayTrappingUsesOfLoads(
bool AllNonStoreUsesGone = true;
// Replace all uses of loads with uses of uses of the stored value.
- for (Value::user_iterator GUI = GV->user_begin(), E = GV->user_end(); GUI != E;){
- User *GlobalUser = *GUI++;
+ for (User *GlobalUser : llvm::make_early_inc_range(GV->users())) {
if (LoadInst *LI = dyn_cast<LoadInst>(GlobalUser)) {
Changed |= OptimizeAwayTrappingUsesOfValue(LI, LV);
// If we were able to delete all uses of the loads
@@ -934,9 +965,8 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
}
}
- Constant *RepValue = NewGV;
- if (NewGV->getType() != GV->getValueType())
- RepValue = ConstantExpr::getBitCast(RepValue, GV->getValueType());
+ SmallPtrSet<Constant *, 1> RepValues;
+ RepValues.insert(NewGV);
// 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.
@@ -947,9 +977,11 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
GV->getName()+".init", GV->getThreadLocalMode());
bool InitBoolUsed = false;
- // Loop over all uses of GV, processing them in turn.
- while (!GV->use_empty()) {
- if (StoreInst *SI = dyn_cast<StoreInst>(GV->user_back())) {
+ // Loop over all instruction uses of GV, processing them in turn.
+ SmallVector<Value *, 4> Guses;
+ allUsesOfLoadAndStores(GV, Guses);
+ for (auto *U : Guses) {
+ if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
// The global is initialized when the store to it occurs. If the stored
// value is null value, the global bool is set to false, otherwise true.
new StoreInst(ConstantInt::getBool(
@@ -961,12 +993,14 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
continue;
}
- LoadInst *LI = cast<LoadInst>(GV->user_back());
+ LoadInst *LI = cast<LoadInst>(U);
while (!LI->use_empty()) {
Use &LoadUse = *LI->use_begin();
ICmpInst *ICI = dyn_cast<ICmpInst>(LoadUse.getUser());
if (!ICI) {
- LoadUse = RepValue;
+ auto *CE = ConstantExpr::getBitCast(NewGV, LI->getType());
+ RepValues.insert(CE);
+ LoadUse.set(CE);
continue;
}
@@ -1012,40 +1046,53 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
// To further other optimizations, loop over all users of NewGV and try to
// constant prop them. This will promote GEP instructions with constant
// indices into GEP constant-exprs, which will allow global-opt to hack on it.
- ConstantPropUsersOf(NewGV, DL, TLI);
- if (RepValue != NewGV)
- ConstantPropUsersOf(RepValue, DL, TLI);
+ for (auto *CE : RepValues)
+ ConstantPropUsersOf(CE, DL, TLI);
return NewGV;
}
-/// Scan the use-list of V checking to make sure that there are no complex uses
-/// of V. We permit simple things like dereferencing the pointer, but not
+/// Scan the use-list of GV checking to make sure that there are no complex uses
+/// of GV. We permit simple things like dereferencing the pointer, but not
/// storing through the address, unless it is to the specified global.
static bool
-valueIsOnlyUsedLocallyOrStoredToOneGlobal(const Instruction *V,
+valueIsOnlyUsedLocallyOrStoredToOneGlobal(const CallInst *CI,
const GlobalVariable *GV) {
- for (const User *U : V->users()) {
- const Instruction *Inst = cast<Instruction>(U);
+ SmallPtrSet<const Value *, 4> Visited;
+ SmallVector<const Value *, 4> Worklist;
+ Worklist.push_back(CI);
- if (isa<LoadInst>(Inst) || isa<CmpInst>(Inst)) {
- continue; // Fine, ignore.
- }
+ while (!Worklist.empty()) {
+ const Value *V = Worklist.pop_back_val();
+ if (!Visited.insert(V).second)
+ continue;
- if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
- if (SI->getOperand(0) == V && SI->getOperand(1) != GV)
- return false; // Storing the pointer itself... bad.
- continue; // Otherwise, storing through it, or storing into GV... fine.
- }
+ for (const Use &VUse : V->uses()) {
+ const User *U = VUse.getUser();
+ if (isa<LoadInst>(U) || isa<CmpInst>(U))
+ continue; // Fine, ignore.
- if (const BitCastInst *BCI = dyn_cast<BitCastInst>(Inst)) {
- if (!valueIsOnlyUsedLocallyOrStoredToOneGlobal(BCI, GV))
- return false;
- continue;
- }
+ if (auto *SI = dyn_cast<StoreInst>(U)) {
+ if (SI->getValueOperand() == V &&
+ SI->getPointerOperand()->stripPointerCasts() != GV)
+ return false; // Storing the pointer not into GV... bad.
+ continue; // Otherwise, storing through it, or storing into GV... fine.
+ }
- return false;
+ if (auto *BCI = dyn_cast<BitCastInst>(U)) {
+ Worklist.push_back(BCI);
+ continue;
+ }
+
+ if (auto *GEPI = dyn_cast<GetElementPtrInst>(U)) {
+ Worklist.push_back(GEPI);
+ continue;
+ }
+
+ return false;
+ }
}
+
return true;
}
@@ -1066,12 +1113,12 @@ static bool tryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, CallInst *CI,
// been reached). To do this, we check to see if all uses of the global
// would trap if the global were null: this proves that they must all
// happen after the malloc.
- if (!AllUsesOfLoadedValueWillTrapIfNull(GV))
+ if (!allUsesOfLoadedValueWillTrapIfNull(GV))
return false;
// We can't optimize this if the malloc itself is used in a complex way,
// for example, being stored into multiple globals. This allows the
- // malloc to be stored into the specified global, loaded icmp'd.
+ // malloc to be stored into the specified global, loaded, gep, icmp'd.
// These are all things we could transform to using the global for.
if (!valueIsOnlyUsedLocallyOrStoredToOneGlobal(CI, GV))
return false;
@@ -1112,6 +1159,7 @@ optimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
// value was null.
if (GV->getInitializer()->getType()->isPointerTy() &&
GV->getInitializer()->isNullValue() &&
+ StoredOnceVal->getType()->isPointerTy() &&
!NullPointerIsDefined(
nullptr /* F */,
GV->getInitializer()->getType()->getPointerAddressSpace())) {
@@ -1442,8 +1490,7 @@ static void makeAllConstantUsesInstructions(Constant *C) {
append_range(UUsers, U->users());
for (auto *UU : UUsers) {
Instruction *UI = cast<Instruction>(UU);
- Instruction *NewU = U->getAsInstruction();
- NewU->insertBefore(UI);
+ Instruction *NewU = U->getAsInstruction(UI);
UI->replaceUsesOfWith(U, NewU);
}
// We've replaced all the uses, so destroy the constant. (destroyConstant
@@ -1456,6 +1503,7 @@ static void makeAllConstantUsesInstructions(Constant *C) {
/// it if possible. If we make a change, return true.
static bool
processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
+ function_ref<TargetTransformInfo &(Function &)> GetTTI,
function_ref<TargetLibraryInfo &(Function &)> GetTLI,
function_ref<DominatorTree &(Function &)> LookupDomTree) {
auto &DL = GV->getParent()->getDataLayout();
@@ -1554,43 +1602,57 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
if (SRAGlobal(GV, DL))
return true;
}
- if (GS.StoredType == GlobalStatus::StoredOnce && GS.StoredOnceValue) {
+ Value *StoredOnceValue = GS.getStoredOnceValue();
+ if (GS.StoredType == GlobalStatus::StoredOnce && StoredOnceValue) {
+ // Avoid speculating constant expressions that might trap (div/rem).
+ auto *SOVConstant = dyn_cast<Constant>(StoredOnceValue);
+ if (SOVConstant && SOVConstant->canTrap())
+ return Changed;
+
+ Function &StoreFn =
+ const_cast<Function &>(*GS.StoredOnceStore->getFunction());
+ bool CanHaveNonUndefGlobalInitializer =
+ GetTTI(StoreFn).canHaveNonUndefGlobalInitializerInAddressSpace(
+ GV->getType()->getAddressSpace());
// 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
// initializer to be the stored value, then delete all stores to the
// global. This allows us to mark it constant.
- if (Constant *SOVConstant = dyn_cast<Constant>(GS.StoredOnceValue))
- if (isa<UndefValue>(GV->getInitializer())) {
- // Change the initial value here.
- GV->setInitializer(SOVConstant);
+ // This is restricted to address spaces that allow globals to have
+ // initializers. NVPTX, for example, does not support initializers for
+ // shared memory (AS 3).
+ if (SOVConstant && SOVConstant->getType() == GV->getValueType() &&
+ isa<UndefValue>(GV->getInitializer()) &&
+ CanHaveNonUndefGlobalInitializer) {
+ // Change the initial value here.
+ GV->setInitializer(SOVConstant);
- // Clean up any obviously simplifiable users now.
- CleanupConstantGlobalUsers(GV, GV->getInitializer(), DL, GetTLI);
+ // Clean up any obviously simplifiable users now.
+ CleanupConstantGlobalUsers(GV, GV->getInitializer(), DL, GetTLI);
- if (GV->use_empty()) {
- LLVM_DEBUG(dbgs() << " *** Substituting initializer allowed us to "
- << "simplify all users and delete global!\n");
- GV->eraseFromParent();
- ++NumDeleted;
- }
- ++NumSubstitute;
- return true;
+ if (GV->use_empty()) {
+ LLVM_DEBUG(dbgs() << " *** Substituting initializer allowed us to "
+ << "simplify all users and delete global!\n");
+ GV->eraseFromParent();
+ ++NumDeleted;
}
+ ++NumSubstitute;
+ return true;
+ }
// 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, GS.Ordering, DL,
- GetTLI))
+ if (optimizeOnceStoredGlobal(GV, StoredOnceValue, GS.Ordering, DL, GetTLI))
return true;
// Otherwise, if the global was not a boolean, we can shrink it to be a
- // boolean.
- if (Constant *SOVConstant = dyn_cast<Constant>(GS.StoredOnceValue)) {
- if (GS.Ordering == AtomicOrdering::NotAtomic) {
- if (TryToShrinkGlobalToBoolean(GV, SOVConstant)) {
- ++NumShrunkToBool;
- return true;
- }
+ // boolean. Skip this optimization for AS that doesn't allow an initializer.
+ if (SOVConstant && GS.Ordering == AtomicOrdering::NotAtomic &&
+ (!isa<UndefValue>(GV->getInitializer()) ||
+ CanHaveNonUndefGlobalInitializer)) {
+ if (TryToShrinkGlobalToBoolean(GV, SOVConstant)) {
+ ++NumShrunkToBool;
+ return true;
}
}
}
@@ -1602,6 +1664,7 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
/// make a change, return true.
static bool
processGlobal(GlobalValue &GV,
+ function_ref<TargetTransformInfo &(Function &)> GetTTI,
function_ref<TargetLibraryInfo &(Function &)> GetTLI,
function_ref<DominatorTree &(Function &)> LookupDomTree) {
if (GV.getName().startswith("llvm."))
@@ -1634,7 +1697,8 @@ processGlobal(GlobalValue &GV,
if (GVar->isConstant() || !GVar->hasInitializer())
return Changed;
- return processInternalGlobal(GVar, GS, GetTLI, LookupDomTree) || Changed;
+ return processInternalGlobal(GVar, GS, GetTTI, GetTLI, LookupDomTree) ||
+ Changed;
}
/// Walk all of the direct calls of the specified function, changing them to
@@ -1651,7 +1715,7 @@ static AttributeList StripAttr(LLVMContext &C, AttributeList Attrs,
Attribute::AttrKind A) {
unsigned AttrIndex;
if (Attrs.hasAttrSomewhere(A, &AttrIndex))
- return Attrs.removeAttribute(C, AttrIndex, A);
+ return Attrs.removeAttributeAtIndex(C, AttrIndex, A);
return Attrs;
}
@@ -1864,10 +1928,8 @@ static void RemovePreallocated(Function *F) {
Value *AllocaReplacement = ArgAllocas[AllocArgIndex];
if (!AllocaReplacement) {
auto AddressSpace = UseCall->getType()->getPointerAddressSpace();
- auto *ArgType = UseCall
- ->getAttribute(AttributeList::FunctionIndex,
- Attribute::Preallocated)
- .getValueAsType();
+ auto *ArgType =
+ UseCall->getFnAttr(Attribute::Preallocated).getValueAsType();
auto *InsertBefore = PreallocatedSetup->getNextNonDebugInstruction();
Builder.SetInsertPoint(InsertBefore);
auto *Alloca =
@@ -1897,26 +1959,22 @@ OptimizeFunctions(Module &M,
bool Changed = false;
std::vector<Function *> AllCallsCold;
- for (Module::iterator FI = M.begin(), E = M.end(); FI != E;) {
- Function *F = &*FI++;
- if (hasOnlyColdCalls(*F, GetBFI))
- AllCallsCold.push_back(F);
- }
+ for (Function &F : llvm::make_early_inc_range(M))
+ if (hasOnlyColdCalls(F, GetBFI))
+ AllCallsCold.push_back(&F);
// Optimize functions.
- for (Module::iterator FI = M.begin(), E = M.end(); FI != E; ) {
- Function *F = &*FI++;
-
+ for (Function &F : llvm::make_early_inc_range(M)) {
// Don't perform global opt pass on naked functions; we don't want fast
// calling conventions for naked functions.
- if (F->hasFnAttribute(Attribute::Naked))
+ if (F.hasFnAttribute(Attribute::Naked))
continue;
// Functions without names cannot be referenced outside this module.
- if (!F->hasName() && !F->isDeclaration() && !F->hasLocalLinkage())
- F->setLinkage(GlobalValue::InternalLinkage);
+ if (!F.hasName() && !F.isDeclaration() && !F.hasLocalLinkage())
+ F.setLinkage(GlobalValue::InternalLinkage);
- if (deleteIfDead(*F, NotDiscardableComdats)) {
+ if (deleteIfDead(F, NotDiscardableComdats)) {
Changed = true;
continue;
}
@@ -1931,17 +1989,17 @@ OptimizeFunctions(Module &M,
// some more complicated logic to break these cycles.
// Removing unreachable blocks might invalidate the dominator so we
// recalculate it.
- if (!F->isDeclaration()) {
- if (removeUnreachableBlocks(*F)) {
- auto &DT = LookupDomTree(*F);
- DT.recalculate(*F);
+ if (!F.isDeclaration()) {
+ if (removeUnreachableBlocks(F)) {
+ auto &DT = LookupDomTree(F);
+ DT.recalculate(F);
Changed = true;
}
}
- Changed |= processGlobal(*F, GetTLI, LookupDomTree);
+ Changed |= processGlobal(F, GetTTI, GetTLI, LookupDomTree);
- if (!F->hasLocalLinkage())
+ if (!F.hasLocalLinkage())
continue;
// If we have an inalloca parameter that we can safely remove the
@@ -1949,56 +2007,55 @@ OptimizeFunctions(Module &M,
// wouldn't be safe in the presence of inalloca.
// FIXME: We should also hoist alloca affected by this to the entry
// block if possible.
- if (F->getAttributes().hasAttrSomewhere(Attribute::InAlloca) &&
- !F->hasAddressTaken() && !hasMustTailCallers(F)) {
- RemoveAttribute(F, Attribute::InAlloca);
+ if (F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) &&
+ !F.hasAddressTaken() && !hasMustTailCallers(&F)) {
+ RemoveAttribute(&F, Attribute::InAlloca);
Changed = true;
}
// FIXME: handle invokes
// FIXME: handle musttail
- if (F->getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {
- if (!F->hasAddressTaken() && !hasMustTailCallers(F) &&
- !hasInvokeCallers(F)) {
- RemovePreallocated(F);
+ if (F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {
+ if (!F.hasAddressTaken() && !hasMustTailCallers(&F) &&
+ !hasInvokeCallers(&F)) {
+ RemovePreallocated(&F);
Changed = true;
}
continue;
}
- if (hasChangeableCC(F) && !F->isVarArg() && !F->hasAddressTaken()) {
+ if (hasChangeableCC(&F) && !F.isVarArg() && !F.hasAddressTaken()) {
NumInternalFunc++;
- TargetTransformInfo &TTI = GetTTI(*F);
+ TargetTransformInfo &TTI = GetTTI(F);
// Change the calling convention to coldcc if either stress testing is
// enabled or the target would like to use coldcc on functions which are
// cold at all call sites and the callers contain no other non coldcc
// calls.
if (EnableColdCCStressTest ||
- (TTI.useColdCCForColdCall(*F) &&
- isValidCandidateForColdCC(*F, GetBFI, AllCallsCold))) {
- F->setCallingConv(CallingConv::Cold);
- changeCallSitesToColdCC(F);
+ (TTI.useColdCCForColdCall(F) &&
+ isValidCandidateForColdCC(F, GetBFI, AllCallsCold))) {
+ F.setCallingConv(CallingConv::Cold);
+ changeCallSitesToColdCC(&F);
Changed = true;
NumColdCC++;
}
}
- if (hasChangeableCC(F) && !F->isVarArg() &&
- !F->hasAddressTaken()) {
+ if (hasChangeableCC(&F) && !F.isVarArg() && !F.hasAddressTaken()) {
// If this function has a calling convention worth changing, is not a
// varargs function, and is only called directly, promote it to use the
// Fast calling convention.
- F->setCallingConv(CallingConv::Fast);
- ChangeCalleesToFastCall(F);
+ F.setCallingConv(CallingConv::Fast);
+ ChangeCalleesToFastCall(&F);
++NumFastCallFns;
Changed = true;
}
- if (F->getAttributes().hasAttrSomewhere(Attribute::Nest) &&
- !F->hasAddressTaken()) {
+ if (F.getAttributes().hasAttrSomewhere(Attribute::Nest) &&
+ !F.hasAddressTaken()) {
// The function is not used by a trampoline intrinsic, so it is safe
// to remove the 'nest' attribute.
- RemoveAttribute(F, Attribute::Nest);
+ RemoveAttribute(&F, Attribute::Nest);
++NumNestRemoved;
Changed = true;
}
@@ -2008,35 +2065,34 @@ OptimizeFunctions(Module &M,
static bool
OptimizeGlobalVars(Module &M,
+ function_ref<TargetTransformInfo &(Function &)> GetTTI,
function_ref<TargetLibraryInfo &(Function &)> GetTLI,
function_ref<DominatorTree &(Function &)> LookupDomTree,
SmallPtrSetImpl<const Comdat *> &NotDiscardableComdats) {
bool Changed = false;
- for (Module::global_iterator GVI = M.global_begin(), E = M.global_end();
- GVI != E; ) {
- GlobalVariable *GV = &*GVI++;
+ for (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) {
// Global variables without names cannot be referenced outside this module.
- if (!GV->hasName() && !GV->isDeclaration() && !GV->hasLocalLinkage())
- GV->setLinkage(GlobalValue::InternalLinkage);
+ if (!GV.hasName() && !GV.isDeclaration() && !GV.hasLocalLinkage())
+ GV.setLinkage(GlobalValue::InternalLinkage);
// Simplify the initializer.
- if (GV->hasInitializer())
- if (auto *C = dyn_cast<Constant>(GV->getInitializer())) {
+ if (GV.hasInitializer())
+ if (auto *C = dyn_cast<Constant>(GV.getInitializer())) {
auto &DL = M.getDataLayout();
// TLI is not used in the case of a Constant, so use default nullptr
// for that optional parameter, since we don't have a Function to
// provide GetTLI anyway.
Constant *New = ConstantFoldConstant(C, DL, /*TLI*/ nullptr);
if (New != C)
- GV->setInitializer(New);
+ GV.setInitializer(New);
}
- if (deleteIfDead(*GV, NotDiscardableComdats)) {
+ if (deleteIfDead(GV, NotDiscardableComdats)) {
Changed = true;
continue;
}
- Changed |= processGlobal(*GV, GetTLI, LookupDomTree);
+ Changed |= processGlobal(GV, GetTTI, GetTLI, LookupDomTree);
}
return Changed;
}
@@ -2425,24 +2481,21 @@ OptimizeGlobalAliases(Module &M,
for (GlobalValue *GV : Used.used())
Used.compilerUsedErase(GV);
- for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
- I != E;) {
- GlobalAlias *J = &*I++;
-
+ for (GlobalAlias &J : llvm::make_early_inc_range(M.aliases())) {
// Aliases without names cannot be referenced outside this module.
- if (!J->hasName() && !J->isDeclaration() && !J->hasLocalLinkage())
- J->setLinkage(GlobalValue::InternalLinkage);
+ if (!J.hasName() && !J.isDeclaration() && !J.hasLocalLinkage())
+ J.setLinkage(GlobalValue::InternalLinkage);
- if (deleteIfDead(*J, NotDiscardableComdats)) {
+ if (deleteIfDead(J, NotDiscardableComdats)) {
Changed = true;
continue;
}
// If the alias can change at link time, nothing can be done - bail out.
- if (J->isInterposable())
+ if (J.isInterposable())
continue;
- Constant *Aliasee = J->getAliasee();
+ Constant *Aliasee = J.getAliasee();
GlobalValue *Target = dyn_cast<GlobalValue>(Aliasee->stripPointerCasts());
// We can't trivially replace the alias with the aliasee if the aliasee is
// non-trivial in some way. We also can't replace the alias with the aliasee
@@ -2455,31 +2508,31 @@ OptimizeGlobalAliases(Module &M,
// Make all users of the alias use the aliasee instead.
bool RenameTarget;
- if (!hasUsesToReplace(*J, Used, RenameTarget))
+ if (!hasUsesToReplace(J, Used, RenameTarget))
continue;
- J->replaceAllUsesWith(ConstantExpr::getBitCast(Aliasee, J->getType()));
+ J.replaceAllUsesWith(ConstantExpr::getBitCast(Aliasee, J.getType()));
++NumAliasesResolved;
Changed = true;
if (RenameTarget) {
// Give the aliasee the name, linkage and other attributes of the alias.
- Target->takeName(&*J);
- Target->setLinkage(J->getLinkage());
- Target->setDSOLocal(J->isDSOLocal());
- Target->setVisibility(J->getVisibility());
- Target->setDLLStorageClass(J->getDLLStorageClass());
+ Target->takeName(&J);
+ Target->setLinkage(J.getLinkage());
+ Target->setDSOLocal(J.isDSOLocal());
+ Target->setVisibility(J.getVisibility());
+ Target->setDLLStorageClass(J.getDLLStorageClass());
- if (Used.usedErase(&*J))
+ if (Used.usedErase(&J))
Used.usedInsert(Target);
- if (Used.compilerUsedErase(&*J))
+ if (Used.compilerUsedErase(&J))
Used.compilerUsedInsert(Target);
- } else if (mayHaveOtherReferences(*J, Used))
+ } else if (mayHaveOtherReferences(J, Used))
continue;
// Delete the alias.
- M.getAliasList().erase(J);
+ M.getAliasList().erase(&J);
++NumAliasesRemoved;
Changed = true;
}
@@ -2526,7 +2579,7 @@ static bool cxxDtorIsEmpty(const Function &Fn) {
return false;
for (auto &I : Fn.getEntryBlock()) {
- if (isa<DbgInfoIntrinsic>(I))
+ if (I.isDebugOrPseudoInst())
continue;
if (isa<ReturnInst>(I))
return true;
@@ -2552,12 +2605,11 @@ static bool OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) {
// and remove them.
bool Changed = false;
- for (auto I = CXAAtExitFn->user_begin(), E = CXAAtExitFn->user_end();
- I != E;) {
+ for (User *U : llvm::make_early_inc_range(CXAAtExitFn->users())) {
// We're only interested in calls. Theoretically, we could handle invoke
// instructions as well, but neither llvm-gcc nor clang generate invokes
// to __cxa_atexit.
- CallInst *CI = dyn_cast<CallInst>(*I++);
+ CallInst *CI = dyn_cast<CallInst>(U);
if (!CI)
continue;
@@ -2614,8 +2666,8 @@ static bool optimizeGlobalsInModule(
});
// Optimize non-address-taken globals.
- LocalChange |=
- OptimizeGlobalVars(M, GetTLI, LookupDomTree, NotDiscardableComdats);
+ LocalChange |= OptimizeGlobalVars(M, GetTTI, GetTLI, LookupDomTree,
+ NotDiscardableComdats);
// Resolve aliases, when possible.
LocalChange |= OptimizeGlobalAliases(M, NotDiscardableComdats);