diff options
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
| -rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 1294 | 
1 files changed, 1283 insertions, 11 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index eead526f099e..2e2020d6183f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -723,9 +723,9 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {    // code to the MachineBasicBlock.    if (TimePassesIsEnabled) {      NamedRegionTimer T("Instruction Selection", GroupName); -    InstructionSelect(); +    DoInstructionSelection();    } else { -    InstructionSelect(); +    DoInstructionSelection();    }    DEBUG(dbgs() << "Selected selection DAG:\n"); @@ -765,6 +765,66 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {    DEBUG(BB->dump());  } +void SelectionDAGISel::DoInstructionSelection() { +  DEBUG(errs() << "===== Instruction selection begins:\n"); + +  PreprocessISelDAG(); +   +  // Select target instructions for the DAG. +  { +    // Number all nodes with a topological order and set DAGSize. +    DAGSize = CurDAG->AssignTopologicalOrder(); +     +    // Create a dummy node (which is not added to allnodes), that adds +    // a reference to the root node, preventing it from being deleted, +    // and tracking any changes of the root. +    HandleSDNode Dummy(CurDAG->getRoot()); +    ISelPosition = SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode()); +    ++ISelPosition; +     +    // The AllNodes list is now topological-sorted. Visit the +    // nodes by starting at the end of the list (the root of the +    // graph) and preceding back toward the beginning (the entry +    // node). +    while (ISelPosition != CurDAG->allnodes_begin()) { +      SDNode *Node = --ISelPosition; +      // Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes, +      // but there are currently some corner cases that it misses. Also, this +      // makes it theoretically possible to disable the DAGCombiner. +      if (Node->use_empty()) +        continue; +       +      SDNode *ResNode = Select(Node); +       +      // FIXME: This is pretty gross.  'Select' should be changed to not return +      // anything at all and this code should be nuked with a tactical strike. +       +      // If node should not be replaced, continue with the next one. +      if (ResNode == Node || Node->getOpcode() == ISD::DELETED_NODE) +        continue; +      // Replace node. +      if (ResNode) +        ReplaceUses(Node, ResNode); +       +      // If after the replacement this node is not used any more, +      // remove this dead node. +      if (Node->use_empty()) { // Don't delete EntryToken, etc. +        ISelUpdater ISU(ISelPosition); +        CurDAG->RemoveDeadNode(Node, &ISU); +      } +    } +     +    CurDAG->setRoot(Dummy.getValue()); +  }     +  DEBUG(errs() << "===== Instruction selection ends:\n"); + +  PostprocessISelDAG(); +   +  // FIXME: This shouldn't be needed, remove it. +  CurDAG->RemoveDeadNodes(); +} + +  void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,                                              MachineFunction &MF,                                              MachineModuleInfo *MMI, @@ -1316,13 +1376,29 @@ static SDNode *findFlagUse(SDNode *N) {  /// This function recursively traverses up the operand chain, ignoring  /// certain nodes.  static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse, -                          SDNode *Root, -                          SmallPtrSet<SDNode*, 16> &Visited) { -  if (Use->getNodeId() < Def->getNodeId() || -      !Visited.insert(Use)) +                          SDNode *Root, SmallPtrSet<SDNode*, 16> &Visited, +                          bool IgnoreChains) { +  // The NodeID's are given uniques ID's where a node ID is guaranteed to be +  // greater than all of its (recursive) operands.  If we scan to a point where +  // 'use' is smaller than the node we're scanning for, then we know we will +  // never find it. +  // +  // The Use may be -1 (unassigned) if it is a newly allocated node.  This can +  // happen because we scan down to newly selected nodes in the case of flag +  // uses. +  if ((Use->getNodeId() < Def->getNodeId() && Use->getNodeId() != -1)) +    return false; +   +  // Don't revisit nodes if we already scanned it and didn't fail, we know we +  // won't fail if we scan it again. +  if (!Visited.insert(Use))      return false;    for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) { +    // Ignore chain uses, they are validated by HandleMergeInputChains. +    if (Use->getOperand(i).getValueType() == MVT::Other && IgnoreChains) +      continue; +          SDNode *N = Use->getOperand(i).getNode();      if (N == Def) {        if (Use == ImmedUse || Use == Root) @@ -1332,7 +1408,7 @@ static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,      }      // Traverse up the operand chain. -    if (findNonImmUse(N, Def, ImmedUse, Root, Visited)) +    if (findNonImmUse(N, Def, ImmedUse, Root, Visited, IgnoreChains))        return true;    }    return false; @@ -1347,9 +1423,10 @@ static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,  /// have one non-chain use, we only need to watch out for load/op/store  /// and load/op/cmp case where the root (store / cmp) may reach the load via  /// its chain operand. -static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) { +static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse, +                               bool IgnoreChains) {    SmallPtrSet<SDNode*, 16> Visited; -  return findNonImmUse(Root, Def, ImmedUse, Root, Visited); +  return findNonImmUse(Root, Def, ImmedUse, Root, Visited, IgnoreChains);  }  /// IsProfitableToFold - Returns true if it's profitable to fold the specific @@ -1362,7 +1439,8 @@ bool SelectionDAGISel::IsProfitableToFold(SDValue N, SDNode *U,  /// IsLegalToFold - Returns true if the specific operand node N of  /// U can be folded during instruction selection that starts at Root. -bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const { +bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root, +                                     bool IgnoreChains) const {    if (OptLevel == CodeGenOpt::None) return false;    // If Root use can somehow reach N through a path that that doesn't contain @@ -1416,7 +1494,7 @@ bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const {      VT = Root->getValueType(Root->getNumValues()-1);    } -  return !isNonImmUse(Root, N.getNode(), U); +  return !isNonImmUse(Root, N.getNode(), U, IgnoreChains);  }  SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) { @@ -1428,6 +1506,7 @@ SDNode *SelectionDAGISel::Select_INLINEASM(SDNode *N) {    VTs.push_back(MVT::Flag);    SDValue New = CurDAG->getNode(ISD::INLINEASM, N->getDebugLoc(),                                  VTs, &Ops[0], Ops.size()); +  New->setNodeId(-1);    return New.getNode();  } @@ -1443,7 +1522,1200 @@ SDNode *SelectionDAGISel::Select_EH_LABEL(SDNode *N) {                                MVT::Other, Tmp, Chain);  } +/// GetVBR - decode a vbr encoding whose top bit is set. +ALWAYS_INLINE static uint64_t +GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) { +  assert(Val >= 128 && "Not a VBR"); +  Val &= 127;  // Remove first vbr bit. +   +  unsigned Shift = 7; +  uint64_t NextBits; +  do { +    NextBits = MatcherTable[Idx++]; +    Val |= (NextBits&127) << Shift; +    Shift += 7; +  } while (NextBits & 128); +   +  return Val; +} + + +/// UpdateChainsAndFlags - When a match is complete, this method updates uses of +/// interior flag and chain results to use the new flag and chain results. +void SelectionDAGISel:: +UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain, +                     const SmallVectorImpl<SDNode*> &ChainNodesMatched, +                     SDValue InputFlag, +                     const SmallVectorImpl<SDNode*> &FlagResultNodesMatched, +                     bool isMorphNodeTo) { +  SmallVector<SDNode*, 4> NowDeadNodes; +   +  ISelUpdater ISU(ISelPosition); + +  // Now that all the normal results are replaced, we replace the chain and +  // flag results if present. +  if (!ChainNodesMatched.empty()) { +    assert(InputChain.getNode() != 0 && +           "Matched input chains but didn't produce a chain"); +    // Loop over all of the nodes we matched that produced a chain result. +    // Replace all the chain results with the final chain we ended up with. +    for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) { +      SDNode *ChainNode = ChainNodesMatched[i]; +       +      // If this node was already deleted, don't look at it. +      if (ChainNode->getOpcode() == ISD::DELETED_NODE) +        continue; +       +      // Don't replace the results of the root node if we're doing a +      // MorphNodeTo. +      if (ChainNode == NodeToMatch && isMorphNodeTo) +        continue; +       +      SDValue ChainVal = SDValue(ChainNode, ChainNode->getNumValues()-1); +      if (ChainVal.getValueType() == MVT::Flag) +        ChainVal = ChainVal.getValue(ChainVal->getNumValues()-2); +      assert(ChainVal.getValueType() == MVT::Other && "Not a chain?"); +      CurDAG->ReplaceAllUsesOfValueWith(ChainVal, InputChain, &ISU); +       +      // If the node became dead, delete it. +      if (ChainNode->use_empty()) +        NowDeadNodes.push_back(ChainNode); +    } +  } +   +  // If the result produces a flag, update any flag results in the matched +  // pattern with the flag result. +  if (InputFlag.getNode() != 0) { +    // Handle any interior nodes explicitly marked. +    for (unsigned i = 0, e = FlagResultNodesMatched.size(); i != e; ++i) { +      SDNode *FRN = FlagResultNodesMatched[i]; +       +      // If this node was already deleted, don't look at it. +      if (FRN->getOpcode() == ISD::DELETED_NODE) +        continue; +       +      assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Flag && +             "Doesn't have a flag result"); +      CurDAG->ReplaceAllUsesOfValueWith(SDValue(FRN, FRN->getNumValues()-1), +                                        InputFlag, &ISU); +       +      // If the node became dead, delete it. +      if (FRN->use_empty()) +        NowDeadNodes.push_back(FRN); +    } +  } +   +  if (!NowDeadNodes.empty()) +    CurDAG->RemoveDeadNodes(NowDeadNodes, &ISU); +   +  DEBUG(errs() << "ISEL: Match complete!\n"); +} + +enum ChainResult { +  CR_Simple, +  CR_InducesCycle, +  CR_LeadsToInteriorNode +}; + +/// WalkChainUsers - Walk down the users of the specified chained node that is +/// part of the pattern we're matching, looking at all of the users we find. +/// This determines whether something is an interior node, whether we have a +/// non-pattern node in between two pattern nodes (which prevent folding because +/// it would induce a cycle) and whether we have a TokenFactor node sandwiched +/// between pattern nodes (in which case the TF becomes part of the pattern). +/// +/// The walk we do here is guaranteed to be small because we quickly get down to +/// already selected nodes "below" us. +static ChainResult  +WalkChainUsers(SDNode *ChainedNode, +               SmallVectorImpl<SDNode*> &ChainedNodesInPattern, +               SmallVectorImpl<SDNode*> &InteriorChainedNodes) { +  ChainResult Result = CR_Simple; +   +  for (SDNode::use_iterator UI = ChainedNode->use_begin(), +         E = ChainedNode->use_end(); UI != E; ++UI) { +    // Make sure the use is of the chain, not some other value we produce. +    if (UI.getUse().getValueType() != MVT::Other) continue; +     +    SDNode *User = *UI; + +    // If we see an already-selected machine node, then we've gone beyond the +    // pattern that we're selecting down into the already selected chunk of the +    // DAG. +    if (User->isMachineOpcode() || +        User->getOpcode() == ISD::HANDLENODE)  // Root of the graph. +      continue; +     +    if (User->getOpcode() == ISD::CopyToReg || +        User->getOpcode() == ISD::CopyFromReg || +        User->getOpcode() == ISD::INLINEASM) { +      // If their node ID got reset to -1 then they've already been selected. +      // Treat them like a MachineOpcode. +      if (User->getNodeId() == -1) +        continue; +    } + +    // If we have a TokenFactor, we handle it specially. +    if (User->getOpcode() != ISD::TokenFactor) { +      // If the node isn't a token factor and isn't part of our pattern, then it +      // must be a random chained node in between two nodes we're selecting. +      // This happens when we have something like: +      //   x = load ptr +      //   call +      //   y = x+4 +      //   store y -> ptr +      // Because we structurally match the load/store as a read/modify/write, +      // but the call is chained between them.  We cannot fold in this case +      // because it would induce a cycle in the graph. +      if (!std::count(ChainedNodesInPattern.begin(), +                      ChainedNodesInPattern.end(), User)) +        return CR_InducesCycle; +       +      // Otherwise we found a node that is part of our pattern.  For example in: +      //   x = load ptr +      //   y = x+4 +      //   store y -> ptr +      // This would happen when we're scanning down from the load and see the +      // store as a user.  Record that there is a use of ChainedNode that is +      // part of the pattern and keep scanning uses. +      Result = CR_LeadsToInteriorNode; +      InteriorChainedNodes.push_back(User); +      continue; +    } +     +    // If we found a TokenFactor, there are two cases to consider: first if the +    // TokenFactor is just hanging "below" the pattern we're matching (i.e. no +    // uses of the TF are in our pattern) we just want to ignore it.  Second, +    // the TokenFactor can be sandwiched in between two chained nodes, like so: +    //     [Load chain] +    //         ^ +    //         | +    //       [Load] +    //       ^    ^ +    //       |    \                    DAG's like cheese +    //      /       \                       do you? +    //     /         | +    // [TokenFactor] [Op] +    //     ^          ^ +    //     |          | +    //      \        / +    //       \      / +    //       [Store] +    // +    // In this case, the TokenFactor becomes part of our match and we rewrite it +    // as a new TokenFactor. +    // +    // To distinguish these two cases, do a recursive walk down the uses. +    switch (WalkChainUsers(User, ChainedNodesInPattern, InteriorChainedNodes)) { +    case CR_Simple: +      // If the uses of the TokenFactor are just already-selected nodes, ignore +      // it, it is "below" our pattern. +      continue; +    case CR_InducesCycle: +      // If the uses of the TokenFactor lead to nodes that are not part of our +      // pattern that are not selected, folding would turn this into a cycle, +      // bail out now. +      return CR_InducesCycle; +    case CR_LeadsToInteriorNode: +      break;  // Otherwise, keep processing. +    } +     +    // Okay, we know we're in the interesting interior case.  The TokenFactor +    // is now going to be considered part of the pattern so that we rewrite its +    // uses (it may have uses that are not part of the pattern) with the +    // ultimate chain result of the generated code.  We will also add its chain +    // inputs as inputs to the ultimate TokenFactor we create. +    Result = CR_LeadsToInteriorNode; +    ChainedNodesInPattern.push_back(User); +    InteriorChainedNodes.push_back(User); +    continue; +  } +   +  return Result; +} + +/// HandleMergeInputChains - This implements the OPC_EmitMergeInputChains +/// operation for when the pattern matched at least one node with a chains.  The +/// input vector contains a list of all of the chained nodes that we match.  We +/// must determine if this is a valid thing to cover (i.e. matching it won't +/// induce cycles in the DAG) and if so, creating a TokenFactor node. that will +/// be used as the input node chain for the generated nodes. +static SDValue +HandleMergeInputChains(SmallVectorImpl<SDNode*> &ChainNodesMatched, +                       SelectionDAG *CurDAG) { +  // Walk all of the chained nodes we've matched, recursively scanning down the +  // users of the chain result. This adds any TokenFactor nodes that are caught +  // in between chained nodes to the chained and interior nodes list. +  SmallVector<SDNode*, 3> InteriorChainedNodes; +  for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) { +    if (WalkChainUsers(ChainNodesMatched[i], ChainNodesMatched, +                       InteriorChainedNodes) == CR_InducesCycle) +      return SDValue(); // Would induce a cycle. +  } +   +  // Okay, we have walked all the matched nodes and collected TokenFactor nodes +  // that we are interested in.  Form our input TokenFactor node. +  SmallVector<SDValue, 3> InputChains; +  for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) { +    // Add the input chain of this node to the InputChains list (which will be +    // the operands of the generated TokenFactor) if it's not an interior node. +    SDNode *N = ChainNodesMatched[i]; +    if (N->getOpcode() != ISD::TokenFactor) { +      if (std::count(InteriorChainedNodes.begin(),InteriorChainedNodes.end(),N)) +        continue; +       +      // Otherwise, add the input chain. +      SDValue InChain = ChainNodesMatched[i]->getOperand(0); +      assert(InChain.getValueType() == MVT::Other && "Not a chain"); +      InputChains.push_back(InChain); +      continue; +    } +     +    // If we have a token factor, we want to add all inputs of the token factor +    // that are not part of the pattern we're matching. +    for (unsigned op = 0, e = N->getNumOperands(); op != e; ++op) { +      if (!std::count(ChainNodesMatched.begin(), ChainNodesMatched.end(), +                      N->getOperand(op).getNode())) +        InputChains.push_back(N->getOperand(op)); +    } +  } +   +  SDValue Res; +  if (InputChains.size() == 1) +    return InputChains[0]; +  return CurDAG->getNode(ISD::TokenFactor, ChainNodesMatched[0]->getDebugLoc(), +                         MVT::Other, &InputChains[0], InputChains.size()); +}   + +/// MorphNode - Handle morphing a node in place for the selector. +SDNode *SelectionDAGISel:: +MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList, +          const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo) { +  // It is possible we're using MorphNodeTo to replace a node with no +  // normal results with one that has a normal result (or we could be +  // adding a chain) and the input could have flags and chains as well. +  // In this case we need to shifting the operands down. +  // FIXME: This is a horrible hack and broken in obscure cases, no worse +  // than the old isel though.  We should sink this into MorphNodeTo. +  int OldFlagResultNo = -1, OldChainResultNo = -1; + +  unsigned NTMNumResults = Node->getNumValues(); +  if (Node->getValueType(NTMNumResults-1) == MVT::Flag) { +    OldFlagResultNo = NTMNumResults-1; +    if (NTMNumResults != 1 && +        Node->getValueType(NTMNumResults-2) == MVT::Other) +      OldChainResultNo = NTMNumResults-2; +  } else if (Node->getValueType(NTMNumResults-1) == MVT::Other) +    OldChainResultNo = NTMNumResults-1; + +  // Call the underlying SelectionDAG routine to do the transmogrification. Note +  // that this deletes operands of the old node that become dead. +  SDNode *Res = CurDAG->MorphNodeTo(Node, ~TargetOpc, VTList, Ops, NumOps); + +  // MorphNodeTo can operate in two ways: if an existing node with the +  // specified operands exists, it can just return it.  Otherwise, it +  // updates the node in place to have the requested operands. +  if (Res == Node) { +    // If we updated the node in place, reset the node ID.  To the isel, +    // this should be just like a newly allocated machine node. +    Res->setNodeId(-1); +  } + +  unsigned ResNumResults = Res->getNumValues(); +  // Move the flag if needed. +  if ((EmitNodeInfo & OPFL_FlagOutput) && OldFlagResultNo != -1 && +      (unsigned)OldFlagResultNo != ResNumResults-1) +    CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldFlagResultNo),  +                                      SDValue(Res, ResNumResults-1)); + +  if ((EmitNodeInfo & OPFL_FlagOutput) != 0) +  --ResNumResults; + +  // Move the chain reference if needed. +  if ((EmitNodeInfo & OPFL_Chain) && OldChainResultNo != -1 && +      (unsigned)OldChainResultNo != ResNumResults-1) +    CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldChainResultNo),  +                                      SDValue(Res, ResNumResults-1)); + +  // Otherwise, no replacement happened because the node already exists. Replace +  // Uses of the old node with the new one. +  if (Res != Node) +    CurDAG->ReplaceAllUsesWith(Node, Res); +   +  return Res; +} + +/// CheckPatternPredicate - Implements OP_CheckPatternPredicate. +ALWAYS_INLINE static bool +CheckSame(const unsigned char *MatcherTable, unsigned &MatcherIndex, +          SDValue N, const SmallVectorImpl<SDValue> &RecordedNodes) { +  // Accept if it is exactly the same as a previously recorded node. +  unsigned RecNo = MatcherTable[MatcherIndex++]; +  assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); +  return N == RecordedNodes[RecNo]; +} +   +/// CheckPatternPredicate - Implements OP_CheckPatternPredicate. +ALWAYS_INLINE static bool +CheckPatternPredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex, +                      SelectionDAGISel &SDISel) { +  return SDISel.CheckPatternPredicate(MatcherTable[MatcherIndex++]); +} + +/// CheckNodePredicate - Implements OP_CheckNodePredicate. +ALWAYS_INLINE static bool +CheckNodePredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex, +                   SelectionDAGISel &SDISel, SDNode *N) { +  return SDISel.CheckNodePredicate(N, MatcherTable[MatcherIndex++]); +} + +ALWAYS_INLINE static bool +CheckOpcode(const unsigned char *MatcherTable, unsigned &MatcherIndex, +            SDNode *N) { +  return N->getOpcode() == MatcherTable[MatcherIndex++]; +} + +ALWAYS_INLINE static bool +CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex, +          SDValue N, const TargetLowering &TLI) { +  MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; +  if (N.getValueType() == VT) return true; +   +  // Handle the case when VT is iPTR. +  return VT == MVT::iPTR && N.getValueType() == TLI.getPointerTy(); +} + +ALWAYS_INLINE static bool +CheckChildType(const unsigned char *MatcherTable, unsigned &MatcherIndex, +               SDValue N, const TargetLowering &TLI, +               unsigned ChildNo) { +  if (ChildNo >= N.getNumOperands()) +    return false;  // Match fails if out of range child #. +  return ::CheckType(MatcherTable, MatcherIndex, N.getOperand(ChildNo), TLI); +} + + +ALWAYS_INLINE static bool +CheckCondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex, +              SDValue N) { +  return cast<CondCodeSDNode>(N)->get() == +      (ISD::CondCode)MatcherTable[MatcherIndex++]; +} + +ALWAYS_INLINE static bool +CheckValueType(const unsigned char *MatcherTable, unsigned &MatcherIndex, +               SDValue N, const TargetLowering &TLI) { +  MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; +  if (cast<VTSDNode>(N)->getVT() == VT) +    return true; +   +  // Handle the case when VT is iPTR. +  return VT == MVT::iPTR && cast<VTSDNode>(N)->getVT() == TLI.getPointerTy(); +} + +ALWAYS_INLINE static bool +CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex, +             SDValue N) { +  int64_t Val = MatcherTable[MatcherIndex++]; +  if (Val & 128) +    Val = GetVBR(Val, MatcherTable, MatcherIndex); +   +  ConstantSDNode *C = dyn_cast<ConstantSDNode>(N); +  return C != 0 && C->getSExtValue() == Val; +} + +ALWAYS_INLINE static bool +CheckAndImm(const unsigned char *MatcherTable, unsigned &MatcherIndex, +            SDValue N, SelectionDAGISel &SDISel) { +  int64_t Val = MatcherTable[MatcherIndex++]; +  if (Val & 128) +    Val = GetVBR(Val, MatcherTable, MatcherIndex); +   +  if (N->getOpcode() != ISD::AND) return false; +   +  ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)); +  return C != 0 && SDISel.CheckAndMask(N.getOperand(0), C, Val); +} + +ALWAYS_INLINE static bool +CheckOrImm(const unsigned char *MatcherTable, unsigned &MatcherIndex, +           SDValue N, SelectionDAGISel &SDISel) { +  int64_t Val = MatcherTable[MatcherIndex++]; +  if (Val & 128) +    Val = GetVBR(Val, MatcherTable, MatcherIndex); +   +  if (N->getOpcode() != ISD::OR) return false; +   +  ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)); +  return C != 0 && SDISel.CheckOrMask(N.getOperand(0), C, Val); +} + +/// IsPredicateKnownToFail - If we know how and can do so without pushing a +/// scope, evaluate the current node.  If the current predicate is known to +/// fail, set Result=true and return anything.  If the current predicate is +/// known to pass, set Result=false and return the MatcherIndex to continue +/// with.  If the current predicate is unknown, set Result=false and return the +/// MatcherIndex to continue with.  +static unsigned IsPredicateKnownToFail(const unsigned char *Table, +                                       unsigned Index, SDValue N, +                                       bool &Result, SelectionDAGISel &SDISel, +                                       SmallVectorImpl<SDValue> &RecordedNodes){ +  switch (Table[Index++]) { +  default: +    Result = false; +    return Index-1;  // Could not evaluate this predicate. +  case SelectionDAGISel::OPC_CheckSame: +    Result = !::CheckSame(Table, Index, N, RecordedNodes); +    return Index; +  case SelectionDAGISel::OPC_CheckPatternPredicate: +    Result = !::CheckPatternPredicate(Table, Index, SDISel); +    return Index; +  case SelectionDAGISel::OPC_CheckPredicate: +    Result = !::CheckNodePredicate(Table, Index, SDISel, N.getNode()); +    return Index; +  case SelectionDAGISel::OPC_CheckOpcode: +    Result = !::CheckOpcode(Table, Index, N.getNode()); +    return Index; +  case SelectionDAGISel::OPC_CheckType: +    Result = !::CheckType(Table, Index, N, SDISel.TLI); +    return Index; +  case SelectionDAGISel::OPC_CheckChild0Type: +  case SelectionDAGISel::OPC_CheckChild1Type: +  case SelectionDAGISel::OPC_CheckChild2Type: +  case SelectionDAGISel::OPC_CheckChild3Type: +  case SelectionDAGISel::OPC_CheckChild4Type: +  case SelectionDAGISel::OPC_CheckChild5Type: +  case SelectionDAGISel::OPC_CheckChild6Type: +  case SelectionDAGISel::OPC_CheckChild7Type: +    Result = !::CheckChildType(Table, Index, N, SDISel.TLI, +                        Table[Index-1] - SelectionDAGISel::OPC_CheckChild0Type); +    return Index; +  case SelectionDAGISel::OPC_CheckCondCode: +    Result = !::CheckCondCode(Table, Index, N); +    return Index; +  case SelectionDAGISel::OPC_CheckValueType: +    Result = !::CheckValueType(Table, Index, N, SDISel.TLI); +    return Index; +  case SelectionDAGISel::OPC_CheckInteger: +    Result = !::CheckInteger(Table, Index, N); +    return Index; +  case SelectionDAGISel::OPC_CheckAndImm: +    Result = !::CheckAndImm(Table, Index, N, SDISel); +    return Index; +  case SelectionDAGISel::OPC_CheckOrImm: +    Result = !::CheckOrImm(Table, Index, N, SDISel); +    return Index; +  } +} + + +struct MatchScope { +  /// FailIndex - If this match fails, this is the index to continue with. +  unsigned FailIndex; +   +  /// NodeStack - The node stack when the scope was formed. +  SmallVector<SDValue, 4> NodeStack; +   +  /// NumRecordedNodes - The number of recorded nodes when the scope was formed. +  unsigned NumRecordedNodes; +   +  /// NumMatchedMemRefs - The number of matched memref entries. +  unsigned NumMatchedMemRefs; +   +  /// InputChain/InputFlag - The current chain/flag  +  SDValue InputChain, InputFlag; + +  /// HasChainNodesMatched - True if the ChainNodesMatched list is non-empty. +  bool HasChainNodesMatched, HasFlagResultNodesMatched; +}; + +SDNode *SelectionDAGISel:: +SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, +                 unsigned TableSize) { +  // FIXME: Should these even be selected?  Handle these cases in the caller? +  switch (NodeToMatch->getOpcode()) { +  default: +    break; +  case ISD::EntryToken:       // These nodes remain the same. +  case ISD::BasicBlock: +  case ISD::Register: +  case ISD::HANDLENODE: +  case ISD::TargetConstant: +  case ISD::TargetConstantFP: +  case ISD::TargetConstantPool: +  case ISD::TargetFrameIndex: +  case ISD::TargetExternalSymbol: +  case ISD::TargetBlockAddress: +  case ISD::TargetJumpTable: +  case ISD::TargetGlobalTLSAddress: +  case ISD::TargetGlobalAddress: +  case ISD::TokenFactor: +  case ISD::CopyFromReg: +  case ISD::CopyToReg: +    NodeToMatch->setNodeId(-1); // Mark selected. +    return 0; +  case ISD::AssertSext: +  case ISD::AssertZext: +    CurDAG->ReplaceAllUsesOfValueWith(SDValue(NodeToMatch, 0), +                                      NodeToMatch->getOperand(0)); +    return 0; +  case ISD::INLINEASM: return Select_INLINEASM(NodeToMatch); +  case ISD::EH_LABEL:  return Select_EH_LABEL(NodeToMatch); +  case ISD::UNDEF:     return Select_UNDEF(NodeToMatch); +  } +   +  assert(!NodeToMatch->isMachineOpcode() && "Node already selected!"); + +  // Set up the node stack with NodeToMatch as the only node on the stack. +  SmallVector<SDValue, 8> NodeStack; +  SDValue N = SDValue(NodeToMatch, 0); +  NodeStack.push_back(N); + +  // MatchScopes - Scopes used when matching, if a match failure happens, this +  // indicates where to continue checking. +  SmallVector<MatchScope, 8> MatchScopes; +   +  // RecordedNodes - This is the set of nodes that have been recorded by the +  // state machine. +  SmallVector<SDValue, 8> RecordedNodes; +   +  // MatchedMemRefs - This is the set of MemRef's we've seen in the input +  // pattern. +  SmallVector<MachineMemOperand*, 2> MatchedMemRefs; +   +  // These are the current input chain and flag for use when generating nodes. +  // Various Emit operations change these.  For example, emitting a copytoreg +  // uses and updates these. +  SDValue InputChain, InputFlag; +   +  // ChainNodesMatched - If a pattern matches nodes that have input/output +  // chains, the OPC_EmitMergeInputChains operation is emitted which indicates +  // which ones they are.  The result is captured into this list so that we can +  // update the chain results when the pattern is complete. +  SmallVector<SDNode*, 3> ChainNodesMatched; +  SmallVector<SDNode*, 3> FlagResultNodesMatched; +   +  DEBUG(errs() << "ISEL: Starting pattern match on root node: "; +        NodeToMatch->dump(CurDAG); +        errs() << '\n'); +   +  // Determine where to start the interpreter.  Normally we start at opcode #0, +  // but if the state machine starts with an OPC_SwitchOpcode, then we +  // accelerate the first lookup (which is guaranteed to be hot) with the +  // OpcodeOffset table. +  unsigned MatcherIndex = 0; +   +  if (!OpcodeOffset.empty()) { +    // Already computed the OpcodeOffset table, just index into it. +    if (N.getOpcode() < OpcodeOffset.size()) +      MatcherIndex = OpcodeOffset[N.getOpcode()]; +    DEBUG(errs() << "  Initial Opcode index to " << MatcherIndex << "\n"); + +  } else if (MatcherTable[0] == OPC_SwitchOpcode) { +    // Otherwise, the table isn't computed, but the state machine does start +    // with an OPC_SwitchOpcode instruction.  Populate the table now, since this +    // is the first time we're selecting an instruction. +    unsigned Idx = 1; +    while (1) { +      // Get the size of this case. +      unsigned CaseSize = MatcherTable[Idx++]; +      if (CaseSize & 128) +        CaseSize = GetVBR(CaseSize, MatcherTable, Idx); +      if (CaseSize == 0) break; + +      // Get the opcode, add the index to the table. +      unsigned Opc = MatcherTable[Idx++]; +      if (Opc >= OpcodeOffset.size()) +        OpcodeOffset.resize((Opc+1)*2); +      OpcodeOffset[Opc] = Idx; +      Idx += CaseSize; +    } + +    // Okay, do the lookup for the first opcode. +    if (N.getOpcode() < OpcodeOffset.size()) +      MatcherIndex = OpcodeOffset[N.getOpcode()]; +  } +   +  while (1) { +    assert(MatcherIndex < TableSize && "Invalid index"); +    BuiltinOpcodes Opcode = (BuiltinOpcodes)MatcherTable[MatcherIndex++]; +    switch (Opcode) { +    case OPC_Scope: { +      // Okay, the semantics of this operation are that we should push a scope +      // then evaluate the first child.  However, pushing a scope only to have +      // the first check fail (which then pops it) is inefficient.  If we can +      // determine immediately that the first check (or first several) will +      // immediately fail, don't even bother pushing a scope for them. +      unsigned FailIndex; +       +      while (1) { +        unsigned NumToSkip = MatcherTable[MatcherIndex++]; +        if (NumToSkip & 128) +          NumToSkip = GetVBR(NumToSkip, MatcherTable, MatcherIndex); +        // Found the end of the scope with no match. +        if (NumToSkip == 0) { +          FailIndex = 0; +          break; +        } +         +        FailIndex = MatcherIndex+NumToSkip; +         +        // If we can't evaluate this predicate without pushing a scope (e.g. if +        // it is a 'MoveParent') or if the predicate succeeds on this node, we +        // push the scope and evaluate the full predicate chain. +        bool Result; +        MatcherIndex = IsPredicateKnownToFail(MatcherTable, MatcherIndex, N, +                                              Result, *this, RecordedNodes); +        if (!Result) +          break; +         +        DEBUG(errs() << "  Skipped scope entry at index " << MatcherIndex +              << " continuing at " << FailIndex << "\n"); + +         +        // Otherwise, we know that this case of the Scope is guaranteed to fail, +        // move to the next case. +        MatcherIndex = FailIndex; +      } +       +      // If the whole scope failed to match, bail. +      if (FailIndex == 0) break; +       +      // Push a MatchScope which indicates where to go if the first child fails +      // to match. +      MatchScope NewEntry; +      NewEntry.FailIndex = FailIndex; +      NewEntry.NodeStack.append(NodeStack.begin(), NodeStack.end()); +      NewEntry.NumRecordedNodes = RecordedNodes.size(); +      NewEntry.NumMatchedMemRefs = MatchedMemRefs.size(); +      NewEntry.InputChain = InputChain; +      NewEntry.InputFlag = InputFlag; +      NewEntry.HasChainNodesMatched = !ChainNodesMatched.empty(); +      NewEntry.HasFlagResultNodesMatched = !FlagResultNodesMatched.empty(); +      MatchScopes.push_back(NewEntry); +      continue; +    } +    case OPC_RecordNode: +      // Remember this node, it may end up being an operand in the pattern. +      RecordedNodes.push_back(N); +      continue; +         +    case OPC_RecordChild0: case OPC_RecordChild1: +    case OPC_RecordChild2: case OPC_RecordChild3: +    case OPC_RecordChild4: case OPC_RecordChild5: +    case OPC_RecordChild6: case OPC_RecordChild7: { +      unsigned ChildNo = Opcode-OPC_RecordChild0; +      if (ChildNo >= N.getNumOperands()) +        break;  // Match fails if out of range child #. + +      RecordedNodes.push_back(N->getOperand(ChildNo)); +      continue; +    } +    case OPC_RecordMemRef: +      MatchedMemRefs.push_back(cast<MemSDNode>(N)->getMemOperand()); +      continue; +         +    case OPC_CaptureFlagInput: +      // If the current node has an input flag, capture it in InputFlag. +      if (N->getNumOperands() != 0 && +          N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) +        InputFlag = N->getOperand(N->getNumOperands()-1); +      continue; +         +    case OPC_MoveChild: { +      unsigned ChildNo = MatcherTable[MatcherIndex++]; +      if (ChildNo >= N.getNumOperands()) +        break;  // Match fails if out of range child #. +      N = N.getOperand(ChildNo); +      NodeStack.push_back(N); +      continue; +    } +         +    case OPC_MoveParent: +      // Pop the current node off the NodeStack. +      NodeStack.pop_back(); +      assert(!NodeStack.empty() && "Node stack imbalance!"); +      N = NodeStack.back();   +      continue; +      +    case OPC_CheckSame: +      if (!::CheckSame(MatcherTable, MatcherIndex, N, RecordedNodes)) break; +      continue; +    case OPC_CheckPatternPredicate: +      if (!::CheckPatternPredicate(MatcherTable, MatcherIndex, *this)) break; +      continue; +    case OPC_CheckPredicate: +      if (!::CheckNodePredicate(MatcherTable, MatcherIndex, *this, +                                N.getNode())) +        break; +      continue; +    case OPC_CheckComplexPat: +      if (!CheckComplexPattern(NodeToMatch, N,  +                               MatcherTable[MatcherIndex++], RecordedNodes)) +        break; +      continue; +    case OPC_CheckOpcode: +      if (!::CheckOpcode(MatcherTable, MatcherIndex, N.getNode())) break; +      continue; +         +    case OPC_CheckType: +      if (!::CheckType(MatcherTable, MatcherIndex, N, TLI)) break; +      continue; +         +    case OPC_SwitchOpcode: { +      unsigned CurNodeOpcode = N.getOpcode(); +      unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart; +      unsigned CaseSize; +      while (1) { +        // Get the size of this case. +        CaseSize = MatcherTable[MatcherIndex++]; +        if (CaseSize & 128) +          CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex); +        if (CaseSize == 0) break; + +        // If the opcode matches, then we will execute this case. +        if (CurNodeOpcode == MatcherTable[MatcherIndex++]) +          break; +       +        // Otherwise, skip over this case. +        MatcherIndex += CaseSize; +      } +       +      // If no cases matched, bail out. +      if (CaseSize == 0) break; +       +      // Otherwise, execute the case we found. +      DEBUG(errs() << "  OpcodeSwitch from " << SwitchStart +                   << " to " << MatcherIndex << "\n"); +      continue; +    } +         +    case OPC_SwitchType: { +      MVT::SimpleValueType CurNodeVT = N.getValueType().getSimpleVT().SimpleTy; +      unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart; +      unsigned CaseSize; +      while (1) { +        // Get the size of this case. +        CaseSize = MatcherTable[MatcherIndex++]; +        if (CaseSize & 128) +          CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex); +        if (CaseSize == 0) break; +         +        MVT::SimpleValueType CaseVT = +          (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; +        if (CaseVT == MVT::iPTR) +          CaseVT = TLI.getPointerTy().SimpleTy; +         +        // If the VT matches, then we will execute this case. +        if (CurNodeVT == CaseVT) +          break; +         +        // Otherwise, skip over this case. +        MatcherIndex += CaseSize; +      } +       +      // If no cases matched, bail out. +      if (CaseSize == 0) break; +       +      // Otherwise, execute the case we found. +      DEBUG(errs() << "  TypeSwitch[" << EVT(CurNodeVT).getEVTString() +                   << "] from " << SwitchStart << " to " << MatcherIndex<<'\n'); +      continue; +    } +    case OPC_CheckChild0Type: case OPC_CheckChild1Type: +    case OPC_CheckChild2Type: case OPC_CheckChild3Type: +    case OPC_CheckChild4Type: case OPC_CheckChild5Type: +    case OPC_CheckChild6Type: case OPC_CheckChild7Type: +      if (!::CheckChildType(MatcherTable, MatcherIndex, N, TLI, +                            Opcode-OPC_CheckChild0Type)) +        break; +      continue; +    case OPC_CheckCondCode: +      if (!::CheckCondCode(MatcherTable, MatcherIndex, N)) break; +      continue; +    case OPC_CheckValueType: +      if (!::CheckValueType(MatcherTable, MatcherIndex, N, TLI)) break; +      continue; +    case OPC_CheckInteger: +      if (!::CheckInteger(MatcherTable, MatcherIndex, N)) break; +      continue; +    case OPC_CheckAndImm: +      if (!::CheckAndImm(MatcherTable, MatcherIndex, N, *this)) break; +      continue; +    case OPC_CheckOrImm: +      if (!::CheckOrImm(MatcherTable, MatcherIndex, N, *this)) break; +      continue; +         +    case OPC_CheckFoldableChainNode: { +      assert(NodeStack.size() != 1 && "No parent node"); +      // Verify that all intermediate nodes between the root and this one have +      // a single use. +      bool HasMultipleUses = false; +      for (unsigned i = 1, e = NodeStack.size()-1; i != e; ++i) +        if (!NodeStack[i].hasOneUse()) { +          HasMultipleUses = true; +          break; +        } +      if (HasMultipleUses) break; + +      // Check to see that the target thinks this is profitable to fold and that +      // we can fold it without inducing cycles in the graph. +      if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(), +                              NodeToMatch) || +          !IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(), +                         NodeToMatch, true/*We validate our own chains*/)) +        break; +       +      continue; +    } +    case OPC_EmitInteger: { +      MVT::SimpleValueType VT = +        (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; +      int64_t Val = MatcherTable[MatcherIndex++]; +      if (Val & 128) +        Val = GetVBR(Val, MatcherTable, MatcherIndex); +      RecordedNodes.push_back(CurDAG->getTargetConstant(Val, VT)); +      continue; +    } +    case OPC_EmitRegister: { +      MVT::SimpleValueType VT = +        (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; +      unsigned RegNo = MatcherTable[MatcherIndex++]; +      RecordedNodes.push_back(CurDAG->getRegister(RegNo, VT)); +      continue; +    } +         +    case OPC_EmitConvertToTarget:  { +      // Convert from IMM/FPIMM to target version. +      unsigned RecNo = MatcherTable[MatcherIndex++]; +      assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); +      SDValue Imm = RecordedNodes[RecNo]; + +      if (Imm->getOpcode() == ISD::Constant) { +        int64_t Val = cast<ConstantSDNode>(Imm)->getZExtValue(); +        Imm = CurDAG->getTargetConstant(Val, Imm.getValueType()); +      } else if (Imm->getOpcode() == ISD::ConstantFP) { +        const ConstantFP *Val=cast<ConstantFPSDNode>(Imm)->getConstantFPValue(); +        Imm = CurDAG->getTargetConstantFP(*Val, Imm.getValueType()); +      } +       +      RecordedNodes.push_back(Imm); +      continue; +    } +         +    case OPC_EmitMergeInputChains: { +      assert(InputChain.getNode() == 0 && +             "EmitMergeInputChains should be the first chain producing node"); +      // This node gets a list of nodes we matched in the input that have +      // chains.  We want to token factor all of the input chains to these nodes +      // together.  However, if any of the input chains is actually one of the +      // nodes matched in this pattern, then we have an intra-match reference. +      // Ignore these because the newly token factored chain should not refer to +      // the old nodes. +      unsigned NumChains = MatcherTable[MatcherIndex++]; +      assert(NumChains != 0 && "Can't TF zero chains"); + +      assert(ChainNodesMatched.empty() && +             "Should only have one EmitMergeInputChains per match"); + +      // Read all of the chained nodes. +      for (unsigned i = 0; i != NumChains; ++i) { +        unsigned RecNo = MatcherTable[MatcherIndex++]; +        assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); +        ChainNodesMatched.push_back(RecordedNodes[RecNo].getNode()); +         +        // FIXME: What if other value results of the node have uses not matched +        // by this pattern? +        if (ChainNodesMatched.back() != NodeToMatch && +            !RecordedNodes[RecNo].hasOneUse()) { +          ChainNodesMatched.clear(); +          break; +        } +      } +       +      // If the inner loop broke out, the match fails. +      if (ChainNodesMatched.empty()) +        break; + +      // Merge the input chains if they are not intra-pattern references. +      InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG); +       +      if (InputChain.getNode() == 0) +        break;  // Failed to merge. + +      continue; +    } +         +    case OPC_EmitCopyToReg: { +      unsigned RecNo = MatcherTable[MatcherIndex++]; +      assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); +      unsigned DestPhysReg = MatcherTable[MatcherIndex++]; +       +      if (InputChain.getNode() == 0) +        InputChain = CurDAG->getEntryNode(); +       +      InputChain = CurDAG->getCopyToReg(InputChain, NodeToMatch->getDebugLoc(), +                                        DestPhysReg, RecordedNodes[RecNo], +                                        InputFlag); +       +      InputFlag = InputChain.getValue(1); +      continue; +    } +         +    case OPC_EmitNodeXForm: { +      unsigned XFormNo = MatcherTable[MatcherIndex++]; +      unsigned RecNo = MatcherTable[MatcherIndex++]; +      assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); +      RecordedNodes.push_back(RunSDNodeXForm(RecordedNodes[RecNo], XFormNo)); +      continue; +    } +         +    case OPC_EmitNode: +    case OPC_MorphNodeTo: { +      uint16_t TargetOpc = MatcherTable[MatcherIndex++]; +      TargetOpc |= (unsigned short)MatcherTable[MatcherIndex++] << 8; +      unsigned EmitNodeInfo = MatcherTable[MatcherIndex++]; +      // Get the result VT list. +      unsigned NumVTs = MatcherTable[MatcherIndex++]; +      SmallVector<EVT, 4> VTs; +      for (unsigned i = 0; i != NumVTs; ++i) { +        MVT::SimpleValueType VT = +          (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; +        if (VT == MVT::iPTR) VT = TLI.getPointerTy().SimpleTy; +        VTs.push_back(VT); +      } +       +      if (EmitNodeInfo & OPFL_Chain) +        VTs.push_back(MVT::Other); +      if (EmitNodeInfo & OPFL_FlagOutput) +        VTs.push_back(MVT::Flag); +       +      // This is hot code, so optimize the two most common cases of 1 and 2 +      // results. +      SDVTList VTList; +      if (VTs.size() == 1) +        VTList = CurDAG->getVTList(VTs[0]); +      else if (VTs.size() == 2) +        VTList = CurDAG->getVTList(VTs[0], VTs[1]); +      else +        VTList = CurDAG->getVTList(VTs.data(), VTs.size()); + +      // Get the operand list. +      unsigned NumOps = MatcherTable[MatcherIndex++]; +      SmallVector<SDValue, 8> Ops; +      for (unsigned i = 0; i != NumOps; ++i) { +        unsigned RecNo = MatcherTable[MatcherIndex++]; +        if (RecNo & 128) +          RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex); +         +        assert(RecNo < RecordedNodes.size() && "Invalid EmitNode"); +        Ops.push_back(RecordedNodes[RecNo]); +      } +       +      // If there are variadic operands to add, handle them now. +      if (EmitNodeInfo & OPFL_VariadicInfo) { +        // Determine the start index to copy from. +        unsigned FirstOpToCopy = getNumFixedFromVariadicInfo(EmitNodeInfo); +        FirstOpToCopy += (EmitNodeInfo & OPFL_Chain) ? 1 : 0; +        assert(NodeToMatch->getNumOperands() >= FirstOpToCopy && +               "Invalid variadic node"); +        // Copy all of the variadic operands, not including a potential flag +        // input. +        for (unsigned i = FirstOpToCopy, e = NodeToMatch->getNumOperands(); +             i != e; ++i) { +          SDValue V = NodeToMatch->getOperand(i); +          if (V.getValueType() == MVT::Flag) break; +          Ops.push_back(V); +        } +      } +       +      // If this has chain/flag inputs, add them. +      if (EmitNodeInfo & OPFL_Chain) +        Ops.push_back(InputChain); +      if ((EmitNodeInfo & OPFL_FlagInput) && InputFlag.getNode() != 0) +        Ops.push_back(InputFlag); +       +      // Create the node. +      SDNode *Res = 0; +      if (Opcode != OPC_MorphNodeTo) { +        // If this is a normal EmitNode command, just create the new node and +        // add the results to the RecordedNodes list. +        Res = CurDAG->getMachineNode(TargetOpc, NodeToMatch->getDebugLoc(), +                                     VTList, Ops.data(), Ops.size()); +         +        // Add all the non-flag/non-chain results to the RecordedNodes list. +        for (unsigned i = 0, e = VTs.size(); i != e; ++i) { +          if (VTs[i] == MVT::Other || VTs[i] == MVT::Flag) break; +          RecordedNodes.push_back(SDValue(Res, i)); +        } +         +      } else { +        Res = MorphNode(NodeToMatch, TargetOpc, VTList, Ops.data(), Ops.size(), +                        EmitNodeInfo); +      } +       +      // If the node had chain/flag results, update our notion of the current +      // chain and flag. +      if (EmitNodeInfo & OPFL_FlagOutput) { +        InputFlag = SDValue(Res, VTs.size()-1); +        if (EmitNodeInfo & OPFL_Chain) +          InputChain = SDValue(Res, VTs.size()-2); +      } else if (EmitNodeInfo & OPFL_Chain) +        InputChain = SDValue(Res, VTs.size()-1); + +      // If the OPFL_MemRefs flag is set on this node, slap all of the +      // accumulated memrefs onto it. +      // +      // FIXME: This is vastly incorrect for patterns with multiple outputs +      // instructions that access memory and for ComplexPatterns that match +      // loads. +      if (EmitNodeInfo & OPFL_MemRefs) { +        MachineSDNode::mmo_iterator MemRefs = +          MF->allocateMemRefsArray(MatchedMemRefs.size()); +        std::copy(MatchedMemRefs.begin(), MatchedMemRefs.end(), MemRefs); +        cast<MachineSDNode>(Res) +          ->setMemRefs(MemRefs, MemRefs + MatchedMemRefs.size()); +      } +       +      DEBUG(errs() << "  " +                   << (Opcode == OPC_MorphNodeTo ? "Morphed" : "Created") +                   << " node: "; Res->dump(CurDAG); errs() << "\n"); +       +      // If this was a MorphNodeTo then we're completely done! +      if (Opcode == OPC_MorphNodeTo) { +        // Update chain and flag uses. +        UpdateChainsAndFlags(NodeToMatch, InputChain, ChainNodesMatched, +                             InputFlag, FlagResultNodesMatched, true); +        return Res; +      } +       +      continue; +    } +         +    case OPC_MarkFlagResults: { +      unsigned NumNodes = MatcherTable[MatcherIndex++]; +       +      // Read and remember all the flag-result nodes. +      for (unsigned i = 0; i != NumNodes; ++i) { +        unsigned RecNo = MatcherTable[MatcherIndex++]; +        if (RecNo & 128) +          RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex); + +        assert(RecNo < RecordedNodes.size() && "Invalid CheckSame"); +        FlagResultNodesMatched.push_back(RecordedNodes[RecNo].getNode()); +      } +      continue; +    } +       +    case OPC_CompleteMatch: { +      // The match has been completed, and any new nodes (if any) have been +      // created.  Patch up references to the matched dag to use the newly +      // created nodes. +      unsigned NumResults = MatcherTable[MatcherIndex++]; + +      for (unsigned i = 0; i != NumResults; ++i) { +        unsigned ResSlot = MatcherTable[MatcherIndex++]; +        if (ResSlot & 128) +          ResSlot = GetVBR(ResSlot, MatcherTable, MatcherIndex); +         +        assert(ResSlot < RecordedNodes.size() && "Invalid CheckSame"); +        SDValue Res = RecordedNodes[ResSlot]; +         +        // FIXME2: Eliminate this horrible hack by fixing the 'Gen' program +        // after (parallel) on input patterns are removed.  This would also +        // allow us to stop encoding #results in OPC_CompleteMatch's table +        // entry. +        if (NodeToMatch->getNumValues() <= i || +            NodeToMatch->getValueType(i) == MVT::Other || +            NodeToMatch->getValueType(i) == MVT::Flag) +          break; +        assert((NodeToMatch->getValueType(i) == Res.getValueType() || +                NodeToMatch->getValueType(i) == MVT::iPTR || +                Res.getValueType() == MVT::iPTR || +                NodeToMatch->getValueType(i).getSizeInBits() == +                    Res.getValueType().getSizeInBits()) && +               "invalid replacement"); +        CurDAG->ReplaceAllUsesOfValueWith(SDValue(NodeToMatch, i), Res); +      } + +      // If the root node defines a flag, add it to the flag nodes to update +      // list. +      if (NodeToMatch->getValueType(NodeToMatch->getNumValues()-1) == MVT::Flag) +        FlagResultNodesMatched.push_back(NodeToMatch); +       +      // Update chain and flag uses. +      UpdateChainsAndFlags(NodeToMatch, InputChain, ChainNodesMatched, +                           InputFlag, FlagResultNodesMatched, false); +       +      assert(NodeToMatch->use_empty() && +             "Didn't replace all uses of the node?"); +       +      // FIXME: We just return here, which interacts correctly with SelectRoot +      // above.  We should fix this to not return an SDNode* anymore. +      return 0; +    } +    } +     +    // If the code reached this point, then the match failed.  See if there is +    // another child to try in the current 'Scope', otherwise pop it until we +    // find a case to check. +    while (1) { +      if (MatchScopes.empty()) { +        CannotYetSelect(NodeToMatch); +        return 0; +      } + +      // Restore the interpreter state back to the point where the scope was +      // formed. +      MatchScope &LastScope = MatchScopes.back(); +      RecordedNodes.resize(LastScope.NumRecordedNodes); +      NodeStack.clear(); +      NodeStack.append(LastScope.NodeStack.begin(), LastScope.NodeStack.end()); +      N = NodeStack.back(); + +      DEBUG(errs() << "  Match failed at index " << MatcherIndex +                   << " continuing at " << LastScope.FailIndex << "\n"); +     +      if (LastScope.NumMatchedMemRefs != MatchedMemRefs.size()) +        MatchedMemRefs.resize(LastScope.NumMatchedMemRefs); +      MatcherIndex = LastScope.FailIndex; +       +      InputChain = LastScope.InputChain; +      InputFlag = LastScope.InputFlag; +      if (!LastScope.HasChainNodesMatched) +        ChainNodesMatched.clear(); +      if (!LastScope.HasFlagResultNodesMatched) +        FlagResultNodesMatched.clear(); + +      // Check to see what the offset is at the new MatcherIndex.  If it is zero +      // we have reached the end of this scope, otherwise we have another child +      // in the current scope to try. +      unsigned NumToSkip = MatcherTable[MatcherIndex++]; +      if (NumToSkip & 128) +        NumToSkip = GetVBR(NumToSkip, MatcherTable, MatcherIndex); + +      // If we have another child in this scope to match, update FailIndex and +      // try it. +      if (NumToSkip != 0) { +        LastScope.FailIndex = MatcherIndex+NumToSkip; +        break; +      } +       +      // End of this scope, pop it and try the next child in the containing +      // scope. +      MatchScopes.pop_back(); +    } +  } +} +     + +  void SelectionDAGISel::CannotYetSelect(SDNode *N) { +  if (N->getOpcode() == ISD::INTRINSIC_W_CHAIN || +      N->getOpcode() == ISD::INTRINSIC_WO_CHAIN || +      N->getOpcode() == ISD::INTRINSIC_VOID) +    return CannotYetSelectIntrinsic(N); +      std::string msg;    raw_string_ostream Msg(msg);    Msg << "Cannot yet select: ";  | 
