diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h --- a/bolt/include/bolt/Core/BinaryFunction.h +++ b/bolt/include/bolt/Core/BinaryFunction.h @@ -835,9 +835,13 @@ /// them. void calculateLoopInfo(); + /// Find blocks with missed macro-fusion opportunities. + using SmallBlocksSet = SmallPtrSet; + SmallBlocksSet findMissedMacroOpFusionBlocks(); + /// Calculate missed macro-fusion opportunities and update BinaryContext /// stats. - void calculateMacroOpFusionStats(); + void calculateMacroOpFusionStats(SmallBlocksSet &Blocks); /// Returns if loop detection has been run for this function. bool hasLoopInfo() const { return BLI != nullptr; } diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -2174,6 +2174,8 @@ } void BinaryFunction::postProcessCFG() { + SmallBlocksSet MissedMacroFusionBlocks = findMissedMacroOpFusionBlocks(); + if (isSimple() && !BasicBlocks.empty()) { // Convert conditional tail call branches to conditional branches that jump // to a tail call. @@ -2185,7 +2187,7 @@ postProcessBranches(); } - calculateMacroOpFusionStats(); + calculateMacroOpFusionStats(MissedMacroFusionBlocks); // The final cleanup of intermediate structures. clearList(IgnoredBranches); @@ -2203,9 +2205,10 @@ "invalid CFG detected after post-processing"); } -void BinaryFunction::calculateMacroOpFusionStats() { +BinaryFunction::SmallBlocksSet BinaryFunction::findMissedMacroOpFusionBlocks() { + SmallBlocksSet Blocks; if (!getBinaryContext().isX86()) - return; + return Blocks; for (const BinaryBasicBlock &BB : blocks()) { auto II = BB.getMacroOpFusionPair(); if (II == BB.end()) @@ -2222,8 +2225,14 @@ << " in function " << *this << "; executed " << BB.getKnownExecutionCount() << " times.\n"); ++BC.MissedMacroFusionPairs; - BC.MissedMacroFusionExecCount += BB.getKnownExecutionCount(); + Blocks.insert(&BB); } + return Blocks; +} + +void BinaryFunction::calculateMacroOpFusionStats(SmallBlocksSet &Blocks) { + for (const BinaryBasicBlock *BB : Blocks) + BC.MissedMacroFusionExecCount += BB->getKnownExecutionCount(); } void BinaryFunction::removeTagsFromProfile() {