[llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp
Chris Lattner
sabre at nondot.org
Thu Feb 10 11:32:54 PST 2005
On Thu, 10 Feb 2005, Reid Spencer wrote:
> Is this a good idea? What if you have a large global variable, say an array
> about 32MB in size. Moving it to the stack will blow the (typically 8MB)
> stack away and cause the program to fail. While its probably a good
> optimization for small things, we ought to set some kind of threshold and not
> perform this optimization if the global variable is very large.
This only applies to scalars.
-Chris
> Alkis Evlogimenos wrote:
>> Changes in directory llvm/lib/Transforms/IPO:
>>
>> GlobalOpt.cpp updated: 1.34 -> 1.35
>> ---
>> Log message:
>>
>> Localize globals if they are only used in main(). This replaces the
>> global with an alloca, which eventually gets promoted into a
>> register. This enables a lot of other optimizations later on.
>>
>>
>> ---
>> Diffs of the changes: (+40 -0)
>>
>> GlobalOpt.cpp | 40 ++++++++++++++++++++++++++++++++++++++++
>> 1 files changed, 40 insertions(+)
>>
>>
>> Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp
>> diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.34
>> llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.35
>> --- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.34 Mon Jan 31 19:23:31
>> 2005
>> +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp Thu Feb 10 12:36:30 2005
>> @@ -38,6 +38,7 @@
>> Statistic<> NumDeleted ("globalopt", "Number of globals deleted");
>> Statistic<> NumFnDeleted("globalopt", "Number of functions deleted");
>> Statistic<> NumGlobUses ("globalopt", "Number of global uses
>> devirtualized");
>> + Statistic<> NumLocalized("globalopt", "Number of globals localized");
>> Statistic<> NumShrunkToBool("globalopt",
>> "Number of global vars shrunk to booleans");
>> @@ -92,12 +93,20 @@
>> /// ever stored to this global, keep track of what value it is.
>> Value *StoredOnceValue;
>> + // AccessingFunction/HasMultipleAccessingFunctions - These start out
>> + // null/false. When the first accessing function is noticed, it is
>> recorded.
>> + // When a second different accessing function is noticed,
>> + // HasMultipleAccessingFunctions is set to true.
>> + Function *AccessingFunction;
>> + bool HasMultipleAccessingFunctions;
>> +
>> /// isNotSuitableForSRA - Keep track of whether any SRA preventing users
>> of
>> /// the global exist. Such users include GEP instruction with variable
>> /// indexes, and non-gep/load/store users like constant expr casts.
>> bool isNotSuitableForSRA;
>> GlobalStatus() : isLoaded(false), StoredType(NotStored),
>> StoredOnceValue(0),
>> + AccessingFunction(0),
>> HasMultipleAccessingFunctions(false),
>> isNotSuitableForSRA(false) {}
>> };
>> @@ -146,6 +155,13 @@
>> }
>> } else if (Instruction *I = dyn_cast<Instruction>(*UI)) {
>> + if (!GS.HasMultipleAccessingFunctions) {
>> + Function *F = I->getParent()->getParent();
>> + if (GS.AccessingFunction == 0)
>> + GS.AccessingFunction = F;
>> + else if (GS.AccessingFunction != F)
>> + GS.HasMultipleAccessingFunctions = true;
>> + }
>> if (isa<LoadInst>(I)) {
>> GS.isLoaded = true;
>> } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
>> @@ -898,6 +914,30 @@
>> }
>> if (!AnalyzeGlobal(GV, GS, PHIUsers)) {
>> + // If this is a first class global and has only one accessing function
>> + // and this function is main (which we know is not recursive we can
>> make
>> + // this global a local variable) we replace the global with a local
>> alloca
>> + // in this function.
>> + //
>> + // NOTE: It doesn't make sense to promote non first class types since
>> we
>> + // are just replacing static memory to stack memory.
>> + if (!GS.HasMultipleAccessingFunctions &&
>> + GS.AccessingFunction &&
>> + GV->getType()->getElementType()->isFirstClassType() &&
>> + GS.AccessingFunction->getName() == "main" &&
>> + GS.AccessingFunction->hasExternalLinkage()) {
>> + DEBUG(std::cerr << "LOCALIZING GLOBAL: " << *GV);
>> + Instruction* FirstI = GS.AccessingFunction->getEntryBlock().begin();
>> + const Type* ElemTy = GV->getType()->getElementType();
>> + AllocaInst* Alloca = new AllocaInst(ElemTy, NULL, GV->getName(),
>> FirstI);
>> + if (!isa<UndefValue>(GV->getInitializer()))
>> + new StoreInst(GV->getInitializer(), Alloca, FirstI);
>> + + GV->replaceAllUsesWith(Alloca);
>> + GV->eraseFromParent();
>> + ++NumLocalized;
>> + return true;
>> + }
>> // If the global is never loaded (but may be stored to), it is dead.
>> // Delete it now.
>> if (!GS.isLoaded) {
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://mail.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-Chris
--
http://nondot.org/sabre/
http://llvm.cs.uiuc.edu/
More information about the llvm-commits
mailing list