1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

The patch is to improve the memory footprint of pass GlobalOpt.

Also check in a case to repeat the issue, on which 'opt -globalopt' consumes 1.6GB memory.
The big memory footprint cause is that current GlobalOpt one by one hoists and stores the leaf element constant into the global array, in each iteration, it recreates the global array initializer constant and leave the old initializer alone. This may result in many obsolete constants left.
For example:  we have global array @rom = global [16 x i32] zeroinitializer
After the first element value is hoisted and installed:   @rom = global [16 x i32] [ 1, 0, 0, ... ]
After the second element value is installed:  @rom = global [16 x 32] [ 1, 2, 0, 0, ... ]        // here the previous initializer is obsolete
...
When the transform is done, we have 15 obsolete initializers left useless.

llvm-svn: 169079
This commit is contained in:
Zhou Sheng 2012-12-01 04:38:53 +00:00
parent 171e0dd910
commit f4e0514807
2 changed files with 8331 additions and 4 deletions

View File

@ -36,6 +36,7 @@
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include <algorithm> #include <algorithm>
@ -2398,7 +2399,8 @@ static bool isSimpleEnoughPointerToCommit(Constant *C) {
/// initializer. This returns 'Init' modified to reflect 'Val' stored into it. /// initializer. This returns 'Init' modified to reflect 'Val' stored into it.
/// At this point, the GEP operands of Addr [0, OpNo) have been stepped into. /// At this point, the GEP operands of Addr [0, OpNo) have been stepped into.
static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
ConstantExpr *Addr, unsigned OpNo) { ConstantExpr *Addr, unsigned OpNo,
SetVector<Constant*>& Obsolete) {
// Base case of the recursion. // Base case of the recursion.
if (OpNo == Addr->getNumOperands()) { if (OpNo == Addr->getNumOperands()) {
assert(Val->getType() == Init->getType() && "Type mismatch!"); assert(Val->getType() == Init->getType() && "Type mismatch!");
@ -2415,7 +2417,9 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
ConstantInt *CU = cast<ConstantInt>(Addr->getOperand(OpNo)); ConstantInt *CU = cast<ConstantInt>(Addr->getOperand(OpNo));
unsigned Idx = CU->getZExtValue(); unsigned Idx = CU->getZExtValue();
assert(Idx < STy->getNumElements() && "Struct index out of range!"); assert(Idx < STy->getNumElements() && "Struct index out of range!");
Elts[Idx] = EvaluateStoreInto(Elts[Idx], Val, Addr, OpNo+1); if (Elts[Idx]->getType()->isAggregateType())
Obsolete.insert(Elts[Idx]);
Elts[Idx] = EvaluateStoreInto(Elts[Idx], Val, Addr, OpNo+1, Obsolete);
// Return the modified struct. // Return the modified struct.
return ConstantStruct::get(STy, Elts); return ConstantStruct::get(STy, Elts);
@ -2435,8 +2439,11 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
Elts.push_back(Init->getAggregateElement(i)); Elts.push_back(Init->getAggregateElement(i));
assert(CI->getZExtValue() < NumElts); assert(CI->getZExtValue() < NumElts);
Constant *OrigElem = Elts[CI->getZExtValue()];
if (OrigElem->getType()->isAggregateType())
Obsolete.insert(OrigElem);
Elts[CI->getZExtValue()] = Elts[CI->getZExtValue()] =
EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1); EvaluateStoreInto(OrigElem, Val, Addr, OpNo+1, Obsolete);
if (Init->getType()->isArrayTy()) if (Init->getType()->isArrayTy())
return ConstantArray::get(cast<ArrayType>(InitTy), Elts); return ConstantArray::get(cast<ArrayType>(InitTy), Elts);
@ -2452,9 +2459,20 @@ static void CommitValueTo(Constant *Val, Constant *Addr) {
return; return;
} }
// Collect obsolete constants created in previous CommitValueTo() invoke.
SetVector<Constant*> Obsolete;
ConstantExpr *CE = cast<ConstantExpr>(Addr); ConstantExpr *CE = cast<ConstantExpr>(Addr);
GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0)); GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
GV->setInitializer(EvaluateStoreInto(GV->getInitializer(), Val, CE, 2)); Constant *OrigInit = GV->getInitializer();
if (OrigInit->getType()->isAggregateType())
Obsolete.insert(OrigInit);
Constant *Init = EvaluateStoreInto(OrigInit, Val, CE, 2, Obsolete);
GV->setInitializer(Init);
for (unsigned i = 0; i < Obsolete.size(); ++i) {
if (Obsolete[i]->use_empty())
Obsolete[i]->destroyConstant();
}
} }
namespace { namespace {

File diff suppressed because it is too large Load Diff