[llvm] e620bea - [M68k] Allow user to preserve certain registers

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Thu May 20 13:58:25 PDT 2021


Author: Min-Yih Hsu
Date: 2021-05-20T13:57:22-07:00
New Revision: e620bea21199791513f3193a71b819b20a707ab1

URL: https://github.com/llvm/llvm-project/commit/e620bea21199791513f3193a71b819b20a707ab1
DIFF: https://github.com/llvm/llvm-project/commit/e620bea21199791513f3193a71b819b20a707ab1.diff

LOG: [M68k] Allow user to preserve certain registers

Add `-ffixed-a[0-6]` and `-ffixed-d[0-7]` and the corresponding
subtarget features to prevent certain register from being allocated.

Differential Revision: https://reviews.llvm.org/D102805

Added: 
    clang/test/Driver/m68k-fixed-register.c
    llvm/test/CodeGen/M68k/reserved-regs.ll

Modified: 
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/ToolChains/Arch/M68k.cpp
    llvm/lib/Target/M68k/M68k.td
    llvm/lib/Target/M68k/M68kRegisterInfo.cpp
    llvm/lib/Target/M68k/M68kSubtarget.cpp
    llvm/lib/Target/M68k/M68kSubtarget.h

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 1274f7a0af2e8..d45798c1d4043 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4010,6 +4010,13 @@ def m68030 : Flag<["-"], "m68030">, Group<m_m68k_Features_Group>;
 def m68040 : Flag<["-"], "m68040">, Group<m_m68k_Features_Group>;
 def m68060 : Flag<["-"], "m68060">, Group<m_m68k_Features_Group>;
 
+foreach i = {0-6} in
+  def ffixed_a#i : Flag<["-"], "ffixed-a"#i>, Group<m_m68k_Features_Group>,
+    HelpText<"Reserve the a"#i#" register (M68k only)">;
+foreach i = {0-7} in
+  def ffixed_d#i : Flag<["-"], "ffixed-d"#i>, Group<m_m68k_Features_Group>,
+    HelpText<"Reserve the d"#i#" register (M68k only)">;
+
 // X86 feature flags
 def mx87 : Flag<["-"], "mx87">, Group<m_x86_Features_Group>;
 def mno_x87 : Flag<["-"], "mno-x87">, Group<m_x86_Features_Group>;

diff  --git a/clang/lib/Driver/ToolChains/Arch/M68k.cpp b/clang/lib/Driver/ToolChains/Arch/M68k.cpp
index 66c9f5c87bfbc..119e24cedbab4 100644
--- a/clang/lib/Driver/ToolChains/Arch/M68k.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/M68k.cpp
@@ -72,6 +72,38 @@ void m68k::getM68kTargetFeatures(const Driver &D, const llvm::Triple &Triple,
   m68k::FloatABI FloatABI = m68k::getM68kFloatABI(D, Args);
   if (FloatABI == m68k::FloatABI::Soft)
     Features.push_back("-hard-float");
+
+  // Handle '-ffixed-<register>' flags
+  if (Args.hasArg(options::OPT_ffixed_a0))
+    Features.push_back("+reserve-a0");
+  if (Args.hasArg(options::OPT_ffixed_a1))
+    Features.push_back("+reserve-a1");
+  if (Args.hasArg(options::OPT_ffixed_a2))
+    Features.push_back("+reserve-a2");
+  if (Args.hasArg(options::OPT_ffixed_a3))
+    Features.push_back("+reserve-a3");
+  if (Args.hasArg(options::OPT_ffixed_a4))
+    Features.push_back("+reserve-a4");
+  if (Args.hasArg(options::OPT_ffixed_a5))
+    Features.push_back("+reserve-a5");
+  if (Args.hasArg(options::OPT_ffixed_a6))
+    Features.push_back("+reserve-a6");
+  if (Args.hasArg(options::OPT_ffixed_d0))
+    Features.push_back("+reserve-d0");
+  if (Args.hasArg(options::OPT_ffixed_d1))
+    Features.push_back("+reserve-d1");
+  if (Args.hasArg(options::OPT_ffixed_d2))
+    Features.push_back("+reserve-d2");
+  if (Args.hasArg(options::OPT_ffixed_d3))
+    Features.push_back("+reserve-d3");
+  if (Args.hasArg(options::OPT_ffixed_d4))
+    Features.push_back("+reserve-d4");
+  if (Args.hasArg(options::OPT_ffixed_d5))
+    Features.push_back("+reserve-d5");
+  if (Args.hasArg(options::OPT_ffixed_d6))
+    Features.push_back("+reserve-d6");
+  if (Args.hasArg(options::OPT_ffixed_d7))
+    Features.push_back("+reserve-d7");
 }
 
 m68k::FloatABI m68k::getM68kFloatABI(const Driver &D, const ArgList &Args) {

diff  --git a/clang/test/Driver/m68k-fixed-register.c b/clang/test/Driver/m68k-fixed-register.c
new file mode 100644
index 0000000000000..0ee9edcfd1647
--- /dev/null
+++ b/clang/test/Driver/m68k-fixed-register.c
@@ -0,0 +1,61 @@
+// REQUIRES: m68k-registered-target
+// RUN: %clang -target m68k -ffixed-a0 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-A0 < %t %s
+// CHECK-FIXED-A0: "-target-feature" "+reserve-a0"
+
+// RUN: %clang -target m68k -ffixed-a1 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-A1 < %t %s
+// CHECK-FIXED-A1: "-target-feature" "+reserve-a1"
+
+// RUN: %clang -target m68k -ffixed-a2 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-A2 < %t %s
+// CHECK-FIXED-A2: "-target-feature" "+reserve-a2"
+
+// RUN: %clang -target m68k -ffixed-a3 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-A3 < %t %s
+// CHECK-FIXED-A3: "-target-feature" "+reserve-a3"
+
+// RUN: %clang -target m68k -ffixed-a4 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-A4 < %t %s
+// CHECK-FIXED-A4: "-target-feature" "+reserve-a4"
+
+// RUN: %clang -target m68k -ffixed-a5 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-A5 < %t %s
+// CHECK-FIXED-A5: "-target-feature" "+reserve-a5"
+
+// RUN: %clang -target m68k -ffixed-a6 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-A6 < %t %s
+// CHECK-FIXED-A6: "-target-feature" "+reserve-a6"
+
+// RUN: %clang -target m68k -ffixed-d0 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-D0 < %t %s
+// CHECK-FIXED-D0: "-target-feature" "+reserve-d0"
+
+// RUN: %clang -target m68k -ffixed-d1 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-D1 < %t %s
+// CHECK-FIXED-D1: "-target-feature" "+reserve-d1"
+
+// RUN: %clang -target m68k -ffixed-d2 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-D2 < %t %s
+// CHECK-FIXED-D2: "-target-feature" "+reserve-d2"
+
+// RUN: %clang -target m68k -ffixed-d3 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-D3 < %t %s
+// CHECK-FIXED-D3: "-target-feature" "+reserve-d3"
+
+// RUN: %clang -target m68k -ffixed-d4 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-D4 < %t %s
+// CHECK-FIXED-D4: "-target-feature" "+reserve-d4"
+
+// RUN: %clang -target m68k -ffixed-d5 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-D5 < %t %s
+// CHECK-FIXED-D5: "-target-feature" "+reserve-d5"
+
+// RUN: %clang -target m68k -ffixed-d6 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-D6 < %t %s
+// CHECK-FIXED-D6: "-target-feature" "+reserve-d6"
+
+// RUN: %clang -target m68k -ffixed-d7 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-D7 < %t %s
+// CHECK-FIXED-D7: "-target-feature" "+reserve-d7"
+

diff  --git a/llvm/lib/Target/M68k/M68k.td b/llvm/lib/Target/M68k/M68k.td
index 85e3a01aaeafb..1493c6c98febf 100644
--- a/llvm/lib/Target/M68k/M68k.td
+++ b/llvm/lib/Target/M68k/M68k.td
@@ -47,6 +47,15 @@ def FeatureISA60
                      "Is M68060 ISA supported",
                      [ FeatureISA40 ]>;
 
+foreach i = {0-6} in
+  def FeatureReserveA#i :
+      SubtargetFeature<"reserve-a"#i, "UserReservedRegister[M68k::A"#i#"]",
+                       "true", "Reserve A"#i#" register">;
+foreach i = {0-7} in
+  def FeatureReserveD#i :
+      SubtargetFeature<"reserve-d"#i, "UserReservedRegister[M68k::D"#i#"]",
+                       "true", "Reserve D"#i#" register">;
+
 //===----------------------------------------------------------------------===//
 // M68k processors supported.
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/M68k/M68kRegisterInfo.cpp b/llvm/lib/Target/M68k/M68kRegisterInfo.cpp
index 288954aa0a14e..7d3f6a123bfa1 100644
--- a/llvm/lib/Target/M68k/M68kRegisterInfo.cpp
+++ b/llvm/lib/Target/M68k/M68kRegisterInfo.cpp
@@ -133,6 +133,12 @@ BitVector M68kRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
     }
   };
 
+  // Registers reserved by users
+  for (size_t Reg = 0, Total = getNumRegs(); Reg != Total; ++Reg) {
+    if (MF.getSubtarget<M68kSubtarget>().isRegisterReservedByUser(Reg))
+      setBitVector(Reg);
+  }
+
   setBitVector(M68k::PC);
   setBitVector(M68k::SP);
 

diff  --git a/llvm/lib/Target/M68k/M68kSubtarget.cpp b/llvm/lib/Target/M68k/M68kSubtarget.cpp
index 6886e1cf95a41..cd886bb1df3ae 100644
--- a/llvm/lib/Target/M68k/M68kSubtarget.cpp
+++ b/llvm/lib/Target/M68k/M68kSubtarget.cpp
@@ -47,7 +47,8 @@ void M68kSubtarget::anchor() {}
 
 M68kSubtarget::M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
                              const M68kTargetMachine &TM)
-    : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TM(TM), TSInfo(),
+    : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
+      UserReservedRegister(M68k::NUM_TARGET_REGS), TM(TM), TSInfo(),
       InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
       FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
       TargetTriple(TT) {}

diff  --git a/llvm/lib/Target/M68k/M68kSubtarget.h b/llvm/lib/Target/M68k/M68kSubtarget.h
index 631b27e1698f5..c46945f3b5d1b 100644
--- a/llvm/lib/Target/M68k/M68kSubtarget.h
+++ b/llvm/lib/Target/M68k/M68kSubtarget.h
@@ -18,6 +18,7 @@
 #include "M68kISelLowering.h"
 #include "M68kInstrInfo.h"
 
+#include "llvm/ADT/BitVector.h"
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DataLayout.h"
@@ -47,6 +48,8 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
   enum SubtargetEnum { M00, M10, M20, M30, M40, M60 };
   SubtargetEnum SubtargetKind = M00;
 
+  BitVector UserReservedRegister;
+
   InstrItineraryData InstrItins;
 
   /// Small section is used.
@@ -95,6 +98,11 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
 
   bool isPositionIndependent() const;
 
+  bool isRegisterReservedByUser(Register R) const {
+    assert(R < M68k::NUM_TARGET_REGS && "Register out of range");
+    return UserReservedRegister[R];
+  }
+
   /// Classify a global variable reference for the current subtarget according
   /// to how we should reference it in a non-pcrel context.
   unsigned char classifyLocalReference(const GlobalValue *GV) const;

diff  --git a/llvm/test/CodeGen/M68k/reserved-regs.ll b/llvm/test/CodeGen/M68k/reserved-regs.ll
new file mode 100644
index 0000000000000..04acaf6797925
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/reserved-regs.ll
@@ -0,0 +1,70 @@
+; RUN: llc -mtriple=m68k -mattr="+reserve-a0" < %s | FileCheck --check-prefix=A0 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-a1" < %s | FileCheck --check-prefix=A1 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-a2" < %s | FileCheck --check-prefix=A2 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-a3" < %s | FileCheck --check-prefix=A3 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-a4" < %s | FileCheck --check-prefix=A4 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-a5" < %s | FileCheck --check-prefix=A5 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-a6" < %s | FileCheck --check-prefix=A6 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-d0" < %s | FileCheck --check-prefix=D0 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-d1" < %s | FileCheck --check-prefix=D1 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-d2" < %s | FileCheck --check-prefix=D2 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-d3" < %s | FileCheck --check-prefix=D3 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-d4" < %s | FileCheck --check-prefix=D4 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-d5" < %s | FileCheck --check-prefix=D5 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-d6" < %s | FileCheck --check-prefix=D6 %s
+; RUN: llc -mtriple=m68k -mattr="+reserve-d7" < %s | FileCheck --check-prefix=D7 %s
+
+; Used to exhaust all registers
+;
+; A better way to do this might be:
+; ```
+; @var = global [16 x i32] zeroinitializer
+; ...
+; %tmp = load load volatile [16 x i32], [16 x i32]* @var
+; store volatile [16 x i32] %tmp, [16 x i32]* @var
+; ```
+; Which is copied from `test/CodeGen/RISCV/reserved-regs.ll`.
+; But currently we have problem doing codegen for the above snippet
+; (https://bugs.llvm.org/show_bug.cgi?id=50377).
+define void @foo(i32* nocapture readonly %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32* nocapture readonly %d,
+                 i32* nocapture readonly %a1, i32* nocapture readonly %b1, i32* nocapture readonly %c1, i32* nocapture readonly %d1,
+                 i32* nocapture readonly %a2, i32* nocapture readonly %b2, i32* nocapture readonly %c2, i32* nocapture readonly %d2,
+                 i32* nocapture readonly %a3, i32* nocapture readonly %b3, i32* nocapture readonly %c3, i32* nocapture readonly %d3) {
+entry:
+  %0 = load i32, i32* %a, align 4
+  %1 = load i32, i32* %b, align 4
+  %2 = load i32, i32* %c, align 4
+  %3 = load i32, i32* %d, align 4
+  %4 = load i32, i32* %a1, align 4
+  %5 = load i32, i32* %b1, align 4
+  %6 = load i32, i32* %c1, align 4
+  %7 = load i32, i32* %d1, align 4
+  %8 = load i32, i32* %a2, align 4
+  %9 = load i32, i32* %b2, align 4
+  %10 = load i32, i32* %c2, align 4
+  %11 = load i32, i32* %d2, align 4
+  %12 = load i32, i32* %a3, align 4
+  %13 = load i32, i32* %b3, align 4
+  %14 = load i32, i32* %c3, align 4
+  %15 = load i32, i32* %d3, align 4
+  ; A0-NOT: %a0
+  ; A1-NOT: %a1
+  ; A2-NOT: %a2
+  ; A3-NOT: %a3
+  ; A4-NOT: %a4
+  ; A5-NOT: %a5
+  ; A6-NOT: %a6
+  ; D0-NOT: %d0
+  ; D1-NOT: %d1
+  ; D2-NOT: %d2
+  ; D3-NOT: %d3
+  ; D4-NOT: %d4
+  ; D5-NOT: %d5
+  ; D6-NOT: %d6
+  ; D7-NOT: %d7
+  tail call void @bar(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, i32 %8, i32 %9, i32 %10, i32 %11, i32 %12, i32 %13, i32 %14, i32 %15)
+  ret void
+}
+
+declare void @bar(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32)
+


        


More information about the llvm-commits mailing list