[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