1 //===-- HexagonISelDAGToDAG.h -----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
8 // Hexagon specific code to select Hexagon machine instructions for
9 // SelectionDAG operations.
10 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
13 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
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"
24 class MachineFunction
;
25 class HexagonInstrInfo
;
26 class HexagonRegisterInfo
;
28 class HexagonDAGToDAGISel
: public SelectionDAGISel
{
29 const HexagonSubtarget
*HST
;
30 const HexagonInstrInfo
*HII
;
31 const HexagonRegisterInfo
*HRI
;
34 HexagonDAGToDAGISel() = delete;
36 explicit HexagonDAGToDAGISel(HexagonTargetMachine
&tm
,
37 CodeGenOptLevel OptLevel
)
38 : SelectionDAGISel(tm
, OptLevel
), HST(nullptr), HII(nullptr),
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
);
51 bool ComplexPatternFuncMutatesDAG() const override
{
54 void PreprocessISelDAG() override
;
55 void emitFunctionEntryCode() override
;
57 void Select(SDNode
*N
) override
;
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
);
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
);
74 // Generate a machine instruction node corresponding to the circ/brev
76 MachineSDNode
*LoadInstrForLoadIntrinsic(SDNode
*IntN
);
77 // Given the circ/brev load intrinsic and the already generated machine
78 // instruction, generate the appropriate store (that is a part of the
79 // intrinsic's functionality).
80 SDNode
*StoreInstrForLoadIntrinsic(MachineSDNode
*LoadN
, SDNode
*IntN
);
82 void SelectFrameIndex(SDNode
*N
);
83 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
84 /// 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
);
116 // Include the declarations autogenerated from the selection patterns.
117 #define GET_DAGISEL_DECL
118 #include "HexagonGenDAGISel.inc"
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
;
126 SDValue
selectUndef(const SDLoc
&dl
, MVT ResTy
) {
127 SDNode
*U
= CurDAG
->getMachineNode(TargetOpcode::IMPLICIT_DEF
, dl
, ResTy
);
128 return SDValue(U
, 0);
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;
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
);
145 void SelectHvxExtractSubvector(SDNode
*N
);
146 void SelectHvxShuffle(SDNode
*N
);
147 void SelectHvxRor(SDNode
*N
);
148 void SelectHvxVAlign(SDNode
*N
);
150 // Function postprocessing.
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 HexagonDAGToDAGISel
165 class HexagonDAGToDAGISelLegacy
: public SelectionDAGISelLegacy
{
168 explicit HexagonDAGToDAGISelLegacy(HexagonTargetMachine
&tm
,
169 CodeGenOptLevel OptLevel
);
173 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H