aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/IPO/GlobalOpt.cpp
diff options
context:
space:
mode:
authorZhou Sheng <zhousheng00@gmail.com>2012-12-01 04:38:53 +0000
committerZhou Sheng <zhousheng00@gmail.com>2012-12-01 04:38:53 +0000
commit702aa2ee19132593b552d211c985aa540787c197 (patch)
treed2b4219bc2bca91ac6c71882afdef9419f506f33 /lib/Transforms/IPO/GlobalOpt.cpp
parent2587a8a18c55116b339d4b47d441512067e9c96b (diff)
downloadexternal_llvm-702aa2ee19132593b552d211c985aa540787c197.zip
external_llvm-702aa2ee19132593b552d211c985aa540787c197.tar.gz
external_llvm-702aa2ee19132593b552d211c985aa540787c197.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169079 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/GlobalOpt.cpp')
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index 591278f..54b97fa 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -36,6 +36,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
@@ -2398,7 +2399,8 @@ static bool isSimpleEnoughPointerToCommit(Constant *C) {
/// 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.
static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
- ConstantExpr *Addr, unsigned OpNo) {
+ ConstantExpr *Addr, unsigned OpNo,
+ SetVector<Constant*>& Obsolete) {
// Base case of the recursion.
if (OpNo == Addr->getNumOperands()) {
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));
unsigned Idx = CU->getZExtValue();
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 ConstantStruct::get(STy, Elts);
@@ -2435,8 +2439,11 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
Elts.push_back(Init->getAggregateElement(i));
assert(CI->getZExtValue() < NumElts);
+ Constant *OrigElem = Elts[CI->getZExtValue()];
+ if (OrigElem->getType()->isAggregateType())
+ Obsolete.insert(OrigElem);
Elts[CI->getZExtValue()] =
- EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1);
+ EvaluateStoreInto(OrigElem, Val, Addr, OpNo+1, Obsolete);
if (Init->getType()->isArrayTy())
return ConstantArray::get(cast<ArrayType>(InitTy), Elts);
@@ -2452,9 +2459,20 @@ static void CommitValueTo(Constant *Val, Constant *Addr) {
return;
}
+ // Collect obsolete constants created in previous CommitValueTo() invoke.
+ SetVector<Constant*> Obsolete;
ConstantExpr *CE = cast<ConstantExpr>(Addr);
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 {