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