diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index bb44a78c0129..e7fa9651cfa4 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -127,6 +127,8 @@ void RISCVAsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM, void RISCVAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) { MCInst CInst; bool Res = RISCVRVC::compress(CInst, Inst, *STI); + if (Inst.getFlags() & RISCV::DoNotCompress) + Res = false; if (Res) ++RISCVNumInstrsCompressed; AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst); @@ -907,6 +909,9 @@ static bool lowerRISCVVMachineInstrToMCInst(const MachineInstr *MI, } bool RISCVAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) { + if (MI->getAsmPrinterFlags() & RISCV::DoNotCompress) + OutMI.setFlags(OutMI.getFlags() | RISCV::DoNotCompress); + if (lowerRISCVVMachineInstrToMCInst(MI, OutMI)) return false; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index d17e095a6586..487f09471c6c 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1510,13 +1510,15 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { *TM.getMCAsmInfo()); } + bool CompressionEnabled = !(MI.getAsmPrinterFlags() & RISCV::DoNotCompress); + if (!MI.memoperands_empty()) { MachineMemOperand *MMO = *(MI.memoperands_begin()); const MachineFunction &MF = *MI.getParent()->getParent(); const auto &ST = MF.getSubtarget(); if (ST.hasStdExtZihintntl() && MMO->isNonTemporal()) { if (ST.hasStdExtCOrZca() && ST.enableRVCHintInstrs()) { - if (isCompressibleInst(MI, STI)) + if (isCompressibleInst(MI, STI) && CompressionEnabled) return 4; // c.ntl.all + c.load/c.store return 6; // c.ntl.all + load/store } @@ -1528,7 +1530,7 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { return getInstBundleLength(MI); if (MI.getParent() && MI.getParent()->getParent()) { - if (isCompressibleInst(MI, STI)) + if (isCompressibleInst(MI, STI) && CompressionEnabled) return 2; } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h index 7e1d3f311806..97102ca10223 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h @@ -271,6 +271,15 @@ class RISCVInstrInfo : public RISCVGenInstrInfo { namespace RISCV { +enum AsmComments { + // This flag disables the compression even if C-ext is given and the + // instruction can be compressed. + // This contradicts the purpose of the 'AsmComment' mechanism as it doesn't + // add any asm comment and modifies asm printer behavior. However, currently + // it should not introduce any real problems. + DoNotCompress = MachineInstr::TAsmComments +}; + // Returns true if this is the sext.w pattern, addiw rd, rs1, 0. bool isSEXT_W(const MachineInstr &MI); bool isZEXT_W(const MachineInstr &MI); diff --git a/llvm/test/tools/llvm-snippy/do-not-compress-main-instrs.yaml b/llvm/test/tools/llvm-snippy/do-not-compress-main-instrs.yaml new file mode 100644 index 000000000000..5fcc89e65c5f --- /dev/null +++ b/llvm/test/tools/llvm-snippy/do-not-compress-main-instrs.yaml @@ -0,0 +1,34 @@ +# COM: run snippy and print MF that contains opcodes as we generated them in snippy +# RUN: llvm-snippy %s -o %t -dump-mf >& %t.dump.mf + +# COM: objdump resulting elf, compressed instructions will be parsed with "c.*" +# RUN: llvm-objdump %t.elf -M no-aliases -d >& %t.dump.obj + +# COM: count entries of compressed add instructions from both dumps +# RUN: grep "C_ADD" %t.dump.mf | wc -l >& %t.count.mf +# RUN: grep "c.add" %t.dump.obj | wc -l >& %t.count.obj + +# COM: check that the number of compressed instructions in MF dump and resulting elf +# COM: is the same. +# RUN: diff -q %t.count.mf %t.count.obj + +options: + march: riscv64-unknown-elf + mattr: +c + num-instrs: 100000 + +sections: + - no: 1 + VMA: 0 + SIZE: 0x1000000 + LMA: 0 + ACCESS: rx + - no: 2 + VMA: 0x1000000 + SIZE: 0x1000000 + LMA: 0 + ACCESS: rw + +histogram: + - [ADD, 1.0] + - [C_ADD, 1.0] diff --git a/llvm/tools/llvm-snippy/include/snippy/Generator/GenerationUtils.h b/llvm/tools/llvm-snippy/include/snippy/Generator/GenerationUtils.h index 1602dcfa2a60..6e2b4b0d3d2a 100644 --- a/llvm/tools/llvm-snippy/include/snippy/Generator/GenerationUtils.h +++ b/llvm/tools/llvm-snippy/include/snippy/Generator/GenerationUtils.h @@ -92,6 +92,36 @@ MachineBasicBlock *createMachineBasicBlock(MachineFunction &MF, std::string getMBBSectionName(const MachineBasicBlock &MBB); +template +MachineInstrBuilder +getInstBuilder(bool IsSupport, const SnippyTarget &Tgt, MachineBasicBlock &MBB, + MachineBasicBlock::iterator Ins, LLVMContext &Context, + const MCInstrDesc &Desc, DstArgs... DstReg) { + static_assert(sizeof...(DstReg) <= 1, "Only 0 or 1 dst regs supported"); + MIMetadata MD({}, IsSupport ? getSupportMark(Context) : nullptr); + auto MIB = BuildMI(MBB, Ins, MD, Desc, DstReg...); + Tgt.addAsmPrinterFlags(*MIB.getInstr()); + return MIB; +} + +template +MachineInstrBuilder +getSupportInstBuilder(const SnippyTarget &Tgt, MachineBasicBlock &MBB, + MachineBasicBlock::iterator Ins, LLVMContext &Context, + const MCInstrDesc &Desc, DstArgs... DstReg) { + return getInstBuilder(/* IsSupport */ true, Tgt, MBB, Ins, Context, Desc, + DstReg...); +} + +template +MachineInstrBuilder +getMainInstBuilder(const SnippyTarget &Tgt, MachineBasicBlock &MBB, + MachineBasicBlock::iterator Ins, LLVMContext &Context, + const MCInstrDesc &Desc, DstArgs... DstReg) { + return getInstBuilder(/* IsSupport */ false, Tgt, MBB, Ins, Context, Desc, + DstReg...); +} + } // namespace snippy } // namespace llvm #endif diff --git a/llvm/tools/llvm-snippy/include/snippy/Support/Utils.h b/llvm/tools/llvm-snippy/include/snippy/Support/Utils.h index ce6713fd13da..42ad1d6ddf9f 100644 --- a/llvm/tools/llvm-snippy/include/snippy/Support/Utils.h +++ b/llvm/tools/llvm-snippy/include/snippy/Support/Utils.h @@ -58,26 +58,6 @@ inline bool isLoadStoreInstr(unsigned Opcode, const MCInstrInfo &InstrInfo) { return InstrInfo.get(Opcode).mayLoad() || InstrInfo.get(Opcode).mayStore(); } -template -MachineInstrBuilder -getSupportInstBuilder(MachineBasicBlock &MBB, MachineBasicBlock::iterator Ins, - LLVMContext &Context, const MCInstrDesc &Desc, - DstArgs... DstReg) { - static_assert(sizeof...(DstReg) <= 1, "Only 0 or 1 dst regs supported"); - return BuildMI(MBB, Ins, MIMetadata({}, getSupportMark(Context)), Desc, - DstReg...); -} - -template -MachineInstrBuilder getInstBuilder(bool IsSupport, MachineBasicBlock &MBB, - MachineBasicBlock::iterator Ins, - LLVMContext &Context, - const MCInstrDesc &Desc, DstArgs... DstReg) { - if (IsSupport) - return getSupportInstBuilder(MBB, Ins, Context, Desc, DstReg...); - return BuildMI(MBB, Ins, MIMetadata(), Desc, DstReg...); -} - std::string addExtensionIfRequired(StringRef StrRef, std::string Ext); void writeFile(StringRef Path, StringRef Data); diff --git a/llvm/tools/llvm-snippy/include/snippy/Target/Target.h b/llvm/tools/llvm-snippy/include/snippy/Target/Target.h index 23c8360fc2cd..f82852e05215 100644 --- a/llvm/tools/llvm-snippy/include/snippy/Target/Target.h +++ b/llvm/tools/llvm-snippy/include/snippy/Target/Target.h @@ -530,6 +530,10 @@ class SnippyTarget { generateJump(MachineBasicBlock &MBB, MachineBasicBlock::iterator Ins, MachineBasicBlock &TBB, LLVMState &State) const = 0; + // Add any additional target-dependent flags to provide additional information + // to asm printer. + virtual void addAsmPrinterFlags(MachineInstr &MI) const = 0; + private: virtual bool matchesArch(Triple::ArchType Arch) const = 0; diff --git a/llvm/tools/llvm-snippy/lib/Generator/Generation.cpp b/llvm/tools/llvm-snippy/lib/Generator/Generation.cpp index 690d93ac2258..cafa750b97e4 100644 --- a/llvm/tools/llvm-snippy/lib/Generator/Generation.cpp +++ b/llvm/tools/llvm-snippy/lib/Generator/Generation.cpp @@ -1047,7 +1047,9 @@ randomInstruction(const MCInstrDesc &InstrDesc, auto &State = GC.getLLVMState(); const auto &SnippyTgt = State.getSnippyTarget(); - auto MIB = BuildMI(MBB, InstrGenCtx.Ins, MIMetadata(), InstrDesc); + auto MIB = getMainInstBuilder(SnippyTgt, MBB, InstrGenCtx.Ins, + MBB.getParent()->getFunction().getContext(), + InstrDesc); bool DoPostprocess = isPostprocessNeeded(InstrDesc, Preselected, GC); diff --git a/llvm/tools/llvm-snippy/lib/Target/RISCV/Target.cpp b/llvm/tools/llvm-snippy/lib/Target/RISCV/Target.cpp index 0cac2915189a..b3de98b0bcbb 100644 --- a/llvm/tools/llvm-snippy/lib/Target/RISCV/Target.cpp +++ b/llvm/tools/llvm-snippy/lib/Target/RISCV/Target.cpp @@ -544,10 +544,12 @@ RISCVMatInt::InstSeq getIntMatInstrSeq(APInt Value, GeneratorContext &GC) { } void generateRVVMaskReset(const MCInstrInfo &InstrInfo, MachineBasicBlock &MBB, - MachineBasicBlock::iterator Ins) { + MachineBasicBlock::iterator Ins, + const SnippyTarget &Tgt) { if (NoMaskModeForRVV) return; - getSupportInstBuilder(MBB, Ins, MBB.getParent()->getFunction().getContext(), + getSupportInstBuilder(Tgt, MBB, Ins, + MBB.getParent()->getFunction().getContext(), InstrInfo.get(RISCV::VMXNOR_MM)) .addReg(RISCV::V0, RegState::Define) .addReg(RISCV::V0, RegState::Undef) @@ -853,13 +855,13 @@ template static void storeWordToMem(It MemIt, uint32_t Value) { static void addGeneratedInstrsToBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator Ins, - GeneratorContext &GC, - ArrayRef Insts) { + GeneratorContext &GC, ArrayRef Insts, + const SnippyTarget &Tgt) { auto &State = GC.getLLVMState(); const auto &InstrInfo = State.getInstrInfo(); for (const auto &Inst : Insts) { - auto MIB = getSupportInstBuilder(MBB, Ins, State.getCtx(), + auto MIB = getSupportInstBuilder(Tgt, MBB, Ins, State.getCtx(), InstrInfo.get(Inst.getOpcode())); assert(Inst.begin()->isReg() && "In write instructions, the first operand " "is always the destination register"); @@ -1142,7 +1144,7 @@ class SnippyRISCVTarget final : public SnippyTarget { auto XReg = regIndexToMCReg(RegNo, RegStorageType::XReg, GC); auto VReg = regIndexToMCReg(RegNo, RegStorageType::VReg, GC); if (!RP.isReserved(VReg, MBB)) - getSupportInstBuilder(MBB, InsertPos, + getSupportInstBuilder(*this, MBB, InsertPos, MBB.getParent()->getFunction().getContext(), InstrInfo.get(RISCV::VMV_V_X), VReg) .addReg(XReg); @@ -1388,7 +1390,9 @@ class SnippyRISCVTarget final : public SnippyTarget { } const auto &RegInfo = State.getRegInfo(); - auto MIB = BuildMI(MBB, MBB.end(), MIMetadata(), BranchDesc); + auto MIB = getMainInstBuilder(*this, MBB, MBB.end(), + MBB.getParent()->getFunction().getContext(), + BranchDesc); const auto &MCRegClass = RegInfo.getRegClass(BranchDesc.operands()[0].RegClass); auto FirstReg = RP.getAvailableRegister("for branch condition", RegInfo, @@ -1428,7 +1432,9 @@ class SnippyRISCVTarget final : public SnippyTarget { auto CondReg = CondOp.getReg(); auto *DstMBB = getBranchDestination(Branch); assert(DstMBB); - auto &MI = *BuildMI(*MBB, Branch, MIMetadata(), InstrInfo.get(UncompOpcode)) + auto &MI = *getMainInstBuilder(*this, *MBB, Branch, + MBB->getParent()->getFunction().getContext(), + InstrInfo.get(UncompOpcode)) .addReg(CondReg) .addReg(RISCV::X0) .addMBB(DstMBB); @@ -1492,7 +1498,7 @@ class SnippyRISCVTarget final : public SnippyTarget { void insertFallbackBranch(MachineBasicBlock &From, MachineBasicBlock &To, const LLVMState &State) const override { const auto &InstrInfo = State.getInstrInfo(); - getSupportInstBuilder(From, From.end(), + getSupportInstBuilder(*this, From, From.end(), From.getParent()->getFunction().getContext(), InstrInfo.get(RISCV::PseudoBR)) .addMBB(&To); @@ -1650,7 +1656,10 @@ class SnippyRISCVTarget final : public SnippyTarget { auto FirstReg = EqBranch ? ReservedRegs[LimitRegIdx] : ReservedRegs[CounterRegIdx]; auto NewBranch = - BuildMI(*BranchMBB, Branch, MIMetadata(), InstrDesc).addReg(FirstReg); + getMainInstBuilder(*this, *BranchMBB, Branch, + BranchMBB->getParent()->getFunction().getContext(), + InstrDesc) + .addReg(FirstReg); if (!isCompressedBranch(Opcode)) { auto SecondReg = EqBranch ? RISCV::X0 : ReservedRegs[LimitRegIdx]; NewBranch.addReg(SecondReg); @@ -1831,14 +1840,14 @@ class SnippyRISCVTarget final : public SnippyTarget { auto LimitReg = ReservedRegs[LimitRegIdx]; // Closest power of two (floor) NIter = bit_floor(NIter); - getSupportInstBuilder(MBB, Pos, + getSupportInstBuilder(*this, MBB, Pos, MBB.getParent()->getFunction().getContext(), InstrInfo.get(ADDIOp)) .addReg(CounterReg, RegState::Define) .addReg(CounterReg) .addImm(1); // SRLI can't be compressed because rd and rs1 are different regs - getSupportInstBuilder(MBB, Pos, + getSupportInstBuilder(*this, MBB, Pos, MBB.getParent()->getFunction().getContext(), InstrInfo.get(RISCV::SRLI)) .addReg(LimitReg, RegState::Define) @@ -1863,7 +1872,7 @@ class SnippyRISCVTarget final : public SnippyTarget { "C_BNEZ is not supported with non zero value of the loop counter"); [[fallthrough]]; case RISCV::BNE: - getSupportInstBuilder(MBB, Pos, + getSupportInstBuilder(*this, MBB, Pos, MBB.getParent()->getFunction().getContext(), InstrInfo.get(ADDIOp)) .addReg(CounterReg, RegState::Define) @@ -1875,7 +1884,7 @@ class SnippyRISCVTarget final : public SnippyTarget { break; case RISCV::BLT: case RISCV::BLTU: - getSupportInstBuilder(MBB, Pos, + getSupportInstBuilder(*this, MBB, Pos, MBB.getParent()->getFunction().getContext(), InstrInfo.get(ADDIOp)) .addReg(CounterReg, RegState::Define) @@ -1888,7 +1897,7 @@ class SnippyRISCVTarget final : public SnippyTarget { break; case RISCV::BGE: case RISCV::BGEU: - getSupportInstBuilder(MBB, Pos, + getSupportInstBuilder(*this, MBB, Pos, MBB.getParent()->getFunction().getContext(), InstrInfo.get(ADDIOp)) .addReg(CounterReg, RegState::Define) @@ -1916,7 +1925,7 @@ class SnippyRISCVTarget final : public SnippyTarget { unsigned LastInstrOpc) const override { const auto &InstrInfo = GC.getLLVMState().getInstrInfo(); auto MIB = getSupportInstBuilder( - MBB, MBB.end(), MBB.getParent()->getFunction().getContext(), + *this, MBB, MBB.end(), MBB.getParent()->getFunction().getContext(), InstrInfo.get(LastInstrOpc)); return MIB; } @@ -2025,7 +2034,7 @@ class SnippyRISCVTarget final : public SnippyTarget { auto &State = GC.getLLVMState(); const auto &InstrInfo = State.getInstrInfo(); auto &Ctx = State.getCtx(); - getSupportInstBuilder(MBB, Ins, Ctx, InstrInfo.get(RISCV::ADDI)) + getSupportInstBuilder(*this, MBB, Ins, Ctx, InstrInfo.get(RISCV::ADDI)) .addDef(SP) .addReg(SP) .addImm(-static_cast(getSpillSizeInBytes(Reg, GC))); @@ -2044,7 +2053,7 @@ class SnippyRISCVTarget final : public SnippyTarget { auto &Ctx = State.getCtx(); loadRegFromAddrInReg(MBB, Ins, SP, Reg, GC); - getSupportInstBuilder(MBB, Ins, Ctx, InstrInfo.get(RISCV::ADDI)) + getSupportInstBuilder(*this, MBB, Ins, Ctx, InstrInfo.get(RISCV::ADDI)) .addDef(SP) .addReg(SP) .addImm(getSpillSizeInBytes(Reg, GC)); @@ -2060,7 +2069,7 @@ class SnippyRISCVTarget final : public SnippyTarget { const auto &InstrInfo = State.getInstrInfo(); auto &Ctx = State.getCtx(); - getSupportInstBuilder(MBB, Ins, Ctx, InstrInfo.get(RISCV::ADDI)) + getSupportInstBuilder(*this, MBB, Ins, Ctx, InstrInfo.get(RISCV::ADDI)) .addDef(SP) .addReg(SP) .addImm(getSpillSizeInBytes(Reg, GC)); @@ -2087,13 +2096,14 @@ class SnippyRISCVTarget final : public SnippyTarget { // That's why create auipc + addi pair manually. MachineInstr *MIAUIPC = - getSupportInstBuilder(MBB, Ins, Ctx, InstrInfo.get(RISCV::AUIPC)) + getSupportInstBuilder(*this, MBB, Ins, Ctx, InstrInfo.get(RISCV::AUIPC)) .addReg(DestReg) .addGlobalAddress(Target, 0, RISCVII::MO_PCREL_HI); MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("pcrel_hi"); MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol); - return getSupportInstBuilder(MBB, Ins, Ctx, InstrInfo.get(RISCV::ADDI)) + return getSupportInstBuilder(*this, MBB, Ins, Ctx, + InstrInfo.get(RISCV::ADDI)) .addReg(DestReg) .addReg(DestReg) .addSym(AUIPCSymbol, RISCVII::MO_PCREL_LO); @@ -2108,7 +2118,7 @@ class SnippyRISCVTarget final : public SnippyTarget { auto &Ctx = State.getCtx(); // Despite PseudoCALL gets expanded by RISCVMCCodeEmitter to JALR // instruction, it has chance to be relaxed back to JAL by linker. - return getInstBuilder(AsSupport, MBB, Ins, Ctx, + return getInstBuilder(AsSupport, *this, MBB, Ins, Ctx, InstrInfo.get(RISCV::PseudoCALL)) .addGlobalAddress(&Target, 0, RISCVII::MO_CALL); } @@ -2126,7 +2136,7 @@ class SnippyRISCVTarget final : public SnippyTarget { auto Reg = getNonZeroReg("scratch register for storing function address", RI, RegClass, RP, MBB); loadSymbolAddress(MBB, Ins, GC, Reg, &Target); - return getInstBuilder(AsSupport, MBB, Ins, Ctx, + return getInstBuilder(AsSupport, *this, MBB, Ins, Ctx, InstrInfo.get(RISCV::PseudoCALLIndirect)) .addReg(Reg); } @@ -2152,7 +2162,7 @@ class SnippyRISCVTarget final : public SnippyTarget { const auto &InstrInfo = GC.getLLVMState().getInstrInfo(); auto &State = GC.getLLVMState(); auto &Ctx = State.getCtx(); - return getSupportInstBuilder(MBB, MBB.end(), Ctx, + return getSupportInstBuilder(*this, MBB, MBB.end(), Ctx, InstrInfo.get(RISCV::PseudoTAIL)) .addGlobalAddress(&Target, 0, RISCVII::MO_CALL); } @@ -2161,7 +2171,7 @@ class SnippyRISCVTarget final : public SnippyTarget { const LLVMState &State) const override { const auto &InstrInfo = State.getInstrInfo(); auto MIB = getSupportInstBuilder( - MBB, MBB.end(), MBB.getParent()->getFunction().getContext(), + *this, MBB, MBB.end(), MBB.getParent()->getFunction().getContext(), InstrInfo.get(RISCV::PseudoRET)); return MIB; } @@ -2171,7 +2181,7 @@ class SnippyRISCVTarget final : public SnippyTarget { const LLVMState &State) const override { const auto &InstrInfo = State.getInstrInfo(); auto MIB = getSupportInstBuilder( - MBB, Ins, MBB.getParent()->getFunction().getContext(), + *this, MBB, Ins, MBB.getParent()->getFunction().getContext(), InstrInfo.get(RISCV::ADDI), RISCV::X0) .addReg(RISCV::X0) .addImm(0); @@ -2241,7 +2251,7 @@ class SnippyRISCVTarget final : public SnippyTarget { getTransformSequenceLength(OldValue, NewValue, Register, GC) == (getWriteValueSequenceLength(ValueToWrite, ScratchReg, GC) + 1) && "Generated sequence length does not match expected one"); - getSupportInstBuilder(MBB, Ins, State.getCtx(), + getSupportInstBuilder(*this, MBB, Ins, State.getCtx(), InstrInfo.get(WillUseAdd ? RISCV::ADD : RISCV::SUB), Register) .addReg(Register) @@ -2264,8 +2274,8 @@ class SnippyRISCVTarget final : public SnippyTarget { auto XRegBitSize = getRegBitWidth(Register, GC); writeValueToReg(MBB, Ins, APInt(XRegBitSize, Stride), Register, RP, GC); - getSupportInstBuilder(MBB, Ins, State.getCtx(), InstrInfo.get(RISCV::MUL), - Register) + getSupportInstBuilder(*this, MBB, Ins, State.getCtx(), + InstrInfo.get(RISCV::MUL), Register) .addReg(Register) .addReg(IndexReg); @@ -2277,8 +2287,8 @@ class SnippyRISCVTarget final : public SnippyTarget { getNonZeroReg("Scratch register for BaseAddr", RI, RegClass, RP, MBB); writeValueToReg(MBB, Ins, APInt(XRegBitSize, BaseAddr), AddrReg, RP, GC); - getSupportInstBuilder(MBB, Ins, State.getCtx(), InstrInfo.get(RISCV::ADD), - Register) + getSupportInstBuilder(*this, MBB, Ins, State.getCtx(), + InstrInfo.get(RISCV::ADD), Register) .addReg(Register) .addReg(AddrReg); } @@ -2528,7 +2538,7 @@ class SnippyRISCVTarget final : public SnippyTarget { SmallVector InstrsForWrite; generateWriteValueSeq(Value, DstReg, GC, RP, MBB, InstrsForWrite); - addGeneratedInstrsToBB(MBB, Ins, GC, InstrsForWrite); + addGeneratedInstrsToBB(MBB, Ins, GC, InstrsForWrite, *this); } void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Ins, @@ -2538,7 +2548,8 @@ class SnippyRISCVTarget final : public SnippyTarget { "Both src and dst registers must be GPR"); auto &State = GC.getLLVMState(); const auto &InstrInfo = State.getInstrInfo(); - getSupportInstBuilder(MBB, Ins, MBB.getParent()->getFunction().getContext(), + getSupportInstBuilder(*this, MBB, Ins, + MBB.getParent()->getFunction().getContext(), InstrInfo.get(RISCV::ADD), Rd) .addReg(Rs) .addReg(RISCV::X0); @@ -2548,7 +2559,7 @@ class SnippyRISCVTarget final : public SnippyTarget { MachineBasicBlock::iterator Ins, MCRegister AddrReg, MCRegister Reg, GeneratorContext &GC) const { const auto LoadInstr = generateLoadRegFromAddrInReg(AddrReg, Reg, GC); - addGeneratedInstrsToBB(MBB, Ins, GC, {LoadInstr}); + addGeneratedInstrsToBB(MBB, Ins, GC, {LoadInstr}, *this); } MCInst generateLoadRegFromAddrInReg(MCRegister AddrReg, MCRegister Reg, @@ -2579,7 +2590,7 @@ class SnippyRISCVTarget final : public SnippyTarget { GeneratorContext &GC) const override { SmallVector InstrsForWrite; generateLoadRegFromAddr(MBB, Addr, Reg, RP, GC, InstrsForWrite); - addGeneratedInstrsToBB(MBB, Ins, GC, InstrsForWrite); + addGeneratedInstrsToBB(MBB, Ins, GC, InstrsForWrite, *this); } void generateLoadRegFromAddr(const MachineBasicBlock &MBB, uint64_t Addr, @@ -2610,7 +2621,7 @@ class SnippyRISCVTarget final : public SnippyTarget { if (RISCV::GPRRegClass.contains(Reg)) { auto StoreOp = getStoreOpcode(BytesToWrite ? BytesToWrite * RISCV_CHAR_BIT : getRegBitWidth(Reg, GC)); - getSupportInstBuilder(MBB, Ins, Ctx, InstrInfo.get(StoreOp)) + getSupportInstBuilder(*this, MBB, Ins, Ctx, InstrInfo.get(StoreOp)) .addReg(Reg) .addReg(AddrReg) .addImm(0); @@ -2618,21 +2629,21 @@ class SnippyRISCVTarget final : public SnippyTarget { RISCV::FPR16RegClass.contains(Reg)) { assert(BytesToWrite == 0 || BytesToWrite * RISCV_CHAR_BIT == getRegBitWidth(Reg, GC)); - getSupportInstBuilder(MBB, Ins, Ctx, InstrInfo.get(RISCV::FSW)) + getSupportInstBuilder(*this, MBB, Ins, Ctx, InstrInfo.get(RISCV::FSW)) .addReg(Reg) .addReg(AddrReg) .addImm(0); } else if (RISCV::FPR64RegClass.contains(Reg)) { assert(BytesToWrite == 0 || BytesToWrite * RISCV_CHAR_BIT == getRegBitWidth(Reg, GC)); - getSupportInstBuilder(MBB, Ins, Ctx, InstrInfo.get(RISCV::FSD)) + getSupportInstBuilder(*this, MBB, Ins, Ctx, InstrInfo.get(RISCV::FSD)) .addReg(Reg) .addReg(AddrReg) .addImm(0); } else if (RISCV::VRRegClass.contains(Reg)) { assert(BytesToWrite == 0 || BytesToWrite * RISCV_CHAR_BIT == getRegBitWidth(Reg, GC)); - getSupportInstBuilder(MBB, Ins, Ctx, InstrInfo.get(RISCV::VS1R_V)) + getSupportInstBuilder(*this, MBB, Ins, Ctx, InstrInfo.get(RISCV::VS1R_V)) .addReg(Reg) .addReg(AddrReg); } else { @@ -3011,11 +3022,19 @@ class SnippyRISCVTarget final : public SnippyTarget { MachineBasicBlock &TBB, LLVMState &State) const override { auto &InstrInfo = State.getInstrInfo(); - return *getSupportInstBuilder(MBB, Ins, State.getCtx(), + return *getSupportInstBuilder(*this, MBB, Ins, State.getCtx(), InstrInfo.get(RISCV::PseudoBR)) .addMBB(&TBB) .getInstr(); } + + void addAsmPrinterFlags(MachineInstr &MI) const override { + // Add DoNotCompress flags only to main instructions as they must correspond + // to the given histogram. On the other hand, we'd like to compress support + // instructions as much as possible to reduce total overhead. + if (!checkSupportMetadata(MI)) + MI.setAsmPrinterFlag(RISCV::DoNotCompress); + } }; static unsigned getOpcodeForGPRToFPRInstr(unsigned DstReg, unsigned XLen, @@ -3120,7 +3139,7 @@ void SnippyRISCVTarget::rvvWriteValueUsingXReg(MachineBasicBlock &MBB, for (unsigned Idx = 0; Idx < VL; ++Idx) { auto EltValue = Value.extractBitsAsZExtValue(SEW, Idx * SEW); writeValueToReg(MBB, Ins, APInt(SEW, EltValue), XScratchReg, RP, GC); - getSupportInstBuilder(MBB, Ins, State.getCtx(), + getSupportInstBuilder(*this, MBB, Ins, State.getCtx(), InstrInfo.get(RISCV::VSLIDE1DOWN_VX), DstReg) .addReg(DstReg, RegFlags) .addReg(XScratchReg) @@ -3282,7 +3301,7 @@ void SnippyRISCVTarget::generateV0MaskUpdate( LLVM_DEBUG(dbgs() << "Resetting mask instruction for mask:" << toString(VLVM.VM, /* Radix */ 16, /* Signed */ false) << "\n"); - generateRVVMaskReset(InstrInfo, MBB, Ins); + generateRVVMaskReset(InstrInfo, MBB, Ins, *this); return; } @@ -3314,8 +3333,9 @@ void SnippyRISCVTarget::generateVSETIVLI( snippy::fatal(formatv("cannot set the desired VL {0} since selected " "VSETIVLI does not support it", VL)); - auto MIB = getInstBuilder(SupportMarker, MBB, Ins, GC.getLLVMState().getCtx(), - InstrInfo.get(RISCV::VSETIVLI)); + auto MIB = + getInstBuilder(SupportMarker, *this, MBB, Ins, GC.getLLVMState().getCtx(), + InstrInfo.get(RISCV::VSETIVLI)); MIB.addDef(DstReg).addImm(VL).addImm(VTYPE); } @@ -3337,8 +3357,9 @@ void SnippyRISCVTarget::generateVSETVLI(const MCInstrInfo &InstrInfo, writeValueToReg(MBB, Ins, APInt(GC.getSubtarget().getXLen(), VL), ScratchRegVL, RP, GC); - auto MIB = getInstBuilder(SupportMarker, MBB, Ins, GC.getLLVMState().getCtx(), - InstrInfo.get(RISCV::VSETVLI)); + auto MIB = + getInstBuilder(SupportMarker, *this, MBB, Ins, GC.getLLVMState().getCtx(), + InstrInfo.get(RISCV::VSETVLI)); MIB.addDef(DstReg); MIB.addReg(ScratchRegVL); MIB.addImm(VTYPE); @@ -3367,8 +3388,9 @@ void SnippyRISCVTarget::generateVSETVL(const MCInstrInfo &InstrInfo, RP.addReserved(ScratchRegVL); writeValueToReg(MBB, Ins, APInt(ST.getXLen(), VTYPE), ScratchRegVType, RP, GC); - auto MIB = getInstBuilder(SupportMarker, MBB, Ins, GC.getLLVMState().getCtx(), - InstrInfo.get(RISCV::VSETVL)); + auto MIB = + getInstBuilder(SupportMarker, *this, MBB, Ins, GC.getLLVMState().getCtx(), + InstrInfo.get(RISCV::VSETVL)); MIB.addDef(DstReg); MIB.addReg(ScratchRegVL); MIB.addReg(ScratchRegVType); diff --git a/llvm/tools/llvm-snippy/lib/Target/X86/Target.cpp b/llvm/tools/llvm-snippy/lib/Target/X86/Target.cpp index 878dde77feca..6873076281f1 100644 --- a/llvm/tools/llvm-snippy/lib/Target/X86/Target.cpp +++ b/llvm/tools/llvm-snippy/lib/Target/X86/Target.cpp @@ -530,6 +530,8 @@ class SnippyX86Target : public SnippyTarget { LLVMState &State) const override { reportUnimplementedError(); } + + void addAsmPrinterFlags(MachineInstr &MI) const override {} }; // namespace bool SnippyX86Target::matchesArch(Triple::ArchType Arch) const {