//===-- LegalizeTypes.cpp - Common code for DAG type legalizer ------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the SelectionDAG::LegalizeTypes method. It transforms // an arbitrary well-formed SelectionDAG to only consist of legal types. This // is common code shared among the LegalizeTypes*.cpp files. // //===----------------------------------------------------------------------===// #include "LegalizeTypes.h" #include "llvm/ADT/SetVector.h" #include "llvm/IR/DataLayout.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" usingnamespacellvm; #define DEBUG_TYPE … static cl::opt<bool> EnableExpensiveChecks("enable-legalize-types-checking", cl::Hidden); /// Do extensive, expensive, basic correctness checking. void DAGTypeLegalizer::PerformExpensiveChecks() { … } /// This is the main entry point for the type legalizer. This does a top-down /// traversal of the dag, legalizing types as it goes. Returns "true" if it made /// any changes. bool DAGTypeLegalizer::run() { … } /// The specified node is the root of a subtree of potentially new nodes. /// Correct any processed operands (this may change the node) and calculate the /// NodeId. If the node itself changes to a processed node, it is not remapped - /// the caller needs to take care of this. Returns the potentially changed node. SDNode *DAGTypeLegalizer::AnalyzeNewNode(SDNode *N) { … } /// Call AnalyzeNewNode, updating the node in Val if needed. /// If the node changes to a processed node, then remap it. void DAGTypeLegalizer::AnalyzeNewValue(SDValue &Val) { … } /// If the specified value was already legalized to another value, /// replace it by that value. void DAGTypeLegalizer::RemapValue(SDValue &V) { … } void DAGTypeLegalizer::RemapId(TableId &Id) { … } namespace { /// This class is a DAGUpdateListener that listens for updates to nodes and /// recomputes their ready state. class NodeUpdateListener : public SelectionDAG::DAGUpdateListener { … }; } /// The specified value was legalized to the specified other value. /// Update the DAG and NodeIds replacing any uses of From to use To instead. void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) { … } void DAGTypeLegalizer::SetPromotedInteger(SDValue Op, SDValue Result) { … } void DAGTypeLegalizer::SetSoftenedFloat(SDValue Op, SDValue Result) { … } void DAGTypeLegalizer::SetPromotedFloat(SDValue Op, SDValue Result) { … } void DAGTypeLegalizer::SetSoftPromotedHalf(SDValue Op, SDValue Result) { … } void DAGTypeLegalizer::SetScalarizedVector(SDValue Op, SDValue Result) { … } void DAGTypeLegalizer::GetExpandedInteger(SDValue Op, SDValue &Lo, SDValue &Hi) { … } void DAGTypeLegalizer::SetExpandedInteger(SDValue Op, SDValue Lo, SDValue Hi) { … } void DAGTypeLegalizer::GetExpandedFloat(SDValue Op, SDValue &Lo, SDValue &Hi) { … } void DAGTypeLegalizer::SetExpandedFloat(SDValue Op, SDValue Lo, SDValue Hi) { … } void DAGTypeLegalizer::GetSplitVector(SDValue Op, SDValue &Lo, SDValue &Hi) { … } void DAGTypeLegalizer::SetSplitVector(SDValue Op, SDValue Lo, SDValue Hi) { … } void DAGTypeLegalizer::SetWidenedVector(SDValue Op, SDValue Result) { … } //===----------------------------------------------------------------------===// // Utilities. //===----------------------------------------------------------------------===// /// Convert to an integer of the same size. SDValue DAGTypeLegalizer::BitConvertToInteger(SDValue Op) { … } /// Convert to a vector of integers of the same size. SDValue DAGTypeLegalizer::BitConvertVectorToIntegerVector(SDValue Op) { … } SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op, EVT DestVT) { … } /// Replace the node's results with custom code provided by the target and /// return "true", or do nothing and return "false". /// The last parameter is FALSE if we are dealing with a node with legal /// result types and illegal operand. The second parameter denotes the type of /// illegal OperandNo in that case. /// The last parameter being TRUE means we are dealing with a /// node with illegal result types. The second parameter denotes the type of /// illegal ResNo in that case. bool DAGTypeLegalizer::CustomLowerNode(SDNode *N, EVT VT, bool LegalizeResult) { … } /// Widen the node's results with custom code provided by the target and return /// "true", or do nothing and return "false". bool DAGTypeLegalizer::CustomWidenLowerNode(SDNode *N, EVT VT) { … } SDValue DAGTypeLegalizer::DisintegrateMERGE_VALUES(SDNode *N, unsigned ResNo) { … } /// Use ISD::EXTRACT_ELEMENT nodes to extract the low and high parts of the /// given value. void DAGTypeLegalizer::GetPairElements(SDValue Pair, SDValue &Lo, SDValue &Hi) { … } /// Build an integer with low bits Lo and high bits Hi. SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) { … } /// Promote the given target boolean to a target boolean of the given type. /// A target boolean is an integer value, not necessarily of type i1, the bits /// of which conform to getBooleanContents. /// /// ValVT is the type of values that produced the boolean. SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, EVT ValVT) { … } /// Return the lower LoVT bits of Op in Lo and the upper HiVT bits in Hi. void DAGTypeLegalizer::SplitInteger(SDValue Op, EVT LoVT, EVT HiVT, SDValue &Lo, SDValue &Hi) { … } /// Return the lower and upper halves of Op's bits in a value type half the /// size of Op's. void DAGTypeLegalizer::SplitInteger(SDValue Op, SDValue &Lo, SDValue &Hi) { … } //===----------------------------------------------------------------------===// // Entry Point //===----------------------------------------------------------------------===// /// This transforms the SelectionDAG into a SelectionDAG that only uses types /// natively supported by the target. Returns "true" if it made any changes. /// /// Note that this is an involved process that may invalidate pointers into /// the graph. bool SelectionDAG::LegalizeTypes() { … }