Skip to content

Commit 3b9b804

Browse files
committed
MC: Store MCRelaxableFragment MCInst out-of-line
Moved MCInst storage to MCSection, enabling trivial ~MCRelaxableFragment and eliminating the need for a fragment walk in ~MCSection. Follow-up to llvm#146307
1 parent 6a9a16d commit 3b9b804

File tree

5 files changed

+36
-23
lines changed

5 files changed

+36
-23
lines changed

llvm/include/llvm/MC/MCInst.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef LLVM_MC_MCINST_H
1616
#define LLVM_MC_MCINST_H
1717

18+
#include "llvm/ADT/ArrayRef.h"
1819
#include "llvm/ADT/SmallVector.h"
1920
#include "llvm/ADT/StringRef.h"
2021
#include "llvm/ADT/bit.h"
@@ -211,6 +212,9 @@ class MCInst {
211212
unsigned getNumOperands() const { return Operands.size(); }
212213

213214
void addOperand(const MCOperand Op) { Operands.push_back(Op); }
215+
void setOperands(ArrayRef<MCOperand> Ops) {
216+
Operands.assign(Ops.begin(), Ops.end());
217+
}
214218

215219
using iterator = SmallVectorImpl<MCOperand>::iterator;
216220
using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;

llvm/include/llvm/MC/MCSection.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class LLVM_ABI MCSection {
133133
friend MCAssembler;
134134
friend MCObjectStreamer;
135135
friend class MCEncodedFragment;
136+
friend class MCRelaxableFragment;
136137
static constexpr unsigned NonUniqueID = ~0U;
137138

138139
enum SectionVariant {
@@ -213,6 +214,7 @@ class LLVM_ABI MCSection {
213214
// Content and fixup storage for fragments
214215
SmallVector<char, 0> ContentStorage;
215216
SmallVector<MCFixup, 0> FixupStorage;
217+
SmallVector<MCOperand, 0> MCOperandStorage;
216218

217219
protected:
218220
// TODO Make Name private when possible.
@@ -221,7 +223,8 @@ class LLVM_ABI MCSection {
221223

222224
MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsVirtual,
223225
MCSymbol *Begin);
224-
~MCSection();
226+
// Protected non-virtual dtor prevents destroy through a base class pointer.
227+
~MCSection() {}
225228

226229
public:
227230
MCSection(const MCSection &) = delete;
@@ -431,16 +434,33 @@ class MCDataFragment : public MCEncodedFragment {
431434
///
432435
class MCRelaxableFragment : public MCEncodedFragment {
433436
/// The instruction this is a fragment for.
434-
MCInst Inst;
437+
unsigned Opcode = 0;
438+
uint32_t OperandStart = 0;
439+
uint32_t OperandSize = 0;
435440

436441
public:
437-
MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI)
438-
: MCEncodedFragment(FT_Relaxable, true), Inst(Inst) {
442+
MCRelaxableFragment(const MCSubtargetInfo &STI)
443+
: MCEncodedFragment(FT_Relaxable, true) {
439444
this->STI = &STI;
440445
}
441446

442-
const MCInst &getInst() const { return Inst; }
443-
void setInst(const MCInst &Value) { Inst = Value; }
447+
MCInst getInst() const {
448+
MCInst Inst;
449+
Inst.setOpcode(Opcode);
450+
Inst.setOperands(ArrayRef(getParent()->MCOperandStorage)
451+
.slice(OperandStart, OperandSize));
452+
return Inst;
453+
}
454+
void setInst(const MCInst &Inst) {
455+
Opcode = Inst.getOpcode();
456+
auto &S = getParent()->MCOperandStorage;
457+
if (Inst.getNumOperands() > OperandSize) {
458+
OperandStart = S.size();
459+
S.resize_for_overwrite(S.size() + Inst.getNumOperands());
460+
}
461+
OperandSize = Inst.getNumOperands();
462+
llvm::copy(Inst, S.begin() + OperandStart);
463+
}
444464

445465
bool getAllowAutoPadding() const { return AllowAutoPadding; }
446466
void setAllowAutoPadding(bool V) { AllowAutoPadding = V; }

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,9 @@ void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
397397
// Always create a new, separate fragment here, because its size can change
398398
// during relaxation.
399399
MCRelaxableFragment *IF =
400-
getContext().allocFragment<MCRelaxableFragment>(Inst, STI);
400+
getContext().allocFragment<MCRelaxableFragment>(STI);
401401
insert(IF);
402+
IF->setInst(Inst);
402403

403404
SmallVector<MCFixup, 1> Fixups;
404405
getAssembler().getEmitter().encodeInstruction(

llvm/lib/MC/MCSection.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,6 @@ MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
3636

3737
bool MCSection::hasEnded() const { return End && End->isInSection(); }
3838

39-
MCSection::~MCSection() {
40-
// If ~MCRelaxableFragment becomes trivial (no longer store a MCInst member),
41-
// this dtor can be made empty.
42-
for (auto &[_, Chain] : Subsections) {
43-
for (MCFragment *X = Chain.Head, *Y; X; X = Y) {
44-
Y = X->Next;
45-
if (auto *F = dyn_cast<MCRelaxableFragment>(X))
46-
F->~MCRelaxableFragment();
47-
}
48-
}
49-
}
50-
5139
void MCSection::setBundleLockState(BundleLockStateType NewState) {
5240
if (NewState == NotBundleLocked) {
5341
if (BundleLockNestingDepth == 0) {

llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class HexagonAsmBackend : public MCAsmBackend {
4040
uint8_t OSABI;
4141
StringRef CPU;
4242
mutable uint64_t relaxedCnt;
43-
mutable const MCInst *RelaxedMCB = nullptr;
43+
mutable MCInst RelaxedMCB;
4444
std::unique_ptr <MCInstrInfo> MCII;
4545
std::unique_ptr <MCInst *> RelaxTarget;
4646
MCInst * Extender;
@@ -434,7 +434,7 @@ class HexagonAsmBackend : public MCAsmBackend {
434434
/// \param Inst - The instruction to test.
435435
bool mayNeedRelaxation(MCInst const &Inst,
436436
const MCSubtargetInfo &STI) const override {
437-
RelaxedMCB = &Inst;
437+
RelaxedMCB = Inst;
438438
return true;
439439
}
440440

@@ -443,7 +443,7 @@ class HexagonAsmBackend : public MCAsmBackend {
443443
bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, const MCValue &,
444444
uint64_t Value,
445445
bool Resolved) const override {
446-
MCInst const &MCB = *RelaxedMCB;
446+
MCInst const &MCB = RelaxedMCB;
447447
assert(HexagonMCInstrInfo::isBundle(MCB));
448448

449449
*RelaxTarget = nullptr;
@@ -598,7 +598,7 @@ class HexagonAsmBackend : public MCAsmBackend {
598598
case MCFragment::FT_Relaxable: {
599599
MCContext &Context = getContext();
600600
auto &RF = cast<MCRelaxableFragment>(*Frags[K]);
601-
auto &Inst = const_cast<MCInst &>(RF.getInst());
601+
MCInst Inst = RF.getInst();
602602

603603
const bool WouldTraverseLabel = llvm::any_of(
604604
Asm.symbols(), [&Asm, &RF, &Inst](MCSymbol const &sym) {

0 commit comments

Comments
 (0)