[llvm-commits] [llvm] r97425 - in /llvm/trunk: include/llvm/CodeGen/DAGISelHeader.h include/llvm/CodeGen/SelectionDAGISel.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Chris Lattner sabre at nondot.org
Sun Feb 28 14:37:22 PST 2010


Author: lattner
Date: Sun Feb 28 16:37:22 2010
New Revision: 97425

URL: http://llvm.org/viewvc/llvm-project?rev=97425&view=rev
Log:
hoist the new isel interpreter out of DAGISelHeader.h
(which gets #included into the middle of each 
target's DAGISel class) into a .cpp file where it is
only compiled once.

Modified:
    llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h
    llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Modified: llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h?rev=97425&r1=97424&r2=97425&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h (original)
+++ llvm/trunk/include/llvm/CodeGen/DAGISelHeader.h Sun Feb 28 16:37:22 2010
@@ -136,827 +136,4 @@
 }
 
 
-/// CheckInteger - Return true if the specified node is not a ConstantSDNode or
-/// if it doesn't have the specified value.
-static bool CheckInteger(SDValue V, int64_t Val) {
-  ConstantSDNode *C = dyn_cast<ConstantSDNode>(V);
-  return C == 0 || C->getSExtValue() != Val;
-}
-
-/// CheckAndImmediate - Check to see if the specified node is an and with an
-/// immediate returning true on failure.
-///
-/// FIXME: Inline this gunk into CheckAndMask.
-bool CheckAndImmediate(SDValue V, int64_t Val) {
-  if (V->getOpcode() == ISD::AND)
-    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1)))
-      if (CheckAndMask(V.getOperand(0), C, Val))
-        return false;
-  return true;
-}
-
-/// CheckOrImmediate - Check to see if the specified node is an or with an
-/// immediate returning true on failure.
-///
-/// FIXME: Inline this gunk into CheckOrMask.
-bool CheckOrImmediate(SDValue V, int64_t Val) {
-  if (V->getOpcode() == ISD::OR)
-    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1)))
-      if (CheckOrMask(V.getOperand(0), C, Val))
-        return false;
-  return true;
-}
-
-// These functions are marked always inline so that Idx doesn't get pinned to
-// the stack.
-ALWAYS_INLINE static int8_t
-GetInt1(const unsigned char *MatcherTable, unsigned &Idx) {
-  return MatcherTable[Idx++];
-}
-
-ALWAYS_INLINE static int16_t
-GetInt2(const unsigned char *MatcherTable, unsigned &Idx) {
-  int16_t Val = (uint8_t)GetInt1(MatcherTable, Idx);
-  Val |= int16_t(GetInt1(MatcherTable, Idx)) << 8;
-  return Val;
-}
-
-/// 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 = GetInt1(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 UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
-                          const SmallVectorImpl<SDNode*> &ChainNodesMatched,
-                          SDValue InputFlag,
-                          const SmallVectorImpl<SDNode*>&FlagResultNodesMatched,
-                          bool isMorphNodeTo) {
-  // 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];
-      
-      // 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?");
-      ReplaceUses(ChainVal, InputChain);
-    }
-  }
-  
-  // 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];
-      assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Flag &&
-             "Doesn't have a flag result");
-      ReplaceUses(SDValue(FRN, FRN->getNumValues()-1), InputFlag);
-    }
-  }
-  
-  DEBUG(errs() << "ISEL: Match complete!\n");
-}
-
-
-
-/// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the
-/// number of fixed arity values that should be skipped when copying from the
-/// root.
-static inline int getNumFixedFromVariadicInfo(unsigned Flags) {
-  return ((Flags&OPFL_VariadicInfo) >> 4)-1;
-}
-
-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 *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:
-    return 0;
-  case ISD::AssertSext:
-  case ISD::AssertZext:
-    ReplaceUses(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');
-  
-  // Interpreter starts at opcode #0.
-  unsigned MatcherIndex = 0;
-  while (1) {
-    assert(MatcherIndex < TableSize && "Invalid index");
-    BuiltinOpcodes Opcode = (BuiltinOpcodes)MatcherTable[MatcherIndex++];
-    switch (Opcode) {
-    case OPC_Scope: {
-      unsigned NumToSkip = MatcherTable[MatcherIndex++];
-      if (NumToSkip & 128)
-        NumToSkip = GetVBR(NumToSkip, MatcherTable, MatcherIndex);
-      assert(NumToSkip != 0 &&
-             "First entry of OPC_Scope shouldn't be 0, scope has no children?");
-
-      // Push a MatchScope which indicates where to go if the first child fails
-      // to match.
-      MatchScope NewEntry;
-      NewEntry.FailIndex = MatcherIndex+NumToSkip;
-      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: {
-      // Accept if it is exactly the same as a previously recorded node.
-      unsigned RecNo = MatcherTable[MatcherIndex++];
-      assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
-      if (N != RecordedNodes[RecNo]) break;
-      continue;
-    }
-    case OPC_CheckPatternPredicate:
-      if (!CheckPatternPredicate(MatcherTable[MatcherIndex++])) break;
-      continue;
-    case OPC_CheckPredicate:
-      if (!CheckNodePredicate(N.getNode(), MatcherTable[MatcherIndex++])) break;
-      continue;
-    case OPC_CheckComplexPat:
-      if (!CheckComplexPattern(NodeToMatch, N, 
-                               MatcherTable[MatcherIndex++], RecordedNodes))
-        break;
-      continue;
-    case OPC_CheckOpcode:
-      if (N->getOpcode() != MatcherTable[MatcherIndex++]) break;
-      continue;
-        
-    case OPC_CheckMultiOpcode: {
-      unsigned NumOps = MatcherTable[MatcherIndex++];
-      bool OpcodeEquals = false;
-      for (unsigned i = 0; i != NumOps; ++i)
-        OpcodeEquals |= N->getOpcode() == MatcherTable[MatcherIndex++];
-      if (!OpcodeEquals) break;
-      continue;
-    }
-        
-    case OPC_CheckType: {
-      MVT::SimpleValueType VT =
-        (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
-      if (N.getValueType() != VT) {
-        // Handle the case when VT is iPTR.
-        if (VT != MVT::iPTR || N.getValueType() != TLI.getPointerTy())
-          break;
-      }
-      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: {
-      unsigned ChildNo = Opcode-OPC_CheckChild0Type;
-      if (ChildNo >= N.getNumOperands())
-        break;  // Match fails if out of range child #.
-      
-      MVT::SimpleValueType VT =
-        (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
-      EVT ChildVT = N.getOperand(ChildNo).getValueType();
-      if (ChildVT != VT) {
-        // Handle the case when VT is iPTR.
-        if (VT != MVT::iPTR || ChildVT != TLI.getPointerTy())
-          break;
-      }
-      continue;
-    }
-    case OPC_CheckCondCode:
-      if (cast<CondCodeSDNode>(N)->get() !=
-          (ISD::CondCode)MatcherTable[MatcherIndex++]) break;
-      continue;
-    case OPC_CheckValueType: {
-      MVT::SimpleValueType VT =
-        (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
-      if (cast<VTSDNode>(N)->getVT() != VT) {
-        // Handle the case when VT is iPTR.
-        if (VT != MVT::iPTR || cast<VTSDNode>(N)->getVT() != TLI.getPointerTy())
-          break;
-      }
-      continue;
-    }
-    case OPC_CheckInteger: {
-      int64_t Val = MatcherTable[MatcherIndex++];
-      if (Val & 128)
-        Val = GetVBR(Val, MatcherTable, MatcherIndex);
-      if (CheckInteger(N, Val)) break;
-      continue;
-    }        
-    case OPC_CheckAndImm: {
-      int64_t Val = MatcherTable[MatcherIndex++];
-      if (Val & 128)
-        Val = GetVBR(Val, MatcherTable, MatcherIndex);
-      if (CheckAndImmediate(N, Val)) break;
-      continue;
-    }
-    case OPC_CheckOrImm: {
-      int64_t Val = MatcherTable[MatcherIndex++];
-      if (Val & 128)
-        Val = GetVBR(Val, MatcherTable, MatcherIndex);
-      if (CheckOrImmediate(N, Val)) 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))
-        break;
-      
-      continue;
-    }
-    case OPC_CheckChainCompatible: {
-      unsigned PrevNode = MatcherTable[MatcherIndex++];
-      assert(PrevNode < RecordedNodes.size() && "Invalid CheckChainCompatible");
-      SDValue PrevChainedNode = RecordedNodes[PrevNode];
-      SDValue ThisChainedNode = RecordedNodes.back();
-      
-      // We have two nodes with chains, verify that their input chains are good.
-      assert(PrevChainedNode.getOperand(0).getValueType() == MVT::Other &&
-             ThisChainedNode.getOperand(0).getValueType() == MVT::Other &&
-             "Invalid chained nodes");
-      
-      if (!IsChainCompatible(// Input chain of the previous node.
-                             PrevChainedNode.getOperand(0).getNode(),
-                             // Node with chain.
-                             ThisChainedNode.getNode()))
-        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");
-
-      // Handle the first chain.
-      unsigned RecNo = MatcherTable[MatcherIndex++];
-      assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
-      ChainNodesMatched.push_back(RecordedNodes[RecNo].getNode());
-      
-      // If the chained node is not the root, we can't fold it if it has
-      // multiple uses.
-      // 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;
-      }
-      
-      // The common case here is that we have exactly one chain, which is really
-      // cheap to handle, just do it.
-      if (NumChains == 1) {
-        InputChain = RecordedNodes[RecNo].getOperand(0);
-        assert(InputChain.getValueType() == MVT::Other && "Not a chain");
-        continue;
-      }
-      
-      // Read all of the chained nodes.
-      for (unsigned i = 1; i != NumChains; ++i) {
-        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;
-        }
-      }
-
-      // Walk all the chained nodes, adding the input chains if they are not in
-      // ChainedNodes (and this, not in the matched pattern).  This is an N^2
-      // algorithm, but # chains is usually 2 here, at most 3 for MSP430.
-      SmallVector<SDValue, 3> InputChains;
-      for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
-        SDValue InChain = ChainNodesMatched[i]->getOperand(0);
-        assert(InChain.getValueType() == MVT::Other && "Not a chain");
-        bool Invalid = false;
-        for (unsigned j = 0; j != e; ++j)
-          Invalid |= ChainNodesMatched[j] == InChain.getNode();
-        if (!Invalid)
-          InputChains.push_back(InChain);
-      }
-
-      SDValue Res;
-      if (InputChains.size() == 1)
-        InputChain = InputChains[0];
-      else
-        InputChain = CurDAG->getNode(ISD::TokenFactor,
-                                     NodeToMatch->getDebugLoc(), MVT::Other,
-                                     &InputChains[0], InputChains.size());
-      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 = GetInt2(MatcherTable, MatcherIndex);
-      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);
-      
-      // FIXME: Use faster version for the common 'one VT' case?
-      SDVTList 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 {
-        // 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 = NodeToMatch->getNumValues();
-        if (NodeToMatch->getValueType(NTMNumResults-1) == MVT::Flag) {
-          OldFlagResultNo = NTMNumResults-1;
-          if (NTMNumResults != 1 &&
-              NodeToMatch->getValueType(NTMNumResults-2) == MVT::Other)
-            OldChainResultNo = NTMNumResults-2;
-        } else if (NodeToMatch->getValueType(NTMNumResults-1) == MVT::Other)
-          OldChainResultNo = NTMNumResults-1;
-        
-        Res = CurDAG->MorphNodeTo(NodeToMatch, ~TargetOpc, VTList,
-                                  Ops.data(), Ops.size());
-        
-        // 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 == NodeToMatch) {
-          // 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)
-          ReplaceUses(SDValue(NodeToMatch, 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)
-          ReplaceUses(SDValue(NodeToMatch, OldChainResultNo), 
-                      SDValue(Res, ResNumResults-1));
-
-        if (Res != NodeToMatch) {
-          // Otherwise, no replacement happened because the node already exists.
-          ReplaceUses(NodeToMatch, Res);
-        }
-      }
-      
-      // If the node had chain/flag results, update our notion of the current
-      // chain and flag.
-      if (VTs.back() == MVT::Flag) {
-        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 0;
-      }
-      
-      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");
-        ReplaceUses(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();
-    }
-  }
-}
-    
-
 #endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=97425&r1=97424&r2=97425&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Sun Feb 28 16:37:22 2010
@@ -154,6 +154,14 @@
     OPFL_VariadicInfo = OPFL_Variadic6
   };
   
+  /// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the
+  /// number of fixed arity values that should be skipped when copying from the
+  /// root.
+  static inline int getNumFixedFromVariadicInfo(unsigned Flags) {
+    return ((Flags&OPFL_VariadicInfo) >> 4)-1;
+  }
+  
+  
 protected:
   /// DAGSize - Size of DAG being instruction selected.
   ///
@@ -204,6 +212,10 @@
   SDNode *Select_INLINEASM(SDNode *N);
   SDNode *Select_UNDEF(SDNode *N);
   SDNode *Select_EH_LABEL(SDNode *N);
+  
+  SDNode *SelectCodeCommon(SDNode *NodeToMatch,
+                           const unsigned char *MatcherTable,
+                           unsigned TableSize);
   void CannotYetSelect(SDNode *N);
   void CannotYetSelectIntrinsic(SDNode *N);
 

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=97425&r1=97424&r2=97425&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sun Feb 28 16:37:22 2010
@@ -1455,6 +1455,865 @@
                               MVT::Other, Tmp, Chain);
 }
 
+
+/// ChainNotReachable - Returns true if Chain does not reach Op.
+static bool ChainNotReachable(SDNode *Chain, SDNode *Op) {
+  if (Chain->getOpcode() == ISD::EntryToken)
+    return true;
+  if (Chain->getOpcode() == ISD::TokenFactor)
+    return false;
+  if (Chain->getNumOperands() > 0) {
+    SDValue C0 = Chain->getOperand(0);
+    if (C0.getValueType() == MVT::Other)
+      return C0.getNode() != Op && ChainNotReachable(C0.getNode(), Op);
+  }
+  return true;
+}
+
+/// IsChainCompatible - Returns true if Chain is Op or Chain does not reach Op.
+/// This is used to ensure that there are no nodes trapped between Chain, which
+/// is the first chain node discovered in a pattern and Op, a later node, that
+/// will not be selected into the pattern.
+static bool IsChainCompatible(SDNode *Chain, SDNode *Op) {
+  return Chain == Op || ChainNotReachable(Chain, Op);
+}
+
+
+// These functions are marked always inline so that Idx doesn't get pinned to
+// the stack.
+ALWAYS_INLINE static int8_t
+GetInt1(const unsigned char *MatcherTable, unsigned &Idx) {
+  return MatcherTable[Idx++];
+}
+
+ALWAYS_INLINE static int16_t
+GetInt2(const unsigned char *MatcherTable, unsigned &Idx) {
+  int16_t Val = (uint8_t)GetInt1(MatcherTable, Idx);
+  Val |= int16_t(GetInt1(MatcherTable, Idx)) << 8;
+  return Val;
+}
+
+/// 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 = GetInt1(MatcherTable, Idx);
+    Val |= (NextBits&127) << Shift;
+    Shift += 7;
+  } while (NextBits & 128);
+  
+  return Val;
+}
+
+/// ISelUpdater - helper class to handle updates of the 
+/// instruciton selection graph.
+namespace {
+class ISelUpdater : public SelectionDAG::DAGUpdateListener {
+  SelectionDAG::allnodes_iterator &ISelPosition;
+public:
+  explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
+  : ISelPosition(isp) {}
+  
+  /// NodeDeleted - Handle nodes deleted from the graph. If the
+  /// node being deleted is the current ISelPosition node, update
+  /// ISelPosition.
+  ///
+  virtual void NodeDeleted(SDNode *N, SDNode *E) {
+    if (ISelPosition == SelectionDAG::allnodes_iterator(N))
+      ++ISelPosition;
+  }
+  
+  /// NodeUpdated - Ignore updates for now.
+  virtual void NodeUpdated(SDNode *N) {}
+};
+}
+
+#if 0
+/// ReplaceUses - replace all uses of the old node F with the use
+/// of the new node T.
+static void ReplaceUses(SDValue F, SDValue T) {
+  ISelUpdater ISU(ISelPosition);
+  CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
+}
+#endif
+
+/// UpdateChainsAndFlags - When a match is complete, this method updates uses of
+/// interior flag and chain results to use the new flag and chain results.
+static void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
+                              const SmallVectorImpl<SDNode*> &ChainNodesMatched,
+                                 SDValue InputFlag,
+                         const SmallVectorImpl<SDNode*> &FlagResultNodesMatched,
+                                 bool isMorphNodeTo, SelectionDAG *CurDAG) {
+  // 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];
+      
+      // 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);
+    }
+  }
+  
+  // 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];
+      assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Flag &&
+             "Doesn't have a flag result");
+      CurDAG->ReplaceAllUsesOfValueWith(SDValue(FRN, FRN->getNumValues()-1),
+                                        InputFlag);
+    }
+  }
+  
+  DEBUG(errs() << "ISEL: Match complete!\n");
+}
+
+
+
+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:
+    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');
+  
+  // Interpreter starts at opcode #0.
+  unsigned MatcherIndex = 0;
+  while (1) {
+    assert(MatcherIndex < TableSize && "Invalid index");
+    BuiltinOpcodes Opcode = (BuiltinOpcodes)MatcherTable[MatcherIndex++];
+    switch (Opcode) {
+    case OPC_Scope: {
+      unsigned NumToSkip = MatcherTable[MatcherIndex++];
+      if (NumToSkip & 128)
+        NumToSkip = GetVBR(NumToSkip, MatcherTable, MatcherIndex);
+      assert(NumToSkip != 0 &&
+             "First entry of OPC_Scope shouldn't be 0, scope has no children?");
+
+      // Push a MatchScope which indicates where to go if the first child fails
+      // to match.
+      MatchScope NewEntry;
+      NewEntry.FailIndex = MatcherIndex+NumToSkip;
+      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: {
+      // Accept if it is exactly the same as a previously recorded node.
+      unsigned RecNo = MatcherTable[MatcherIndex++];
+      assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+      if (N != RecordedNodes[RecNo]) break;
+      continue;
+    }
+    case OPC_CheckPatternPredicate:
+      if (!CheckPatternPredicate(MatcherTable[MatcherIndex++])) break;
+      continue;
+    case OPC_CheckPredicate:
+      if (!CheckNodePredicate(N.getNode(), MatcherTable[MatcherIndex++])) break;
+      continue;
+    case OPC_CheckComplexPat:
+      if (!CheckComplexPattern(NodeToMatch, N, 
+                               MatcherTable[MatcherIndex++], RecordedNodes))
+        break;
+      continue;
+    case OPC_CheckOpcode:
+      if (N->getOpcode() != MatcherTable[MatcherIndex++]) break;
+      continue;
+        
+    case OPC_CheckMultiOpcode: {
+      unsigned NumOps = MatcherTable[MatcherIndex++];
+      bool OpcodeEquals = false;
+      for (unsigned i = 0; i != NumOps; ++i)
+        OpcodeEquals |= N->getOpcode() == MatcherTable[MatcherIndex++];
+      if (!OpcodeEquals) break;
+      continue;
+    }
+        
+    case OPC_CheckType: {
+      MVT::SimpleValueType VT =
+        (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+      if (N.getValueType() != VT) {
+        // Handle the case when VT is iPTR.
+        if (VT != MVT::iPTR || N.getValueType() != TLI.getPointerTy())
+          break;
+      }
+      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: {
+      unsigned ChildNo = Opcode-OPC_CheckChild0Type;
+      if (ChildNo >= N.getNumOperands())
+        break;  // Match fails if out of range child #.
+      
+      MVT::SimpleValueType VT =
+        (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+      EVT ChildVT = N.getOperand(ChildNo).getValueType();
+      if (ChildVT != VT) {
+        // Handle the case when VT is iPTR.
+        if (VT != MVT::iPTR || ChildVT != TLI.getPointerTy())
+          break;
+      }
+      continue;
+    }
+    case OPC_CheckCondCode:
+      if (cast<CondCodeSDNode>(N)->get() !=
+          (ISD::CondCode)MatcherTable[MatcherIndex++]) break;
+      continue;
+    case OPC_CheckValueType: {
+      MVT::SimpleValueType VT =
+        (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+      if (cast<VTSDNode>(N)->getVT() != VT) {
+        // Handle the case when VT is iPTR.
+        if (VT != MVT::iPTR || cast<VTSDNode>(N)->getVT() != TLI.getPointerTy())
+          break;
+      }
+      continue;
+    }
+    case OPC_CheckInteger: {
+      int64_t Val = MatcherTable[MatcherIndex++];
+      if (Val & 128)
+        Val = GetVBR(Val, MatcherTable, MatcherIndex);
+      
+      ConstantSDNode *C = dyn_cast<ConstantSDNode>(N);
+      if (C == 0 || C->getSExtValue() != Val)
+        break;
+      continue;
+    }        
+    case OPC_CheckAndImm: {
+      int64_t Val = MatcherTable[MatcherIndex++];
+      if (Val & 128)
+        Val = GetVBR(Val, MatcherTable, MatcherIndex);
+      
+      if (N->getOpcode() != ISD::AND) break;
+      ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
+      if (C == 0 || !CheckAndMask(N.getOperand(0), C, Val))
+        break;
+      continue;
+    }
+    case OPC_CheckOrImm: {
+      int64_t Val = MatcherTable[MatcherIndex++];
+      if (Val & 128)
+        Val = GetVBR(Val, MatcherTable, MatcherIndex);
+      
+      if (N->getOpcode() != ISD::OR) break;
+      
+      ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
+      if (C == 0 || !CheckOrMask(N.getOperand(0), C, Val))
+        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))
+        break;
+      
+      continue;
+    }
+    case OPC_CheckChainCompatible: {
+      unsigned PrevNode = MatcherTable[MatcherIndex++];
+      assert(PrevNode < RecordedNodes.size() && "Invalid CheckChainCompatible");
+      SDValue PrevChainedNode = RecordedNodes[PrevNode];
+      SDValue ThisChainedNode = RecordedNodes.back();
+      
+      // We have two nodes with chains, verify that their input chains are good.
+      assert(PrevChainedNode.getOperand(0).getValueType() == MVT::Other &&
+             ThisChainedNode.getOperand(0).getValueType() == MVT::Other &&
+             "Invalid chained nodes");
+      
+      if (!IsChainCompatible(// Input chain of the previous node.
+                             PrevChainedNode.getOperand(0).getNode(),
+                             // Node with chain.
+                             ThisChainedNode.getNode()))
+        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");
+
+      // Handle the first chain.
+      unsigned RecNo = MatcherTable[MatcherIndex++];
+      assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+      ChainNodesMatched.push_back(RecordedNodes[RecNo].getNode());
+      
+      // If the chained node is not the root, we can't fold it if it has
+      // multiple uses.
+      // 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;
+      }
+      
+      // The common case here is that we have exactly one chain, which is really
+      // cheap to handle, just do it.
+      if (NumChains == 1) {
+        InputChain = RecordedNodes[RecNo].getOperand(0);
+        assert(InputChain.getValueType() == MVT::Other && "Not a chain");
+        continue;
+      }
+      
+      // Read all of the chained nodes.
+      for (unsigned i = 1; i != NumChains; ++i) {
+        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;
+        }
+      }
+
+      // Walk all the chained nodes, adding the input chains if they are not in
+      // ChainedNodes (and this, not in the matched pattern).  This is an N^2
+      // algorithm, but # chains is usually 2 here, at most 3 for MSP430.
+      SmallVector<SDValue, 3> InputChains;
+      for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
+        SDValue InChain = ChainNodesMatched[i]->getOperand(0);
+        assert(InChain.getValueType() == MVT::Other && "Not a chain");
+        bool Invalid = false;
+        for (unsigned j = 0; j != e; ++j)
+          Invalid |= ChainNodesMatched[j] == InChain.getNode();
+        if (!Invalid)
+          InputChains.push_back(InChain);
+      }
+
+      SDValue Res;
+      if (InputChains.size() == 1)
+        InputChain = InputChains[0];
+      else
+        InputChain = CurDAG->getNode(ISD::TokenFactor,
+                                     NodeToMatch->getDebugLoc(), MVT::Other,
+                                     &InputChains[0], InputChains.size());
+      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 = GetInt2(MatcherTable, MatcherIndex);
+      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);
+      
+      // FIXME: Use faster version for the common 'one VT' case?
+      SDVTList 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 {
+        // 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 = NodeToMatch->getNumValues();
+        if (NodeToMatch->getValueType(NTMNumResults-1) == MVT::Flag) {
+          OldFlagResultNo = NTMNumResults-1;
+          if (NTMNumResults != 1 &&
+              NodeToMatch->getValueType(NTMNumResults-2) == MVT::Other)
+            OldChainResultNo = NTMNumResults-2;
+        } else if (NodeToMatch->getValueType(NTMNumResults-1) == MVT::Other)
+          OldChainResultNo = NTMNumResults-1;
+        
+        Res = CurDAG->MorphNodeTo(NodeToMatch, ~TargetOpc, VTList,
+                                  Ops.data(), Ops.size());
+        
+        // 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 == NodeToMatch) {
+          // 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(NodeToMatch,
+                                                    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(NodeToMatch,
+                                                    OldChainResultNo), 
+                                            SDValue(Res, ResNumResults-1));
+
+        if (Res != NodeToMatch) {
+          // Otherwise, no replacement happened because the node already exists.
+          CurDAG->ReplaceAllUsesWith(NodeToMatch, Res);
+        }
+      }
+      
+      // If the node had chain/flag results, update our notion of the current
+      // chain and flag.
+      if (VTs.back() == MVT::Flag) {
+        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, CurDAG);
+        return 0;
+      }
+      
+      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, CurDAG);
+      
+      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 ||





More information about the llvm-commits mailing list