mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-15 09:33:39 +00:00
Pass TargetData and TargetLibraryInfo through to the constant folder. Fixes a
few fixme's when TLI was added. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150322 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
26f927951b
commit
6a577f82ba
@ -82,6 +82,9 @@ namespace {
|
|||||||
const SmallPtrSet<const PHINode*, 16> &PHIUsers,
|
const SmallPtrSet<const PHINode*, 16> &PHIUsers,
|
||||||
const GlobalStatus &GS);
|
const GlobalStatus &GS);
|
||||||
bool OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn);
|
bool OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn);
|
||||||
|
|
||||||
|
TargetData *TD;
|
||||||
|
TargetLibraryInfo *TLI;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +298,8 @@ static bool AnalyzeGlobal(const Value *V, GlobalStatus &GS,
|
|||||||
/// users of the global, cleaning up the obvious ones. This is largely just a
|
/// users of the global, cleaning up the obvious ones. This is largely just a
|
||||||
/// quick scan over the use list to clean up the easy and obvious cruft. This
|
/// quick scan over the use list to clean up the easy and obvious cruft. This
|
||||||
/// returns true if it made a change.
|
/// returns true if it made a change.
|
||||||
static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) {
|
static bool CleanupConstantGlobalUsers(Value *V, Constant *Init,
|
||||||
|
TargetData *TD, TargetLibraryInfo *TLI) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;) {
|
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;) {
|
||||||
User *U = *UI++;
|
User *U = *UI++;
|
||||||
@ -316,11 +320,11 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) {
|
|||||||
Constant *SubInit = 0;
|
Constant *SubInit = 0;
|
||||||
if (Init)
|
if (Init)
|
||||||
SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
|
SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
|
||||||
Changed |= CleanupConstantGlobalUsers(CE, SubInit);
|
Changed |= CleanupConstantGlobalUsers(CE, SubInit, TD, TLI);
|
||||||
} else if (CE->getOpcode() == Instruction::BitCast &&
|
} else if (CE->getOpcode() == Instruction::BitCast &&
|
||||||
CE->getType()->isPointerTy()) {
|
CE->getType()->isPointerTy()) {
|
||||||
// Pointer cast, delete any stores and memsets to the global.
|
// Pointer cast, delete any stores and memsets to the global.
|
||||||
Changed |= CleanupConstantGlobalUsers(CE, 0);
|
Changed |= CleanupConstantGlobalUsers(CE, 0, TD, TLI);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CE->use_empty()) {
|
if (CE->use_empty()) {
|
||||||
@ -333,13 +337,12 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) {
|
|||||||
// and will invalidate our notion of what Init is.
|
// and will invalidate our notion of what Init is.
|
||||||
Constant *SubInit = 0;
|
Constant *SubInit = 0;
|
||||||
if (!isa<ConstantExpr>(GEP->getOperand(0))) {
|
if (!isa<ConstantExpr>(GEP->getOperand(0))) {
|
||||||
// FIXME: use TargetData/TargetLibraryInfo for smarter constant folding.
|
|
||||||
ConstantExpr *CE =
|
ConstantExpr *CE =
|
||||||
dyn_cast_or_null<ConstantExpr>(ConstantFoldInstruction(GEP));
|
dyn_cast_or_null<ConstantExpr>(ConstantFoldInstruction(GEP, TD, TLI));
|
||||||
if (Init && CE && CE->getOpcode() == Instruction::GetElementPtr)
|
if (Init && CE && CE->getOpcode() == Instruction::GetElementPtr)
|
||||||
SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
|
SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
|
||||||
}
|
}
|
||||||
Changed |= CleanupConstantGlobalUsers(GEP, SubInit);
|
Changed |= CleanupConstantGlobalUsers(GEP, SubInit, TD, TLI);
|
||||||
|
|
||||||
if (GEP->use_empty()) {
|
if (GEP->use_empty()) {
|
||||||
GEP->eraseFromParent();
|
GEP->eraseFromParent();
|
||||||
@ -357,7 +360,7 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) {
|
|||||||
if (SafeToDestroyConstant(C)) {
|
if (SafeToDestroyConstant(C)) {
|
||||||
C->destroyConstant();
|
C->destroyConstant();
|
||||||
// This could have invalidated UI, start over from scratch.
|
// This could have invalidated UI, start over from scratch.
|
||||||
CleanupConstantGlobalUsers(V, Init);
|
CleanupConstantGlobalUsers(V, Init, TD, TLI);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -757,7 +760,9 @@ static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
|
|||||||
/// value stored into it. If there are uses of the loaded value that would trap
|
/// value stored into it. If there are uses of the loaded value that would trap
|
||||||
/// if the loaded value is dynamically null, then we know that they cannot be
|
/// if the loaded value is dynamically null, then we know that they cannot be
|
||||||
/// reachable with a null optimize away the load.
|
/// reachable with a null optimize away the load.
|
||||||
static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV) {
|
static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV,
|
||||||
|
TargetData *TD,
|
||||||
|
TargetLibraryInfo *TLI) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
// Keep track of whether we are able to remove all the uses of the global
|
// Keep track of whether we are able to remove all the uses of the global
|
||||||
@ -800,7 +805,7 @@ static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV) {
|
|||||||
// nor is the global.
|
// nor is the global.
|
||||||
if (AllNonStoreUsesGone) {
|
if (AllNonStoreUsesGone) {
|
||||||
DEBUG(dbgs() << " *** GLOBAL NOW DEAD!\n");
|
DEBUG(dbgs() << " *** GLOBAL NOW DEAD!\n");
|
||||||
CleanupConstantGlobalUsers(GV, 0);
|
CleanupConstantGlobalUsers(GV, 0, TD, TLI);
|
||||||
if (GV->use_empty()) {
|
if (GV->use_empty()) {
|
||||||
GV->eraseFromParent();
|
GV->eraseFromParent();
|
||||||
++NumDeleted;
|
++NumDeleted;
|
||||||
@ -812,11 +817,11 @@ static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV) {
|
|||||||
|
|
||||||
/// ConstantPropUsersOf - Walk the use list of V, constant folding all of the
|
/// ConstantPropUsersOf - Walk the use list of V, constant folding all of the
|
||||||
/// instructions that are foldable.
|
/// instructions that are foldable.
|
||||||
static void ConstantPropUsersOf(Value *V) {
|
static void ConstantPropUsersOf(Value *V,
|
||||||
|
TargetData *TD, TargetLibraryInfo *TLI) {
|
||||||
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; )
|
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; )
|
||||||
if (Instruction *I = dyn_cast<Instruction>(*UI++))
|
if (Instruction *I = dyn_cast<Instruction>(*UI++))
|
||||||
// FIXME: use TargetData/TargetLibraryInfo for smarter constant folding.
|
if (Constant *NewC = ConstantFoldInstruction(I, TD, TLI)) {
|
||||||
if (Constant *NewC = ConstantFoldInstruction(I)) {
|
|
||||||
I->replaceAllUsesWith(NewC);
|
I->replaceAllUsesWith(NewC);
|
||||||
|
|
||||||
// Advance UI to the next non-I use to avoid invalidating it!
|
// Advance UI to the next non-I use to avoid invalidating it!
|
||||||
@ -836,7 +841,8 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
|
|||||||
CallInst *CI,
|
CallInst *CI,
|
||||||
Type *AllocTy,
|
Type *AllocTy,
|
||||||
ConstantInt *NElements,
|
ConstantInt *NElements,
|
||||||
TargetData *TD) {
|
TargetData *TD,
|
||||||
|
TargetLibraryInfo *TLI) {
|
||||||
DEBUG(errs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI << '\n');
|
DEBUG(errs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI << '\n');
|
||||||
|
|
||||||
Type *GlobalType;
|
Type *GlobalType;
|
||||||
@ -954,9 +960,9 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
|
|||||||
// To further other optimizations, loop over all users of NewGV and try to
|
// To further other optimizations, loop over all users of NewGV and try to
|
||||||
// constant prop them. This will promote GEP instructions with constant
|
// constant prop them. This will promote GEP instructions with constant
|
||||||
// indices into GEP constant-exprs, which will allow global-opt to hack on it.
|
// indices into GEP constant-exprs, which will allow global-opt to hack on it.
|
||||||
ConstantPropUsersOf(NewGV);
|
ConstantPropUsersOf(NewGV, TD, TLI);
|
||||||
if (RepValue != NewGV)
|
if (RepValue != NewGV)
|
||||||
ConstantPropUsersOf(RepValue);
|
ConstantPropUsersOf(RepValue, TD, TLI);
|
||||||
|
|
||||||
return NewGV;
|
return NewGV;
|
||||||
}
|
}
|
||||||
@ -1475,7 +1481,8 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
|||||||
Type *AllocTy,
|
Type *AllocTy,
|
||||||
AtomicOrdering Ordering,
|
AtomicOrdering Ordering,
|
||||||
Module::global_iterator &GVI,
|
Module::global_iterator &GVI,
|
||||||
TargetData *TD) {
|
TargetData *TD,
|
||||||
|
TargetLibraryInfo *TLI) {
|
||||||
if (!TD)
|
if (!TD)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1515,7 +1522,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
|||||||
// (2048 bytes currently), as we don't want to introduce a 16M global or
|
// (2048 bytes currently), as we don't want to introduce a 16M global or
|
||||||
// something.
|
// something.
|
||||||
if (NElements->getZExtValue() * TD->getTypeAllocSize(AllocTy) < 2048) {
|
if (NElements->getZExtValue() * TD->getTypeAllocSize(AllocTy) < 2048) {
|
||||||
GVI = OptimizeGlobalAddressOfMalloc(GV, CI, AllocTy, NElements, TD);
|
GVI = OptimizeGlobalAddressOfMalloc(GV, CI, AllocTy, NElements, TD, TLI);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1570,7 +1577,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
|||||||
static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
|
static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
|
||||||
AtomicOrdering Ordering,
|
AtomicOrdering Ordering,
|
||||||
Module::global_iterator &GVI,
|
Module::global_iterator &GVI,
|
||||||
TargetData *TD) {
|
TargetData *TD, TargetLibraryInfo *TLI) {
|
||||||
// Ignore no-op GEPs and bitcasts.
|
// Ignore no-op GEPs and bitcasts.
|
||||||
StoredOnceVal = StoredOnceVal->stripPointerCasts();
|
StoredOnceVal = StoredOnceVal->stripPointerCasts();
|
||||||
|
|
||||||
@ -1585,12 +1592,13 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
|
|||||||
SOVC = ConstantExpr::getBitCast(SOVC, GV->getInitializer()->getType());
|
SOVC = ConstantExpr::getBitCast(SOVC, GV->getInitializer()->getType());
|
||||||
|
|
||||||
// Optimize away any trapping uses of the loaded value.
|
// Optimize away any trapping uses of the loaded value.
|
||||||
if (OptimizeAwayTrappingUsesOfLoads(GV, SOVC))
|
if (OptimizeAwayTrappingUsesOfLoads(GV, SOVC, TD, TLI))
|
||||||
return true;
|
return true;
|
||||||
} else if (CallInst *CI = extractMallocCall(StoredOnceVal)) {
|
} else if (CallInst *CI = extractMallocCall(StoredOnceVal)) {
|
||||||
Type *MallocType = getMallocAllocatedType(CI);
|
Type *MallocType = getMallocAllocatedType(CI);
|
||||||
if (MallocType && TryToOptimizeStoreOfMallocToGlobal(GV, CI, MallocType,
|
if (MallocType &&
|
||||||
Ordering, GVI, TD))
|
TryToOptimizeStoreOfMallocToGlobal(GV, CI, MallocType, Ordering, GVI,
|
||||||
|
TD, TLI))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1775,7 +1783,8 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
|
|||||||
|
|
||||||
// Delete any stores we can find to the global. We may not be able to
|
// Delete any stores we can find to the global. We may not be able to
|
||||||
// make it completely dead though.
|
// make it completely dead though.
|
||||||
bool Changed = CleanupConstantGlobalUsers(GV, GV->getInitializer());
|
bool Changed = CleanupConstantGlobalUsers(GV, GV->getInitializer(),
|
||||||
|
TD, TLI);
|
||||||
|
|
||||||
// If the global is dead now, delete it.
|
// If the global is dead now, delete it.
|
||||||
if (GV->use_empty()) {
|
if (GV->use_empty()) {
|
||||||
@ -1790,7 +1799,7 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
|
|||||||
GV->setConstant(true);
|
GV->setConstant(true);
|
||||||
|
|
||||||
// Clean up any obviously simplifiable users now.
|
// Clean up any obviously simplifiable users now.
|
||||||
CleanupConstantGlobalUsers(GV, GV->getInitializer());
|
CleanupConstantGlobalUsers(GV, GV->getInitializer(), TD, TLI);
|
||||||
|
|
||||||
// If the global is dead now, just nuke it.
|
// If the global is dead now, just nuke it.
|
||||||
if (GV->use_empty()) {
|
if (GV->use_empty()) {
|
||||||
@ -1819,7 +1828,7 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
|
|||||||
GV->setInitializer(SOVConstant);
|
GV->setInitializer(SOVConstant);
|
||||||
|
|
||||||
// Clean up any obviously simplifiable users now.
|
// Clean up any obviously simplifiable users now.
|
||||||
CleanupConstantGlobalUsers(GV, GV->getInitializer());
|
CleanupConstantGlobalUsers(GV, GV->getInitializer(), TD, TLI);
|
||||||
|
|
||||||
if (GV->use_empty()) {
|
if (GV->use_empty()) {
|
||||||
DEBUG(dbgs() << " *** Substituting initializer allowed us to "
|
DEBUG(dbgs() << " *** Substituting initializer allowed us to "
|
||||||
@ -1836,7 +1845,7 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
|
|||||||
// Try to optimize globals based on the knowledge that only one value
|
// Try to optimize globals based on the knowledge that only one value
|
||||||
// (besides its initializer) is ever stored to the global.
|
// (besides its initializer) is ever stored to the global.
|
||||||
if (OptimizeOnceStoredGlobal(GV, GS.StoredOnceValue, GS.Ordering, GVI,
|
if (OptimizeOnceStoredGlobal(GV, GS.StoredOnceValue, GS.Ordering, GVI,
|
||||||
getAnalysisIfAvailable<TargetData>()))
|
TD, TLI))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Otherwise, if the global was not a boolean, we can shrink it to be a
|
// Otherwise, if the global was not a boolean, we can shrink it to be a
|
||||||
@ -2844,6 +2853,9 @@ bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) {
|
|||||||
bool GlobalOpt::runOnModule(Module &M) {
|
bool GlobalOpt::runOnModule(Module &M) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
|
TD = getAnalysisIfAvailable<TargetData>();
|
||||||
|
TLI = getAnalysisIfAvailable<TargetLibraryInfo>();
|
||||||
|
|
||||||
// Try to find the llvm.globalctors list.
|
// Try to find the llvm.globalctors list.
|
||||||
GlobalVariable *GlobalCtors = FindGlobalCtors(M);
|
GlobalVariable *GlobalCtors = FindGlobalCtors(M);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user