174 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8// Hexagon specific code to select Hexagon machine instructions for9// SelectionDAG operations.10//===----------------------------------------------------------------------===//11 12#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H13#define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H14 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 23namespace llvm {24class MachineFunction;25class HexagonInstrInfo;26class HexagonRegisterInfo;27 28class HexagonDAGToDAGISel : public SelectionDAGISel {29 const HexagonSubtarget *HST;30 const HexagonInstrInfo *HII;31 const HexagonRegisterInfo *HRI;32 33public:34 HexagonDAGToDAGISel() = delete;35 36 explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm,37 CodeGenOptLevel OptLevel)38 : SelectionDAGISel(tm, OptLevel), HST(nullptr), HII(nullptr),39 HRI(nullptr) {}40 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 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/brev75 // load intrinsic.76 MachineSDNode *LoadInstrForLoadIntrinsic(SDNode *IntN);77 // Given the circ/brev load intrinsic and the already generated machine78 // instruction, generate the appropriate store (that is a part of the79 // intrinsic's functionality).80 SDNode *StoreInstrForLoadIntrinsic(MachineSDNode *LoadN, SDNode *IntN);81 82 void SelectFrameIndex(SDNode *N);83 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for84 /// 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_DECL118 #include "HexagonGenDAGISel.inc"119 120private:121 // This is really only to get access to ReplaceNode (which is a protected122 // member). Any other members used by HvxSelector can be moved around to123 // make them accessible).124 friend struct HvxSelector;125 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 HexagonDAGToDAGISel164 165class HexagonDAGToDAGISelLegacy : public SelectionDAGISelLegacy {166public:167 static char ID;168 explicit HexagonDAGToDAGISelLegacy(HexagonTargetMachine &tm,169 CodeGenOptLevel OptLevel);170};171}172 173#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H174