llvm.org GIT mirror llvm / f4df3d4
[X86][GlobalISel] Add general-purpose Register Bank Summary: [X86][GlobalISel] Add general-purpose Register Bank. Add trivial handling of G_ADD legalization . Add Regestry Bank selection for COPY and G_ADD instructions Reviewers: rovka, zvi, ab, t.p.northover, qcolombet Reviewed By: qcolombet Subscribers: qcolombet, mgorny, dberris, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D29771 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294723 91177308-0d34-0410-b5e6-96231b3b80d8 Igor Breger 3 years ago
11 changed file(s) with 546 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
99 tablegen(LLVM X86GenFastISel.inc -gen-fast-isel)
1010 tablegen(LLVM X86GenCallingConv.inc -gen-callingconv)
1111 tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget)
12 if(LLVM_BUILD_GLOBAL_ISEL)
13 tablegen(LLVM X86GenRegisterBank.inc -gen-register-bank)
14 endif()
15
1216 add_public_tablegen_target(X86CommonTableGen)
1317
1418 # Add GlobalISel files if the build option was enabled.
1519 set(GLOBAL_ISEL_FILES
1620 X86CallLowering.cpp
21 X86LegalizerInfo.cpp
22 X86RegisterBankInfo.cpp
1723 )
1824
1925 if(LLVM_BUILD_GLOBAL_ISEL)
810810 //===----------------------------------------------------------------------===//
811811
812812 include "X86RegisterInfo.td"
813 include "X86RegisterBanks.td"
813814
814815 //===----------------------------------------------------------------------===//
815816 // Instruction Descriptions
0 //===- X86GenRegisterBankInfo.def ----------------------------*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file defines all the static objects used by X86RegisterBankInfo.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_BUILD_GLOBAL_ISEL
14 #error "You shouldn't build this"
15 #endif
16
17 namespace llvm {
18 RegisterBankInfo::PartialMapping X86GenRegisterBankInfo::PartMappings[]{
19 /* StartIdx, Length, RegBank */
20 // GPR value
21 {0, 8, X86::GPRRegBank}, // :0
22 {0, 16, X86::GPRRegBank}, // :1
23 {0, 32, X86::GPRRegBank}, // :2
24 {0, 64, X86::GPRRegBank}, // :3
25 };
26
27 enum PartialMappingIdx {
28 PMI_None = -1,
29 PMI_GPR8,
30 PMI_GPR16,
31 PMI_GPR32,
32 PMI_GPR64,
33 };
34
35 #define INSTR_3OP(INFO) INFO, INFO, INFO,
36 #define BREAKDOWN(INDEX, NUM) \
37 { &X86GenRegisterBankInfo::PartMappings[INDEX], NUM }
38 // ValueMappings.
39 RegisterBankInfo::ValueMapping X86GenRegisterBankInfo::ValMappings[]{
40 /* BreakDown, NumBreakDowns */
41 // 3-operands instructions (all binary operations should end up with one of
42 // those mapping).
43 INSTR_3OP(BREAKDOWN(PMI_GPR8, 1)) // 0: GPR_8
44 INSTR_3OP(BREAKDOWN(PMI_GPR16, 1)) // 3: GPR_16
45 INSTR_3OP(BREAKDOWN(PMI_GPR32, 1)) // 6: GPR_32
46 INSTR_3OP(BREAKDOWN(PMI_GPR64, 1)) // 9: GPR_64
47 };
48 #undef INSTR_3OP
49 #undef BREAKDOWN
50
51 enum ValueMappingIdx {
52 VMI_None = -1,
53 VMI_3OpsGpr8Idx = 0,
54 VMI_3OpsGpr16Idx = 3,
55 VMI_3OpsGpr32Idx = 6,
56 VMI_3OpsGpr64Idx = 9,
57 };
58
59 } // End llvm namespace.
0 //===- X86LegalizerInfo.cpp --------------------------------------*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the targeting of the Machinelegalizer class for X86.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12
13 #include "X86LegalizerInfo.h"
14 #include "X86Subtarget.h"
15 #include "llvm/CodeGen/ValueTypes.h"
16 #include "llvm/IR/DerivedTypes.h"
17 #include "llvm/IR/Type.h"
18 #include "llvm/Target/TargetOpcodes.h"
19
20 using namespace llvm;
21
22 #ifndef LLVM_BUILD_GLOBAL_ISEL
23 #error "You shouldn't build this"
24 #endif
25
26 X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI) : Subtarget(STI) {
27
28 setLegalizerInfo32bit();
29 setLegalizerInfo64bit();
30
31 computeTables();
32 }
33
34 void X86LegalizerInfo::setLegalizerInfo32bit() {
35
36 const LLT s8 = LLT::scalar(8);
37 const LLT s16 = LLT::scalar(16);
38 const LLT s32 = LLT::scalar(32);
39
40 for (auto Ty : {s8, s16, s32})
41 setAction({TargetOpcode::G_ADD, Ty}, Legal);
42 }
43 void
44
45 X86LegalizerInfo::setLegalizerInfo64bit() {
46
47 if (!Subtarget.is64Bit())
48 return;
49
50 const LLT s64 = LLT::scalar(64);
51
52 setAction({TargetOpcode::G_ADD, s64}, Legal);
53 }
0 //===- X86LegalizerInfo.h ------------------------------------------*- C++
1 //-*-==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file declares the targeting of the Machinelegalizer class for X86.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_TARGET_X86_X86MACHINELEGALIZER_H
15 #define LLVM_LIB_TARGET_X86_X86MACHINELEGALIZER_H
16
17 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
18
19 namespace llvm {
20
21 class X86Subtarget;
22
23 /// This class provides the information for the target register banks.
24 class X86LegalizerInfo : public LegalizerInfo {
25 private:
26 /// Keep a reference to the X86Subtarget around so that we can
27 /// make the right decision when generating code for different targets.
28 const X86Subtarget &Subtarget;
29
30 public:
31 X86LegalizerInfo(const X86Subtarget &STI);
32
33 private:
34 void setLegalizerInfo32bit();
35 void setLegalizerInfo64bit();
36 };
37 } // End llvm namespace.
38 #endif
0 //===- X86RegisterBankInfo.cpp -----------------------------------*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the targeting of the RegisterBankInfo class for X86.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12
13 #include "X86RegisterBankInfo.h"
14 #include "X86InstrInfo.h"
15 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
16 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/Target/TargetRegisterInfo.h"
19
20 #define GET_TARGET_REGBANK_IMPL
21 #include "X86GenRegisterBank.inc"
22
23 // This file will be TableGen'ed at some point.
24 #include "X86GenRegisterBankInfo.def"
25
26 using namespace llvm;
27
28 #ifndef LLVM_BUILD_GLOBAL_ISEL
29 #error "You shouldn't build this"
30 #endif
31
32 X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI)
33 : X86GenRegisterBankInfo() {
34
35 // validate RegBank initialization.
36 const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID);
37 (void)RBGPR;
38 assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization.");
39
40 // The GPR register bank is fully defined by all the registers in
41 // GR64 + its subclasses.
42 assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) &&
43 "Subclass not added?");
44 assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
45 }
46
47 const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass(
48 const TargetRegisterClass &RC) const {
49
50 if (X86::GR8RegClass.hasSubClassEq(&RC) ||
51 X86::GR16RegClass.hasSubClassEq(&RC) ||
52 X86::GR32RegClass.hasSubClassEq(&RC) ||
53 X86::GR64RegClass.hasSubClassEq(&RC))
54 return getRegBank(X86::GPRRegBankID);
55
56 llvm_unreachable("Unsupported register kind yet.");
57 }
58
59 RegisterBankInfo::InstructionMapping
60 X86RegisterBankInfo::getOperandsMapping(const MachineInstr &MI, bool isFP) {
61 const MachineFunction &MF = *MI.getParent()->getParent();
62 const MachineRegisterInfo &MRI = MF.getRegInfo();
63
64 unsigned NumOperands = MI.getNumOperands();
65 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
66
67 if (NumOperands != 3 ||
68 (Ty != MRI.getType(MI.getOperand(1).getReg())) ||
69 (Ty != MRI.getType(MI.getOperand(2).getReg())))
70 llvm_unreachable("Unsupported operand maping yet.");
71
72 ValueMappingIdx ValMapIdx = VMI_None;
73 if (!isFP) {
74 switch (Ty.getSizeInBits()) {
75 case 8:
76 ValMapIdx = VMI_3OpsGpr8Idx;
77 break;
78 case 16:
79 ValMapIdx = VMI_3OpsGpr16Idx;
80 break;
81 case 32:
82 ValMapIdx = VMI_3OpsGpr32Idx;
83 break;
84 case 64:
85 ValMapIdx = VMI_3OpsGpr64Idx;
86 break;
87 default:
88 llvm_unreachable("Unsupported register size.");
89 break;
90 }
91 } else {
92 llvm_unreachable("Floating point not supported yet.");
93 }
94
95 return InstructionMapping{DefaultMappingID, 1, &ValMappings[ValMapIdx],
96 NumOperands};
97 }
98
99 RegisterBankInfo::InstructionMapping
100 X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
101 auto Opc = MI.getOpcode();
102
103 // Try the default logic for non-generic instructions that are either copies
104 // or already have some operands assigned to banks.
105 if (!isPreISelGenericOpcode(Opc)) {
106 InstructionMapping Mapping = getInstrMappingImpl(MI);
107 if (Mapping.isValid())
108 return Mapping;
109 }
110
111 switch (Opc) {
112 case TargetOpcode::G_ADD:
113 return getOperandsMapping(MI, false);
114 break;
115 default:
116 return InstructionMapping{};
117 }
118
119 return InstructionMapping{};
120 }
0 //===- X86RegisterBankInfo ---------------------------------------*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file declares the targeting of the RegisterBankInfo class for X86.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_LIB_TARGET_X86_X86REGISTERBANKINFO_H
14 #define LLVM_LIB_TARGET_X86_X86REGISTERBANKINFO_H
15
16 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
17
18 #define GET_REGBANK_DECLARATIONS
19 #include "X86GenRegisterBank.inc"
20
21 namespace llvm {
22
23 class X86GenRegisterBankInfo : public RegisterBankInfo {
24 protected:
25 static RegisterBankInfo::PartialMapping PartMappings[];
26 static RegisterBankInfo::ValueMapping ValMappings[];
27
28 #define GET_TARGET_REGBANK_CLASS
29 #include "X86GenRegisterBank.inc"
30 };
31
32 class TargetRegisterInfo;
33
34 /// This class provides the information for the target register banks.
35 class X86RegisterBankInfo final : public X86GenRegisterBankInfo {
36 private:
37 /// Get an instruction mapping.
38 /// \return An InstructionMappings with a statically allocated
39 /// OperandsMapping.
40 static InstructionMapping getOperandsMapping(const MachineInstr &MI,
41 bool isFP);
42
43 public:
44 X86RegisterBankInfo(const TargetRegisterInfo &TRI);
45
46 const RegisterBank &
47 getRegBankFromRegClass(const TargetRegisterClass &RC) const override;
48
49 InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
50 };
51
52 } // End llvm namespace.
53 #endif
0 //=- X86RegisterBank.td - Describe the AArch64 Banks -----*- tablegen -*-=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //===----------------------------------------------------------------------===//
11
12 /// General Purpose Registers: RAX, RCX,...
13 def GPRRegBank : RegisterBank<"GPR", [GR64]>;
1313 #include "MCTargetDesc/X86MCTargetDesc.h"
1414 #include "X86.h"
1515 #include "X86CallLowering.h"
16 #include "X86LegalizerInfo.h"
17 #include "X86RegisterBankInfo.h"
1618 #include "X86MacroFusion.h"
1719 #include "X86Subtarget.h"
1820 #include "X86TargetMachine.h"
2729 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
2830 #include "llvm/CodeGen/GlobalISel/GISelAccessor.h"
2931 #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
32 #include "llvm/CodeGen/GlobalISel/Legalizer.h"
33 #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
3034 #include "llvm/CodeGen/MachineScheduler.h"
3135 #include "llvm/CodeGen/Passes.h"
3236 #include "llvm/CodeGen/TargetPassConfig.h"
201205 namespace {
202206
203207 struct X86GISelActualAccessor : public GISelAccessor {
204 std::unique_ptr CL;
205
206 X86GISelActualAccessor(CallLowering* CL): CL(CL) {}
208 std::unique_ptr CallLoweringInfo;
209 std::unique_ptr Legalizer;
210 std::unique_ptr RegBankInfo;
207211
208212 const CallLowering *getCallLowering() const override {
209 return CL.get();
213 return CallLoweringInfo.get();
210214 }
211215
212216 const InstructionSelector *getInstructionSelector() const override {
215219 }
216220
217221 const LegalizerInfo *getLegalizerInfo() const override {
218 //TODO: Implement
219 return nullptr;
222 return Legalizer.get();
220223 }
221224
222225 const RegisterBankInfo *getRegBankInfo() const override {
223 //TODO: Implement
224 return nullptr;
226 return RegBankInfo.get();
225227 }
226228 };
227229
270272 #ifndef LLVM_BUILD_GLOBAL_ISEL
271273 GISelAccessor *GISel = new GISelAccessor();
272274 #else
273 X86GISelActualAccessor *GISel = new X86GISelActualAccessor(
274 new X86CallLowering(*I->getTargetLowering()));
275 X86GISelActualAccessor *GISel = new X86GISelActualAccessor();
276
277 GISel->CallLoweringInfo.reset(new X86CallLowering(*I->getTargetLowering()));
278 GISel->Legalizer.reset(new X86LegalizerInfo(*I));
279
280 auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());
281 GISel->RegBankInfo.reset(RBI);
282
275283 #endif
276284 I->setGISelAccessor(*GISel);
277285 }
370378 }
371379
372380 bool X86PassConfig::addLegalizeMachineIR() {
373 //TODO: Implement
381 addPass(new Legalizer());
374382 return false;
375383 }
376384
377385 bool X86PassConfig::addRegBankSelect() {
378 //TODO: Implement
386 addPass(new RegBankSelect());
379387 return false;
380388 }
381389
0 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=regbankselect %s -o - | FileCheck %s
1
2 --- |
3 ; ModuleID = 'tmp.ll'
4 source_filename = "tmp.ll"
5 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6 target triple = "x86_64--linux-gnu"
7
8 define i8 @test_add_i8(i8 %arg1, i8 %arg2) {
9 %ret = add i8 %arg1, %arg2
10 ret i8 %ret
11 }
12
13 define i16 @test_add_i16(i16 %arg1, i16 %arg2) {
14 %ret = add i16 %arg1, %arg2
15 ret i16 %ret
16 }
17
18 define i32 @test_add_i32(i32 %arg1, i32 %arg2) {
19 %ret = add i32 %arg1, %arg2
20 ret i32 %ret
21 }
22
23 define i64 @test_add_i64(i64 %arg1, i64 %arg2) {
24 %ret = add i64 %arg1, %arg2
25 ret i64 %ret
26 }
27
28 ...
29 ---
30 name: test_add_i8
31 alignment: 4
32 legalized: true
33 regBankSelected: false
34 selected: false
35 tracksRegLiveness: true
36 # CHECK-LABEL: name: test_add_i8
37 # CHECK: registers:
38 # CHECK: - { id: 0, class: gpr }
39 # CHECK: - { id: 1, class: gpr }
40 # CHECK: - { id: 2, class: gpr }
41 registers:
42 - { id: 0, class: _ }
43 - { id: 1, class: _ }
44 - { id: 2, class: _ }
45 body: |
46 bb.1 (%ir-block.0):
47 liveins: %edi, %esi
48
49 %0(s8) = COPY %edi
50 %1(s8) = COPY %esi
51 %2(s8) = G_ADD %0, %1
52 %al = COPY %2(s8)
53 RET 0, implicit %al
54
55 ...
56 ---
57 name: test_add_i16
58 alignment: 4
59 legalized: true
60 regBankSelected: false
61 selected: false
62 tracksRegLiveness: true
63 # CHECK-LABEL: name: test_add_i16
64 # CHECK: registers:
65 # CHECK: - { id: 0, class: gpr }
66 # CHECK: - { id: 1, class: gpr }
67 # CHECK: - { id: 2, class: gpr }
68 registers:
69 - { id: 0, class: _ }
70 - { id: 1, class: _ }
71 - { id: 2, class: _ }
72 body: |
73 bb.1 (%ir-block.0):
74 liveins: %edi, %esi
75
76 %0(s16) = COPY %edi
77 %1(s16) = COPY %esi
78 %2(s16) = G_ADD %0, %1
79 %ax = COPY %2(s16)
80 RET 0, implicit %ax
81
82 ...
83 ---
84 name: test_add_i32
85 alignment: 4
86 legalized: true
87 regBankSelected: false
88 selected: false
89 tracksRegLiveness: true
90 # CHECK-LABEL: name: test_add_i32
91 # CHECK: registers:
92 # CHECK: - { id: 0, class: gpr }
93 # CHECK: - { id: 1, class: gpr }
94 # CHECK: - { id: 2, class: gpr }
95 registers:
96 - { id: 0, class: _ }
97 - { id: 1, class: _ }
98 - { id: 2, class: _ }
99 body: |
100 bb.1 (%ir-block.0):
101 liveins: %edi, %esi
102
103 %0(s32) = COPY %edi
104 %1(s32) = COPY %esi
105 %2(s32) = G_ADD %0, %1
106 %eax = COPY %2(s32)
107 RET 0, implicit %eax
108
109 ...
110 ---
111 name: test_add_i64
112 alignment: 4
113 legalized: true
114 regBankSelected: false
115 selected: false
116 tracksRegLiveness: true
117 # CHECK-LABEL: name: test_add_i64
118 # CHECK: registers:
119 # CHECK: - { id: 0, class: gpr }
120 # CHECK: - { id: 1, class: gpr }
121 # CHECK: - { id: 2, class: gpr }
122 registers:
123 - { id: 0, class: _ }
124 - { id: 1, class: _ }
125 - { id: 2, class: _ }
126 body: |
127 bb.1 (%ir-block.0):
128 liveins: %rdi, %rsi
129
130 %0(s64) = COPY %rdi
131 %1(s64) = COPY %rsi
132 %2(s64) = G_ADD %0, %1
133 %rax = COPY %2(s64)
134 RET 0, implicit %rax
135
136 ...
0 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
1
2 --- |
3 ; ModuleID = ''
4 source_filename = ""
5 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6 target triple = "x86_64--linux-gnu"
7
8 define i32 @test_add_i32(i32 %arg1, i32 %arg2) {
9 %ret = add i32 %arg1, %arg2
10 ret i32 %ret
11 }
12
13 ...
14 ---
15 name: test_add_i32
16 alignment: 4
17 legalized: false
18 regBankSelected: false
19 selected: false
20 tracksRegLiveness: true
21 registers:
22 - { id: 0, class: _ }
23 - { id: 1, class: _ }
24 - { id: 2, class: _ }
25 body: |
26 bb.1 (%ir-block.0):
27 liveins: %edi, %esi
28 ; CHECK-LABEL: name: test_add_i32
29 ; CHECK: [[VAL1:%.*]](s32) = COPY %edi
30 ; CHECK: [[VAL2:%.*]](s32) = COPY %esi
31 ; CHECK: [[RES:%.*]](s32) = G_ADD [[VAL1:%.*]], [[VAL2:%.*]]
32
33 %0(s32) = COPY %edi
34 %1(s32) = COPY %esi
35 %2(s32) = G_ADD %0, %1
36 %eax = COPY %2(s32)
37 RET 0, implicit %eax
38
39 ...