HexagonISelDAGToDAG.h revision 360784
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
24namespace llvm {
25class MachineFunction;
26class HexagonInstrInfo;
27class HexagonRegisterInfo;
28class HexagonTargetLowering;
29
30class HexagonDAGToDAGISel : public SelectionDAGISel {
31  const HexagonSubtarget *HST;
32  const HexagonInstrInfo *HII;
33  const HexagonRegisterInfo *HRI;
34public:
35  explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm,
36                               CodeGenOpt::Level OptLevel)
37      : SelectionDAGISel(tm, OptLevel), HST(nullptr), HII(nullptr),
38        HRI(nullptr) {}
39
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    updateAligna();
47    return true;
48  }
49
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
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
121private:
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
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  // 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