[llvm] [BOLT] Modify MCPlus annotation internals. NFCI. (PR #70412)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 26 21:38:00 PDT 2023
https://github.com/maksfb created https://github.com/llvm/llvm-project/pull/70412
When annotating MCInst instructions, attach extra annotation operands directly to the annotated instruction, instead of attaching them to an instruction pointed to by a special kInst operand.
With this change, it's no longer necessary to allocate MCInst and most of the first-class annotations come with free memory as currently MCInst is declared with:
SmallVector<MCOperand, 10> Operands;
i.e. more operands than are normally being used.
We still create a kInst operand with a nullptr instruction value to designate the beginning of annotation operands. However, this special operand might not be needed if we can rely on MCInstrDesc::NumOperands.
>From 767efa984052324e1c8723930f9c6c6c54ab9fe5 Mon Sep 17 00:00:00 2001
From: Maksim Panchenko <maks at fb.com>
Date: Wed, 18 Oct 2023 16:00:43 -0700
Subject: [PATCH] [BOLT] Modify MCPlus annotation internals. NFCI.
When annotating MCInst instructions, attach extra annotation operands
directly to the annotated instruction, instead of attaching them to an
instruction pointed to by a special kInst operand.
With this change, it's no longer necessary to allocate MCInst and most
of the first-class annotations come with free memory as currently MCInst
is declared with:
SmallVector<MCOperand, 10> Operands;
i.e. more operands than are normally being used.
We still create a kInst operand with a nullptr instruction value to
designate the beginning of annotation operands. However, this special
operand might not be needed if we can rely on MCInstrDesc::NumOperands.
---
bolt/include/bolt/Core/MCPlus.h | 26 +++---
bolt/include/bolt/Core/MCPlusBuilder.h | 113 ++++++++++++-------------
bolt/lib/Core/BinaryFunction.cpp | 19 +++--
bolt/lib/Core/MCPlusBuilder.cpp | 62 ++++++--------
4 files changed, 106 insertions(+), 114 deletions(-)
diff --git a/bolt/include/bolt/Core/MCPlus.h b/bolt/include/bolt/Core/MCPlus.h
index 31cc9071de76ace..f6ffd33513dd258 100644
--- a/bolt/include/bolt/Core/MCPlus.h
+++ b/bolt/include/bolt/Core/MCPlus.h
@@ -32,11 +32,16 @@ namespace MCPlus {
/// pad and the uint64_t represents the action.
using MCLandingPad = std::pair<const MCSymbol *, uint64_t>;
-/// An extension to MCInst is provided via an extra operand of type MCInst with
-/// ANNOTATION_LABEL opcode (i.e. we are tying an annotation instruction to an
-/// existing one). The annotation instruction contains a list of Immediate
-/// operands. Each operand either contains a value, or is a pointer to
-/// an instance of class MCAnnotation.
+/// An extension to MCInst is provided via extra operands, i.e. operands that
+/// are not used in the instruction assembly. Any kind of metadata can be
+/// attached to MCInst with this "annotation" extension using MCPlusBuilder
+/// interface.
+//
+/// The first extra operand must be of type kInst with an empty (nullptr)
+/// value. The kInst operand type is unused on most non-VLIW architectures.
+/// We use it to mark the beginning of annotations operands. The rest of the
+/// operands are of Immediate type with annotation info encoded into the value
+/// of the immediate.
///
/// There are 2 distinct groups of annotations. The first group is a first-class
/// annotation that affects semantics of the instruction, such as an
@@ -55,7 +60,7 @@ using MCLandingPad = std::pair<const MCSymbol *, uint64_t>;
/// of their corresponding operand.
///
/// Annotations in the second group could be addressed either by name, or by
-/// by and index which could be queried by providing a name.
+/// by index which could be queried by providing the name.
class MCAnnotation {
public:
enum Kind {
@@ -106,10 +111,11 @@ template <typename ValueType> class MCSimpleAnnotation : public MCAnnotation {
/// Return a number of operands in \Inst excluding operands representing
/// annotations.
inline unsigned getNumPrimeOperands(const MCInst &Inst) {
- if (Inst.getNumOperands() > 0 && std::prev(Inst.end())->isInst()) {
- assert(std::prev(Inst.end())->getInst()->getOpcode() ==
- TargetOpcode::ANNOTATION_LABEL);
- return Inst.getNumOperands() - 1;
+ for (signed I = Inst.getNumOperands() - 1; I >= 0; --I) {
+ if (Inst.getOperand(I).isInst())
+ return I;
+ if (!Inst.getOperand(I).isImm())
+ return Inst.getNumOperands();
}
return Inst.getNumOperands();
}
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index d136c627bc5cc10..bd2430535a092a7 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -65,7 +65,6 @@ class MCPlusBuilder {
private:
/// A struct that represents a single annotation allocator
struct AnnotationAllocator {
- SpecificBumpPtrAllocator<MCInst> MCInstAllocator;
BumpPtrAllocator ValueAllocator;
std::unordered_set<MCPlus::MCAnnotation *> AnnotationPool;
};
@@ -97,60 +96,62 @@ class MCPlusBuilder {
return SignExtend64<56>(ImmValue & 0xff'ffff'ffff'ffffULL);
}
- MCInst *getAnnotationInst(const MCInst &Inst) const {
- if (Inst.getNumOperands() == 0)
- return nullptr;
+ std::optional<unsigned> getFirstAnnotationOpIndex(const MCInst &Inst) const {
+ const unsigned NumPrimeOperands = MCPlus::getNumPrimeOperands(Inst);
+ if (Inst.getNumOperands() == NumPrimeOperands)
+ return std::nullopt;
- const MCOperand &LastOp = Inst.getOperand(Inst.getNumOperands() - 1);
- if (!LastOp.isInst())
- return nullptr;
+ assert(Inst.getOperand(NumPrimeOperands).getInst() == nullptr &&
+ "Empty instruction expected.");
- MCInst *AnnotationInst = const_cast<MCInst *>(LastOp.getInst());
- assert(AnnotationInst->getOpcode() == TargetOpcode::ANNOTATION_LABEL);
+ return NumPrimeOperands + 1;
+ }
- return AnnotationInst;
+ MCInst::iterator getAnnotationInstOp(MCInst &Inst) const {
+ for (MCInst::iterator Iter = Inst.begin(); Iter != Inst.end(); ++Iter) {
+ if (Iter->isInst()) {
+ assert(Iter->getInst() == nullptr && "Empty instruction expected.");
+ return Iter;
+ }
+ }
+ return Inst.end();
}
- void removeAnnotationInst(MCInst &Inst) const {
- assert(getAnnotationInst(Inst) && "Expected annotation instruction.");
- Inst.erase(std::prev(Inst.end()));
- assert(!getAnnotationInst(Inst) &&
- "More than one annotation instruction detected.");
+ void removeAnnotations(MCInst &Inst) const {
+ Inst.erase(getAnnotationInstOp(Inst), Inst.end());
}
- void setAnnotationOpValue(MCInst &Inst, unsigned Index, int64_t Value,
- AllocatorIdTy AllocatorId = 0) {
- MCInst *AnnotationInst = getAnnotationInst(Inst);
- if (!AnnotationInst) {
- AnnotationAllocator &Allocator = getAnnotationAllocator(AllocatorId);
- AnnotationInst = new (Allocator.MCInstAllocator.Allocate()) MCInst();
- AnnotationInst->setOpcode(TargetOpcode::ANNOTATION_LABEL);
- Inst.addOperand(MCOperand::createInst(AnnotationInst));
+ void setAnnotationOpValue(MCInst &Inst, unsigned Index, int64_t Value) const {
+ const int64_t AnnotationValue = encodeAnnotationImm(Index, Value);
+ const std::optional<unsigned> FirstAnnotationOp =
+ getFirstAnnotationOpIndex(Inst);
+ if (!FirstAnnotationOp) {
+ Inst.addOperand(MCOperand::createInst(nullptr));
+ Inst.addOperand(MCOperand::createImm(AnnotationValue));
+ return;
}
- const int64_t AnnotationValue = encodeAnnotationImm(Index, Value);
- for (int I = AnnotationInst->getNumOperands() - 1; I >= 0; --I) {
- int64_t ImmValue = AnnotationInst->getOperand(I).getImm();
+ for (unsigned I = *FirstAnnotationOp; I < Inst.getNumOperands(); ++I) {
+ const int64_t ImmValue = Inst.getOperand(I).getImm();
if (extractAnnotationIndex(ImmValue) == Index) {
- AnnotationInst->getOperand(I).setImm(AnnotationValue);
+ Inst.getOperand(I).setImm(AnnotationValue);
return;
}
}
- AnnotationInst->addOperand(MCOperand::createImm(AnnotationValue));
+ Inst.addOperand(MCOperand::createImm(AnnotationValue));
}
std::optional<int64_t> getAnnotationOpValue(const MCInst &Inst,
unsigned Index) const {
- const MCInst *AnnotationInst = getAnnotationInst(Inst);
- if (!AnnotationInst)
+ std::optional<unsigned> FirstAnnotationOp = getFirstAnnotationOpIndex(Inst);
+ if (!FirstAnnotationOp)
return std::nullopt;
- for (int I = AnnotationInst->getNumOperands() - 1; I >= 0; --I) {
- int64_t ImmValue = AnnotationInst->getOperand(I).getImm();
- if (extractAnnotationIndex(ImmValue) == Index) {
+ for (unsigned I = *FirstAnnotationOp; I < Inst.getNumOperands(); ++I) {
+ const int64_t ImmValue = Inst.getOperand(I).getImm();
+ if (extractAnnotationIndex(ImmValue) == Index)
return extractAnnotationValue(ImmValue);
- }
}
return std::nullopt;
@@ -172,21 +173,18 @@ class MCPlusBuilder {
/// AnnotationNameIndexMap and AnnotationsNames.
mutable llvm::sys::RWMutex AnnotationNameMutex;
- /// Allocate the TailCall annotation value. Clients of the target-specific
+ /// Set TailCall annotation value to true. Clients of the target-specific
/// MCPlusBuilder classes must use convert/lower/create* interfaces instead.
- void setTailCall(MCInst &Inst);
+ void setTailCall(MCInst &Inst) const;
public:
/// Transfer annotations from \p SrcInst to \p DstInst.
void moveAnnotations(MCInst &&SrcInst, MCInst &DstInst) const {
- assert(!getAnnotationInst(DstInst) &&
- "Destination instruction should not have annotations.");
- const MCInst *AnnotationInst = getAnnotationInst(SrcInst);
- if (!AnnotationInst)
- return;
+ MCInst::iterator AnnotationOp = getAnnotationInstOp(SrcInst);
+ for (MCInst::iterator Iter = AnnotationOp; Iter != SrcInst.end(); ++Iter)
+ DstInst.addOperand(*Iter);
- DstInst.addOperand(MCOperand::createInst(AnnotationInst));
- removeAnnotationInst(SrcInst);
+ SrcInst.erase(AnnotationOp, SrcInst.end());
}
/// Return iterator range covering def operands.
@@ -390,7 +388,6 @@ class MCPlusBuilder {
Allocator.AnnotationPool.clear();
Allocator.ValueAllocator.Reset();
- Allocator.MCInstAllocator.DestroyAll();
}
}
@@ -1128,20 +1125,19 @@ class MCPlusBuilder {
std::optional<MCPlus::MCLandingPad> getEHInfo(const MCInst &Inst) const;
/// Add handler and action info for call instruction.
- void addEHInfo(MCInst &Inst, const MCPlus::MCLandingPad &LP);
+ void addEHInfo(MCInst &Inst, const MCPlus::MCLandingPad &LP) const;
/// Update exception-handling info for the invoke instruction \p Inst.
/// Return true on success and false otherwise, e.g. if the instruction is
/// not an invoke.
- bool updateEHInfo(MCInst &Inst, const MCPlus::MCLandingPad &LP);
+ bool updateEHInfo(MCInst &Inst, const MCPlus::MCLandingPad &LP) const;
/// Return non-negative GNU_args_size associated with the instruction
/// or -1 if there's no associated info.
int64_t getGnuArgsSize(const MCInst &Inst) const;
/// Add the value of GNU_args_size to Inst if it already has EH info.
- void addGnuArgsSize(MCInst &Inst, int64_t GnuArgsSize,
- AllocatorIdTy AllocId = 0);
+ void addGnuArgsSize(MCInst &Inst, int64_t GnuArgsSize) const;
/// Return jump table addressed by this instruction.
uint64_t getJumpTable(const MCInst &Inst) const;
@@ -1154,7 +1150,7 @@ class MCPlusBuilder {
AllocatorIdTy AllocId = 0);
/// Disassociate instruction with a jump table.
- bool unsetJumpTable(MCInst &Inst);
+ bool unsetJumpTable(MCInst &Inst) const;
/// Return destination of conditional tail call instruction if \p Inst is one.
std::optional<uint64_t> getConditionalTailCall(const MCInst &Inst) const;
@@ -1162,11 +1158,11 @@ class MCPlusBuilder {
/// Mark the \p Instruction as a conditional tail call, and set its
/// destination address if it is known. If \p Instruction was already marked,
/// update its destination with \p Dest.
- bool setConditionalTailCall(MCInst &Inst, uint64_t Dest = 0);
+ bool setConditionalTailCall(MCInst &Inst, uint64_t Dest = 0) const;
/// If \p Inst was marked as a conditional tail call convert it to a regular
/// branch. Return true if the instruction was converted.
- bool unsetConditionalTailCall(MCInst &Inst);
+ bool unsetConditionalTailCall(MCInst &Inst) const;
/// Return offset of \p Inst in the original function, if available.
std::optional<uint32_t> getOffset(const MCInst &Inst) const;
@@ -1175,10 +1171,10 @@ class MCPlusBuilder {
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);
+ bool setOffset(MCInst &Inst, uint32_t Offset) const;
/// Remove offset annotation.
- bool clearOffset(MCInst &Inst);
+ bool clearOffset(MCInst &Inst) const;
/// Return the label of \p Inst, if available.
std::optional<MCSymbol *> getLabel(const MCInst &Inst) const;
@@ -1827,8 +1823,7 @@ class MCPlusBuilder {
if (!std::is_trivial<ValueType>::value)
Allocator.AnnotationPool.insert(A);
- setAnnotationOpValue(Inst, Index, reinterpret_cast<int64_t>(A),
- AllocatorId);
+ setAnnotationOpValue(Inst, Index, reinterpret_cast<int64_t>(A));
return A->getValue();
}
@@ -1961,21 +1956,21 @@ class MCPlusBuilder {
///
/// Return true if the annotation was removed, false if the annotation
/// was not present.
- bool removeAnnotation(MCInst &Inst, unsigned Index);
+ bool removeAnnotation(MCInst &Inst, unsigned Index) const;
/// Remove annotation associated with \p Name.
///
/// Return true if the annotation was removed, false if the annotation
/// was not present.
- bool removeAnnotation(MCInst &Inst, StringRef Name) {
+ bool removeAnnotation(MCInst &Inst, StringRef Name) const {
const auto Index = getAnnotationIndex(Name);
if (!Index)
return false;
return removeAnnotation(Inst, *Index);
}
- /// Remove meta-data, but don't destroy it.
- void stripAnnotations(MCInst &Inst, bool KeepTC = false);
+ /// Remove meta-data from the instruction, but don't destroy it.
+ void stripAnnotations(MCInst &Inst, bool KeepTC = false) const;
virtual InstructionListType
createInstrumentedIndirectCall(MCInst &&CallInst, MCSymbol *HandlerFuncAddr,
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 2e1fa739e53f20b..2fbb4d4b1384206 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -1999,7 +1999,7 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
}
}
if (LastNonNop && !MIB->getOffset(*LastNonNop))
- MIB->setOffset(*LastNonNop, static_cast<uint32_t>(Offset), AllocatorId);
+ MIB->setOffset(*LastNonNop, static_cast<uint32_t>(Offset));
};
for (auto I = Instructions.begin(), E = Instructions.end(); I != E; ++I) {
@@ -2022,7 +2022,7 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
if (MIB->isNoop(Instr) && !MIB->getOffset(Instr)) {
// If "Offset" annotation is not present, set it and mark the nop for
// deletion.
- MIB->setOffset(Instr, static_cast<uint32_t>(Offset), AllocatorId);
+ MIB->setOffset(Instr, static_cast<uint32_t>(Offset));
// Annotate ordinary nops, so we can safely delete them if required.
MIB->addAnnotation(Instr, "NOP", static_cast<uint32_t>(1), AllocatorId);
}
@@ -2303,6 +2303,13 @@ void BinaryFunction::removeConditionalTailCalls() {
assert(CTCTargetLabel && "symbol expected for conditional tail call");
MCInst TailCallInstr;
BC.MIB->createTailCall(TailCallInstr, CTCTargetLabel, BC.Ctx.get());
+
+ // Move offset from CTCInstr to TailCallInstr.
+ if (const std::optional<uint32_t> Offset = BC.MIB->getOffset(*CTCInstr)) {
+ BC.MIB->setOffset(TailCallInstr, *Offset);
+ BC.MIB->clearOffset(*CTCInstr);
+ }
+
// Link new BBs to the original input offset of the BB where the CTC
// is, so we can map samples recorded in new BBs back to the original BB
// seem in the input binary (if using BAT)
@@ -2331,12 +2338,6 @@ void BinaryFunction::removeConditionalTailCalls() {
// This branch is no longer a conditional tail call.
BC.MIB->unsetConditionalTailCall(*CTCInstr);
-
- // Move offset from CTCInstr to TailCallInstr.
- if (std::optional<uint32_t> Offset = BC.MIB->getOffset(*CTCInstr)) {
- BC.MIB->setOffset(TailCallInstr, *Offset);
- BC.MIB->clearOffset(*CTCInstr);
- }
}
insertBasicBlocks(std::prev(end()), std::move(NewBlocks),
@@ -3373,7 +3374,7 @@ void BinaryFunction::propagateGnuArgsSizeInfo(
}
} else if (BC.MIB->isInvoke(Instr)) {
// Add the value of GNU_args_size as an extra operand to invokes.
- BC.MIB->addGnuArgsSize(Instr, CurrentGnuArgsSize, AllocId);
+ BC.MIB->addGnuArgsSize(Instr, CurrentGnuArgsSize);
}
++II;
}
diff --git a/bolt/lib/Core/MCPlusBuilder.cpp b/bolt/lib/Core/MCPlusBuilder.cpp
index 036fcf8b3e27fd9..dc9a3b60a4813ab 100644
--- a/bolt/lib/Core/MCPlusBuilder.cpp
+++ b/bolt/lib/Core/MCPlusBuilder.cpp
@@ -120,7 +120,7 @@ bool MCPlusBuilder::equals(const MCTargetExpr &A, const MCTargetExpr &B,
llvm_unreachable("target-specific expressions are unsupported");
}
-void MCPlusBuilder::setTailCall(MCInst &Inst) {
+void MCPlusBuilder::setTailCall(MCInst &Inst) const {
assert(!hasAnnotation(Inst, MCAnnotation::kTailCall));
setAnnotationOpValue(Inst, MCAnnotation::kTailCall, true);
}
@@ -149,7 +149,7 @@ std::optional<MCLandingPad> MCPlusBuilder::getEHInfo(const MCInst &Inst) const {
static_cast<uint64_t>(*Action));
}
-void MCPlusBuilder::addEHInfo(MCInst &Inst, const MCLandingPad &LP) {
+void MCPlusBuilder::addEHInfo(MCInst &Inst, const MCLandingPad &LP) const {
if (isCall(Inst)) {
assert(!getEHInfo(Inst));
setAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad,
@@ -159,7 +159,7 @@ void MCPlusBuilder::addEHInfo(MCInst &Inst, const MCLandingPad &LP) {
}
}
-bool MCPlusBuilder::updateEHInfo(MCInst &Inst, const MCLandingPad &LP) {
+bool MCPlusBuilder::updateEHInfo(MCInst &Inst, const MCLandingPad &LP) const {
if (!isInvoke(Inst))
return false;
@@ -178,13 +178,12 @@ int64_t MCPlusBuilder::getGnuArgsSize(const MCInst &Inst) const {
return *Value;
}
-void MCPlusBuilder::addGnuArgsSize(MCInst &Inst, int64_t GnuArgsSize,
- AllocatorIdTy AllocId) {
+void MCPlusBuilder::addGnuArgsSize(MCInst &Inst, int64_t GnuArgsSize) const {
assert(GnuArgsSize >= 0 && "cannot set GNU_args_size to negative value");
assert(getGnuArgsSize(Inst) == -1LL && "GNU_args_size already set");
assert(isInvoke(Inst) && "GNU_args_size can only be set for invoke");
- setAnnotationOpValue(Inst, MCAnnotation::kGnuArgsSize, GnuArgsSize, AllocId);
+ setAnnotationOpValue(Inst, MCAnnotation::kGnuArgsSize, GnuArgsSize);
}
uint64_t MCPlusBuilder::getJumpTable(const MCInst &Inst) const {
@@ -203,12 +202,12 @@ bool MCPlusBuilder::setJumpTable(MCInst &Inst, uint64_t Value,
uint16_t IndexReg, AllocatorIdTy AllocId) {
if (!isIndirectBranch(Inst))
return false;
- setAnnotationOpValue(Inst, MCAnnotation::kJumpTable, Value, AllocId);
+ setAnnotationOpValue(Inst, MCAnnotation::kJumpTable, Value);
getOrCreateAnnotationAs<uint16_t>(Inst, "JTIndexReg", AllocId) = IndexReg;
return true;
}
-bool MCPlusBuilder::unsetJumpTable(MCInst &Inst) {
+bool MCPlusBuilder::unsetJumpTable(MCInst &Inst) const {
if (!getJumpTable(Inst))
return false;
removeAnnotation(Inst, MCAnnotation::kJumpTable);
@@ -225,7 +224,7 @@ MCPlusBuilder::getConditionalTailCall(const MCInst &Inst) const {
return static_cast<uint64_t>(*Value);
}
-bool MCPlusBuilder::setConditionalTailCall(MCInst &Inst, uint64_t Dest) {
+bool MCPlusBuilder::setConditionalTailCall(MCInst &Inst, uint64_t Dest) const {
if (!isConditionalBranch(Inst))
return false;
@@ -233,7 +232,7 @@ bool MCPlusBuilder::setConditionalTailCall(MCInst &Inst, uint64_t Dest) {
return true;
}
-bool MCPlusBuilder::unsetConditionalTailCall(MCInst &Inst) {
+bool MCPlusBuilder::unsetConditionalTailCall(MCInst &Inst) const {
if (!getConditionalTailCall(Inst))
return false;
removeAnnotation(Inst, MCAnnotation::kConditionalTailCall);
@@ -255,13 +254,12 @@ uint32_t MCPlusBuilder::getOffsetWithDefault(const MCInst &Inst,
return Default;
}
-bool MCPlusBuilder::setOffset(MCInst &Inst, uint32_t Offset,
- AllocatorIdTy AllocatorId) {
- setAnnotationOpValue(Inst, MCAnnotation::kOffset, Offset, AllocatorId);
+bool MCPlusBuilder::setOffset(MCInst &Inst, uint32_t Offset) const {
+ setAnnotationOpValue(Inst, MCAnnotation::kOffset, Offset);
return true;
}
-bool MCPlusBuilder::clearOffset(MCInst &Inst) {
+bool MCPlusBuilder::clearOffset(MCInst &Inst) const {
if (!hasAnnotation(Inst, MCAnnotation::kOffset))
return false;
removeAnnotation(Inst, MCAnnotation::kOffset);
@@ -282,49 +280,41 @@ bool MCPlusBuilder::setLabel(MCInst &Inst, MCSymbol *Label,
}
bool MCPlusBuilder::hasAnnotation(const MCInst &Inst, unsigned Index) const {
- const MCInst *AnnotationInst = getAnnotationInst(Inst);
- if (!AnnotationInst)
- return false;
-
return (bool)getAnnotationOpValue(Inst, Index);
}
-bool MCPlusBuilder::removeAnnotation(MCInst &Inst, unsigned Index) {
- MCInst *AnnotationInst = getAnnotationInst(Inst);
- if (!AnnotationInst)
+bool MCPlusBuilder::removeAnnotation(MCInst &Inst, unsigned Index) const {
+ std::optional<unsigned> FirstAnnotationOp = getFirstAnnotationOpIndex(Inst);
+ if (!FirstAnnotationOp)
return false;
- for (int I = AnnotationInst->getNumOperands() - 1; I >= 0; --I) {
- int64_t ImmValue = AnnotationInst->getOperand(I).getImm();
+ for (unsigned I = Inst.getNumOperands() - 1; I >= *FirstAnnotationOp; --I) {
+ const int64_t ImmValue = Inst.getOperand(I).getImm();
if (extractAnnotationIndex(ImmValue) == Index) {
- AnnotationInst->erase(AnnotationInst->begin() + I);
+ Inst.erase(Inst.begin() + I);
return true;
}
}
return false;
}
-void MCPlusBuilder::stripAnnotations(MCInst &Inst, bool KeepTC) {
- MCInst *AnnotationInst = getAnnotationInst(Inst);
- if (!AnnotationInst)
- return;
- // Preserve TailCall annotation.
- auto IsTC = hasAnnotation(Inst, MCAnnotation::kTailCall);
+void MCPlusBuilder::stripAnnotations(MCInst &Inst, bool KeepTC) const {
+ KeepTC &= hasAnnotation(Inst, MCAnnotation::kTailCall);
- removeAnnotationInst(Inst);
+ removeAnnotations(Inst);
- if (KeepTC && IsTC)
+ if (KeepTC)
setTailCall(Inst);
}
void MCPlusBuilder::printAnnotations(const MCInst &Inst,
raw_ostream &OS) const {
- const MCInst *AnnotationInst = getAnnotationInst(Inst);
- if (!AnnotationInst)
+ std::optional<unsigned> FirstAnnotationOp = getFirstAnnotationOpIndex(Inst);
+ if (!FirstAnnotationOp)
return;
- for (unsigned I = 0; I < AnnotationInst->getNumOperands(); ++I) {
- const int64_t Imm = AnnotationInst->getOperand(I).getImm();
+ for (unsigned I = *FirstAnnotationOp; I < Inst.getNumOperands(); ++I) {
+ const int64_t Imm = Inst.getOperand(I).getImm();
const unsigned Index = extractAnnotationIndex(Imm);
const int64_t Value = extractAnnotationValue(Imm);
const auto *Annotation = reinterpret_cast<const MCAnnotation *>(Value);
More information about the llvm-commits
mailing list