| 1 | //===-- LegalizeTypes.cpp - Common code for DAG type legalizer ------------===// |
| 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 implements the SelectionDAG::LegalizeTypes method. It transforms |
| 10 | // an arbitrary well-formed SelectionDAG to only consist of legal types. This |
| 11 | // is common code shared among the LegalizeTypes*.cpp files. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | #include "LegalizeTypes.h" |
| 16 | #include "llvm/ADT/SetVector.h" |
| 17 | #include "llvm/IR/DataLayout.h" |
| 18 | #include "llvm/Support/CommandLine.h" |
| 19 | #include "llvm/Support/ErrorHandling.h" |
| 20 | #include "llvm/Support/raw_ostream.h" |
| 21 | using namespace llvm; |
| 22 | |
| 23 | #define DEBUG_TYPE "legalize-types" |
| 24 | |
| 25 | static cl::opt<bool> |
| 26 | EnableExpensiveChecks("enable-legalize-types-checking" , cl::Hidden); |
| 27 | |
| 28 | /// Do extensive, expensive, basic correctness checking. |
| 29 | void DAGTypeLegalizer::PerformExpensiveChecks() { |
| 30 | // If a node is not processed, then none of its values should be mapped by any |
| 31 | // of PromotedIntegers, ExpandedIntegers, ..., ReplacedValues. |
| 32 | |
| 33 | // If a node is processed, then each value with an illegal type must be mapped |
| 34 | // by exactly one of PromotedIntegers, ExpandedIntegers, ..., ReplacedValues. |
| 35 | // Values with a legal type may be mapped by ReplacedValues, but not by any of |
| 36 | // the other maps. |
| 37 | |
| 38 | // Note that these invariants may not hold momentarily when processing a node: |
| 39 | // the node being processed may be put in a map before being marked Processed. |
| 40 | |
| 41 | // Note that it is possible to have nodes marked NewNode in the DAG. This can |
| 42 | // occur in two ways. Firstly, a node may be created during legalization but |
| 43 | // never passed to the legalization core. This is usually due to the implicit |
| 44 | // folding that occurs when using the DAG.getNode operators. Secondly, a new |
| 45 | // node may be passed to the legalization core, but when analyzed may morph |
| 46 | // into a different node, leaving the original node as a NewNode in the DAG. |
| 47 | // A node may morph if one of its operands changes during analysis. Whether |
| 48 | // it actually morphs or not depends on whether, after updating its operands, |
| 49 | // it is equivalent to an existing node: if so, it morphs into that existing |
| 50 | // node (CSE). An operand can change during analysis if the operand is a new |
| 51 | // node that morphs, or it is a processed value that was mapped to some other |
| 52 | // value (as recorded in ReplacedValues) in which case the operand is turned |
| 53 | // into that other value. If a node morphs then the node it morphed into will |
| 54 | // be used instead of it for legalization, however the original node continues |
| 55 | // to live on in the DAG. |
| 56 | // The conclusion is that though there may be nodes marked NewNode in the DAG, |
| 57 | // all uses of such nodes are also marked NewNode: the result is a fungus of |
| 58 | // NewNodes growing on top of the useful nodes, and perhaps using them, but |
| 59 | // not used by them. |
| 60 | |
| 61 | // If a value is mapped by ReplacedValues, then it must have no uses, except |
| 62 | // by nodes marked NewNode (see above). |
| 63 | |
| 64 | // The final node obtained by mapping by ReplacedValues is not marked NewNode. |
| 65 | // Note that ReplacedValues should be applied iteratively. |
| 66 | |
| 67 | // Note that the ReplacedValues map may also map deleted nodes (by iterating |
| 68 | // over the DAG we never dereference deleted nodes). This means that it may |
| 69 | // also map nodes marked NewNode if the deallocated memory was reallocated as |
| 70 | // another node, and that new node was not seen by the LegalizeTypes machinery |
| 71 | // (for example because it was created but not used). In general, we cannot |
| 72 | // distinguish between new nodes and deleted nodes. |
| 73 | SmallVector<SDNode*, 16> NewNodes; |
| 74 | for (SDNode &Node : DAG.allnodes()) { |
| 75 | // Remember nodes marked NewNode - they are subject to extra checking below. |
| 76 | if (Node.getNodeId() == NewNode) |
| 77 | NewNodes.push_back(Elt: &Node); |
| 78 | |
| 79 | for (unsigned i = 0, e = Node.getNumValues(); i != e; ++i) { |
| 80 | SDValue Res(&Node, i); |
| 81 | bool Failed = false; |
| 82 | // Don't create a value in map. |
| 83 | auto ResId = ValueToIdMap.lookup(Val: Res); |
| 84 | |
| 85 | unsigned Mapped = 0; |
| 86 | if (ResId) { |
| 87 | auto I = ReplacedValues.find(Val: ResId); |
| 88 | if (I != ReplacedValues.end()) { |
| 89 | Mapped |= 1; |
| 90 | // Check that remapped values are only used by nodes marked NewNode. |
| 91 | for (SDUse &U : Node.uses()) |
| 92 | if (U.getResNo() == i) |
| 93 | assert(U.getUser()->getNodeId() == NewNode && |
| 94 | "Remapped value has non-trivial use!" ); |
| 95 | |
| 96 | // Check that the final result of applying ReplacedValues is not |
| 97 | // marked NewNode. |
| 98 | auto NewValId = I->second; |
| 99 | I = ReplacedValues.find(Val: NewValId); |
| 100 | while (I != ReplacedValues.end()) { |
| 101 | NewValId = I->second; |
| 102 | I = ReplacedValues.find(Val: NewValId); |
| 103 | } |
| 104 | SDValue NewVal = getSDValue(Id&: NewValId); |
| 105 | (void)NewVal; |
| 106 | assert(NewVal.getNode()->getNodeId() != NewNode && |
| 107 | "ReplacedValues maps to a new node!" ); |
| 108 | } |
| 109 | if (PromotedIntegers.count(Val: ResId)) |
| 110 | Mapped |= 2; |
| 111 | if (SoftenedFloats.count(Val: ResId)) |
| 112 | Mapped |= 4; |
| 113 | if (ScalarizedVectors.count(Val: ResId)) |
| 114 | Mapped |= 8; |
| 115 | if (ExpandedIntegers.count(Val: ResId)) |
| 116 | Mapped |= 16; |
| 117 | if (ExpandedFloats.count(Val: ResId)) |
| 118 | Mapped |= 32; |
| 119 | if (SplitVectors.count(Val: ResId)) |
| 120 | Mapped |= 64; |
| 121 | if (WidenedVectors.count(Val: ResId)) |
| 122 | Mapped |= 128; |
| 123 | if (PromotedFloats.count(Val: ResId)) |
| 124 | Mapped |= 256; |
| 125 | if (SoftPromotedHalfs.count(Val: ResId)) |
| 126 | Mapped |= 512; |
| 127 | } |
| 128 | |
| 129 | if (Node.getNodeId() != Processed) { |
| 130 | // Since we allow ReplacedValues to map deleted nodes, it may map nodes |
| 131 | // marked NewNode too, since a deleted node may have been reallocated as |
| 132 | // another node that has not been seen by the LegalizeTypes machinery. |
| 133 | if ((Node.getNodeId() == NewNode && Mapped > 1) || |
| 134 | (Node.getNodeId() != NewNode && Mapped != 0)) { |
| 135 | dbgs() << "Unprocessed value in a map!" ; |
| 136 | Failed = true; |
| 137 | } |
| 138 | } else if (isTypeLegal(VT: Res.getValueType()) || IgnoreNodeResults(N: &Node)) { |
| 139 | if (Mapped > 1) { |
| 140 | dbgs() << "Value with legal type was transformed!" ; |
| 141 | Failed = true; |
| 142 | } |
| 143 | } else { |
| 144 | if (Mapped == 0) { |
| 145 | SDValue NodeById = IdToValueMap.lookup(Val: ResId); |
| 146 | // It is possible the node has been remapped to another node and had |
| 147 | // its Id updated in the Value to Id table. The node it remapped to |
| 148 | // may not have been processed yet. Look up the Id in the Id to Value |
| 149 | // table and re-check the Processed state. If the node hasn't been |
| 150 | // remapped we'll get the same state as we got earlier. |
| 151 | if (NodeById->getNodeId() == Processed) { |
| 152 | dbgs() << "Processed value not in any map!" ; |
| 153 | Failed = true; |
| 154 | } |
| 155 | } else if (Mapped & (Mapped - 1)) { |
| 156 | dbgs() << "Value in multiple maps!" ; |
| 157 | Failed = true; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | if (Failed) { |
| 162 | if (Mapped & 1) |
| 163 | dbgs() << " ReplacedValues" ; |
| 164 | if (Mapped & 2) |
| 165 | dbgs() << " PromotedIntegers" ; |
| 166 | if (Mapped & 4) |
| 167 | dbgs() << " SoftenedFloats" ; |
| 168 | if (Mapped & 8) |
| 169 | dbgs() << " ScalarizedVectors" ; |
| 170 | if (Mapped & 16) |
| 171 | dbgs() << " ExpandedIntegers" ; |
| 172 | if (Mapped & 32) |
| 173 | dbgs() << " ExpandedFloats" ; |
| 174 | if (Mapped & 64) |
| 175 | dbgs() << " SplitVectors" ; |
| 176 | if (Mapped & 128) |
| 177 | dbgs() << " WidenedVectors" ; |
| 178 | if (Mapped & 256) |
| 179 | dbgs() << " PromotedFloats" ; |
| 180 | if (Mapped & 512) |
| 181 | dbgs() << " SoftPromoteHalfs" ; |
| 182 | dbgs() << "\n" ; |
| 183 | llvm_unreachable(nullptr); |
| 184 | } |
| 185 | } |
| 186 | } |
| 187 | |
| 188 | #ifndef NDEBUG |
| 189 | // Checked that NewNodes are only used by other NewNodes. |
| 190 | for (SDNode *N : NewNodes) { |
| 191 | for (SDNode *U : N->users()) |
| 192 | assert(U->getNodeId() == NewNode && "NewNode used by non-NewNode!" ); |
| 193 | } |
| 194 | #endif |
| 195 | } |
| 196 | |
| 197 | /// This is the main entry point for the type legalizer. This does a top-down |
| 198 | /// traversal of the dag, legalizing types as it goes. Returns "true" if it made |
| 199 | /// any changes. |
| 200 | bool DAGTypeLegalizer::run() { |
| 201 | bool Changed = false; |
| 202 | |
| 203 | // Create a dummy node (which is not added to allnodes), that adds a reference |
| 204 | // to the root node, preventing it from being deleted, and tracking any |
| 205 | // changes of the root. |
| 206 | HandleSDNode Dummy(DAG.getRoot()); |
| 207 | Dummy.setNodeId(Unanalyzed); |
| 208 | |
| 209 | // The root of the dag may dangle to deleted nodes until the type legalizer is |
| 210 | // done. Set it to null to avoid confusion. |
| 211 | DAG.setRoot(SDValue()); |
| 212 | |
| 213 | // Walk all nodes in the graph, assigning them a NodeId of 'ReadyToProcess' |
| 214 | // (and remembering them) if they are leaves and assigning 'Unanalyzed' if |
| 215 | // non-leaves. |
| 216 | for (SDNode &Node : DAG.allnodes()) { |
| 217 | if (Node.getNumOperands() == 0) { |
| 218 | Node.setNodeId(ReadyToProcess); |
| 219 | Worklist.push_back(Elt: &Node); |
| 220 | } else { |
| 221 | Node.setNodeId(Unanalyzed); |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | // Now that we have a set of nodes to process, handle them all. |
| 226 | while (!Worklist.empty()) { |
| 227 | #ifndef EXPENSIVE_CHECKS |
| 228 | if (EnableExpensiveChecks) |
| 229 | #endif |
| 230 | PerformExpensiveChecks(); |
| 231 | |
| 232 | SDNode *N = Worklist.pop_back_val(); |
| 233 | assert(N->getNodeId() == ReadyToProcess && |
| 234 | "Node should be ready if on worklist!" ); |
| 235 | |
| 236 | // Preserve fast math flags |
| 237 | SDNodeFlags FastMathFlags = N->getFlags() & SDNodeFlags::FastMathFlags; |
| 238 | SelectionDAG::FlagInserter FlagsInserter(DAG, FastMathFlags); |
| 239 | |
| 240 | LLVM_DEBUG(dbgs() << "\nLegalizing node: " ; N->dump(&DAG)); |
| 241 | if (IgnoreNodeResults(N)) { |
| 242 | LLVM_DEBUG(dbgs() << "Ignoring node results\n" ); |
| 243 | goto ScanOperands; |
| 244 | } |
| 245 | |
| 246 | // Scan the values produced by the node, checking to see if any result |
| 247 | // types are illegal. |
| 248 | for (unsigned i = 0, NumResults = N->getNumValues(); i < NumResults; ++i) { |
| 249 | EVT ResultVT = N->getValueType(ResNo: i); |
| 250 | LLVM_DEBUG(dbgs() << "Analyzing result type: " << ResultVT << "\n" ); |
| 251 | switch (getTypeAction(VT: ResultVT)) { |
| 252 | case TargetLowering::TypeLegal: |
| 253 | LLVM_DEBUG(dbgs() << "Legal result type\n" ); |
| 254 | break; |
| 255 | case TargetLowering::TypeScalarizeScalableVector: |
| 256 | report_fatal_error( |
| 257 | reason: "Scalarization of scalable vectors is not supported." ); |
| 258 | // The following calls must take care of *all* of the node's results, |
| 259 | // not just the illegal result they were passed (this includes results |
| 260 | // with a legal type). Results can be remapped using ReplaceValueWith, |
| 261 | // or their promoted/expanded/etc values registered in PromotedIntegers, |
| 262 | // ExpandedIntegers etc. |
| 263 | case TargetLowering::TypePromoteInteger: |
| 264 | PromoteIntegerResult(N, ResNo: i); |
| 265 | Changed = true; |
| 266 | goto NodeDone; |
| 267 | case TargetLowering::TypeExpandInteger: |
| 268 | ExpandIntegerResult(N, ResNo: i); |
| 269 | Changed = true; |
| 270 | goto NodeDone; |
| 271 | case TargetLowering::TypeSoftenFloat: |
| 272 | SoftenFloatResult(N, ResNo: i); |
| 273 | Changed = true; |
| 274 | goto NodeDone; |
| 275 | case TargetLowering::TypeExpandFloat: |
| 276 | ExpandFloatResult(N, ResNo: i); |
| 277 | Changed = true; |
| 278 | goto NodeDone; |
| 279 | case TargetLowering::TypeScalarizeVector: |
| 280 | ScalarizeVectorResult(N, ResNo: i); |
| 281 | Changed = true; |
| 282 | goto NodeDone; |
| 283 | case TargetLowering::TypeSplitVector: |
| 284 | SplitVectorResult(N, ResNo: i); |
| 285 | Changed = true; |
| 286 | goto NodeDone; |
| 287 | case TargetLowering::TypeWidenVector: |
| 288 | WidenVectorResult(N, ResNo: i); |
| 289 | Changed = true; |
| 290 | goto NodeDone; |
| 291 | case TargetLowering::TypePromoteFloat: |
| 292 | PromoteFloatResult(N, ResNo: i); |
| 293 | Changed = true; |
| 294 | goto NodeDone; |
| 295 | case TargetLowering::TypeSoftPromoteHalf: |
| 296 | SoftPromoteHalfResult(N, ResNo: i); |
| 297 | Changed = true; |
| 298 | goto NodeDone; |
| 299 | } |
| 300 | } |
| 301 | |
| 302 | ScanOperands: |
| 303 | // Scan the operand list for the node, handling any nodes with operands that |
| 304 | // are illegal. |
| 305 | { |
| 306 | unsigned NumOperands = N->getNumOperands(); |
| 307 | bool NeedsReanalyzing = false; |
| 308 | unsigned i; |
| 309 | for (i = 0; i != NumOperands; ++i) { |
| 310 | if (IgnoreNodeResults(N: N->getOperand(Num: i).getNode())) |
| 311 | continue; |
| 312 | |
| 313 | const auto &Op = N->getOperand(Num: i); |
| 314 | LLVM_DEBUG(dbgs() << "Analyzing operand: " ; Op.dump(&DAG)); |
| 315 | EVT OpVT = Op.getValueType(); |
| 316 | switch (getTypeAction(VT: OpVT)) { |
| 317 | case TargetLowering::TypeLegal: |
| 318 | LLVM_DEBUG(dbgs() << "Legal operand\n" ); |
| 319 | continue; |
| 320 | case TargetLowering::TypeScalarizeScalableVector: |
| 321 | report_fatal_error( |
| 322 | reason: "Scalarization of scalable vectors is not supported." ); |
| 323 | // The following calls must either replace all of the node's results |
| 324 | // using ReplaceValueWith, and return "false"; or update the node's |
| 325 | // operands in place, and return "true". |
| 326 | case TargetLowering::TypePromoteInteger: |
| 327 | NeedsReanalyzing = PromoteIntegerOperand(N, OpNo: i); |
| 328 | Changed = true; |
| 329 | break; |
| 330 | case TargetLowering::TypeExpandInteger: |
| 331 | NeedsReanalyzing = ExpandIntegerOperand(N, OpNo: i); |
| 332 | Changed = true; |
| 333 | break; |
| 334 | case TargetLowering::TypeSoftenFloat: |
| 335 | NeedsReanalyzing = SoftenFloatOperand(N, OpNo: i); |
| 336 | Changed = true; |
| 337 | break; |
| 338 | case TargetLowering::TypeExpandFloat: |
| 339 | NeedsReanalyzing = ExpandFloatOperand(N, OpNo: i); |
| 340 | Changed = true; |
| 341 | break; |
| 342 | case TargetLowering::TypeScalarizeVector: |
| 343 | NeedsReanalyzing = ScalarizeVectorOperand(N, OpNo: i); |
| 344 | Changed = true; |
| 345 | break; |
| 346 | case TargetLowering::TypeSplitVector: |
| 347 | NeedsReanalyzing = SplitVectorOperand(N, OpNo: i); |
| 348 | Changed = true; |
| 349 | break; |
| 350 | case TargetLowering::TypeWidenVector: |
| 351 | NeedsReanalyzing = WidenVectorOperand(N, OpNo: i); |
| 352 | Changed = true; |
| 353 | break; |
| 354 | case TargetLowering::TypePromoteFloat: |
| 355 | NeedsReanalyzing = PromoteFloatOperand(N, OpNo: i); |
| 356 | Changed = true; |
| 357 | break; |
| 358 | case TargetLowering::TypeSoftPromoteHalf: |
| 359 | NeedsReanalyzing = SoftPromoteHalfOperand(N, OpNo: i); |
| 360 | Changed = true; |
| 361 | break; |
| 362 | } |
| 363 | break; |
| 364 | } |
| 365 | |
| 366 | // The sub-method updated N in place. Check to see if any operands are new, |
| 367 | // and if so, mark them. If the node needs revisiting, don't add all users |
| 368 | // to the worklist etc. |
| 369 | if (NeedsReanalyzing) { |
| 370 | assert(N->getNodeId() == ReadyToProcess && "Node ID recalculated?" ); |
| 371 | |
| 372 | N->setNodeId(NewNode); |
| 373 | // Recompute the NodeId and correct processed operands, adding the node to |
| 374 | // the worklist if ready. |
| 375 | SDNode *M = AnalyzeNewNode(N); |
| 376 | if (M == N) |
| 377 | // The node didn't morph - nothing special to do, it will be revisited. |
| 378 | continue; |
| 379 | |
| 380 | // The node morphed - this is equivalent to legalizing by replacing every |
| 381 | // value of N with the corresponding value of M. So do that now. |
| 382 | assert(N->getNumValues() == M->getNumValues() && |
| 383 | "Node morphing changed the number of results!" ); |
| 384 | for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) |
| 385 | // Replacing the value takes care of remapping the new value. |
| 386 | ReplaceValueWith(From: SDValue(N, i), To: SDValue(M, i)); |
| 387 | assert(N->getNodeId() == NewNode && "Unexpected node state!" ); |
| 388 | // The node continues to live on as part of the NewNode fungus that |
| 389 | // grows on top of the useful nodes. Nothing more needs to be done |
| 390 | // with it - move on to the next node. |
| 391 | continue; |
| 392 | } |
| 393 | |
| 394 | if (i == NumOperands) { |
| 395 | LLVM_DEBUG(dbgs() << "Legally typed node: " ; N->dump(&DAG)); |
| 396 | } |
| 397 | } |
| 398 | NodeDone: |
| 399 | |
| 400 | // If we reach here, the node was processed, potentially creating new nodes. |
| 401 | // Mark it as processed and add its users to the worklist as appropriate. |
| 402 | assert(N->getNodeId() == ReadyToProcess && "Node ID recalculated?" ); |
| 403 | N->setNodeId(Processed); |
| 404 | |
| 405 | for (SDNode *User : N->users()) { |
| 406 | int NodeId = User->getNodeId(); |
| 407 | |
| 408 | // This node has two options: it can either be a new node or its Node ID |
| 409 | // may be a count of the number of operands it has that are not ready. |
| 410 | if (NodeId > 0) { |
| 411 | User->setNodeId(NodeId-1); |
| 412 | |
| 413 | // If this was the last use it was waiting on, add it to the ready list. |
| 414 | if (NodeId-1 == ReadyToProcess) |
| 415 | Worklist.push_back(Elt: User); |
| 416 | continue; |
| 417 | } |
| 418 | |
| 419 | // If this is an unreachable new node, then ignore it. If it ever becomes |
| 420 | // reachable by being used by a newly created node then it will be handled |
| 421 | // by AnalyzeNewNode. |
| 422 | if (NodeId == NewNode) |
| 423 | continue; |
| 424 | |
| 425 | // Otherwise, this node is new: this is the first operand of it that |
| 426 | // became ready. Its new NodeId is the number of operands it has minus 1 |
| 427 | // (as this node is now processed). |
| 428 | assert(NodeId == Unanalyzed && "Unknown node ID!" ); |
| 429 | User->setNodeId(User->getNumOperands() - 1); |
| 430 | |
| 431 | // If the node only has a single operand, it is now ready. |
| 432 | if (User->getNumOperands() == 1) |
| 433 | Worklist.push_back(Elt: User); |
| 434 | } |
| 435 | } |
| 436 | |
| 437 | #ifndef EXPENSIVE_CHECKS |
| 438 | if (EnableExpensiveChecks) |
| 439 | #endif |
| 440 | PerformExpensiveChecks(); |
| 441 | |
| 442 | // If the root changed (e.g. it was a dead load) update the root. |
| 443 | DAG.setRoot(Dummy.getValue()); |
| 444 | |
| 445 | // Remove dead nodes. This is important to do for cleanliness but also before |
| 446 | // the checking loop below. Implicit folding by the DAG.getNode operators and |
| 447 | // node morphing can cause unreachable nodes to be around with their flags set |
| 448 | // to new. |
| 449 | DAG.RemoveDeadNodes(); |
| 450 | |
| 451 | // In a debug build, scan all the nodes to make sure we found them all. This |
| 452 | // ensures that there are no cycles and that everything got processed. |
| 453 | #ifndef NDEBUG |
| 454 | for (SDNode &Node : DAG.allnodes()) { |
| 455 | bool Failed = false; |
| 456 | |
| 457 | // Check that all result types are legal. |
| 458 | if (!IgnoreNodeResults(&Node)) |
| 459 | for (unsigned i = 0, NumVals = Node.getNumValues(); i < NumVals; ++i) |
| 460 | if (!isTypeLegal(Node.getValueType(i))) { |
| 461 | dbgs() << "Result type " << i << " illegal: " ; |
| 462 | Node.dump(&DAG); |
| 463 | Failed = true; |
| 464 | } |
| 465 | |
| 466 | // Check that all operand types are legal. |
| 467 | for (unsigned i = 0, NumOps = Node.getNumOperands(); i < NumOps; ++i) |
| 468 | if (!IgnoreNodeResults(Node.getOperand(i).getNode()) && |
| 469 | !isTypeLegal(Node.getOperand(i).getValueType())) { |
| 470 | dbgs() << "Operand type " << i << " illegal: " ; |
| 471 | Node.getOperand(i).dump(&DAG); |
| 472 | Failed = true; |
| 473 | } |
| 474 | |
| 475 | if (Node.getNodeId() != Processed) { |
| 476 | if (Node.getNodeId() == NewNode) |
| 477 | dbgs() << "New node not analyzed?\n" ; |
| 478 | else if (Node.getNodeId() == Unanalyzed) |
| 479 | dbgs() << "Unanalyzed node not noticed?\n" ; |
| 480 | else if (Node.getNodeId() > 0) |
| 481 | dbgs() << "Operand not processed?\n" ; |
| 482 | else if (Node.getNodeId() == ReadyToProcess) |
| 483 | dbgs() << "Not added to worklist?\n" ; |
| 484 | Failed = true; |
| 485 | } |
| 486 | |
| 487 | if (Failed) { |
| 488 | Node.dump(&DAG); dbgs() << "\n" ; |
| 489 | llvm_unreachable(nullptr); |
| 490 | } |
| 491 | } |
| 492 | #endif |
| 493 | |
| 494 | return Changed; |
| 495 | } |
| 496 | |
| 497 | /// The specified node is the root of a subtree of potentially new nodes. |
| 498 | /// Correct any processed operands (this may change the node) and calculate the |
| 499 | /// NodeId. If the node itself changes to a processed node, it is not remapped - |
| 500 | /// the caller needs to take care of this. Returns the potentially changed node. |
| 501 | SDNode *DAGTypeLegalizer::AnalyzeNewNode(SDNode *N) { |
| 502 | // If this was an existing node that is already done, we're done. |
| 503 | if (N->getNodeId() != NewNode && N->getNodeId() != Unanalyzed) |
| 504 | return N; |
| 505 | |
| 506 | // Okay, we know that this node is new. Recursively walk all of its operands |
| 507 | // to see if they are new also. The depth of this walk is bounded by the size |
| 508 | // of the new tree that was constructed (usually 2-3 nodes), so we don't worry |
| 509 | // about revisiting of nodes. |
| 510 | // |
| 511 | // As we walk the operands, keep track of the number of nodes that are |
| 512 | // processed. If non-zero, this will become the new nodeid of this node. |
| 513 | // Operands may morph when they are analyzed. If so, the node will be |
| 514 | // updated after all operands have been analyzed. Since this is rare, |
| 515 | // the code tries to minimize overhead in the non-morphing case. |
| 516 | |
| 517 | std::vector<SDValue> NewOps; |
| 518 | unsigned NumProcessed = 0; |
| 519 | for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { |
| 520 | SDValue OrigOp = N->getOperand(Num: i); |
| 521 | SDValue Op = OrigOp; |
| 522 | |
| 523 | AnalyzeNewValue(Val&: Op); // Op may morph. |
| 524 | |
| 525 | if (Op.getNode()->getNodeId() == Processed) |
| 526 | ++NumProcessed; |
| 527 | |
| 528 | if (!NewOps.empty()) { |
| 529 | // Some previous operand changed. Add this one to the list. |
| 530 | NewOps.push_back(x: Op); |
| 531 | } else if (Op != OrigOp) { |
| 532 | // This is the first operand to change - add all operands so far. |
| 533 | llvm::append_range(C&: NewOps, R: N->ops().take_front(N: i)); |
| 534 | NewOps.push_back(x: Op); |
| 535 | } |
| 536 | } |
| 537 | |
| 538 | // Some operands changed - update the node. |
| 539 | if (!NewOps.empty()) { |
| 540 | SDNode *M = DAG.UpdateNodeOperands(N, Ops: NewOps); |
| 541 | if (M != N) { |
| 542 | // The node morphed into a different node. Normally for this to happen |
| 543 | // the original node would have to be marked NewNode. However this can |
| 544 | // in theory momentarily not be the case while ReplaceValueWith is doing |
| 545 | // its stuff. Mark the original node NewNode to help basic correctness |
| 546 | // checking. |
| 547 | N->setNodeId(NewNode); |
| 548 | if (M->getNodeId() != NewNode && M->getNodeId() != Unanalyzed) |
| 549 | // It morphed into a previously analyzed node - nothing more to do. |
| 550 | return M; |
| 551 | |
| 552 | // It morphed into a different new node. Do the equivalent of passing |
| 553 | // it to AnalyzeNewNode: expunge it and calculate the NodeId. No need |
| 554 | // to remap the operands, since they are the same as the operands we |
| 555 | // remapped above. |
| 556 | N = M; |
| 557 | } |
| 558 | } |
| 559 | |
| 560 | // Calculate the NodeId. |
| 561 | N->setNodeId(N->getNumOperands() - NumProcessed); |
| 562 | if (N->getNodeId() == ReadyToProcess) |
| 563 | Worklist.push_back(Elt: N); |
| 564 | |
| 565 | return N; |
| 566 | } |
| 567 | |
| 568 | /// Call AnalyzeNewNode, updating the node in Val if needed. |
| 569 | /// If the node changes to a processed node, then remap it. |
| 570 | void DAGTypeLegalizer::AnalyzeNewValue(SDValue &Val) { |
| 571 | Val.setNode(AnalyzeNewNode(N: Val.getNode())); |
| 572 | if (Val.getNode()->getNodeId() == Processed) |
| 573 | // We were passed a processed node, or it morphed into one - remap it. |
| 574 | RemapValue(V&: Val); |
| 575 | } |
| 576 | |
| 577 | /// If the specified value was already legalized to another value, |
| 578 | /// replace it by that value. |
| 579 | void DAGTypeLegalizer::RemapValue(SDValue &V) { |
| 580 | auto Id = getTableId(V); |
| 581 | V = getSDValue(Id); |
| 582 | } |
| 583 | |
| 584 | void DAGTypeLegalizer::RemapId(TableId &Id) { |
| 585 | auto I = ReplacedValues.find(Val: Id); |
| 586 | if (I != ReplacedValues.end()) { |
| 587 | assert(Id != I->second && "Id is mapped to itself." ); |
| 588 | // Use path compression to speed up future lookups if values get multiply |
| 589 | // replaced with other values. |
| 590 | RemapId(Id&: I->second); |
| 591 | Id = I->second; |
| 592 | |
| 593 | // Note that N = IdToValueMap[Id] it is possible to have |
| 594 | // N.getNode()->getNodeId() == NewNode at this point because it is possible |
| 595 | // for a node to be put in the map before being processed. |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | namespace { |
| 600 | /// This class is a DAGUpdateListener that listens for updates to nodes and |
| 601 | /// recomputes their ready state. |
| 602 | class NodeUpdateListener : public SelectionDAG::DAGUpdateListener { |
| 603 | DAGTypeLegalizer &DTL; |
| 604 | SmallSetVector<SDNode*, 16> &NodesToAnalyze; |
| 605 | public: |
| 606 | explicit NodeUpdateListener(DAGTypeLegalizer &dtl, |
| 607 | SmallSetVector<SDNode*, 16> &nta) |
| 608 | : SelectionDAG::DAGUpdateListener(dtl.getDAG()), |
| 609 | DTL(dtl), NodesToAnalyze(nta) {} |
| 610 | |
| 611 | void NodeDeleted(SDNode *N, SDNode *E) override { |
| 612 | assert(N->getNodeId() != DAGTypeLegalizer::ReadyToProcess && |
| 613 | N->getNodeId() != DAGTypeLegalizer::Processed && |
| 614 | "Invalid node ID for RAUW deletion!" ); |
| 615 | // It is possible, though rare, for the deleted node N to occur as a |
| 616 | // target in a map, so note the replacement N -> E in ReplacedValues. |
| 617 | assert(E && "Node not replaced?" ); |
| 618 | DTL.NoteDeletion(Old: N, New: E); |
| 619 | |
| 620 | // In theory the deleted node could also have been scheduled for analysis. |
| 621 | // So remove it from the set of nodes which will be analyzed. |
| 622 | NodesToAnalyze.remove(X: N); |
| 623 | |
| 624 | // In general nothing needs to be done for E, since it didn't change but |
| 625 | // only gained new uses. However N -> E was just added to ReplacedValues, |
| 626 | // and the result of a ReplacedValues mapping is not allowed to be marked |
| 627 | // NewNode. So if E is marked NewNode, then it needs to be analyzed. |
| 628 | if (E->getNodeId() == DAGTypeLegalizer::NewNode) |
| 629 | NodesToAnalyze.insert(X: E); |
| 630 | } |
| 631 | |
| 632 | void NodeUpdated(SDNode *N) override { |
| 633 | // Node updates can mean pretty much anything. It is possible that an |
| 634 | // operand was set to something already processed (f.e.) in which case |
| 635 | // this node could become ready. Recompute its flags. |
| 636 | assert(N->getNodeId() != DAGTypeLegalizer::ReadyToProcess && |
| 637 | N->getNodeId() != DAGTypeLegalizer::Processed && |
| 638 | "Invalid node ID for RAUW deletion!" ); |
| 639 | N->setNodeId(DAGTypeLegalizer::NewNode); |
| 640 | NodesToAnalyze.insert(X: N); |
| 641 | } |
| 642 | }; |
| 643 | } |
| 644 | |
| 645 | |
| 646 | /// The specified value was legalized to the specified other value. |
| 647 | /// Update the DAG and NodeIds replacing any uses of From to use To instead. |
| 648 | void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) { |
| 649 | assert(From.getNode() != To.getNode() && "Potential legalization loop!" ); |
| 650 | |
| 651 | // If expansion produced new nodes, make sure they are properly marked. |
| 652 | AnalyzeNewValue(Val&: To); |
| 653 | |
| 654 | // Anything that used the old node should now use the new one. Note that this |
| 655 | // can potentially cause recursive merging. |
| 656 | SmallSetVector<SDNode*, 16> NodesToAnalyze; |
| 657 | NodeUpdateListener NUL(*this, NodesToAnalyze); |
| 658 | do { |
| 659 | |
| 660 | // The old node may be present in a map like ExpandedIntegers or |
| 661 | // PromotedIntegers. Inform maps about the replacement. |
| 662 | auto FromId = getTableId(V: From); |
| 663 | auto ToId = getTableId(V: To); |
| 664 | |
| 665 | if (FromId != ToId) |
| 666 | ReplacedValues[FromId] = ToId; |
| 667 | DAG.ReplaceAllUsesOfValueWith(From, To); |
| 668 | |
| 669 | // Process the list of nodes that need to be reanalyzed. |
| 670 | while (!NodesToAnalyze.empty()) { |
| 671 | SDNode *N = NodesToAnalyze.pop_back_val(); |
| 672 | if (N->getNodeId() != DAGTypeLegalizer::NewNode) |
| 673 | // The node was analyzed while reanalyzing an earlier node - it is safe |
| 674 | // to skip. Note that this is not a morphing node - otherwise it would |
| 675 | // still be marked NewNode. |
| 676 | continue; |
| 677 | |
| 678 | // Analyze the node's operands and recalculate the node ID. |
| 679 | SDNode *M = AnalyzeNewNode(N); |
| 680 | if (M != N) { |
| 681 | // The node morphed into a different node. Make everyone use the new |
| 682 | // node instead. |
| 683 | assert(M->getNodeId() != NewNode && "Analysis resulted in NewNode!" ); |
| 684 | assert(N->getNumValues() == M->getNumValues() && |
| 685 | "Node morphing changed the number of results!" ); |
| 686 | for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) { |
| 687 | SDValue OldVal(N, i); |
| 688 | SDValue NewVal(M, i); |
| 689 | if (M->getNodeId() == Processed) |
| 690 | RemapValue(V&: NewVal); |
| 691 | // OldVal may be a target of the ReplacedValues map which was marked |
| 692 | // NewNode to force reanalysis because it was updated. Ensure that |
| 693 | // anything that ReplacedValues mapped to OldVal will now be mapped |
| 694 | // all the way to NewVal. |
| 695 | auto OldValId = getTableId(V: OldVal); |
| 696 | auto NewValId = getTableId(V: NewVal); |
| 697 | DAG.ReplaceAllUsesOfValueWith(From: OldVal, To: NewVal); |
| 698 | if (OldValId != NewValId) |
| 699 | ReplacedValues[OldValId] = NewValId; |
| 700 | } |
| 701 | // The original node continues to exist in the DAG, marked NewNode. |
| 702 | } |
| 703 | } |
| 704 | // When recursively update nodes with new nodes, it is possible to have |
| 705 | // new uses of From due to CSE. If this happens, replace the new uses of |
| 706 | // From with To. |
| 707 | } while (!From.use_empty()); |
| 708 | } |
| 709 | |
| 710 | void DAGTypeLegalizer::SetPromotedInteger(SDValue Op, SDValue Result) { |
| 711 | assert(Result.getValueType() == |
| 712 | TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType()) && |
| 713 | "Invalid type for promoted integer" ); |
| 714 | AnalyzeNewValue(Val&: Result); |
| 715 | |
| 716 | auto &OpIdEntry = PromotedIntegers[getTableId(V: Op)]; |
| 717 | assert((OpIdEntry == 0) && "Node is already promoted!" ); |
| 718 | OpIdEntry = getTableId(V: Result); |
| 719 | |
| 720 | DAG.transferDbgValues(From: Op, To: Result); |
| 721 | } |
| 722 | |
| 723 | void DAGTypeLegalizer::SetSoftenedFloat(SDValue Op, SDValue Result) { |
| 724 | #ifndef NDEBUG |
| 725 | EVT VT = Result.getValueType(); |
| 726 | LLVMContext &Ctx = *DAG.getContext(); |
| 727 | assert((VT == EVT::getIntegerVT(Ctx, 80) || |
| 728 | VT == TLI.getTypeToTransformTo(Ctx, Op.getValueType())) && |
| 729 | "Invalid type for softened float" ); |
| 730 | #endif |
| 731 | AnalyzeNewValue(Val&: Result); |
| 732 | |
| 733 | auto &OpIdEntry = SoftenedFloats[getTableId(V: Op)]; |
| 734 | assert((OpIdEntry == 0) && "Node is already converted to integer!" ); |
| 735 | OpIdEntry = getTableId(V: Result); |
| 736 | } |
| 737 | |
| 738 | void DAGTypeLegalizer::SetPromotedFloat(SDValue Op, SDValue Result) { |
| 739 | assert(Result.getValueType() == |
| 740 | TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType()) && |
| 741 | "Invalid type for promoted float" ); |
| 742 | AnalyzeNewValue(Val&: Result); |
| 743 | |
| 744 | auto &OpIdEntry = PromotedFloats[getTableId(V: Op)]; |
| 745 | assert((OpIdEntry == 0) && "Node is already promoted!" ); |
| 746 | OpIdEntry = getTableId(V: Result); |
| 747 | } |
| 748 | |
| 749 | void DAGTypeLegalizer::SetSoftPromotedHalf(SDValue Op, SDValue Result) { |
| 750 | assert(Result.getValueType() == MVT::i16 && |
| 751 | "Invalid type for soft-promoted half" ); |
| 752 | AnalyzeNewValue(Val&: Result); |
| 753 | |
| 754 | auto &OpIdEntry = SoftPromotedHalfs[getTableId(V: Op)]; |
| 755 | assert((OpIdEntry == 0) && "Node is already promoted!" ); |
| 756 | OpIdEntry = getTableId(V: Result); |
| 757 | } |
| 758 | |
| 759 | void DAGTypeLegalizer::SetScalarizedVector(SDValue Op, SDValue Result) { |
| 760 | // Note that in some cases vector operation operands may be greater than |
| 761 | // the vector element type. For example BUILD_VECTOR of type <1 x i1> with |
| 762 | // a constant i8 operand. |
| 763 | |
| 764 | // We don't currently support the scalarization of scalable vector types. |
| 765 | assert(Result.getValueSizeInBits().getFixedValue() >= |
| 766 | Op.getScalarValueSizeInBits() && |
| 767 | "Invalid type for scalarized vector" ); |
| 768 | AnalyzeNewValue(Val&: Result); |
| 769 | |
| 770 | auto &OpIdEntry = ScalarizedVectors[getTableId(V: Op)]; |
| 771 | assert((OpIdEntry == 0) && "Node is already scalarized!" ); |
| 772 | OpIdEntry = getTableId(V: Result); |
| 773 | } |
| 774 | |
| 775 | void DAGTypeLegalizer::GetExpandedInteger(SDValue Op, SDValue &Lo, |
| 776 | SDValue &Hi) { |
| 777 | std::pair<TableId, TableId> &Entry = ExpandedIntegers[getTableId(V: Op)]; |
| 778 | assert((Entry.first != 0) && "Operand isn't expanded" ); |
| 779 | Lo = getSDValue(Id&: Entry.first); |
| 780 | Hi = getSDValue(Id&: Entry.second); |
| 781 | } |
| 782 | |
| 783 | void DAGTypeLegalizer::SetExpandedInteger(SDValue Op, SDValue Lo, |
| 784 | SDValue Hi) { |
| 785 | assert(Lo.getValueType() == |
| 786 | TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType()) && |
| 787 | Hi.getValueType() == Lo.getValueType() && |
| 788 | "Invalid type for expanded integer" ); |
| 789 | // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant. |
| 790 | AnalyzeNewValue(Val&: Lo); |
| 791 | AnalyzeNewValue(Val&: Hi); |
| 792 | |
| 793 | // Transfer debug values. Don't invalidate the source debug value until it's |
| 794 | // been transferred to the high and low bits. |
| 795 | if (DAG.getDataLayout().isBigEndian()) { |
| 796 | DAG.transferDbgValues(From: Op, To: Hi, OffsetInBits: 0, SizeInBits: Hi.getValueSizeInBits(), InvalidateDbg: false); |
| 797 | DAG.transferDbgValues(From: Op, To: Lo, OffsetInBits: Hi.getValueSizeInBits(), |
| 798 | SizeInBits: Lo.getValueSizeInBits()); |
| 799 | } else { |
| 800 | DAG.transferDbgValues(From: Op, To: Lo, OffsetInBits: 0, SizeInBits: Lo.getValueSizeInBits(), InvalidateDbg: false); |
| 801 | DAG.transferDbgValues(From: Op, To: Hi, OffsetInBits: Lo.getValueSizeInBits(), |
| 802 | SizeInBits: Hi.getValueSizeInBits()); |
| 803 | } |
| 804 | |
| 805 | // Remember that this is the result of the node. |
| 806 | std::pair<TableId, TableId> &Entry = ExpandedIntegers[getTableId(V: Op)]; |
| 807 | assert((Entry.first == 0) && "Node already expanded" ); |
| 808 | Entry.first = getTableId(V: Lo); |
| 809 | Entry.second = getTableId(V: Hi); |
| 810 | } |
| 811 | |
| 812 | void DAGTypeLegalizer::GetExpandedFloat(SDValue Op, SDValue &Lo, |
| 813 | SDValue &Hi) { |
| 814 | std::pair<TableId, TableId> &Entry = ExpandedFloats[getTableId(V: Op)]; |
| 815 | assert((Entry.first != 0) && "Operand isn't expanded" ); |
| 816 | Lo = getSDValue(Id&: Entry.first); |
| 817 | Hi = getSDValue(Id&: Entry.second); |
| 818 | } |
| 819 | |
| 820 | void DAGTypeLegalizer::SetExpandedFloat(SDValue Op, SDValue Lo, |
| 821 | SDValue Hi) { |
| 822 | assert(Lo.getValueType() == |
| 823 | TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType()) && |
| 824 | Hi.getValueType() == Lo.getValueType() && |
| 825 | "Invalid type for expanded float" ); |
| 826 | // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant. |
| 827 | AnalyzeNewValue(Val&: Lo); |
| 828 | AnalyzeNewValue(Val&: Hi); |
| 829 | |
| 830 | std::pair<TableId, TableId> &Entry = ExpandedFloats[getTableId(V: Op)]; |
| 831 | assert((Entry.first == 0) && "Node already expanded" ); |
| 832 | Entry.first = getTableId(V: Lo); |
| 833 | Entry.second = getTableId(V: Hi); |
| 834 | } |
| 835 | |
| 836 | void DAGTypeLegalizer::GetSplitVector(SDValue Op, SDValue &Lo, |
| 837 | SDValue &Hi) { |
| 838 | std::pair<TableId, TableId> &Entry = SplitVectors[getTableId(V: Op)]; |
| 839 | Lo = getSDValue(Id&: Entry.first); |
| 840 | Hi = getSDValue(Id&: Entry.second); |
| 841 | assert(Lo.getNode() && "Operand isn't split" ); |
| 842 | ; |
| 843 | } |
| 844 | |
| 845 | void DAGTypeLegalizer::SetSplitVector(SDValue Op, SDValue Lo, |
| 846 | SDValue Hi) { |
| 847 | assert(Lo.getValueType().getVectorElementType() == |
| 848 | Op.getValueType().getVectorElementType() && |
| 849 | Lo.getValueType().getVectorElementCount() * 2 == |
| 850 | Op.getValueType().getVectorElementCount() && |
| 851 | Hi.getValueType() == Lo.getValueType() && |
| 852 | "Invalid type for split vector" ); |
| 853 | // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant. |
| 854 | AnalyzeNewValue(Val&: Lo); |
| 855 | AnalyzeNewValue(Val&: Hi); |
| 856 | |
| 857 | // Remember that this is the result of the node. |
| 858 | std::pair<TableId, TableId> &Entry = SplitVectors[getTableId(V: Op)]; |
| 859 | assert((Entry.first == 0) && "Node already split" ); |
| 860 | Entry.first = getTableId(V: Lo); |
| 861 | Entry.second = getTableId(V: Hi); |
| 862 | } |
| 863 | |
| 864 | void DAGTypeLegalizer::SetWidenedVector(SDValue Op, SDValue Result) { |
| 865 | assert(Result.getValueType() == |
| 866 | TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType()) && |
| 867 | "Invalid type for widened vector" ); |
| 868 | AnalyzeNewValue(Val&: Result); |
| 869 | |
| 870 | auto &OpIdEntry = WidenedVectors[getTableId(V: Op)]; |
| 871 | assert((OpIdEntry == 0) && "Node already widened!" ); |
| 872 | OpIdEntry = getTableId(V: Result); |
| 873 | } |
| 874 | |
| 875 | |
| 876 | //===----------------------------------------------------------------------===// |
| 877 | // Utilities. |
| 878 | //===----------------------------------------------------------------------===// |
| 879 | |
| 880 | /// Convert to an integer of the same size. |
| 881 | SDValue DAGTypeLegalizer::BitConvertToInteger(SDValue Op) { |
| 882 | unsigned BitWidth = Op.getValueSizeInBits(); |
| 883 | return DAG.getNode(Opcode: ISD::BITCAST, DL: SDLoc(Op), |
| 884 | VT: EVT::getIntegerVT(Context&: *DAG.getContext(), BitWidth), Operand: Op); |
| 885 | } |
| 886 | |
| 887 | /// Convert to a vector of integers of the same size. |
| 888 | SDValue DAGTypeLegalizer::BitConvertVectorToIntegerVector(SDValue Op) { |
| 889 | assert(Op.getValueType().isVector() && "Only applies to vectors!" ); |
| 890 | unsigned EltWidth = Op.getScalarValueSizeInBits(); |
| 891 | EVT EltNVT = EVT::getIntegerVT(Context&: *DAG.getContext(), BitWidth: EltWidth); |
| 892 | auto EltCnt = Op.getValueType().getVectorElementCount(); |
| 893 | return DAG.getNode(Opcode: ISD::BITCAST, DL: SDLoc(Op), |
| 894 | VT: EVT::getVectorVT(Context&: *DAG.getContext(), VT: EltNVT, EC: EltCnt), Operand: Op); |
| 895 | } |
| 896 | |
| 897 | SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op, |
| 898 | EVT DestVT) { |
| 899 | SDLoc dl(Op); |
| 900 | // Create the stack frame object. Make sure it is aligned for both |
| 901 | // the source and destination types. |
| 902 | |
| 903 | // In cases where the vector is illegal it will be broken down into parts |
| 904 | // and stored in parts - we should use the alignment for the smallest part. |
| 905 | Align DestAlign = DAG.getReducedAlign(VT: DestVT, /*UseABI=*/false); |
| 906 | Align OpAlign = DAG.getReducedAlign(VT: Op.getValueType(), /*UseABI=*/false); |
| 907 | Align Align = std::max(a: DestAlign, b: OpAlign); |
| 908 | SDValue StackPtr = |
| 909 | DAG.CreateStackTemporary(Bytes: Op.getValueType().getStoreSize(), Alignment: Align); |
| 910 | // Emit a store to the stack slot. |
| 911 | SDValue Store = DAG.getStore(Chain: DAG.getEntryNode(), dl, Val: Op, Ptr: StackPtr, |
| 912 | PtrInfo: MachinePointerInfo(), Alignment: Align); |
| 913 | // Result is a load from the stack slot. |
| 914 | return DAG.getLoad(VT: DestVT, dl, Chain: Store, Ptr: StackPtr, PtrInfo: MachinePointerInfo(), Alignment: Align); |
| 915 | } |
| 916 | |
| 917 | /// Replace the node's results with custom code provided by the target and |
| 918 | /// return "true", or do nothing and return "false". |
| 919 | /// The last parameter is FALSE if we are dealing with a node with legal |
| 920 | /// result types and illegal operand. The second parameter denotes the type of |
| 921 | /// illegal OperandNo in that case. |
| 922 | /// The last parameter being TRUE means we are dealing with a |
| 923 | /// node with illegal result types. The second parameter denotes the type of |
| 924 | /// illegal ResNo in that case. |
| 925 | bool DAGTypeLegalizer::CustomLowerNode(SDNode *N, EVT VT, bool LegalizeResult) { |
| 926 | // See if the target wants to custom lower this node. |
| 927 | if (TLI.getOperationAction(Op: N->getOpcode(), VT) != TargetLowering::Custom) |
| 928 | return false; |
| 929 | |
| 930 | SmallVector<SDValue, 8> Results; |
| 931 | if (LegalizeResult) |
| 932 | TLI.ReplaceNodeResults(N, Results, DAG); |
| 933 | else |
| 934 | TLI.LowerOperationWrapper(N, Results, DAG); |
| 935 | |
| 936 | if (Results.empty()) |
| 937 | // The target didn't want to custom lower it after all. |
| 938 | return false; |
| 939 | |
| 940 | // Make everything that once used N's values now use those in Results instead. |
| 941 | assert(Results.size() == N->getNumValues() && |
| 942 | "Custom lowering returned the wrong number of results!" ); |
| 943 | for (unsigned i = 0, e = Results.size(); i != e; ++i) { |
| 944 | ReplaceValueWith(From: SDValue(N, i), To: Results[i]); |
| 945 | } |
| 946 | return true; |
| 947 | } |
| 948 | |
| 949 | |
| 950 | /// Widen the node's results with custom code provided by the target and return |
| 951 | /// "true", or do nothing and return "false". |
| 952 | bool DAGTypeLegalizer::CustomWidenLowerNode(SDNode *N, EVT VT) { |
| 953 | // See if the target wants to custom lower this node. |
| 954 | if (TLI.getOperationAction(Op: N->getOpcode(), VT) != TargetLowering::Custom) |
| 955 | return false; |
| 956 | |
| 957 | SmallVector<SDValue, 8> Results; |
| 958 | TLI.ReplaceNodeResults(N, Results, DAG); |
| 959 | |
| 960 | if (Results.empty()) |
| 961 | // The target didn't want to custom widen lower its result after all. |
| 962 | return false; |
| 963 | |
| 964 | // Update the widening map. |
| 965 | assert(Results.size() == N->getNumValues() && |
| 966 | "Custom lowering returned the wrong number of results!" ); |
| 967 | for (unsigned i = 0, e = Results.size(); i != e; ++i) { |
| 968 | // If this is a chain output or already widened just replace it. |
| 969 | bool WasWidened = SDValue(N, i).getValueType() != Results[i].getValueType(); |
| 970 | if (WasWidened) |
| 971 | SetWidenedVector(Op: SDValue(N, i), Result: Results[i]); |
| 972 | else |
| 973 | ReplaceValueWith(From: SDValue(N, i), To: Results[i]); |
| 974 | } |
| 975 | return true; |
| 976 | } |
| 977 | |
| 978 | SDValue DAGTypeLegalizer::DisintegrateMERGE_VALUES(SDNode *N, unsigned ResNo) { |
| 979 | for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) |
| 980 | if (i != ResNo) |
| 981 | ReplaceValueWith(From: SDValue(N, i), To: SDValue(N->getOperand(Num: i))); |
| 982 | return SDValue(N->getOperand(Num: ResNo)); |
| 983 | } |
| 984 | |
| 985 | /// Use ISD::EXTRACT_ELEMENT nodes to extract the low and high parts of the |
| 986 | /// given value. |
| 987 | void DAGTypeLegalizer::GetPairElements(SDValue Pair, |
| 988 | SDValue &Lo, SDValue &Hi) { |
| 989 | SDLoc dl(Pair); |
| 990 | EVT NVT = TLI.getTypeToTransformTo(Context&: *DAG.getContext(), VT: Pair.getValueType()); |
| 991 | std::tie(args&: Lo, args&: Hi) = DAG.SplitScalar(N: Pair, DL: dl, LoVT: NVT, HiVT: NVT); |
| 992 | } |
| 993 | |
| 994 | /// Build an integer with low bits Lo and high bits Hi. |
| 995 | SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) { |
| 996 | // Arbitrarily use dlHi for result SDLoc |
| 997 | SDLoc dlHi(Hi); |
| 998 | SDLoc dlLo(Lo); |
| 999 | EVT LVT = Lo.getValueType(); |
| 1000 | EVT HVT = Hi.getValueType(); |
| 1001 | EVT NVT = EVT::getIntegerVT(Context&: *DAG.getContext(), |
| 1002 | BitWidth: LVT.getSizeInBits() + HVT.getSizeInBits()); |
| 1003 | |
| 1004 | EVT ShiftAmtVT = TLI.getShiftAmountTy(LHSTy: NVT, DL: DAG.getDataLayout()); |
| 1005 | Lo = DAG.getNode(Opcode: ISD::ZERO_EXTEND, DL: dlLo, VT: NVT, Operand: Lo); |
| 1006 | Hi = DAG.getNode(Opcode: ISD::ANY_EXTEND, DL: dlHi, VT: NVT, Operand: Hi); |
| 1007 | Hi = DAG.getNode(Opcode: ISD::SHL, DL: dlHi, VT: NVT, N1: Hi, |
| 1008 | N2: DAG.getConstant(Val: LVT.getSizeInBits(), DL: dlHi, VT: ShiftAmtVT)); |
| 1009 | return DAG.getNode(Opcode: ISD::OR, DL: dlHi, VT: NVT, N1: Lo, N2: Hi); |
| 1010 | } |
| 1011 | |
| 1012 | /// Promote the given target boolean to a target boolean of the given type. |
| 1013 | /// A target boolean is an integer value, not necessarily of type i1, the bits |
| 1014 | /// of which conform to getBooleanContents. |
| 1015 | /// |
| 1016 | /// ValVT is the type of values that produced the boolean. |
| 1017 | SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, EVT ValVT) { |
| 1018 | return TLI.promoteTargetBoolean(DAG, Bool, ValVT); |
| 1019 | } |
| 1020 | |
| 1021 | /// Return the lower LoVT bits of Op in Lo and the upper HiVT bits in Hi. |
| 1022 | void DAGTypeLegalizer::SplitInteger(SDValue Op, |
| 1023 | EVT LoVT, EVT HiVT, |
| 1024 | SDValue &Lo, SDValue &Hi) { |
| 1025 | SDLoc dl(Op); |
| 1026 | assert(LoVT.getSizeInBits() + HiVT.getSizeInBits() == |
| 1027 | Op.getValueSizeInBits() && "Invalid integer splitting!" ); |
| 1028 | Lo = DAG.getNode(Opcode: ISD::TRUNCATE, DL: dl, VT: LoVT, Operand: Op); |
| 1029 | unsigned ReqShiftAmountInBits = |
| 1030 | Log2_32_Ceil(Value: Op.getValueType().getSizeInBits()); |
| 1031 | MVT ShiftAmountTy = |
| 1032 | TLI.getScalarShiftAmountTy(DAG.getDataLayout(), Op.getValueType()); |
| 1033 | if (ReqShiftAmountInBits > ShiftAmountTy.getSizeInBits()) |
| 1034 | ShiftAmountTy = MVT::getIntegerVT(BitWidth: NextPowerOf2(A: ReqShiftAmountInBits)); |
| 1035 | Hi = DAG.getNode(Opcode: ISD::SRL, DL: dl, VT: Op.getValueType(), N1: Op, |
| 1036 | N2: DAG.getConstant(Val: LoVT.getSizeInBits(), DL: dl, VT: ShiftAmountTy)); |
| 1037 | Hi = DAG.getNode(Opcode: ISD::TRUNCATE, DL: dl, VT: HiVT, Operand: Hi); |
| 1038 | } |
| 1039 | |
| 1040 | /// Return the lower and upper halves of Op's bits in a value type half the |
| 1041 | /// size of Op's. |
| 1042 | void DAGTypeLegalizer::SplitInteger(SDValue Op, |
| 1043 | SDValue &Lo, SDValue &Hi) { |
| 1044 | EVT HalfVT = |
| 1045 | EVT::getIntegerVT(Context&: *DAG.getContext(), BitWidth: Op.getValueSizeInBits() / 2); |
| 1046 | SplitInteger(Op, LoVT: HalfVT, HiVT: HalfVT, Lo, Hi); |
| 1047 | } |
| 1048 | |
| 1049 | |
| 1050 | //===----------------------------------------------------------------------===// |
| 1051 | // Entry Point |
| 1052 | //===----------------------------------------------------------------------===// |
| 1053 | |
| 1054 | /// This transforms the SelectionDAG into a SelectionDAG that only uses types |
| 1055 | /// natively supported by the target. Returns "true" if it made any changes. |
| 1056 | /// |
| 1057 | /// Note that this is an involved process that may invalidate pointers into |
| 1058 | /// the graph. |
| 1059 | bool SelectionDAG::LegalizeTypes() { |
| 1060 | return DAGTypeLegalizer(*this).run(); |
| 1061 | } |
| 1062 | |