Use a linked data structure for the uses lists of an SDNode, just like
[oota-llvm.git] / lib / Target / X86 / X86ISelDAGToDAG.cpp
index 75e9faecb290b3f72e95c2b170acf1e94153e1c1..bcc87e9b2b0a1b07fb34eac359ed191856728cb7 100644 (file)
@@ -44,13 +44,6 @@ using namespace llvm;
 STATISTIC(NumFPKill   , "Number of FP_REG_KILL instructions added");
 STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor");
 
-namespace {
-  static cl::opt<bool>
-  AlwaysFoldAndInTest("always-fold-and-in-test",
-                cl::desc("Always fold and operation in test"),
-                cl::init(true), cl::Hidden);
-}
-
 //===----------------------------------------------------------------------===//
 //                      Pattern Matcher Implementation
 //===----------------------------------------------------------------------===//
@@ -232,7 +225,7 @@ namespace {
 static SDNode *findFlagUse(SDNode *N) {
   unsigned FlagResNo = N->getNumValues()-1;
   for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
-    SDNode *User = *I;
+    SDNode *User = I->getUser();
     for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
       SDOperand Op = User->getOperand(i);
       if (Op.Val == N && Op.ResNo == FlagResNo)
@@ -433,7 +426,7 @@ void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) {
           RModW = true;
           std::swap(N10, N11);
         }
-        RModW = RModW && N10.Val->isOperand(Chain.Val) && N10.hasOneUse() &&
+        RModW = RModW && N10.Val->isOperandOf(Chain.Val) && N10.hasOneUse() &&
           (N10.getOperand(1) == N2) &&
           (N10.Val->getValueType(0) == N1.getValueType());
         if (RModW)
@@ -452,7 +445,7 @@ void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) {
       case X86ISD::SHRD: {
         SDOperand N10 = N1.getOperand(0);
         if (ISD::isNON_EXTLoad(N10.Val))
-          RModW = N10.Val->isOperand(Chain.Val) && N10.hasOneUse() &&
+          RModW = N10.Val->isOperandOf(Chain.Val) && N10.hasOneUse() &&
             (N10.getOperand(1) == N2) &&
             (N10.Val->getValueType(0) == N1.getValueType());
         if (RModW)
@@ -493,10 +486,15 @@ void X86DAGToDAGISel::PreprocessForFPConvert(SelectionDAG &DAG) {
     if (SrcIsSSE && DstIsSSE)
       continue;
 
-    // If this is an FPStack extension (but not a truncation), it is a noop.
-    if (!SrcIsSSE && !DstIsSSE && N->getOpcode() == ISD::FP_EXTEND)
-      continue;
-    
+    if (!SrcIsSSE && !DstIsSSE) {
+      // If this is an FPStack extension, it is a noop.
+      if (N->getOpcode() == ISD::FP_EXTEND)
+        continue;
+      // If this is a value-preserving FPStack truncation, it is a noop.
+      if (N->getConstantOperandVal(1))
+        continue;
+    }
+   
     // Here we could have an FP stack truncation or an FPStack <-> SSE convert.
     // FPStack has extload and truncstore.  SSE can fold direct loads into other
     // operations.  Based on this, decide what we want to do.
@@ -552,7 +550,8 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
 
   DAG.RemoveDeadNodes();
 
-  // Emit machine code to BB. 
+  // Emit machine code to BB.  This can change 'BB' to the last block being 
+  // inserted into.
   ScheduleAndEmitDAG(DAG);
   
   // If we are emitting FP stack code, scan the basic block to determine if this
@@ -568,15 +567,27 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
   // Scan all of the machine instructions in these MBBs, checking for FP
   // stores.  (RFP32 and RFP64 will not exist in SSE mode, but RFP80 might.)
   MachineFunction::iterator MBBI = FirstMBB;
-  do {
+  MachineFunction::iterator EndMBB = BB; ++EndMBB;
+  for (; MBBI != EndMBB; ++MBBI) {
+    MachineBasicBlock *MBB = MBBI;
+    
+    // If this block returns, ignore it.  We don't want to insert an FP_REG_KILL
+    // before the return.
+    if (!MBB->empty()) {
+      MachineBasicBlock::iterator EndI = MBB->end();
+      --EndI;
+      if (EndI->getDesc().isReturn())
+        continue;
+    }
+    
     bool ContainsFPCode = false;
-    for (MachineBasicBlock::iterator I = MBBI->begin(), E = MBBI->end();
+    for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
          !ContainsFPCode && I != E; ++I) {
       if (I->getNumOperands() != 0 && I->getOperand(0).isRegister()) {
         const TargetRegisterClass *clas;
         for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
           if (I->getOperand(op).isRegister() && I->getOperand(op).isDef() &&
-              TargetRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) &&
+            TargetRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) &&
               ((clas = RegInfo->getRegClass(I->getOperand(0).getReg())) == 
                  X86::RFP32RegisterClass ||
                clas == X86::RFP64RegisterClass ||
@@ -610,11 +621,11 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
     }
     // Finally, if we found any FP code, emit the FP_REG_KILL instruction.
     if (ContainsFPCode) {
-      BuildMI(*MBBI, MBBI->getFirstTerminator(),
+      BuildMI(*MBB, MBBI->getFirstTerminator(),
               TM.getInstrInfo()->get(X86::FP_REG_KILL));
       ++NumFPKill;
     }
-  } while (&*(MBBI++) != BB);
+  }
 }
 
 /// EmitSpecialCodeForMain - Emit any code that needs to be executed only in
@@ -1157,26 +1168,35 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
     case X86ISD::GlobalBaseReg: 
       return getGlobalBaseReg();
 
-    case X86ISD::FP_GET_RESULT2: {
-      SDOperand Chain = N.getOperand(0);
-      SDOperand InFlag = N.getOperand(1);
-      AddToISelQueue(Chain);
-      AddToISelQueue(InFlag);
-      std::vector<MVT::ValueType> Tys;
-      Tys.push_back(MVT::f80);
-      Tys.push_back(MVT::f80);
-      Tys.push_back(MVT::Other);
-      Tys.push_back(MVT::Flag);
-      SDOperand Ops[] = { Chain, InFlag };
-      SDNode *ResNode = CurDAG->getTargetNode(X86::FpGETRESULT80x2, Tys,
-                                              Ops, 2);
-      Chain = SDOperand(ResNode, 2);
-      InFlag = SDOperand(ResNode, 3);
-      ReplaceUses(SDOperand(N.Val, 2), Chain);
-      ReplaceUses(SDOperand(N.Val, 3), InFlag);
-      return ResNode;
-    }
-
+    // FIXME: This is a workaround for a tblgen problem: rdar://5791600
+    case X86ISD::RET_FLAG:
+      if (ConstantSDNode *Amt = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+        if (Amt->getSignExtended() != 0) break;
+        
+        // Match (X86retflag 0).
+        SDOperand Chain = N.getOperand(0);
+        bool HasInFlag = N.getOperand(N.getNumOperands()-1).getValueType()
+                          == MVT::Flag;
+        SmallVector<SDOperand, 8> Ops0;
+        AddToISelQueue(Chain);
+        SDOperand InFlag(0, 0);
+        if (HasInFlag) {
+          InFlag = N.getOperand(N.getNumOperands()-1);
+          AddToISelQueue(InFlag);
+        }
+        for (unsigned i = 2, e = N.getNumOperands()-(HasInFlag?1:0); i != e;
+             ++i) {
+          AddToISelQueue(N.getOperand(i));
+          Ops0.push_back(N.getOperand(i));
+        }
+        Ops0.push_back(Chain);
+        if (HasInFlag)
+          Ops0.push_back(InFlag);
+        return CurDAG->getTargetNode(X86::RET, MVT::Other,
+                                     &Ops0[0], Ops0.size());
+      }
+      break;
+      
     case ISD::ADD: {
       // Turn ADD X, c to MOV32ri X+c. This cannot be done with tblgen'd
       // code and is matched first so to prevent it from being turned into
@@ -1489,37 +1509,36 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
     }
 
     case ISD::ANY_EXTEND: {
+      // Check if the type  extended to supports subregs.
+      if (NVT == MVT::i8)
+        break;
+      
       SDOperand N0 = Node->getOperand(0);
+      // Get the subregsiter index for the type to extend.
+      MVT::ValueType N0VT = N0.getValueType();
+      unsigned Idx = (N0VT == MVT::i32) ? X86::SUBREG_32BIT :
+                      (N0VT == MVT::i16) ? X86::SUBREG_16BIT :
+                        (Subtarget->is64Bit()) ? X86::SUBREG_8BIT : 0;
+      
+      // If we don't have a subreg Idx, let generated ISel have a try.
+      if (Idx == 0)
+        break;
+        
+      // If we have an index, generate an insert_subreg into undef.
       AddToISelQueue(N0);
-      if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
-        SDOperand SRIdx;
-        switch(N0.getValueType()) {
-        case MVT::i32:
-          SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
-          break;
-        case MVT::i16:
-          SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
-          break;
-        case MVT::i8:
-          if (Subtarget->is64Bit())
-            SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
-          break;
-        default: assert(0 && "Unknown any_extend!");
-        }
-        if (SRIdx.Val) {
-          SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
-                                                  NVT, N0, SRIdx);
+      SDOperand Undef = 
+                  SDOperand(CurDAG->getTargetNode(X86::IMPLICIT_DEF, NVT), 0);
+      SDOperand SRIdx = CurDAG->getTargetConstant(Idx, MVT::i32);
+      SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
+                                                NVT, Undef, N0, SRIdx);
 
 #ifndef NDEBUG
-          DOUT << std::string(Indent-2, ' ') << "=> ";
-          DEBUG(ResNode->dump(CurDAG));
-          DOUT << "\n";
-          Indent -= 2;
+      DOUT << std::string(Indent-2, ' ') << "=> ";
+      DEBUG(ResNode->dump(CurDAG));
+      DOUT << "\n";
+      Indent -= 2;
 #endif
-          return ResNode;
-        } // Otherwise let generated ISel handle it.
-      }
-      break;
+      return ResNode;
     }
     
     case ISD::SIGN_EXTEND_INREG: {