@@ -84,6 +84,7 @@ extern cl::opt<bool> KeepNops;
8484extern cl::opt<bool > Lite;
8585extern cl::list<std::string> ReorderData;
8686extern cl::opt<bolt::ReorderFunctions::ReorderType> ReorderFunctions;
87+ extern cl::opt<bool > TerminalHLT;
8788extern cl::opt<bool > TerminalTrap;
8889extern cl::opt<bool > TimeBuild;
8990extern cl::opt<bool > TimeRewrite;
@@ -114,6 +115,35 @@ cl::opt<bool> DumpDotAll(
114115 " enable '-print-loops' for color-coded blocks" ),
115116 cl::Hidden, cl::cat(BoltCategory));
116117
118+ cl::list<std::string> DumpDotFunc (
119+ " dump-dot-func" , cl::CommaSeparated,
120+ cl::desc (
121+ " dump function CFGs to graphviz format for specified functions only;"
122+ " takes function name patterns (regex supported)" ),
123+ cl::value_desc(" func1,func2,func3,..." ), cl::Hidden, cl::cat(BoltCategory));
124+
125+ bool shouldDumpDot (const bolt::BinaryFunction &Function) {
126+ // If dump-dot-all is enabled, dump all functions
127+ if (DumpDotAll)
128+ return !Function.isIgnored ();
129+
130+ // If no specific functions specified in dump-dot-func, don't dump any
131+ if (DumpDotFunc.empty ())
132+ return false ;
133+
134+ if (Function.isIgnored ())
135+ return false ;
136+
137+ // Check if function matches any of the specified patterns
138+ for (const std::string &Name : DumpDotFunc) {
139+ if (Function.hasNameRegex (Name)) {
140+ return true ;
141+ }
142+ }
143+
144+ return false ;
145+ }
146+
117147static cl::list<std::string>
118148ForceFunctionNames (" funcs" ,
119149 cl::CommaSeparated,
@@ -880,14 +910,9 @@ void RewriteInstance::discoverFileObjects() {
880910 // code section (see IHI0056B). $d identifies data contents.
881911 // Compilers usually merge multiple data objects in a single $d-$x interval,
882912 // but we need every data object to be marked with $d. Because of that we
883- // create a vector of MarkerSyms with all locations of data objects.
913+ // keep track of marker symbols with all locations of data objects.
884914
885- struct MarkerSym {
886- uint64_t Address;
887- MarkerSymType Type;
888- };
889-
890- std::vector<MarkerSym> SortedMarkerSymbols;
915+ DenseMap<uint64_t , MarkerSymType> MarkerSymbols;
891916 auto addExtraDataMarkerPerSymbol = [&]() {
892917 bool IsData = false ;
893918 uint64_t LastAddr = 0 ;
@@ -911,14 +936,14 @@ void RewriteInstance::discoverFileObjects() {
911936 }
912937
913938 if (MarkerType != MarkerSymType::NONE) {
914- SortedMarkerSymbols. push_back (MarkerSym{ SymInfo.Address , MarkerType}) ;
939+ MarkerSymbols[ SymInfo.Address ] = MarkerType;
915940 LastAddr = SymInfo.Address ;
916941 IsData = MarkerType == MarkerSymType::DATA;
917942 continue ;
918943 }
919944
920945 if (IsData) {
921- SortedMarkerSymbols. push_back ({ SymInfo.Address , MarkerSymType::DATA}) ;
946+ MarkerSymbols[ SymInfo.Address ] = MarkerSymType::DATA;
922947 LastAddr = SymInfo.Address ;
923948 }
924949 }
@@ -1283,27 +1308,24 @@ void RewriteInstance::discoverFileObjects() {
12831308 BC->setHasSymbolsWithFileName (FileSymbols.size ());
12841309
12851310 // Now that all the functions were created - adjust their boundaries.
1286- adjustFunctionBoundaries ();
1311+ adjustFunctionBoundaries (MarkerSymbols );
12871312
12881313 // Annotate functions with code/data markers in AArch64
1289- for (auto ISym = SortedMarkerSymbols.begin ();
1290- ISym != SortedMarkerSymbols.end (); ++ISym) {
1291-
1292- auto *BF =
1293- BC->getBinaryFunctionContainingAddress (ISym->Address , true , true );
1314+ for (auto &[Address, Type] : MarkerSymbols) {
1315+ auto *BF = BC->getBinaryFunctionContainingAddress (Address, true , true );
12941316
12951317 if (!BF) {
12961318 // Stray marker
12971319 continue ;
12981320 }
1299- const auto EntryOffset = ISym-> Address - BF->getAddress ();
1300- if (ISym-> Type == MarkerSymType::CODE) {
1321+ const auto EntryOffset = Address - BF->getAddress ();
1322+ if (Type == MarkerSymType::CODE) {
13011323 BF->markCodeAtOffset (EntryOffset);
13021324 continue ;
13031325 }
1304- if (ISym-> Type == MarkerSymType::DATA) {
1326+ if (Type == MarkerSymType::DATA) {
13051327 BF->markDataAtOffset (EntryOffset);
1306- BC->AddressToConstantIslandMap [ISym-> Address ] = BF;
1328+ BC->AddressToConstantIslandMap [Address] = BF;
13071329 continue ;
13081330 }
13091331 llvm_unreachable (" Unknown marker" );
@@ -1832,7 +1854,8 @@ void RewriteInstance::disassemblePLT() {
18321854 }
18331855}
18341856
1835- void RewriteInstance::adjustFunctionBoundaries () {
1857+ void RewriteInstance::adjustFunctionBoundaries (
1858+ DenseMap<uint64_t , MarkerSymType> &MarkerSyms) {
18361859 for (auto BFI = BC->getBinaryFunctions ().begin (),
18371860 BFE = BC->getBinaryFunctions ().end ();
18381861 BFI != BFE; ++BFI) {
@@ -1870,12 +1893,15 @@ void RewriteInstance::adjustFunctionBoundaries() {
18701893 continue ;
18711894 }
18721895
1873- // This is potentially another entry point into the function.
1874- uint64_t EntryOffset = NextSymRefI->first - Function.getAddress ();
1875- LLVM_DEBUG (dbgs () << " BOLT-DEBUG: adding entry point to function "
1876- << Function << " at offset 0x"
1877- << Twine::utohexstr (EntryOffset) << ' \n ' );
1878- Function.addEntryPointAtOffset (EntryOffset);
1896+ auto It = MarkerSyms.find (NextSymRefI->first );
1897+ if (It == MarkerSyms.end () || It->second != MarkerSymType::DATA) {
1898+ // This is potentially another entry point into the function.
1899+ uint64_t EntryOffset = NextSymRefI->first - Function.getAddress ();
1900+ LLVM_DEBUG (dbgs () << " BOLT-DEBUG: adding entry point to function "
1901+ << Function << " at offset 0x"
1902+ << Twine::utohexstr (EntryOffset) << ' \n ' );
1903+ Function.addEntryPointAtOffset (EntryOffset);
1904+ }
18791905
18801906 ++NextSymRefI;
18811907 }
@@ -2177,7 +2203,9 @@ void RewriteInstance::adjustCommandLineOptions() {
21772203 if (!opts::KeepNops.getNumOccurrences ())
21782204 opts::KeepNops = true ;
21792205
2180- // Linux kernel may resume execution after a trap instruction in some cases.
2206+ // Linux kernel may resume execution after a trap or x86 HLT instruction.
2207+ if (!opts::TerminalHLT.getNumOccurrences ())
2208+ opts::TerminalHLT = false ;
21812209 if (!opts::TerminalTrap.getNumOccurrences ())
21822210 opts::TerminalTrap = false ;
21832211 }
@@ -3570,7 +3598,7 @@ void RewriteInstance::postProcessFunctions() {
35703598 if (opts::PrintAll || opts::PrintCFG)
35713599 Function.print (BC->outs (), " after building cfg" );
35723600
3573- if (opts::DumpDotAll )
3601+ if (opts::shouldDumpDot (Function) )
35743602 Function.dumpGraphForPass (" 00_build-cfg" );
35753603
35763604 if (opts::PrintLoopInfo) {
0 commit comments