@@ -799,7 +799,12 @@ void RewriteInstance::discoverFileObjects() {
799
799
}
800
800
801
801
// Sort symbols in the file by value. Ignore symbols from non-allocatable
802
- // sections.
802
+ // sections. We memoize getAddress(), as it has rather high overhead.
803
+ struct SymbolInfo {
804
+ uint64_t Address;
805
+ SymbolRef Symbol;
806
+ };
807
+ std::vector<SymbolInfo> SortedSymbols;
803
808
auto isSymbolInMemory = [this ](const SymbolRef &Sym) {
804
809
if (cantFail (Sym.getType ()) == SymbolRef::ST_File)
805
810
return false ;
@@ -810,37 +815,33 @@ void RewriteInstance::discoverFileObjects() {
810
815
BinarySection Section (*BC, *cantFail (Sym.getSection ()));
811
816
return Section.isAllocatable ();
812
817
};
813
- std::vector<SymbolRef> SortedFileSymbols;
814
- llvm::copy_if (InputFile->symbols (), std::back_inserter (SortedFileSymbols),
815
- isSymbolInMemory);
816
- auto CompareSymbols = [this ](const SymbolRef &A, const SymbolRef &B) {
817
- // Marker symbols have the highest precedence, while
818
- // SECTIONs have the lowest.
819
- auto AddressA = cantFail (A.getAddress ());
820
- auto AddressB = cantFail (B.getAddress ());
821
- if (AddressA != AddressB)
822
- return AddressA < AddressB;
823
-
824
- bool AMarker = BC->isMarker (A);
825
- bool BMarker = BC->isMarker (B);
818
+ for (const SymbolRef &Symbol : InputFile->symbols ())
819
+ if (isSymbolInMemory (Symbol))
820
+ SortedSymbols.push_back ({cantFail (Symbol.getAddress ()), Symbol});
821
+
822
+ auto CompareSymbols = [this ](const SymbolInfo &A, const SymbolInfo &B) {
823
+ if (A.Address != B.Address )
824
+ return A.Address < B.Address ;
825
+
826
+ const bool AMarker = BC->isMarker (A.Symbol );
827
+ const bool BMarker = BC->isMarker (B.Symbol );
826
828
if (AMarker || BMarker) {
827
829
return AMarker && !BMarker;
828
830
}
829
831
830
- auto AType = cantFail (A.getType ());
831
- auto BType = cantFail (B.getType ());
832
+ const auto AType = cantFail (A. Symbol .getType ());
833
+ const auto BType = cantFail (B. Symbol .getType ());
832
834
if (AType == SymbolRef::ST_Function && BType != SymbolRef::ST_Function)
833
835
return true ;
834
836
if (BType == SymbolRef::ST_Debug && AType != SymbolRef::ST_Debug)
835
837
return true ;
836
838
837
839
return false ;
838
840
};
841
+ llvm::stable_sort (SortedSymbols, CompareSymbols);
839
842
840
- llvm::stable_sort (SortedFileSymbols, CompareSymbols);
841
-
842
- auto LastSymbol = SortedFileSymbols.end ();
843
- if (!SortedFileSymbols.empty ())
843
+ auto LastSymbol = SortedSymbols.end ();
844
+ if (!SortedSymbols.empty ())
844
845
--LastSymbol;
845
846
846
847
// For aarch64, the ABI defines mapping symbols so we identify data in the
@@ -855,39 +856,34 @@ void RewriteInstance::discoverFileObjects() {
855
856
};
856
857
857
858
std::vector<MarkerSym> SortedMarkerSymbols;
858
- auto addExtraDataMarkerPerSymbol =
859
- [this ](const std::vector<SymbolRef> &SortedFileSymbols,
860
- std::vector<MarkerSym> &SortedMarkerSymbols) {
861
- bool IsData = false ;
862
- uint64_t LastAddr = 0 ;
863
- for (auto Sym = SortedFileSymbols.begin ();
864
- Sym < SortedFileSymbols.end (); ++Sym) {
865
- uint64_t Address = cantFail (Sym->getAddress ());
866
- if (LastAddr == Address) // don't repeat markers
867
- continue ;
859
+ auto addExtraDataMarkerPerSymbol = [&]() {
860
+ bool IsData = false ;
861
+ uint64_t LastAddr = 0 ;
862
+ for (const auto &SymInfo : SortedSymbols) {
863
+ if (LastAddr == SymInfo.Address ) // don't repeat markers
864
+ continue ;
868
865
869
- MarkerSymType MarkerType = BC->getMarkerType (*Sym );
870
- if (MarkerType != MarkerSymType::NONE) {
871
- SortedMarkerSymbols.push_back (MarkerSym{Address, MarkerType});
872
- LastAddr = Address;
873
- IsData = MarkerType == MarkerSymType::DATA;
874
- continue ;
875
- }
866
+ MarkerSymType MarkerType = BC->getMarkerType (SymInfo. Symbol );
867
+ if (MarkerType != MarkerSymType::NONE) {
868
+ SortedMarkerSymbols.push_back (MarkerSym{SymInfo. Address , MarkerType});
869
+ LastAddr = SymInfo. Address ;
870
+ IsData = MarkerType == MarkerSymType::DATA;
871
+ continue ;
872
+ }
876
873
877
- if (IsData) {
878
- SortedMarkerSymbols.push_back (
879
- MarkerSym{cantFail (Sym->getAddress ()), MarkerSymType::DATA});
880
- LastAddr = Address;
881
- }
882
- }
883
- };
874
+ if (IsData) {
875
+ SortedMarkerSymbols.push_back ({SymInfo.Address , MarkerSymType::DATA});
876
+ LastAddr = SymInfo.Address ;
877
+ }
878
+ }
879
+ };
884
880
885
881
if (BC->isAArch64 () || BC->isRISCV ()) {
886
- addExtraDataMarkerPerSymbol (SortedFileSymbols, SortedMarkerSymbols );
882
+ addExtraDataMarkerPerSymbol ();
887
883
LastSymbol = std::stable_partition (
888
- SortedFileSymbols .begin (), SortedFileSymbols .end (),
889
- [this ](const SymbolRef &Symbol ) { return !BC->isMarker (Symbol); });
890
- if (!SortedFileSymbols .empty ())
884
+ SortedSymbols .begin (), SortedSymbols .end (),
885
+ [this ](const SymbolInfo &S ) { return !BC->isMarker (S. Symbol ); });
886
+ if (!SortedSymbols .empty ())
891
887
--LastSymbol;
892
888
}
893
889
@@ -897,12 +893,11 @@ void RewriteInstance::discoverFileObjects() {
897
893
// Regex object for matching cold fragments.
898
894
Regex ColdFragment (" .*\\ .cold(\\ .[0-9]+)?" );
899
895
900
- const auto SortedSymbolsEnd = LastSymbol == SortedFileSymbols.end ()
901
- ? LastSymbol
902
- : std::next (LastSymbol);
903
- for (auto ISym = SortedFileSymbols.begin (); ISym != SortedSymbolsEnd;
904
- ++ISym) {
905
- const SymbolRef &Symbol = *ISym;
896
+ const auto SortedSymbolsEnd =
897
+ LastSymbol == SortedSymbols.end () ? LastSymbol : std::next (LastSymbol);
898
+ for (auto Iter = SortedSymbols.begin (); Iter != SortedSymbolsEnd; ++Iter) {
899
+ const SymbolRef &Symbol = Iter->Symbol ;
900
+
906
901
// Keep undefined symbols for pretty printing?
907
902
if (cantFail (Symbol.getFlags ()) & SymbolRef::SF_Undefined)
908
903
continue ;
0 commit comments