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/ADT/StringRef.h" 18 #include "llvm/CodeGen/SelectionDAG.h" 19 #include "llvm/CodeGen/SelectionDAGISel.h" 20 #include "llvm/Support/CodeGen.h" 21 22 #include <vector> 23 24 namespace llvm { 25 class MachineFunction; 26 class HexagonInstrInfo; 27 class HexagonRegisterInfo; 28 class HexagonTargetLowering; 29 30 class HexagonDAGToDAGISel : public SelectionDAGISel { 31 const HexagonSubtarget *HST; 32 const HexagonInstrInfo *HII; 33 const HexagonRegisterInfo *HRI; 34 public: HexagonDAGToDAGISel(HexagonTargetMachine & tm,CodeGenOpt::Level OptLevel)35 explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm, 36 CodeGenOpt::Level OptLevel) 37 : SelectionDAGISel(tm, OptLevel), HST(nullptr), HII(nullptr), 38 HRI(nullptr) {} 39 runOnMachineFunction(MachineFunction & MF)40 bool runOnMachineFunction(MachineFunction &MF) override { 41 // Reset the subtarget each time through. 42 HST = &MF.getSubtarget<HexagonSubtarget>(); 43 HII = HST->getInstrInfo(); 44 HRI = HST->getRegisterInfo(); 45 SelectionDAGISel::runOnMachineFunction(MF); 46 return true; 47 } 48 ComplexPatternFuncMutatesDAG()49 bool ComplexPatternFuncMutatesDAG() const override { 50 return true; 51 } 52 void PreprocessISelDAG() override; 53 void EmitFunctionEntryCode() override; 54 55 void Select(SDNode *N) override; 56 57 // Complex Pattern Selectors. 58 inline bool SelectAddrGA(SDValue &N, SDValue &R); 59 inline bool SelectAddrGP(SDValue &N, SDValue &R); 60 inline bool SelectAnyImm(SDValue &N, SDValue &R); 61 inline bool SelectAnyInt(SDValue &N, SDValue &R); 62 bool SelectAnyImmediate(SDValue &N, SDValue &R, uint32_t LogAlign); 63 bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP, 64 uint32_t LogAlign); 65 bool SelectAddrFI(SDValue &N, SDValue &R); 66 bool DetectUseSxtw(SDValue &N, SDValue &R); 67 68 inline bool SelectAnyImm0(SDValue &N, SDValue &R); 69 inline bool SelectAnyImm1(SDValue &N, SDValue &R); 70 inline bool SelectAnyImm2(SDValue &N, SDValue &R); 71 inline bool SelectAnyImm3(SDValue &N, SDValue &R); 72 getPassName()73 StringRef getPassName() const override { 74 return "Hexagon DAG->DAG Pattern Instruction Selection"; 75 } 76 77 // Generate a machine instruction node corresponding to the circ/brev 78 // load intrinsic. 79 MachineSDNode *LoadInstrForLoadIntrinsic(SDNode *IntN); 80 // Given the circ/brev load intrinsic and the already generated machine 81 // instruction, generate the appropriate store (that is a part of the 82 // intrinsic's functionality). 83 SDNode *StoreInstrForLoadIntrinsic(MachineSDNode *LoadN, SDNode *IntN); 84 85 void SelectFrameIndex(SDNode *N); 86 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 87 /// inline asm expressions. 88 bool SelectInlineAsmMemoryOperand(const SDValue &Op, 89 unsigned ConstraintID, 90 std::vector<SDValue> &OutOps) override; 91 bool tryLoadOfLoadIntrinsic(LoadSDNode *N); 92 bool SelectBrevLdIntrinsic(SDNode *IntN); 93 bool SelectNewCircIntrinsic(SDNode *IntN); 94 void SelectLoad(SDNode *N); 95 void SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl); 96 void SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl); 97 void SelectStore(SDNode *N); 98 void SelectSHL(SDNode *N); 99 void SelectZeroExtend(SDNode *N); 100 void SelectIntrinsicWChain(SDNode *N); 101 void SelectIntrinsicWOChain(SDNode *N); 102 void SelectConstant(SDNode *N); 103 void SelectConstantFP(SDNode *N); 104 void SelectV65Gather(SDNode *N); 105 void SelectV65GatherPred(SDNode *N); 106 void SelectHVXDualOutput(SDNode *N); 107 void SelectAddSubCarry(SDNode *N); 108 void SelectVAlign(SDNode *N); 109 void SelectVAlignAddr(SDNode *N); 110 void SelectTypecast(SDNode *N); 111 void SelectP2D(SDNode *N); 112 void SelectD2P(SDNode *N); 113 void SelectQ2V(SDNode *N); 114 void SelectV2Q(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 void SelectHvxShuffle(SDNode *N); 132 void SelectHvxRor(SDNode *N); 133 void SelectHvxVAlign(SDNode *N); 134 135 bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src); 136 bool isAlignedMemNode(const MemSDNode *N) const; 137 bool isSmallStackStore(const StoreSDNode *N) const; 138 bool isPositiveHalfWord(const SDNode *N) const; 139 bool hasOneUse(const SDNode *N) const; 140 141 // DAG preprocessing functions. 142 void ppSimplifyOrSelect0(std::vector<SDNode*> &&Nodes); 143 void ppAddrReorderAddShl(std::vector<SDNode*> &&Nodes); 144 void ppAddrRewriteAndSrl(std::vector<SDNode*> &&Nodes); 145 void ppHoistZextI1(std::vector<SDNode*> &&Nodes); 146 147 SmallDenseMap<SDNode *,int> RootWeights; 148 SmallDenseMap<SDNode *,int> RootHeights; 149 SmallDenseMap<const Value *,int> GAUsesInFunction; 150 int getWeight(SDNode *N); 151 int getHeight(SDNode *N); 152 SDValue getMultiplierForSHL(SDNode *N); 153 SDValue factorOutPowerOf2(SDValue V, unsigned Power); 154 unsigned getUsesInFunction(const Value *V); 155 SDValue balanceSubTree(SDNode *N, bool Factorize = false); 156 void rebalanceAddressTrees(); 157 }; // end HexagonDAGToDAGISel 158 } 159 160 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H 161