[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