[llvm] r272170 - [AArch64][RegisterBankInfo] G_OR are fine on either GPR or FPR.

Quentin Colombet via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 8 09:53:32 PDT 2016


Author: qcolombet
Date: Wed Jun  8 11:53:32 2016
New Revision: 272170

URL: http://llvm.org/viewvc/llvm-project?rev=272170&view=rev
Log:
[AArch64][RegisterBankInfo] G_OR are fine on either GPR or FPR.

Teach AArch64RegisterBankInfo that G_OR can be mapped on either GPR or
FPR for 64-bit or 32-bit values.

Add test cases demonstrating how this information is used to coalesce a
computation on a single register bank.

Modified:
    llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
    llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir

Modified: llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp?rev=272170&r1=272169&r2=272170&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp Wed Jun  8 11:53:32 2016
@@ -17,6 +17,7 @@
 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
 #include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
 
 using namespace llvm;
 
@@ -111,3 +112,57 @@ const RegisterBank &AArch64RegisterBankI
     llvm_unreachable("Register class not supported");
   }
 }
+
+RegisterBankInfo::InstructionMappings
+AArch64RegisterBankInfo::getInstrAlternativeMappings(
+    const MachineInstr &MI) const {
+  switch (MI.getOpcode()) {
+  case TargetOpcode::G_OR: {
+    // 32 and 64-bit or can be mapped on either FPR or
+    // GPR for the same cost.
+    const MachineFunction &MF = *MI.getParent()->getParent();
+    const TargetSubtargetInfo &STI = MF.getSubtarget();
+    const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
+    const MachineRegisterInfo &MRI = MF.getRegInfo();
+
+    unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
+    if (Size != 32 && Size != 64)
+      break;
+
+    // If the instruction has any implicit-defs or uses,
+    // do not mess with it.
+    if (MI.getNumOperands() != 3)
+      break;
+    InstructionMappings AltMappings;
+    InstructionMapping GPRMapping(/*ID*/ 1, /*Cost*/ 1, /*NumOperands*/ 3);
+    InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1, /*NumOperands*/ 3);
+    for (unsigned Idx = 0; Idx != 3; ++Idx) {
+      GPRMapping.setOperandMapping(Idx, Size,
+                                   getRegBank(AArch64::GPRRegBankID));
+      FPRMapping.setOperandMapping(Idx, Size,
+                                   getRegBank(AArch64::FPRRegBankID));
+    }
+    AltMappings.emplace_back(std::move(GPRMapping));
+    AltMappings.emplace_back(std::move(FPRMapping));
+    return AltMappings;
+  }
+  default:
+    break;
+  }
+  return RegisterBankInfo::getInstrAlternativeMappings(MI);
+}
+
+void AArch64RegisterBankInfo::applyMappingImpl(
+    const OperandsMapper &OpdMapper) const {
+  switch (OpdMapper.getMI().getOpcode()) {
+  case TargetOpcode::G_OR: {
+    // Those ID must match getInstrAlternativeMappings.
+    assert((OpdMapper.getInstrMapping().getID() == 1 ||
+            OpdMapper.getInstrMapping().getID() == 2) &&
+           "Don't know how to handle that ID");
+    return applyDefaultMapping(OpdMapper);
+  }
+  default:
+    llvm_unreachable("Don't know how to handle that operation");
+  }
+}

Modified: llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h?rev=272170&r1=272169&r2=272170&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.h Wed Jun  8 11:53:32 2016
@@ -31,6 +31,9 @@ enum {
 
 /// This class provides the information for the target register banks.
 class AArch64RegisterBankInfo : public RegisterBankInfo {
+  /// See RegisterBankInfo::applyMapping.
+  void applyMappingImpl(const OperandsMapper &OpdMapper) const override;
+
 public:
   AArch64RegisterBankInfo(const TargetRegisterInfo &TRI);
   /// Get the cost of a copy from \p B to \p A, or put differently,
@@ -56,6 +59,11 @@ public:
   /// \todo This should be TableGen'ed.
   const RegisterBank &
   getRegBankFromRegClass(const TargetRegisterClass &RC) const override;
+
+  /// Get the alternative mappings for \p MI.
+  /// Alternative in the sense different from getInstrMapping.
+  InstructionMappings
+  getInstrAlternativeMappings(const MachineInstr &MI) const override;
 };
 } // End llvm namespace.
 #endif

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir?rev=272170&r1=272169&r2=272170&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-regbankselect.mir Wed Jun  8 11:53:32 2016
@@ -1,4 +1,5 @@
-# RUN: llc -O0 -run-pass=regbankselect -global-isel %s -o - 2>&1 | FileCheck %s
+# RUN: llc -O0 -run-pass=regbankselect -global-isel %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
+# RUN: llc -O0 -run-pass=regbankselect -global-isel %s -regbankselect-greedy -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY
 # REQUIRES: global-isel
 
 --- |
@@ -45,6 +46,14 @@
   entry:
     ret void
   }
+  define void @greedyMappingOr() {
+  entry:
+    ret void
+  }
+  define void @greedyMappingOrWithConstraints() {
+  entry:
+    ret void
+  }
 ...
 
 ---
@@ -225,3 +234,96 @@ body: |
     %0(32) = COPY %w0
     %s0 = G_ADD i32 %0, %0
 ...
+
+---
+# Check that the greedy mode is able to switch the
+# G_OR instruction from fpr to gpr.
+name:            greedyMappingOr
+isSSA:           true
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr }
+# CHECK-NEXT:  - { id: 1, class: gpr }
+
+# Fast mode maps vector instruction on FPR.
+# FAST-NEXT:  - { id: 2, class: fpr }
+# Fast mode needs two extra copies.
+# FAST-NEXT:  - { id: 3, class: fpr }
+# FAST-NEXT:  - { id: 4, class: fpr }
+
+# Greedy mode coalesce the computation on the GPR register
+# because it is the cheapest.
+# GREEDY-NEXT:  - { id: 2, class: gpr }
+
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body: |
+  bb.0.entry:
+    liveins: %x0, %x1
+    ; CHECK: %0(64) = COPY %x0
+    ; CHECK-NEXT: %1(64) = COPY %x1
+
+
+    ; Fast mode tries to reuse the source of the copy for the destination.
+    ; Now, the default mapping says that %0 and %1 need to be in FPR.
+    ; The repairing code insert two copies to materialize that.
+    ; FAST-NEXT: %3(64) = COPY %0
+    ; FAST-NEXT: %4(64) = COPY %1
+    ; The mapping of G_OR is on FPR.
+    ; FAST-NEXT: %2(64) = G_OR <2 x i32> %3, %4
+
+    ; Greedy mode remapped the instruction on the GPR bank.
+    ; GREEDY-NEXT: %2(64) = G_OR <2 x i32> %0, %1
+    %0(64) = COPY %x0
+    %1(64) = COPY %x1
+    %2(64) = G_OR <2 x i32> %0, %1
+...
+
+---
+# Check that the greedy mode is able to switch the
+# G_OR instruction from fpr to gpr, while still honoring
+# %2 constraint.
+name:            greedyMappingOrWithConstraints
+isSSA:           true
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: gpr }
+# CHECK-NEXT:  - { id: 1, class: gpr }
+# CHECK-NEXT:  - { id: 2, class: fpr }
+
+# Fast mode maps vector instruction on FPR.
+# Fast mode needs two extra copies.
+# FAST-NEXT:  - { id: 3, class: fpr }
+# FAST-NEXT:  - { id: 4, class: fpr }
+
+# Greedy mode coalesce the computation on the GPR register because it
+# is the cheapest, but will need one extra copy to materialize %2 into a FPR.
+# GREEDY-NEXT:  - { id: 3, class: gpr }
+
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: fpr }
+body: |
+  bb.0.entry:
+    liveins: %x0, %x1
+    ; CHECK: %0(64) = COPY %x0
+    ; CHECK-NEXT: %1(64) = COPY %x1
+
+
+    ; Fast mode tries to reuse the source of the copy for the destination.
+    ; Now, the default mapping says that %0 and %1 need to be in FPR.
+    ; The repairing code insert two copies to materialize that.
+    ; FAST-NEXT: %3(64) = COPY %0
+    ; FAST-NEXT: %4(64) = COPY %1
+    ; The mapping of G_OR is on FPR.
+    ; FAST-NEXT: %2(64) = G_OR <2 x i32> %3, %4
+
+    ; Greedy mode remapped the instruction on the GPR bank.
+    ; GREEDY-NEXT: %3(64) = G_OR <2 x i32> %0, %1
+    ; We need to keep %2 into FPR because we do not know anything about it.
+    ; GREEDY-NEXT: %2(64) = COPY %3
+    %0(64) = COPY %x0
+    %1(64) = COPY %x1
+    %2(64) = G_OR <2 x i32> %0, %1
+...




More information about the llvm-commits mailing list