[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