23#define DEBUG_TYPE "legalize-types" 
   29void DAGTypeLegalizer::PerformExpensiveChecks() {
 
   79    for (
unsigned i = 0, e = 
Node.getNumValues(); i != e; ++i) {
 
   83      auto ResId = ValueToIdMap.lookup(Res);
 
   87        auto I = ReplacedValues.find(ResId);
 
   88        if (
I != ReplacedValues.end()) {
 
   92            if (U.getResNo() == i)
 
   94                     "Remapped value has non-trivial use!");
 
   98          auto NewValId = 
I->second;
 
   99          I = ReplacedValues.find(NewValId);
 
  100          while (
I != ReplacedValues.end()) {
 
  101            NewValId = 
I->second;
 
  102            I = ReplacedValues.find(NewValId);
 
  104          SDValue NewVal = getSDValue(NewValId);
 
  107                 "ReplacedValues maps to a new node!");
 
  109        if (PromotedIntegers.count(ResId))
 
  111        if (SoftenedFloats.count(ResId))
 
  113        if (ScalarizedVectors.count(ResId))
 
  115        if (ExpandedIntegers.count(ResId))
 
  117        if (ExpandedFloats.count(ResId))
 
  119        if (SplitVectors.count(ResId))
 
  121        if (WidenedVectors.count(ResId))
 
  123        if (PromotedFloats.count(ResId))
 
  125        if (SoftPromotedHalfs.count(ResId))
 
  135          dbgs() << 
"Unprocessed value in a map!";
 
  138      } 
else if (isTypeLegal(Res.getValueType()) || IgnoreNodeResults(&Node)) {
 
  140          dbgs() << 
"Value with legal type was transformed!";
 
  145          SDValue NodeById = IdToValueMap.lookup(ResId);
 
  152            dbgs() << 
"Processed value not in any map!";
 
  155        } 
else if (Mapped & (Mapped - 1)) {
 
  156          dbgs() << 
"Value in multiple maps!";
 
  163          dbgs() << 
" ReplacedValues";
 
  165          dbgs() << 
" PromotedIntegers";
 
  167          dbgs() << 
" SoftenedFloats";
 
  169          dbgs() << 
" ScalarizedVectors";
 
  171          dbgs() << 
" ExpandedIntegers";
 
  173          dbgs() << 
" ExpandedFloats";
 
  175          dbgs() << 
" SplitVectors";
 
  177          dbgs() << 
" WidenedVectors";
 
  179          dbgs() << 
" PromotedFloats";
 
  181          dbgs() << 
" SoftPromoteHalfs";
 
  190  for (SDNode *
N : NewNodes) {
 
  191    for (SDNode *U : 
N->users())
 
  192      assert(
U->getNodeId() == 
NewNode && 
"NewNode used by non-NewNode!");
 
  217    if (
Node.getNumOperands() == 0) {
 
  219      Worklist.push_back(&
Node);
 
  226  while (!Worklist.empty()) {
 
  227#ifndef EXPENSIVE_CHECKS 
  230      PerformExpensiveChecks();
 
  232    SDNode *
N = Worklist.pop_back_val();
 
  234           "Node should be ready if on worklist!");
 
  241    if (IgnoreNodeResults(
N)) {
 
  248    for (
unsigned i = 0, NumResults = 
N->getNumValues(); i < NumResults; ++i) {
 
  249      EVT ResultVT = 
N->getValueType(i);
 
  250      LLVM_DEBUG(
dbgs() << 
"Analyzing result type: " << ResultVT << 
"\n");
 
  251      switch (getTypeAction(ResultVT)) {
 
  257            "Scalarization of scalable vectors is not supported.");
 
  264        PromoteIntegerResult(
N, i);
 
  268        ExpandIntegerResult(
N, i);
 
  272        SoftenFloatResult(
N, i);
 
  276        ExpandFloatResult(
N, i);
 
  280        ScalarizeVectorResult(
N, i);
 
  284        SplitVectorResult(
N, i);
 
  288        WidenVectorResult(
N, i);
 
  292        PromoteFloatResult(
N, i);
 
  296        SoftPromoteHalfResult(
N, i);
 
  306    unsigned NumOperands = 
N->getNumOperands();
 
  307    bool NeedsReanalyzing = 
false;
 
  309    for (i = 0; i != NumOperands; ++i) {
 
  310      if (IgnoreNodeResults(
N->getOperand(i).getNode()))
 
  313      const auto &
Op = 
N->getOperand(i);
 
  315      EVT OpVT = 
Op.getValueType();
 
  316      switch (getTypeAction(OpVT)) {
 
  322            "Scalarization of scalable vectors is not supported.");
 
  327        NeedsReanalyzing = PromoteIntegerOperand(
N, i);
 
  331        NeedsReanalyzing = ExpandIntegerOperand(
N, i);
 
  335        NeedsReanalyzing = SoftenFloatOperand(
N, i);
 
  339        NeedsReanalyzing = ExpandFloatOperand(
N, i);
 
  343        NeedsReanalyzing = ScalarizeVectorOperand(
N, i);
 
  347        NeedsReanalyzing = SplitVectorOperand(
N, i);
 
  351        NeedsReanalyzing = WidenVectorOperand(
N, i);
 
  355        NeedsReanalyzing = PromoteFloatOperand(
N, i);
 
  359        NeedsReanalyzing = SoftPromoteHalfOperand(
N, i);
 
  369    if (NeedsReanalyzing) {
 
  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)
 
  394    if (i == NumOperands) {
 
  406      int NodeId = 
User->getNodeId();
 
  411        User->setNodeId(NodeId-1);
 
  415          Worklist.push_back(
User);
 
  433        Worklist.push_back(
User);
 
  437#ifndef EXPENSIVE_CHECKS 
  440    PerformExpensiveChecks();
 
  449  DAG.RemoveDeadNodes();
 
  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: ";
 
  468      if (!IgnoreNodeResults(
Node.getOperand(i).getNode()) &&
 
  469          !isTypeLegal(
Node.getOperand(i).getValueType())) {
 
  470        dbgs() << 
"Operand type " << i << 
" illegal: ";
 
  477         dbgs() << 
"New node not analyzed?\n";
 
  479         dbgs() << 
"Unanalyzed node not noticed?\n";
 
  480       else if (
Node.getNodeId() > 0)
 
  481         dbgs() << 
"Operand not processed?\n";
 
  483         dbgs() << 
"Not added to worklist?\n";
 
 
  517  std::vector<SDValue> NewOps;
 
  518  unsigned NumProcessed = 0;
 
  519  for (
unsigned i = 0, e = 
N->getNumOperands(); i != e; ++i) {
 
  528    if (!NewOps.empty()) {
 
  530      NewOps.push_back(
Op);
 
  531    } 
else if (
Op != OrigOp) {
 
  534      NewOps.push_back(
Op);
 
  539  if (!NewOps.empty()) {
 
  540    SDNode *
M = DAG.UpdateNodeOperands(
N, NewOps);
 
  561  N->setNodeId(
N->getNumOperands() - NumProcessed);
 
  563    Worklist.push_back(
N);
 
  570void DAGTypeLegalizer::AnalyzeNewValue(
SDValue &Val) {
 
  579void DAGTypeLegalizer::RemapValue(
SDValue &V) {
 
  580  auto Id = getTableId(V);
 
  584void DAGTypeLegalizer::RemapId(TableId &Id) {
 
  585  auto I = ReplacedValues.find(Id);
 
  586  if (
I != ReplacedValues.end()) {
 
  587    assert(Id != 
I->second && 
"Id is mapped to itself.");
 
  603    DAGTypeLegalizer &DTL;
 
  604    SmallSetVector<SDNode*, 16> &NodesToAnalyze;
 
  606    explicit NodeUpdateListener(DAGTypeLegalizer &dtl,
 
  607                                SmallSetVector<SDNode*, 16> &nta)
 
  608      : SelectionDAG::DAGUpdateListener(dtl.getDAG()),
 
  609        DTL(dtl), NodesToAnalyze(nta) {}
 
  611    void NodeDeleted(SDNode *
N, SDNode *
E)
 override {
 
  614             "Invalid node ID for RAUW deletion!");
 
  617      assert(
E && 
"Node not replaced?");
 
  632    void NodeUpdated(SDNode *
N)
 override {
 
  638             "Invalid node ID for RAUW deletion!");
 
  648void DAGTypeLegalizer::ReplaceValueWith(
SDValue From, 
SDValue To) {
 
  656  SmallSetVector<SDNode*, 16> NodesToAnalyze;
 
  657  NodeUpdateListener NUL(*
this, NodesToAnalyze);
 
  662    auto FromId = getTableId(From);
 
  663    auto ToId = getTableId(To);
 
  666      ReplacedValues[FromId] = ToId;
 
  667    DAG.ReplaceAllUsesOfValueWith(From, To);
 
  670    while (!NodesToAnalyze.
empty()) {
 
  679      SDNode *
M = AnalyzeNewNode(
N);
 
  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) {
 
  695          auto OldValId = getTableId(OldVal);
 
  696          auto NewValId = getTableId(NewVal);
 
  697          DAG.ReplaceAllUsesOfValueWith(OldVal, NewVal);
 
  698          if (OldValId != NewValId)
 
  699            ReplacedValues[OldValId] = NewValId;
 
  712         TLI.getTypeToTransformTo(*DAG.getContext(), 
Op.getValueType()) &&
 
  713         "Invalid type for promoted integer");
 
  714  AnalyzeNewValue(Result);
 
  716  auto &OpIdEntry = PromotedIntegers[getTableId(
Op)];
 
  717  assert((OpIdEntry == 0) && 
"Node is already promoted!");
 
  718  OpIdEntry = getTableId(Result);
 
  720  DAG.transferDbgValues(
Op, Result);
 
  725  EVT VT = 
Result.getValueType();
 
  726  LLVMContext &Ctx = *DAG.getContext();
 
  728          VT == TLI.getTypeToTransformTo(Ctx, 
Op.getValueType())) &&
 
  729         "Invalid type for softened float");
 
  731  AnalyzeNewValue(Result);
 
  733  auto &OpIdEntry = SoftenedFloats[getTableId(
Op)];
 
  734  assert((OpIdEntry == 0) && 
"Node is already converted to integer!");
 
  735  OpIdEntry = getTableId(Result);
 
  740         TLI.getTypeToTransformTo(*DAG.getContext(), 
Op.getValueType()) &&
 
  741         "Invalid type for promoted float");
 
  742  AnalyzeNewValue(Result);
 
  744  auto &OpIdEntry = PromotedFloats[getTableId(
Op)];
 
  745  assert((OpIdEntry == 0) && 
"Node is already promoted!");
 
  746  OpIdEntry = getTableId(Result);
 
  751         "Invalid type for soft-promoted half");
 
  752  AnalyzeNewValue(Result);
 
  754  auto &OpIdEntry = SoftPromotedHalfs[getTableId(
Op)];
 
  755  assert((OpIdEntry == 0) && 
"Node is already promoted!");
 
  756  OpIdEntry = getTableId(Result);
 
  766             Op.getScalarValueSizeInBits() &&
 
  767         "Invalid type for scalarized vector");
 
  768  AnalyzeNewValue(Result);
 
  770  auto &OpIdEntry = ScalarizedVectors[getTableId(
Op)];
 
  771  assert((OpIdEntry == 0) && 
"Node is already scalarized!");
 
  772  OpIdEntry = getTableId(Result);
 
  777  std::pair<TableId, TableId> &
Entry = ExpandedIntegers[getTableId(
Op)];
 
  778  assert((
Entry.first != 0) && 
"Operand isn't expanded");
 
  786         TLI.getTypeToTransformTo(*DAG.getContext(), 
Op.getValueType()) &&
 
  787         Hi.getValueType() == 
Lo.getValueType() &&
 
  788         "Invalid type for expanded integer");
 
  795  if (DAG.getDataLayout().isBigEndian()) {
 
  796    DAG.transferDbgValues(
Op, 
Hi, 0, 
Hi.getValueSizeInBits(), 
false);
 
  797    DAG.transferDbgValues(
Op, 
Lo, 
Hi.getValueSizeInBits(),
 
  798                          Lo.getValueSizeInBits());
 
  800    DAG.transferDbgValues(
Op, 
Lo, 0, 
Lo.getValueSizeInBits(), 
false);
 
  801    DAG.transferDbgValues(
Op, 
Hi, 
Lo.getValueSizeInBits(),
 
  802                          Hi.getValueSizeInBits());
 
  806  std::pair<TableId, TableId> &
Entry = ExpandedIntegers[getTableId(
Op)];
 
  807  assert((
Entry.first == 0) && 
"Node already expanded");
 
  814  std::pair<TableId, TableId> &
Entry = ExpandedFloats[getTableId(
Op)];
 
  815  assert((
Entry.first != 0) && 
"Operand isn't expanded");
 
  823         TLI.getTypeToTransformTo(*DAG.getContext(), 
Op.getValueType()) &&
 
  824         Hi.getValueType() == 
Lo.getValueType() &&
 
  825         "Invalid type for expanded float");
 
  830  std::pair<TableId, TableId> &
Entry = ExpandedFloats[getTableId(
Op)];
 
  831  assert((
Entry.first == 0) && 
"Node already expanded");
 
  838  std::pair<TableId, TableId> &
Entry = SplitVectors[getTableId(
Op)];
 
  841  assert(
Lo.getNode() && 
"Operand isn't split");
 
  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");
 
  858  std::pair<TableId, TableId> &
Entry = SplitVectors[getTableId(
Op)];
 
  859  assert((
Entry.first == 0) && 
"Node already split");
 
  866         TLI.getTypeToTransformTo(*DAG.getContext(), 
Op.getValueType()) &&
 
  867         "Invalid type for widened vector");
 
  868  AnalyzeNewValue(Result);
 
  870  auto &OpIdEntry = WidenedVectors[getTableId(
Op)];
 
  871  assert((OpIdEntry == 0) && 
"Node already widened!");
 
  872  OpIdEntry = getTableId(Result);
 
  883  return DAG.getNode(ISD::BITCAST, SDLoc(
Op),
 
  889  assert(
Op.getValueType().isVector() && 
"Only applies to vectors!");
 
  890  unsigned EltWidth = 
Op.getScalarValueSizeInBits();
 
  892  auto EltCnt = 
Op.getValueType().getVectorElementCount();
 
  893  return DAG.getNode(ISD::BITCAST, SDLoc(
Op),
 
  905  Align DestAlign = DAG.getReducedAlign(DestVT, 
false);
 
  906  Align OpAlign = DAG.getReducedAlign(
Op.getValueType(), 
false);
 
  909      DAG.CreateStackTemporary(
Op.getValueType().getStoreSize(), Align);
 
  911  SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, 
Op, StackPtr,
 
  912                               MachinePointerInfo(), Align);
 
  914  return DAG.getLoad(DestVT, dl, Store, StackPtr, MachinePointerInfo(), Align);
 
  925bool DAGTypeLegalizer::CustomLowerNode(
SDNode *
N, 
EVT VT, 
bool LegalizeResult) {
 
  932    TLI.ReplaceNodeResults(
N, 
Results, DAG);
 
  934    TLI.LowerOperationWrapper(
N, 
Results, DAG);
 
  942         "Custom lowering returned the wrong number of results!");
 
  943  for (
unsigned i = 0, e = 
Results.
size(); i != e; ++i) {
 
  952bool DAGTypeLegalizer::CustomWidenLowerNode(
SDNode *
N, 
EVT VT) {
 
  958  TLI.ReplaceNodeResults(
N, 
Results, DAG);
 
  966         "Custom lowering returned the wrong number of results!");
 
  967  for (
unsigned i = 0, e = 
Results.
size(); i != e; ++i) {
 
  978SDValue DAGTypeLegalizer::DisintegrateMERGE_VALUES(
SDNode *
N, 
unsigned ResNo) {
 
  979  for (
unsigned i = 0, e = 
N->getNumValues(); i != e; ++i)
 
  982  return SDValue(
N->getOperand(ResNo));
 
  987void DAGTypeLegalizer::GetPairElements(
SDValue Pair,
 
  990  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Pair.
getValueType());
 
  991  std::tie(
Lo, 
Hi) = DAG.SplitScalar(Pair, dl, NVT, NVT);
 
  999  EVT LVT = 
Lo.getValueType();
 
 1000  EVT HVT = 
Hi.getValueType();
 
 1007                   DAG.getShiftAmountConstant(LVT.
getSizeInBits(), NVT, dlHi));
 
 1017  return TLI.promoteTargetBoolean(DAG, 
Bool, ValVT);
 
 1021void DAGTypeLegalizer::SplitInteger(
SDValue Op,
 
 1026         Op.getValueSizeInBits() && 
"Invalid integer splitting!");
 
 1030      DAG.getShiftAmountConstant(LoVT.
getSizeInBits(), 
Op.getValueType(), dl));
 
 1036void DAGTypeLegalizer::SplitInteger(
SDValue Op,
 
 1040  SplitInteger(
Op, HalfVT, HalfVT, 
Lo, 
Hi);
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
Function Alias Analysis Results
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
 
static cl::opt< bool > EnableExpensiveChecks("enable-legalize-types-checking", cl::Hidden)
 
This file implements a set that has insertion order iteration characteristics.
 
DEMANGLE_DUMP_METHOD void dump() const
 
This takes an arbitrary SelectionDAG as input and hacks on it until only value types the target machi...
 
bool run()
This is the main entry point for the type legalizer.
 
void NoteDeletion(SDNode *Old, SDNode *New)
 
@ ReadyToProcess
All operands have been processed, so this node is ready to be handled.
 
@ NewNode
This is a new node, not before seen, that was created in the process of legalizing some other node.
 
@ Unanalyzed
This node's ID needs to be set to the number of its unprocessed operands.
 
@ Processed
This is a node that has already been processed.
 
Convenience struct for specifying and reasoning about fast-math flags.
 
Type * getValueType() const
 
This class is used to form a handle around another node that is persistent and is updated across invo...
 
const SDValue & getValue() const
 
Represents one node in the SelectionDAG.
 
int getNodeId() const
Return the unique node id.
 
void setNodeId(int Id)
Set unique node id.
 
Represents a use of a SDNode.
 
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
 
SDNode * getNode() const
get the SDNode which holds the desired result
 
EVT getValueType() const
Return the ValueType of the referenced return value.
 
bool use_empty() const
Return true if there are no nodes using value ResNo of Node.
 
void setNode(SDNode *N)
set the SDNode
 
Help to insert SDNodeFlags automatically in transforming.
 
iterator_range< allnodes_iterator > allnodes()
 
LLVM_ABI bool LegalizeTypes()
This transforms the SelectionDAG into a SelectionDAG that only uses types natively supported by the t...
 
bool remove(const value_type &X)
Remove an item from the set vector.
 
bool empty() const
Determine if the SetVector is empty or not.
 
bool insert(const value_type &X)
Insert a new element into the SetVector.
 
value_type pop_back_val()
 
void push_back(const T &Elt)
 
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
 
@ TypeScalarizeScalableVector
 
unsigned getNumOperands() const
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
 
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
 
@ SHL
Shift and rotation operations.
 
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
 
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
 
NodeAddr< NodeBase * > Node
 
This is an optimization pass for GlobalISel generic memory operations.
 
testing::Matcher< const detail::ErrorHolder & > Failed()
 
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
 
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
 
DWARFExpression::Operation Op
 
constexpr unsigned BitWidth
 
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
 
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
 
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
 
These are IR-level optimization flags that may be propagated to SDNodes.
 
Clients of various APIs that cause global effects on the DAG can optionally implement this interface.