• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- HexagonISelDAGToDAG.h -----------------------------------*- C++ -*-===//
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 // Hexagon specific code to select Hexagon machine instructions for
10 // SelectionDAG operations.
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
14 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
15 
16 #include "HexagonSubtarget.h"
17 #include "HexagonTargetMachine.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/CodeGen/SelectionDAGISel.h"
21 #include "llvm/Support/CodeGen.h"
22 
23 #include <vector>
24 
25 namespace llvm {
26 class MachineFunction;
27 class HexagonInstrInfo;
28 class HexagonRegisterInfo;
29 class HexagonTargetLowering;
30 
31 class HexagonDAGToDAGISel : public SelectionDAGISel {
32   const HexagonSubtarget *HST;
33   const HexagonInstrInfo *HII;
34   const HexagonRegisterInfo *HRI;
35 public:
HexagonDAGToDAGISel(HexagonTargetMachine & tm,CodeGenOpt::Level OptLevel)36   explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm,
37                                CodeGenOpt::Level 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     return true;
48   }
49 
ComplexPatternFuncMutatesDAG()50   bool ComplexPatternFuncMutatesDAG() const override {
51     return true;
52   }
53   void PreprocessISelDAG() override;
54   void EmitFunctionEntryCode() override;
55 
56   void Select(SDNode *N) override;
57 
58   // Complex Pattern Selectors.
59   inline bool SelectAddrGA(SDValue &N, SDValue &R);
60   inline bool SelectAddrGP(SDValue &N, SDValue &R);
61   inline bool SelectAnyImm(SDValue &N, SDValue &R);
62   inline bool SelectAnyInt(SDValue &N, SDValue &R);
63   bool SelectAnyImmediate(SDValue &N, SDValue &R, uint32_t LogAlign);
64   bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP,
65                            uint32_t LogAlign);
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 
getPassName()74   StringRef getPassName() const override {
75     return "Hexagon DAG->DAG Pattern Instruction Selection";
76   }
77 
78   // Generate a machine instruction node corresponding to the circ/brev
79   // load intrinsic.
80   MachineSDNode *LoadInstrForLoadIntrinsic(SDNode *IntN);
81   // Given the circ/brev load intrinsic and the already generated machine
82   // instruction, generate the appropriate store (that is a part of the
83   // intrinsic's functionality).
84   SDNode *StoreInstrForLoadIntrinsic(MachineSDNode *LoadN, SDNode *IntN);
85 
86   void SelectFrameIndex(SDNode *N);
87   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
88   /// inline asm expressions.
89   bool SelectInlineAsmMemoryOperand(const SDValue &Op,
90                                     unsigned ConstraintID,
91                                     std::vector<SDValue> &OutOps) override;
92   bool tryLoadOfLoadIntrinsic(LoadSDNode *N);
93   bool SelectBrevLdIntrinsic(SDNode *IntN);
94   bool SelectNewCircIntrinsic(SDNode *IntN);
95   void SelectLoad(SDNode *N);
96   void SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl);
97   void SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl);
98   void SelectStore(SDNode *N);
99   void SelectSHL(SDNode *N);
100   void SelectZeroExtend(SDNode *N);
101   void SelectIntrinsicWChain(SDNode *N);
102   void SelectIntrinsicWOChain(SDNode *N);
103   void SelectConstant(SDNode *N);
104   void SelectConstantFP(SDNode *N);
105   void SelectV65Gather(SDNode *N);
106   void SelectV65GatherPred(SDNode *N);
107   void SelectHVXDualOutput(SDNode *N);
108   void SelectAddSubCarry(SDNode *N);
109   void SelectVAlign(SDNode *N);
110   void SelectVAlignAddr(SDNode *N);
111   void SelectTypecast(SDNode *N);
112   void SelectP2D(SDNode *N);
113   void SelectD2P(SDNode *N);
114   void SelectQ2V(SDNode *N);
115   void SelectV2Q(SDNode *N);
116 
117   // Include the declarations autogenerated from the selection patterns.
118   #define GET_DAGISEL_DECL
119   #include "HexagonGenDAGISel.inc"
120 
121 private:
122   // This is really only to get access to ReplaceNode (which is a protected
123   // member). Any other members used by HvxSelector can be moved around to
124   // make them accessible).
125   friend struct HvxSelector;
126 
selectUndef(const SDLoc & dl,MVT ResTy)127   SDValue selectUndef(const SDLoc &dl, MVT ResTy) {
128     SDNode *U = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy);
129     return SDValue(U, 0);
130   }
131 
132   void SelectHvxShuffle(SDNode *N);
133   void SelectHvxRor(SDNode *N);
134   void SelectHvxVAlign(SDNode *N);
135 
136   bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src);
137   bool isAlignedMemNode(const MemSDNode *N) const;
138   bool isSmallStackStore(const StoreSDNode *N) const;
139   bool isPositiveHalfWord(const SDNode *N) const;
140   bool hasOneUse(const SDNode *N) const;
141 
142   // DAG preprocessing functions.
143   void ppSimplifyOrSelect0(std::vector<SDNode*> &&Nodes);
144   void ppAddrReorderAddShl(std::vector<SDNode*> &&Nodes);
145   void ppAddrRewriteAndSrl(std::vector<SDNode*> &&Nodes);
146   void ppHoistZextI1(std::vector<SDNode*> &&Nodes);
147 
148   SmallDenseMap<SDNode *,int> RootWeights;
149   SmallDenseMap<SDNode *,int> RootHeights;
150   SmallDenseMap<const Value *,int> GAUsesInFunction;
151   int getWeight(SDNode *N);
152   int getHeight(SDNode *N);
153   SDValue getMultiplierForSHL(SDNode *N);
154   SDValue factorOutPowerOf2(SDValue V, unsigned Power);
155   unsigned getUsesInFunction(const Value *V);
156   SDValue balanceSubTree(SDNode *N, bool Factorize = false);
157   void rebalanceAddressTrees();
158 }; // end HexagonDAGToDAGISel
159 }
160 
161 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
162