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