File: | llvm/include/llvm/CodeGen/SelectionDAGNodes.h |
Warning: | line 1114, column 10 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- StatepointLowering.cpp - SDAGBuilder's statepoint code -------------===// | ||||||
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 | // | ||||||
9 | // This file includes support code use by SelectionDAGBuilder when lowering a | ||||||
10 | // statepoint sequence in SelectionDAG IR. | ||||||
11 | // | ||||||
12 | //===----------------------------------------------------------------------===// | ||||||
13 | |||||||
14 | #include "StatepointLowering.h" | ||||||
15 | #include "SelectionDAGBuilder.h" | ||||||
16 | #include "llvm/ADT/ArrayRef.h" | ||||||
17 | #include "llvm/ADT/None.h" | ||||||
18 | #include "llvm/ADT/Optional.h" | ||||||
19 | #include "llvm/ADT/STLExtras.h" | ||||||
20 | #include "llvm/ADT/SmallSet.h" | ||||||
21 | #include "llvm/ADT/Statistic.h" | ||||||
22 | #include "llvm/CodeGen/FunctionLoweringInfo.h" | ||||||
23 | #include "llvm/CodeGen/GCMetadata.h" | ||||||
24 | #include "llvm/CodeGen/ISDOpcodes.h" | ||||||
25 | #include "llvm/CodeGen/MachineFrameInfo.h" | ||||||
26 | #include "llvm/CodeGen/MachineFunction.h" | ||||||
27 | #include "llvm/CodeGen/MachineMemOperand.h" | ||||||
28 | #include "llvm/CodeGen/RuntimeLibcalls.h" | ||||||
29 | #include "llvm/CodeGen/SelectionDAG.h" | ||||||
30 | #include "llvm/CodeGen/StackMaps.h" | ||||||
31 | #include "llvm/CodeGen/TargetLowering.h" | ||||||
32 | #include "llvm/CodeGen/TargetOpcodes.h" | ||||||
33 | #include "llvm/IR/CallingConv.h" | ||||||
34 | #include "llvm/IR/DerivedTypes.h" | ||||||
35 | #include "llvm/IR/GCStrategy.h" | ||||||
36 | #include "llvm/IR/Instruction.h" | ||||||
37 | #include "llvm/IR/Instructions.h" | ||||||
38 | #include "llvm/IR/LLVMContext.h" | ||||||
39 | #include "llvm/IR/Statepoint.h" | ||||||
40 | #include "llvm/IR/Type.h" | ||||||
41 | #include "llvm/Support/Casting.h" | ||||||
42 | #include "llvm/Support/CommandLine.h" | ||||||
43 | #include "llvm/Support/MachineValueType.h" | ||||||
44 | #include "llvm/Target/TargetMachine.h" | ||||||
45 | #include "llvm/Target/TargetOptions.h" | ||||||
46 | #include <cassert> | ||||||
47 | #include <cstddef> | ||||||
48 | #include <cstdint> | ||||||
49 | #include <iterator> | ||||||
50 | #include <tuple> | ||||||
51 | #include <utility> | ||||||
52 | |||||||
53 | using namespace llvm; | ||||||
54 | |||||||
55 | #define DEBUG_TYPE"statepoint-lowering" "statepoint-lowering" | ||||||
56 | |||||||
57 | STATISTIC(NumSlotsAllocatedForStatepoints,static llvm::Statistic NumSlotsAllocatedForStatepoints = {"statepoint-lowering" , "NumSlotsAllocatedForStatepoints", "Number of stack slots allocated for statepoints" } | ||||||
58 | "Number of stack slots allocated for statepoints")static llvm::Statistic NumSlotsAllocatedForStatepoints = {"statepoint-lowering" , "NumSlotsAllocatedForStatepoints", "Number of stack slots allocated for statepoints" }; | ||||||
59 | STATISTIC(NumOfStatepoints, "Number of statepoint nodes encountered")static llvm::Statistic NumOfStatepoints = {"statepoint-lowering" , "NumOfStatepoints", "Number of statepoint nodes encountered" }; | ||||||
60 | STATISTIC(StatepointMaxSlotsRequired,static llvm::Statistic StatepointMaxSlotsRequired = {"statepoint-lowering" , "StatepointMaxSlotsRequired", "Maximum number of stack slots required for a singe statepoint" } | ||||||
61 | "Maximum number of stack slots required for a singe statepoint")static llvm::Statistic StatepointMaxSlotsRequired = {"statepoint-lowering" , "StatepointMaxSlotsRequired", "Maximum number of stack slots required for a singe statepoint" }; | ||||||
62 | |||||||
63 | cl::opt<bool> UseRegistersForDeoptValues( | ||||||
64 | "use-registers-for-deopt-values", cl::Hidden, cl::init(false), | ||||||
65 | cl::desc("Allow using registers for non pointer deopt args")); | ||||||
66 | |||||||
67 | cl::opt<bool> UseRegistersForGCPointersInLandingPad( | ||||||
68 | "use-registers-for-gc-values-in-landing-pad", cl::Hidden, cl::init(false), | ||||||
69 | cl::desc("Allow using registers for gc pointer in landing pad")); | ||||||
70 | |||||||
71 | cl::opt<unsigned> MaxRegistersForGCPointers( | ||||||
72 | "max-registers-for-gc-values", cl::Hidden, cl::init(0), | ||||||
73 | cl::desc("Max number of VRegs allowed to pass GC pointer meta args in")); | ||||||
74 | |||||||
75 | typedef FunctionLoweringInfo::StatepointRelocationRecord RecordType; | ||||||
76 | |||||||
77 | static void pushStackMapConstant(SmallVectorImpl<SDValue>& Ops, | ||||||
78 | SelectionDAGBuilder &Builder, uint64_t Value) { | ||||||
79 | SDLoc L = Builder.getCurSDLoc(); | ||||||
80 | Ops.push_back(Builder.DAG.getTargetConstant(StackMaps::ConstantOp, L, | ||||||
81 | MVT::i64)); | ||||||
82 | Ops.push_back(Builder.DAG.getTargetConstant(Value, L, MVT::i64)); | ||||||
83 | } | ||||||
84 | |||||||
85 | void StatepointLoweringState::startNewStatepoint(SelectionDAGBuilder &Builder) { | ||||||
86 | // Consistency check | ||||||
87 | assert(PendingGCRelocateCalls.empty() &&(static_cast <bool> (PendingGCRelocateCalls.empty() && "Trying to visit statepoint before finished processing previous one" ) ? void (0) : __assert_fail ("PendingGCRelocateCalls.empty() && \"Trying to visit statepoint before finished processing previous one\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 88, __extension__ __PRETTY_FUNCTION__)) | ||||||
88 | "Trying to visit statepoint before finished processing previous one")(static_cast <bool> (PendingGCRelocateCalls.empty() && "Trying to visit statepoint before finished processing previous one" ) ? void (0) : __assert_fail ("PendingGCRelocateCalls.empty() && \"Trying to visit statepoint before finished processing previous one\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 88, __extension__ __PRETTY_FUNCTION__)); | ||||||
89 | Locations.clear(); | ||||||
90 | NextSlotToAllocate = 0; | ||||||
91 | // Need to resize this on each safepoint - we need the two to stay in sync and | ||||||
92 | // the clear patterns of a SelectionDAGBuilder have no relation to | ||||||
93 | // FunctionLoweringInfo. Also need to ensure used bits get cleared. | ||||||
94 | AllocatedStackSlots.clear(); | ||||||
95 | AllocatedStackSlots.resize(Builder.FuncInfo.StatepointStackSlots.size()); | ||||||
96 | } | ||||||
97 | |||||||
98 | void StatepointLoweringState::clear() { | ||||||
99 | Locations.clear(); | ||||||
100 | AllocatedStackSlots.clear(); | ||||||
101 | assert(PendingGCRelocateCalls.empty() &&(static_cast <bool> (PendingGCRelocateCalls.empty() && "cleared before statepoint sequence completed") ? void (0) : __assert_fail ("PendingGCRelocateCalls.empty() && \"cleared before statepoint sequence completed\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 102, __extension__ __PRETTY_FUNCTION__)) | ||||||
102 | "cleared before statepoint sequence completed")(static_cast <bool> (PendingGCRelocateCalls.empty() && "cleared before statepoint sequence completed") ? void (0) : __assert_fail ("PendingGCRelocateCalls.empty() && \"cleared before statepoint sequence completed\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 102, __extension__ __PRETTY_FUNCTION__)); | ||||||
103 | } | ||||||
104 | |||||||
105 | SDValue | ||||||
106 | StatepointLoweringState::allocateStackSlot(EVT ValueType, | ||||||
107 | SelectionDAGBuilder &Builder) { | ||||||
108 | NumSlotsAllocatedForStatepoints++; | ||||||
109 | MachineFrameInfo &MFI = Builder.DAG.getMachineFunction().getFrameInfo(); | ||||||
110 | |||||||
111 | unsigned SpillSize = ValueType.getStoreSize(); | ||||||
112 | assert((SpillSize * 8) ==(static_cast <bool> ((SpillSize * 8) == (-8u & (7 + ValueType.getSizeInBits())) && "Size not in bytes?") ? void (0) : __assert_fail ("(SpillSize * 8) == (-8u & (7 + ValueType.getSizeInBits())) && \"Size not in bytes?\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 114, __extension__ __PRETTY_FUNCTION__)) | ||||||
113 | (-8u & (7 + ValueType.getSizeInBits())) && // Round up modulo 8.(static_cast <bool> ((SpillSize * 8) == (-8u & (7 + ValueType.getSizeInBits())) && "Size not in bytes?") ? void (0) : __assert_fail ("(SpillSize * 8) == (-8u & (7 + ValueType.getSizeInBits())) && \"Size not in bytes?\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 114, __extension__ __PRETTY_FUNCTION__)) | ||||||
114 | "Size not in bytes?")(static_cast <bool> ((SpillSize * 8) == (-8u & (7 + ValueType.getSizeInBits())) && "Size not in bytes?") ? void (0) : __assert_fail ("(SpillSize * 8) == (-8u & (7 + ValueType.getSizeInBits())) && \"Size not in bytes?\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 114, __extension__ __PRETTY_FUNCTION__)); | ||||||
115 | |||||||
116 | // First look for a previously created stack slot which is not in | ||||||
117 | // use (accounting for the fact arbitrary slots may already be | ||||||
118 | // reserved), or to create a new stack slot and use it. | ||||||
119 | |||||||
120 | const size_t NumSlots = AllocatedStackSlots.size(); | ||||||
121 | assert(NextSlotToAllocate <= NumSlots && "Broken invariant")(static_cast <bool> (NextSlotToAllocate <= NumSlots && "Broken invariant") ? void (0) : __assert_fail ("NextSlotToAllocate <= NumSlots && \"Broken invariant\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 121, __extension__ __PRETTY_FUNCTION__)); | ||||||
122 | |||||||
123 | assert(AllocatedStackSlots.size() ==(static_cast <bool> (AllocatedStackSlots.size() == Builder .FuncInfo.StatepointStackSlots.size() && "Broken invariant" ) ? void (0) : __assert_fail ("AllocatedStackSlots.size() == Builder.FuncInfo.StatepointStackSlots.size() && \"Broken invariant\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 125, __extension__ __PRETTY_FUNCTION__)) | ||||||
124 | Builder.FuncInfo.StatepointStackSlots.size() &&(static_cast <bool> (AllocatedStackSlots.size() == Builder .FuncInfo.StatepointStackSlots.size() && "Broken invariant" ) ? void (0) : __assert_fail ("AllocatedStackSlots.size() == Builder.FuncInfo.StatepointStackSlots.size() && \"Broken invariant\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 125, __extension__ __PRETTY_FUNCTION__)) | ||||||
125 | "Broken invariant")(static_cast <bool> (AllocatedStackSlots.size() == Builder .FuncInfo.StatepointStackSlots.size() && "Broken invariant" ) ? void (0) : __assert_fail ("AllocatedStackSlots.size() == Builder.FuncInfo.StatepointStackSlots.size() && \"Broken invariant\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 125, __extension__ __PRETTY_FUNCTION__)); | ||||||
126 | |||||||
127 | for (; NextSlotToAllocate < NumSlots; NextSlotToAllocate++) { | ||||||
128 | if (!AllocatedStackSlots.test(NextSlotToAllocate)) { | ||||||
129 | const int FI = Builder.FuncInfo.StatepointStackSlots[NextSlotToAllocate]; | ||||||
130 | if (MFI.getObjectSize(FI) == SpillSize) { | ||||||
131 | AllocatedStackSlots.set(NextSlotToAllocate); | ||||||
132 | // TODO: Is ValueType the right thing to use here? | ||||||
133 | return Builder.DAG.getFrameIndex(FI, ValueType); | ||||||
134 | } | ||||||
135 | } | ||||||
136 | } | ||||||
137 | |||||||
138 | // Couldn't find a free slot, so create a new one: | ||||||
139 | |||||||
140 | SDValue SpillSlot = Builder.DAG.CreateStackTemporary(ValueType); | ||||||
141 | const unsigned FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex(); | ||||||
142 | MFI.markAsStatepointSpillSlotObjectIndex(FI); | ||||||
143 | |||||||
144 | Builder.FuncInfo.StatepointStackSlots.push_back(FI); | ||||||
145 | AllocatedStackSlots.resize(AllocatedStackSlots.size()+1, true); | ||||||
146 | assert(AllocatedStackSlots.size() ==(static_cast <bool> (AllocatedStackSlots.size() == Builder .FuncInfo.StatepointStackSlots.size() && "Broken invariant" ) ? void (0) : __assert_fail ("AllocatedStackSlots.size() == Builder.FuncInfo.StatepointStackSlots.size() && \"Broken invariant\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 148, __extension__ __PRETTY_FUNCTION__)) | ||||||
147 | Builder.FuncInfo.StatepointStackSlots.size() &&(static_cast <bool> (AllocatedStackSlots.size() == Builder .FuncInfo.StatepointStackSlots.size() && "Broken invariant" ) ? void (0) : __assert_fail ("AllocatedStackSlots.size() == Builder.FuncInfo.StatepointStackSlots.size() && \"Broken invariant\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 148, __extension__ __PRETTY_FUNCTION__)) | ||||||
148 | "Broken invariant")(static_cast <bool> (AllocatedStackSlots.size() == Builder .FuncInfo.StatepointStackSlots.size() && "Broken invariant" ) ? void (0) : __assert_fail ("AllocatedStackSlots.size() == Builder.FuncInfo.StatepointStackSlots.size() && \"Broken invariant\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 148, __extension__ __PRETTY_FUNCTION__)); | ||||||
149 | |||||||
150 | StatepointMaxSlotsRequired.updateMax( | ||||||
151 | Builder.FuncInfo.StatepointStackSlots.size()); | ||||||
152 | |||||||
153 | return SpillSlot; | ||||||
154 | } | ||||||
155 | |||||||
156 | /// Utility function for reservePreviousStackSlotForValue. Tries to find | ||||||
157 | /// stack slot index to which we have spilled value for previous statepoints. | ||||||
158 | /// LookUpDepth specifies maximum DFS depth this function is allowed to look. | ||||||
159 | static Optional<int> findPreviousSpillSlot(const Value *Val, | ||||||
160 | SelectionDAGBuilder &Builder, | ||||||
161 | int LookUpDepth) { | ||||||
162 | // Can not look any further - give up now | ||||||
163 | if (LookUpDepth <= 0) | ||||||
164 | return None; | ||||||
165 | |||||||
166 | // Spill location is known for gc relocates | ||||||
167 | if (const auto *Relocate = dyn_cast<GCRelocateInst>(Val)) { | ||||||
168 | const auto &RelocationMap = | ||||||
169 | Builder.FuncInfo.StatepointRelocationMaps[Relocate->getStatepoint()]; | ||||||
170 | |||||||
171 | auto It = RelocationMap.find(Relocate->getDerivedPtr()); | ||||||
172 | if (It == RelocationMap.end()) | ||||||
173 | return None; | ||||||
174 | |||||||
175 | auto &Record = It->second; | ||||||
176 | if (Record.type != RecordType::Spill) | ||||||
177 | return None; | ||||||
178 | |||||||
179 | return Record.payload.FI; | ||||||
180 | } | ||||||
181 | |||||||
182 | // Look through bitcast instructions. | ||||||
183 | if (const BitCastInst *Cast = dyn_cast<BitCastInst>(Val)) | ||||||
184 | return findPreviousSpillSlot(Cast->getOperand(0), Builder, LookUpDepth - 1); | ||||||
185 | |||||||
186 | // Look through phi nodes | ||||||
187 | // All incoming values should have same known stack slot, otherwise result | ||||||
188 | // is unknown. | ||||||
189 | if (const PHINode *Phi = dyn_cast<PHINode>(Val)) { | ||||||
190 | Optional<int> MergedResult = None; | ||||||
191 | |||||||
192 | for (auto &IncomingValue : Phi->incoming_values()) { | ||||||
193 | Optional<int> SpillSlot = | ||||||
194 | findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth - 1); | ||||||
195 | if (!SpillSlot.hasValue()) | ||||||
196 | return None; | ||||||
197 | |||||||
198 | if (MergedResult.hasValue() && *MergedResult != *SpillSlot) | ||||||
199 | return None; | ||||||
200 | |||||||
201 | MergedResult = SpillSlot; | ||||||
202 | } | ||||||
203 | return MergedResult; | ||||||
204 | } | ||||||
205 | |||||||
206 | // TODO: We can do better for PHI nodes. In cases like this: | ||||||
207 | // ptr = phi(relocated_pointer, not_relocated_pointer) | ||||||
208 | // statepoint(ptr) | ||||||
209 | // We will return that stack slot for ptr is unknown. And later we might | ||||||
210 | // assign different stack slots for ptr and relocated_pointer. This limits | ||||||
211 | // llvm's ability to remove redundant stores. | ||||||
212 | // Unfortunately it's hard to accomplish in current infrastructure. | ||||||
213 | // We use this function to eliminate spill store completely, while | ||||||
214 | // in example we still need to emit store, but instead of any location | ||||||
215 | // we need to use special "preferred" location. | ||||||
216 | |||||||
217 | // TODO: handle simple updates. If a value is modified and the original | ||||||
218 | // value is no longer live, it would be nice to put the modified value in the | ||||||
219 | // same slot. This allows folding of the memory accesses for some | ||||||
220 | // instructions types (like an increment). | ||||||
221 | // statepoint (i) | ||||||
222 | // i1 = i+1 | ||||||
223 | // statepoint (i1) | ||||||
224 | // However we need to be careful for cases like this: | ||||||
225 | // statepoint(i) | ||||||
226 | // i1 = i+1 | ||||||
227 | // statepoint(i, i1) | ||||||
228 | // Here we want to reserve spill slot for 'i', but not for 'i+1'. If we just | ||||||
229 | // put handling of simple modifications in this function like it's done | ||||||
230 | // for bitcasts we might end up reserving i's slot for 'i+1' because order in | ||||||
231 | // which we visit values is unspecified. | ||||||
232 | |||||||
233 | // Don't know any information about this instruction | ||||||
234 | return None; | ||||||
235 | } | ||||||
236 | |||||||
237 | /// Return true if-and-only-if the given SDValue can be lowered as either a | ||||||
238 | /// constant argument or a stack reference. The key point is that the value | ||||||
239 | /// doesn't need to be spilled or tracked as a vreg use. | ||||||
240 | static bool willLowerDirectly(SDValue Incoming) { | ||||||
241 | // We are making an unchecked assumption that the frame size <= 2^16 as that | ||||||
242 | // is the largest offset which can be encoded in the stackmap format. | ||||||
243 | if (isa<FrameIndexSDNode>(Incoming)) | ||||||
244 | return true; | ||||||
245 | |||||||
246 | // The largest constant describeable in the StackMap format is 64 bits. | ||||||
247 | // Potential Optimization: Constants values are sign extended by consumer, | ||||||
248 | // and thus there are many constants of static type > 64 bits whose value | ||||||
249 | // happens to be sext(Con64) and could thus be lowered directly. | ||||||
250 | if (Incoming.getValueType().getSizeInBits() > 64) | ||||||
251 | return false; | ||||||
252 | |||||||
253 | return (isa<ConstantSDNode>(Incoming) || isa<ConstantFPSDNode>(Incoming) || | ||||||
254 | Incoming.isUndef()); | ||||||
255 | } | ||||||
256 | |||||||
257 | /// Try to find existing copies of the incoming values in stack slots used for | ||||||
258 | /// statepoint spilling. If we can find a spill slot for the incoming value, | ||||||
259 | /// mark that slot as allocated, and reuse the same slot for this safepoint. | ||||||
260 | /// This helps to avoid series of loads and stores that only serve to reshuffle | ||||||
261 | /// values on the stack between calls. | ||||||
262 | static void reservePreviousStackSlotForValue(const Value *IncomingValue, | ||||||
263 | SelectionDAGBuilder &Builder) { | ||||||
264 | SDValue Incoming = Builder.getValue(IncomingValue); | ||||||
265 | |||||||
266 | // If we won't spill this, we don't need to check for previously allocated | ||||||
267 | // stack slots. | ||||||
268 | if (willLowerDirectly(Incoming)) | ||||||
269 | return; | ||||||
270 | |||||||
271 | SDValue OldLocation = Builder.StatepointLowering.getLocation(Incoming); | ||||||
272 | if (OldLocation.getNode()) | ||||||
273 | // Duplicates in input | ||||||
274 | return; | ||||||
275 | |||||||
276 | const int LookUpDepth = 6; | ||||||
277 | Optional<int> Index = | ||||||
278 | findPreviousSpillSlot(IncomingValue, Builder, LookUpDepth); | ||||||
279 | if (!Index.hasValue()) | ||||||
280 | return; | ||||||
281 | |||||||
282 | const auto &StatepointSlots = Builder.FuncInfo.StatepointStackSlots; | ||||||
283 | |||||||
284 | auto SlotIt = find(StatepointSlots, *Index); | ||||||
285 | assert(SlotIt != StatepointSlots.end() &&(static_cast <bool> (SlotIt != StatepointSlots.end() && "Value spilled to the unknown stack slot") ? void (0) : __assert_fail ("SlotIt != StatepointSlots.end() && \"Value spilled to the unknown stack slot\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 286, __extension__ __PRETTY_FUNCTION__)) | ||||||
286 | "Value spilled to the unknown stack slot")(static_cast <bool> (SlotIt != StatepointSlots.end() && "Value spilled to the unknown stack slot") ? void (0) : __assert_fail ("SlotIt != StatepointSlots.end() && \"Value spilled to the unknown stack slot\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 286, __extension__ __PRETTY_FUNCTION__)); | ||||||
287 | |||||||
288 | // This is one of our dedicated lowering slots | ||||||
289 | const int Offset = std::distance(StatepointSlots.begin(), SlotIt); | ||||||
290 | if (Builder.StatepointLowering.isStackSlotAllocated(Offset)) { | ||||||
291 | // stack slot already assigned to someone else, can't use it! | ||||||
292 | // TODO: currently we reserve space for gc arguments after doing | ||||||
293 | // normal allocation for deopt arguments. We should reserve for | ||||||
294 | // _all_ deopt and gc arguments, then start allocating. This | ||||||
295 | // will prevent some moves being inserted when vm state changes, | ||||||
296 | // but gc state doesn't between two calls. | ||||||
297 | return; | ||||||
298 | } | ||||||
299 | // Reserve this stack slot | ||||||
300 | Builder.StatepointLowering.reserveStackSlot(Offset); | ||||||
301 | |||||||
302 | // Cache this slot so we find it when going through the normal | ||||||
303 | // assignment loop. | ||||||
304 | SDValue Loc = | ||||||
305 | Builder.DAG.getTargetFrameIndex(*Index, Builder.getFrameIndexTy()); | ||||||
306 | Builder.StatepointLowering.setLocation(Incoming, Loc); | ||||||
307 | } | ||||||
308 | |||||||
309 | /// Extract call from statepoint, lower it and return pointer to the | ||||||
310 | /// call node. Also update NodeMap so that getValue(statepoint) will | ||||||
311 | /// reference lowered call result | ||||||
312 | static std::pair<SDValue, SDNode *> lowerCallFromStatepointLoweringInfo( | ||||||
313 | SelectionDAGBuilder::StatepointLoweringInfo &SI, | ||||||
314 | SelectionDAGBuilder &Builder, SmallVectorImpl<SDValue> &PendingExports) { | ||||||
315 | SDValue ReturnValue, CallEndVal; | ||||||
316 | std::tie(ReturnValue, CallEndVal) = | ||||||
317 | Builder.lowerInvokable(SI.CLI, SI.EHPadBB); | ||||||
318 | SDNode *CallEnd = CallEndVal.getNode(); | ||||||
319 | |||||||
320 | // Get a call instruction from the call sequence chain. Tail calls are not | ||||||
321 | // allowed. The following code is essentially reverse engineering X86's | ||||||
322 | // LowerCallTo. | ||||||
323 | // | ||||||
324 | // We are expecting DAG to have the following form: | ||||||
325 | // | ||||||
326 | // ch = eh_label (only in case of invoke statepoint) | ||||||
327 | // ch, glue = callseq_start ch | ||||||
328 | // ch, glue = X86::Call ch, glue | ||||||
329 | // ch, glue = callseq_end ch, glue | ||||||
330 | // get_return_value ch, glue | ||||||
331 | // | ||||||
332 | // get_return_value can either be a sequence of CopyFromReg instructions | ||||||
333 | // to grab the return value from the return register(s), or it can be a LOAD | ||||||
334 | // to load a value returned by reference via a stack slot. | ||||||
335 | |||||||
336 | bool HasDef = !SI.CLI.RetTy->isVoidTy(); | ||||||
337 | if (HasDef) { | ||||||
338 | if (CallEnd->getOpcode() == ISD::LOAD) | ||||||
339 | CallEnd = CallEnd->getOperand(0).getNode(); | ||||||
340 | else | ||||||
341 | while (CallEnd->getOpcode() == ISD::CopyFromReg) | ||||||
342 | CallEnd = CallEnd->getOperand(0).getNode(); | ||||||
343 | } | ||||||
344 | |||||||
345 | assert(CallEnd->getOpcode() == ISD::CALLSEQ_END && "expected!")(static_cast <bool> (CallEnd->getOpcode() == ISD::CALLSEQ_END && "expected!") ? void (0) : __assert_fail ("CallEnd->getOpcode() == ISD::CALLSEQ_END && \"expected!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 345, __extension__ __PRETTY_FUNCTION__)); | ||||||
346 | return std::make_pair(ReturnValue, CallEnd->getOperand(0).getNode()); | ||||||
347 | } | ||||||
348 | |||||||
349 | static MachineMemOperand* getMachineMemOperand(MachineFunction &MF, | ||||||
350 | FrameIndexSDNode &FI) { | ||||||
351 | auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FI.getIndex()); | ||||||
352 | auto MMOFlags = MachineMemOperand::MOStore | | ||||||
353 | MachineMemOperand::MOLoad | MachineMemOperand::MOVolatile; | ||||||
354 | auto &MFI = MF.getFrameInfo(); | ||||||
355 | return MF.getMachineMemOperand(PtrInfo, MMOFlags, | ||||||
356 | MFI.getObjectSize(FI.getIndex()), | ||||||
357 | MFI.getObjectAlign(FI.getIndex())); | ||||||
358 | } | ||||||
359 | |||||||
360 | /// Spill a value incoming to the statepoint. It might be either part of | ||||||
361 | /// vmstate | ||||||
362 | /// or gcstate. In both cases unconditionally spill it on the stack unless it | ||||||
363 | /// is a null constant. Return pair with first element being frame index | ||||||
364 | /// containing saved value and second element with outgoing chain from the | ||||||
365 | /// emitted store | ||||||
366 | static std::tuple<SDValue, SDValue, MachineMemOperand*> | ||||||
367 | spillIncomingStatepointValue(SDValue Incoming, SDValue Chain, | ||||||
368 | SelectionDAGBuilder &Builder) { | ||||||
369 | SDValue Loc = Builder.StatepointLowering.getLocation(Incoming); | ||||||
370 | MachineMemOperand* MMO = nullptr; | ||||||
371 | |||||||
372 | // Emit new store if we didn't do it for this ptr before | ||||||
373 | if (!Loc.getNode()) { | ||||||
374 | Loc = Builder.StatepointLowering.allocateStackSlot(Incoming.getValueType(), | ||||||
375 | Builder); | ||||||
376 | int Index = cast<FrameIndexSDNode>(Loc)->getIndex(); | ||||||
377 | // We use TargetFrameIndex so that isel will not select it into LEA | ||||||
378 | Loc = Builder.DAG.getTargetFrameIndex(Index, Builder.getFrameIndexTy()); | ||||||
379 | |||||||
380 | // Right now we always allocate spill slots that are of the same | ||||||
381 | // size as the value we're about to spill (the size of spillee can | ||||||
382 | // vary since we spill vectors of pointers too). At some point we | ||||||
383 | // can consider allowing spills of smaller values to larger slots | ||||||
384 | // (i.e. change the '==' in the assert below to a '>='). | ||||||
385 | MachineFrameInfo &MFI = Builder.DAG.getMachineFunction().getFrameInfo(); | ||||||
386 | assert((MFI.getObjectSize(Index) * 8) ==(static_cast <bool> ((MFI.getObjectSize(Index) * 8) == ( -8 & (7 + (int64_t)Incoming.getValueSizeInBits())) && "Bad spill: stack slot does not match!") ? void (0) : __assert_fail ("(MFI.getObjectSize(Index) * 8) == (-8 & (7 + (int64_t)Incoming.getValueSizeInBits())) && \"Bad spill: stack slot does not match!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 389, __extension__ __PRETTY_FUNCTION__)) | ||||||
387 | (-8 & (7 + // Round up modulo 8.(static_cast <bool> ((MFI.getObjectSize(Index) * 8) == ( -8 & (7 + (int64_t)Incoming.getValueSizeInBits())) && "Bad spill: stack slot does not match!") ? void (0) : __assert_fail ("(MFI.getObjectSize(Index) * 8) == (-8 & (7 + (int64_t)Incoming.getValueSizeInBits())) && \"Bad spill: stack slot does not match!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 389, __extension__ __PRETTY_FUNCTION__)) | ||||||
388 | (int64_t)Incoming.getValueSizeInBits())) &&(static_cast <bool> ((MFI.getObjectSize(Index) * 8) == ( -8 & (7 + (int64_t)Incoming.getValueSizeInBits())) && "Bad spill: stack slot does not match!") ? void (0) : __assert_fail ("(MFI.getObjectSize(Index) * 8) == (-8 & (7 + (int64_t)Incoming.getValueSizeInBits())) && \"Bad spill: stack slot does not match!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 389, __extension__ __PRETTY_FUNCTION__)) | ||||||
389 | "Bad spill: stack slot does not match!")(static_cast <bool> ((MFI.getObjectSize(Index) * 8) == ( -8 & (7 + (int64_t)Incoming.getValueSizeInBits())) && "Bad spill: stack slot does not match!") ? void (0) : __assert_fail ("(MFI.getObjectSize(Index) * 8) == (-8 & (7 + (int64_t)Incoming.getValueSizeInBits())) && \"Bad spill: stack slot does not match!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 389, __extension__ __PRETTY_FUNCTION__)); | ||||||
390 | |||||||
391 | // Note: Using the alignment of the spill slot (rather than the abi or | ||||||
392 | // preferred alignment) is required for correctness when dealing with spill | ||||||
393 | // slots with preferred alignments larger than frame alignment.. | ||||||
394 | auto &MF = Builder.DAG.getMachineFunction(); | ||||||
395 | auto PtrInfo = MachinePointerInfo::getFixedStack(MF, Index); | ||||||
396 | auto *StoreMMO = MF.getMachineMemOperand( | ||||||
397 | PtrInfo, MachineMemOperand::MOStore, MFI.getObjectSize(Index), | ||||||
398 | MFI.getObjectAlign(Index)); | ||||||
399 | Chain = Builder.DAG.getStore(Chain, Builder.getCurSDLoc(), Incoming, Loc, | ||||||
400 | StoreMMO); | ||||||
401 | |||||||
402 | MMO = getMachineMemOperand(MF, *cast<FrameIndexSDNode>(Loc)); | ||||||
403 | |||||||
404 | Builder.StatepointLowering.setLocation(Incoming, Loc); | ||||||
405 | } | ||||||
406 | |||||||
407 | assert(Loc.getNode())(static_cast <bool> (Loc.getNode()) ? void (0) : __assert_fail ("Loc.getNode()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 407, __extension__ __PRETTY_FUNCTION__)); | ||||||
408 | return std::make_tuple(Loc, Chain, MMO); | ||||||
409 | } | ||||||
410 | |||||||
411 | /// Lower a single value incoming to a statepoint node. This value can be | ||||||
412 | /// either a deopt value or a gc value, the handling is the same. We special | ||||||
413 | /// case constants and allocas, then fall back to spilling if required. | ||||||
414 | static void | ||||||
415 | lowerIncomingStatepointValue(SDValue Incoming, bool RequireSpillSlot, | ||||||
416 | SmallVectorImpl<SDValue> &Ops, | ||||||
417 | SmallVectorImpl<MachineMemOperand *> &MemRefs, | ||||||
418 | SelectionDAGBuilder &Builder) { | ||||||
419 | |||||||
420 | if (willLowerDirectly(Incoming)) { | ||||||
421 | if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { | ||||||
422 | // This handles allocas as arguments to the statepoint (this is only | ||||||
423 | // really meaningful for a deopt value. For GC, we'd be trying to | ||||||
424 | // relocate the address of the alloca itself?) | ||||||
425 | assert(Incoming.getValueType() == Builder.getFrameIndexTy() &&(static_cast <bool> (Incoming.getValueType() == Builder .getFrameIndexTy() && "Incoming value is a frame index!" ) ? void (0) : __assert_fail ("Incoming.getValueType() == Builder.getFrameIndexTy() && \"Incoming value is a frame index!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 426, __extension__ __PRETTY_FUNCTION__)) | ||||||
426 | "Incoming value is a frame index!")(static_cast <bool> (Incoming.getValueType() == Builder .getFrameIndexTy() && "Incoming value is a frame index!" ) ? void (0) : __assert_fail ("Incoming.getValueType() == Builder.getFrameIndexTy() && \"Incoming value is a frame index!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 426, __extension__ __PRETTY_FUNCTION__)); | ||||||
427 | Ops.push_back(Builder.DAG.getTargetFrameIndex(FI->getIndex(), | ||||||
428 | Builder.getFrameIndexTy())); | ||||||
429 | |||||||
430 | auto &MF = Builder.DAG.getMachineFunction(); | ||||||
431 | auto *MMO = getMachineMemOperand(MF, *FI); | ||||||
432 | MemRefs.push_back(MMO); | ||||||
433 | return; | ||||||
434 | } | ||||||
435 | |||||||
436 | assert(Incoming.getValueType().getSizeInBits() <= 64)(static_cast <bool> (Incoming.getValueType().getSizeInBits () <= 64) ? void (0) : __assert_fail ("Incoming.getValueType().getSizeInBits() <= 64" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 436, __extension__ __PRETTY_FUNCTION__)); | ||||||
437 | |||||||
438 | if (Incoming.isUndef()) { | ||||||
439 | // Put an easily recognized constant that's unlikely to be a valid | ||||||
440 | // value so that uses of undef by the consumer of the stackmap is | ||||||
441 | // easily recognized. This is legal since the compiler is always | ||||||
442 | // allowed to chose an arbitrary value for undef. | ||||||
443 | pushStackMapConstant(Ops, Builder, 0xFEFEFEFE); | ||||||
444 | return; | ||||||
445 | } | ||||||
446 | |||||||
447 | // If the original value was a constant, make sure it gets recorded as | ||||||
448 | // such in the stackmap. This is required so that the consumer can | ||||||
449 | // parse any internal format to the deopt state. It also handles null | ||||||
450 | // pointers and other constant pointers in GC states. | ||||||
451 | if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Incoming)) { | ||||||
452 | pushStackMapConstant(Ops, Builder, C->getSExtValue()); | ||||||
453 | return; | ||||||
454 | } else if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Incoming)) { | ||||||
455 | pushStackMapConstant(Ops, Builder, | ||||||
456 | C->getValueAPF().bitcastToAPInt().getZExtValue()); | ||||||
457 | return; | ||||||
458 | } | ||||||
459 | |||||||
460 | llvm_unreachable("unhandled direct lowering case")::llvm::llvm_unreachable_internal("unhandled direct lowering case" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 460); | ||||||
461 | } | ||||||
462 | |||||||
463 | |||||||
464 | |||||||
465 | if (!RequireSpillSlot) { | ||||||
466 | // If this value is live in (not live-on-return, or live-through), we can | ||||||
467 | // treat it the same way patchpoint treats it's "live in" values. We'll | ||||||
468 | // end up folding some of these into stack references, but they'll be | ||||||
469 | // handled by the register allocator. Note that we do not have the notion | ||||||
470 | // of a late use so these values might be placed in registers which are | ||||||
471 | // clobbered by the call. This is fine for live-in. For live-through | ||||||
472 | // fix-up pass should be executed to force spilling of such registers. | ||||||
473 | Ops.push_back(Incoming); | ||||||
474 | } else { | ||||||
475 | // Otherwise, locate a spill slot and explicitly spill it so it can be | ||||||
476 | // found by the runtime later. Note: We know all of these spills are | ||||||
477 | // independent, but don't bother to exploit that chain wise. DAGCombine | ||||||
478 | // will happily do so as needed, so doing it here would be a small compile | ||||||
479 | // time win at most. | ||||||
480 | SDValue Chain = Builder.getRoot(); | ||||||
481 | auto Res = spillIncomingStatepointValue(Incoming, Chain, Builder); | ||||||
482 | Ops.push_back(std::get<0>(Res)); | ||||||
483 | if (auto *MMO = std::get<2>(Res)) | ||||||
484 | MemRefs.push_back(MMO); | ||||||
485 | Chain = std::get<1>(Res);; | ||||||
486 | Builder.DAG.setRoot(Chain); | ||||||
487 | } | ||||||
488 | |||||||
489 | } | ||||||
490 | |||||||
491 | /// Return true if value V represents the GC value. The behavior is conservative | ||||||
492 | /// in case it is not sure that value is not GC the function returns true. | ||||||
493 | static bool isGCValue(const Value *V, SelectionDAGBuilder &Builder) { | ||||||
494 | auto *Ty = V->getType(); | ||||||
495 | if (!Ty->isPtrOrPtrVectorTy()) | ||||||
496 | return false; | ||||||
497 | if (auto *GFI = Builder.GFI) | ||||||
498 | if (auto IsManaged = GFI->getStrategy().isGCManagedPointer(Ty)) | ||||||
499 | return *IsManaged; | ||||||
500 | return true; // conservative | ||||||
501 | } | ||||||
502 | |||||||
503 | /// Lower deopt state and gc pointer arguments of the statepoint. The actual | ||||||
504 | /// lowering is described in lowerIncomingStatepointValue. This function is | ||||||
505 | /// responsible for lowering everything in the right position and playing some | ||||||
506 | /// tricks to avoid redundant stack manipulation where possible. On | ||||||
507 | /// completion, 'Ops' will contain ready to use operands for machine code | ||||||
508 | /// statepoint. The chain nodes will have already been created and the DAG root | ||||||
509 | /// will be set to the last value spilled (if any were). | ||||||
510 | static void | ||||||
511 | lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops, | ||||||
512 | SmallVectorImpl<MachineMemOperand *> &MemRefs, | ||||||
513 | SmallVectorImpl<SDValue> &GCPtrs, | ||||||
514 | DenseMap<SDValue, int> &LowerAsVReg, | ||||||
515 | SelectionDAGBuilder::StatepointLoweringInfo &SI, | ||||||
516 | SelectionDAGBuilder &Builder) { | ||||||
517 | // Lower the deopt and gc arguments for this statepoint. Layout will be: | ||||||
518 | // deopt argument length, deopt arguments.., gc arguments... | ||||||
519 | #ifndef NDEBUG | ||||||
520 | if (auto *GFI = Builder.GFI) { | ||||||
| |||||||
521 | // Check that each of the gc pointer and bases we've gotten out of the | ||||||
522 | // safepoint is something the strategy thinks might be a pointer (or vector | ||||||
523 | // of pointers) into the GC heap. This is basically just here to help catch | ||||||
524 | // errors during statepoint insertion. TODO: This should actually be in the | ||||||
525 | // Verifier, but we can't get to the GCStrategy from there (yet). | ||||||
526 | GCStrategy &S = GFI->getStrategy(); | ||||||
527 | for (const Value *V : SI.Bases) { | ||||||
528 | auto Opt = S.isGCManagedPointer(V->getType()->getScalarType()); | ||||||
529 | if (Opt.hasValue()) { | ||||||
530 | assert(Opt.getValue() &&(static_cast <bool> (Opt.getValue() && "non gc managed base pointer found in statepoint" ) ? void (0) : __assert_fail ("Opt.getValue() && \"non gc managed base pointer found in statepoint\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 531, __extension__ __PRETTY_FUNCTION__)) | ||||||
531 | "non gc managed base pointer found in statepoint")(static_cast <bool> (Opt.getValue() && "non gc managed base pointer found in statepoint" ) ? void (0) : __assert_fail ("Opt.getValue() && \"non gc managed base pointer found in statepoint\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 531, __extension__ __PRETTY_FUNCTION__)); | ||||||
532 | } | ||||||
533 | } | ||||||
534 | for (const Value *V : SI.Ptrs) { | ||||||
535 | auto Opt = S.isGCManagedPointer(V->getType()->getScalarType()); | ||||||
536 | if (Opt.hasValue()) { | ||||||
537 | assert(Opt.getValue() &&(static_cast <bool> (Opt.getValue() && "non gc managed derived pointer found in statepoint" ) ? void (0) : __assert_fail ("Opt.getValue() && \"non gc managed derived pointer found in statepoint\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 538, __extension__ __PRETTY_FUNCTION__)) | ||||||
538 | "non gc managed derived pointer found in statepoint")(static_cast <bool> (Opt.getValue() && "non gc managed derived pointer found in statepoint" ) ? void (0) : __assert_fail ("Opt.getValue() && \"non gc managed derived pointer found in statepoint\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 538, __extension__ __PRETTY_FUNCTION__)); | ||||||
539 | } | ||||||
540 | } | ||||||
541 | assert(SI.Bases.size() == SI.Ptrs.size() && "Pointer without base!")(static_cast <bool> (SI.Bases.size() == SI.Ptrs.size() && "Pointer without base!") ? void (0) : __assert_fail ("SI.Bases.size() == SI.Ptrs.size() && \"Pointer without base!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 541, __extension__ __PRETTY_FUNCTION__)); | ||||||
542 | } else { | ||||||
543 | assert(SI.Bases.empty() && "No gc specified, so cannot relocate pointers!")(static_cast <bool> (SI.Bases.empty() && "No gc specified, so cannot relocate pointers!" ) ? void (0) : __assert_fail ("SI.Bases.empty() && \"No gc specified, so cannot relocate pointers!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 543, __extension__ __PRETTY_FUNCTION__)); | ||||||
544 | assert(SI.Ptrs.empty() && "No gc specified, so cannot relocate pointers!")(static_cast <bool> (SI.Ptrs.empty() && "No gc specified, so cannot relocate pointers!" ) ? void (0) : __assert_fail ("SI.Ptrs.empty() && \"No gc specified, so cannot relocate pointers!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 544, __extension__ __PRETTY_FUNCTION__)); | ||||||
545 | } | ||||||
546 | #endif | ||||||
547 | |||||||
548 | // Figure out what lowering strategy we're going to use for each part | ||||||
549 | // Note: Is is conservatively correct to lower both "live-in" and "live-out" | ||||||
550 | // as "live-through". A "live-through" variable is one which is "live-in", | ||||||
551 | // "live-out", and live throughout the lifetime of the call (i.e. we can find | ||||||
552 | // it from any PC within the transitive callee of the statepoint). In | ||||||
553 | // particular, if the callee spills callee preserved registers we may not | ||||||
554 | // be able to find a value placed in that register during the call. This is | ||||||
555 | // fine for live-out, but not for live-through. If we were willing to make | ||||||
556 | // assumptions about the code generator producing the callee, we could | ||||||
557 | // potentially allow live-through values in callee saved registers. | ||||||
558 | const bool LiveInDeopt = | ||||||
559 | SI.StatepointFlags & (uint64_t)StatepointFlags::DeoptLiveIn; | ||||||
560 | |||||||
561 | // Decide which deriver pointers will go on VRegs | ||||||
562 | unsigned MaxVRegPtrs = MaxRegistersForGCPointers.getValue(); | ||||||
563 | |||||||
564 | // Pointers used on exceptional path of invoke statepoint. | ||||||
565 | // We cannot assing them to VRegs. | ||||||
566 | SmallSet<SDValue, 8> LPadPointers; | ||||||
567 | if (!UseRegistersForGCPointersInLandingPad) | ||||||
568 | if (auto *StInvoke = dyn_cast_or_null<InvokeInst>(SI.StatepointInstr)) { | ||||||
569 | LandingPadInst *LPI = StInvoke->getLandingPadInst(); | ||||||
570 | for (auto *Relocate : SI.GCRelocates) | ||||||
571 | if (Relocate->getOperand(0) == LPI) { | ||||||
572 | LPadPointers.insert(Builder.getValue(Relocate->getBasePtr())); | ||||||
573 | LPadPointers.insert(Builder.getValue(Relocate->getDerivedPtr())); | ||||||
574 | } | ||||||
575 | } | ||||||
576 | |||||||
577 | LLVM_DEBUG(dbgs() << "Deciding how to lower GC Pointers:\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("statepoint-lowering")) { dbgs() << "Deciding how to lower GC Pointers:\n" ; } } while (false); | ||||||
578 | |||||||
579 | // List of unique lowered GC Pointer values. | ||||||
580 | SmallSetVector<SDValue, 16> LoweredGCPtrs; | ||||||
581 | // Map lowered GC Pointer value to the index in above vector | ||||||
582 | DenseMap<SDValue, unsigned> GCPtrIndexMap; | ||||||
583 | |||||||
584 | unsigned CurNumVRegs = 0; | ||||||
585 | |||||||
586 | auto canPassGCPtrOnVReg = [&](SDValue SD) { | ||||||
587 | if (SD.getValueType().isVector()) | ||||||
588 | return false; | ||||||
589 | if (LPadPointers.count(SD)) | ||||||
590 | return false; | ||||||
591 | return !willLowerDirectly(SD); | ||||||
592 | }; | ||||||
593 | |||||||
594 | auto processGCPtr = [&](const Value *V) { | ||||||
595 | SDValue PtrSD = Builder.getValue(V); | ||||||
596 | if (!LoweredGCPtrs.insert(PtrSD)) | ||||||
597 | return; // skip duplicates | ||||||
598 | GCPtrIndexMap[PtrSD] = LoweredGCPtrs.size() - 1; | ||||||
599 | |||||||
600 | assert(!LowerAsVReg.count(PtrSD) && "must not have been seen")(static_cast <bool> (!LowerAsVReg.count(PtrSD) && "must not have been seen") ? void (0) : __assert_fail ("!LowerAsVReg.count(PtrSD) && \"must not have been seen\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 600, __extension__ __PRETTY_FUNCTION__)); | ||||||
601 | if (LowerAsVReg.size() == MaxVRegPtrs) | ||||||
602 | return; | ||||||
603 | assert(V->getType()->isVectorTy() == PtrSD.getValueType().isVector() &&(static_cast <bool> (V->getType()->isVectorTy() == PtrSD.getValueType().isVector() && "IR and SD types disagree" ) ? void (0) : __assert_fail ("V->getType()->isVectorTy() == PtrSD.getValueType().isVector() && \"IR and SD types disagree\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 604, __extension__ __PRETTY_FUNCTION__)) | ||||||
604 | "IR and SD types disagree")(static_cast <bool> (V->getType()->isVectorTy() == PtrSD.getValueType().isVector() && "IR and SD types disagree" ) ? void (0) : __assert_fail ("V->getType()->isVectorTy() == PtrSD.getValueType().isVector() && \"IR and SD types disagree\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 604, __extension__ __PRETTY_FUNCTION__)); | ||||||
605 | if (!canPassGCPtrOnVReg(PtrSD)) { | ||||||
606 | LLVM_DEBUG(dbgs() << "direct/spill "; PtrSD.dump(&Builder.DAG))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("statepoint-lowering")) { dbgs() << "direct/spill "; PtrSD .dump(&Builder.DAG); } } while (false); | ||||||
607 | return; | ||||||
608 | } | ||||||
609 | LLVM_DEBUG(dbgs() << "vreg "; PtrSD.dump(&Builder.DAG))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("statepoint-lowering")) { dbgs() << "vreg "; PtrSD.dump (&Builder.DAG); } } while (false); | ||||||
610 | LowerAsVReg[PtrSD] = CurNumVRegs++; | ||||||
611 | }; | ||||||
612 | |||||||
613 | // Process derived pointers first to give them more chance to go on VReg. | ||||||
614 | for (const Value *V : SI.Ptrs) | ||||||
615 | processGCPtr(V); | ||||||
616 | for (const Value *V : SI.Bases) | ||||||
617 | processGCPtr(V); | ||||||
618 | |||||||
619 | LLVM_DEBUG(dbgs() << LowerAsVReg.size() << " pointers will go in vregs\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("statepoint-lowering")) { dbgs() << LowerAsVReg.size() << " pointers will go in vregs\n"; } } while (false); | ||||||
620 | |||||||
621 | auto requireSpillSlot = [&](const Value *V) { | ||||||
622 | if (!Builder.DAG.getTargetLoweringInfo().isTypeLegal( | ||||||
623 | Builder.getValue(V).getValueType())) | ||||||
624 | return true; | ||||||
625 | if (isGCValue(V, Builder)) | ||||||
626 | return !LowerAsVReg.count(Builder.getValue(V)); | ||||||
627 | return !(LiveInDeopt || UseRegistersForDeoptValues); | ||||||
628 | }; | ||||||
629 | |||||||
630 | // Before we actually start lowering (and allocating spill slots for values), | ||||||
631 | // reserve any stack slots which we judge to be profitable to reuse for a | ||||||
632 | // particular value. This is purely an optimization over the code below and | ||||||
633 | // doesn't change semantics at all. It is important for performance that we | ||||||
634 | // reserve slots for both deopt and gc values before lowering either. | ||||||
635 | for (const Value *V : SI.DeoptState) { | ||||||
636 | if (requireSpillSlot(V)) | ||||||
637 | reservePreviousStackSlotForValue(V, Builder); | ||||||
638 | } | ||||||
639 | |||||||
640 | for (const Value *V : SI.Ptrs) { | ||||||
641 | SDValue SDV = Builder.getValue(V); | ||||||
642 | if (!LowerAsVReg.count(SDV)) | ||||||
643 | reservePreviousStackSlotForValue(V, Builder); | ||||||
644 | } | ||||||
645 | |||||||
646 | for (const Value *V : SI.Bases) { | ||||||
647 | SDValue SDV = Builder.getValue(V); | ||||||
648 | if (!LowerAsVReg.count(SDV)) | ||||||
649 | reservePreviousStackSlotForValue(V, Builder); | ||||||
650 | } | ||||||
651 | |||||||
652 | // First, prefix the list with the number of unique values to be | ||||||
653 | // lowered. Note that this is the number of *Values* not the | ||||||
654 | // number of SDValues required to lower them. | ||||||
655 | const int NumVMSArgs = SI.DeoptState.size(); | ||||||
656 | pushStackMapConstant(Ops, Builder, NumVMSArgs); | ||||||
657 | |||||||
658 | // The vm state arguments are lowered in an opaque manner. We do not know | ||||||
659 | // what type of values are contained within. | ||||||
660 | LLVM_DEBUG(dbgs() << "Lowering deopt state\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("statepoint-lowering")) { dbgs() << "Lowering deopt state\n" ; } } while (false); | ||||||
661 | for (const Value *V : SI.DeoptState) { | ||||||
662 | SDValue Incoming; | ||||||
663 | // If this is a function argument at a static frame index, generate it as | ||||||
664 | // the frame index. | ||||||
665 | if (const Argument *Arg
| ||||||
666 | int FI = Builder.FuncInfo.getArgumentFrameIndex(Arg); | ||||||
667 | if (FI != INT_MAX2147483647) | ||||||
668 | Incoming = Builder.DAG.getFrameIndex(FI, Builder.getFrameIndexTy()); | ||||||
669 | } | ||||||
670 | if (!Incoming.getNode()) | ||||||
671 | Incoming = Builder.getValue(V); | ||||||
672 | LLVM_DEBUG(dbgs() << "Value " << *Vdo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("statepoint-lowering")) { dbgs() << "Value " << * V << " requireSpillSlot = " << requireSpillSlot(V ) << "\n"; } } while (false) | ||||||
673 | << " requireSpillSlot = " << requireSpillSlot(V) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("statepoint-lowering")) { dbgs() << "Value " << * V << " requireSpillSlot = " << requireSpillSlot(V ) << "\n"; } } while (false); | ||||||
674 | lowerIncomingStatepointValue(Incoming, requireSpillSlot(V), Ops, MemRefs, | ||||||
675 | Builder); | ||||||
676 | } | ||||||
677 | |||||||
678 | // Finally, go ahead and lower all the gc arguments. | ||||||
679 | pushStackMapConstant(Ops, Builder, LoweredGCPtrs.size()); | ||||||
680 | for (SDValue SDV : LoweredGCPtrs) | ||||||
681 | lowerIncomingStatepointValue(SDV, !LowerAsVReg.count(SDV), Ops, MemRefs, | ||||||
682 | Builder); | ||||||
683 | |||||||
684 | // Copy to out vector. LoweredGCPtrs will be empty after this point. | ||||||
685 | GCPtrs = LoweredGCPtrs.takeVector(); | ||||||
686 | |||||||
687 | // If there are any explicit spill slots passed to the statepoint, record | ||||||
688 | // them, but otherwise do not do anything special. These are user provided | ||||||
689 | // allocas and give control over placement to the consumer. In this case, | ||||||
690 | // it is the contents of the slot which may get updated, not the pointer to | ||||||
691 | // the alloca | ||||||
692 | SmallVector<SDValue, 4> Allocas; | ||||||
693 | for (Value *V : SI.GCArgs) { | ||||||
694 | SDValue Incoming = Builder.getValue(V); | ||||||
695 | if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) { | ||||||
696 | // This handles allocas as arguments to the statepoint | ||||||
697 | assert(Incoming.getValueType() == Builder.getFrameIndexTy() &&(static_cast <bool> (Incoming.getValueType() == Builder .getFrameIndexTy() && "Incoming value is a frame index!" ) ? void (0) : __assert_fail ("Incoming.getValueType() == Builder.getFrameIndexTy() && \"Incoming value is a frame index!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 698, __extension__ __PRETTY_FUNCTION__)) | ||||||
698 | "Incoming value is a frame index!")(static_cast <bool> (Incoming.getValueType() == Builder .getFrameIndexTy() && "Incoming value is a frame index!" ) ? void (0) : __assert_fail ("Incoming.getValueType() == Builder.getFrameIndexTy() && \"Incoming value is a frame index!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 698, __extension__ __PRETTY_FUNCTION__)); | ||||||
699 | Allocas.push_back(Builder.DAG.getTargetFrameIndex( | ||||||
700 | FI->getIndex(), Builder.getFrameIndexTy())); | ||||||
701 | |||||||
702 | auto &MF = Builder.DAG.getMachineFunction(); | ||||||
703 | auto *MMO = getMachineMemOperand(MF, *FI); | ||||||
704 | MemRefs.push_back(MMO); | ||||||
705 | } | ||||||
706 | } | ||||||
707 | pushStackMapConstant(Ops, Builder, Allocas.size()); | ||||||
708 | Ops.append(Allocas.begin(), Allocas.end()); | ||||||
709 | |||||||
710 | // Now construct GC base/derived map; | ||||||
711 | pushStackMapConstant(Ops, Builder, SI.Ptrs.size()); | ||||||
712 | SDLoc L = Builder.getCurSDLoc(); | ||||||
713 | for (unsigned i = 0; i < SI.Ptrs.size(); ++i) { | ||||||
714 | SDValue Base = Builder.getValue(SI.Bases[i]); | ||||||
715 | assert(GCPtrIndexMap.count(Base) && "base not found in index map")(static_cast <bool> (GCPtrIndexMap.count(Base) && "base not found in index map") ? void (0) : __assert_fail ("GCPtrIndexMap.count(Base) && \"base not found in index map\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 715, __extension__ __PRETTY_FUNCTION__)); | ||||||
716 | Ops.push_back( | ||||||
717 | Builder.DAG.getTargetConstant(GCPtrIndexMap[Base], L, MVT::i64)); | ||||||
718 | SDValue Derived = Builder.getValue(SI.Ptrs[i]); | ||||||
719 | assert(GCPtrIndexMap.count(Derived) && "derived not found in index map")(static_cast <bool> (GCPtrIndexMap.count(Derived) && "derived not found in index map") ? void (0) : __assert_fail ("GCPtrIndexMap.count(Derived) && \"derived not found in index map\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 719, __extension__ __PRETTY_FUNCTION__)); | ||||||
720 | Ops.push_back( | ||||||
721 | Builder.DAG.getTargetConstant(GCPtrIndexMap[Derived], L, MVT::i64)); | ||||||
722 | } | ||||||
723 | } | ||||||
724 | |||||||
725 | SDValue SelectionDAGBuilder::LowerAsSTATEPOINT( | ||||||
726 | SelectionDAGBuilder::StatepointLoweringInfo &SI) { | ||||||
727 | // The basic scheme here is that information about both the original call and | ||||||
728 | // the safepoint is encoded in the CallInst. We create a temporary call and | ||||||
729 | // lower it, then reverse engineer the calling sequence. | ||||||
730 | |||||||
731 | NumOfStatepoints++; | ||||||
732 | // Clear state | ||||||
733 | StatepointLowering.startNewStatepoint(*this); | ||||||
734 | assert(SI.Bases.size() == SI.Ptrs.size())(static_cast <bool> (SI.Bases.size() == SI.Ptrs.size()) ? void (0) : __assert_fail ("SI.Bases.size() == SI.Ptrs.size()" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 734, __extension__ __PRETTY_FUNCTION__)); | ||||||
735 | |||||||
736 | LLVM_DEBUG(dbgs() << "Lowering statepoint " << *SI.StatepointInstr << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("statepoint-lowering")) { dbgs() << "Lowering statepoint " << *SI.StatepointInstr << "\n"; } } while (false ); | ||||||
737 | #ifndef NDEBUG | ||||||
738 | for (auto *Reloc : SI.GCRelocates) | ||||||
739 | if (Reloc->getParent() == SI.StatepointInstr->getParent()) | ||||||
740 | StatepointLowering.scheduleRelocCall(*Reloc); | ||||||
741 | #endif | ||||||
742 | |||||||
743 | // Lower statepoint vmstate and gcstate arguments | ||||||
744 | |||||||
745 | // All lowered meta args. | ||||||
746 | SmallVector<SDValue, 10> LoweredMetaArgs; | ||||||
747 | // Lowered GC pointers (subset of above). | ||||||
748 | SmallVector<SDValue, 16> LoweredGCArgs; | ||||||
749 | SmallVector<MachineMemOperand*, 16> MemRefs; | ||||||
750 | // Maps derived pointer SDValue to statepoint result of relocated pointer. | ||||||
751 | DenseMap<SDValue, int> LowerAsVReg; | ||||||
752 | lowerStatepointMetaArgs(LoweredMetaArgs, MemRefs, LoweredGCArgs, LowerAsVReg, | ||||||
753 | SI, *this); | ||||||
754 | |||||||
755 | // Now that we've emitted the spills, we need to update the root so that the | ||||||
756 | // call sequence is ordered correctly. | ||||||
757 | SI.CLI.setChain(getRoot()); | ||||||
758 | |||||||
759 | // Get call node, we will replace it later with statepoint | ||||||
760 | SDValue ReturnVal; | ||||||
761 | SDNode *CallNode; | ||||||
762 | std::tie(ReturnVal, CallNode) = | ||||||
763 | lowerCallFromStatepointLoweringInfo(SI, *this, PendingExports); | ||||||
764 | |||||||
765 | // Construct the actual GC_TRANSITION_START, STATEPOINT, and GC_TRANSITION_END | ||||||
766 | // nodes with all the appropriate arguments and return values. | ||||||
767 | |||||||
768 | // Call Node: Chain, Target, {Args}, RegMask, [Glue] | ||||||
769 | SDValue Chain = CallNode->getOperand(0); | ||||||
770 | |||||||
771 | SDValue Glue; | ||||||
772 | bool CallHasIncomingGlue = CallNode->getGluedNode(); | ||||||
773 | if (CallHasIncomingGlue) { | ||||||
774 | // Glue is always last operand | ||||||
775 | Glue = CallNode->getOperand(CallNode->getNumOperands() - 1); | ||||||
776 | } | ||||||
777 | |||||||
778 | // Build the GC_TRANSITION_START node if necessary. | ||||||
779 | // | ||||||
780 | // The operands to the GC_TRANSITION_{START,END} nodes are laid out in the | ||||||
781 | // order in which they appear in the call to the statepoint intrinsic. If | ||||||
782 | // any of the operands is a pointer-typed, that operand is immediately | ||||||
783 | // followed by a SRCVALUE for the pointer that may be used during lowering | ||||||
784 | // (e.g. to form MachinePointerInfo values for loads/stores). | ||||||
785 | const bool IsGCTransition = | ||||||
786 | (SI.StatepointFlags & (uint64_t)StatepointFlags::GCTransition) == | ||||||
787 | (uint64_t)StatepointFlags::GCTransition; | ||||||
788 | if (IsGCTransition) { | ||||||
789 | SmallVector<SDValue, 8> TSOps; | ||||||
790 | |||||||
791 | // Add chain | ||||||
792 | TSOps.push_back(Chain); | ||||||
793 | |||||||
794 | // Add GC transition arguments | ||||||
795 | for (const Value *V : SI.GCTransitionArgs) { | ||||||
796 | TSOps.push_back(getValue(V)); | ||||||
797 | if (V->getType()->isPointerTy()) | ||||||
798 | TSOps.push_back(DAG.getSrcValue(V)); | ||||||
799 | } | ||||||
800 | |||||||
801 | // Add glue if necessary | ||||||
802 | if (CallHasIncomingGlue) | ||||||
803 | TSOps.push_back(Glue); | ||||||
804 | |||||||
805 | SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); | ||||||
806 | |||||||
807 | SDValue GCTransitionStart = | ||||||
808 | DAG.getNode(ISD::GC_TRANSITION_START, getCurSDLoc(), NodeTys, TSOps); | ||||||
809 | |||||||
810 | Chain = GCTransitionStart.getValue(0); | ||||||
811 | Glue = GCTransitionStart.getValue(1); | ||||||
812 | } | ||||||
813 | |||||||
814 | // TODO: Currently, all of these operands are being marked as read/write in | ||||||
815 | // PrologEpilougeInserter.cpp, we should special case the VMState arguments | ||||||
816 | // and flags to be read-only. | ||||||
817 | SmallVector<SDValue, 40> Ops; | ||||||
818 | |||||||
819 | // Add the <id> and <numBytes> constants. | ||||||
820 | Ops.push_back(DAG.getTargetConstant(SI.ID, getCurSDLoc(), MVT::i64)); | ||||||
821 | Ops.push_back( | ||||||
822 | DAG.getTargetConstant(SI.NumPatchBytes, getCurSDLoc(), MVT::i32)); | ||||||
823 | |||||||
824 | // Calculate and push starting position of vmstate arguments | ||||||
825 | // Get number of arguments incoming directly into call node | ||||||
826 | unsigned NumCallRegArgs = | ||||||
827 | CallNode->getNumOperands() - (CallHasIncomingGlue ? 4 : 3); | ||||||
828 | Ops.push_back(DAG.getTargetConstant(NumCallRegArgs, getCurSDLoc(), MVT::i32)); | ||||||
829 | |||||||
830 | // Add call target | ||||||
831 | SDValue CallTarget = SDValue(CallNode->getOperand(1).getNode(), 0); | ||||||
832 | Ops.push_back(CallTarget); | ||||||
833 | |||||||
834 | // Add call arguments | ||||||
835 | // Get position of register mask in the call | ||||||
836 | SDNode::op_iterator RegMaskIt; | ||||||
837 | if (CallHasIncomingGlue) | ||||||
838 | RegMaskIt = CallNode->op_end() - 2; | ||||||
839 | else | ||||||
840 | RegMaskIt = CallNode->op_end() - 1; | ||||||
841 | Ops.insert(Ops.end(), CallNode->op_begin() + 2, RegMaskIt); | ||||||
842 | |||||||
843 | // Add a constant argument for the calling convention | ||||||
844 | pushStackMapConstant(Ops, *this, SI.CLI.CallConv); | ||||||
845 | |||||||
846 | // Add a constant argument for the flags | ||||||
847 | uint64_t Flags = SI.StatepointFlags; | ||||||
848 | assert(((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0) &&(static_cast <bool> (((Flags & ~(uint64_t)StatepointFlags ::MaskAll) == 0) && "Unknown flag used") ? void (0) : __assert_fail ("((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0) && \"Unknown flag used\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 849, __extension__ __PRETTY_FUNCTION__)) | ||||||
849 | "Unknown flag used")(static_cast <bool> (((Flags & ~(uint64_t)StatepointFlags ::MaskAll) == 0) && "Unknown flag used") ? void (0) : __assert_fail ("((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0) && \"Unknown flag used\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 849, __extension__ __PRETTY_FUNCTION__)); | ||||||
850 | pushStackMapConstant(Ops, *this, Flags); | ||||||
851 | |||||||
852 | // Insert all vmstate and gcstate arguments | ||||||
853 | llvm::append_range(Ops, LoweredMetaArgs); | ||||||
854 | |||||||
855 | // Add register mask from call node | ||||||
856 | Ops.push_back(*RegMaskIt); | ||||||
857 | |||||||
858 | // Add chain | ||||||
859 | Ops.push_back(Chain); | ||||||
860 | |||||||
861 | // Same for the glue, but we add it only if original call had it | ||||||
862 | if (Glue.getNode()) | ||||||
863 | Ops.push_back(Glue); | ||||||
864 | |||||||
865 | // Compute return values. Provide a glue output since we consume one as | ||||||
866 | // input. This allows someone else to chain off us as needed. | ||||||
867 | SmallVector<EVT, 8> NodeTys; | ||||||
868 | for (auto SD : LoweredGCArgs) { | ||||||
869 | if (!LowerAsVReg.count(SD)) | ||||||
870 | continue; | ||||||
871 | NodeTys.push_back(SD.getValueType()); | ||||||
872 | } | ||||||
873 | LLVM_DEBUG(dbgs() << "Statepoint has " << NodeTys.size() << " results\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("statepoint-lowering")) { dbgs() << "Statepoint has " << NodeTys.size() << " results\n"; } } while (false); | ||||||
874 | assert(NodeTys.size() == LowerAsVReg.size() && "Inconsistent GC Ptr lowering")(static_cast <bool> (NodeTys.size() == LowerAsVReg.size () && "Inconsistent GC Ptr lowering") ? void (0) : __assert_fail ("NodeTys.size() == LowerAsVReg.size() && \"Inconsistent GC Ptr lowering\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 874, __extension__ __PRETTY_FUNCTION__)); | ||||||
875 | NodeTys.push_back(MVT::Other); | ||||||
876 | NodeTys.push_back(MVT::Glue); | ||||||
877 | |||||||
878 | unsigned NumResults = NodeTys.size(); | ||||||
879 | MachineSDNode *StatepointMCNode = | ||||||
880 | DAG.getMachineNode(TargetOpcode::STATEPOINT, getCurSDLoc(), NodeTys, Ops); | ||||||
881 | DAG.setNodeMemRefs(StatepointMCNode, MemRefs); | ||||||
882 | |||||||
883 | // For values lowered to tied-defs, create the virtual registers. Note that | ||||||
884 | // for simplicity, we *always* create a vreg even within a single block. | ||||||
885 | DenseMap<SDValue, Register> VirtRegs; | ||||||
886 | for (const auto *Relocate : SI.GCRelocates) { | ||||||
887 | Value *Derived = Relocate->getDerivedPtr(); | ||||||
888 | SDValue SD = getValue(Derived); | ||||||
889 | if (!LowerAsVReg.count(SD)) | ||||||
890 | continue; | ||||||
891 | |||||||
892 | // Handle multiple gc.relocates of the same input efficiently. | ||||||
893 | if (VirtRegs.count(SD)) | ||||||
894 | continue; | ||||||
895 | |||||||
896 | SDValue Relocated = SDValue(StatepointMCNode, LowerAsVReg[SD]); | ||||||
897 | |||||||
898 | auto *RetTy = Relocate->getType(); | ||||||
899 | Register Reg = FuncInfo.CreateRegs(RetTy); | ||||||
900 | RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(), | ||||||
901 | DAG.getDataLayout(), Reg, RetTy, None); | ||||||
902 | SDValue Chain = DAG.getRoot(); | ||||||
903 | RFV.getCopyToRegs(Relocated, DAG, getCurSDLoc(), Chain, nullptr); | ||||||
904 | PendingExports.push_back(Chain); | ||||||
905 | |||||||
906 | VirtRegs[SD] = Reg; | ||||||
907 | } | ||||||
908 | |||||||
909 | // Record for later use how each relocation was lowered. This is needed to | ||||||
910 | // allow later gc.relocates to mirror the lowering chosen. | ||||||
911 | const Instruction *StatepointInstr = SI.StatepointInstr; | ||||||
912 | auto &RelocationMap = FuncInfo.StatepointRelocationMaps[StatepointInstr]; | ||||||
913 | for (const GCRelocateInst *Relocate : SI.GCRelocates) { | ||||||
914 | const Value *V = Relocate->getDerivedPtr(); | ||||||
915 | SDValue SDV = getValue(V); | ||||||
916 | SDValue Loc = StatepointLowering.getLocation(SDV); | ||||||
917 | |||||||
918 | RecordType Record; | ||||||
919 | if (LowerAsVReg.count(SDV)) { | ||||||
920 | Record.type = RecordType::VReg; | ||||||
921 | assert(VirtRegs.count(SDV))(static_cast <bool> (VirtRegs.count(SDV)) ? void (0) : __assert_fail ("VirtRegs.count(SDV)", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 921, __extension__ __PRETTY_FUNCTION__)); | ||||||
922 | Record.payload.Reg = VirtRegs[SDV]; | ||||||
923 | } else if (Loc.getNode()) { | ||||||
924 | Record.type = RecordType::Spill; | ||||||
925 | Record.payload.FI = cast<FrameIndexSDNode>(Loc)->getIndex(); | ||||||
926 | } else { | ||||||
927 | Record.type = RecordType::NoRelocate; | ||||||
928 | // If we didn't relocate a value, we'll essentialy end up inserting an | ||||||
929 | // additional use of the original value when lowering the gc.relocate. | ||||||
930 | // We need to make sure the value is available at the new use, which | ||||||
931 | // might be in another block. | ||||||
932 | if (Relocate->getParent() != StatepointInstr->getParent()) | ||||||
933 | ExportFromCurrentBlock(V); | ||||||
934 | } | ||||||
935 | RelocationMap[V] = Record; | ||||||
936 | } | ||||||
937 | |||||||
938 | |||||||
939 | |||||||
940 | SDNode *SinkNode = StatepointMCNode; | ||||||
941 | |||||||
942 | // Build the GC_TRANSITION_END node if necessary. | ||||||
943 | // | ||||||
944 | // See the comment above regarding GC_TRANSITION_START for the layout of | ||||||
945 | // the operands to the GC_TRANSITION_END node. | ||||||
946 | if (IsGCTransition) { | ||||||
947 | SmallVector<SDValue, 8> TEOps; | ||||||
948 | |||||||
949 | // Add chain | ||||||
950 | TEOps.push_back(SDValue(StatepointMCNode, NumResults - 2)); | ||||||
951 | |||||||
952 | // Add GC transition arguments | ||||||
953 | for (const Value *V : SI.GCTransitionArgs) { | ||||||
954 | TEOps.push_back(getValue(V)); | ||||||
955 | if (V->getType()->isPointerTy()) | ||||||
956 | TEOps.push_back(DAG.getSrcValue(V)); | ||||||
957 | } | ||||||
958 | |||||||
959 | // Add glue | ||||||
960 | TEOps.push_back(SDValue(StatepointMCNode, NumResults - 1)); | ||||||
961 | |||||||
962 | SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); | ||||||
963 | |||||||
964 | SDValue GCTransitionStart = | ||||||
965 | DAG.getNode(ISD::GC_TRANSITION_END, getCurSDLoc(), NodeTys, TEOps); | ||||||
966 | |||||||
967 | SinkNode = GCTransitionStart.getNode(); | ||||||
968 | } | ||||||
969 | |||||||
970 | // Replace original call | ||||||
971 | // Call: ch,glue = CALL ... | ||||||
972 | // Statepoint: [gc relocates],ch,glue = STATEPOINT ... | ||||||
973 | unsigned NumSinkValues = SinkNode->getNumValues(); | ||||||
974 | SDValue StatepointValues[2] = {SDValue(SinkNode, NumSinkValues - 2), | ||||||
975 | SDValue(SinkNode, NumSinkValues - 1)}; | ||||||
976 | DAG.ReplaceAllUsesWith(CallNode, StatepointValues); | ||||||
977 | // Remove original call node | ||||||
978 | DAG.DeleteNode(CallNode); | ||||||
979 | |||||||
980 | // Since we always emit CopyToRegs (even for local relocates), we must | ||||||
981 | // update root, so that they are emitted before any local uses. | ||||||
982 | (void)getControlRoot(); | ||||||
983 | |||||||
984 | // TODO: A better future implementation would be to emit a single variable | ||||||
985 | // argument, variable return value STATEPOINT node here and then hookup the | ||||||
986 | // return value of each gc.relocate to the respective output of the | ||||||
987 | // previously emitted STATEPOINT value. Unfortunately, this doesn't appear | ||||||
988 | // to actually be possible today. | ||||||
989 | |||||||
990 | return ReturnVal; | ||||||
991 | } | ||||||
992 | |||||||
993 | void | ||||||
994 | SelectionDAGBuilder::LowerStatepoint(const GCStatepointInst &I, | ||||||
995 | const BasicBlock *EHPadBB /*= nullptr*/) { | ||||||
996 | assert(I.getCallingConv() != CallingConv::AnyReg &&(static_cast <bool> (I.getCallingConv() != CallingConv:: AnyReg && "anyregcc is not supported on statepoints!" ) ? void (0) : __assert_fail ("I.getCallingConv() != CallingConv::AnyReg && \"anyregcc is not supported on statepoints!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 997, __extension__ __PRETTY_FUNCTION__)) | ||||||
997 | "anyregcc is not supported on statepoints!")(static_cast <bool> (I.getCallingConv() != CallingConv:: AnyReg && "anyregcc is not supported on statepoints!" ) ? void (0) : __assert_fail ("I.getCallingConv() != CallingConv::AnyReg && \"anyregcc is not supported on statepoints!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 997, __extension__ __PRETTY_FUNCTION__)); | ||||||
998 | |||||||
999 | #ifndef NDEBUG | ||||||
1000 | // Check that the associated GCStrategy expects to encounter statepoints. | ||||||
1001 | assert(GFI->getStrategy().useStatepoints() &&(static_cast <bool> (GFI->getStrategy().useStatepoints () && "GCStrategy does not expect to encounter statepoints" ) ? void (0) : __assert_fail ("GFI->getStrategy().useStatepoints() && \"GCStrategy does not expect to encounter statepoints\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 1002, __extension__ __PRETTY_FUNCTION__)) | ||||||
1002 | "GCStrategy does not expect to encounter statepoints")(static_cast <bool> (GFI->getStrategy().useStatepoints () && "GCStrategy does not expect to encounter statepoints" ) ? void (0) : __assert_fail ("GFI->getStrategy().useStatepoints() && \"GCStrategy does not expect to encounter statepoints\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 1002, __extension__ __PRETTY_FUNCTION__)); | ||||||
1003 | #endif | ||||||
1004 | |||||||
1005 | SDValue ActualCallee; | ||||||
1006 | SDValue Callee = getValue(I.getActualCalledOperand()); | ||||||
1007 | |||||||
1008 | if (I.getNumPatchBytes() > 0) { | ||||||
1009 | // If we've been asked to emit a nop sequence instead of a call instruction | ||||||
1010 | // for this statepoint then don't lower the call target, but use a constant | ||||||
1011 | // `undef` instead. Not lowering the call target lets statepoint clients | ||||||
1012 | // get away without providing a physical address for the symbolic call | ||||||
1013 | // target at link time. | ||||||
1014 | ActualCallee = DAG.getUNDEF(Callee.getValueType()); | ||||||
1015 | } else { | ||||||
1016 | ActualCallee = Callee; | ||||||
1017 | } | ||||||
1018 | |||||||
1019 | StatepointLoweringInfo SI(DAG); | ||||||
1020 | populateCallLoweringInfo(SI.CLI, &I, GCStatepointInst::CallArgsBeginPos, | ||||||
1021 | I.getNumCallArgs(), ActualCallee, | ||||||
1022 | I.getActualReturnType(), false /* IsPatchPoint */); | ||||||
1023 | |||||||
1024 | // There may be duplication in the gc.relocate list; such as two copies of | ||||||
1025 | // each relocation on normal and exceptional path for an invoke. We only | ||||||
1026 | // need to spill once and record one copy in the stackmap, but we need to | ||||||
1027 | // reload once per gc.relocate. (Dedupping gc.relocates is trickier and best | ||||||
1028 | // handled as a CSE problem elsewhere.) | ||||||
1029 | // TODO: There a couple of major stackmap size optimizations we could do | ||||||
1030 | // here if we wished. | ||||||
1031 | // 1) If we've encountered a derived pair {B, D}, we don't need to actually | ||||||
1032 | // record {B,B} if it's seen later. | ||||||
1033 | // 2) Due to rematerialization, actual derived pointers are somewhat rare; | ||||||
1034 | // given that, we could change the format to record base pointer relocations | ||||||
1035 | // separately with half the space. This would require a format rev and a | ||||||
1036 | // fairly major rework of the STATEPOINT node though. | ||||||
1037 | SmallSet<SDValue, 8> Seen; | ||||||
1038 | for (const GCRelocateInst *Relocate : I.getGCRelocates()) { | ||||||
1039 | SI.GCRelocates.push_back(Relocate); | ||||||
1040 | |||||||
1041 | SDValue DerivedSD = getValue(Relocate->getDerivedPtr()); | ||||||
1042 | if (Seen.insert(DerivedSD).second) { | ||||||
1043 | SI.Bases.push_back(Relocate->getBasePtr()); | ||||||
1044 | SI.Ptrs.push_back(Relocate->getDerivedPtr()); | ||||||
1045 | } | ||||||
1046 | } | ||||||
1047 | |||||||
1048 | // If we find a deopt value which isn't explicitly added, we need to | ||||||
1049 | // ensure it gets lowered such that gc cycles occurring before the | ||||||
1050 | // deoptimization event during the lifetime of the call don't invalidate | ||||||
1051 | // the pointer we're deopting with. Note that we assume that all | ||||||
1052 | // pointers passed to deopt are base pointers; relaxing that assumption | ||||||
1053 | // would require relatively large changes to how we represent relocations. | ||||||
1054 | for (Value *V : I.deopt_operands()) { | ||||||
1055 | if (!isGCValue(V, *this)) | ||||||
1056 | continue; | ||||||
1057 | if (Seen.insert(getValue(V)).second) { | ||||||
1058 | SI.Bases.push_back(V); | ||||||
1059 | SI.Ptrs.push_back(V); | ||||||
1060 | } | ||||||
1061 | } | ||||||
1062 | |||||||
1063 | SI.GCArgs = ArrayRef<const Use>(I.gc_args_begin(), I.gc_args_end()); | ||||||
1064 | SI.StatepointInstr = &I; | ||||||
1065 | SI.ID = I.getID(); | ||||||
1066 | |||||||
1067 | SI.DeoptState = ArrayRef<const Use>(I.deopt_begin(), I.deopt_end()); | ||||||
1068 | SI.GCTransitionArgs = ArrayRef<const Use>(I.gc_transition_args_begin(), | ||||||
1069 | I.gc_transition_args_end()); | ||||||
1070 | |||||||
1071 | SI.StatepointFlags = I.getFlags(); | ||||||
1072 | SI.NumPatchBytes = I.getNumPatchBytes(); | ||||||
1073 | SI.EHPadBB = EHPadBB; | ||||||
1074 | |||||||
1075 | SDValue ReturnValue = LowerAsSTATEPOINT(SI); | ||||||
1076 | |||||||
1077 | // Export the result value if needed | ||||||
1078 | const std::pair<bool, bool> GCResultLocality = I.getGCResultLocality(); | ||||||
1079 | Type *RetTy = I.getActualReturnType(); | ||||||
1080 | |||||||
1081 | if (RetTy->isVoidTy() || | ||||||
1082 | (!GCResultLocality.first && !GCResultLocality.second)) { | ||||||
1083 | // The return value is not needed, just generate a poison value. | ||||||
1084 | setValue(&I, DAG.getIntPtrConstant(-1, getCurSDLoc())); | ||||||
1085 | return; | ||||||
1086 | } | ||||||
1087 | |||||||
1088 | if (GCResultLocality.first) { | ||||||
1089 | // Result value will be used in a same basic block. Don't export it or | ||||||
1090 | // perform any explicit register copies. The gc_result will simply grab | ||||||
1091 | // this value. | ||||||
1092 | setValue(&I, ReturnValue); | ||||||
1093 | } | ||||||
1094 | |||||||
1095 | if (!GCResultLocality.second) | ||||||
1096 | return; | ||||||
1097 | // Result value will be used in a different basic block so we need to export | ||||||
1098 | // it now. Default exporting mechanism will not work here because statepoint | ||||||
1099 | // call has a different type than the actual call. It means that by default | ||||||
1100 | // llvm will create export register of the wrong type (always i32 in our | ||||||
1101 | // case). So instead we need to create export register with correct type | ||||||
1102 | // manually. | ||||||
1103 | // TODO: To eliminate this problem we can remove gc.result intrinsics | ||||||
1104 | // completely and make statepoint call to return a tuple. | ||||||
1105 | unsigned Reg = FuncInfo.CreateRegs(RetTy); | ||||||
1106 | RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(), | ||||||
1107 | DAG.getDataLayout(), Reg, RetTy, | ||||||
1108 | I.getCallingConv()); | ||||||
1109 | SDValue Chain = DAG.getEntryNode(); | ||||||
1110 | |||||||
1111 | RFV.getCopyToRegs(ReturnValue, DAG, getCurSDLoc(), Chain, nullptr); | ||||||
1112 | PendingExports.push_back(Chain); | ||||||
1113 | FuncInfo.ValueMap[&I] = Reg; | ||||||
1114 | } | ||||||
1115 | |||||||
1116 | void SelectionDAGBuilder::LowerCallSiteWithDeoptBundleImpl( | ||||||
1117 | const CallBase *Call, SDValue Callee, const BasicBlock *EHPadBB, | ||||||
1118 | bool VarArgDisallowed, bool ForceVoidReturnTy) { | ||||||
1119 | StatepointLoweringInfo SI(DAG); | ||||||
1120 | unsigned ArgBeginIndex = Call->arg_begin() - Call->op_begin(); | ||||||
1121 | populateCallLoweringInfo( | ||||||
1122 | SI.CLI, Call, ArgBeginIndex, Call->getNumArgOperands(), Callee, | ||||||
1123 | ForceVoidReturnTy ? Type::getVoidTy(*DAG.getContext()) : Call->getType(), | ||||||
1124 | false); | ||||||
1125 | if (!VarArgDisallowed) | ||||||
1126 | SI.CLI.IsVarArg = Call->getFunctionType()->isVarArg(); | ||||||
1127 | |||||||
1128 | auto DeoptBundle = *Call->getOperandBundle(LLVMContext::OB_deopt); | ||||||
1129 | |||||||
1130 | unsigned DefaultID = StatepointDirectives::DeoptBundleStatepointID; | ||||||
1131 | |||||||
1132 | auto SD = parseStatepointDirectivesFromAttrs(Call->getAttributes()); | ||||||
1133 | SI.ID = SD.StatepointID.getValueOr(DefaultID); | ||||||
1134 | SI.NumPatchBytes = SD.NumPatchBytes.getValueOr(0); | ||||||
1135 | |||||||
1136 | SI.DeoptState = | ||||||
1137 | ArrayRef<const Use>(DeoptBundle.Inputs.begin(), DeoptBundle.Inputs.end()); | ||||||
1138 | SI.StatepointFlags = static_cast<uint64_t>(StatepointFlags::None); | ||||||
1139 | SI.EHPadBB = EHPadBB; | ||||||
1140 | |||||||
1141 | // NB! The GC arguments are deliberately left empty. | ||||||
1142 | |||||||
1143 | if (SDValue ReturnVal = LowerAsSTATEPOINT(SI)) { | ||||||
1144 | ReturnVal = lowerRangeToAssertZExt(DAG, *Call, ReturnVal); | ||||||
1145 | setValue(Call, ReturnVal); | ||||||
1146 | } | ||||||
1147 | } | ||||||
1148 | |||||||
1149 | void SelectionDAGBuilder::LowerCallSiteWithDeoptBundle( | ||||||
1150 | const CallBase *Call, SDValue Callee, const BasicBlock *EHPadBB) { | ||||||
1151 | LowerCallSiteWithDeoptBundleImpl(Call, Callee, EHPadBB, | ||||||
1152 | /* VarArgDisallowed = */ false, | ||||||
1153 | /* ForceVoidReturnTy = */ false); | ||||||
1154 | } | ||||||
1155 | |||||||
1156 | void SelectionDAGBuilder::visitGCResult(const GCResultInst &CI) { | ||||||
1157 | // The result value of the gc_result is simply the result of the actual | ||||||
1158 | // call. We've already emitted this, so just grab the value. | ||||||
1159 | const GCStatepointInst *SI = CI.getStatepoint(); | ||||||
1160 | |||||||
1161 | if (SI->getParent() == CI.getParent()) { | ||||||
1162 | setValue(&CI, getValue(SI)); | ||||||
1163 | return; | ||||||
1164 | } | ||||||
1165 | // Statepoint is in different basic block so we should have stored call | ||||||
1166 | // result in a virtual register. | ||||||
1167 | // We can not use default getValue() functionality to copy value from this | ||||||
1168 | // register because statepoint and actual call return types can be | ||||||
1169 | // different, and getValue() will use CopyFromReg of the wrong type, | ||||||
1170 | // which is always i32 in our case. | ||||||
1171 | Type *RetTy = SI->getActualReturnType(); | ||||||
1172 | SDValue CopyFromReg = getCopyFromRegs(SI, RetTy); | ||||||
1173 | |||||||
1174 | assert(CopyFromReg.getNode())(static_cast <bool> (CopyFromReg.getNode()) ? void (0) : __assert_fail ("CopyFromReg.getNode()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 1174, __extension__ __PRETTY_FUNCTION__)); | ||||||
1175 | setValue(&CI, CopyFromReg); | ||||||
1176 | } | ||||||
1177 | |||||||
1178 | void SelectionDAGBuilder::visitGCRelocate(const GCRelocateInst &Relocate) { | ||||||
1179 | #ifndef NDEBUG | ||||||
1180 | // Consistency check | ||||||
1181 | // We skip this check for relocates not in the same basic block as their | ||||||
1182 | // statepoint. It would be too expensive to preserve validation info through | ||||||
1183 | // different basic blocks. | ||||||
1184 | if (Relocate.getStatepoint()->getParent() == Relocate.getParent()) | ||||||
1185 | StatepointLowering.relocCallVisited(Relocate); | ||||||
1186 | |||||||
1187 | auto *Ty = Relocate.getType()->getScalarType(); | ||||||
1188 | if (auto IsManaged = GFI->getStrategy().isGCManagedPointer(Ty)) | ||||||
1189 | assert(*IsManaged && "Non gc managed pointer relocated!")(static_cast <bool> (*IsManaged && "Non gc managed pointer relocated!" ) ? void (0) : __assert_fail ("*IsManaged && \"Non gc managed pointer relocated!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 1189, __extension__ __PRETTY_FUNCTION__)); | ||||||
1190 | #endif | ||||||
1191 | |||||||
1192 | const Value *DerivedPtr = Relocate.getDerivedPtr(); | ||||||
1193 | auto &RelocationMap = | ||||||
1194 | FuncInfo.StatepointRelocationMaps[Relocate.getStatepoint()]; | ||||||
1195 | auto SlotIt = RelocationMap.find(DerivedPtr); | ||||||
1196 | assert(SlotIt != RelocationMap.end() && "Relocating not lowered gc value")(static_cast <bool> (SlotIt != RelocationMap.end() && "Relocating not lowered gc value") ? void (0) : __assert_fail ("SlotIt != RelocationMap.end() && \"Relocating not lowered gc value\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 1196, __extension__ __PRETTY_FUNCTION__)); | ||||||
1197 | const RecordType &Record = SlotIt->second; | ||||||
1198 | |||||||
1199 | // If relocation was done via virtual register.. | ||||||
1200 | if (Record.type == RecordType::VReg) { | ||||||
1201 | Register InReg = Record.payload.Reg; | ||||||
1202 | RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(), | ||||||
1203 | DAG.getDataLayout(), InReg, Relocate.getType(), | ||||||
1204 | None); // This is not an ABI copy. | ||||||
1205 | // We generate copy to/from regs even for local uses, hence we must | ||||||
1206 | // chain with current root to ensure proper ordering of copies w.r.t. | ||||||
1207 | // statepoint. | ||||||
1208 | SDValue Chain = DAG.getRoot(); | ||||||
1209 | SDValue Relocation = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), | ||||||
1210 | Chain, nullptr, nullptr); | ||||||
1211 | setValue(&Relocate, Relocation); | ||||||
1212 | return; | ||||||
1213 | } | ||||||
1214 | |||||||
1215 | if (Record.type == RecordType::Spill) { | ||||||
1216 | unsigned Index = Record.payload.FI; | ||||||
1217 | SDValue SpillSlot = DAG.getTargetFrameIndex(Index, getFrameIndexTy()); | ||||||
1218 | |||||||
1219 | // All the reloads are independent and are reading memory only modified by | ||||||
1220 | // statepoints (i.e. no other aliasing stores); informing SelectionDAG of | ||||||
1221 | // this this let's CSE kick in for free and allows reordering of | ||||||
1222 | // instructions if possible. The lowering for statepoint sets the root, | ||||||
1223 | // so this is ordering all reloads with the either | ||||||
1224 | // a) the statepoint node itself, or | ||||||
1225 | // b) the entry of the current block for an invoke statepoint. | ||||||
1226 | const SDValue Chain = DAG.getRoot(); // != Builder.getRoot() | ||||||
1227 | |||||||
1228 | auto &MF = DAG.getMachineFunction(); | ||||||
1229 | auto &MFI = MF.getFrameInfo(); | ||||||
1230 | auto PtrInfo = MachinePointerInfo::getFixedStack(MF, Index); | ||||||
1231 | auto *LoadMMO = MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad, | ||||||
1232 | MFI.getObjectSize(Index), | ||||||
1233 | MFI.getObjectAlign(Index)); | ||||||
1234 | |||||||
1235 | auto LoadVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(), | ||||||
1236 | Relocate.getType()); | ||||||
1237 | |||||||
1238 | SDValue SpillLoad = | ||||||
1239 | DAG.getLoad(LoadVT, getCurSDLoc(), Chain, SpillSlot, LoadMMO); | ||||||
1240 | PendingLoads.push_back(SpillLoad.getValue(1)); | ||||||
1241 | |||||||
1242 | assert(SpillLoad.getNode())(static_cast <bool> (SpillLoad.getNode()) ? void (0) : __assert_fail ("SpillLoad.getNode()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 1242, __extension__ __PRETTY_FUNCTION__)); | ||||||
1243 | setValue(&Relocate, SpillLoad); | ||||||
1244 | return; | ||||||
1245 | } | ||||||
1246 | |||||||
1247 | assert(Record.type == RecordType::NoRelocate)(static_cast <bool> (Record.type == RecordType::NoRelocate ) ? void (0) : __assert_fail ("Record.type == RecordType::NoRelocate" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp" , 1247, __extension__ __PRETTY_FUNCTION__)); | ||||||
1248 | SDValue SD = getValue(DerivedPtr); | ||||||
1249 | |||||||
1250 | if (SD.isUndef() && SD.getValueType().getSizeInBits() <= 64) { | ||||||
1251 | // Lowering relocate(undef) as arbitrary constant. Current constant value | ||||||
1252 | // is chosen such that it's unlikely to be a valid pointer. | ||||||
1253 | setValue(&Relocate, DAG.getTargetConstant(0xFEFEFEFE, SDLoc(SD), MVT::i64)); | ||||||
1254 | return; | ||||||
1255 | } | ||||||
1256 | |||||||
1257 | // We didn't need to spill these special cases (constants and allocas). | ||||||
1258 | // See the handling in spillIncomingValueForStatepoint for detail. | ||||||
1259 | setValue(&Relocate, SD); | ||||||
1260 | } | ||||||
1261 | |||||||
1262 | void SelectionDAGBuilder::LowerDeoptimizeCall(const CallInst *CI) { | ||||||
1263 | const auto &TLI = DAG.getTargetLoweringInfo(); | ||||||
1264 | SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(RTLIB::DEOPTIMIZE), | ||||||
1265 | TLI.getPointerTy(DAG.getDataLayout())); | ||||||
1266 | |||||||
1267 | // We don't lower calls to __llvm_deoptimize as varargs, but as a regular | ||||||
1268 | // call. We also do not lower the return value to any virtual register, and | ||||||
1269 | // change the immediately following return to a trap instruction. | ||||||
1270 | LowerCallSiteWithDeoptBundleImpl(CI, Callee, /* EHPadBB = */ nullptr, | ||||||
1271 | /* VarArgDisallowed = */ true, | ||||||
1272 | /* ForceVoidReturnTy = */ true); | ||||||
1273 | } | ||||||
1274 | |||||||
1275 | void SelectionDAGBuilder::LowerDeoptimizingReturn() { | ||||||
1276 | // We do not lower the return value from llvm.deoptimize to any virtual | ||||||
1277 | // register, and change the immediately following return to a trap | ||||||
1278 | // instruction. | ||||||
1279 | if (DAG.getTarget().Options.TrapUnreachable) | ||||||
1280 | DAG.setRoot( | ||||||
1281 | DAG.getNode(ISD::TRAP, getCurSDLoc(), MVT::Other, DAG.getRoot())); | ||||||
1282 | } |
1 | //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- 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 | // |
9 | // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(), |
10 | // and dyn_cast_or_null<X>() templates. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_SUPPORT_CASTING_H |
15 | #define LLVM_SUPPORT_CASTING_H |
16 | |
17 | #include "llvm/Support/Compiler.h" |
18 | #include "llvm/Support/type_traits.h" |
19 | #include <cassert> |
20 | #include <memory> |
21 | #include <type_traits> |
22 | |
23 | namespace llvm { |
24 | |
25 | //===----------------------------------------------------------------------===// |
26 | // isa<x> Support Templates |
27 | //===----------------------------------------------------------------------===// |
28 | |
29 | // Define a template that can be specialized by smart pointers to reflect the |
30 | // fact that they are automatically dereferenced, and are not involved with the |
31 | // template selection process... the default implementation is a noop. |
32 | // |
33 | template<typename From> struct simplify_type { |
34 | using SimpleType = From; // The real type this represents... |
35 | |
36 | // An accessor to get the real value... |
37 | static SimpleType &getSimplifiedValue(From &Val) { return Val; } |
38 | }; |
39 | |
40 | template<typename From> struct simplify_type<const From> { |
41 | using NonConstSimpleType = typename simplify_type<From>::SimpleType; |
42 | using SimpleType = |
43 | typename add_const_past_pointer<NonConstSimpleType>::type; |
44 | using RetType = |
45 | typename add_lvalue_reference_if_not_pointer<SimpleType>::type; |
46 | |
47 | static RetType getSimplifiedValue(const From& Val) { |
48 | return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); |
49 | } |
50 | }; |
51 | |
52 | // The core of the implementation of isa<X> is here; To and From should be |
53 | // the names of classes. This template can be specialized to customize the |
54 | // implementation of isa<> without rewriting it from scratch. |
55 | template <typename To, typename From, typename Enabler = void> |
56 | struct isa_impl { |
57 | static inline bool doit(const From &Val) { |
58 | return To::classof(&Val); |
59 | } |
60 | }; |
61 | |
62 | /// Always allow upcasts, and perform no dynamic check for them. |
63 | template <typename To, typename From> |
64 | struct isa_impl<To, From, std::enable_if_t<std::is_base_of<To, From>::value>> { |
65 | static inline bool doit(const From &) { return true; } |
66 | }; |
67 | |
68 | template <typename To, typename From> struct isa_impl_cl { |
69 | static inline bool doit(const From &Val) { |
70 | return isa_impl<To, From>::doit(Val); |
71 | } |
72 | }; |
73 | |
74 | template <typename To, typename From> struct isa_impl_cl<To, const From> { |
75 | static inline bool doit(const From &Val) { |
76 | return isa_impl<To, From>::doit(Val); |
77 | } |
78 | }; |
79 | |
80 | template <typename To, typename From> |
81 | struct isa_impl_cl<To, const std::unique_ptr<From>> { |
82 | static inline bool doit(const std::unique_ptr<From> &Val) { |
83 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 83, __extension__ __PRETTY_FUNCTION__)); |
84 | return isa_impl_cl<To, From>::doit(*Val); |
85 | } |
86 | }; |
87 | |
88 | template <typename To, typename From> struct isa_impl_cl<To, From*> { |
89 | static inline bool doit(const From *Val) { |
90 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 90, __extension__ __PRETTY_FUNCTION__)); |
91 | return isa_impl<To, From>::doit(*Val); |
92 | } |
93 | }; |
94 | |
95 | template <typename To, typename From> struct isa_impl_cl<To, From*const> { |
96 | static inline bool doit(const From *Val) { |
97 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 97, __extension__ __PRETTY_FUNCTION__)); |
98 | return isa_impl<To, From>::doit(*Val); |
99 | } |
100 | }; |
101 | |
102 | template <typename To, typename From> struct isa_impl_cl<To, const From*> { |
103 | static inline bool doit(const From *Val) { |
104 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 104, __extension__ __PRETTY_FUNCTION__)); |
105 | return isa_impl<To, From>::doit(*Val); |
106 | } |
107 | }; |
108 | |
109 | template <typename To, typename From> struct isa_impl_cl<To, const From*const> { |
110 | static inline bool doit(const From *Val) { |
111 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 111, __extension__ __PRETTY_FUNCTION__)); |
112 | return isa_impl<To, From>::doit(*Val); |
113 | } |
114 | }; |
115 | |
116 | template<typename To, typename From, typename SimpleFrom> |
117 | struct isa_impl_wrap { |
118 | // When From != SimplifiedType, we can simplify the type some more by using |
119 | // the simplify_type template. |
120 | static bool doit(const From &Val) { |
121 | return isa_impl_wrap<To, SimpleFrom, |
122 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
123 | simplify_type<const From>::getSimplifiedValue(Val)); |
124 | } |
125 | }; |
126 | |
127 | template<typename To, typename FromTy> |
128 | struct isa_impl_wrap<To, FromTy, FromTy> { |
129 | // When From == SimpleType, we are as simple as we are going to get. |
130 | static bool doit(const FromTy &Val) { |
131 | return isa_impl_cl<To,FromTy>::doit(Val); |
132 | } |
133 | }; |
134 | |
135 | // isa<X> - Return true if the parameter to the template is an instance of one |
136 | // of the template type arguments. Used like this: |
137 | // |
138 | // if (isa<Type>(myVal)) { ... } |
139 | // if (isa<Type0, Type1, Type2>(myVal)) { ... } |
140 | // |
141 | template <class X, class Y> LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) { |
142 | return isa_impl_wrap<X, const Y, |
143 | typename simplify_type<const Y>::SimpleType>::doit(Val); |
144 | } |
145 | |
146 | template <typename First, typename Second, typename... Rest, typename Y> |
147 | LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) { |
148 | return isa<First>(Val) || isa<Second, Rest...>(Val); |
149 | } |
150 | |
151 | // isa_and_nonnull<X> - Functionally identical to isa, except that a null value |
152 | // is accepted. |
153 | // |
154 | template <typename... X, class Y> |
155 | LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa_and_nonnull(const Y &Val) { |
156 | if (!Val) |
157 | return false; |
158 | return isa<X...>(Val); |
159 | } |
160 | |
161 | //===----------------------------------------------------------------------===// |
162 | // cast<x> Support Templates |
163 | //===----------------------------------------------------------------------===// |
164 | |
165 | template<class To, class From> struct cast_retty; |
166 | |
167 | // Calculate what type the 'cast' function should return, based on a requested |
168 | // type of To and a source type of From. |
169 | template<class To, class From> struct cast_retty_impl { |
170 | using ret_type = To &; // Normal case, return Ty& |
171 | }; |
172 | template<class To, class From> struct cast_retty_impl<To, const From> { |
173 | using ret_type = const To &; // Normal case, return Ty& |
174 | }; |
175 | |
176 | template<class To, class From> struct cast_retty_impl<To, From*> { |
177 | using ret_type = To *; // Pointer arg case, return Ty* |
178 | }; |
179 | |
180 | template<class To, class From> struct cast_retty_impl<To, const From*> { |
181 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
182 | }; |
183 | |
184 | template<class To, class From> struct cast_retty_impl<To, const From*const> { |
185 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
186 | }; |
187 | |
188 | template <class To, class From> |
189 | struct cast_retty_impl<To, std::unique_ptr<From>> { |
190 | private: |
191 | using PointerType = typename cast_retty_impl<To, From *>::ret_type; |
192 | using ResultType = std::remove_pointer_t<PointerType>; |
193 | |
194 | public: |
195 | using ret_type = std::unique_ptr<ResultType>; |
196 | }; |
197 | |
198 | template<class To, class From, class SimpleFrom> |
199 | struct cast_retty_wrap { |
200 | // When the simplified type and the from type are not the same, use the type |
201 | // simplifier to reduce the type, then reuse cast_retty_impl to get the |
202 | // resultant type. |
203 | using ret_type = typename cast_retty<To, SimpleFrom>::ret_type; |
204 | }; |
205 | |
206 | template<class To, class FromTy> |
207 | struct cast_retty_wrap<To, FromTy, FromTy> { |
208 | // When the simplified type is equal to the from type, use it directly. |
209 | using ret_type = typename cast_retty_impl<To,FromTy>::ret_type; |
210 | }; |
211 | |
212 | template<class To, class From> |
213 | struct cast_retty { |
214 | using ret_type = typename cast_retty_wrap< |
215 | To, From, typename simplify_type<From>::SimpleType>::ret_type; |
216 | }; |
217 | |
218 | // Ensure the non-simple values are converted using the simplify_type template |
219 | // that may be specialized by smart pointers... |
220 | // |
221 | template<class To, class From, class SimpleFrom> struct cast_convert_val { |
222 | // This is not a simple type, use the template to simplify it... |
223 | static typename cast_retty<To, From>::ret_type doit(From &Val) { |
224 | return cast_convert_val<To, SimpleFrom, |
225 | typename simplify_type<SimpleFrom>::SimpleType>::doit( |
226 | simplify_type<From>::getSimplifiedValue(Val)); |
227 | } |
228 | }; |
229 | |
230 | template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { |
231 | // This _is_ a simple type, just cast it. |
232 | static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { |
233 | typename cast_retty<To, FromTy>::ret_type Res2 |
234 | = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val); |
235 | return Res2; |
236 | } |
237 | }; |
238 | |
239 | template <class X> struct is_simple_type { |
240 | static const bool value = |
241 | std::is_same<X, typename simplify_type<X>::SimpleType>::value; |
242 | }; |
243 | |
244 | // cast<X> - Return the argument parameter cast to the specified type. This |
245 | // casting operator asserts that the type is correct, so it does not return null |
246 | // on failure. It does not allow a null argument (use cast_or_null for that). |
247 | // It is typically used like this: |
248 | // |
249 | // cast<Instruction>(myVal)->getParent() |
250 | // |
251 | template <class X, class Y> |
252 | inline std::enable_if_t<!is_simple_type<Y>::value, |
253 | typename cast_retty<X, const Y>::ret_type> |
254 | cast(const Y &Val) { |
255 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 255, __extension__ __PRETTY_FUNCTION__)); |
256 | return cast_convert_val< |
257 | X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); |
258 | } |
259 | |
260 | template <class X, class Y> |
261 | inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { |
262 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 262, __extension__ __PRETTY_FUNCTION__)); |
263 | return cast_convert_val<X, Y, |
264 | typename simplify_type<Y>::SimpleType>::doit(Val); |
265 | } |
266 | |
267 | template <class X, class Y> |
268 | inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { |
269 | assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 269, __extension__ __PRETTY_FUNCTION__)); |
270 | return cast_convert_val<X, Y*, |
271 | typename simplify_type<Y*>::SimpleType>::doit(Val); |
272 | } |
273 | |
274 | template <class X, class Y> |
275 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
276 | cast(std::unique_ptr<Y> &&Val) { |
277 | assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!") ? void (0 ) : __assert_fail ("isa<X>(Val.get()) && \"cast<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 277, __extension__ __PRETTY_FUNCTION__)); |
278 | using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type; |
279 | return ret_type( |
280 | cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit( |
281 | Val.release())); |
282 | } |
283 | |
284 | // cast_or_null<X> - Functionally identical to cast, except that a null value is |
285 | // accepted. |
286 | // |
287 | template <class X, class Y> |
288 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t< |
289 | !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type> |
290 | cast_or_null(const Y &Val) { |
291 | if (!Val) |
292 | return nullptr; |
293 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 293, __extension__ __PRETTY_FUNCTION__)); |
294 | return cast<X>(Val); |
295 | } |
296 | |
297 | template <class X, class Y> |
298 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t<!is_simple_type<Y>::value, |
299 | typename cast_retty<X, Y>::ret_type> |
300 | cast_or_null(Y &Val) { |
301 | if (!Val) |
302 | return nullptr; |
303 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 303, __extension__ __PRETTY_FUNCTION__)); |
304 | return cast<X>(Val); |
305 | } |
306 | |
307 | template <class X, class Y> |
308 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
309 | cast_or_null(Y *Val) { |
310 | if (!Val) return nullptr; |
311 | assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/Support/Casting.h" , 311, __extension__ __PRETTY_FUNCTION__)); |
312 | return cast<X>(Val); |
313 | } |
314 | |
315 | template <class X, class Y> |
316 | inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type |
317 | cast_or_null(std::unique_ptr<Y> &&Val) { |
318 | if (!Val) |
319 | return nullptr; |
320 | return cast<X>(std::move(Val)); |
321 | } |
322 | |
323 | // dyn_cast<X> - Return the argument parameter cast to the specified type. This |
324 | // casting operator returns null if the argument is of the wrong type, so it can |
325 | // be used to test for a type as well as cast if successful. This should be |
326 | // used in the context of an if statement like this: |
327 | // |
328 | // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } |
329 | // |
330 | |
331 | template <class X, class Y> |
332 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t< |
333 | !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type> |
334 | dyn_cast(const Y &Val) { |
335 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
336 | } |
337 | |
338 | template <class X, class Y> |
339 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { |
340 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
341 | } |
342 | |
343 | template <class X, class Y> |
344 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { |
345 | return isa<X>(Val) ? cast<X>(Val) : nullptr; |
346 | } |
347 | |
348 | // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null |
349 | // value is accepted. |
350 | // |
351 | template <class X, class Y> |
352 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t< |
353 | !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type> |
354 | dyn_cast_or_null(const Y &Val) { |
355 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
356 | } |
357 | |
358 | template <class X, class Y> |
359 | LLVM_NODISCARD[[clang::warn_unused_result]] inline std::enable_if_t<!is_simple_type<Y>::value, |
360 | typename cast_retty<X, Y>::ret_type> |
361 | dyn_cast_or_null(Y &Val) { |
362 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
363 | } |
364 | |
365 | template <class X, class Y> |
366 | LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type |
367 | dyn_cast_or_null(Y *Val) { |
368 | return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; |
369 | } |
370 | |
371 | // unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, |
372 | // taking ownership of the input pointer iff isa<X>(Val) is true. If the |
373 | // cast is successful, From refers to nullptr on exit and the casted value |
374 | // is returned. If the cast is unsuccessful, the function returns nullptr |
375 | // and From is unchanged. |
376 | template <class X, class Y> |
377 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &Val) |
378 | -> decltype(cast<X>(Val)) { |
379 | if (!isa<X>(Val)) |
380 | return nullptr; |
381 | return cast<X>(std::move(Val)); |
382 | } |
383 | |
384 | template <class X, class Y> |
385 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) { |
386 | return unique_dyn_cast<X, Y>(Val); |
387 | } |
388 | |
389 | // dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that |
390 | // a null value is accepted. |
391 | template <class X, class Y> |
392 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) |
393 | -> decltype(cast<X>(Val)) { |
394 | if (!Val) |
395 | return nullptr; |
396 | return unique_dyn_cast<X, Y>(Val); |
397 | } |
398 | |
399 | template <class X, class Y> |
400 | LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) { |
401 | return unique_dyn_cast_or_null<X, Y>(Val); |
402 | } |
403 | |
404 | } // end namespace llvm |
405 | |
406 | #endif // LLVM_SUPPORT_CASTING_H |
1 | //===- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ----*- 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 | // | |||
9 | // This file declares the SDNode class and derived classes, which are used to | |||
10 | // represent the nodes and operations present in a SelectionDAG. These nodes | |||
11 | // and operations are machine code level operations, with some similarities to | |||
12 | // the GCC RTL representation. | |||
13 | // | |||
14 | // Clients should include the SelectionDAG.h file instead of this file directly. | |||
15 | // | |||
16 | //===----------------------------------------------------------------------===// | |||
17 | ||||
18 | #ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H | |||
19 | #define LLVM_CODEGEN_SELECTIONDAGNODES_H | |||
20 | ||||
21 | #include "llvm/ADT/APFloat.h" | |||
22 | #include "llvm/ADT/ArrayRef.h" | |||
23 | #include "llvm/ADT/BitVector.h" | |||
24 | #include "llvm/ADT/FoldingSet.h" | |||
25 | #include "llvm/ADT/GraphTraits.h" | |||
26 | #include "llvm/ADT/SmallPtrSet.h" | |||
27 | #include "llvm/ADT/SmallVector.h" | |||
28 | #include "llvm/ADT/ilist_node.h" | |||
29 | #include "llvm/ADT/iterator.h" | |||
30 | #include "llvm/ADT/iterator_range.h" | |||
31 | #include "llvm/CodeGen/ISDOpcodes.h" | |||
32 | #include "llvm/CodeGen/MachineMemOperand.h" | |||
33 | #include "llvm/CodeGen/Register.h" | |||
34 | #include "llvm/CodeGen/ValueTypes.h" | |||
35 | #include "llvm/IR/Constants.h" | |||
36 | #include "llvm/IR/DebugLoc.h" | |||
37 | #include "llvm/IR/Instruction.h" | |||
38 | #include "llvm/IR/Instructions.h" | |||
39 | #include "llvm/IR/Metadata.h" | |||
40 | #include "llvm/IR/Operator.h" | |||
41 | #include "llvm/Support/AlignOf.h" | |||
42 | #include "llvm/Support/AtomicOrdering.h" | |||
43 | #include "llvm/Support/Casting.h" | |||
44 | #include "llvm/Support/ErrorHandling.h" | |||
45 | #include "llvm/Support/MachineValueType.h" | |||
46 | #include "llvm/Support/TypeSize.h" | |||
47 | #include <algorithm> | |||
48 | #include <cassert> | |||
49 | #include <climits> | |||
50 | #include <cstddef> | |||
51 | #include <cstdint> | |||
52 | #include <cstring> | |||
53 | #include <iterator> | |||
54 | #include <string> | |||
55 | #include <tuple> | |||
56 | ||||
57 | namespace llvm { | |||
58 | ||||
59 | class APInt; | |||
60 | class Constant; | |||
61 | template <typename T> struct DenseMapInfo; | |||
62 | class GlobalValue; | |||
63 | class MachineBasicBlock; | |||
64 | class MachineConstantPoolValue; | |||
65 | class MCSymbol; | |||
66 | class raw_ostream; | |||
67 | class SDNode; | |||
68 | class SelectionDAG; | |||
69 | class Type; | |||
70 | class Value; | |||
71 | ||||
72 | void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr, | |||
73 | bool force = false); | |||
74 | ||||
75 | /// This represents a list of ValueType's that has been intern'd by | |||
76 | /// a SelectionDAG. Instances of this simple value class are returned by | |||
77 | /// SelectionDAG::getVTList(...). | |||
78 | /// | |||
79 | struct SDVTList { | |||
80 | const EVT *VTs; | |||
81 | unsigned int NumVTs; | |||
82 | }; | |||
83 | ||||
84 | namespace ISD { | |||
85 | ||||
86 | /// Node predicates | |||
87 | ||||
88 | /// If N is a BUILD_VECTOR or SPLAT_VECTOR node whose elements are all the | |||
89 | /// same constant or undefined, return true and return the constant value in | |||
90 | /// \p SplatValue. | |||
91 | bool isConstantSplatVector(const SDNode *N, APInt &SplatValue); | |||
92 | ||||
93 | /// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where | |||
94 | /// all of the elements are ~0 or undef. If \p BuildVectorOnly is set to | |||
95 | /// true, it only checks BUILD_VECTOR. | |||
96 | bool isConstantSplatVectorAllOnes(const SDNode *N, | |||
97 | bool BuildVectorOnly = false); | |||
98 | ||||
99 | /// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where | |||
100 | /// all of the elements are 0 or undef. If \p BuildVectorOnly is set to true, it | |||
101 | /// only checks BUILD_VECTOR. | |||
102 | bool isConstantSplatVectorAllZeros(const SDNode *N, | |||
103 | bool BuildVectorOnly = false); | |||
104 | ||||
105 | /// Return true if the specified node is a BUILD_VECTOR where all of the | |||
106 | /// elements are ~0 or undef. | |||
107 | bool isBuildVectorAllOnes(const SDNode *N); | |||
108 | ||||
109 | /// Return true if the specified node is a BUILD_VECTOR where all of the | |||
110 | /// elements are 0 or undef. | |||
111 | bool isBuildVectorAllZeros(const SDNode *N); | |||
112 | ||||
113 | /// Return true if the specified node is a BUILD_VECTOR node of all | |||
114 | /// ConstantSDNode or undef. | |||
115 | bool isBuildVectorOfConstantSDNodes(const SDNode *N); | |||
116 | ||||
117 | /// Return true if the specified node is a BUILD_VECTOR node of all | |||
118 | /// ConstantFPSDNode or undef. | |||
119 | bool isBuildVectorOfConstantFPSDNodes(const SDNode *N); | |||
120 | ||||
121 | /// Return true if the node has at least one operand and all operands of the | |||
122 | /// specified node are ISD::UNDEF. | |||
123 | bool allOperandsUndef(const SDNode *N); | |||
124 | ||||
125 | } // end namespace ISD | |||
126 | ||||
127 | //===----------------------------------------------------------------------===// | |||
128 | /// Unlike LLVM values, Selection DAG nodes may return multiple | |||
129 | /// values as the result of a computation. Many nodes return multiple values, | |||
130 | /// from loads (which define a token and a return value) to ADDC (which returns | |||
131 | /// a result and a carry value), to calls (which may return an arbitrary number | |||
132 | /// of values). | |||
133 | /// | |||
134 | /// As such, each use of a SelectionDAG computation must indicate the node that | |||
135 | /// computes it as well as which return value to use from that node. This pair | |||
136 | /// of information is represented with the SDValue value type. | |||
137 | /// | |||
138 | class SDValue { | |||
139 | friend struct DenseMapInfo<SDValue>; | |||
140 | ||||
141 | SDNode *Node = nullptr; // The node defining the value we are using. | |||
142 | unsigned ResNo = 0; // Which return value of the node we are using. | |||
143 | ||||
144 | public: | |||
145 | SDValue() = default; | |||
146 | SDValue(SDNode *node, unsigned resno); | |||
147 | ||||
148 | /// get the index which selects a specific result in the SDNode | |||
149 | unsigned getResNo() const { return ResNo; } | |||
150 | ||||
151 | /// get the SDNode which holds the desired result | |||
152 | SDNode *getNode() const { return Node; } | |||
153 | ||||
154 | /// set the SDNode | |||
155 | void setNode(SDNode *N) { Node = N; } | |||
156 | ||||
157 | inline SDNode *operator->() const { return Node; } | |||
158 | ||||
159 | bool operator==(const SDValue &O) const { | |||
160 | return Node == O.Node && ResNo == O.ResNo; | |||
161 | } | |||
162 | bool operator!=(const SDValue &O) const { | |||
163 | return !operator==(O); | |||
164 | } | |||
165 | bool operator<(const SDValue &O) const { | |||
166 | return std::tie(Node, ResNo) < std::tie(O.Node, O.ResNo); | |||
167 | } | |||
168 | explicit operator bool() const { | |||
169 | return Node != nullptr; | |||
170 | } | |||
171 | ||||
172 | SDValue getValue(unsigned R) const { | |||
173 | return SDValue(Node, R); | |||
174 | } | |||
175 | ||||
176 | /// Return true if this node is an operand of N. | |||
177 | bool isOperandOf(const SDNode *N) const; | |||
178 | ||||
179 | /// Return the ValueType of the referenced return value. | |||
180 | inline EVT getValueType() const; | |||
181 | ||||
182 | /// Return the simple ValueType of the referenced return value. | |||
183 | MVT getSimpleValueType() const { | |||
184 | return getValueType().getSimpleVT(); | |||
185 | } | |||
186 | ||||
187 | /// Returns the size of the value in bits. | |||
188 | /// | |||
189 | /// If the value type is a scalable vector type, the scalable property will | |||
190 | /// be set and the runtime size will be a positive integer multiple of the | |||
191 | /// base size. | |||
192 | TypeSize getValueSizeInBits() const { | |||
193 | return getValueType().getSizeInBits(); | |||
194 | } | |||
195 | ||||
196 | uint64_t getScalarValueSizeInBits() const { | |||
197 | return getValueType().getScalarType().getFixedSizeInBits(); | |||
198 | } | |||
199 | ||||
200 | // Forwarding methods - These forward to the corresponding methods in SDNode. | |||
201 | inline unsigned getOpcode() const; | |||
202 | inline unsigned getNumOperands() const; | |||
203 | inline const SDValue &getOperand(unsigned i) const; | |||
204 | inline uint64_t getConstantOperandVal(unsigned i) const; | |||
205 | inline const APInt &getConstantOperandAPInt(unsigned i) const; | |||
206 | inline bool isTargetMemoryOpcode() const; | |||
207 | inline bool isTargetOpcode() const; | |||
208 | inline bool isMachineOpcode() const; | |||
209 | inline bool isUndef() const; | |||
210 | inline unsigned getMachineOpcode() const; | |||
211 | inline const DebugLoc &getDebugLoc() const; | |||
212 | inline void dump() const; | |||
213 | inline void dump(const SelectionDAG *G) const; | |||
214 | inline void dumpr() const; | |||
215 | inline void dumpr(const SelectionDAG *G) const; | |||
216 | ||||
217 | /// Return true if this operand (which must be a chain) reaches the | |||
218 | /// specified operand without crossing any side-effecting instructions. | |||
219 | /// In practice, this looks through token factors and non-volatile loads. | |||
220 | /// In order to remain efficient, this only | |||
221 | /// looks a couple of nodes in, it does not do an exhaustive search. | |||
222 | bool reachesChainWithoutSideEffects(SDValue Dest, | |||
223 | unsigned Depth = 2) const; | |||
224 | ||||
225 | /// Return true if there are no nodes using value ResNo of Node. | |||
226 | inline bool use_empty() const; | |||
227 | ||||
228 | /// Return true if there is exactly one node using value ResNo of Node. | |||
229 | inline bool hasOneUse() const; | |||
230 | }; | |||
231 | ||||
232 | template<> struct DenseMapInfo<SDValue> { | |||
233 | static inline SDValue getEmptyKey() { | |||
234 | SDValue V; | |||
235 | V.ResNo = -1U; | |||
236 | return V; | |||
237 | } | |||
238 | ||||
239 | static inline SDValue getTombstoneKey() { | |||
240 | SDValue V; | |||
241 | V.ResNo = -2U; | |||
242 | return V; | |||
243 | } | |||
244 | ||||
245 | static unsigned getHashValue(const SDValue &Val) { | |||
246 | return ((unsigned)((uintptr_t)Val.getNode() >> 4) ^ | |||
247 | (unsigned)((uintptr_t)Val.getNode() >> 9)) + Val.getResNo(); | |||
248 | } | |||
249 | ||||
250 | static bool isEqual(const SDValue &LHS, const SDValue &RHS) { | |||
251 | return LHS == RHS; | |||
252 | } | |||
253 | }; | |||
254 | ||||
255 | /// Allow casting operators to work directly on | |||
256 | /// SDValues as if they were SDNode*'s. | |||
257 | template<> struct simplify_type<SDValue> { | |||
258 | using SimpleType = SDNode *; | |||
259 | ||||
260 | static SimpleType getSimplifiedValue(SDValue &Val) { | |||
261 | return Val.getNode(); | |||
262 | } | |||
263 | }; | |||
264 | template<> struct simplify_type<const SDValue> { | |||
265 | using SimpleType = /*const*/ SDNode *; | |||
266 | ||||
267 | static SimpleType getSimplifiedValue(const SDValue &Val) { | |||
268 | return Val.getNode(); | |||
269 | } | |||
270 | }; | |||
271 | ||||
272 | /// Represents a use of a SDNode. This class holds an SDValue, | |||
273 | /// which records the SDNode being used and the result number, a | |||
274 | /// pointer to the SDNode using the value, and Next and Prev pointers, | |||
275 | /// which link together all the uses of an SDNode. | |||
276 | /// | |||
277 | class SDUse { | |||
278 | /// Val - The value being used. | |||
279 | SDValue Val; | |||
280 | /// User - The user of this value. | |||
281 | SDNode *User = nullptr; | |||
282 | /// Prev, Next - Pointers to the uses list of the SDNode referred by | |||
283 | /// this operand. | |||
284 | SDUse **Prev = nullptr; | |||
285 | SDUse *Next = nullptr; | |||
286 | ||||
287 | public: | |||
288 | SDUse() = default; | |||
289 | SDUse(const SDUse &U) = delete; | |||
290 | SDUse &operator=(const SDUse &) = delete; | |||
291 | ||||
292 | /// Normally SDUse will just implicitly convert to an SDValue that it holds. | |||
293 | operator const SDValue&() const { return Val; } | |||
294 | ||||
295 | /// If implicit conversion to SDValue doesn't work, the get() method returns | |||
296 | /// the SDValue. | |||
297 | const SDValue &get() const { return Val; } | |||
298 | ||||
299 | /// This returns the SDNode that contains this Use. | |||
300 | SDNode *getUser() { return User; } | |||
301 | ||||
302 | /// Get the next SDUse in the use list. | |||
303 | SDUse *getNext() const { return Next; } | |||
304 | ||||
305 | /// Convenience function for get().getNode(). | |||
306 | SDNode *getNode() const { return Val.getNode(); } | |||
307 | /// Convenience function for get().getResNo(). | |||
308 | unsigned getResNo() const { return Val.getResNo(); } | |||
309 | /// Convenience function for get().getValueType(). | |||
310 | EVT getValueType() const { return Val.getValueType(); } | |||
311 | ||||
312 | /// Convenience function for get().operator== | |||
313 | bool operator==(const SDValue &V) const { | |||
314 | return Val == V; | |||
315 | } | |||
316 | ||||
317 | /// Convenience function for get().operator!= | |||
318 | bool operator!=(const SDValue &V) const { | |||
319 | return Val != V; | |||
320 | } | |||
321 | ||||
322 | /// Convenience function for get().operator< | |||
323 | bool operator<(const SDValue &V) const { | |||
324 | return Val < V; | |||
325 | } | |||
326 | ||||
327 | private: | |||
328 | friend class SelectionDAG; | |||
329 | friend class SDNode; | |||
330 | // TODO: unfriend HandleSDNode once we fix its operand handling. | |||
331 | friend class HandleSDNode; | |||
332 | ||||
333 | void setUser(SDNode *p) { User = p; } | |||
334 | ||||
335 | /// Remove this use from its existing use list, assign it the | |||
336 | /// given value, and add it to the new value's node's use list. | |||
337 | inline void set(const SDValue &V); | |||
338 | /// Like set, but only supports initializing a newly-allocated | |||
339 | /// SDUse with a non-null value. | |||
340 | inline void setInitial(const SDValue &V); | |||
341 | /// Like set, but only sets the Node portion of the value, | |||
342 | /// leaving the ResNo portion unmodified. | |||
343 | inline void setNode(SDNode *N); | |||
344 | ||||
345 | void addToList(SDUse **List) { | |||
346 | Next = *List; | |||
347 | if (Next) Next->Prev = &Next; | |||
348 | Prev = List; | |||
349 | *List = this; | |||
350 | } | |||
351 | ||||
352 | void removeFromList() { | |||
353 | *Prev = Next; | |||
354 | if (Next) Next->Prev = Prev; | |||
355 | } | |||
356 | }; | |||
357 | ||||
358 | /// simplify_type specializations - Allow casting operators to work directly on | |||
359 | /// SDValues as if they were SDNode*'s. | |||
360 | template<> struct simplify_type<SDUse> { | |||
361 | using SimpleType = SDNode *; | |||
362 | ||||
363 | static SimpleType getSimplifiedValue(SDUse &Val) { | |||
364 | return Val.getNode(); | |||
365 | } | |||
366 | }; | |||
367 | ||||
368 | /// These are IR-level optimization flags that may be propagated to SDNodes. | |||
369 | /// TODO: This data structure should be shared by the IR optimizer and the | |||
370 | /// the backend. | |||
371 | struct SDNodeFlags { | |||
372 | private: | |||
373 | bool NoUnsignedWrap : 1; | |||
374 | bool NoSignedWrap : 1; | |||
375 | bool Exact : 1; | |||
376 | bool NoNaNs : 1; | |||
377 | bool NoInfs : 1; | |||
378 | bool NoSignedZeros : 1; | |||
379 | bool AllowReciprocal : 1; | |||
380 | bool AllowContract : 1; | |||
381 | bool ApproximateFuncs : 1; | |||
382 | bool AllowReassociation : 1; | |||
383 | ||||
384 | // We assume instructions do not raise floating-point exceptions by default, | |||
385 | // and only those marked explicitly may do so. We could choose to represent | |||
386 | // this via a positive "FPExcept" flags like on the MI level, but having a | |||
387 | // negative "NoFPExcept" flag here (that defaults to true) makes the flag | |||
388 | // intersection logic more straightforward. | |||
389 | bool NoFPExcept : 1; | |||
390 | ||||
391 | public: | |||
392 | /// Default constructor turns off all optimization flags. | |||
393 | SDNodeFlags() | |||
394 | : NoUnsignedWrap(false), NoSignedWrap(false), Exact(false), NoNaNs(false), | |||
395 | NoInfs(false), NoSignedZeros(false), AllowReciprocal(false), | |||
396 | AllowContract(false), ApproximateFuncs(false), | |||
397 | AllowReassociation(false), NoFPExcept(false) {} | |||
398 | ||||
399 | /// Propagate the fast-math-flags from an IR FPMathOperator. | |||
400 | void copyFMF(const FPMathOperator &FPMO) { | |||
401 | setNoNaNs(FPMO.hasNoNaNs()); | |||
402 | setNoInfs(FPMO.hasNoInfs()); | |||
403 | setNoSignedZeros(FPMO.hasNoSignedZeros()); | |||
404 | setAllowReciprocal(FPMO.hasAllowReciprocal()); | |||
405 | setAllowContract(FPMO.hasAllowContract()); | |||
406 | setApproximateFuncs(FPMO.hasApproxFunc()); | |||
407 | setAllowReassociation(FPMO.hasAllowReassoc()); | |||
408 | } | |||
409 | ||||
410 | // These are mutators for each flag. | |||
411 | void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; } | |||
412 | void setNoSignedWrap(bool b) { NoSignedWrap = b; } | |||
413 | void setExact(bool b) { Exact = b; } | |||
414 | void setNoNaNs(bool b) { NoNaNs = b; } | |||
415 | void setNoInfs(bool b) { NoInfs = b; } | |||
416 | void setNoSignedZeros(bool b) { NoSignedZeros = b; } | |||
417 | void setAllowReciprocal(bool b) { AllowReciprocal = b; } | |||
418 | void setAllowContract(bool b) { AllowContract = b; } | |||
419 | void setApproximateFuncs(bool b) { ApproximateFuncs = b; } | |||
420 | void setAllowReassociation(bool b) { AllowReassociation = b; } | |||
421 | void setNoFPExcept(bool b) { NoFPExcept = b; } | |||
422 | ||||
423 | // These are accessors for each flag. | |||
424 | bool hasNoUnsignedWrap() const { return NoUnsignedWrap; } | |||
425 | bool hasNoSignedWrap() const { return NoSignedWrap; } | |||
426 | bool hasExact() const { return Exact; } | |||
427 | bool hasNoNaNs() const { return NoNaNs; } | |||
428 | bool hasNoInfs() const { return NoInfs; } | |||
429 | bool hasNoSignedZeros() const { return NoSignedZeros; } | |||
430 | bool hasAllowReciprocal() const { return AllowReciprocal; } | |||
431 | bool hasAllowContract() const { return AllowContract; } | |||
432 | bool hasApproximateFuncs() const { return ApproximateFuncs; } | |||
433 | bool hasAllowReassociation() const { return AllowReassociation; } | |||
434 | bool hasNoFPExcept() const { return NoFPExcept; } | |||
435 | ||||
436 | /// Clear any flags in this flag set that aren't also set in Flags. All | |||
437 | /// flags will be cleared if Flags are undefined. | |||
438 | void intersectWith(const SDNodeFlags Flags) { | |||
439 | NoUnsignedWrap &= Flags.NoUnsignedWrap; | |||
440 | NoSignedWrap &= Flags.NoSignedWrap; | |||
441 | Exact &= Flags.Exact; | |||
442 | NoNaNs &= Flags.NoNaNs; | |||
443 | NoInfs &= Flags.NoInfs; | |||
444 | NoSignedZeros &= Flags.NoSignedZeros; | |||
445 | AllowReciprocal &= Flags.AllowReciprocal; | |||
446 | AllowContract &= Flags.AllowContract; | |||
447 | ApproximateFuncs &= Flags.ApproximateFuncs; | |||
448 | AllowReassociation &= Flags.AllowReassociation; | |||
449 | NoFPExcept &= Flags.NoFPExcept; | |||
450 | } | |||
451 | }; | |||
452 | ||||
453 | /// Represents one node in the SelectionDAG. | |||
454 | /// | |||
455 | class SDNode : public FoldingSetNode, public ilist_node<SDNode> { | |||
456 | private: | |||
457 | /// The operation that this node performs. | |||
458 | int16_t NodeType; | |||
459 | ||||
460 | protected: | |||
461 | // We define a set of mini-helper classes to help us interpret the bits in our | |||
462 | // SubclassData. These are designed to fit within a uint16_t so they pack | |||
463 | // with NodeType. | |||
464 | ||||
465 | #if defined(_AIX) && (!defined(__GNUC__4) || defined(__clang__1)) | |||
466 | // Except for GCC; by default, AIX compilers store bit-fields in 4-byte words | |||
467 | // and give the `pack` pragma push semantics. | |||
468 | #define BEGIN_TWO_BYTE_PACK() _Pragma("pack(2)")pack(2) | |||
469 | #define END_TWO_BYTE_PACK() _Pragma("pack(pop)")pack(pop) | |||
470 | #else | |||
471 | #define BEGIN_TWO_BYTE_PACK() | |||
472 | #define END_TWO_BYTE_PACK() | |||
473 | #endif | |||
474 | ||||
475 | BEGIN_TWO_BYTE_PACK() | |||
476 | class SDNodeBitfields { | |||
477 | friend class SDNode; | |||
478 | friend class MemIntrinsicSDNode; | |||
479 | friend class MemSDNode; | |||
480 | friend class SelectionDAG; | |||
481 | ||||
482 | uint16_t HasDebugValue : 1; | |||
483 | uint16_t IsMemIntrinsic : 1; | |||
484 | uint16_t IsDivergent : 1; | |||
485 | }; | |||
486 | enum { NumSDNodeBits = 3 }; | |||
487 | ||||
488 | class ConstantSDNodeBitfields { | |||
489 | friend class ConstantSDNode; | |||
490 | ||||
491 | uint16_t : NumSDNodeBits; | |||
492 | ||||
493 | uint16_t IsOpaque : 1; | |||
494 | }; | |||
495 | ||||
496 | class MemSDNodeBitfields { | |||
497 | friend class MemSDNode; | |||
498 | friend class MemIntrinsicSDNode; | |||
499 | friend class AtomicSDNode; | |||
500 | ||||
501 | uint16_t : NumSDNodeBits; | |||
502 | ||||
503 | uint16_t IsVolatile : 1; | |||
504 | uint16_t IsNonTemporal : 1; | |||
505 | uint16_t IsDereferenceable : 1; | |||
506 | uint16_t IsInvariant : 1; | |||
507 | }; | |||
508 | enum { NumMemSDNodeBits = NumSDNodeBits + 4 }; | |||
509 | ||||
510 | class LSBaseSDNodeBitfields { | |||
511 | friend class LSBaseSDNode; | |||
512 | friend class MaskedLoadStoreSDNode; | |||
513 | friend class MaskedGatherScatterSDNode; | |||
514 | ||||
515 | uint16_t : NumMemSDNodeBits; | |||
516 | ||||
517 | // This storage is shared between disparate class hierarchies to hold an | |||
518 | // enumeration specific to the class hierarchy in use. | |||
519 | // LSBaseSDNode => enum ISD::MemIndexedMode | |||
520 | // MaskedLoadStoreBaseSDNode => enum ISD::MemIndexedMode | |||
521 | // MaskedGatherScatterSDNode => enum ISD::MemIndexType | |||
522 | uint16_t AddressingMode : 3; | |||
523 | }; | |||
524 | enum { NumLSBaseSDNodeBits = NumMemSDNodeBits + 3 }; | |||
525 | ||||
526 | class LoadSDNodeBitfields { | |||
527 | friend class LoadSDNode; | |||
528 | friend class MaskedLoadSDNode; | |||
529 | friend class MaskedGatherSDNode; | |||
530 | ||||
531 | uint16_t : NumLSBaseSDNodeBits; | |||
532 | ||||
533 | uint16_t ExtTy : 2; // enum ISD::LoadExtType | |||
534 | uint16_t IsExpanding : 1; | |||
535 | }; | |||
536 | ||||
537 | class StoreSDNodeBitfields { | |||
538 | friend class StoreSDNode; | |||
539 | friend class MaskedStoreSDNode; | |||
540 | friend class MaskedScatterSDNode; | |||
541 | ||||
542 | uint16_t : NumLSBaseSDNodeBits; | |||
543 | ||||
544 | uint16_t IsTruncating : 1; | |||
545 | uint16_t IsCompressing : 1; | |||
546 | }; | |||
547 | ||||
548 | union { | |||
549 | char RawSDNodeBits[sizeof(uint16_t)]; | |||
550 | SDNodeBitfields SDNodeBits; | |||
551 | ConstantSDNodeBitfields ConstantSDNodeBits; | |||
552 | MemSDNodeBitfields MemSDNodeBits; | |||
553 | LSBaseSDNodeBitfields LSBaseSDNodeBits; | |||
554 | LoadSDNodeBitfields LoadSDNodeBits; | |||
555 | StoreSDNodeBitfields StoreSDNodeBits; | |||
556 | }; | |||
557 | END_TWO_BYTE_PACK() | |||
558 | #undef BEGIN_TWO_BYTE_PACK | |||
559 | #undef END_TWO_BYTE_PACK | |||
560 | ||||
561 | // RawSDNodeBits must cover the entirety of the union. This means that all of | |||
562 | // the union's members must have size <= RawSDNodeBits. We write the RHS as | |||
563 | // "2" instead of sizeof(RawSDNodeBits) because MSVC can't handle the latter. | |||
564 | static_assert(sizeof(SDNodeBitfields) <= 2, "field too wide"); | |||
565 | static_assert(sizeof(ConstantSDNodeBitfields) <= 2, "field too wide"); | |||
566 | static_assert(sizeof(MemSDNodeBitfields) <= 2, "field too wide"); | |||
567 | static_assert(sizeof(LSBaseSDNodeBitfields) <= 2, "field too wide"); | |||
568 | static_assert(sizeof(LoadSDNodeBitfields) <= 2, "field too wide"); | |||
569 | static_assert(sizeof(StoreSDNodeBitfields) <= 2, "field too wide"); | |||
570 | ||||
571 | private: | |||
572 | friend class SelectionDAG; | |||
573 | // TODO: unfriend HandleSDNode once we fix its operand handling. | |||
574 | friend class HandleSDNode; | |||
575 | ||||
576 | /// Unique id per SDNode in the DAG. | |||
577 | int NodeId = -1; | |||
578 | ||||
579 | /// The values that are used by this operation. | |||
580 | SDUse *OperandList = nullptr; | |||
581 | ||||
582 | /// The types of the values this node defines. SDNode's may | |||
583 | /// define multiple values simultaneously. | |||
584 | const EVT *ValueList; | |||
585 | ||||
586 | /// List of uses for this SDNode. | |||
587 | SDUse *UseList = nullptr; | |||
588 | ||||
589 | /// The number of entries in the Operand/Value list. | |||
590 | unsigned short NumOperands = 0; | |||
591 | unsigned short NumValues; | |||
592 | ||||
593 | // The ordering of the SDNodes. It roughly corresponds to the ordering of the | |||
594 | // original LLVM instructions. | |||
595 | // This is used for turning off scheduling, because we'll forgo | |||
596 | // the normal scheduling algorithms and output the instructions according to | |||
597 | // this ordering. | |||
598 | unsigned IROrder; | |||
599 | ||||
600 | /// Source line information. | |||
601 | DebugLoc debugLoc; | |||
602 | ||||
603 | /// Return a pointer to the specified value type. | |||
604 | static const EVT *getValueTypeList(EVT VT); | |||
605 | ||||
606 | SDNodeFlags Flags; | |||
607 | ||||
608 | public: | |||
609 | /// Unique and persistent id per SDNode in the DAG. | |||
610 | /// Used for debug printing. | |||
611 | uint16_t PersistentId; | |||
612 | ||||
613 | //===--------------------------------------------------------------------===// | |||
614 | // Accessors | |||
615 | // | |||
616 | ||||
617 | /// Return the SelectionDAG opcode value for this node. For | |||
618 | /// pre-isel nodes (those for which isMachineOpcode returns false), these | |||
619 | /// are the opcode values in the ISD and <target>ISD namespaces. For | |||
620 | /// post-isel opcodes, see getMachineOpcode. | |||
621 | unsigned getOpcode() const { return (unsigned short)NodeType; } | |||
622 | ||||
623 | /// Test if this node has a target-specific opcode (in the | |||
624 | /// \<target\>ISD namespace). | |||
625 | bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; } | |||
626 | ||||
627 | /// Test if this node has a target-specific opcode that may raise | |||
628 | /// FP exceptions (in the \<target\>ISD namespace and greater than | |||
629 | /// FIRST_TARGET_STRICTFP_OPCODE). Note that all target memory | |||
630 | /// opcode are currently automatically considered to possibly raise | |||
631 | /// FP exceptions as well. | |||
632 | bool isTargetStrictFPOpcode() const { | |||
633 | return NodeType >= ISD::FIRST_TARGET_STRICTFP_OPCODE; | |||
634 | } | |||
635 | ||||
636 | /// Test if this node has a target-specific | |||
637 | /// memory-referencing opcode (in the \<target\>ISD namespace and | |||
638 | /// greater than FIRST_TARGET_MEMORY_OPCODE). | |||
639 | bool isTargetMemoryOpcode() const { | |||
640 | return NodeType >= ISD::FIRST_TARGET_MEMORY_OPCODE; | |||
641 | } | |||
642 | ||||
643 | /// Return true if the type of the node type undefined. | |||
644 | bool isUndef() const { return NodeType == ISD::UNDEF; } | |||
645 | ||||
646 | /// Test if this node is a memory intrinsic (with valid pointer information). | |||
647 | /// INTRINSIC_W_CHAIN and INTRINSIC_VOID nodes are sometimes created for | |||
648 | /// non-memory intrinsics (with chains) that are not really instances of | |||
649 | /// MemSDNode. For such nodes, we need some extra state to determine the | |||
650 | /// proper classof relationship. | |||
651 | bool isMemIntrinsic() const { | |||
652 | return (NodeType == ISD::INTRINSIC_W_CHAIN || | |||
653 | NodeType == ISD::INTRINSIC_VOID) && | |||
654 | SDNodeBits.IsMemIntrinsic; | |||
655 | } | |||
656 | ||||
657 | /// Test if this node is a strict floating point pseudo-op. | |||
658 | bool isStrictFPOpcode() { | |||
659 | switch (NodeType) { | |||
660 | default: | |||
661 | return false; | |||
662 | case ISD::STRICT_FP16_TO_FP: | |||
663 | case ISD::STRICT_FP_TO_FP16: | |||
664 | #define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \ | |||
665 | case ISD::STRICT_##DAGN: | |||
666 | #include "llvm/IR/ConstrainedOps.def" | |||
667 | return true; | |||
668 | } | |||
669 | } | |||
670 | ||||
671 | /// Test if this node has a post-isel opcode, directly | |||
672 | /// corresponding to a MachineInstr opcode. | |||
673 | bool isMachineOpcode() const { return NodeType < 0; } | |||
674 | ||||
675 | /// This may only be called if isMachineOpcode returns | |||
676 | /// true. It returns the MachineInstr opcode value that the node's opcode | |||
677 | /// corresponds to. | |||
678 | unsigned getMachineOpcode() const { | |||
679 | assert(isMachineOpcode() && "Not a MachineInstr opcode!")(static_cast <bool> (isMachineOpcode() && "Not a MachineInstr opcode!" ) ? void (0) : __assert_fail ("isMachineOpcode() && \"Not a MachineInstr opcode!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 679, __extension__ __PRETTY_FUNCTION__)); | |||
680 | return ~NodeType; | |||
681 | } | |||
682 | ||||
683 | bool getHasDebugValue() const { return SDNodeBits.HasDebugValue; } | |||
684 | void setHasDebugValue(bool b) { SDNodeBits.HasDebugValue = b; } | |||
685 | ||||
686 | bool isDivergent() const { return SDNodeBits.IsDivergent; } | |||
687 | ||||
688 | /// Return true if there are no uses of this node. | |||
689 | bool use_empty() const { return UseList == nullptr; } | |||
690 | ||||
691 | /// Return true if there is exactly one use of this node. | |||
692 | bool hasOneUse() const { return hasSingleElement(uses()); } | |||
693 | ||||
694 | /// Return the number of uses of this node. This method takes | |||
695 | /// time proportional to the number of uses. | |||
696 | size_t use_size() const { return std::distance(use_begin(), use_end()); } | |||
697 | ||||
698 | /// Return the unique node id. | |||
699 | int getNodeId() const { return NodeId; } | |||
700 | ||||
701 | /// Set unique node id. | |||
702 | void setNodeId(int Id) { NodeId = Id; } | |||
703 | ||||
704 | /// Return the node ordering. | |||
705 | unsigned getIROrder() const { return IROrder; } | |||
706 | ||||
707 | /// Set the node ordering. | |||
708 | void setIROrder(unsigned Order) { IROrder = Order; } | |||
709 | ||||
710 | /// Return the source location info. | |||
711 | const DebugLoc &getDebugLoc() const { return debugLoc; } | |||
712 | ||||
713 | /// Set source location info. Try to avoid this, putting | |||
714 | /// it in the constructor is preferable. | |||
715 | void setDebugLoc(DebugLoc dl) { debugLoc = std::move(dl); } | |||
716 | ||||
717 | /// This class provides iterator support for SDUse | |||
718 | /// operands that use a specific SDNode. | |||
719 | class use_iterator { | |||
720 | friend class SDNode; | |||
721 | ||||
722 | SDUse *Op = nullptr; | |||
723 | ||||
724 | explicit use_iterator(SDUse *op) : Op(op) {} | |||
725 | ||||
726 | public: | |||
727 | using iterator_category = std::forward_iterator_tag; | |||
728 | using value_type = SDUse; | |||
729 | using difference_type = std::ptrdiff_t; | |||
730 | using pointer = value_type *; | |||
731 | using reference = value_type &; | |||
732 | ||||
733 | use_iterator() = default; | |||
734 | use_iterator(const use_iterator &I) : Op(I.Op) {} | |||
735 | ||||
736 | bool operator==(const use_iterator &x) const { | |||
737 | return Op == x.Op; | |||
738 | } | |||
739 | bool operator!=(const use_iterator &x) const { | |||
740 | return !operator==(x); | |||
741 | } | |||
742 | ||||
743 | /// Return true if this iterator is at the end of uses list. | |||
744 | bool atEnd() const { return Op == nullptr; } | |||
745 | ||||
746 | // Iterator traversal: forward iteration only. | |||
747 | use_iterator &operator++() { // Preincrement | |||
748 | assert(Op && "Cannot increment end iterator!")(static_cast <bool> (Op && "Cannot increment end iterator!" ) ? void (0) : __assert_fail ("Op && \"Cannot increment end iterator!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 748, __extension__ __PRETTY_FUNCTION__)); | |||
749 | Op = Op->getNext(); | |||
750 | return *this; | |||
751 | } | |||
752 | ||||
753 | use_iterator operator++(int) { // Postincrement | |||
754 | use_iterator tmp = *this; ++*this; return tmp; | |||
755 | } | |||
756 | ||||
757 | /// Retrieve a pointer to the current user node. | |||
758 | SDNode *operator*() const { | |||
759 | assert(Op && "Cannot dereference end iterator!")(static_cast <bool> (Op && "Cannot dereference end iterator!" ) ? void (0) : __assert_fail ("Op && \"Cannot dereference end iterator!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 759, __extension__ __PRETTY_FUNCTION__)); | |||
760 | return Op->getUser(); | |||
761 | } | |||
762 | ||||
763 | SDNode *operator->() const { return operator*(); } | |||
764 | ||||
765 | SDUse &getUse() const { return *Op; } | |||
766 | ||||
767 | /// Retrieve the operand # of this use in its user. | |||
768 | unsigned getOperandNo() const { | |||
769 | assert(Op && "Cannot dereference end iterator!")(static_cast <bool> (Op && "Cannot dereference end iterator!" ) ? void (0) : __assert_fail ("Op && \"Cannot dereference end iterator!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 769, __extension__ __PRETTY_FUNCTION__)); | |||
770 | return (unsigned)(Op - Op->getUser()->OperandList); | |||
771 | } | |||
772 | }; | |||
773 | ||||
774 | /// Provide iteration support to walk over all uses of an SDNode. | |||
775 | use_iterator use_begin() const { | |||
776 | return use_iterator(UseList); | |||
777 | } | |||
778 | ||||
779 | static use_iterator use_end() { return use_iterator(nullptr); } | |||
780 | ||||
781 | inline iterator_range<use_iterator> uses() { | |||
782 | return make_range(use_begin(), use_end()); | |||
783 | } | |||
784 | inline iterator_range<use_iterator> uses() const { | |||
785 | return make_range(use_begin(), use_end()); | |||
786 | } | |||
787 | ||||
788 | /// Return true if there are exactly NUSES uses of the indicated value. | |||
789 | /// This method ignores uses of other values defined by this operation. | |||
790 | bool hasNUsesOfValue(unsigned NUses, unsigned Value) const; | |||
791 | ||||
792 | /// Return true if there are any use of the indicated value. | |||
793 | /// This method ignores uses of other values defined by this operation. | |||
794 | bool hasAnyUseOfValue(unsigned Value) const; | |||
795 | ||||
796 | /// Return true if this node is the only use of N. | |||
797 | bool isOnlyUserOf(const SDNode *N) const; | |||
798 | ||||
799 | /// Return true if this node is an operand of N. | |||
800 | bool isOperandOf(const SDNode *N) const; | |||
801 | ||||
802 | /// Return true if this node is a predecessor of N. | |||
803 | /// NOTE: Implemented on top of hasPredecessor and every bit as | |||
804 | /// expensive. Use carefully. | |||
805 | bool isPredecessorOf(const SDNode *N) const { | |||
806 | return N->hasPredecessor(this); | |||
807 | } | |||
808 | ||||
809 | /// Return true if N is a predecessor of this node. | |||
810 | /// N is either an operand of this node, or can be reached by recursively | |||
811 | /// traversing up the operands. | |||
812 | /// NOTE: This is an expensive method. Use it carefully. | |||
813 | bool hasPredecessor(const SDNode *N) const; | |||
814 | ||||
815 | /// Returns true if N is a predecessor of any node in Worklist. This | |||
816 | /// helper keeps Visited and Worklist sets externally to allow unions | |||
817 | /// searches to be performed in parallel, caching of results across | |||
818 | /// queries and incremental addition to Worklist. Stops early if N is | |||
819 | /// found but will resume. Remember to clear Visited and Worklists | |||
820 | /// if DAG changes. MaxSteps gives a maximum number of nodes to visit before | |||
821 | /// giving up. The TopologicalPrune flag signals that positive NodeIds are | |||
822 | /// topologically ordered (Operands have strictly smaller node id) and search | |||
823 | /// can be pruned leveraging this. | |||
824 | static bool hasPredecessorHelper(const SDNode *N, | |||
825 | SmallPtrSetImpl<const SDNode *> &Visited, | |||
826 | SmallVectorImpl<const SDNode *> &Worklist, | |||
827 | unsigned int MaxSteps = 0, | |||
828 | bool TopologicalPrune = false) { | |||
829 | SmallVector<const SDNode *, 8> DeferredNodes; | |||
830 | if (Visited.count(N)) | |||
831 | return true; | |||
832 | ||||
833 | // Node Id's are assigned in three places: As a topological | |||
834 | // ordering (> 0), during legalization (results in values set to | |||
835 | // 0), new nodes (set to -1). If N has a topolgical id then we | |||
836 | // know that all nodes with ids smaller than it cannot be | |||
837 | // successors and we need not check them. Filter out all node | |||
838 | // that can't be matches. We add them to the worklist before exit | |||
839 | // in case of multiple calls. Note that during selection the topological id | |||
840 | // may be violated if a node's predecessor is selected before it. We mark | |||
841 | // this at selection negating the id of unselected successors and | |||
842 | // restricting topological pruning to positive ids. | |||
843 | ||||
844 | int NId = N->getNodeId(); | |||
845 | // If we Invalidated the Id, reconstruct original NId. | |||
846 | if (NId < -1) | |||
847 | NId = -(NId + 1); | |||
848 | ||||
849 | bool Found = false; | |||
850 | while (!Worklist.empty()) { | |||
851 | const SDNode *M = Worklist.pop_back_val(); | |||
852 | int MId = M->getNodeId(); | |||
853 | if (TopologicalPrune && M->getOpcode() != ISD::TokenFactor && (NId > 0) && | |||
854 | (MId > 0) && (MId < NId)) { | |||
855 | DeferredNodes.push_back(M); | |||
856 | continue; | |||
857 | } | |||
858 | for (const SDValue &OpV : M->op_values()) { | |||
859 | SDNode *Op = OpV.getNode(); | |||
860 | if (Visited.insert(Op).second) | |||
861 | Worklist.push_back(Op); | |||
862 | if (Op == N) | |||
863 | Found = true; | |||
864 | } | |||
865 | if (Found) | |||
866 | break; | |||
867 | if (MaxSteps != 0 && Visited.size() >= MaxSteps) | |||
868 | break; | |||
869 | } | |||
870 | // Push deferred nodes back on worklist. | |||
871 | Worklist.append(DeferredNodes.begin(), DeferredNodes.end()); | |||
872 | // If we bailed early, conservatively return found. | |||
873 | if (MaxSteps != 0 && Visited.size() >= MaxSteps) | |||
874 | return true; | |||
875 | return Found; | |||
876 | } | |||
877 | ||||
878 | /// Return true if all the users of N are contained in Nodes. | |||
879 | /// NOTE: Requires at least one match, but doesn't require them all. | |||
880 | static bool areOnlyUsersOf(ArrayRef<const SDNode *> Nodes, const SDNode *N); | |||
881 | ||||
882 | /// Return the number of values used by this operation. | |||
883 | unsigned getNumOperands() const { return NumOperands; } | |||
884 | ||||
885 | /// Return the maximum number of operands that a SDNode can hold. | |||
886 | static constexpr size_t getMaxNumOperands() { | |||
887 | return std::numeric_limits<decltype(SDNode::NumOperands)>::max(); | |||
888 | } | |||
889 | ||||
890 | /// Helper method returns the integer value of a ConstantSDNode operand. | |||
891 | inline uint64_t getConstantOperandVal(unsigned Num) const; | |||
892 | ||||
893 | /// Helper method returns the APInt of a ConstantSDNode operand. | |||
894 | inline const APInt &getConstantOperandAPInt(unsigned Num) const; | |||
895 | ||||
896 | const SDValue &getOperand(unsigned Num) const { | |||
897 | assert(Num < NumOperands && "Invalid child # of SDNode!")(static_cast <bool> (Num < NumOperands && "Invalid child # of SDNode!" ) ? void (0) : __assert_fail ("Num < NumOperands && \"Invalid child # of SDNode!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 897, __extension__ __PRETTY_FUNCTION__)); | |||
898 | return OperandList[Num]; | |||
899 | } | |||
900 | ||||
901 | using op_iterator = SDUse *; | |||
902 | ||||
903 | op_iterator op_begin() const { return OperandList; } | |||
904 | op_iterator op_end() const { return OperandList+NumOperands; } | |||
905 | ArrayRef<SDUse> ops() const { return makeArrayRef(op_begin(), op_end()); } | |||
906 | ||||
907 | /// Iterator for directly iterating over the operand SDValue's. | |||
908 | struct value_op_iterator | |||
909 | : iterator_adaptor_base<value_op_iterator, op_iterator, | |||
910 | std::random_access_iterator_tag, SDValue, | |||
911 | ptrdiff_t, value_op_iterator *, | |||
912 | value_op_iterator *> { | |||
913 | explicit value_op_iterator(SDUse *U = nullptr) | |||
914 | : iterator_adaptor_base(U) {} | |||
915 | ||||
916 | const SDValue &operator*() const { return I->get(); } | |||
917 | }; | |||
918 | ||||
919 | iterator_range<value_op_iterator> op_values() const { | |||
920 | return make_range(value_op_iterator(op_begin()), | |||
921 | value_op_iterator(op_end())); | |||
922 | } | |||
923 | ||||
924 | SDVTList getVTList() const { | |||
925 | SDVTList X = { ValueList, NumValues }; | |||
926 | return X; | |||
927 | } | |||
928 | ||||
929 | /// If this node has a glue operand, return the node | |||
930 | /// to which the glue operand points. Otherwise return NULL. | |||
931 | SDNode *getGluedNode() const { | |||
932 | if (getNumOperands() != 0 && | |||
933 | getOperand(getNumOperands()-1).getValueType() == MVT::Glue) | |||
934 | return getOperand(getNumOperands()-1).getNode(); | |||
935 | return nullptr; | |||
936 | } | |||
937 | ||||
938 | /// If this node has a glue value with a user, return | |||
939 | /// the user (there is at most one). Otherwise return NULL. | |||
940 | SDNode *getGluedUser() const { | |||
941 | for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI) | |||
942 | if (UI.getUse().get().getValueType() == MVT::Glue) | |||
943 | return *UI; | |||
944 | return nullptr; | |||
945 | } | |||
946 | ||||
947 | SDNodeFlags getFlags() const { return Flags; } | |||
948 | void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; } | |||
949 | ||||
950 | /// Clear any flags in this node that aren't also set in Flags. | |||
951 | /// If Flags is not in a defined state then this has no effect. | |||
952 | void intersectFlagsWith(const SDNodeFlags Flags); | |||
953 | ||||
954 | /// Return the number of values defined/returned by this operator. | |||
955 | unsigned getNumValues() const { return NumValues; } | |||
956 | ||||
957 | /// Return the type of a specified result. | |||
958 | EVT getValueType(unsigned ResNo) const { | |||
959 | assert(ResNo < NumValues && "Illegal result number!")(static_cast <bool> (ResNo < NumValues && "Illegal result number!" ) ? void (0) : __assert_fail ("ResNo < NumValues && \"Illegal result number!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 959, __extension__ __PRETTY_FUNCTION__)); | |||
960 | return ValueList[ResNo]; | |||
961 | } | |||
962 | ||||
963 | /// Return the type of a specified result as a simple type. | |||
964 | MVT getSimpleValueType(unsigned ResNo) const { | |||
965 | return getValueType(ResNo).getSimpleVT(); | |||
966 | } | |||
967 | ||||
968 | /// Returns MVT::getSizeInBits(getValueType(ResNo)). | |||
969 | /// | |||
970 | /// If the value type is a scalable vector type, the scalable property will | |||
971 | /// be set and the runtime size will be a positive integer multiple of the | |||
972 | /// base size. | |||
973 | TypeSize getValueSizeInBits(unsigned ResNo) const { | |||
974 | return getValueType(ResNo).getSizeInBits(); | |||
975 | } | |||
976 | ||||
977 | using value_iterator = const EVT *; | |||
978 | ||||
979 | value_iterator value_begin() const { return ValueList; } | |||
980 | value_iterator value_end() const { return ValueList+NumValues; } | |||
981 | iterator_range<value_iterator> values() const { | |||
982 | return llvm::make_range(value_begin(), value_end()); | |||
983 | } | |||
984 | ||||
985 | /// Return the opcode of this operation for printing. | |||
986 | std::string getOperationName(const SelectionDAG *G = nullptr) const; | |||
987 | static const char* getIndexedModeName(ISD::MemIndexedMode AM); | |||
988 | void print_types(raw_ostream &OS, const SelectionDAG *G) const; | |||
989 | void print_details(raw_ostream &OS, const SelectionDAG *G) const; | |||
990 | void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const; | |||
991 | void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const; | |||
992 | ||||
993 | /// Print a SelectionDAG node and all children down to | |||
994 | /// the leaves. The given SelectionDAG allows target-specific nodes | |||
995 | /// to be printed in human-readable form. Unlike printr, this will | |||
996 | /// print the whole DAG, including children that appear multiple | |||
997 | /// times. | |||
998 | /// | |||
999 | void printrFull(raw_ostream &O, const SelectionDAG *G = nullptr) const; | |||
1000 | ||||
1001 | /// Print a SelectionDAG node and children up to | |||
1002 | /// depth "depth." The given SelectionDAG allows target-specific | |||
1003 | /// nodes to be printed in human-readable form. Unlike printr, this | |||
1004 | /// will print children that appear multiple times wherever they are | |||
1005 | /// used. | |||
1006 | /// | |||
1007 | void printrWithDepth(raw_ostream &O, const SelectionDAG *G = nullptr, | |||
1008 | unsigned depth = 100) const; | |||
1009 | ||||
1010 | /// Dump this node, for debugging. | |||
1011 | void dump() const; | |||
1012 | ||||
1013 | /// Dump (recursively) this node and its use-def subgraph. | |||
1014 | void dumpr() const; | |||
1015 | ||||
1016 | /// Dump this node, for debugging. | |||
1017 | /// The given SelectionDAG allows target-specific nodes to be printed | |||
1018 | /// in human-readable form. | |||
1019 | void dump(const SelectionDAG *G) const; | |||
1020 | ||||
1021 | /// Dump (recursively) this node and its use-def subgraph. | |||
1022 | /// The given SelectionDAG allows target-specific nodes to be printed | |||
1023 | /// in human-readable form. | |||
1024 | void dumpr(const SelectionDAG *G) const; | |||
1025 | ||||
1026 | /// printrFull to dbgs(). The given SelectionDAG allows | |||
1027 | /// target-specific nodes to be printed in human-readable form. | |||
1028 | /// Unlike dumpr, this will print the whole DAG, including children | |||
1029 | /// that appear multiple times. | |||
1030 | void dumprFull(const SelectionDAG *G = nullptr) const; | |||
1031 | ||||
1032 | /// printrWithDepth to dbgs(). The given | |||
1033 | /// SelectionDAG allows target-specific nodes to be printed in | |||
1034 | /// human-readable form. Unlike dumpr, this will print children | |||
1035 | /// that appear multiple times wherever they are used. | |||
1036 | /// | |||
1037 | void dumprWithDepth(const SelectionDAG *G = nullptr, | |||
1038 | unsigned depth = 100) const; | |||
1039 | ||||
1040 | /// Gather unique data for the node. | |||
1041 | void Profile(FoldingSetNodeID &ID) const; | |||
1042 | ||||
1043 | /// This method should only be used by the SDUse class. | |||
1044 | void addUse(SDUse &U) { U.addToList(&UseList); } | |||
1045 | ||||
1046 | protected: | |||
1047 | static SDVTList getSDVTList(EVT VT) { | |||
1048 | SDVTList Ret = { getValueTypeList(VT), 1 }; | |||
1049 | return Ret; | |||
1050 | } | |||
1051 | ||||
1052 | /// Create an SDNode. | |||
1053 | /// | |||
1054 | /// SDNodes are created without any operands, and never own the operand | |||
1055 | /// storage. To add operands, see SelectionDAG::createOperands. | |||
1056 | SDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs) | |||
1057 | : NodeType(Opc), ValueList(VTs.VTs), NumValues(VTs.NumVTs), | |||
1058 | IROrder(Order), debugLoc(std::move(dl)) { | |||
1059 | memset(&RawSDNodeBits, 0, sizeof(RawSDNodeBits)); | |||
1060 | assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor")(static_cast <bool> (debugLoc.hasTrivialDestructor() && "Expected trivial destructor") ? void (0) : __assert_fail ("debugLoc.hasTrivialDestructor() && \"Expected trivial destructor\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1060, __extension__ __PRETTY_FUNCTION__)); | |||
1061 | assert(NumValues == VTs.NumVTs &&(static_cast <bool> (NumValues == VTs.NumVTs && "NumValues wasn't wide enough for its operands!") ? void (0) : __assert_fail ("NumValues == VTs.NumVTs && \"NumValues wasn't wide enough for its operands!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1062, __extension__ __PRETTY_FUNCTION__)) | |||
1062 | "NumValues wasn't wide enough for its operands!")(static_cast <bool> (NumValues == VTs.NumVTs && "NumValues wasn't wide enough for its operands!") ? void (0) : __assert_fail ("NumValues == VTs.NumVTs && \"NumValues wasn't wide enough for its operands!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1062, __extension__ __PRETTY_FUNCTION__)); | |||
1063 | } | |||
1064 | ||||
1065 | /// Release the operands and set this node to have zero operands. | |||
1066 | void DropOperands(); | |||
1067 | }; | |||
1068 | ||||
1069 | /// Wrapper class for IR location info (IR ordering and DebugLoc) to be passed | |||
1070 | /// into SDNode creation functions. | |||
1071 | /// When an SDNode is created from the DAGBuilder, the DebugLoc is extracted | |||
1072 | /// from the original Instruction, and IROrder is the ordinal position of | |||
1073 | /// the instruction. | |||
1074 | /// When an SDNode is created after the DAG is being built, both DebugLoc and | |||
1075 | /// the IROrder are propagated from the original SDNode. | |||
1076 | /// So SDLoc class provides two constructors besides the default one, one to | |||
1077 | /// be used by the DAGBuilder, the other to be used by others. | |||
1078 | class SDLoc { | |||
1079 | private: | |||
1080 | DebugLoc DL; | |||
1081 | int IROrder = 0; | |||
1082 | ||||
1083 | public: | |||
1084 | SDLoc() = default; | |||
1085 | SDLoc(const SDNode *N) : DL(N->getDebugLoc()), IROrder(N->getIROrder()) {} | |||
1086 | SDLoc(const SDValue V) : SDLoc(V.getNode()) {} | |||
1087 | SDLoc(const Instruction *I, int Order) : IROrder(Order) { | |||
1088 | assert(Order >= 0 && "bad IROrder")(static_cast <bool> (Order >= 0 && "bad IROrder" ) ? void (0) : __assert_fail ("Order >= 0 && \"bad IROrder\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1088, __extension__ __PRETTY_FUNCTION__)); | |||
1089 | if (I) | |||
1090 | DL = I->getDebugLoc(); | |||
1091 | } | |||
1092 | ||||
1093 | unsigned getIROrder() const { return IROrder; } | |||
1094 | const DebugLoc &getDebugLoc() const { return DL; } | |||
1095 | }; | |||
1096 | ||||
1097 | // Define inline functions from the SDValue class. | |||
1098 | ||||
1099 | inline SDValue::SDValue(SDNode *node, unsigned resno) | |||
1100 | : Node(node), ResNo(resno) { | |||
1101 | // Explicitly check for !ResNo to avoid use-after-free, because there are | |||
1102 | // callers that use SDValue(N, 0) with a deleted N to indicate successful | |||
1103 | // combines. | |||
1104 | assert((!Node || !ResNo || ResNo < Node->getNumValues()) &&(static_cast <bool> ((!Node || !ResNo || ResNo < Node ->getNumValues()) && "Invalid result number for the given node!" ) ? void (0) : __assert_fail ("(!Node || !ResNo || ResNo < Node->getNumValues()) && \"Invalid result number for the given node!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1105, __extension__ __PRETTY_FUNCTION__)) | |||
1105 | "Invalid result number for the given node!")(static_cast <bool> ((!Node || !ResNo || ResNo < Node ->getNumValues()) && "Invalid result number for the given node!" ) ? void (0) : __assert_fail ("(!Node || !ResNo || ResNo < Node->getNumValues()) && \"Invalid result number for the given node!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1105, __extension__ __PRETTY_FUNCTION__)); | |||
1106 | assert(ResNo < -2U && "Cannot use result numbers reserved for DenseMaps.")(static_cast <bool> (ResNo < -2U && "Cannot use result numbers reserved for DenseMaps." ) ? void (0) : __assert_fail ("ResNo < -2U && \"Cannot use result numbers reserved for DenseMaps.\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1106, __extension__ __PRETTY_FUNCTION__)); | |||
1107 | } | |||
1108 | ||||
1109 | inline unsigned SDValue::getOpcode() const { | |||
1110 | return Node->getOpcode(); | |||
1111 | } | |||
1112 | ||||
1113 | inline EVT SDValue::getValueType() const { | |||
1114 | return Node->getValueType(ResNo); | |||
| ||||
1115 | } | |||
1116 | ||||
1117 | inline unsigned SDValue::getNumOperands() const { | |||
1118 | return Node->getNumOperands(); | |||
1119 | } | |||
1120 | ||||
1121 | inline const SDValue &SDValue::getOperand(unsigned i) const { | |||
1122 | return Node->getOperand(i); | |||
1123 | } | |||
1124 | ||||
1125 | inline uint64_t SDValue::getConstantOperandVal(unsigned i) const { | |||
1126 | return Node->getConstantOperandVal(i); | |||
1127 | } | |||
1128 | ||||
1129 | inline const APInt &SDValue::getConstantOperandAPInt(unsigned i) const { | |||
1130 | return Node->getConstantOperandAPInt(i); | |||
1131 | } | |||
1132 | ||||
1133 | inline bool SDValue::isTargetOpcode() const { | |||
1134 | return Node->isTargetOpcode(); | |||
1135 | } | |||
1136 | ||||
1137 | inline bool SDValue::isTargetMemoryOpcode() const { | |||
1138 | return Node->isTargetMemoryOpcode(); | |||
1139 | } | |||
1140 | ||||
1141 | inline bool SDValue::isMachineOpcode() const { | |||
1142 | return Node->isMachineOpcode(); | |||
1143 | } | |||
1144 | ||||
1145 | inline unsigned SDValue::getMachineOpcode() const { | |||
1146 | return Node->getMachineOpcode(); | |||
1147 | } | |||
1148 | ||||
1149 | inline bool SDValue::isUndef() const { | |||
1150 | return Node->isUndef(); | |||
1151 | } | |||
1152 | ||||
1153 | inline bool SDValue::use_empty() const { | |||
1154 | return !Node->hasAnyUseOfValue(ResNo); | |||
1155 | } | |||
1156 | ||||
1157 | inline bool SDValue::hasOneUse() const { | |||
1158 | return Node->hasNUsesOfValue(1, ResNo); | |||
1159 | } | |||
1160 | ||||
1161 | inline const DebugLoc &SDValue::getDebugLoc() const { | |||
1162 | return Node->getDebugLoc(); | |||
1163 | } | |||
1164 | ||||
1165 | inline void SDValue::dump() const { | |||
1166 | return Node->dump(); | |||
1167 | } | |||
1168 | ||||
1169 | inline void SDValue::dump(const SelectionDAG *G) const { | |||
1170 | return Node->dump(G); | |||
1171 | } | |||
1172 | ||||
1173 | inline void SDValue::dumpr() const { | |||
1174 | return Node->dumpr(); | |||
1175 | } | |||
1176 | ||||
1177 | inline void SDValue::dumpr(const SelectionDAG *G) const { | |||
1178 | return Node->dumpr(G); | |||
1179 | } | |||
1180 | ||||
1181 | // Define inline functions from the SDUse class. | |||
1182 | ||||
1183 | inline void SDUse::set(const SDValue &V) { | |||
1184 | if (Val.getNode()) removeFromList(); | |||
1185 | Val = V; | |||
1186 | if (V.getNode()) V.getNode()->addUse(*this); | |||
1187 | } | |||
1188 | ||||
1189 | inline void SDUse::setInitial(const SDValue &V) { | |||
1190 | Val = V; | |||
1191 | V.getNode()->addUse(*this); | |||
1192 | } | |||
1193 | ||||
1194 | inline void SDUse::setNode(SDNode *N) { | |||
1195 | if (Val.getNode()) removeFromList(); | |||
1196 | Val.setNode(N); | |||
1197 | if (N) N->addUse(*this); | |||
1198 | } | |||
1199 | ||||
1200 | /// This class is used to form a handle around another node that | |||
1201 | /// is persistent and is updated across invocations of replaceAllUsesWith on its | |||
1202 | /// operand. This node should be directly created by end-users and not added to | |||
1203 | /// the AllNodes list. | |||
1204 | class HandleSDNode : public SDNode { | |||
1205 | SDUse Op; | |||
1206 | ||||
1207 | public: | |||
1208 | explicit HandleSDNode(SDValue X) | |||
1209 | : SDNode(ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) { | |||
1210 | // HandleSDNodes are never inserted into the DAG, so they won't be | |||
1211 | // auto-numbered. Use ID 65535 as a sentinel. | |||
1212 | PersistentId = 0xffff; | |||
1213 | ||||
1214 | // Manually set up the operand list. This node type is special in that it's | |||
1215 | // always stack allocated and SelectionDAG does not manage its operands. | |||
1216 | // TODO: This should either (a) not be in the SDNode hierarchy, or (b) not | |||
1217 | // be so special. | |||
1218 | Op.setUser(this); | |||
1219 | Op.setInitial(X); | |||
1220 | NumOperands = 1; | |||
1221 | OperandList = &Op; | |||
1222 | } | |||
1223 | ~HandleSDNode(); | |||
1224 | ||||
1225 | const SDValue &getValue() const { return Op; } | |||
1226 | }; | |||
1227 | ||||
1228 | class AddrSpaceCastSDNode : public SDNode { | |||
1229 | private: | |||
1230 | unsigned SrcAddrSpace; | |||
1231 | unsigned DestAddrSpace; | |||
1232 | ||||
1233 | public: | |||
1234 | AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, EVT VT, | |||
1235 | unsigned SrcAS, unsigned DestAS); | |||
1236 | ||||
1237 | unsigned getSrcAddressSpace() const { return SrcAddrSpace; } | |||
1238 | unsigned getDestAddressSpace() const { return DestAddrSpace; } | |||
1239 | ||||
1240 | static bool classof(const SDNode *N) { | |||
1241 | return N->getOpcode() == ISD::ADDRSPACECAST; | |||
1242 | } | |||
1243 | }; | |||
1244 | ||||
1245 | /// This is an abstract virtual class for memory operations. | |||
1246 | class MemSDNode : public SDNode { | |||
1247 | private: | |||
1248 | // VT of in-memory value. | |||
1249 | EVT MemoryVT; | |||
1250 | ||||
1251 | protected: | |||
1252 | /// Memory reference information. | |||
1253 | MachineMemOperand *MMO; | |||
1254 | ||||
1255 | public: | |||
1256 | MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs, | |||
1257 | EVT memvt, MachineMemOperand *MMO); | |||
1258 | ||||
1259 | bool readMem() const { return MMO->isLoad(); } | |||
1260 | bool writeMem() const { return MMO->isStore(); } | |||
1261 | ||||
1262 | /// Returns alignment and volatility of the memory access | |||
1263 | Align getOriginalAlign() const { return MMO->getBaseAlign(); } | |||
1264 | Align getAlign() const { return MMO->getAlign(); } | |||
1265 | // FIXME: Remove once transition to getAlign is over. | |||
1266 | unsigned getAlignment() const { return MMO->getAlign().value(); } | |||
1267 | ||||
1268 | /// Return the SubclassData value, without HasDebugValue. This contains an | |||
1269 | /// encoding of the volatile flag, as well as bits used by subclasses. This | |||
1270 | /// function should only be used to compute a FoldingSetNodeID value. | |||
1271 | /// The HasDebugValue bit is masked out because CSE map needs to match | |||
1272 | /// nodes with debug info with nodes without debug info. Same is about | |||
1273 | /// isDivergent bit. | |||
1274 | unsigned getRawSubclassData() const { | |||
1275 | uint16_t Data; | |||
1276 | union { | |||
1277 | char RawSDNodeBits[sizeof(uint16_t)]; | |||
1278 | SDNodeBitfields SDNodeBits; | |||
1279 | }; | |||
1280 | memcpy(&RawSDNodeBits, &this->RawSDNodeBits, sizeof(this->RawSDNodeBits)); | |||
1281 | SDNodeBits.HasDebugValue = 0; | |||
1282 | SDNodeBits.IsDivergent = false; | |||
1283 | memcpy(&Data, &RawSDNodeBits, sizeof(RawSDNodeBits)); | |||
1284 | return Data; | |||
1285 | } | |||
1286 | ||||
1287 | bool isVolatile() const { return MemSDNodeBits.IsVolatile; } | |||
1288 | bool isNonTemporal() const { return MemSDNodeBits.IsNonTemporal; } | |||
1289 | bool isDereferenceable() const { return MemSDNodeBits.IsDereferenceable; } | |||
1290 | bool isInvariant() const { return MemSDNodeBits.IsInvariant; } | |||
1291 | ||||
1292 | // Returns the offset from the location of the access. | |||
1293 | int64_t getSrcValueOffset() const { return MMO->getOffset(); } | |||
1294 | ||||
1295 | /// Returns the AA info that describes the dereference. | |||
1296 | AAMDNodes getAAInfo() const { return MMO->getAAInfo(); } | |||
1297 | ||||
1298 | /// Returns the Ranges that describes the dereference. | |||
1299 | const MDNode *getRanges() const { return MMO->getRanges(); } | |||
1300 | ||||
1301 | /// Returns the synchronization scope ID for this memory operation. | |||
1302 | SyncScope::ID getSyncScopeID() const { return MMO->getSyncScopeID(); } | |||
1303 | ||||
1304 | /// Return the atomic ordering requirements for this memory operation. For | |||
1305 | /// cmpxchg atomic operations, return the atomic ordering requirements when | |||
1306 | /// store occurs. | |||
1307 | AtomicOrdering getSuccessOrdering() const { | |||
1308 | return MMO->getSuccessOrdering(); | |||
1309 | } | |||
1310 | ||||
1311 | /// Return a single atomic ordering that is at least as strong as both the | |||
1312 | /// success and failure orderings for an atomic operation. (For operations | |||
1313 | /// other than cmpxchg, this is equivalent to getSuccessOrdering().) | |||
1314 | AtomicOrdering getMergedOrdering() const { return MMO->getMergedOrdering(); } | |||
1315 | ||||
1316 | /// Return true if the memory operation ordering is Unordered or higher. | |||
1317 | bool isAtomic() const { return MMO->isAtomic(); } | |||
1318 | ||||
1319 | /// Returns true if the memory operation doesn't imply any ordering | |||
1320 | /// constraints on surrounding memory operations beyond the normal memory | |||
1321 | /// aliasing rules. | |||
1322 | bool isUnordered() const { return MMO->isUnordered(); } | |||
1323 | ||||
1324 | /// Returns true if the memory operation is neither atomic or volatile. | |||
1325 | bool isSimple() const { return !isAtomic() && !isVolatile(); } | |||
1326 | ||||
1327 | /// Return the type of the in-memory value. | |||
1328 | EVT getMemoryVT() const { return MemoryVT; } | |||
1329 | ||||
1330 | /// Return a MachineMemOperand object describing the memory | |||
1331 | /// reference performed by operation. | |||
1332 | MachineMemOperand *getMemOperand() const { return MMO; } | |||
1333 | ||||
1334 | const MachinePointerInfo &getPointerInfo() const { | |||
1335 | return MMO->getPointerInfo(); | |||
1336 | } | |||
1337 | ||||
1338 | /// Return the address space for the associated pointer | |||
1339 | unsigned getAddressSpace() const { | |||
1340 | return getPointerInfo().getAddrSpace(); | |||
1341 | } | |||
1342 | ||||
1343 | /// Update this MemSDNode's MachineMemOperand information | |||
1344 | /// to reflect the alignment of NewMMO, if it has a greater alignment. | |||
1345 | /// This must only be used when the new alignment applies to all users of | |||
1346 | /// this MachineMemOperand. | |||
1347 | void refineAlignment(const MachineMemOperand *NewMMO) { | |||
1348 | MMO->refineAlignment(NewMMO); | |||
1349 | } | |||
1350 | ||||
1351 | const SDValue &getChain() const { return getOperand(0); } | |||
1352 | ||||
1353 | const SDValue &getBasePtr() const { | |||
1354 | switch (getOpcode()) { | |||
1355 | case ISD::STORE: | |||
1356 | case ISD::MSTORE: | |||
1357 | return getOperand(2); | |||
1358 | case ISD::MGATHER: | |||
1359 | case ISD::MSCATTER: | |||
1360 | return getOperand(3); | |||
1361 | default: | |||
1362 | return getOperand(1); | |||
1363 | } | |||
1364 | } | |||
1365 | ||||
1366 | // Methods to support isa and dyn_cast | |||
1367 | static bool classof(const SDNode *N) { | |||
1368 | // For some targets, we lower some target intrinsics to a MemIntrinsicNode | |||
1369 | // with either an intrinsic or a target opcode. | |||
1370 | switch (N->getOpcode()) { | |||
1371 | case ISD::LOAD: | |||
1372 | case ISD::STORE: | |||
1373 | case ISD::PREFETCH: | |||
1374 | case ISD::ATOMIC_CMP_SWAP: | |||
1375 | case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: | |||
1376 | case ISD::ATOMIC_SWAP: | |||
1377 | case ISD::ATOMIC_LOAD_ADD: | |||
1378 | case ISD::ATOMIC_LOAD_SUB: | |||
1379 | case ISD::ATOMIC_LOAD_AND: | |||
1380 | case ISD::ATOMIC_LOAD_CLR: | |||
1381 | case ISD::ATOMIC_LOAD_OR: | |||
1382 | case ISD::ATOMIC_LOAD_XOR: | |||
1383 | case ISD::ATOMIC_LOAD_NAND: | |||
1384 | case ISD::ATOMIC_LOAD_MIN: | |||
1385 | case ISD::ATOMIC_LOAD_MAX: | |||
1386 | case ISD::ATOMIC_LOAD_UMIN: | |||
1387 | case ISD::ATOMIC_LOAD_UMAX: | |||
1388 | case ISD::ATOMIC_LOAD_FADD: | |||
1389 | case ISD::ATOMIC_LOAD_FSUB: | |||
1390 | case ISD::ATOMIC_LOAD: | |||
1391 | case ISD::ATOMIC_STORE: | |||
1392 | case ISD::MLOAD: | |||
1393 | case ISD::MSTORE: | |||
1394 | case ISD::MGATHER: | |||
1395 | case ISD::MSCATTER: | |||
1396 | return true; | |||
1397 | default: | |||
1398 | return N->isMemIntrinsic() || N->isTargetMemoryOpcode(); | |||
1399 | } | |||
1400 | } | |||
1401 | }; | |||
1402 | ||||
1403 | /// This is an SDNode representing atomic operations. | |||
1404 | class AtomicSDNode : public MemSDNode { | |||
1405 | public: | |||
1406 | AtomicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTL, | |||
1407 | EVT MemVT, MachineMemOperand *MMO) | |||
1408 | : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) { | |||
1409 | assert(((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) ||(static_cast <bool> (((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) || MMO->isAtomic()) && "then why are we using an AtomicSDNode?" ) ? void (0) : __assert_fail ("((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) || MMO->isAtomic()) && \"then why are we using an AtomicSDNode?\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1410, __extension__ __PRETTY_FUNCTION__)) | |||
1410 | MMO->isAtomic()) && "then why are we using an AtomicSDNode?")(static_cast <bool> (((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) || MMO->isAtomic()) && "then why are we using an AtomicSDNode?" ) ? void (0) : __assert_fail ("((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) || MMO->isAtomic()) && \"then why are we using an AtomicSDNode?\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1410, __extension__ __PRETTY_FUNCTION__)); | |||
1411 | } | |||
1412 | ||||
1413 | const SDValue &getBasePtr() const { return getOperand(1); } | |||
1414 | const SDValue &getVal() const { return getOperand(2); } | |||
1415 | ||||
1416 | /// Returns true if this SDNode represents cmpxchg atomic operation, false | |||
1417 | /// otherwise. | |||
1418 | bool isCompareAndSwap() const { | |||
1419 | unsigned Op = getOpcode(); | |||
1420 | return Op == ISD::ATOMIC_CMP_SWAP || | |||
1421 | Op == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS; | |||
1422 | } | |||
1423 | ||||
1424 | /// For cmpxchg atomic operations, return the atomic ordering requirements | |||
1425 | /// when store does not occur. | |||
1426 | AtomicOrdering getFailureOrdering() const { | |||
1427 | assert(isCompareAndSwap() && "Must be cmpxchg operation")(static_cast <bool> (isCompareAndSwap() && "Must be cmpxchg operation" ) ? void (0) : __assert_fail ("isCompareAndSwap() && \"Must be cmpxchg operation\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1427, __extension__ __PRETTY_FUNCTION__)); | |||
1428 | return MMO->getFailureOrdering(); | |||
1429 | } | |||
1430 | ||||
1431 | // Methods to support isa and dyn_cast | |||
1432 | static bool classof(const SDNode *N) { | |||
1433 | return N->getOpcode() == ISD::ATOMIC_CMP_SWAP || | |||
1434 | N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS || | |||
1435 | N->getOpcode() == ISD::ATOMIC_SWAP || | |||
1436 | N->getOpcode() == ISD::ATOMIC_LOAD_ADD || | |||
1437 | N->getOpcode() == ISD::ATOMIC_LOAD_SUB || | |||
1438 | N->getOpcode() == ISD::ATOMIC_LOAD_AND || | |||
1439 | N->getOpcode() == ISD::ATOMIC_LOAD_CLR || | |||
1440 | N->getOpcode() == ISD::ATOMIC_LOAD_OR || | |||
1441 | N->getOpcode() == ISD::ATOMIC_LOAD_XOR || | |||
1442 | N->getOpcode() == ISD::ATOMIC_LOAD_NAND || | |||
1443 | N->getOpcode() == ISD::ATOMIC_LOAD_MIN || | |||
1444 | N->getOpcode() == ISD::ATOMIC_LOAD_MAX || | |||
1445 | N->getOpcode() == ISD::ATOMIC_LOAD_UMIN || | |||
1446 | N->getOpcode() == ISD::ATOMIC_LOAD_UMAX || | |||
1447 | N->getOpcode() == ISD::ATOMIC_LOAD_FADD || | |||
1448 | N->getOpcode() == ISD::ATOMIC_LOAD_FSUB || | |||
1449 | N->getOpcode() == ISD::ATOMIC_LOAD || | |||
1450 | N->getOpcode() == ISD::ATOMIC_STORE; | |||
1451 | } | |||
1452 | }; | |||
1453 | ||||
1454 | /// This SDNode is used for target intrinsics that touch | |||
1455 | /// memory and need an associated MachineMemOperand. Its opcode may be | |||
1456 | /// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode | |||
1457 | /// with a value not less than FIRST_TARGET_MEMORY_OPCODE. | |||
1458 | class MemIntrinsicSDNode : public MemSDNode { | |||
1459 | public: | |||
1460 | MemIntrinsicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, | |||
1461 | SDVTList VTs, EVT MemoryVT, MachineMemOperand *MMO) | |||
1462 | : MemSDNode(Opc, Order, dl, VTs, MemoryVT, MMO) { | |||
1463 | SDNodeBits.IsMemIntrinsic = true; | |||
1464 | } | |||
1465 | ||||
1466 | // Methods to support isa and dyn_cast | |||
1467 | static bool classof(const SDNode *N) { | |||
1468 | // We lower some target intrinsics to their target opcode | |||
1469 | // early a node with a target opcode can be of this class | |||
1470 | return N->isMemIntrinsic() || | |||
1471 | N->getOpcode() == ISD::PREFETCH || | |||
1472 | N->isTargetMemoryOpcode(); | |||
1473 | } | |||
1474 | }; | |||
1475 | ||||
1476 | /// This SDNode is used to implement the code generator | |||
1477 | /// support for the llvm IR shufflevector instruction. It combines elements | |||
1478 | /// from two input vectors into a new input vector, with the selection and | |||
1479 | /// ordering of elements determined by an array of integers, referred to as | |||
1480 | /// the shuffle mask. For input vectors of width N, mask indices of 0..N-1 | |||
1481 | /// refer to elements from the LHS input, and indices from N to 2N-1 the RHS. | |||
1482 | /// An index of -1 is treated as undef, such that the code generator may put | |||
1483 | /// any value in the corresponding element of the result. | |||
1484 | class ShuffleVectorSDNode : public SDNode { | |||
1485 | // The memory for Mask is owned by the SelectionDAG's OperandAllocator, and | |||
1486 | // is freed when the SelectionDAG object is destroyed. | |||
1487 | const int *Mask; | |||
1488 | ||||
1489 | protected: | |||
1490 | friend class SelectionDAG; | |||
1491 | ||||
1492 | ShuffleVectorSDNode(EVT VT, unsigned Order, const DebugLoc &dl, const int *M) | |||
1493 | : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, getSDVTList(VT)), Mask(M) {} | |||
1494 | ||||
1495 | public: | |||
1496 | ArrayRef<int> getMask() const { | |||
1497 | EVT VT = getValueType(0); | |||
1498 | return makeArrayRef(Mask, VT.getVectorNumElements()); | |||
1499 | } | |||
1500 | ||||
1501 | int getMaskElt(unsigned Idx) const { | |||
1502 | assert(Idx < getValueType(0).getVectorNumElements() && "Idx out of range!")(static_cast <bool> (Idx < getValueType(0).getVectorNumElements () && "Idx out of range!") ? void (0) : __assert_fail ("Idx < getValueType(0).getVectorNumElements() && \"Idx out of range!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1502, __extension__ __PRETTY_FUNCTION__)); | |||
1503 | return Mask[Idx]; | |||
1504 | } | |||
1505 | ||||
1506 | bool isSplat() const { return isSplatMask(Mask, getValueType(0)); } | |||
1507 | ||||
1508 | int getSplatIndex() const { | |||
1509 | assert(isSplat() && "Cannot get splat index for non-splat!")(static_cast <bool> (isSplat() && "Cannot get splat index for non-splat!" ) ? void (0) : __assert_fail ("isSplat() && \"Cannot get splat index for non-splat!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1509, __extension__ __PRETTY_FUNCTION__)); | |||
1510 | EVT VT = getValueType(0); | |||
1511 | for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) | |||
1512 | if (Mask[i] >= 0) | |||
1513 | return Mask[i]; | |||
1514 | ||||
1515 | // We can choose any index value here and be correct because all elements | |||
1516 | // are undefined. Return 0 for better potential for callers to simplify. | |||
1517 | return 0; | |||
1518 | } | |||
1519 | ||||
1520 | static bool isSplatMask(const int *Mask, EVT VT); | |||
1521 | ||||
1522 | /// Change values in a shuffle permute mask assuming | |||
1523 | /// the two vector operands have swapped position. | |||
1524 | static void commuteMask(MutableArrayRef<int> Mask) { | |||
1525 | unsigned NumElems = Mask.size(); | |||
1526 | for (unsigned i = 0; i != NumElems; ++i) { | |||
1527 | int idx = Mask[i]; | |||
1528 | if (idx < 0) | |||
1529 | continue; | |||
1530 | else if (idx < (int)NumElems) | |||
1531 | Mask[i] = idx + NumElems; | |||
1532 | else | |||
1533 | Mask[i] = idx - NumElems; | |||
1534 | } | |||
1535 | } | |||
1536 | ||||
1537 | static bool classof(const SDNode *N) { | |||
1538 | return N->getOpcode() == ISD::VECTOR_SHUFFLE; | |||
1539 | } | |||
1540 | }; | |||
1541 | ||||
1542 | class ConstantSDNode : public SDNode { | |||
1543 | friend class SelectionDAG; | |||
1544 | ||||
1545 | const ConstantInt *Value; | |||
1546 | ||||
1547 | ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val, EVT VT) | |||
1548 | : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, 0, DebugLoc(), | |||
1549 | getSDVTList(VT)), | |||
1550 | Value(val) { | |||
1551 | ConstantSDNodeBits.IsOpaque = isOpaque; | |||
1552 | } | |||
1553 | ||||
1554 | public: | |||
1555 | const ConstantInt *getConstantIntValue() const { return Value; } | |||
1556 | const APInt &getAPIntValue() const { return Value->getValue(); } | |||
1557 | uint64_t getZExtValue() const { return Value->getZExtValue(); } | |||
1558 | int64_t getSExtValue() const { return Value->getSExtValue(); } | |||
1559 | uint64_t getLimitedValue(uint64_t Limit = UINT64_MAX(18446744073709551615UL)) { | |||
1560 | return Value->getLimitedValue(Limit); | |||
1561 | } | |||
1562 | MaybeAlign getMaybeAlignValue() const { return Value->getMaybeAlignValue(); } | |||
1563 | Align getAlignValue() const { return Value->getAlignValue(); } | |||
1564 | ||||
1565 | bool isOne() const { return Value->isOne(); } | |||
1566 | bool isNullValue() const { return Value->isZero(); } | |||
1567 | bool isAllOnesValue() const { return Value->isMinusOne(); } | |||
1568 | bool isMaxSignedValue() const { return Value->isMaxValue(true); } | |||
1569 | bool isMinSignedValue() const { return Value->isMinValue(true); } | |||
1570 | ||||
1571 | bool isOpaque() const { return ConstantSDNodeBits.IsOpaque; } | |||
1572 | ||||
1573 | static bool classof(const SDNode *N) { | |||
1574 | return N->getOpcode() == ISD::Constant || | |||
1575 | N->getOpcode() == ISD::TargetConstant; | |||
1576 | } | |||
1577 | }; | |||
1578 | ||||
1579 | uint64_t SDNode::getConstantOperandVal(unsigned Num) const { | |||
1580 | return cast<ConstantSDNode>(getOperand(Num))->getZExtValue(); | |||
1581 | } | |||
1582 | ||||
1583 | const APInt &SDNode::getConstantOperandAPInt(unsigned Num) const { | |||
1584 | return cast<ConstantSDNode>(getOperand(Num))->getAPIntValue(); | |||
1585 | } | |||
1586 | ||||
1587 | class ConstantFPSDNode : public SDNode { | |||
1588 | friend class SelectionDAG; | |||
1589 | ||||
1590 | const ConstantFP *Value; | |||
1591 | ||||
1592 | ConstantFPSDNode(bool isTarget, const ConstantFP *val, EVT VT) | |||
1593 | : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, 0, | |||
1594 | DebugLoc(), getSDVTList(VT)), | |||
1595 | Value(val) {} | |||
1596 | ||||
1597 | public: | |||
1598 | const APFloat& getValueAPF() const { return Value->getValueAPF(); } | |||
1599 | const ConstantFP *getConstantFPValue() const { return Value; } | |||
1600 | ||||
1601 | /// Return true if the value is positive or negative zero. | |||
1602 | bool isZero() const { return Value->isZero(); } | |||
1603 | ||||
1604 | /// Return true if the value is a NaN. | |||
1605 | bool isNaN() const { return Value->isNaN(); } | |||
1606 | ||||
1607 | /// Return true if the value is an infinity | |||
1608 | bool isInfinity() const { return Value->isInfinity(); } | |||
1609 | ||||
1610 | /// Return true if the value is negative. | |||
1611 | bool isNegative() const { return Value->isNegative(); } | |||
1612 | ||||
1613 | /// We don't rely on operator== working on double values, as | |||
1614 | /// it returns true for things that are clearly not equal, like -0.0 and 0.0. | |||
1615 | /// As such, this method can be used to do an exact bit-for-bit comparison of | |||
1616 | /// two floating point values. | |||
1617 | ||||
1618 | /// We leave the version with the double argument here because it's just so | |||
1619 | /// convenient to write "2.0" and the like. Without this function we'd | |||
1620 | /// have to duplicate its logic everywhere it's called. | |||
1621 | bool isExactlyValue(double V) const { | |||
1622 | return Value->getValueAPF().isExactlyValue(V); | |||
1623 | } | |||
1624 | bool isExactlyValue(const APFloat& V) const; | |||
1625 | ||||
1626 | static bool isValueValidForType(EVT VT, const APFloat& Val); | |||
1627 | ||||
1628 | static bool classof(const SDNode *N) { | |||
1629 | return N->getOpcode() == ISD::ConstantFP || | |||
1630 | N->getOpcode() == ISD::TargetConstantFP; | |||
1631 | } | |||
1632 | }; | |||
1633 | ||||
1634 | /// Returns true if \p V is a constant integer zero. | |||
1635 | bool isNullConstant(SDValue V); | |||
1636 | ||||
1637 | /// Returns true if \p V is an FP constant with a value of positive zero. | |||
1638 | bool isNullFPConstant(SDValue V); | |||
1639 | ||||
1640 | /// Returns true if \p V is an integer constant with all bits set. | |||
1641 | bool isAllOnesConstant(SDValue V); | |||
1642 | ||||
1643 | /// Returns true if \p V is a constant integer one. | |||
1644 | bool isOneConstant(SDValue V); | |||
1645 | ||||
1646 | /// Return the non-bitcasted source operand of \p V if it exists. | |||
1647 | /// If \p V is not a bitcasted value, it is returned as-is. | |||
1648 | SDValue peekThroughBitcasts(SDValue V); | |||
1649 | ||||
1650 | /// Return the non-bitcasted and one-use source operand of \p V if it exists. | |||
1651 | /// If \p V is not a bitcasted one-use value, it is returned as-is. | |||
1652 | SDValue peekThroughOneUseBitcasts(SDValue V); | |||
1653 | ||||
1654 | /// Return the non-extracted vector source operand of \p V if it exists. | |||
1655 | /// If \p V is not an extracted subvector, it is returned as-is. | |||
1656 | SDValue peekThroughExtractSubvectors(SDValue V); | |||
1657 | ||||
1658 | /// Returns true if \p V is a bitwise not operation. Assumes that an all ones | |||
1659 | /// constant is canonicalized to be operand 1. | |||
1660 | bool isBitwiseNot(SDValue V, bool AllowUndefs = false); | |||
1661 | ||||
1662 | /// Returns the SDNode if it is a constant splat BuildVector or constant int. | |||
1663 | ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false, | |||
1664 | bool AllowTruncation = false); | |||
1665 | ||||
1666 | /// Returns the SDNode if it is a demanded constant splat BuildVector or | |||
1667 | /// constant int. | |||
1668 | ConstantSDNode *isConstOrConstSplat(SDValue N, const APInt &DemandedElts, | |||
1669 | bool AllowUndefs = false, | |||
1670 | bool AllowTruncation = false); | |||
1671 | ||||
1672 | /// Returns the SDNode if it is a constant splat BuildVector or constant float. | |||
1673 | ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, bool AllowUndefs = false); | |||
1674 | ||||
1675 | /// Returns the SDNode if it is a demanded constant splat BuildVector or | |||
1676 | /// constant float. | |||
1677 | ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, const APInt &DemandedElts, | |||
1678 | bool AllowUndefs = false); | |||
1679 | ||||
1680 | /// Return true if the value is a constant 0 integer or a splatted vector of | |||
1681 | /// a constant 0 integer (with no undefs by default). | |||
1682 | /// Build vector implicit truncation is not an issue for null values. | |||
1683 | bool isNullOrNullSplat(SDValue V, bool AllowUndefs = false); | |||
1684 | ||||
1685 | /// Return true if the value is a constant 1 integer or a splatted vector of a | |||
1686 | /// constant 1 integer (with no undefs). | |||
1687 | /// Does not permit build vector implicit truncation. | |||
1688 | bool isOneOrOneSplat(SDValue V, bool AllowUndefs = false); | |||
1689 | ||||
1690 | /// Return true if the value is a constant -1 integer or a splatted vector of a | |||
1691 | /// constant -1 integer (with no undefs). | |||
1692 | /// Does not permit build vector implicit truncation. | |||
1693 | bool isAllOnesOrAllOnesSplat(SDValue V, bool AllowUndefs = false); | |||
1694 | ||||
1695 | /// Return true if \p V is either a integer or FP constant. | |||
1696 | inline bool isIntOrFPConstant(SDValue V) { | |||
1697 | return isa<ConstantSDNode>(V) || isa<ConstantFPSDNode>(V); | |||
1698 | } | |||
1699 | ||||
1700 | class GlobalAddressSDNode : public SDNode { | |||
1701 | friend class SelectionDAG; | |||
1702 | ||||
1703 | const GlobalValue *TheGlobal; | |||
1704 | int64_t Offset; | |||
1705 | unsigned TargetFlags; | |||
1706 | ||||
1707 | GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, | |||
1708 | const GlobalValue *GA, EVT VT, int64_t o, | |||
1709 | unsigned TF); | |||
1710 | ||||
1711 | public: | |||
1712 | const GlobalValue *getGlobal() const { return TheGlobal; } | |||
1713 | int64_t getOffset() const { return Offset; } | |||
1714 | unsigned getTargetFlags() const { return TargetFlags; } | |||
1715 | // Return the address space this GlobalAddress belongs to. | |||
1716 | unsigned getAddressSpace() const; | |||
1717 | ||||
1718 | static bool classof(const SDNode *N) { | |||
1719 | return N->getOpcode() == ISD::GlobalAddress || | |||
1720 | N->getOpcode() == ISD::TargetGlobalAddress || | |||
1721 | N->getOpcode() == ISD::GlobalTLSAddress || | |||
1722 | N->getOpcode() == ISD::TargetGlobalTLSAddress; | |||
1723 | } | |||
1724 | }; | |||
1725 | ||||
1726 | class FrameIndexSDNode : public SDNode { | |||
1727 | friend class SelectionDAG; | |||
1728 | ||||
1729 | int FI; | |||
1730 | ||||
1731 | FrameIndexSDNode(int fi, EVT VT, bool isTarg) | |||
1732 | : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, | |||
1733 | 0, DebugLoc(), getSDVTList(VT)), FI(fi) { | |||
1734 | } | |||
1735 | ||||
1736 | public: | |||
1737 | int getIndex() const { return FI; } | |||
1738 | ||||
1739 | static bool classof(const SDNode *N) { | |||
1740 | return N->getOpcode() == ISD::FrameIndex || | |||
1741 | N->getOpcode() == ISD::TargetFrameIndex; | |||
1742 | } | |||
1743 | }; | |||
1744 | ||||
1745 | /// This SDNode is used for LIFETIME_START/LIFETIME_END values, which indicate | |||
1746 | /// the offet and size that are started/ended in the underlying FrameIndex. | |||
1747 | class LifetimeSDNode : public SDNode { | |||
1748 | friend class SelectionDAG; | |||
1749 | int64_t Size; | |||
1750 | int64_t Offset; // -1 if offset is unknown. | |||
1751 | ||||
1752 | LifetimeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl, | |||
1753 | SDVTList VTs, int64_t Size, int64_t Offset) | |||
1754 | : SDNode(Opcode, Order, dl, VTs), Size(Size), Offset(Offset) {} | |||
1755 | public: | |||
1756 | int64_t getFrameIndex() const { | |||
1757 | return cast<FrameIndexSDNode>(getOperand(1))->getIndex(); | |||
1758 | } | |||
1759 | ||||
1760 | bool hasOffset() const { return Offset >= 0; } | |||
1761 | int64_t getOffset() const { | |||
1762 | assert(hasOffset() && "offset is unknown")(static_cast <bool> (hasOffset() && "offset is unknown" ) ? void (0) : __assert_fail ("hasOffset() && \"offset is unknown\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1762, __extension__ __PRETTY_FUNCTION__)); | |||
1763 | return Offset; | |||
1764 | } | |||
1765 | int64_t getSize() const { | |||
1766 | assert(hasOffset() && "offset is unknown")(static_cast <bool> (hasOffset() && "offset is unknown" ) ? void (0) : __assert_fail ("hasOffset() && \"offset is unknown\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1766, __extension__ __PRETTY_FUNCTION__)); | |||
1767 | return Size; | |||
1768 | } | |||
1769 | ||||
1770 | // Methods to support isa and dyn_cast | |||
1771 | static bool classof(const SDNode *N) { | |||
1772 | return N->getOpcode() == ISD::LIFETIME_START || | |||
1773 | N->getOpcode() == ISD::LIFETIME_END; | |||
1774 | } | |||
1775 | }; | |||
1776 | ||||
1777 | /// This SDNode is used for PSEUDO_PROBE values, which are the function guid and | |||
1778 | /// the index of the basic block being probed. A pseudo probe serves as a place | |||
1779 | /// holder and will be removed at the end of compilation. It does not have any | |||
1780 | /// operand because we do not want the instruction selection to deal with any. | |||
1781 | class PseudoProbeSDNode : public SDNode { | |||
1782 | friend class SelectionDAG; | |||
1783 | uint64_t Guid; | |||
1784 | uint64_t Index; | |||
1785 | uint32_t Attributes; | |||
1786 | ||||
1787 | PseudoProbeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &Dl, | |||
1788 | SDVTList VTs, uint64_t Guid, uint64_t Index, uint32_t Attr) | |||
1789 | : SDNode(Opcode, Order, Dl, VTs), Guid(Guid), Index(Index), | |||
1790 | Attributes(Attr) {} | |||
1791 | ||||
1792 | public: | |||
1793 | uint64_t getGuid() const { return Guid; } | |||
1794 | uint64_t getIndex() const { return Index; } | |||
1795 | uint32_t getAttributes() const { return Attributes; } | |||
1796 | ||||
1797 | // Methods to support isa and dyn_cast | |||
1798 | static bool classof(const SDNode *N) { | |||
1799 | return N->getOpcode() == ISD::PSEUDO_PROBE; | |||
1800 | } | |||
1801 | }; | |||
1802 | ||||
1803 | class JumpTableSDNode : public SDNode { | |||
1804 | friend class SelectionDAG; | |||
1805 | ||||
1806 | int JTI; | |||
1807 | unsigned TargetFlags; | |||
1808 | ||||
1809 | JumpTableSDNode(int jti, EVT VT, bool isTarg, unsigned TF) | |||
1810 | : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, | |||
1811 | 0, DebugLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) { | |||
1812 | } | |||
1813 | ||||
1814 | public: | |||
1815 | int getIndex() const { return JTI; } | |||
1816 | unsigned getTargetFlags() const { return TargetFlags; } | |||
1817 | ||||
1818 | static bool classof(const SDNode *N) { | |||
1819 | return N->getOpcode() == ISD::JumpTable || | |||
1820 | N->getOpcode() == ISD::TargetJumpTable; | |||
1821 | } | |||
1822 | }; | |||
1823 | ||||
1824 | class ConstantPoolSDNode : public SDNode { | |||
1825 | friend class SelectionDAG; | |||
1826 | ||||
1827 | union { | |||
1828 | const Constant *ConstVal; | |||
1829 | MachineConstantPoolValue *MachineCPVal; | |||
1830 | } Val; | |||
1831 | int Offset; // It's a MachineConstantPoolValue if top bit is set. | |||
1832 | Align Alignment; // Minimum alignment requirement of CP. | |||
1833 | unsigned TargetFlags; | |||
1834 | ||||
1835 | ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o, | |||
1836 | Align Alignment, unsigned TF) | |||
1837 | : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0, | |||
1838 | DebugLoc(), getSDVTList(VT)), | |||
1839 | Offset(o), Alignment(Alignment), TargetFlags(TF) { | |||
1840 | assert(Offset >= 0 && "Offset is too large")(static_cast <bool> (Offset >= 0 && "Offset is too large" ) ? void (0) : __assert_fail ("Offset >= 0 && \"Offset is too large\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1840, __extension__ __PRETTY_FUNCTION__)); | |||
1841 | Val.ConstVal = c; | |||
1842 | } | |||
1843 | ||||
1844 | ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, EVT VT, int o, | |||
1845 | Align Alignment, unsigned TF) | |||
1846 | : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0, | |||
1847 | DebugLoc(), getSDVTList(VT)), | |||
1848 | Offset(o), Alignment(Alignment), TargetFlags(TF) { | |||
1849 | assert(Offset >= 0 && "Offset is too large")(static_cast <bool> (Offset >= 0 && "Offset is too large" ) ? void (0) : __assert_fail ("Offset >= 0 && \"Offset is too large\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1849, __extension__ __PRETTY_FUNCTION__)); | |||
1850 | Val.MachineCPVal = v; | |||
1851 | Offset |= 1 << (sizeof(unsigned)*CHAR_BIT8-1); | |||
1852 | } | |||
1853 | ||||
1854 | public: | |||
1855 | bool isMachineConstantPoolEntry() const { | |||
1856 | return Offset < 0; | |||
1857 | } | |||
1858 | ||||
1859 | const Constant *getConstVal() const { | |||
1860 | assert(!isMachineConstantPoolEntry() && "Wrong constantpool type")(static_cast <bool> (!isMachineConstantPoolEntry() && "Wrong constantpool type") ? void (0) : __assert_fail ("!isMachineConstantPoolEntry() && \"Wrong constantpool type\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1860, __extension__ __PRETTY_FUNCTION__)); | |||
1861 | return Val.ConstVal; | |||
1862 | } | |||
1863 | ||||
1864 | MachineConstantPoolValue *getMachineCPVal() const { | |||
1865 | assert(isMachineConstantPoolEntry() && "Wrong constantpool type")(static_cast <bool> (isMachineConstantPoolEntry() && "Wrong constantpool type") ? void (0) : __assert_fail ("isMachineConstantPoolEntry() && \"Wrong constantpool type\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 1865, __extension__ __PRETTY_FUNCTION__)); | |||
1866 | return Val.MachineCPVal; | |||
1867 | } | |||
1868 | ||||
1869 | int getOffset() const { | |||
1870 | return Offset & ~(1 << (sizeof(unsigned)*CHAR_BIT8-1)); | |||
1871 | } | |||
1872 | ||||
1873 | // Return the alignment of this constant pool object, which is either 0 (for | |||
1874 | // default alignment) or the desired value. | |||
1875 | Align getAlign() const { return Alignment; } | |||
1876 | unsigned getTargetFlags() const { return TargetFlags; } | |||
1877 | ||||
1878 | Type *getType() const; | |||
1879 | ||||
1880 | static bool classof(const SDNode *N) { | |||
1881 | return N->getOpcode() == ISD::ConstantPool || | |||
1882 | N->getOpcode() == ISD::TargetConstantPool; | |||
1883 | } | |||
1884 | }; | |||
1885 | ||||
1886 | /// Completely target-dependent object reference. | |||
1887 | class TargetIndexSDNode : public SDNode { | |||
1888 | friend class SelectionDAG; | |||
1889 | ||||
1890 | unsigned TargetFlags; | |||
1891 | int Index; | |||
1892 | int64_t Offset; | |||
1893 | ||||
1894 | public: | |||
1895 | TargetIndexSDNode(int Idx, EVT VT, int64_t Ofs, unsigned TF) | |||
1896 | : SDNode(ISD::TargetIndex, 0, DebugLoc(), getSDVTList(VT)), | |||
1897 | TargetFlags(TF), Index(Idx), Offset(Ofs) {} | |||
1898 | ||||
1899 | unsigned getTargetFlags() const { return TargetFlags; } | |||
1900 | int getIndex() const { return Index; } | |||
1901 | int64_t getOffset() const { return Offset; } | |||
1902 | ||||
1903 | static bool classof(const SDNode *N) { | |||
1904 | return N->getOpcode() == ISD::TargetIndex; | |||
1905 | } | |||
1906 | }; | |||
1907 | ||||
1908 | class BasicBlockSDNode : public SDNode { | |||
1909 | friend class SelectionDAG; | |||
1910 | ||||
1911 | MachineBasicBlock *MBB; | |||
1912 | ||||
1913 | /// Debug info is meaningful and potentially useful here, but we create | |||
1914 | /// blocks out of order when they're jumped to, which makes it a bit | |||
1915 | /// harder. Let's see if we need it first. | |||
1916 | explicit BasicBlockSDNode(MachineBasicBlock *mbb) | |||
1917 | : SDNode(ISD::BasicBlock, 0, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb) | |||
1918 | {} | |||
1919 | ||||
1920 | public: | |||
1921 | MachineBasicBlock *getBasicBlock() const { return MBB; } | |||
1922 | ||||
1923 | static bool classof(const SDNode *N) { | |||
1924 | return N->getOpcode() == ISD::BasicBlock; | |||
1925 | } | |||
1926 | }; | |||
1927 | ||||
1928 | /// A "pseudo-class" with methods for operating on BUILD_VECTORs. | |||
1929 | class BuildVectorSDNode : public SDNode { | |||
1930 | public: | |||
1931 | // These are constructed as SDNodes and then cast to BuildVectorSDNodes. | |||
1932 | explicit BuildVectorSDNode() = delete; | |||
1933 | ||||
1934 | /// Check if this is a constant splat, and if so, find the | |||
1935 | /// smallest element size that splats the vector. If MinSplatBits is | |||
1936 | /// nonzero, the element size must be at least that large. Note that the | |||
1937 | /// splat element may be the entire vector (i.e., a one element vector). | |||
1938 | /// Returns the splat element value in SplatValue. Any undefined bits in | |||
1939 | /// that value are zero, and the corresponding bits in the SplatUndef mask | |||
1940 | /// are set. The SplatBitSize value is set to the splat element size in | |||
1941 | /// bits. HasAnyUndefs is set to true if any bits in the vector are | |||
1942 | /// undefined. isBigEndian describes the endianness of the target. | |||
1943 | bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, | |||
1944 | unsigned &SplatBitSize, bool &HasAnyUndefs, | |||
1945 | unsigned MinSplatBits = 0, | |||
1946 | bool isBigEndian = false) const; | |||
1947 | ||||
1948 | /// Returns the demanded splatted value or a null value if this is not a | |||
1949 | /// splat. | |||
1950 | /// | |||
1951 | /// The DemandedElts mask indicates the elements that must be in the splat. | |||
1952 | /// If passed a non-null UndefElements bitvector, it will resize it to match | |||
1953 | /// the vector width and set the bits where elements are undef. | |||
1954 | SDValue getSplatValue(const APInt &DemandedElts, | |||
1955 | BitVector *UndefElements = nullptr) const; | |||
1956 | ||||
1957 | /// Returns the splatted value or a null value if this is not a splat. | |||
1958 | /// | |||
1959 | /// If passed a non-null UndefElements bitvector, it will resize it to match | |||
1960 | /// the vector width and set the bits where elements are undef. | |||
1961 | SDValue getSplatValue(BitVector *UndefElements = nullptr) const; | |||
1962 | ||||
1963 | /// Find the shortest repeating sequence of values in the build vector. | |||
1964 | /// | |||
1965 | /// e.g. { u, X, u, X, u, u, X, u } -> { X } | |||
1966 | /// { X, Y, u, Y, u, u, X, u } -> { X, Y } | |||
1967 | /// | |||
1968 | /// Currently this must be a power-of-2 build vector. | |||
1969 | /// The DemandedElts mask indicates the elements that must be present, | |||
1970 | /// undemanded elements in Sequence may be null (SDValue()). If passed a | |||
1971 | /// non-null UndefElements bitvector, it will resize it to match the original | |||
1972 | /// vector width and set the bits where elements are undef. If result is | |||
1973 | /// false, Sequence will be empty. | |||
1974 | bool getRepeatedSequence(const APInt &DemandedElts, | |||
1975 | SmallVectorImpl<SDValue> &Sequence, | |||
1976 | BitVector *UndefElements = nullptr) const; | |||
1977 | ||||
1978 | /// Find the shortest repeating sequence of values in the build vector. | |||
1979 | /// | |||
1980 | /// e.g. { u, X, u, X, u, u, X, u } -> { X } | |||
1981 | /// { X, Y, u, Y, u, u, X, u } -> { X, Y } | |||
1982 | /// | |||
1983 | /// Currently this must be a power-of-2 build vector. | |||
1984 | /// If passed a non-null UndefElements bitvector, it will resize it to match | |||
1985 | /// the original vector width and set the bits where elements are undef. | |||
1986 | /// If result is false, Sequence will be empty. | |||
1987 | bool getRepeatedSequence(SmallVectorImpl<SDValue> &Sequence, | |||
1988 | BitVector *UndefElements = nullptr) const; | |||
1989 | ||||
1990 | /// Returns the demanded splatted constant or null if this is not a constant | |||
1991 | /// splat. | |||
1992 | /// | |||
1993 | /// The DemandedElts mask indicates the elements that must be in the splat. | |||
1994 | /// If passed a non-null UndefElements bitvector, it will resize it to match | |||
1995 | /// the vector width and set the bits where elements are undef. | |||
1996 | ConstantSDNode * | |||
1997 | getConstantSplatNode(const APInt &DemandedElts, | |||
1998 | BitVector *UndefElements = nullptr) const; | |||
1999 | ||||
2000 | /// Returns the splatted constant or null if this is not a constant | |||
2001 | /// splat. | |||
2002 | /// | |||
2003 | /// If passed a non-null UndefElements bitvector, it will resize it to match | |||
2004 | /// the vector width and set the bits where elements are undef. | |||
2005 | ConstantSDNode * | |||
2006 | getConstantSplatNode(BitVector *UndefElements = nullptr) const; | |||
2007 | ||||
2008 | /// Returns the demanded splatted constant FP or null if this is not a | |||
2009 | /// constant FP splat. | |||
2010 | /// | |||
2011 | /// The DemandedElts mask indicates the elements that must be in the splat. | |||
2012 | /// If passed a non-null UndefElements bitvector, it will resize it to match | |||
2013 | /// the vector width and set the bits where elements are undef. | |||
2014 | ConstantFPSDNode * | |||
2015 | getConstantFPSplatNode(const APInt &DemandedElts, | |||
2016 | BitVector *UndefElements = nullptr) const; | |||
2017 | ||||
2018 | /// Returns the splatted constant FP or null if this is not a constant | |||
2019 | /// FP splat. | |||
2020 | /// | |||
2021 | /// If passed a non-null UndefElements bitvector, it will resize it to match | |||
2022 | /// the vector width and set the bits where elements are undef. | |||
2023 | ConstantFPSDNode * | |||
2024 | getConstantFPSplatNode(BitVector *UndefElements = nullptr) const; | |||
2025 | ||||
2026 | /// If this is a constant FP splat and the splatted constant FP is an | |||
2027 | /// exact power or 2, return the log base 2 integer value. Otherwise, | |||
2028 | /// return -1. | |||
2029 | /// | |||
2030 | /// The BitWidth specifies the necessary bit precision. | |||
2031 | int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements, | |||
2032 | uint32_t BitWidth) const; | |||
2033 | ||||
2034 | bool isConstant() const; | |||
2035 | ||||
2036 | static bool classof(const SDNode *N) { | |||
2037 | return N->getOpcode() == ISD::BUILD_VECTOR; | |||
2038 | } | |||
2039 | }; | |||
2040 | ||||
2041 | /// An SDNode that holds an arbitrary LLVM IR Value. This is | |||
2042 | /// used when the SelectionDAG needs to make a simple reference to something | |||
2043 | /// in the LLVM IR representation. | |||
2044 | /// | |||
2045 | class SrcValueSDNode : public SDNode { | |||
2046 | friend class SelectionDAG; | |||
2047 | ||||
2048 | const Value *V; | |||
2049 | ||||
2050 | /// Create a SrcValue for a general value. | |||
2051 | explicit SrcValueSDNode(const Value *v) | |||
2052 | : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {} | |||
2053 | ||||
2054 | public: | |||
2055 | /// Return the contained Value. | |||
2056 | const Value *getValue() const { return V; } | |||
2057 | ||||
2058 | static bool classof(const SDNode *N) { | |||
2059 | return N->getOpcode() == ISD::SRCVALUE; | |||
2060 | } | |||
2061 | }; | |||
2062 | ||||
2063 | class MDNodeSDNode : public SDNode { | |||
2064 | friend class SelectionDAG; | |||
2065 | ||||
2066 | const MDNode *MD; | |||
2067 | ||||
2068 | explicit MDNodeSDNode(const MDNode *md) | |||
2069 | : SDNode(ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md) | |||
2070 | {} | |||
2071 | ||||
2072 | public: | |||
2073 | const MDNode *getMD() const { return MD; } | |||
2074 | ||||
2075 | static bool classof(const SDNode *N) { | |||
2076 | return N->getOpcode() == ISD::MDNODE_SDNODE; | |||
2077 | } | |||
2078 | }; | |||
2079 | ||||
2080 | class RegisterSDNode : public SDNode { | |||
2081 | friend class SelectionDAG; | |||
2082 | ||||
2083 | Register Reg; | |||
2084 | ||||
2085 | RegisterSDNode(Register reg, EVT VT) | |||
2086 | : SDNode(ISD::Register, 0, DebugLoc(), getSDVTList(VT)), Reg(reg) {} | |||
2087 | ||||
2088 | public: | |||
2089 | Register getReg() const { return Reg; } | |||
2090 | ||||
2091 | static bool classof(const SDNode *N) { | |||
2092 | return N->getOpcode() == ISD::Register; | |||
2093 | } | |||
2094 | }; | |||
2095 | ||||
2096 | class RegisterMaskSDNode : public SDNode { | |||
2097 | friend class SelectionDAG; | |||
2098 | ||||
2099 | // The memory for RegMask is not owned by the node. | |||
2100 | const uint32_t *RegMask; | |||
2101 | ||||
2102 | RegisterMaskSDNode(const uint32_t *mask) | |||
2103 | : SDNode(ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)), | |||
2104 | RegMask(mask) {} | |||
2105 | ||||
2106 | public: | |||
2107 | const uint32_t *getRegMask() const { return RegMask; } | |||
2108 | ||||
2109 | static bool classof(const SDNode *N) { | |||
2110 | return N->getOpcode() == ISD::RegisterMask; | |||
2111 | } | |||
2112 | }; | |||
2113 | ||||
2114 | class BlockAddressSDNode : public SDNode { | |||
2115 | friend class SelectionDAG; | |||
2116 | ||||
2117 | const BlockAddress *BA; | |||
2118 | int64_t Offset; | |||
2119 | unsigned TargetFlags; | |||
2120 | ||||
2121 | BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba, | |||
2122 | int64_t o, unsigned Flags) | |||
2123 | : SDNode(NodeTy, 0, DebugLoc(), getSDVTList(VT)), | |||
2124 | BA(ba), Offset(o), TargetFlags(Flags) {} | |||
2125 | ||||
2126 | public: | |||
2127 | const BlockAddress *getBlockAddress() const { return BA; } | |||
2128 | int64_t getOffset() const { return Offset; } | |||
2129 | unsigned getTargetFlags() const { return TargetFlags; } | |||
2130 | ||||
2131 | static bool classof(const SDNode *N) { | |||
2132 | return N->getOpcode() == ISD::BlockAddress || | |||
2133 | N->getOpcode() == ISD::TargetBlockAddress; | |||
2134 | } | |||
2135 | }; | |||
2136 | ||||
2137 | class LabelSDNode : public SDNode { | |||
2138 | friend class SelectionDAG; | |||
2139 | ||||
2140 | MCSymbol *Label; | |||
2141 | ||||
2142 | LabelSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl, MCSymbol *L) | |||
2143 | : SDNode(Opcode, Order, dl, getSDVTList(MVT::Other)), Label(L) { | |||
2144 | assert(LabelSDNode::classof(this) && "not a label opcode")(static_cast <bool> (LabelSDNode::classof(this) && "not a label opcode") ? void (0) : __assert_fail ("LabelSDNode::classof(this) && \"not a label opcode\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2144, __extension__ __PRETTY_FUNCTION__)); | |||
2145 | } | |||
2146 | ||||
2147 | public: | |||
2148 | MCSymbol *getLabel() const { return Label; } | |||
2149 | ||||
2150 | static bool classof(const SDNode *N) { | |||
2151 | return N->getOpcode() == ISD::EH_LABEL || | |||
2152 | N->getOpcode() == ISD::ANNOTATION_LABEL; | |||
2153 | } | |||
2154 | }; | |||
2155 | ||||
2156 | class ExternalSymbolSDNode : public SDNode { | |||
2157 | friend class SelectionDAG; | |||
2158 | ||||
2159 | const char *Symbol; | |||
2160 | unsigned TargetFlags; | |||
2161 | ||||
2162 | ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned TF, EVT VT) | |||
2163 | : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, 0, | |||
2164 | DebugLoc(), getSDVTList(VT)), | |||
2165 | Symbol(Sym), TargetFlags(TF) {} | |||
2166 | ||||
2167 | public: | |||
2168 | const char *getSymbol() const { return Symbol; } | |||
2169 | unsigned getTargetFlags() const { return TargetFlags; } | |||
2170 | ||||
2171 | static bool classof(const SDNode *N) { | |||
2172 | return N->getOpcode() == ISD::ExternalSymbol || | |||
2173 | N->getOpcode() == ISD::TargetExternalSymbol; | |||
2174 | } | |||
2175 | }; | |||
2176 | ||||
2177 | class MCSymbolSDNode : public SDNode { | |||
2178 | friend class SelectionDAG; | |||
2179 | ||||
2180 | MCSymbol *Symbol; | |||
2181 | ||||
2182 | MCSymbolSDNode(MCSymbol *Symbol, EVT VT) | |||
2183 | : SDNode(ISD::MCSymbol, 0, DebugLoc(), getSDVTList(VT)), Symbol(Symbol) {} | |||
2184 | ||||
2185 | public: | |||
2186 | MCSymbol *getMCSymbol() const { return Symbol; } | |||
2187 | ||||
2188 | static bool classof(const SDNode *N) { | |||
2189 | return N->getOpcode() == ISD::MCSymbol; | |||
2190 | } | |||
2191 | }; | |||
2192 | ||||
2193 | class CondCodeSDNode : public SDNode { | |||
2194 | friend class SelectionDAG; | |||
2195 | ||||
2196 | ISD::CondCode Condition; | |||
2197 | ||||
2198 | explicit CondCodeSDNode(ISD::CondCode Cond) | |||
2199 | : SDNode(ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)), | |||
2200 | Condition(Cond) {} | |||
2201 | ||||
2202 | public: | |||
2203 | ISD::CondCode get() const { return Condition; } | |||
2204 | ||||
2205 | static bool classof(const SDNode *N) { | |||
2206 | return N->getOpcode() == ISD::CONDCODE; | |||
2207 | } | |||
2208 | }; | |||
2209 | ||||
2210 | /// This class is used to represent EVT's, which are used | |||
2211 | /// to parameterize some operations. | |||
2212 | class VTSDNode : public SDNode { | |||
2213 | friend class SelectionDAG; | |||
2214 | ||||
2215 | EVT ValueType; | |||
2216 | ||||
2217 | explicit VTSDNode(EVT VT) | |||
2218 | : SDNode(ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)), | |||
2219 | ValueType(VT) {} | |||
2220 | ||||
2221 | public: | |||
2222 | EVT getVT() const { return ValueType; } | |||
2223 | ||||
2224 | static bool classof(const SDNode *N) { | |||
2225 | return N->getOpcode() == ISD::VALUETYPE; | |||
2226 | } | |||
2227 | }; | |||
2228 | ||||
2229 | /// Base class for LoadSDNode and StoreSDNode | |||
2230 | class LSBaseSDNode : public MemSDNode { | |||
2231 | public: | |||
2232 | LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl, | |||
2233 | SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT, | |||
2234 | MachineMemOperand *MMO) | |||
2235 | : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) { | |||
2236 | LSBaseSDNodeBits.AddressingMode = AM; | |||
2237 | assert(getAddressingMode() == AM && "Value truncated")(static_cast <bool> (getAddressingMode() == AM && "Value truncated") ? void (0) : __assert_fail ("getAddressingMode() == AM && \"Value truncated\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2237, __extension__ __PRETTY_FUNCTION__)); | |||
2238 | } | |||
2239 | ||||
2240 | const SDValue &getOffset() const { | |||
2241 | return getOperand(getOpcode() == ISD::LOAD ? 2 : 3); | |||
2242 | } | |||
2243 | ||||
2244 | /// Return the addressing mode for this load or store: | |||
2245 | /// unindexed, pre-inc, pre-dec, post-inc, or post-dec. | |||
2246 | ISD::MemIndexedMode getAddressingMode() const { | |||
2247 | return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode); | |||
2248 | } | |||
2249 | ||||
2250 | /// Return true if this is a pre/post inc/dec load/store. | |||
2251 | bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; } | |||
2252 | ||||
2253 | /// Return true if this is NOT a pre/post inc/dec load/store. | |||
2254 | bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; } | |||
2255 | ||||
2256 | static bool classof(const SDNode *N) { | |||
2257 | return N->getOpcode() == ISD::LOAD || | |||
2258 | N->getOpcode() == ISD::STORE; | |||
2259 | } | |||
2260 | }; | |||
2261 | ||||
2262 | /// This class is used to represent ISD::LOAD nodes. | |||
2263 | class LoadSDNode : public LSBaseSDNode { | |||
2264 | friend class SelectionDAG; | |||
2265 | ||||
2266 | LoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, | |||
2267 | ISD::MemIndexedMode AM, ISD::LoadExtType ETy, EVT MemVT, | |||
2268 | MachineMemOperand *MMO) | |||
2269 | : LSBaseSDNode(ISD::LOAD, Order, dl, VTs, AM, MemVT, MMO) { | |||
2270 | LoadSDNodeBits.ExtTy = ETy; | |||
2271 | assert(readMem() && "Load MachineMemOperand is not a load!")(static_cast <bool> (readMem() && "Load MachineMemOperand is not a load!" ) ? void (0) : __assert_fail ("readMem() && \"Load MachineMemOperand is not a load!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2271, __extension__ __PRETTY_FUNCTION__)); | |||
2272 | assert(!writeMem() && "Load MachineMemOperand is a store!")(static_cast <bool> (!writeMem() && "Load MachineMemOperand is a store!" ) ? void (0) : __assert_fail ("!writeMem() && \"Load MachineMemOperand is a store!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2272, __extension__ __PRETTY_FUNCTION__)); | |||
2273 | } | |||
2274 | ||||
2275 | public: | |||
2276 | /// Return whether this is a plain node, | |||
2277 | /// or one of the varieties of value-extending loads. | |||
2278 | ISD::LoadExtType getExtensionType() const { | |||
2279 | return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy); | |||
2280 | } | |||
2281 | ||||
2282 | const SDValue &getBasePtr() const { return getOperand(1); } | |||
2283 | const SDValue &getOffset() const { return getOperand(2); } | |||
2284 | ||||
2285 | static bool classof(const SDNode *N) { | |||
2286 | return N->getOpcode() == ISD::LOAD; | |||
2287 | } | |||
2288 | }; | |||
2289 | ||||
2290 | /// This class is used to represent ISD::STORE nodes. | |||
2291 | class StoreSDNode : public LSBaseSDNode { | |||
2292 | friend class SelectionDAG; | |||
2293 | ||||
2294 | StoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, | |||
2295 | ISD::MemIndexedMode AM, bool isTrunc, EVT MemVT, | |||
2296 | MachineMemOperand *MMO) | |||
2297 | : LSBaseSDNode(ISD::STORE, Order, dl, VTs, AM, MemVT, MMO) { | |||
2298 | StoreSDNodeBits.IsTruncating = isTrunc; | |||
2299 | assert(!readMem() && "Store MachineMemOperand is a load!")(static_cast <bool> (!readMem() && "Store MachineMemOperand is a load!" ) ? void (0) : __assert_fail ("!readMem() && \"Store MachineMemOperand is a load!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2299, __extension__ __PRETTY_FUNCTION__)); | |||
2300 | assert(writeMem() && "Store MachineMemOperand is not a store!")(static_cast <bool> (writeMem() && "Store MachineMemOperand is not a store!" ) ? void (0) : __assert_fail ("writeMem() && \"Store MachineMemOperand is not a store!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2300, __extension__ __PRETTY_FUNCTION__)); | |||
2301 | } | |||
2302 | ||||
2303 | public: | |||
2304 | /// Return true if the op does a truncation before store. | |||
2305 | /// For integers this is the same as doing a TRUNCATE and storing the result. | |||
2306 | /// For floats, it is the same as doing an FP_ROUND and storing the result. | |||
2307 | bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; } | |||
2308 | void setTruncatingStore(bool Truncating) { | |||
2309 | StoreSDNodeBits.IsTruncating = Truncating; | |||
2310 | } | |||
2311 | ||||
2312 | const SDValue &getValue() const { return getOperand(1); } | |||
2313 | const SDValue &getBasePtr() const { return getOperand(2); } | |||
2314 | const SDValue &getOffset() const { return getOperand(3); } | |||
2315 | ||||
2316 | static bool classof(const SDNode *N) { | |||
2317 | return N->getOpcode() == ISD::STORE; | |||
2318 | } | |||
2319 | }; | |||
2320 | ||||
2321 | /// This base class is used to represent MLOAD and MSTORE nodes | |||
2322 | class MaskedLoadStoreSDNode : public MemSDNode { | |||
2323 | public: | |||
2324 | friend class SelectionDAG; | |||
2325 | ||||
2326 | MaskedLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order, | |||
2327 | const DebugLoc &dl, SDVTList VTs, | |||
2328 | ISD::MemIndexedMode AM, EVT MemVT, | |||
2329 | MachineMemOperand *MMO) | |||
2330 | : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) { | |||
2331 | LSBaseSDNodeBits.AddressingMode = AM; | |||
2332 | assert(getAddressingMode() == AM && "Value truncated")(static_cast <bool> (getAddressingMode() == AM && "Value truncated") ? void (0) : __assert_fail ("getAddressingMode() == AM && \"Value truncated\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2332, __extension__ __PRETTY_FUNCTION__)); | |||
2333 | } | |||
2334 | ||||
2335 | // MaskedLoadSDNode (Chain, ptr, offset, mask, passthru) | |||
2336 | // MaskedStoreSDNode (Chain, data, ptr, offset, mask) | |||
2337 | // Mask is a vector of i1 elements | |||
2338 | const SDValue &getOffset() const { | |||
2339 | return getOperand(getOpcode() == ISD::MLOAD ? 2 : 3); | |||
2340 | } | |||
2341 | const SDValue &getMask() const { | |||
2342 | return getOperand(getOpcode() == ISD::MLOAD ? 3 : 4); | |||
2343 | } | |||
2344 | ||||
2345 | /// Return the addressing mode for this load or store: | |||
2346 | /// unindexed, pre-inc, pre-dec, post-inc, or post-dec. | |||
2347 | ISD::MemIndexedMode getAddressingMode() const { | |||
2348 | return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode); | |||
2349 | } | |||
2350 | ||||
2351 | /// Return true if this is a pre/post inc/dec load/store. | |||
2352 | bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; } | |||
2353 | ||||
2354 | /// Return true if this is NOT a pre/post inc/dec load/store. | |||
2355 | bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; } | |||
2356 | ||||
2357 | static bool classof(const SDNode *N) { | |||
2358 | return N->getOpcode() == ISD::MLOAD || | |||
2359 | N->getOpcode() == ISD::MSTORE; | |||
2360 | } | |||
2361 | }; | |||
2362 | ||||
2363 | /// This class is used to represent an MLOAD node | |||
2364 | class MaskedLoadSDNode : public MaskedLoadStoreSDNode { | |||
2365 | public: | |||
2366 | friend class SelectionDAG; | |||
2367 | ||||
2368 | MaskedLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, | |||
2369 | ISD::MemIndexedMode AM, ISD::LoadExtType ETy, | |||
2370 | bool IsExpanding, EVT MemVT, MachineMemOperand *MMO) | |||
2371 | : MaskedLoadStoreSDNode(ISD::MLOAD, Order, dl, VTs, AM, MemVT, MMO) { | |||
2372 | LoadSDNodeBits.ExtTy = ETy; | |||
2373 | LoadSDNodeBits.IsExpanding = IsExpanding; | |||
2374 | } | |||
2375 | ||||
2376 | ISD::LoadExtType getExtensionType() const { | |||
2377 | return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy); | |||
2378 | } | |||
2379 | ||||
2380 | const SDValue &getBasePtr() const { return getOperand(1); } | |||
2381 | const SDValue &getOffset() const { return getOperand(2); } | |||
2382 | const SDValue &getMask() const { return getOperand(3); } | |||
2383 | const SDValue &getPassThru() const { return getOperand(4); } | |||
2384 | ||||
2385 | static bool classof(const SDNode *N) { | |||
2386 | return N->getOpcode() == ISD::MLOAD; | |||
2387 | } | |||
2388 | ||||
2389 | bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; } | |||
2390 | }; | |||
2391 | ||||
2392 | /// This class is used to represent an MSTORE node | |||
2393 | class MaskedStoreSDNode : public MaskedLoadStoreSDNode { | |||
2394 | public: | |||
2395 | friend class SelectionDAG; | |||
2396 | ||||
2397 | MaskedStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, | |||
2398 | ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing, | |||
2399 | EVT MemVT, MachineMemOperand *MMO) | |||
2400 | : MaskedLoadStoreSDNode(ISD::MSTORE, Order, dl, VTs, AM, MemVT, MMO) { | |||
2401 | StoreSDNodeBits.IsTruncating = isTrunc; | |||
2402 | StoreSDNodeBits.IsCompressing = isCompressing; | |||
2403 | } | |||
2404 | ||||
2405 | /// Return true if the op does a truncation before store. | |||
2406 | /// For integers this is the same as doing a TRUNCATE and storing the result. | |||
2407 | /// For floats, it is the same as doing an FP_ROUND and storing the result. | |||
2408 | bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; } | |||
2409 | ||||
2410 | /// Returns true if the op does a compression to the vector before storing. | |||
2411 | /// The node contiguously stores the active elements (integers or floats) | |||
2412 | /// in src (those with their respective bit set in writemask k) to unaligned | |||
2413 | /// memory at base_addr. | |||
2414 | bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; } | |||
2415 | ||||
2416 | const SDValue &getValue() const { return getOperand(1); } | |||
2417 | const SDValue &getBasePtr() const { return getOperand(2); } | |||
2418 | const SDValue &getOffset() const { return getOperand(3); } | |||
2419 | const SDValue &getMask() const { return getOperand(4); } | |||
2420 | ||||
2421 | static bool classof(const SDNode *N) { | |||
2422 | return N->getOpcode() == ISD::MSTORE; | |||
2423 | } | |||
2424 | }; | |||
2425 | ||||
2426 | /// This is a base class used to represent | |||
2427 | /// MGATHER and MSCATTER nodes | |||
2428 | /// | |||
2429 | class MaskedGatherScatterSDNode : public MemSDNode { | |||
2430 | public: | |||
2431 | friend class SelectionDAG; | |||
2432 | ||||
2433 | MaskedGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order, | |||
2434 | const DebugLoc &dl, SDVTList VTs, EVT MemVT, | |||
2435 | MachineMemOperand *MMO, ISD::MemIndexType IndexType) | |||
2436 | : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) { | |||
2437 | LSBaseSDNodeBits.AddressingMode = IndexType; | |||
2438 | assert(getIndexType() == IndexType && "Value truncated")(static_cast <bool> (getIndexType() == IndexType && "Value truncated") ? void (0) : __assert_fail ("getIndexType() == IndexType && \"Value truncated\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2438, __extension__ __PRETTY_FUNCTION__)); | |||
2439 | } | |||
2440 | ||||
2441 | /// How is Index applied to BasePtr when computing addresses. | |||
2442 | ISD::MemIndexType getIndexType() const { | |||
2443 | return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode); | |||
2444 | } | |||
2445 | void setIndexType(ISD::MemIndexType IndexType) { | |||
2446 | LSBaseSDNodeBits.AddressingMode = IndexType; | |||
2447 | } | |||
2448 | bool isIndexScaled() const { | |||
2449 | return (getIndexType() == ISD::SIGNED_SCALED) || | |||
2450 | (getIndexType() == ISD::UNSIGNED_SCALED); | |||
2451 | } | |||
2452 | bool isIndexSigned() const { | |||
2453 | return (getIndexType() == ISD::SIGNED_SCALED) || | |||
2454 | (getIndexType() == ISD::SIGNED_UNSCALED); | |||
2455 | } | |||
2456 | ||||
2457 | // In the both nodes address is Op1, mask is Op2: | |||
2458 | // MaskedGatherSDNode (Chain, passthru, mask, base, index, scale) | |||
2459 | // MaskedScatterSDNode (Chain, value, mask, base, index, scale) | |||
2460 | // Mask is a vector of i1 elements | |||
2461 | const SDValue &getBasePtr() const { return getOperand(3); } | |||
2462 | const SDValue &getIndex() const { return getOperand(4); } | |||
2463 | const SDValue &getMask() const { return getOperand(2); } | |||
2464 | const SDValue &getScale() const { return getOperand(5); } | |||
2465 | ||||
2466 | static bool classof(const SDNode *N) { | |||
2467 | return N->getOpcode() == ISD::MGATHER || | |||
2468 | N->getOpcode() == ISD::MSCATTER; | |||
2469 | } | |||
2470 | }; | |||
2471 | ||||
2472 | /// This class is used to represent an MGATHER node | |||
2473 | /// | |||
2474 | class MaskedGatherSDNode : public MaskedGatherScatterSDNode { | |||
2475 | public: | |||
2476 | friend class SelectionDAG; | |||
2477 | ||||
2478 | MaskedGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, | |||
2479 | EVT MemVT, MachineMemOperand *MMO, | |||
2480 | ISD::MemIndexType IndexType, ISD::LoadExtType ETy) | |||
2481 | : MaskedGatherScatterSDNode(ISD::MGATHER, Order, dl, VTs, MemVT, MMO, | |||
2482 | IndexType) { | |||
2483 | LoadSDNodeBits.ExtTy = ETy; | |||
2484 | } | |||
2485 | ||||
2486 | const SDValue &getPassThru() const { return getOperand(1); } | |||
2487 | ||||
2488 | ISD::LoadExtType getExtensionType() const { | |||
2489 | return ISD::LoadExtType(LoadSDNodeBits.ExtTy); | |||
2490 | } | |||
2491 | ||||
2492 | static bool classof(const SDNode *N) { | |||
2493 | return N->getOpcode() == ISD::MGATHER; | |||
2494 | } | |||
2495 | }; | |||
2496 | ||||
2497 | /// This class is used to represent an MSCATTER node | |||
2498 | /// | |||
2499 | class MaskedScatterSDNode : public MaskedGatherScatterSDNode { | |||
2500 | public: | |||
2501 | friend class SelectionDAG; | |||
2502 | ||||
2503 | MaskedScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, | |||
2504 | EVT MemVT, MachineMemOperand *MMO, | |||
2505 | ISD::MemIndexType IndexType, bool IsTrunc) | |||
2506 | : MaskedGatherScatterSDNode(ISD::MSCATTER, Order, dl, VTs, MemVT, MMO, | |||
2507 | IndexType) { | |||
2508 | StoreSDNodeBits.IsTruncating = IsTrunc; | |||
2509 | } | |||
2510 | ||||
2511 | /// Return true if the op does a truncation before store. | |||
2512 | /// For integers this is the same as doing a TRUNCATE and storing the result. | |||
2513 | /// For floats, it is the same as doing an FP_ROUND and storing the result. | |||
2514 | bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; } | |||
2515 | ||||
2516 | const SDValue &getValue() const { return getOperand(1); } | |||
2517 | ||||
2518 | static bool classof(const SDNode *N) { | |||
2519 | return N->getOpcode() == ISD::MSCATTER; | |||
2520 | } | |||
2521 | }; | |||
2522 | ||||
2523 | /// An SDNode that represents everything that will be needed | |||
2524 | /// to construct a MachineInstr. These nodes are created during the | |||
2525 | /// instruction selection proper phase. | |||
2526 | /// | |||
2527 | /// Note that the only supported way to set the `memoperands` is by calling the | |||
2528 | /// `SelectionDAG::setNodeMemRefs` function as the memory management happens | |||
2529 | /// inside the DAG rather than in the node. | |||
2530 | class MachineSDNode : public SDNode { | |||
2531 | private: | |||
2532 | friend class SelectionDAG; | |||
2533 | ||||
2534 | MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, SDVTList VTs) | |||
2535 | : SDNode(Opc, Order, DL, VTs) {} | |||
2536 | ||||
2537 | // We use a pointer union between a single `MachineMemOperand` pointer and | |||
2538 | // a pointer to an array of `MachineMemOperand` pointers. This is null when | |||
2539 | // the number of these is zero, the single pointer variant used when the | |||
2540 | // number is one, and the array is used for larger numbers. | |||
2541 | // | |||
2542 | // The array is allocated via the `SelectionDAG`'s allocator and so will | |||
2543 | // always live until the DAG is cleaned up and doesn't require ownership here. | |||
2544 | // | |||
2545 | // We can't use something simpler like `TinyPtrVector` here because `SDNode` | |||
2546 | // subclasses aren't managed in a conforming C++ manner. See the comments on | |||
2547 | // `SelectionDAG::MorphNodeTo` which details what all goes on, but the | |||
2548 | // constraint here is that these don't manage memory with their constructor or | |||
2549 | // destructor and can be initialized to a good state even if they start off | |||
2550 | // uninitialized. | |||
2551 | PointerUnion<MachineMemOperand *, MachineMemOperand **> MemRefs = {}; | |||
2552 | ||||
2553 | // Note that this could be folded into the above `MemRefs` member if doing so | |||
2554 | // is advantageous at some point. We don't need to store this in most cases. | |||
2555 | // However, at the moment this doesn't appear to make the allocation any | |||
2556 | // smaller and makes the code somewhat simpler to read. | |||
2557 | int NumMemRefs = 0; | |||
2558 | ||||
2559 | public: | |||
2560 | using mmo_iterator = ArrayRef<MachineMemOperand *>::const_iterator; | |||
2561 | ||||
2562 | ArrayRef<MachineMemOperand *> memoperands() const { | |||
2563 | // Special case the common cases. | |||
2564 | if (NumMemRefs == 0) | |||
2565 | return {}; | |||
2566 | if (NumMemRefs == 1) | |||
2567 | return makeArrayRef(MemRefs.getAddrOfPtr1(), 1); | |||
2568 | ||||
2569 | // Otherwise we have an actual array. | |||
2570 | return makeArrayRef(MemRefs.get<MachineMemOperand **>(), NumMemRefs); | |||
2571 | } | |||
2572 | mmo_iterator memoperands_begin() const { return memoperands().begin(); } | |||
2573 | mmo_iterator memoperands_end() const { return memoperands().end(); } | |||
2574 | bool memoperands_empty() const { return memoperands().empty(); } | |||
2575 | ||||
2576 | /// Clear out the memory reference descriptor list. | |||
2577 | void clearMemRefs() { | |||
2578 | MemRefs = nullptr; | |||
2579 | NumMemRefs = 0; | |||
2580 | } | |||
2581 | ||||
2582 | static bool classof(const SDNode *N) { | |||
2583 | return N->isMachineOpcode(); | |||
2584 | } | |||
2585 | }; | |||
2586 | ||||
2587 | /// An SDNode that records if a register contains a value that is guaranteed to | |||
2588 | /// be aligned accordingly. | |||
2589 | class AssertAlignSDNode : public SDNode { | |||
2590 | Align Alignment; | |||
2591 | ||||
2592 | public: | |||
2593 | AssertAlignSDNode(unsigned Order, const DebugLoc &DL, EVT VT, Align A) | |||
2594 | : SDNode(ISD::AssertAlign, Order, DL, getSDVTList(VT)), Alignment(A) {} | |||
2595 | ||||
2596 | Align getAlign() const { return Alignment; } | |||
2597 | ||||
2598 | static bool classof(const SDNode *N) { | |||
2599 | return N->getOpcode() == ISD::AssertAlign; | |||
2600 | } | |||
2601 | }; | |||
2602 | ||||
2603 | class SDNodeIterator { | |||
2604 | const SDNode *Node; | |||
2605 | unsigned Operand; | |||
2606 | ||||
2607 | SDNodeIterator(const SDNode *N, unsigned Op) : Node(N), Operand(Op) {} | |||
2608 | ||||
2609 | public: | |||
2610 | using iterator_category = std::forward_iterator_tag; | |||
2611 | using value_type = SDNode; | |||
2612 | using difference_type = std::ptrdiff_t; | |||
2613 | using pointer = value_type *; | |||
2614 | using reference = value_type &; | |||
2615 | ||||
2616 | bool operator==(const SDNodeIterator& x) const { | |||
2617 | return Operand == x.Operand; | |||
2618 | } | |||
2619 | bool operator!=(const SDNodeIterator& x) const { return !operator==(x); } | |||
2620 | ||||
2621 | pointer operator*() const { | |||
2622 | return Node->getOperand(Operand).getNode(); | |||
2623 | } | |||
2624 | pointer operator->() const { return operator*(); } | |||
2625 | ||||
2626 | SDNodeIterator& operator++() { // Preincrement | |||
2627 | ++Operand; | |||
2628 | return *this; | |||
2629 | } | |||
2630 | SDNodeIterator operator++(int) { // Postincrement | |||
2631 | SDNodeIterator tmp = *this; ++*this; return tmp; | |||
2632 | } | |||
2633 | size_t operator-(SDNodeIterator Other) const { | |||
2634 | assert(Node == Other.Node &&(static_cast <bool> (Node == Other.Node && "Cannot compare iterators of two different nodes!" ) ? void (0) : __assert_fail ("Node == Other.Node && \"Cannot compare iterators of two different nodes!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2635, __extension__ __PRETTY_FUNCTION__)) | |||
2635 | "Cannot compare iterators of two different nodes!")(static_cast <bool> (Node == Other.Node && "Cannot compare iterators of two different nodes!" ) ? void (0) : __assert_fail ("Node == Other.Node && \"Cannot compare iterators of two different nodes!\"" , "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/CodeGen/SelectionDAGNodes.h" , 2635, __extension__ __PRETTY_FUNCTION__)); | |||
2636 | return Operand - Other.Operand; | |||
2637 | } | |||
2638 | ||||
2639 | static SDNodeIterator begin(const SDNode *N) { return SDNodeIterator(N, 0); } | |||
2640 | static SDNodeIterator end (const SDNode *N) { | |||
2641 | return SDNodeIterator(N, N->getNumOperands()); | |||
2642 | } | |||
2643 | ||||
2644 | unsigned getOperand() const { return Operand; } | |||
2645 | const SDNode *getNode() const { return Node; } | |||
2646 | }; | |||
2647 | ||||
2648 | template <> struct GraphTraits<SDNode*> { | |||
2649 | using NodeRef = SDNode *; | |||
2650 | using ChildIteratorType = SDNodeIterator; | |||
2651 | ||||
2652 | static NodeRef getEntryNode(SDNode *N) { return N; } | |||
2653 | ||||
2654 | static ChildIteratorType child_begin(NodeRef N) { | |||
2655 | return SDNodeIterator::begin(N); | |||
2656 | } | |||
2657 | ||||
2658 | static ChildIteratorType child_end(NodeRef N) { | |||
2659 | return SDNodeIterator::end(N); | |||
2660 | } | |||
2661 | }; | |||
2662 | ||||
2663 | /// A representation of the largest SDNode, for use in sizeof(). | |||
2664 | /// | |||
2665 | /// This needs to be a union because the largest node differs on 32 bit systems | |||
2666 | /// with 4 and 8 byte pointer alignment, respectively. | |||
2667 | using LargestSDNode = AlignedCharArrayUnion<AtomicSDNode, TargetIndexSDNode, | |||
2668 | BlockAddressSDNode, | |||
2669 | GlobalAddressSDNode, | |||
2670 | PseudoProbeSDNode>; | |||
2671 | ||||
2672 | /// The SDNode class with the greatest alignment requirement. | |||
2673 | using MostAlignedSDNode = GlobalAddressSDNode; | |||
2674 | ||||
2675 | namespace ISD { | |||
2676 | ||||
2677 | /// Returns true if the specified node is a non-extending and unindexed load. | |||
2678 | inline bool isNormalLoad(const SDNode *N) { | |||
2679 | const LoadSDNode *Ld = dyn_cast<LoadSDNode>(N); | |||
2680 | return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD && | |||
2681 | Ld->getAddressingMode() == ISD::UNINDEXED; | |||
2682 | } | |||
2683 | ||||
2684 | /// Returns true if the specified node is a non-extending load. | |||
2685 | inline bool isNON_EXTLoad(const SDNode *N) { | |||
2686 | return isa<LoadSDNode>(N) && | |||
2687 | cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD; | |||
2688 | } | |||
2689 | ||||
2690 | /// Returns true if the specified node is a EXTLOAD. | |||
2691 | inline bool isEXTLoad(const SDNode *N) { | |||
2692 | return isa<LoadSDNode>(N) && | |||
2693 | cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD; | |||
2694 | } | |||
2695 | ||||
2696 | /// Returns true if the specified node is a SEXTLOAD. | |||
2697 | inline bool isSEXTLoad(const SDNode *N) { | |||
2698 | return isa<LoadSDNode>(N) && | |||
2699 | cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; | |||
2700 | } | |||
2701 | ||||
2702 | /// Returns true if the specified node is a ZEXTLOAD. | |||
2703 | inline bool isZEXTLoad(const SDNode *N) { | |||
2704 | return isa<LoadSDNode>(N) && | |||
2705 | cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD; | |||
2706 | } | |||
2707 | ||||
2708 | /// Returns true if the specified node is an unindexed load. | |||
2709 | inline bool isUNINDEXEDLoad(const SDNode *N) { | |||
2710 | return isa<LoadSDNode>(N) && | |||
2711 | cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; | |||
2712 | } | |||
2713 | ||||
2714 | /// Returns true if the specified node is a non-truncating | |||
2715 | /// and unindexed store. | |||
2716 | inline bool isNormalStore(const SDNode *N) { | |||
2717 | const StoreSDNode *St = dyn_cast<StoreSDNode>(N); | |||
2718 | return St && !St->isTruncatingStore() && | |||
2719 | St->getAddressingMode() == ISD::UNINDEXED; | |||
2720 | } | |||
2721 | ||||
2722 | /// Returns true if the specified node is an unindexed store. | |||
2723 | inline bool isUNINDEXEDStore(const SDNode *N) { | |||
2724 | return isa<StoreSDNode>(N) && | |||
2725 | cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; | |||
2726 | } | |||
2727 | ||||
2728 | /// Attempt to match a unary predicate against a scalar/splat constant or | |||
2729 | /// every element of a constant BUILD_VECTOR. | |||
2730 | /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match. | |||
2731 | bool matchUnaryPredicate(SDValue Op, | |||
2732 | std::function<bool(ConstantSDNode *)> Match, | |||
2733 | bool AllowUndefs = false); | |||
2734 | ||||
2735 | /// Attempt to match a binary predicate against a pair of scalar/splat | |||
2736 | /// constants or every element of a pair of constant BUILD_VECTORs. | |||
2737 | /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match. | |||
2738 | /// If AllowTypeMismatch is true then RetType + ArgTypes don't need to match. | |||
2739 | bool matchBinaryPredicate( | |||
2740 | SDValue LHS, SDValue RHS, | |||
2741 | std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match, | |||
2742 | bool AllowUndefs = false, bool AllowTypeMismatch = false); | |||
2743 | ||||
2744 | /// Returns true if the specified value is the overflow result from one | |||
2745 | /// of the overflow intrinsic nodes. | |||
2746 | inline bool isOverflowIntrOpRes(SDValue Op) { | |||
2747 | unsigned Opc = Op.getOpcode(); | |||
2748 | return (Op.getResNo() == 1 && | |||
2749 | (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO || | |||
2750 | Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO)); | |||
2751 | } | |||
2752 | ||||
2753 | } // end namespace ISD | |||
2754 | ||||
2755 | } // end namespace llvm | |||
2756 | ||||
2757 | #endif // LLVM_CODEGEN_SELECTIONDAGNODES_H |