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 /// RISC-V.
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/GIMatchTableExecutorImpl.h"
18 #include "llvm/CodeGen/GlobalISel/InstructionSelector.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;
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 
69 RISCVInstructionSelector::RISCVInstructionSelector(
70     const RISCVTargetMachine &TM, const RISCVSubtarget &STI,
71     const RISCVRegisterBankInfo &RBI)
72     : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI),
73 
74 #define GET_GLOBALISEL_PREDICATES_INIT
75 #include "RISCVGenGlobalISel.inc"
76 #undef GET_GLOBALISEL_PREDICATES_INIT
77 #define GET_GLOBALISEL_TEMPORARIES_INIT
78 #include "RISCVGenGlobalISel.inc"
79 #undef GET_GLOBALISEL_TEMPORARIES_INIT
80 {
81 }
82 
83 bool RISCVInstructionSelector::select(MachineInstr &I) {
84 
85   if (!isPreISelGenericOpcode(I.getOpcode())) {
86     // Certain non-generic instructions also need some special handling.
87     return true;
88   }
89 
90   if (selectImpl(I, *CoverageInfo))
91     return true;
92 
93   return false;
94 }
95 
96 namespace llvm {
97 InstructionSelector *
98 createRISCVInstructionSelector(const RISCVTargetMachine &TM,
99                                RISCVSubtarget &Subtarget,
100                                RISCVRegisterBankInfo &RBI) {
101   return new RISCVInstructionSelector(TM, Subtarget, RBI);
102 }
103 } // end namespace llvm
104