[llvm] dd88f40 - [AArch64] Make getInstSizeInBytes() use instruction size from InstrInfo.td
via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 1 02:39:48 PST 2022
Author: tyb0807
Date: 2022-02-01T10:39:14Z
New Revision: dd88f40c80f54e5f66b5ead1787f88c376b61d8a
URL: https://github.com/llvm/llvm-project/commit/dd88f40c80f54e5f66b5ead1787f88c376b61d8a
DIFF: https://github.com/llvm/llvm-project/commit/dd88f40c80f54e5f66b5ead1787f88c376b61d8a.diff
LOG: [AArch64] Make getInstSizeInBytes() use instruction size from InstrInfo.td
Currently, AArch64InstrInfo::getInstSizeInBytes() uses hard-coded
instruction size for some pseudo-instructions, while this
information should ideally be found in AArch64InstrInfo.td file (which
can be accessed via MCInstrDesc). Hence, the .td file should be updated
and no hard-coded instruction sizes should be used by
getInstSizeInBytes() anymore.
Differential Revision: https://reviews.llvm.org/D117970
Added:
Modified:
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/unittests/Target/AArch64/InstSizes.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index c3ccc541c0b8a..a9191924129c6 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -93,9 +93,18 @@ unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
// before the assembly printer.
unsigned NumBytes = 0;
const MCInstrDesc &Desc = MI.getDesc();
+
+ // Size should be preferably set in
+ // llvm/lib/Target/AArch64/AArch64InstrInfo.td (default case).
+ // Specific cases handle instructions of variable sizes
switch (Desc.getOpcode()) {
default:
- // Anything not explicitly designated otherwise is a normal 4-byte insn.
+ if (Desc.getSize())
+ return Desc.getSize();
+
+ // Anything not explicitly designated otherwise (i.e. pseudo-instructions
+ // with fixed constant size but not specified in .td file) is a normal
+ // 4-byte insn.
NumBytes = 4;
break;
case TargetOpcode::STACKMAP:
@@ -115,33 +124,9 @@ unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
if (NumBytes == 0)
NumBytes = 4;
break;
- case AArch64::TLSDESC_CALLSEQ:
- // This gets lowered to an instruction sequence which takes 16 bytes
- NumBytes = 16;
- break;
- case AArch64::SpeculationBarrierISBDSBEndBB:
- // This gets lowered to 2 4-byte instructions.
- NumBytes = 8;
- break;
- case AArch64::SpeculationBarrierSBEndBB:
- // This gets lowered to 1 4-byte instructions.
- NumBytes = 4;
- break;
- case AArch64::JumpTableDest32:
- case AArch64::JumpTableDest16:
- case AArch64::JumpTableDest8:
- case AArch64::MOPSMemoryCopyPseudo:
- case AArch64::MOPSMemoryMovePseudo:
- case AArch64::MOPSMemorySetPseudo:
- case AArch64::MOPSMemorySetTaggingPseudo:
- NumBytes = 12;
- break;
case AArch64::SPACE:
NumBytes = MI.getOperand(1).getImm();
break;
- case AArch64::StoreSwiftAsyncContext:
- NumBytes = 20;
- break;
case TargetOpcode::BUNDLE:
NumBytes = getInstBundleLength(MI);
break;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index daceb3feffa3c..83bf89ff97c50 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -780,6 +780,7 @@ def : Pat<(AArch64LOADgot texternalsym:$addr),
def : Pat<(AArch64LOADgot tconstpool:$addr),
(LOADgot tconstpool:$addr)>;
+// In general these get lowered into a sequence of three 4-byte instructions.
// 32-bit jump table destination is actually only 2 instructions since we can
// use the table itself as a PC-relative base. But optimization occurs after
// branch relaxation so be pessimistic.
@@ -815,8 +816,12 @@ let hasSideEffects = 1, isCodeGenOnly = 1 in {
// SpeculationBarrierEndBB must only be used after an unconditional control
// flow, i.e. after a terminator for which isBarrier is True.
let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
+ // This gets lowered to a pair of 4-byte instructions.
+ let Size = 8 in
def SpeculationBarrierISBDSBEndBB
: Pseudo<(outs), (ins), []>, Sched<[]>;
+ // This gets lowered to a 4-byte instruction.
+ let Size = 4 in
def SpeculationBarrierSBEndBB
: Pseudo<(outs), (ins), []>, Sched<[]>;
}
@@ -2356,7 +2361,8 @@ def EMITBKEY : Pseudo<(outs), (ins), []>, Sched<[]> {}
// FIXME: maybe the scratch register used shouldn't be fixed to X1?
// FIXME: can "hasSideEffects be dropped?
-let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1,
+// This gets lowered to an instruction sequence which takes 16 bytes
+let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1, Size = 16,
isCodeGenOnly = 1 in
def TLSDESC_CALLSEQ
: Pseudo<(outs), (ins i64imm:$sym),
@@ -8370,6 +8376,7 @@ def AArch64mops_memset_tagging : SDNode<"AArch64ISD::MOPS_MEMSET_TAGGING", SDT_A
def AArch64mops_memcopy : SDNode<"AArch64ISD::MOPS_MEMCOPY", SDT_AArch64mops>;
def AArch64mops_memmove : SDNode<"AArch64ISD::MOPS_MEMMOVE", SDT_AArch64mops>;
+// MOPS operations always contain three 4-byte instructions
let Predicates = [HasMOPS], Defs = [NZCV], Size = 12, mayStore = 1 in {
let mayLoad = 1 in {
def MOPSMemoryCopyPseudo : Pseudo<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb),
@@ -8391,7 +8398,8 @@ let Predicates = [HasMOPS, HasMTE], Defs = [NZCV], Size = 12, mayLoad = 0, maySt
[], "$Rd = $Rd_wb,$Rn = $Rn_wb">, Sched<[]>;
}
-let Defs = [X16, X17], mayStore = 1, isCodeGenOnly = 1 in
+// This gets lowered into an instruction sequence of 20 bytes
+let Defs = [X16, X17], mayStore = 1, isCodeGenOnly = 1, Size = 20 in
def StoreSwiftAsyncContext
: Pseudo<(outs), (ins GPR64:$ctx, GPR64sp:$base, simm9:$offset),
[]>, Sched<[]>;
diff --git a/llvm/unittests/Target/AArch64/InstSizes.cpp b/llvm/unittests/Target/AArch64/InstSizes.cpp
index 540e248bad6e3..f17290c73ee59 100644
--- a/llvm/unittests/Target/AArch64/InstSizes.cpp
+++ b/llvm/unittests/Target/AArch64/InstSizes.cpp
@@ -52,6 +52,11 @@ void runChecks(
"...\n"
"---\n"
"name: sizes\n"
+ "jumpTable:\n"
+ " kind: block-address\n"
+ " entries:\n"
+ " - id: 0\n"
+ " blocks: [ '%bb.0' ]\n"
"body: |\n"
" bb.0:\n"
+ InputMIRSnippet.str();
@@ -142,6 +147,34 @@ TEST(InstSizes, PATCHPOINT) {
});
}
+TEST(InstSizes, STATEPOINT) {
+ std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
+ std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
+
+ runChecks(TM.get(), II.get(), "",
+ " STATEPOINT 0, 0, 0, @sizes, 2, 0, 2, 0, 2, 0, 2, 1, 1, 8,"
+ " $sp, 24, 2, 0, 2, 1, 0, 0\n",
+ [](AArch64InstrInfo &II, MachineFunction &MF) {
+ auto I = MF.begin()->begin();
+ EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
+ });
+}
+
+TEST(InstSizes, SPACE) {
+ std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
+ std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
+
+ runChecks(TM.get(), II.get(), "",
+ " $xzr = SPACE 1024, undef $xzr\n"
+ " dead $xzr = SPACE 4096, $xzr\n",
+ [](AArch64InstrInfo &II, MachineFunction &MF) {
+ auto I = MF.begin()->begin();
+ EXPECT_EQ(1024u, II.getInstSizeInBytes(*I));
+ ++I;
+ EXPECT_EQ(4096u, II.getInstSizeInBytes(*I));
+ });
+}
+
TEST(InstSizes, TLSDESC_CALLSEQ) {
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
@@ -156,16 +189,87 @@ TEST(InstSizes, TLSDESC_CALLSEQ) {
});
}
-TEST(InstSizes, MOPSMemorySetTaggingPseudo) {
+TEST(InstSizes, StoreSwiftAsyncContext) {
+ std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
+ std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
+
+ runChecks(
+ TM.get(), II.get(), "",
+ " StoreSwiftAsyncContext $x0, $x1, 12, implicit-def $x16, "
+ "implicit-def $x17\n",
+ [](AArch64InstrInfo &II, MachineFunction &MF) {
+ auto I = MF.begin()->begin();
+ EXPECT_EQ(20u, II.getInstSizeInBytes(*I));
+ });
+}
+
+TEST(InstSizes, SpeculationBarrierISBDSBEndBB) {
+ std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
+ std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
+
+ runChecks(
+ TM.get(), II.get(), "",
+ " SpeculationBarrierISBDSBEndBB\n"
+ " BR $x8\n",
+ [](AArch64InstrInfo &II, MachineFunction &MF) {
+ auto I = MF.begin()->begin();
+ EXPECT_EQ(8u, II.getInstSizeInBytes(*I));
+ });
+}
+
+TEST(InstSizes, SpeculationBarrierSBEndBB) {
+ std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
+ std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
+
+ runChecks(
+ TM.get(), II.get(), "",
+ " SpeculationBarrierSBEndBB\n"
+ " BR $x8\n",
+ [](AArch64InstrInfo &II, MachineFunction &MF) {
+ auto I = MF.begin()->begin();
+ EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
+ });
+}
+
+TEST(InstSizes, JumpTable) {
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
runChecks(TM.get(), II.get(), "",
- " renamable $x0, dead renamable $x1 = MOPSMemorySetTaggingPseudo "
- "killed renamable $x0, killed renamable $x1, killed renamable $x2, "
- "implicit-def dead $nzcv\n",
+ " $x10, $x11 = JumpTableDest32 $x9, $x8, %jump-table.0\n"
+ " $x10, $x11 = JumpTableDest16 $x9, $x8, %jump-table.0\n"
+ " $x10, $x11 = JumpTableDest8 $x9, $x8, %jump-table.0\n",
[](AArch64InstrInfo &II, MachineFunction &MF) {
auto I = MF.begin()->begin();
EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
+ ++I;
+ EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
+ ++I;
+ EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
+ });
+}
+
+TEST(InstSizes, MOPSMemoryPseudos) {
+ std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
+ std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
+
+ runChecks(TM.get(), II.get(), "",
+ " $x0, $x1, $x2 = MOPSMemoryMovePseudo $x0, $x1, $x2, "
+ "implicit-def $nzcv\n"
+ " $x0, $x1 = MOPSMemorySetPseudo $x0, $x1, $x2, "
+ "implicit-def $nzcv\n"
+ " $x0, $x1, $x8 = MOPSMemoryCopyPseudo $x0, $x1, $x8, "
+ "implicit-def $nzcv\n"
+ " $x0, $x1 = MOPSMemorySetTaggingPseudo $x0, $x1, $x2, "
+ "implicit-def $nzcv\n",
+ [](AArch64InstrInfo &II, MachineFunction &MF) {
+ auto I = MF.begin()->begin();
+ EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
+ ++I;
+ EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
+ ++I;
+ EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
+ ++I;
+ EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
});
}
More information about the llvm-commits
mailing list