This is an archive of the discontinued LLVM Phabricator instance.

[clang][deps] Make order of module dependencies deterministic
ClosedPublic

Authored by benlangmuir on Jun 7 2022, 12:28 PM.

Details

Summary

This fixes the underlying module dependencies, which had a non-deterministic order, which was also visible in the order of calls to DependencyConsumer methods. This was not directly observable in the clang-scan-deps utility, because it was previously seeing a sorted order from std::map in DependencyScanningTool. However, the underlying API previously created a likely issue for any other clients. Note: if you only apply the change from DependencyScanningTool, you can see the issue in clang-scan-deps, and existing tests will fail non-deterministicaly.

Diff Detail

Event Timeline

benlangmuir created this revision.Jun 7 2022, 12:28 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 7 2022, 12:28 PM
Herald added a subscriber: mgrang. · View Herald Transcript
benlangmuir requested review of this revision.Jun 7 2022, 12:28 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 7 2022, 12:28 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
jansvoboda11 added inline comments.Jun 8 2022, 1:02 AM
clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
179

What's the reason for wrapping ModuleDeps in unique_ptr?

benlangmuir added inline comments.Jun 8 2022, 8:38 AM
clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
179

Oh hmm, my thinking was that DenseMap is optimized for small values, but I guess in this setup the map only stores integers and the values are in a vector. I'll change this to values, thanks!

Removed use of std::unique_ptr in DependencyScanningTool.cpp, per review feedback.

@jansvoboda11 Note: there is another map containing std::unique_ptr<ModuleDeps> in ModuleDepCollector, but that one is required for correctness. The problem is that there is code that forms a ModuleDeps & lvalue and assumes it will be correct after mutating the containing ModularDeps map. For example, the signature of addAllSubmoduleDeps requires this. If we want to switch to using this as a value in the map, we would need to do the lookup in the map again after each mutation. This code worked previously with unordered_map, because it guarantees that keys and values are not mutated by unrelated mutations of the containing map, unlike MapVector. In practice, this means there is no additional overhead from the unique_ptr, because it was already doing a separate allocation for each value in the unordered_map.

jansvoboda11 accepted this revision.Jun 8 2022, 10:19 AM

Thanks for explaining this, LGTM.

This revision is now accepted and ready to land.Jun 8 2022, 10:19 AM
This revision was landed with ongoing or failed builds.Jun 8 2022, 11:11 AM
This revision was automatically updated to reflect the committed changes.