[llvm] [BOLT] Refactor MCInstReference and move it to Core (NFC) (PR #155846)
Anatoly Trosinenko via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 23 06:20:20 PDT 2025
================
@@ -0,0 +1,175 @@
+//===- bolt/Core/MCInstUtils.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BOLT_CORE_MCINSTUTILS_H
+#define BOLT_CORE_MCINSTUTILS_H
+
+#include "bolt/Core/BinaryBasicBlock.h"
+#include <map>
+#include <variant>
+
+namespace llvm {
+class MCCodeEmitter;
+}
+
+namespace llvm {
+namespace bolt {
+
+class BinaryFunction;
+
+/// MCInstReference represents a reference to a constant MCInst as stored either
+/// in a BinaryFunction (i.e. before a CFG is created), or in a BinaryBasicBlock
+/// (after a CFG is created).
+///
+/// The reference may be invalidated when the function containing the referenced
+/// instruction is modified.
+class MCInstReference {
+public:
+ using nocfg_const_iterator = std::map<uint32_t, MCInst>::const_iterator;
+
+ /// Constructs an empty reference.
+ MCInstReference() : Reference(RefInBB(nullptr, /*Index=*/0)) {}
+ /// Constructs a reference to the instruction inside the basic block.
+ MCInstReference(const BinaryBasicBlock *BB, const MCInst *Inst)
+ : Reference(RefInBB(BB, getInstIndexInBB(BB, Inst))) {}
+ /// Constructs a reference to the instruction inside the basic block.
+ MCInstReference(const BinaryBasicBlock *BB, unsigned Index)
+ : Reference(RefInBB(BB, Index)) {
+ assert(BB && "Basic block should not be nullptr");
+ }
+ /// Constructs a reference to the instruction inside the function without
+ /// CFG information.
+ MCInstReference(const BinaryFunction *BF, nocfg_const_iterator It)
+ : Reference(RefInBF(BF, It)) {
+ assert(BF && "Function should not be nullptr");
+ }
+
+ /// Locates an instruction inside a function and returns a reference.
+ static MCInstReference get(const MCInst *Inst, const BinaryFunction &BF);
+
+ bool operator==(const MCInstReference &Other) const {
+ return Reference == Other.Reference;
+ }
+
+ const MCInst &getMCInst() const {
+ assert(!empty() && "Empty reference");
+ if (auto *Ref = tryGetRefInBB()) {
+ [[maybe_unused]] unsigned NumInstructions = Ref->BB->size();
+ assert(Ref->Index < NumInstructions && "Invalid reference");
+ return Ref->BB->getInstructionAtIndex(Ref->Index);
+ }
+ return getRefInBF().It->second;
+ }
+
+ operator const MCInst &() const { return getMCInst(); }
+
+ bool empty() const {
+ if (auto *Ref = tryGetRefInBB())
+ return Ref->BB == nullptr;
+ return getRefInBF().BF == nullptr;
+ }
+
+ bool hasCFG() const { return !empty() && tryGetRefInBB() != nullptr; }
+
+ const BinaryFunction *getFunction() const {
+ assert(!empty() && "Empty reference");
+ if (auto *Ref = tryGetRefInBB())
+ return Ref->BB->getFunction();
+ return getRefInBF().BF;
+ }
+
+ const BinaryBasicBlock *getBasicBlock() const {
+ assert(!empty() && "Empty reference");
+ if (auto *Ref = tryGetRefInBB())
+ return Ref->BB;
+ return nullptr;
+ }
+
+ // MCCodeEmitter is not thread safe.
+ uint64_t getAddress(const MCCodeEmitter *Emitter = nullptr) const;
----------------
atrosinenko wrote:
Writing the documentation made it obvious to me that a name starting with "get" is rather misleading for this method:
* it does not just retrieve the address from a field of some object, it performs computations every time
* it does not return "the" address, it returns an approximation that is expected to be good enough for debug printing (and for the addresses reported by gadget scanner to the user, which are, frankly speaking, reported on the best-effort basis)
For that reason, I renamed this method in b06809883ed96d1c00793834bd05bcff51f032d9 and refactored its callers a bit.
https://github.com/llvm/llvm-project/pull/155846
More information about the llvm-commits
mailing list