1 //===-- RISCVInstructionSelector.cpp -----------------------------*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the targeting of the InstructionSelector class for
10 /// RISCV.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13
14 #include "RISCVRegisterBankInfo.h"
15 #include "RISCVSubtarget.h"
16 #include "RISCVTargetMachine.h"
17 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
18 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
19 #include "llvm/IR/IntrinsicsRISCV.h"
20 #include "llvm/Support/Debug.h"
21
22 #define DEBUG_TYPE "riscv-isel"
23
24 using namespace llvm;
25
26 #define GET_GLOBALISEL_PREDICATE_BITSET
27 #include "RISCVGenGlobalISel.inc"
28 #undef GET_GLOBALISEL_PREDICATE_BITSET
29
30 namespace {
31
32 class RISCVInstructionSelector : public InstructionSelector {
33 public:
34 RISCVInstructionSelector(const RISCVTargetMachine &TM,
35 const RISCVSubtarget &STI,
36 const RISCVRegisterBankInfo &RBI);
37
38 bool select(MachineInstr &I) override;
getName()39 static const char *getName() { return DEBUG_TYPE; }
40
41 private:
42 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
43
44 const RISCVSubtarget &STI;
45 const RISCVInstrInfo &TII;
46 const RISCVRegisterInfo &TRI;
47 const RISCVRegisterBankInfo &RBI;
48
49 // FIXME: This is necessary because DAGISel uses "Subtarget->" and GlobalISel
50 // uses "STI." in the code generated by TableGen. We need to unify the name of
51 // Subtarget variable.
52 const RISCVSubtarget *Subtarget = &STI;
53
54 #define GET_GLOBALISEL_PREDICATES_DECL
55 #include "RISCVGenGlobalISel.inc"
56 #undef GET_GLOBALISEL_PREDICATES_DECL
57
58 #define GET_GLOBALISEL_TEMPORARIES_DECL
59 #include "RISCVGenGlobalISel.inc"
60 #undef GET_GLOBALISEL_TEMPORARIES_DECL
61 };
62
63 } // end anonymous namespace
64
65 #define GET_GLOBALISEL_IMPL
66 #include "RISCVGenGlobalISel.inc"
67 #undef GET_GLOBALISEL_IMPL
68
RISCVInstructionSelector(const RISCVTargetMachine & TM,const RISCVSubtarget & STI,const RISCVRegisterBankInfo & RBI)69 RISCVInstructionSelector::RISCVInstructionSelector(
70 const RISCVTargetMachine &TM, const RISCVSubtarget &STI,
71 const RISCVRegisterBankInfo &RBI)
72 : InstructionSelector(), STI(STI), TII(*STI.getInstrInfo()),
73 TRI(*STI.getRegisterInfo()), RBI(RBI),
74
75 #define GET_GLOBALISEL_PREDICATES_INIT
76 #include "RISCVGenGlobalISel.inc"
77 #undef GET_GLOBALISEL_PREDICATES_INIT
78 #define GET_GLOBALISEL_TEMPORARIES_INIT
79 #include "RISCVGenGlobalISel.inc"
80 #undef GET_GLOBALISEL_TEMPORARIES_INIT
81 {
82 }
83
select(MachineInstr & I)84 bool RISCVInstructionSelector::select(MachineInstr &I) {
85
86 if (!isPreISelGenericOpcode(I.getOpcode())) {
87 // Certain non-generic instructions also need some special handling.
88 return true;
89 }
90
91 if (selectImpl(I, *CoverageInfo))
92 return true;
93
94 return false;
95 }
96
97 namespace llvm {
98 InstructionSelector *
createRISCVInstructionSelector(const RISCVTargetMachine & TM,RISCVSubtarget & Subtarget,RISCVRegisterBankInfo & RBI)99 createRISCVInstructionSelector(const RISCVTargetMachine &TM,
100 RISCVSubtarget &Subtarget,
101 RISCVRegisterBankInfo &RBI) {
102 return new RISCVInstructionSelector(TM, Subtarget, RBI);
103 }
104 } // end namespace llvm
105