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