[llvm] 211f1d2 - [X86][mem-fold] Refine the code in X86FoldTablesEmitter.cpp, NFCI
Shengchen Kan via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 5 21:11:13 PDT 2023
Author: Shengchen Kan
Date: 2023-04-06T12:10:45+08:00
New Revision: 211f1d2bb8b753f7068d17b3939d1c59b60e838c
URL: https://github.com/llvm/llvm-project/commit/211f1d2bb8b753f7068d17b3939d1c59b60e838c
DIFF: https://github.com/llvm/llvm-project/commit/211f1d2bb8b753f7068d17b3939d1c59b60e838c.diff
LOG: [X86][mem-fold] Refine the code in X86FoldTablesEmitter.cpp, NFCI
1. Avoid vulnerable assumption: the enum of reg/memory format are continous
2. Remove redundant inline keyword
3. Replace getValueFromBitsInit with byteFromBitsInit b/c both Form and
Opcode can be represented in 1 byte
Added:
Modified:
llvm/utils/TableGen/X86FoldTablesEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
index d5338564eaf61..84d292c4c9029 100644
--- a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
@@ -186,37 +186,86 @@ static bool hasPtrTailcallRegClass(const CodeGenInstruction *Inst) {
});
}
-// Calculates the integer value representing the BitsInit object
-static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
- assert(B->getNumBits() <= sizeof(uint64_t) * 8 && "BitInits' too long!");
-
- uint64_t Value = 0;
- for (unsigned i = 0, e = B->getNumBits(); i != e; ++i) {
- BitInit *Bit = cast<BitInit>(B->getBit(i));
- Value |= uint64_t(Bit->getValue()) << i;
+static uint8_t byteFromBitsInit(const BitsInit *B) {
+ unsigned N = B->getNumBits();
+ assert(N <= 8 && "Field is too large for uint8_t!");
+
+ uint8_t Value = 0;
+ for (unsigned I = 0; I != N; ++I) {
+ BitInit *Bit = cast<BitInit>(B->getBit(I));
+ Value |= Bit->getValue() << I;
}
return Value;
}
-// Return true if the instruction defined as a register flavor.
-static inline bool hasRegisterFormat(const Record *Inst) {
- const BitsInit *FormBits = Inst->getValueAsBitsInit("FormBits");
- uint64_t FormBitsNum = getValueFromBitsInit(FormBits);
-
- // Values from X86Local namespace defined in X86RecognizableInstr.cpp
- return FormBitsNum >= X86Local::MRMDestReg && FormBitsNum <= X86Local::MRM7r;
+static bool mayFoldFromForm(uint8_t Form) {
+ switch (Form) {
+ default:
+ return Form >= X86Local::MRM0r && Form <= X86Local::MRM7r;
+ case X86Local::MRMXr:
+ case X86Local::MRMXrCC:
+ case X86Local::MRMDestReg:
+ case X86Local::MRMSrcReg:
+ case X86Local::MRMSrcReg4VOp3:
+ case X86Local::MRMSrcRegOp4:
+ case X86Local::MRMSrcRegCC:
+ return true;
+ }
}
-// Return true if the instruction defined as a memory flavor.
-static inline bool hasMemoryFormat(const Record *Inst) {
- const BitsInit *FormBits = Inst->getValueAsBitsInit("FormBits");
- uint64_t FormBitsNum = getValueFromBitsInit(FormBits);
+static bool mayFoldToForm(uint8_t Form) {
+ switch (Form) {
+ default:
+ return Form >= X86Local::MRM0m && Form <= X86Local::MRM7m;
+ case X86Local::MRMXm:
+ case X86Local::MRMXmCC:
+ case X86Local::MRMDestMem:
+ case X86Local::MRMSrcMem:
+ case X86Local::MRMSrcMem4VOp3:
+ case X86Local::MRMSrcMemOp4:
+ case X86Local::MRMSrcMemCC:
+ return true;
+ }
+}
- // Values from X86Local namespace defined in X86RecognizableInstr.cpp
- return FormBitsNum >= X86Local::MRMDestMem && FormBitsNum <= X86Local::MRM7m;
+static bool mayFoldFromLeftToRight(uint8_t LHS, uint8_t RHS) {
+ switch (LHS) {
+ default:
+ llvm_unreachable("Unexpected Form!");
+ case X86Local::MRM0r:
+ return RHS == X86Local::MRM0m;
+ case X86Local::MRM1r:
+ return RHS == X86Local::MRM1m;
+ case X86Local::MRM2r:
+ return RHS == X86Local::MRM2m;
+ case X86Local::MRM3r:
+ return RHS == X86Local::MRM3m;
+ case X86Local::MRM4r:
+ return RHS == X86Local::MRM4m;
+ case X86Local::MRM5r:
+ return RHS == X86Local::MRM5m;
+ case X86Local::MRM6r:
+ return RHS == X86Local::MRM6m;
+ case X86Local::MRM7r:
+ return RHS == X86Local::MRM7m;
+ case X86Local::MRMXr:
+ return RHS == X86Local::MRMXm;
+ case X86Local::MRMXrCC:
+ return RHS == X86Local::MRMXmCC;
+ case X86Local::MRMDestReg:
+ return RHS == X86Local::MRMDestMem;
+ case X86Local::MRMSrcReg:
+ return RHS == X86Local::MRMSrcMem;
+ case X86Local::MRMSrcReg4VOp3:
+ return RHS == X86Local::MRMSrcMem4VOp3;
+ case X86Local::MRMSrcRegOp4:
+ return RHS == X86Local::MRMSrcMemOp4;
+ case X86Local::MRMSrcRegCC:
+ return RHS == X86Local::MRMSrcMemCC;
+ }
}
-static inline bool isNOREXRegClass(const Record *Op) {
+static bool isNOREXRegClass(const Record *Op) {
return Op->getName().contains("_NOREX");
}
@@ -240,9 +289,7 @@ class IsMatch {
if (RegRI.HasEVEX_B != 0 || MemRI.HasEVEX_B != 0)
return false;
- // Instruction's format - The register form's "Form" field should be
- // the opposite of the memory form's "Form" field.
- if (!areOppositeForms(RegRI.Form, MemRI.Form))
+ if (!mayFoldFromLeftToRight(RegRI.Form, MemRI.Form))
return false;
// X86 encoding is crazy, e.g
@@ -325,31 +372,6 @@ class IsMatch {
return true;
}
-
-private:
- // Return true of the 2 given forms are the opposite of each other.
- bool areOppositeForms(unsigned RegForm, unsigned MemForm) {
- if ((MemForm == X86Local::MRM0m && RegForm == X86Local::MRM0r) ||
- (MemForm == X86Local::MRM1m && RegForm == X86Local::MRM1r) ||
- (MemForm == X86Local::MRM2m && RegForm == X86Local::MRM2r) ||
- (MemForm == X86Local::MRM3m && RegForm == X86Local::MRM3r) ||
- (MemForm == X86Local::MRM4m && RegForm == X86Local::MRM4r) ||
- (MemForm == X86Local::MRM5m && RegForm == X86Local::MRM5r) ||
- (MemForm == X86Local::MRM6m && RegForm == X86Local::MRM6r) ||
- (MemForm == X86Local::MRM7m && RegForm == X86Local::MRM7r) ||
- (MemForm == X86Local::MRMXm && RegForm == X86Local::MRMXr) ||
- (MemForm == X86Local::MRMXmCC && RegForm == X86Local::MRMXrCC) ||
- (MemForm == X86Local::MRMDestMem && RegForm == X86Local::MRMDestReg) ||
- (MemForm == X86Local::MRMSrcMem && RegForm == X86Local::MRMSrcReg) ||
- (MemForm == X86Local::MRMSrcMem4VOp3 &&
- RegForm == X86Local::MRMSrcReg4VOp3) ||
- (MemForm == X86Local::MRMSrcMemOp4 &&
- RegForm == X86Local::MRMSrcRegOp4) ||
- (MemForm == X86Local::MRMSrcMemCC && RegForm == X86Local::MRMSrcRegCC))
- return true;
-
- return false;
- }
};
} // end anonymous namespace
@@ -420,21 +442,18 @@ void X86FoldTablesEmitter::addEntryWithFlags(FoldTable &Table,
} else if (RegInstr->isMoveReg && Result.IsStore)
Result.CannotUnfold = true;
- uint64_t Enc = getValueFromBitsInit(RegRec->getValueAsBitsInit("OpEncBits"));
+ uint8_t Enc = byteFromBitsInit(RegRec->getValueAsBitsInit("OpEncBits"));
if (isExplicitAlign(RegInstr)) {
// The instruction require explicitly aligned memory.
BitsInit *VectSize = RegRec->getValueAsBitsInit("VectSize");
- uint64_t Value = getValueFromBitsInit(VectSize);
Result.IsAligned = true;
- Result.Alignment = Value;
- } else if (Enc != X86Local::XOP && Enc != X86Local::VEX &&
- Enc != X86Local::EVEX) {
- // Instructions with VEX encoding do not require alignment.
- if (!isExplicitUnalign(RegInstr) && getMemOperandSize(MemOpRec) > 64) {
- // SSE packed vector instructions require a 16 byte alignment.
- Result.IsAligned = true;
- Result.Alignment = 16;
- }
+ Result.Alignment = byteFromBitsInit(VectSize);
+ } else if (!Enc && !isExplicitUnalign(RegInstr) &&
+ getMemOperandSize(MemOpRec) > 64) {
+ // Instructions with XOP/VEX/EVEX encoding do not require alignment while
+ // SSE packed vector instructions require a 16 byte alignment.
+ Result.IsAligned = true;
+ Result.Alignment = 16;
}
// Expand is only ever created as a masked instruction. It is not safe to
// unfold a masked expand because we don't know if it came from an expand load
@@ -539,12 +558,14 @@ void X86FoldTablesEmitter::run(raw_ostream &o) {
continue;
// Add all the memory form instructions to MemInsts, and all the register
- // form instructions to RegInsts[Opc], where Opc in the opcode of each
+ // form instructions to RegInsts[Opc], where Opc is the opcode of each
// instructions. this helps reducing the runtime of the backend.
- if (hasMemoryFormat(Rec))
+ const BitsInit *FormBits = Rec->getValueAsBitsInit("FormBits");
+ uint8_t Form = byteFromBitsInit(FormBits);
+ if (mayFoldToForm(Form))
MemInsts.push_back(Inst);
- else if (hasRegisterFormat(Rec)) {
- uint8_t Opc = getValueFromBitsInit(Rec->getValueAsBitsInit("Opcode"));
+ else if (mayFoldFromForm(Form)) {
+ uint8_t Opc = byteFromBitsInit(Rec->getValueAsBitsInit("Opcode"));
RegInsts[Opc].push_back(Inst);
}
}
@@ -555,7 +576,7 @@ void X86FoldTablesEmitter::run(raw_ostream &o) {
// instruction.
for (const CodeGenInstruction *MemInst : MemInsts) {
uint8_t Opc =
- getValueFromBitsInit(MemInst->TheDef->getValueAsBitsInit("Opcode"));
+ byteFromBitsInit(MemInst->TheDef->getValueAsBitsInit("Opcode"));
auto RegInstsIt = RegInsts.find(Opc);
if (RegInstsIt == RegInsts.end())
More information about the llvm-commits
mailing list