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?