This speeds-up thin-link by ~47% for large programs.
Details
Diff Detail
- Build Status
Buildable 8103 Build 8103: arc lint + arc unit
Event Timeline
When we used an std::map originally it was because we needed the ordering. Have you checked that we don't iterate on any instance of this map?
| lib/LTO/LTO.cpp | ||
|---|---|---|
| 1033 | Can we use GVSummaryMapTy here? | |
From http://llvm.org/docs/ProgrammersManual.html#llvm-adt-densemap-h it doesn't appear that iteration order is an issue for DenseMap. StringMap on the other hand does not have a deterministic iteration ordering, and I recall using a std::map somewhere instead of a StringMap for that reason.
Note the index itself still uses a std::map, for other reasons (documented at the declaration). We also still use a std::map where we write out the individual index files for the backends in the distributed backend case. In any case from what I can tell, we typically query this map, rather than iterate. The only place I see an iteration is when we are computing imports for a module, so I suppose that could affect the debug output ordering, but does that matter (if iteration order is even non-deterministic for DenseMap, and from what I can tell from the LLVM doc linked above it isn't).
As long as keys aren't pointers...
(But just as every hash_map right?)
StringMap on the other hand does not have a deterministic iteration ordering, and I recall using a std::map somewhere instead of a StringMap for that reason.
Really? I'm pretty sure the order is deterministic, but just like any hash_map (including DenseMap): the order of insertion and the hash function are determining the resulting order.
Note the index itself still uses a std::map, for other reasons (documented at the declaration). We also still use a std::map where we write out the individual index files for the backends in the distributed backend case. In any case from what I can tell, we typically query this map, rather than iterate. The only place I see an iteration is when we are computing imports for a module, so I suppose that could affect the debug output ordering, but does that matter (if iteration order is even non-deterministic for DenseMap, and from what I can tell from the LLVM doc linked above it isn't).
OK!
How should we proceed with this patch?
There are indeed some code that iterates through this type, e.g.:
// Populate the worklist with the import for the functions in the current
// module
for (auto &GVSummary : DefinedGVSummaries) {
if (!Index.isGlobalValueLive(GVSummary.second)) {
DEBUG(dbgs() << "Ignores Dead GUID: " << GVSummary.first << "\n");
continue;
}
auto *Summary = GVSummary.second;
if (auto *AS = dyn_cast<AliasSummary>(Summary))
Summary = &AS->getAliasee();
auto *FuncSummary = dyn_cast<FunctionSummary>(Summary);
if (!FuncSummary)
// Skip import for global variables
continue;
DEBUG(dbgs() << "Initalize import for " << GVSummary.first << "\n");
computeImportForFunction(*FuncSummary, Index, ImportInstrLimit,
DefinedGVSummaries, Worklist, ImportList,
ExportLists);
}
Can we use GVSummaryMapTy here?