diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h --- a/llvm/include/llvm/MC/MCAsmBackend.h +++ b/llvm/include/llvm/MC/MCAsmBackend.h @@ -11,6 +11,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCFragment.h" @@ -166,8 +167,8 @@ /// \param [out] Inst The instruction to relax, which is also the relaxed /// instruction. /// \param STI the subtarget information for the associated instruction. - virtual void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const {}; + virtual void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const {}; /// @} diff --git a/llvm/include/llvm/MCA/CodeEmitter.h b/llvm/include/llvm/MCA/CodeEmitter.h --- a/llvm/include/llvm/MCA/CodeEmitter.h +++ b/llvm/include/llvm/MCA/CodeEmitter.h @@ -34,6 +34,7 @@ /// It provides a simple API to compute and return instruction encodings as /// strings. Encodings are cached internally for later usage. class CodeEmitter { + MCContext &Ctx; const MCSubtargetInfo &STI; const MCAsmBackend &MAB; const MCCodeEmitter &MCE; @@ -52,9 +53,9 @@ EncodingInfo getOrCreateEncodingInfo(unsigned MCID); public: - CodeEmitter(const MCSubtargetInfo &ST, const MCAsmBackend &AB, + CodeEmitter(MCContext &C, const MCSubtargetInfo &ST, const MCAsmBackend &AB, const MCCodeEmitter &CE, ArrayRef S) - : STI(ST), MAB(AB), MCE(CE), VecOS(Code), Sequence(S), + : Ctx(C), STI(ST), MAB(AB), MCE(CE), VecOS(Code), Sequence(S), Encodings(S.size()) {} StringRef getEncoding(unsigned MCID) { diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -998,7 +998,8 @@ // Relax the fragment. MCInst Relaxed = F.getInst(); - getBackend().relaxInstruction(Relaxed, *F.getSubtargetInfo()); + getBackend().relaxInstruction(Relaxed, *F.getSubtargetInfo(), + Layout.getAssembler().getContext()); // Encode the new instruction. // diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -405,7 +405,7 @@ (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) { MCInst Relaxed = Inst; while (Backend.mayNeedRelaxation(Relaxed, STI)) - Backend.relaxInstruction(Relaxed, STI); + Backend.relaxInstruction(Relaxed, STI, Assembler.getContext()); emitInstToData(Relaxed, STI); return; } diff --git a/llvm/lib/MCA/CodeEmitter.cpp b/llvm/lib/MCA/CodeEmitter.cpp --- a/llvm/lib/MCA/CodeEmitter.cpp +++ b/llvm/lib/MCA/CodeEmitter.cpp @@ -25,7 +25,7 @@ const MCInst &Inst = Sequence[MCID]; MCInst Relaxed(Sequence[MCID]); if (MAB.mayNeedRelaxation(Inst, STI)) - MAB.relaxInstruction(Relaxed, STI); + MAB.relaxInstruction(Relaxed, STI, Ctx); EI.first = Code.size(); MCE.encodeInstruction(Relaxed, VecOS, Fixups, STI); diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -91,8 +91,8 @@ bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override; + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override; bool writeNopData(raw_ostream &OS, uint64_t Count) const override; void HandleAssemblerFlag(MCAssemblerFlag Flag) {} @@ -457,7 +457,8 @@ } void AArch64AsmBackend::relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const { + const MCSubtargetInfo &STI, + MCContext &Ctx) const { llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented"); } diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp @@ -37,8 +37,8 @@ const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override; + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override; bool mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const override; @@ -52,7 +52,8 @@ } //End anonymous namespace void AMDGPUAsmBackend::relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const { + const MCSubtargetInfo &STI, + MCContext &Ctx) const { MCInst Res; unsigned RelaxedOpcode = AMDGPU::getSOPPWithRelaxation(Inst.getOpcode()); Res.setOpcode(RelaxedOpcode); diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -66,8 +66,8 @@ const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override; + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override; bool writeNopData(raw_ostream &OS, uint64_t Count) const override; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -322,8 +322,8 @@ return reasonForFixupRelaxation(Fixup, Value); } -void ARMAsmBackend::relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const { +void ARMAsmBackend::relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const { unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode(), STI); // Sanity check w/ diagnostic if we get here w/ a bogus instruction. diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h --- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h +++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h @@ -28,8 +28,8 @@ bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override; + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override; bool writeNopData(raw_ostream &OS, uint64_t Count) const override; std::unique_ptr createObjectTargetWriter() const override; diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp --- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp +++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp @@ -40,8 +40,8 @@ return false; } -void CSKYAsmBackend::relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const { +void CSKYAsmBackend::relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const { llvm_unreachable("CSKYAsmBackend::relaxInstruction() unimplemented"); } diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -651,8 +651,8 @@ llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced"); } - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override { + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override { assert(HexagonMCInstrInfo::isBundle(Inst) && "Hexagon relaxInstruction only works on bundles"); diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -190,8 +190,8 @@ llvm_unreachable("relaxInstruction() unimplemented"); } - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override { + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override { // FIXME. llvm_unreachable("relaxInstruction() unimplemented"); } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -105,8 +105,8 @@ const MCSubtargetInfo &STI) const override; unsigned getRelaxedOpcode(unsigned Op) const; - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override; + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override; bool writeNopData(raw_ostream &OS, uint64_t Count) const override; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -139,8 +139,8 @@ } } -void RISCVAsmBackend::relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const { +void RISCVAsmBackend::relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const { // TODO: replace this with call to auto generated uncompressinstr() function. MCInst Res; switch (Inst.getOpcode()) { diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -265,8 +265,8 @@ llvm_unreachable("fixupNeedsRelaxation() unimplemented"); return false; } - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override { + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override { // FIXME. llvm_unreachable("relaxInstruction() unimplemented"); } diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp --- a/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp +++ b/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp @@ -158,8 +158,8 @@ // branch instructions. return false; } - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override { + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override { // Aurora VE doesn't support relaxInstruction yet. llvm_unreachable("relaxInstruction() should not be called"); } diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -192,17 +192,17 @@ const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; - void relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const override; + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const override; bool padInstructionViaRelaxation(MCRelaxableFragment &RF, - MCCodeEmitter &Emitter, + const MCAssembler &Asm, unsigned &RemainingSize) const; - bool padInstructionViaPrefix(MCRelaxableFragment &RF, MCCodeEmitter &Emitter, + bool padInstructionViaPrefix(MCRelaxableFragment &RF, const MCAssembler &Asm, unsigned &RemainingSize) const; - bool padInstructionEncoding(MCRelaxableFragment &RF, MCCodeEmitter &Emitter, + bool padInstructionEncoding(MCRelaxableFragment &RF, const MCAssembler &Asm, unsigned &RemainingSize) const; void finishLayout(MCAssembler const &Asm, MCAsmLayout &Layout) const override; @@ -827,8 +827,8 @@ // FIXME: Can tblgen help at all here to verify there aren't other instructions // we can relax? -void X86AsmBackend::relaxInstruction(MCInst &Inst, - const MCSubtargetInfo &STI) const { +void X86AsmBackend::relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI, + MCContext &Ctx) const { // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel. bool Is16BitMode = STI.getFeatureBits()[X86::Mode16Bit]; unsigned RelaxedOp = getRelaxedOpcode(Inst, Is16BitMode); @@ -854,7 +854,7 @@ } bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF, - MCCodeEmitter &Emitter, + const MCAssembler &Asm, unsigned &RemainingSize) const { if (!RF.getAllowAutoPadding()) return false; @@ -873,7 +873,7 @@ const unsigned RemainingPrefixSize = [&]() -> unsigned { SmallString<15> Code; raw_svector_ostream VecOS(Code); - Emitter.emitPrefix(RF.getInst(), VecOS, STI); + Asm.getEmitter().emitPrefix(RF.getInst(), VecOS, STI); assert(Code.size() < 15 && "The number of prefixes must be less than 15."); // TODO: It turns out we need a decent amount of plumbing for the target @@ -908,7 +908,7 @@ } bool X86AsmBackend::padInstructionViaRelaxation(MCRelaxableFragment &RF, - MCCodeEmitter &Emitter, + const MCAssembler &Asm, unsigned &RemainingSize) const { if (isFullyRelaxed(RF)) // TODO: There are lots of other tricks we could apply for increasing @@ -916,12 +916,13 @@ return false; MCInst Relaxed = RF.getInst(); - relaxInstruction(Relaxed, *RF.getSubtargetInfo()); + relaxInstruction(Relaxed, *RF.getSubtargetInfo(), Asm.getContext()); SmallVector Fixups; SmallString<15> Code; raw_svector_ostream VecOS(Code); - Emitter.encodeInstruction(Relaxed, VecOS, Fixups, *RF.getSubtargetInfo()); + Asm.getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, + *RF.getSubtargetInfo()); const unsigned OldSize = RF.getContents().size(); const unsigned NewSize = Code.size(); assert(NewSize >= OldSize && "size decrease during relaxation?"); @@ -936,13 +937,13 @@ } bool X86AsmBackend::padInstructionEncoding(MCRelaxableFragment &RF, - MCCodeEmitter &Emitter, + const MCAssembler &Asm, unsigned &RemainingSize) const { bool Changed = false; if (RemainingSize != 0) - Changed |= padInstructionViaRelaxation(RF, Emitter, RemainingSize); + Changed |= padInstructionViaRelaxation(RF, Asm, RemainingSize); if (RemainingSize != 0) - Changed |= padInstructionViaPrefix(RF, Emitter, RemainingSize); + Changed |= padInstructionViaPrefix(RF, Asm, RemainingSize); return Changed; } @@ -1015,7 +1016,7 @@ // Give the backend a chance to play any tricks it wishes to increase // the encoding size of the given instruction. Target independent code // will try further relaxation, but target's may play further tricks. - if (padInstructionEncoding(RF, Asm.getEmitter(), RemainingSize)) + if (padInstructionEncoding(RF, Asm, RemainingSize)) FirstChangedFragment = &RF; // If we have an instruction which hasn't been fully relaxed, we can't diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp --- a/llvm/tools/llvm-mca/llvm-mca.cpp +++ b/llvm/tools/llvm-mca/llvm-mca.cpp @@ -468,7 +468,7 @@ // Lower the MCInst sequence into an mca::Instruction sequence. ArrayRef Insts = Region->getInstructions(); - mca::CodeEmitter CE(*STI, *MAB, *MCE, Insts); + mca::CodeEmitter CE(Ctx, *STI, *MAB, *MCE, Insts); std::vector> LoweredSequence; for (const MCInst &MCI : Insts) { Expected> Inst =