Skip to content

Commit

Permalink
[snippy][AsmParser] Add DoNotCompress flag for MachineInstr
Browse files Browse the repository at this point in the history
In snippy we need a mechanism to pass information if an instruction can be
compressed or not to AsmPrinter. This patch uses AsmPrinterFlags for this purpose.

It will work is a following way. To generate instructions according to the given
histogram, snippy will disallow compressing main instructions by adding
DoNotCompress flag to them.
  • Loading branch information
asi-sc committed Nov 21, 2024
1 parent c4e5f0d commit 4d7fa97
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 71 deletions.
5 changes: 5 additions & 0 deletions llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<RISCVSubtarget>();
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
}
Expand All @@ -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;
}

Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
34 changes: 34 additions & 0 deletions llvm/test/tools/llvm-snippy/do-not-compress-main-instrs.yaml
Original file line number Diff line number Diff line change
@@ -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]
30 changes: 30 additions & 0 deletions llvm/tools/llvm-snippy/include/snippy/Generator/GenerationUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,36 @@ MachineBasicBlock *createMachineBasicBlock(MachineFunction &MF,

std::string getMBBSectionName(const MachineBasicBlock &MBB);

template <typename... DstArgs>
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 <typename... DstArgs>
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 <typename... DstArgs>
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
20 changes: 0 additions & 20 deletions llvm/tools/llvm-snippy/include/snippy/Support/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,6 @@ inline bool isLoadStoreInstr(unsigned Opcode, const MCInstrInfo &InstrInfo) {
return InstrInfo.get(Opcode).mayLoad() || InstrInfo.get(Opcode).mayStore();
}

template <typename... DstArgs>
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 <typename... DstArgs>
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);
Expand Down
4 changes: 4 additions & 0 deletions llvm/tools/llvm-snippy/include/snippy/Target/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 3 additions & 1 deletion llvm/tools/llvm-snippy/lib/Generator/Generation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Loading

0 comments on commit 4d7fa97

Please sign in to comment.