forked from OSchip/llvm-project
[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
This commit is contained in:
parent
b00bce2a93
commit
dd88f40c80
|
@ -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;
|
||||
|
|
|
@ -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<[]>;
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue