[llvm] bdc7840 - [X86][CodeGen] Share code between CompressEVEX pass and ND2NonND transform, NFCI
Shengchen Kan via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 19 01:04:17 PDT 2024
Author: Shengchen Kan
Date: 2024-06-19T16:03:57+08:00
New Revision: bdc7840c5758076e63719d45427c3c756c630ddd
URL: https://github.com/llvm/llvm-project/commit/bdc7840c5758076e63719d45427c3c756c630ddd
DIFF: https://github.com/llvm/llvm-project/commit/bdc7840c5758076e63719d45427c3c756c630ddd.diff
LOG: [X86][CodeGen] Share code between CompressEVEX pass and ND2NonND transform, NFCI
Added:
llvm/utils/TableGen/X86ManualInstrMapping.def
Modified:
llvm/lib/Target/X86/X86CompressEVEX.cpp
llvm/lib/Target/X86/X86InstrInfo.cpp
llvm/lib/Target/X86/X86InstrInfo.h
llvm/utils/TableGen/X86InstrMappingEmitter.cpp
Removed:
llvm/utils/TableGen/X86ManualCompressEVEXTables.def
################################################################################
diff --git a/llvm/lib/Target/X86/X86CompressEVEX.cpp b/llvm/lib/Target/X86/X86CompressEVEX.cpp
index 11b2155e3f985..7343af1bdc9a5 100644
--- a/llvm/lib/Target/X86/X86CompressEVEX.cpp
+++ b/llvm/lib/Target/X86/X86CompressEVEX.cpp
@@ -174,29 +174,6 @@ static bool performCustomAdjustments(MachineInstr &MI, unsigned NewOpc) {
return true;
}
-static bool isRedundantNewDataDest(MachineInstr &MI, const X86Subtarget &ST) {
- // $rbx = ADD64rr_ND $rbx, $rax / $rbx = ADD64rr_ND $rax, $rbx
- // ->
- // $rbx = ADD64rr $rbx, $rax
- const MCInstrDesc &Desc = MI.getDesc();
- Register Reg0 = MI.getOperand(0).getReg();
- const MachineOperand &Op1 = MI.getOperand(1);
- if (!Op1.isReg() || X86::getFirstAddrOperandIdx(MI) == 1 ||
- X86::isCFCMOVCC(MI.getOpcode()))
- return false;
- Register Reg1 = Op1.getReg();
- if (Reg1 == Reg0)
- return true;
-
- // Op1 and Op2 may be commutable for ND instructions.
- if (!Desc.isCommutable() || Desc.getNumOperands() < 3 ||
- !MI.getOperand(2).isReg() || MI.getOperand(2).getReg() != Reg0)
- return false;
- // Opcode may change after commute, e.g. SHRD -> SHLD
- ST.getInstrInfo()->commuteInstruction(MI, false, 1, 2);
- return true;
-}
-
static bool CompressEVEXImpl(MachineInstr &MI, const X86Subtarget &ST) {
uint64_t TSFlags = MI.getDesc().TSFlags;
@@ -208,6 +185,30 @@ static bool CompressEVEXImpl(MachineInstr &MI, const X86Subtarget &ST) {
if (TSFlags & (X86II::EVEX_K | X86II::EVEX_L2))
return false;
+ auto IsRedundantNewDataDest = [&](unsigned &Opc) {
+ // $rbx = ADD64rr_ND $rbx, $rax / $rbx = ADD64rr_ND $rax, $rbx
+ // ->
+ // $rbx = ADD64rr $rbx, $rax
+ const MCInstrDesc &Desc = MI.getDesc();
+ Register Reg0 = MI.getOperand(0).getReg();
+ const MachineOperand &Op1 = MI.getOperand(1);
+ if (!Op1.isReg() || X86::getFirstAddrOperandIdx(MI) == 1 ||
+ X86::isCFCMOVCC(MI.getOpcode()))
+ return false;
+ Register Reg1 = Op1.getReg();
+ if (Reg1 == Reg0)
+ return true;
+
+ // Op1 and Op2 may be commutable for ND instructions.
+ if (!Desc.isCommutable() || Desc.getNumOperands() < 3 ||
+ !MI.getOperand(2).isReg() || MI.getOperand(2).getReg() != Reg0)
+ return false;
+ // Opcode may change after commute, e.g. SHRD -> SHLD
+ ST.getInstrInfo()->commuteInstruction(MI, false, 1, 2);
+ Opc = MI.getOpcode();
+ return true;
+ };
+
// EVEX_B has several meanings.
// AVX512:
// register form: rounding control or SAE
@@ -218,40 +219,36 @@ static bool CompressEVEXImpl(MachineInstr &MI, const X86Subtarget &ST) {
//
// For AVX512 cases, EVEX prefix is needed in order to carry this information
// thus preventing the transformation to VEX encoding.
- unsigned Opc = MI.getOpcode();
bool IsND = X86II::hasNewDataDest(TSFlags);
if (TSFlags & X86II::EVEX_B && !IsND)
return false;
+ unsigned Opc = MI.getOpcode();
// MOVBE*rr is special because it has semantic of NDD but not set EVEX_B.
bool IsNDLike = IsND || Opc == X86::MOVBE32rr || Opc == X86::MOVBE64rr;
- bool IsRedundantNDD = IsNDLike ? isRedundantNewDataDest(MI, ST) : false;
- // NonNF -> NF only if it's not a compressible NDD instruction and eflags is
- // dead.
- unsigned NFOpc = (ST.hasNF() && !IsRedundantNDD &&
- MI.registerDefIsDead(X86::EFLAGS, /*TRI=*/nullptr))
- ? X86::getNFVariant(Opc)
- : 0U;
- if (IsNDLike && !IsRedundantNDD && !NFOpc)
- return false;
+ bool IsRedundantNDD = IsNDLike ? IsRedundantNewDataDest(Opc) : false;
- unsigned NewOpc = NFOpc;
- if (!NewOpc) {
+ auto GetCompressedOpc = [&](unsigned Opc) -> unsigned {
ArrayRef<X86TableEntry> Table = ArrayRef(X86CompressEVEXTable);
-
- Opc = MI.getOpcode();
const auto I = llvm::lower_bound(Table, Opc);
- if (I == Table.end() || I->OldOpc != Opc) {
- assert(!IsNDLike && "Missing entry for ND-like instruction");
- return false;
- }
-
- if (!IsNDLike) {
- if (usesExtendedRegister(MI) || !checkPredicate(I->NewOpc, &ST) ||
- !performCustomAdjustments(MI, I->NewOpc))
- return false;
- }
- NewOpc = I->NewOpc;
- }
+ if (I == Table.end() || I->OldOpc != Opc)
+ return 0;
+
+ if (usesExtendedRegister(MI) || !checkPredicate(I->NewOpc, &ST) ||
+ !performCustomAdjustments(MI, I->NewOpc))
+ return 0;
+ return I->NewOpc;
+ };
+ // NonNF -> NF only if it's not a compressible NDD instruction and eflags is
+ // dead.
+ unsigned NewOpc = IsRedundantNDD
+ ? X86::getNonNDVariant(Opc)
+ : ((IsNDLike && ST.hasNF() &&
+ MI.registerDefIsDead(X86::EFLAGS, /*TRI=*/nullptr))
+ ? X86::getNFVariant(Opc)
+ : GetCompressedOpc(Opc));
+
+ if (!NewOpc)
+ return false;
const MCInstrDesc &NewDesc = ST.getInstrInfo()->get(NewOpc);
MI.setDesc(NewDesc);
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 66d0c09d08551..1a43d5c17080e 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -3224,18 +3224,18 @@ int X86::getCCMPCondFlagsFromCondCode(X86::CondCode CC) {
#define GET_X86_NF_TRANSFORM_TABLE
#define GET_X86_ND2NONND_TABLE
#include "X86GenInstrMapping.inc"
-unsigned X86::getNFVariant(unsigned Opc) {
- ArrayRef<X86TableEntry> Table = ArrayRef(X86NFTransformTable);
+
+static unsigned getNewOpcFromTable(ArrayRef<X86TableEntry> Table,
+ unsigned Opc) {
const auto I = llvm::lower_bound(Table, Opc);
return (I == Table.end() || I->OldOpc != Opc) ? 0U : I->NewOpc;
}
+unsigned X86::getNFVariant(unsigned Opc) {
+ return getNewOpcFromTable(X86NFTransformTable, Opc);
+}
-static unsigned getNonNDVariant(unsigned Opc, const X86Subtarget &STI) {
- if (!STI.hasNDD())
- return 0U;
- ArrayRef<X86TableEntry> Table = ArrayRef(X86ND2NonNDTable);
- const auto I = llvm::lower_bound(Table, Opc);
- return (I == Table.end() || I->OldOpc != Opc) ? 0U : I->NewOpc;
+unsigned X86::getNonNDVariant(unsigned Opc) {
+ return getNewOpcFromTable(X86ND2NonNDTable, Opc);
}
/// Return the inverse of the specified condition,
@@ -7393,7 +7393,7 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
// replacing the *two* registers with the memory location.
//
// Utilize the mapping NonNDD -> RMW for the NDD variant.
- unsigned NonNDOpc = getNonNDVariant(Opc, Subtarget);
+ unsigned NonNDOpc = Subtarget.hasNDD() ? X86::getNonNDVariant(Opc) : 0U;
const X86FoldTableEntry *I =
IsTwoAddr ? lookupTwoAddrFoldTable(NonNDOpc ? NonNDOpc : Opc)
: lookupFoldTable(Opc, OpNum);
@@ -7514,7 +7514,8 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
switch (Opc) {
default:
// NDD can be folded into RMW though its Op0 and Op1 are not tied.
- return getNonNDVariant(Opc, Subtarget) ? Impl() : nullptr;
+ return (Subtarget.hasNDD() ? X86::getNonNDVariant(Opc) : 0U) ? Impl()
+ : nullptr;
case X86::TEST8rr:
NewOpc = X86::CMP8ri;
RCSize = 1;
diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h
index 9eb2bd56b2ab5..eaa3dd0893948 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.h
+++ b/llvm/lib/Target/X86/X86InstrInfo.h
@@ -80,6 +80,9 @@ int getCCMPCondFlagsFromCondCode(CondCode CC);
// Get the opcode of corresponding NF variant.
unsigned getNFVariant(unsigned Opc);
+// Get the opcode of corresponding NonND variant.
+unsigned getNonNDVariant(unsigned Opc);
+
/// GetOppositeBranchCondition - Return the inverse of the specified cond,
/// e.g. turning COND_E to COND_NE.
CondCode GetOppositeBranchCondition(CondCode CC);
diff --git a/llvm/utils/TableGen/X86InstrMappingEmitter.cpp b/llvm/utils/TableGen/X86InstrMappingEmitter.cpp
index 5a2b669dbcd48..950ff1394b9fd 100644
--- a/llvm/utils/TableGen/X86InstrMappingEmitter.cpp
+++ b/llvm/utils/TableGen/X86InstrMappingEmitter.cpp
@@ -25,15 +25,6 @@ using namespace X86Disassembler;
namespace {
-const std::map<StringRef, StringRef> ManualMap = {
-#define ENTRY(OLD, NEW) {#OLD, #NEW},
-#include "X86ManualCompressEVEXTables.def"
-};
-const std::set<StringRef> NoCompressSet = {
-#define NOCOMP(INSN) #INSN,
-#include "X86ManualCompressEVEXTables.def"
-};
-
class X86InstrMappingEmitter {
RecordKeeper &Records;
CodeGenTarget Target;
@@ -176,6 +167,16 @@ static bool isInteresting(const Record *Rec) {
void X86InstrMappingEmitter::emitCompressEVEXTable(
ArrayRef<const CodeGenInstruction *> Insts, raw_ostream &OS) {
+
+ const std::map<StringRef, StringRef> ManualMap = {
+#define ENTRY(OLD, NEW) {#OLD, #NEW},
+#include "X86ManualInstrMapping.def"
+ };
+ const std::set<StringRef> NoCompressSet = {
+#define NOCOMP(INSN) #INSN,
+#include "X86ManualInstrMapping.def"
+ };
+
for (const CodeGenInstruction *Inst : Insts) {
const Record *Rec = Inst->TheDef;
StringRef Name = Rec->getName();
@@ -219,13 +220,10 @@ void X86InstrMappingEmitter::emitCompressEVEXTable(
} else if (Name.ends_with("_EVEX")) {
if (auto *NewRec = Records.getDef(Name.drop_back(5)))
NewInst = &Target.getInstruction(NewRec);
- } else if (Name.ends_with("_ND")) {
- if (auto *NewRec = Records.getDef(Name.drop_back(3))) {
- auto &TempInst = Target.getInstruction(NewRec);
- if (isRegisterOperand(TempInst.Operands[0].Rec))
- NewInst = &TempInst;
- }
- } else {
+ } else if (Name.ends_with("_ND"))
+ // Leave it to ND2NONND table.
+ continue;
+ else {
// For each pre-compression instruction look for a match in the
// appropriate vector (instructions with the same opcode) using function
// object IsMatch.
@@ -301,11 +299,31 @@ void X86InstrMappingEmitter::emitNFTransformTable(
void X86InstrMappingEmitter::emitND2NonNDTable(
ArrayRef<const CodeGenInstruction *> Insts, raw_ostream &OS) {
+
+ const std::map<StringRef, StringRef> ManualMap = {
+#define ENTRY_ND(OLD, NEW) {#OLD, #NEW},
+#include "X86ManualInstrMapping.def"
+ };
+ const std::set<StringRef> NoCompressSet = {
+#define NOCOMP_ND(INSN) #INSN,
+#include "X86ManualInstrMapping.def"
+ };
+
std::vector<Entry> Table;
for (const CodeGenInstruction *Inst : Insts) {
const Record *Rec = Inst->TheDef;
StringRef Name = Rec->getName();
- if (!isInteresting(Rec) || !Name.ends_with("_ND"))
+ if (!isInteresting(Rec) || NoCompressSet.find(Name) != NoCompressSet.end())
+ continue;
+ if (ManualMap.find(Name) != ManualMap.end()) {
+ auto *NewRec = Records.getDef(ManualMap.at(Rec->getName()));
+ assert(NewRec && "Instruction not found!");
+ auto &NewInst = Target.getInstruction(NewRec);
+ Table.push_back(std::pair(Inst, &NewInst));
+ continue;
+ }
+
+ if (!Name.ends_with("_ND"))
continue;
auto *NewRec = Records.getDef(Name.drop_back(3));
if (!NewRec)
diff --git a/llvm/utils/TableGen/X86ManualCompressEVEXTables.def b/llvm/utils/TableGen/X86ManualInstrMapping.def
similarity index 96%
rename from llvm/utils/TableGen/X86ManualCompressEVEXTables.def
rename to llvm/utils/TableGen/X86ManualInstrMapping.def
index cab601bf8131f..364f15607f73d 100644
--- a/llvm/utils/TableGen/X86ManualCompressEVEXTables.def
+++ b/llvm/utils/TableGen/X86ManualInstrMapping.def
@@ -48,14 +48,6 @@ NOCOMP(VPSRAQZ256ri)
NOCOMP(VPSRAQZ256rm)
NOCOMP(VPSRAQZ256rr)
NOCOMP(VSCALEFPSZ256rm)
-// When condition evaluates to false, the destination register is zeroed for
-// nonNDD CFCMOV but not for NDD CFCMOV.
-NOCOMP(CFCMOV16rm_ND)
-NOCOMP(CFCMOV16rr_ND)
-NOCOMP(CFCMOV32rm_ND)
-NOCOMP(CFCMOV32rr_ND)
-NOCOMP(CFCMOV64rm_ND)
-NOCOMP(CFCMOV64rr_ND)
#undef NOCOMP
#ifndef ENTRY
@@ -336,6 +328,24 @@ ENTRY(VBROADCASTSDZ256rm, VBROADCASTSDYrm)
ENTRY(VBROADCASTSDZ256rr, VBROADCASTSDYrr)
ENTRY(VPBROADCASTQZ256rm, VPBROADCASTQYrm)
ENTRY(VPBROADCASTQZ256rr, VPBROADCASTQYrr)
-ENTRY(MOVBE32rr, BSWAP32r)
-ENTRY(MOVBE64rr, BSWAP64r)
#undef ENTRY
+
+#ifndef NOCOMP_ND
+#define NOCOMP_ND(INSN)
+#endif
+// When condition evaluates to false, the destination register is zeroed for
+// nonNDD CFCMOV but not for NDD CFCMOV.
+NOCOMP_ND(CFCMOV16rm_ND)
+NOCOMP_ND(CFCMOV16rr_ND)
+NOCOMP_ND(CFCMOV32rm_ND)
+NOCOMP_ND(CFCMOV32rr_ND)
+NOCOMP_ND(CFCMOV64rm_ND)
+NOCOMP_ND(CFCMOV64rr_ND)
+#undef NOCOMP_ND
+
+#ifndef ENTRY_ND
+#define ENTRY_ND(OLD, NEW)
+#endif
+ENTRY_ND(MOVBE32rr, BSWAP32r)
+ENTRY_ND(MOVBE64rr, BSWAP64r)
+#undef ENTRY_ND
More information about the llvm-commits
mailing list