xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- HexagonISelDAGToDAG.h -----------------------------------*- 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 // Hexagon specific code to select Hexagon machine instructions for
9 // SelectionDAG operations.
10 //===----------------------------------------------------------------------===//
11 
12 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
13 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
14 
15 #include "HexagonSubtarget.h"
16 #include "HexagonTargetMachine.h"
17 #include "llvm/CodeGen/SelectionDAG.h"
18 #include "llvm/CodeGen/SelectionDAGISel.h"
19 #include "llvm/Support/CodeGen.h"
20 
21 #include <vector>
22 
23 namespace llvm {
24 class MachineFunction;
25 class HexagonInstrInfo;
26 class HexagonRegisterInfo;
27 
28 class HexagonDAGToDAGISel : public SelectionDAGISel {
29   const HexagonSubtarget *HST;
30   const HexagonInstrInfo *HII;
31   const HexagonRegisterInfo *HRI;
32 
33 public:
34   HexagonDAGToDAGISel() = delete;
35 
HexagonDAGToDAGISel(HexagonTargetMachine & tm,CodeGenOptLevel OptLevel)36   explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm,
37                                CodeGenOptLevel OptLevel)
38       : SelectionDAGISel(tm, OptLevel), HST(nullptr), HII(nullptr),
39         HRI(nullptr) {}
40 
runOnMachineFunction(MachineFunction & MF)41   bool runOnMachineFunction(MachineFunction &MF) override {
42     // Reset the subtarget each time through.
43     HST = &MF.getSubtarget<HexagonSubtarget>();
44     HII = HST->getInstrInfo();
45     HRI = HST->getRegisterInfo();
46     SelectionDAGISel::runOnMachineFunction(MF);
47     updateAligna();
48     return true;
49   }
50 
ComplexPatternFuncMutatesDAG()51   bool ComplexPatternFuncMutatesDAG() const override {
52     return true;
53   }
54   void PreprocessISelDAG() override;
55   void emitFunctionEntryCode() override;
56 
57   void Select(SDNode *N) override;
58 
59   // Complex Pattern Selectors.
60   inline bool SelectAddrGA(SDValue &N, SDValue &R);
61   inline bool SelectAddrGP(SDValue &N, SDValue &R);
62   inline bool SelectAnyImm(SDValue &N, SDValue &R);
63   inline bool SelectAnyInt(SDValue &N, SDValue &R);
64   bool SelectAnyImmediate(SDValue &N, SDValue &R, Align Alignment);
65   bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP, Align Alignment);
66   bool SelectAddrFI(SDValue &N, SDValue &R);
67   bool DetectUseSxtw(SDValue &N, SDValue &R);
68 
69   inline bool SelectAnyImm0(SDValue &N, SDValue &R);
70   inline bool SelectAnyImm1(SDValue &N, SDValue &R);
71   inline bool SelectAnyImm2(SDValue &N, SDValue &R);
72   inline bool SelectAnyImm3(SDValue &N, SDValue &R);
73 
74   // Generate a machine instruction node corresponding to the circ/brev
75   // load intrinsic.
76   MachineSDNode *LoadInstrForLoadIntrinsic(SDNode *IntN);
77   // Given the circ/brev load intrinsic and the already generated machine
78   // instruction, generate the appropriate store (that is a part of the
79   // intrinsic's functionality).
80   SDNode *StoreInstrForLoadIntrinsic(MachineSDNode *LoadN, SDNode *IntN);
81 
82   void SelectFrameIndex(SDNode *N);
83   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
84   /// inline asm expressions.
85   bool SelectInlineAsmMemoryOperand(const SDValue &Op,
86                                     InlineAsm::ConstraintCode ConstraintID,
87                                     std::vector<SDValue> &OutOps) override;
88   bool tryLoadOfLoadIntrinsic(LoadSDNode *N);
89   bool SelectBrevLdIntrinsic(SDNode *IntN);
90   bool SelectNewCircIntrinsic(SDNode *IntN);
91   void SelectLoad(SDNode *N);
92   void SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl);
93   void SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl);
94   void SelectStore(SDNode *N);
95   void SelectSHL(SDNode *N);
96   void SelectIntrinsicWChain(SDNode *N);
97   void SelectIntrinsicWOChain(SDNode *N);
98   void SelectExtractSubvector(SDNode *N);
99   void SelectConstant(SDNode *N);
100   void SelectConstantFP(SDNode *N);
101   void SelectV65Gather(SDNode *N);
102   void SelectV65GatherPred(SDNode *N);
103   void SelectHVXDualOutput(SDNode *N);
104   void SelectAddSubCarry(SDNode *N);
105   void SelectVAlign(SDNode *N);
106   void SelectVAlignAddr(SDNode *N);
107   void SelectTypecast(SDNode *N);
108   void SelectP2D(SDNode *N);
109   void SelectD2P(SDNode *N);
110   void SelectQ2V(SDNode *N);
111   void SelectV2Q(SDNode *N);
112   void SelectFDiv(SDNode *N);
113   void FDiv(SDNode *N);
114   void FastFDiv(SDNode *N);
115 
116   // Include the declarations autogenerated from the selection patterns.
117   #define GET_DAGISEL_DECL
118   #include "HexagonGenDAGISel.inc"
119 
120 private:
121   // This is really only to get access to ReplaceNode (which is a protected
122   // member). Any other members used by HvxSelector can be moved around to
123   // make them accessible).
124   friend struct HvxSelector;
125 
selectUndef(const SDLoc & dl,MVT ResTy)126   SDValue selectUndef(const SDLoc &dl, MVT ResTy) {
127     SDNode *U = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy);
128     return SDValue(U, 0);
129   }
130 
131   bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src);
132   bool isAlignedMemNode(const MemSDNode *N) const;
133   bool isSmallStackStore(const StoreSDNode *N) const;
134   bool isPositiveHalfWord(const SDNode *N) const;
135   bool hasOneUse(const SDNode *N) const;
136 
137   // DAG preprocessing functions.
138   void PreprocessHvxISelDAG();
139   void ppSimplifyOrSelect0(std::vector<SDNode*> &&Nodes);
140   void ppAddrReorderAddShl(std::vector<SDNode*> &&Nodes);
141   void ppAddrRewriteAndSrl(std::vector<SDNode*> &&Nodes);
142   void ppHoistZextI1(std::vector<SDNode*> &&Nodes);
143   void ppHvxShuffleOfShuffle(std::vector<SDNode*> &&Nodes);
144 
145   void SelectHvxExtractSubvector(SDNode *N);
146   void SelectHvxShuffle(SDNode *N);
147   void SelectHvxRor(SDNode *N);
148   void SelectHvxVAlign(SDNode *N);
149 
150   // Function postprocessing.
151   void updateAligna();
152 
153   SmallDenseMap<SDNode *,int> RootWeights;
154   SmallDenseMap<SDNode *,int> RootHeights;
155   SmallDenseMap<const Value *,int> GAUsesInFunction;
156   int getWeight(SDNode *N);
157   int getHeight(SDNode *N);
158   SDValue getMultiplierForSHL(SDNode *N);
159   SDValue factorOutPowerOf2(SDValue V, unsigned Power);
160   unsigned getUsesInFunction(const Value *V);
161   SDValue balanceSubTree(SDNode *N, bool Factorize = false);
162   void rebalanceAddressTrees();
163 }; // end HexagonDAGToDAGISel
164 
165 class HexagonDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
166 public:
167   static char ID;
168   explicit HexagonDAGToDAGISelLegacy(HexagonTargetMachine &tm,
169                                      CodeGenOptLevel OptLevel);
170 };
171 }
172 
173 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
174