[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