Skip to content

Commit 1f38d49

Browse files
authored
ValueMapper: Delete unused initializers of replaced appending globals.
A full LTO link time performance and memory regression was introduced by #137081 in cases where the modules contain large quantities of llvm.used globals. This was unnoticed because it was not expected that this would be a typical case, but this is exactly what coverage collection does, and when this feature is enabled together with full LTO we end up with quadratic memory consumption (from the unused constants) and quadratic complexity in the function Verifier::visitGlobalValue (which visits all the unused constants in the use list of each global value). This is a targeted fix that avoids reintroducing the quadratic complexity from before #137081, by having ValueMapper delete the old initializer of an appending global if it is unused, instead of visiting every global in the context after every link. The repro-cfi-64 reproducer from #167037 before and after this change: ``` Elapsed time Max RSS (KB) Before 12:05.11 52537184 After 3:27.68 7520696 ``` Fixes #167037. Reviewers: nikic, teresajohnson Reviewed By: teresajohnson Pull Request: #167629
1 parent 905ee44 commit 1f38d49

File tree

3 files changed

+17
-14
lines changed

3 files changed

+17
-14
lines changed

llvm/include/llvm/Transforms/Utils/ValueMapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ class ValueMapper {
204204
LLVM_ABI void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
205205
unsigned MappingContextID = 0);
206206
LLVM_ABI void scheduleMapAppendingVariable(GlobalVariable &GV,
207-
Constant *InitPrefix,
207+
GlobalVariable *OldGV,
208208
bool IsOldCtorDtor,
209209
ArrayRef<Constant *> NewMembers,
210210
unsigned MappingContextID = 0);

llvm/lib/Linker/IRMover.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -882,10 +882,7 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
882882
NG->copyAttributesFrom(SrcGV);
883883
forceRenaming(NG, SrcGV->getName());
884884

885-
Mapper.scheduleMapAppendingVariable(
886-
*NG,
887-
(DstGV && !DstGV->isDeclaration()) ? DstGV->getInitializer() : nullptr,
888-
IsOldStructor, SrcElements);
885+
Mapper.scheduleMapAppendingVariable(*NG, DstGV, IsOldStructor, SrcElements);
889886

890887
// Replace any uses of the two global variables with uses of the new
891888
// global.

llvm/lib/Transforms/Utils/ValueMapper.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ struct WorklistEntry {
7777
};
7878
struct AppendingGVTy {
7979
GlobalVariable *GV;
80-
Constant *InitPrefix;
80+
GlobalVariable *OldGV;
8181
};
8282
struct AliasOrIFuncTy {
8383
GlobalValue *GV;
@@ -162,7 +162,7 @@ class Mapper {
162162

163163
void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
164164
unsigned MCID);
165-
void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
165+
void scheduleMapAppendingVariable(GlobalVariable &GV, GlobalVariable *OldGV,
166166
bool IsOldCtorDtor,
167167
ArrayRef<Constant *> NewMembers,
168168
unsigned MCID);
@@ -173,7 +173,7 @@ class Mapper {
173173
void flush();
174174

175175
private:
176-
void mapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
176+
void mapAppendingVariable(GlobalVariable &GV, GlobalVariable *OldGV,
177177
bool IsOldCtorDtor,
178178
ArrayRef<Constant *> NewMembers);
179179

@@ -944,7 +944,7 @@ void Mapper::flush() {
944944
drop_begin(AppendingInits, PrefixSize));
945945
AppendingInits.resize(PrefixSize);
946946
mapAppendingVariable(*E.Data.AppendingGV.GV,
947-
E.Data.AppendingGV.InitPrefix,
947+
E.Data.AppendingGV.OldGV,
948948
E.AppendingGVIsOldCtorDtor, ArrayRef(NewInits));
949949
break;
950950
}
@@ -1094,15 +1094,21 @@ void Mapper::remapFunction(Function &F) {
10941094
}
10951095
}
10961096

1097-
void Mapper::mapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
1097+
void Mapper::mapAppendingVariable(GlobalVariable &GV, GlobalVariable *OldGV,
10981098
bool IsOldCtorDtor,
10991099
ArrayRef<Constant *> NewMembers) {
1100+
Constant *InitPrefix =
1101+
(OldGV && !OldGV->isDeclaration()) ? OldGV->getInitializer() : nullptr;
1102+
11001103
SmallVector<Constant *, 16> Elements;
11011104
if (InitPrefix) {
11021105
unsigned NumElements =
11031106
cast<ArrayType>(InitPrefix->getType())->getNumElements();
11041107
for (unsigned I = 0; I != NumElements; ++I)
11051108
Elements.push_back(InitPrefix->getAggregateElement(I));
1109+
OldGV->setInitializer(nullptr);
1110+
if (InitPrefix->hasUseList() && InitPrefix->use_empty())
1111+
InitPrefix->destroyConstant();
11061112
}
11071113

11081114
PointerType *VoidPtrTy;
@@ -1148,7 +1154,7 @@ void Mapper::scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
11481154
}
11491155

11501156
void Mapper::scheduleMapAppendingVariable(GlobalVariable &GV,
1151-
Constant *InitPrefix,
1157+
GlobalVariable *OldGV,
11521158
bool IsOldCtorDtor,
11531159
ArrayRef<Constant *> NewMembers,
11541160
unsigned MCID) {
@@ -1159,7 +1165,7 @@ void Mapper::scheduleMapAppendingVariable(GlobalVariable &GV,
11591165
WE.Kind = WorklistEntry::MapAppendingVar;
11601166
WE.MCID = MCID;
11611167
WE.Data.AppendingGV.GV = &GV;
1162-
WE.Data.AppendingGV.InitPrefix = InitPrefix;
1168+
WE.Data.AppendingGV.OldGV = OldGV;
11631169
WE.AppendingGVIsOldCtorDtor = IsOldCtorDtor;
11641170
WE.AppendingGVNumNewMembers = NewMembers.size();
11651171
Worklist.push_back(WE);
@@ -1282,12 +1288,12 @@ void ValueMapper::scheduleMapGlobalInitializer(GlobalVariable &GV,
12821288
}
12831289

12841290
void ValueMapper::scheduleMapAppendingVariable(GlobalVariable &GV,
1285-
Constant *InitPrefix,
1291+
GlobalVariable *OldGV,
12861292
bool IsOldCtorDtor,
12871293
ArrayRef<Constant *> NewMembers,
12881294
unsigned MCID) {
12891295
getAsMapper(pImpl)->scheduleMapAppendingVariable(
1290-
GV, InitPrefix, IsOldCtorDtor, NewMembers, MCID);
1296+
GV, OldGV, IsOldCtorDtor, NewMembers, MCID);
12911297
}
12921298

12931299
void ValueMapper::scheduleMapGlobalAlias(GlobalAlias &GA, Constant &Aliasee,

0 commit comments

Comments
 (0)