11
11
#include < stdio.h>
12
12
13
13
#include < vector>
14
+ #include < set>
14
15
15
16
#include " rustllvm.h"
16
17
@@ -885,86 +886,6 @@ getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
885
886
return FirstDefForLinker->get ();
886
887
}
887
888
888
- // This is a helper function we added that isn't present in LLVM's source.
889
- //
890
- // The way LTO works in Rust is that we typically have a number of symbols that
891
- // we know ahead of time need to be preserved. We want to ensure that ThinLTO
892
- // doesn't accidentally internalize any of these and otherwise is always
893
- // ready to keep them linking correctly.
894
- //
895
- // This function will recursively walk the `GUID` provided and all of its
896
- // references, as specified in the `Index`. In other words, we're taking a
897
- // `GUID` as input, adding it to `Preserved`, and then taking all `GUID`
898
- // items that the input references and recursing.
899
- static void
900
- addPreservedGUID (const ModuleSummaryIndex &Index,
901
- DenseSet<GlobalValue::GUID> &Preserved,
902
- GlobalValue::GUID GUID) {
903
- if (Preserved.count (GUID))
904
- return ;
905
- Preserved.insert (GUID);
906
-
907
- #if LLVM_VERSION_GE(5, 0)
908
- auto Info = Index.getValueInfo (GUID);
909
- if (!Info) {
910
- return ;
911
- }
912
- for (auto &Summary : Info.getSummaryList ()) {
913
- for (auto &Ref : Summary->refs ()) {
914
- addPreservedGUID (Index, Preserved, Ref.getGUID ());
915
- }
916
-
917
- GlobalValueSummary *GVSummary = Summary.get ();
918
- if (isa<FunctionSummary>(GVSummary)) {
919
- auto *FS = cast<FunctionSummary>(GVSummary);
920
- for (auto &Call: FS->calls ()) {
921
- addPreservedGUID (Index, Preserved, Call.first .getGUID ());
922
- }
923
- for (auto &GUID: FS->type_tests ()) {
924
- addPreservedGUID (Index, Preserved, GUID);
925
- }
926
- }
927
- if (isa<AliasSummary>(GVSummary)) {
928
- auto *AS = cast<AliasSummary>(GVSummary);
929
- auto GUID = AS->getAliasee ().getOriginalName ();
930
- addPreservedGUID (Index, Preserved, GUID);
931
- }
932
- }
933
- #else
934
- auto SummaryList = Index.findGlobalValueSummaryList (GUID);
935
- if (SummaryList == Index.end ())
936
- return ;
937
- for (auto &Summary : SummaryList->second ) {
938
- for (auto &Ref : Summary->refs ()) {
939
- if (Ref.isGUID ()) {
940
- addPreservedGUID (Index, Preserved, Ref.getGUID ());
941
- } else {
942
- auto Value = Ref.getValue ();
943
- addPreservedGUID (Index, Preserved, Value->getGUID ());
944
- }
945
- }
946
-
947
- if (auto *FS = dyn_cast<FunctionSummary>(Summary.get ())) {
948
- for (auto &Call: FS->calls ()) {
949
- if (Call.first .isGUID ()) {
950
- addPreservedGUID (Index, Preserved, Call.first .getGUID ());
951
- } else {
952
- auto Value = Call.first .getValue ();
953
- addPreservedGUID (Index, Preserved, Value->getGUID ());
954
- }
955
- }
956
- for (auto &GUID: FS->type_tests ()) {
957
- addPreservedGUID (Index, Preserved, GUID);
958
- }
959
- }
960
- if (auto *AS = dyn_cast<AliasSummary>(Summary.get ())) {
961
- auto GUID = AS->getAliasee ().getOriginalName ();
962
- addPreservedGUID (Index, Preserved, GUID);
963
- }
964
- }
965
- #endif
966
- }
967
-
968
889
// The main entry point for creating the global ThinLTO analysis. The structure
969
890
// here is basically the same as before threads are spawned in the `run`
970
891
// function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
@@ -1004,12 +925,10 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
1004
925
Ret->Index .collectDefinedGVSummariesPerModule (Ret->ModuleToDefinedGVSummaries );
1005
926
1006
927
// Convert the preserved symbols set from string to GUID, this is then needed
1007
- // for internalization. We use `addPreservedGUID` to include any transitively
1008
- // used symbol as well.
928
+ // for internalization.
1009
929
for (int i = 0 ; i < num_symbols; i++) {
1010
- addPreservedGUID (Ret->Index ,
1011
- Ret->GUIDPreservedSymbols ,
1012
- GlobalValue::getGUID (preserved_symbols[i]));
930
+ auto GUID = GlobalValue::getGUID (preserved_symbols[i]);
931
+ Ret->GUIDPreservedSymbols .insert (GUID);
1013
932
}
1014
933
1015
934
// Collect the import/export lists for all modules from the call-graph in the
@@ -1038,7 +957,8 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
1038
957
// Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
1039
958
// impacts the caching.
1040
959
//
1041
- // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
960
+ // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` with some of this
961
+ // being lifted from `lib/LTO/LTO.cpp` as well
1042
962
StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1043
963
DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
1044
964
for (auto &I : Ret->Index ) {
@@ -1062,11 +982,27 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
1062
982
ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1063
983
};
1064
984
thinLTOResolveWeakForLinkerInIndex (Ret->Index , isPrevailing, recordNewLinkage);
985
+
986
+ // Here we calculate an `ExportedGUIDs` set for use in the `isExported`
987
+ // callback below. This callback below will dictate the linkage for all
988
+ // summaries in the index, and we basically just only want to ensure that dead
989
+ // symbols are internalized. Otherwise everything that's already external
990
+ // linkage will stay as external, and internal will stay as internal.
991
+ std::set<GlobalValue::GUID> ExportedGUIDs;
992
+ for (auto &List : Ret->Index ) {
993
+ for (auto &GVS: List.second ) {
994
+ if (!GlobalValue::isExternalLinkage (GVS->linkage ()))
995
+ continue ;
996
+ auto GUID = GVS->getOriginalName ();
997
+ if (!DeadSymbols.count (GUID))
998
+ ExportedGUIDs.insert (GUID);
999
+ }
1000
+ }
1065
1001
auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
1066
1002
const auto &ExportList = Ret->ExportLists .find (ModuleIdentifier);
1067
1003
return (ExportList != Ret->ExportLists .end () &&
1068
1004
ExportList->second .count (GUID)) ||
1069
- Ret-> GUIDPreservedSymbols .count (GUID);
1005
+ ExportedGUIDs .count (GUID);
1070
1006
};
1071
1007
thinLTOInternalizeAndPromoteInIndex (Ret->Index , isExported);
1072
1008
0 commit comments