Skip to content

Commit

Permalink
[X86][NFC] Use single table for EVEX compression
Browse files Browse the repository at this point in the history
This patch is to address my review comments in llvm#77065 to simplify the
implemention of EVEX2Legacy compression.
  • Loading branch information
KanRobert committed Jan 6, 2024
1 parent 1687555 commit 0abf3a9
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 46 deletions.
26 changes: 5 additions & 21 deletions llvm/lib/Target/X86/X86CompressEVEX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,7 @@ static bool performCustomAdjustments(MachineInstr &MI, unsigned NewOpc) {
return true;
}

// For EVEX instructions that can be encoded using VEX encoding
// replace them by the VEX encoding in order to reduce size.
static bool CompressEvexToVexImpl(MachineInstr &MI, const X86Subtarget &ST) {
// VEX format.
// # of bytes: 0,2,3 1 1 0,1 0,1,2,4 0,1
// [Prefixes] [VEX] OPCODE ModR/M [SIB] [DISP] [IMM]
//
// EVEX format.
// # of bytes: 4 1 1 1 4 / 1 1
// [Prefixes] EVEX Opcode ModR/M [SIB] [Disp32] / [Disp8*N] [Immediate]
static bool CompressEVEXImpl(MachineInstr &MI, const X86Subtarget &ST) {
const MCInstrDesc &Desc = MI.getDesc();

// Check for EVEX instructions only.
Expand All @@ -251,10 +242,7 @@ static bool CompressEvexToVexImpl(MachineInstr &MI, const X86Subtarget &ST) {
if (Desc.TSFlags & X86II::EVEX_L2)
return false;

// Use the VEX.L bit to select the 128 or 256-bit table.
ArrayRef<X86CompressEVEXTableEntry> Table =
(Desc.TSFlags & X86II::VEX_L) ? ArrayRef(X86EvexToVex256CompressTable)
: ArrayRef(X86EvexToVex128CompressTable);
ArrayRef<X86CompressEVEXTableEntry> Table = ArrayRef(X86CompressEVEXTable);

unsigned Opc = MI.getOpcode();
const auto *I = llvm::lower_bound(Table, Opc);
Expand All @@ -278,10 +266,8 @@ bool CompressEVEXPass::runOnMachineFunction(MachineFunction &MF) {
// Make sure the tables are sorted.
static std::atomic<bool> TableChecked(false);
if (!TableChecked.load(std::memory_order_relaxed)) {
assert(llvm::is_sorted(X86EvexToVex128CompressTable) &&
"X86EvexToVex128CompressTable is not sorted!");
assert(llvm::is_sorted(X86EvexToVex256CompressTable) &&
"X86EvexToVex256CompressTable is not sorted!");
assert(llvm::is_sorted(X86CompressEVEXTable) &&
"X86CompressEVEXTable is not sorted!");
TableChecked.store(true, std::memory_order_relaxed);
}
#endif
Expand All @@ -291,12 +277,10 @@ bool CompressEVEXPass::runOnMachineFunction(MachineFunction &MF) {

bool Changed = false;

/// Go over all basic blocks in function and replace
/// EVEX encoded instrs by VEX encoding when possible.
for (MachineBasicBlock &MBB : MF) {
// Traverse the basic block.
for (MachineInstr &MI : MBB)
Changed |= CompressEvexToVexImpl(MI, ST);
Changed |= CompressEVEXImpl(MI, ST);
}

return Changed;
Expand Down
35 changes: 10 additions & 25 deletions llvm/utils/TableGen/X86CompressEVEXTablesEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ class X86CompressEVEXTablesEmitter {
typedef std::pair<const CodeGenInstruction *, const CodeGenInstruction *>
Entry;

// Represent both compress tables
std::vector<Entry> EVEX2VEX128;
std::vector<Entry> EVEX2VEX256;
std::vector<Entry> Table;

public:
X86CompressEVEXTablesEmitter(RecordKeeper &R) : Records(R), Target(R) {}
Expand All @@ -64,20 +62,13 @@ class X86CompressEVEXTablesEmitter {

void X86CompressEVEXTablesEmitter::printTable(const std::vector<Entry> &Table,
raw_ostream &OS) {
StringRef Size = (Table == EVEX2VEX128) ? "128" : "256";

OS << "// X86 EVEX encoded instructions that have a VEX " << Size
<< " encoding\n"
<< "// (table format: <EVEX opcode, VEX-" << Size << " opcode>).\n"
<< "static const X86CompressEVEXTableEntry X86EvexToVex" << Size
<< "CompressTable[] = {\n"
<< " // EVEX scalar with corresponding VEX.\n";
OS << "static const X86CompressEVEXTableEntry X86CompressEVEXTable[] = { \n";

// Print all entries added to the table
for (const auto &Pair : Table) {
for (const auto &Pair : Table)
OS << " { X86::" << Pair.first->TheDef->getName()
<< ", X86::" << Pair.second->TheDef->getName() << " },\n";
}

OS << "};\n\n";
}
Expand Down Expand Up @@ -175,33 +166,27 @@ void X86CompressEVEXTablesEmitter::run(raw_ostream &OS) {
const Record *Rec = Inst->TheDef;
uint64_t Opcode =
getValueFromBitsInit(Inst->TheDef->getValueAsBitsInit("Opcode"));
const CodeGenInstruction *VEXInst = nullptr;
const CodeGenInstruction *NewInst = nullptr;
if (ManualMap.find(Rec->getName()) != ManualMap.end()) {
Record *NewRec = Records.getDef(ManualMap.at(Rec->getName()));
assert(NewRec && "Instruction not found!");
VEXInst = &Target.getInstruction(NewRec);
NewInst = &Target.getInstruction(NewRec);
} else {
// For each EVEX instruction look for a VEX match in the appropriate
// For each pre-compression instruction look for a match in the appropriate
// vector (instructions with the same opcode) using function object
// IsMatch.
auto Match = llvm::find_if(CompressedInsts[Opcode], IsMatch(Inst));
if (Match != CompressedInsts[Opcode].end())
VEXInst = *Match;
NewInst = *Match;
}

if (!VEXInst)
if (!NewInst)
continue;

// In case a match is found add new entry to the appropriate table
if (Rec->getValueAsBit("hasVEX_L"))
EVEX2VEX256.push_back(std::make_pair(Inst, VEXInst)); // {0,1}
else
EVEX2VEX128.push_back(std::make_pair(Inst, VEXInst)); // {0,0}
Table.push_back(std::make_pair(Inst, NewInst));
}

// Print both tables
printTable(EVEX2VEX128, OS);
printTable(EVEX2VEX256, OS);
printTable(Table, OS);
}
} // namespace

Expand Down

0 comments on commit 0abf3a9

Please sign in to comment.