aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/BasicBlockSections.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/CodeGen/BasicBlockSections.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/CodeGen/BasicBlockSections.cpp')
-rw-r--r--llvm/lib/CodeGen/BasicBlockSections.cpp43
1 files changed, 40 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp
index 7499ea8b42d4..1a6eed272ca2 100644
--- a/llvm/lib/CodeGen/BasicBlockSections.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSections.cpp
@@ -88,6 +88,12 @@ cl::opt<std::string> llvm::BBSectionsColdTextPrefix(
cl::desc("The text prefix to use for cold basic block clusters"),
cl::init(".text.split."), cl::Hidden);
+cl::opt<bool> BBSectionsDetectSourceDrift(
+ "bbsections-detect-source-drift",
+ cl::desc("This checks if there is a fdo instr. profile hash "
+ "mismatch for this function"),
+ cl::init(true), cl::Hidden);
+
namespace {
// This struct represents the cluster information for a machine basic block.
@@ -303,20 +309,51 @@ static bool avoidZeroOffsetLandingPad(MachineFunction &MF) {
MachineBasicBlock::iterator MI = MBB.begin();
while (!MI->isEHLabel())
++MI;
- MCInst Noop;
- MF.getSubtarget().getInstrInfo()->getNoop(Noop);
+ MCInst Nop = MF.getSubtarget().getInstrInfo()->getNop();
BuildMI(MBB, MI, DebugLoc(),
- MF.getSubtarget().getInstrInfo()->get(Noop.getOpcode()));
+ MF.getSubtarget().getInstrInfo()->get(Nop.getOpcode()));
return false;
}
}
return true;
}
+// This checks if the source of this function has drifted since this binary was
+// profiled previously. For now, we are piggy backing on what PGO does to
+// detect this with instrumented profiles. PGO emits an hash of the IR and
+// checks if the hash has changed. Advanced basic block layout is usually done
+// on top of PGO optimized binaries and hence this check works well in practice.
+static bool hasInstrProfHashMismatch(MachineFunction &MF) {
+ if (!BBSectionsDetectSourceDrift)
+ return false;
+
+ const char MetadataName[] = "instr_prof_hash_mismatch";
+ auto *Existing = MF.getFunction().getMetadata(LLVMContext::MD_annotation);
+ if (Existing) {
+ MDTuple *Tuple = cast<MDTuple>(Existing);
+ for (auto &N : Tuple->operands())
+ if (cast<MDString>(N.get())->getString() == MetadataName)
+ return true;
+ }
+
+ return false;
+}
+
bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
auto BBSectionsType = MF.getTarget().getBBSectionsType();
assert(BBSectionsType != BasicBlockSection::None &&
"BB Sections not enabled!");
+
+ // Check for source drift. If the source has changed since the profiles
+ // were obtained, optimizing basic blocks might be sub-optimal.
+ // This only applies to BasicBlockSection::List as it creates
+ // clusters of basic blocks using basic block ids. Source drift can
+ // invalidate these groupings leading to sub-optimal code generation with
+ // regards to performance.
+ if (BBSectionsType == BasicBlockSection::List &&
+ hasInstrProfHashMismatch(MF))
+ return true;
+
// Renumber blocks before sorting them for basic block sections. This is
// useful during sorting, basic blocks in the same section will retain the
// default order. This renumbering should also be done for basic block