aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmir Ayupov <aaupov@fb.com>2021-08-03 17:53:32 -0700
committerAmir Ayupov <aaupov@fb.com>2022-01-18 13:24:50 -0800
commita9cd49d50e88aa142e6d57de90321d8810e1027f (patch)
tree46954d023164fb0050cb3d2c33fb30a1dd31894a
parent4777eb2954080864bcf9dfca0e828c637268eb13 (diff)
downloadllvm-a9cd49d50e88aa142e6d57de90321d8810e1027f.zip
llvm-a9cd49d50e88aa142e6d57de90321d8810e1027f.tar.gz
llvm-a9cd49d50e88aa142e6d57de90321d8810e1027f.tar.bz2
[BOLT][NFC] Move Offset annotation to Group 1
Summary: Move the annotation to avoid dynamic memory allocations. Improves the CPU time of instrumenting a large binary by 1% (+-0.8%, p-value 0.01) Test Plan: NFC Reviewers: maksfb FBD30091656
-rw-r--r--bolt/include/bolt/Core/MCPlus.h1
-rw-r--r--bolt/include/bolt/Core/MCPlusBuilder.h12
-rw-r--r--bolt/lib/Core/BinaryContext.cpp2
-rw-r--r--bolt/lib/Core/BinaryEmitter.cpp4
-rw-r--r--bolt/lib/Core/BinaryFunction.cpp20
-rw-r--r--bolt/lib/Core/MCPlusBuilder.cpp27
-rw-r--r--bolt/lib/Passes/BinaryPasses.cpp9
-rw-r--r--bolt/lib/Passes/Instrumentation.cpp8
-rw-r--r--bolt/lib/Profile/DataAggregator.cpp2
-rw-r--r--bolt/lib/Profile/DataReader.cpp2
-rw-r--r--bolt/lib/Profile/YAMLProfileWriter.cpp6
-rw-r--r--bolt/lib/Rewrite/RewriteInstance.cpp1
-rw-r--r--bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp2
-rw-r--r--bolt/lib/Target/X86/X86MCPlusBuilder.cpp7
14 files changed, 69 insertions, 34 deletions
diff --git a/bolt/include/bolt/Core/MCPlus.h b/bolt/include/bolt/Core/MCPlus.h
index 67430bb..0abb70a 100644
--- a/bolt/include/bolt/Core/MCPlus.h
+++ b/bolt/include/bolt/Core/MCPlus.h
@@ -65,6 +65,7 @@ public:
kJumpTable, /// Jump Table.
kTailCall, /// Tail call.
kConditionalTailCall, /// CTC.
+ kOffset, /// Offset in the function.
kGeneric /// First generic annotation.
};
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index 6576263..8a4497b 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -1075,6 +1075,18 @@ public:
/// branch. Return true if the instruction was converted.
bool unsetConditionalTailCall(MCInst &Inst);
+ /// Return offset of \p Inst in the original function, if available.
+ Optional<uint32_t> getOffset(const MCInst &Inst) const;
+
+ /// Return the offset if the annotation is present, or \p Default otherwise.
+ uint32_t getOffsetWithDefault(const MCInst &Inst, uint32_t Default) const;
+
+ /// Set offset of \p Inst in the original function.
+ bool setOffset(MCInst &Inst, uint32_t Offset, AllocatorIdTy AllocatorId = 0);
+
+ /// Remove offset annotation.
+ bool clearOffset(MCInst &Inst);
+
/// Return MCSymbol that represents a target of this instruction at a given
/// operand number \p OpNum. If there's no symbol associated with
/// the operand - return nullptr.
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index 5ba0dcd..5368d2a 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -1632,6 +1632,8 @@ void BinaryContext::printInstruction(raw_ostream &OS, const MCInst &Instruction,
OS << " # UNKNOWN CONTROL FLOW";
}
}
+ if (Optional<uint32_t> Offset = MIB->getOffset(Instruction))
+ OS << " # Offset: " << *Offset;
MIB->printAnnotations(Instruction, OS);
diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp
index 61ebeae..6bf7ab0 100644
--- a/bolt/lib/Core/BinaryEmitter.cpp
+++ b/bolt/lib/Core/BinaryEmitter.cpp
@@ -468,8 +468,8 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, bool EmitColdPart,
// Prepare to tag this location with a label if we need to keep track of
// the location of calls/returns for BOLT address translation maps
if (!EmitCodeOnly && BF.requiresAddressTranslation() &&
- BC.MIB->hasAnnotation(Instr, "Offset")) {
- const auto Offset = BC.MIB->getAnnotationAs<uint32_t>(Instr, "Offset");
+ BC.MIB->getOffset(Instr)) {
+ const uint32_t Offset = *BC.MIB->getOffset(Instr);
MCSymbol *LocSym = BC.Ctx->createTempSymbol();
Streamer.emitLabel(LocSym);
BB->getLocSyms().emplace_back(Offset, LocSym);
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 9a2344e..5b81dfa 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -1406,7 +1406,7 @@ add_instruction:
// Record offset of the instruction for profile matching.
if (BC.keepOffsetForInstruction(Instruction))
- MIB->addAnnotation(Instruction, "Offset", static_cast<uint32_t>(Offset));
+ MIB->setOffset(Instruction, static_cast<uint32_t>(Offset));
if (BC.MIB->isNoop(Instruction)) {
// NOTE: disassembly loses the correct size information for noops.
@@ -1989,9 +1989,8 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
break;
}
}
- if (LastNonNop && !MIB->hasAnnotation(*LastNonNop, "Offset"))
- MIB->addAnnotation(*LastNonNop, "Offset", static_cast<uint32_t>(Offset),
- AllocatorId);
+ if (LastNonNop && !MIB->getOffset(*LastNonNop))
+ MIB->setOffset(*LastNonNop, static_cast<uint32_t>(Offset), AllocatorId);
};
for (auto I = Instructions.begin(), E = Instructions.end(); I != E; ++I) {
@@ -2014,9 +2013,8 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
bool IsLKMarker = BC.LKMarkers.count(InstrInputAddr);
// Mark all nops with Offset for profile tracking purposes.
if (MIB->isNoop(Instr) || IsLKMarker) {
- if (!MIB->hasAnnotation(Instr, "Offset"))
- MIB->addAnnotation(Instr, "Offset", static_cast<uint32_t>(Offset),
- AllocatorId);
+ if (!MIB->getOffset(Instr))
+ MIB->setOffset(Instr, static_cast<uint32_t>(Offset), AllocatorId);
if (IsSDTMarker || IsLKMarker)
HasSDTMarker = true;
else
@@ -2216,7 +2214,7 @@ void BinaryFunction::postProcessCFG() {
if (!requiresAddressTranslation() && !opts::Instrument) {
for (BinaryBasicBlock *BB : layout())
for (MCInst &Inst : *BB)
- BC.MIB->removeAnnotation(Inst, "Offset");
+ BC.MIB->clearOffset(Inst);
}
assert((!isSimple() || validateCFG()) &&
@@ -2233,8 +2231,7 @@ void BinaryFunction::calculateMacroOpFusionStats() {
// Check offset of the second instruction.
// FIXME: arch-specific.
- const uint32_t Offset =
- BC.MIB->getAnnotationWithDefault<uint32_t>(*std::next(II), "Offset", 0);
+ const uint32_t Offset = BC.MIB->getOffsetWithDefault(*std::next(II), 0);
if (!Offset || (getAddress() + Offset) % 64)
continue;
@@ -4325,8 +4322,7 @@ MCInst *BinaryFunction::getInstructionAtOffset(uint64_t Offset) {
for (MCInst &Inst : *BB) {
constexpr uint32_t InvalidOffset = std::numeric_limits<uint32_t>::max();
- if (Offset == BC.MIB->getAnnotationWithDefault<uint32_t>(Inst, "Offset",
- InvalidOffset))
+ if (Offset == BC.MIB->getOffsetWithDefault(Inst, InvalidOffset))
return &Inst;
}
diff --git a/bolt/lib/Core/MCPlusBuilder.cpp b/bolt/lib/Core/MCPlusBuilder.cpp
index b02e139..d5d135b 100644
--- a/bolt/lib/Core/MCPlusBuilder.cpp
+++ b/bolt/lib/Core/MCPlusBuilder.cpp
@@ -228,6 +228,33 @@ bool MCPlusBuilder::unsetConditionalTailCall(MCInst &Inst) {
return true;
}
+Optional<uint32_t> MCPlusBuilder::getOffset(const MCInst &Inst) const {
+ Optional<int64_t> Value = getAnnotationOpValue(Inst, MCAnnotation::kOffset);
+ if (!Value)
+ return NoneType();
+ return static_cast<uint32_t>(*Value);
+}
+
+uint32_t MCPlusBuilder::getOffsetWithDefault(const MCInst &Inst,
+ uint32_t Default) const {
+ if (Optional<uint32_t> Offset = getOffset(Inst))
+ return *Offset;
+ return Default;
+}
+
+bool MCPlusBuilder::setOffset(MCInst &Inst, uint32_t Offset,
+ AllocatorIdTy AllocatorId) {
+ setAnnotationOpValue(Inst, MCAnnotation::kOffset, Offset, AllocatorId);
+ return true;
+}
+
+bool MCPlusBuilder::clearOffset(MCInst &Inst) {
+ if (!hasAnnotation(Inst, MCAnnotation::kOffset))
+ return false;
+ removeAnnotation(Inst, MCAnnotation::kOffset);
+ return true;
+}
+
bool MCPlusBuilder::hasAnnotation(const MCInst &Inst, unsigned Index) const {
const MCInst *AnnotationInst = getAnnotationInst(Inst);
if (!AnnotationInst)
diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp
index 4ac06e0..fb6e387 100644
--- a/bolt/lib/Passes/BinaryPasses.cpp
+++ b/bolt/lib/Passes/BinaryPasses.cpp
@@ -629,10 +629,9 @@ void LowerAnnotations::runOnFunctions(BinaryContext &BC) {
// Now record preserved annotations separately and then strip annotations.
for (auto II = BB->begin(); II != BB->end(); ++II) {
- if (BF.requiresAddressTranslation() &&
- BC.MIB->hasAnnotation(*II, "Offset"))
- PreservedOffsetAnnotations.emplace_back(
- &(*II), BC.MIB->getAnnotationAs<uint32_t>(*II, "Offset"));
+ if (BF.requiresAddressTranslation() && BC.MIB->getOffset(*II))
+ PreservedOffsetAnnotations.emplace_back(&(*II),
+ *BC.MIB->getOffset(*II));
BC.MIB->stripAnnotations(*II);
}
}
@@ -647,7 +646,7 @@ void LowerAnnotations::runOnFunctions(BinaryContext &BC) {
// Reinsert preserved annotations we need during code emission.
for (const std::pair<MCInst *, uint32_t> &Item : PreservedOffsetAnnotations)
- BC.MIB->addAnnotation<uint32_t>(*Item.first, "Offset", Item.second);
+ BC.MIB->setOffset(*Item.first, Item.second);
}
namespace {
diff --git a/bolt/lib/Passes/Instrumentation.cpp b/bolt/lib/Passes/Instrumentation.cpp
index 50cb6f9..c0084e04 100644
--- a/bolt/lib/Passes/Instrumentation.cpp
+++ b/bolt/lib/Passes/Instrumentation.cpp
@@ -377,7 +377,7 @@ void Instrumentation::instrumentFunction(BinaryFunction &Function,
for (auto I = BB.begin(); I != BB.end(); ++I) {
const MCInst &Inst = *I;
- if (!BC.MIB->hasAnnotation(Inst, "Offset"))
+ if (!BC.MIB->getOffset(Inst))
continue;
const bool IsJumpTable = Function.getJumpTable(Inst);
@@ -389,7 +389,7 @@ void Instrumentation::instrumentFunction(BinaryFunction &Function,
BC.MIB->isUnsupportedBranch(Inst.getOpcode()))
continue;
- uint32_t FromOffset = BC.MIB->getAnnotationAs<uint32_t>(Inst, "Offset");
+ const uint32_t FromOffset = *BC.MIB->getOffset(Inst);
const MCSymbol *Target = BC.MIB->getTargetSymbol(Inst);
BinaryBasicBlock *TargetBB = Function.getBasicBlockForLabel(Target);
uint32_t ToOffset = TargetBB ? TargetBB->getInputOffset() : 0;
@@ -465,9 +465,9 @@ void Instrumentation::instrumentFunction(BinaryFunction &Function,
// if it was branching to the end of the function as a result of
// __builtin_unreachable(), in which case it was deleted by fixBranches.
// Ignore this case. FIXME: force fixBranches() to preserve the offset.
- if (!BC.MIB->hasAnnotation(*LastInstr, "Offset"))
+ if (!BC.MIB->getOffset(*LastInstr))
continue;
- FromOffset = BC.MIB->getAnnotationAs<uint32_t>(*LastInstr, "Offset");
+ FromOffset = *BC.MIB->getOffset(*LastInstr);
// Do not instrument edges in the spanning tree
if (STOutSet[&BB].find(FTBB) != STOutSet[&BB].end()) {
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index 87be768..bb110cdb 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -914,7 +914,7 @@ bool DataAggregator::recordTrace(
const MCInst *Instr = BB->getLastNonPseudoInstr();
uint64_t Offset = 0;
if (Instr)
- Offset = BC.MIB->getAnnotationWithDefault<uint32_t>(*Instr, "Offset");
+ Offset = BC.MIB->getOffsetWithDefault(*Instr, 0);
else
Offset = BB->getOffset();
diff --git a/bolt/lib/Profile/DataReader.cpp b/bolt/lib/Profile/DataReader.cpp
index 65e8e73..28b8629 100644
--- a/bolt/lib/Profile/DataReader.cpp
+++ b/bolt/lib/Profile/DataReader.cpp
@@ -721,7 +721,7 @@ bool DataReader::recordBranch(BinaryFunction &BF, uint64_t From, uint64_t To,
const MCInst *LastInstr = ToBB->getLastNonPseudoInstr();
if (LastInstr) {
const uint32_t LastInstrOffset =
- BC.MIB->getAnnotationWithDefault<uint32_t>(*LastInstr, "Offset");
+ BC.MIB->getOffsetWithDefault(*LastInstr, 0);
// With old .fdata we are getting FT branches for "jcc,jmp" sequences.
if (To == LastInstrOffset && BC.MIB->isUnconditionalBranch(*LastInstr))
diff --git a/bolt/lib/Profile/YAMLProfileWriter.cpp b/bolt/lib/Profile/YAMLProfileWriter.cpp
index 2b72de2..d8d6975 100644
--- a/bolt/lib/Profile/YAMLProfileWriter.cpp
+++ b/bolt/lib/Profile/YAMLProfileWriter.cpp
@@ -53,10 +53,10 @@ void convert(const BinaryFunction &BF,
continue;
yaml::bolt::CallSiteInfo CSI;
- auto Offset = BC.MIB->tryGetAnnotationAs<uint32_t>(Instr, "Offset");
- if (!Offset || Offset.get() < BB->getInputOffset())
+ Optional<uint32_t> Offset = BC.MIB->getOffset(Instr);
+ if (!Offset || *Offset < BB->getInputOffset())
continue;
- CSI.Offset = Offset.get() - BB->getInputOffset();
+ CSI.Offset = *Offset - BB->getInputOffset();
if (BC.MIB->isIndirectCall(Instr) || BC.MIB->isIndirectBranch(Instr)) {
auto ICSP = BC.MIB->tryGetAnnotationAs<IndirectCallSiteProfile>(
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 9dc7a9e..73288a3 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2771,7 +2771,6 @@ void RewriteInstance::buildFunctionsCFG() {
"Build Binary Functions", opts::TimeBuild);
// Create annotation indices to allow lock-free execution
- BC->MIB->getOrCreateAnnotationIndex("Offset");
BC->MIB->getOrCreateAnnotationIndex("JTIndexReg");
BC->MIB->getOrCreateAnnotationIndex("NOP");
BC->MIB->getOrCreateAnnotationIndex("Size");
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 1cb0772..976348a 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -805,7 +805,7 @@ public:
bool convertTailCallToJmp(MCInst &Inst) override {
removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
- removeAnnotation(Inst, "Offset");
+ clearOffset(Inst);
if (getConditionalTailCall(Inst))
unsetConditionalTailCall(Inst);
return true;
diff --git a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp
index 21878c9..67efa16 100644
--- a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp
+++ b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp
@@ -2020,7 +2020,7 @@ public:
Inst.setOpcode(NewOpcode);
removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
- removeAnnotation(Inst, "Offset");
+ clearOffset(Inst);
return true;
}
@@ -3808,10 +3808,9 @@ public:
if (CallOrJmp.getOpcode() == X86::CALL64r ||
CallOrJmp.getOpcode() == X86::CALL64pcrel32) {
- if (hasAnnotation(CallInst, "Offset"))
+ if (Optional<uint32_t> Offset = getOffset(CallInst))
// Annotated as duplicated call
- addAnnotation(CallOrJmp, "Offset",
- getAnnotationAs<uint32_t>(CallInst, "Offset"));
+ setOffset(CallOrJmp, *Offset);
}
if (isInvoke(CallInst) && !isInvoke(CallOrJmp)) {