-
Notifications
You must be signed in to change notification settings - Fork 15.1k
X86: Switch to RegClassByHwMode #158274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/arsenm/codegen/targetinstrinfo-add-regclass-by-hwmode
Are you sure you want to change the base?
X86: Switch to RegClassByHwMode #158274
Conversation
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-llvm-mc Author: Matt Arsenault (arsenm) ChangesReplace the target uses of PointerLikeRegClass with RegClassByHwMode Full diff: https://github.com/llvm/llvm-project/pull/158274.diff 8 Files Affected:
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index bb1e716c33ed5..1d5ef8b0996dc 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -55,6 +55,9 @@ std::string X86_MC::ParseX86Triple(const Triple &TT) {
else
FS = "-64bit-mode,-32bit-mode,+16bit-mode";
+ if (TT.isX32())
+ FS += ",+x32";
+
return FS;
}
diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index 7c9e821c02fda..3af8b3e060a16 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -25,6 +25,8 @@ def Is32Bit : SubtargetFeature<"32bit-mode", "Is32Bit", "true",
"32-bit mode (80386)">;
def Is16Bit : SubtargetFeature<"16bit-mode", "Is16Bit", "true",
"16-bit mode (i8086)">;
+def IsX32 : SubtargetFeature<"x32", "IsX32", "true",
+ "64-bit with ILP32 programming model (e.g. x32 ABI)">;
//===----------------------------------------------------------------------===//
// X86 Subtarget ISA features
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index 7f6c5614847e3..0c4abc2c400f6 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -18,14 +18,14 @@ include "X86InstrFragments.td"
include "X86InstrFragmentsSIMD.td"
//===----------------------------------------------------------------------===//
-// X86 Operand Definitions.
+// X86 Predicate Definitions.
//
-include "X86InstrOperands.td"
+include "X86InstrPredicates.td"
//===----------------------------------------------------------------------===//
-// X86 Predicate Definitions.
+// X86 Operand Definitions.
//
-include "X86InstrPredicates.td"
+include "X86InstrOperands.td"
//===----------------------------------------------------------------------===//
// X86 Instruction Format Definitions.
diff --git a/llvm/lib/Target/X86/X86InstrOperands.td b/llvm/lib/Target/X86/X86InstrOperands.td
index 80843f6bb80e6..5207ecad127a2 100644
--- a/llvm/lib/Target/X86/X86InstrOperands.td
+++ b/llvm/lib/Target/X86/X86InstrOperands.td
@@ -6,9 +6,15 @@
//
//===----------------------------------------------------------------------===//
+def x86_ptr_rc : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32, GR64, LOW32_ADDR_ACCESS]>;
+
// A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
// the index operand of an address, to conform to x86 encoding restrictions.
-def ptr_rc_nosp : PointerLikeRegClass<1>;
+def ptr_rc_nosp : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32_NOSP, GR64_NOSP, GR32_NOSP]>;
// *mem - Operand definitions for the funky X86 addressing mode operands.
//
@@ -53,7 +59,7 @@ class X86MemOperand<string printMethod,
AsmOperandClass parserMatchClass = X86MemAsmOperand,
int size = 0> : Operand<iPTR> {
let PrintMethod = printMethod;
- let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
+ let MIOperandInfo = (ops x86_ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
let ParserMatchClass = parserMatchClass;
let OperandType = "OPERAND_MEMORY";
int Size = size;
@@ -63,7 +69,7 @@ class X86MemOperand<string printMethod,
class X86VMemOperand<RegisterClass RC, string printMethod,
AsmOperandClass parserMatchClass, int size = 0>
: X86MemOperand<printMethod, parserMatchClass, size> {
- let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
+ let MIOperandInfo = (ops x86_ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
}
def anymem : X86MemOperand<"printMemReference">;
@@ -113,8 +119,14 @@ def sdmem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>;
// A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
// of a plain GPR, so that it doesn't potentially require a REX prefix.
-def ptr_rc_norex : PointerLikeRegClass<2>;
-def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
+def ptr_rc_norex : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32_NOREX, GR64_NOREX, GR32_NOREX]>;
+
+def ptr_rc_norex_nosp : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32_NOREX_NOSP, GR64_NOREX_NOSP, GR32_NOREX_NOSP]>;
+
def i8mem_NOREX : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8> {
let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
@@ -123,7 +135,9 @@ def i8mem_NOREX : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8> {
// GPRs available for tailcall.
// It represents GR32_TC, GR64_TC or GR64_TCW64.
-def ptr_rc_tailcall : PointerLikeRegClass<4>;
+def ptr_rc_tailcall : RegClassByHwMode<
+ [X86_32, X86_64, X86_64_X32],
+ [GR32_TC, GR64_TC, GR64_TC]>;
// Special i32mem for addresses of load folding tail calls. These are not
// allowed to use callee-saved registers since they must be scheduled
@@ -270,12 +284,12 @@ let RenderMethod = "addMemOffsOperands" in {
class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
: X86MemOperand<printMethod, parserMatchClass> {
- let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
+ let MIOperandInfo = (ops x86_ptr_rc, SEGMENT_REG);
}
class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
: X86MemOperand<printMethod, parserMatchClass> {
- let MIOperandInfo = (ops ptr_rc);
+ let MIOperandInfo = (ops x86_ptr_rc);
}
def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
diff --git a/llvm/lib/Target/X86/X86InstrPredicates.td b/llvm/lib/Target/X86/X86InstrPredicates.td
index 8339c2081842d..c20bb05018b4d 100644
--- a/llvm/lib/Target/X86/X86InstrPredicates.td
+++ b/llvm/lib/Target/X86/X86InstrPredicates.td
@@ -195,6 +195,12 @@ def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
AssemblerPredicate<(all_of (not Is64Bit)), "Not 64-bit mode">;
def In64BitMode : Predicate<"Subtarget->is64Bit()">,
AssemblerPredicate<(all_of Is64Bit), "64-bit mode">;
+
+def IsX32Mode : Predicate<"Subtarget->getTargetTriple().isX32()">,
+ AssemblerPredicate<(all_of IsX32), "x32 ABI">;
+def NotX32Mode : Predicate<"!Subtarget->getTargetTriple().isX32()">,
+ AssemblerPredicate<(all_of (not IsX32)), "not x32 ABI">;
+
def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
def In16BitMode : Predicate<"Subtarget->is16Bit()">,
@@ -250,3 +256,11 @@ def HasMFence : Predicate<"Subtarget->hasMFence()">;
def HasFastDPWSSD: Predicate<"Subtarget->hasFastDPWSSD()">;
def UseIndirectThunkCalls : Predicate<"Subtarget->useIndirectThunkCalls()">;
def NotUseIndirectThunkCalls : Predicate<"!Subtarget->useIndirectThunkCalls()">;
+
+//===----------------------------------------------------------------------===//
+// HwModes
+//===----------------------------------------------------------------------===//
+
+defvar X86_32 = DefaultMode;
+def X86_64 : HwMode<[In64BitMode, NotX32Mode]>;
+def X86_64_X32 : HwMode<[IsX32Mode]>;
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index c47bb3e67e625..efccf5c72596e 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -194,33 +194,14 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
const TargetRegisterClass *
X86RegisterInfo::getPointerRegClass(unsigned Kind) const {
- switch (Kind) {
- default: llvm_unreachable("Unexpected Kind in getPointerRegClass!");
- case 0: // Normal GPRs.
- if (IsTarget64BitLP64)
- return &X86::GR64RegClass;
- // If the target is 64bit but we have been told to use 32bit addresses,
- // we can still use 64-bit register as long as we know the high bits
- // are zeros.
- // Reflect that in the returned register class.
- return Is64Bit ? &X86::LOW32_ADDR_ACCESSRegClass : &X86::GR32RegClass;
- case 1: // Normal GPRs except the stack pointer (for encoding reasons).
- if (IsTarget64BitLP64)
- return &X86::GR64_NOSPRegClass;
- // NOSP does not contain RIP, so no special case here.
- return &X86::GR32_NOSPRegClass;
- case 2: // NOREX GPRs.
- if (IsTarget64BitLP64)
- return &X86::GR64_NOREXRegClass;
- return &X86::GR32_NOREXRegClass;
- case 3: // NOREX GPRs except the stack pointer (for encoding reasons).
- if (IsTarget64BitLP64)
- return &X86::GR64_NOREX_NOSPRegClass;
- // NOSP does not contain RIP, so no special case here.
- return &X86::GR32_NOREX_NOSPRegClass;
- case 4: // Available for tailcall (not callee-saved GPRs).
- return Is64Bit ? &X86::GR64_TCRegClass : &X86::GR32_TCRegClass;
- }
+ assert(Kind == 0 && "this should only be used for default cases");
+ if (IsTarget64BitLP64)
+ return &X86::GR64RegClass;
+ // If the target is 64bit but we have been told to use 32bit addresses,
+ // we can still use 64-bit register as long as we know the high bits
+ // are zeros.
+ // Reflect that in the returned register class.
+ return Is64Bit ? &X86::LOW32_ADDR_ACCESSRegClass : &X86::GR32RegClass;
}
const TargetRegisterClass *
diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h
index fa3f3b59741df..a8802c4bf164d 100644
--- a/llvm/lib/Target/X86/X86Subtarget.h
+++ b/llvm/lib/Target/X86/X86Subtarget.h
@@ -170,10 +170,10 @@ class X86Subtarget final : public X86GenSubtargetInfo {
#include "X86GenSubtargetInfo.inc"
/// Is this x86_64 with the ILP32 programming model (x32 ABI)?
- bool isTarget64BitILP32() const { return Is64Bit && (TargetTriple.isX32()); }
+ bool isTarget64BitILP32() const { return Is64Bit && IsX32; }
/// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)?
- bool isTarget64BitLP64() const { return Is64Bit && (!TargetTriple.isX32()); }
+ bool isTarget64BitLP64() const { return Is64Bit && !IsX32; }
PICStyles::Style getPICStyle() const { return PICStyle; }
void setPICStyle(PICStyles::Style Style) { PICStyle = Style; }
diff --git a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
index b1f7b9a6b4ad9..1e1e4ab650030 100644
--- a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
@@ -553,10 +553,10 @@ void X86FoldTablesEmitter::updateTables(const CodeGenInstruction *RegInst,
for (unsigned I = RegOutSize, E = RegInst->Operands.size(); I < E; I++) {
const Record *RegOpRec = RegInst->Operands[I].Rec;
const Record *MemOpRec = MemInst->Operands[I].Rec;
- // PointerLikeRegClass: For instructions like TAILJMPr, TAILJMPr64,
+ // RegClassByHwMode: For instructions like TAILJMPr, TAILJMPr64,
// TAILJMPr64_REX
if ((isRegisterOperand(RegOpRec) ||
- RegOpRec->isSubClassOf("PointerLikeRegClass")) &&
+ (RegOpRec->isSubClassOf("RegClassByHwMode"))) &&
isMemoryOperand(MemOpRec)) {
switch (I) {
case 0:
|
ba508eb
to
b0954df
Compare
cbdfe4d
to
1a85c9c
Compare
b0954df
to
480926a
Compare
ca5e60c
to
f2baeeb
Compare
480926a
to
bdfdc33
Compare
Replace the target uses of PointerLikeRegClass with RegClassByHwMode
f2baeeb
to
1a834b6
Compare
Replace the target uses of PointerLikeRegClass with RegClassByHwMode