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