Added MemOperands to Atomic operations since Atomics touches memory.
Added abstract class MemSDNode for any Node that have an associated MemOperand
Changed atomic.lcs => atomic.cmp.swap, atomic.las => atomic.load.add, and
atomic.lss => atomic.load.sub


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52706 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index bf1608d..cf33508 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1228,7 +1228,7 @@
     break;
   }
 
-  case ISD::ATOMIC_LCS: {
+  case ISD::ATOMIC_CMP_SWAP: {
     unsigned int num_operands = 4;
     assert(Node->getNumOperands() == num_operands && "Invalid Atomic node!");
     SDOperand Ops[4];
@@ -1248,8 +1248,8 @@
     AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
     return Result.getValue(Op.ResNo);
   }      
-  case ISD::ATOMIC_LAS:
-  case ISD::ATOMIC_LSS:
+  case ISD::ATOMIC_LOAD_ADD:
+  case ISD::ATOMIC_LOAD_SUB:
   case ISD::ATOMIC_LOAD_AND:
   case ISD::ATOMIC_LOAD_OR:
   case ISD::ATOMIC_LOAD_XOR:
@@ -4270,18 +4270,20 @@
     break;
   }
     
-  case ISD::ATOMIC_LCS: {
+  case ISD::ATOMIC_CMP_SWAP: {
+    AtomicSDNode* AtomNode = cast<AtomicSDNode>(Node);
     Tmp2 = PromoteOp(Node->getOperand(2));
     Tmp3 = PromoteOp(Node->getOperand(3));
-    Result = DAG.getAtomic(Node->getOpcode(), Node->getOperand(0), 
-                           Node->getOperand(1), Tmp2, Tmp3,
-                           cast<AtomicSDNode>(Node)->getVT());
+    Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getChain(), 
+                           AtomNode->getBasePtr(), Tmp2, Tmp3,
+                           AtomNode->getVT(), AtomNode->getSrcValue(),
+                           AtomNode->getAlignment());
     // Remember that we legalized the chain.
     AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
     break;
   }
-  case ISD::ATOMIC_LAS:
-  case ISD::ATOMIC_LSS:
+  case ISD::ATOMIC_LOAD_ADD:
+  case ISD::ATOMIC_LOAD_SUB:
   case ISD::ATOMIC_LOAD_AND:
   case ISD::ATOMIC_LOAD_OR:
   case ISD::ATOMIC_LOAD_XOR:
@@ -4291,10 +4293,12 @@
   case ISD::ATOMIC_LOAD_UMIN:
   case ISD::ATOMIC_LOAD_UMAX:
   case ISD::ATOMIC_SWAP: {
+    AtomicSDNode* AtomNode = cast<AtomicSDNode>(Node);
     Tmp2 = PromoteOp(Node->getOperand(2));
-    Result = DAG.getAtomic(Node->getOpcode(), Node->getOperand(0), 
-                           Node->getOperand(1), Tmp2,
-                           cast<AtomicSDNode>(Node)->getVT());
+    Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getChain(), 
+                           AtomNode->getBasePtr(), Tmp2,
+                           AtomNode->getVT(), AtomNode->getSrcValue(),
+                           AtomNode->getAlignment());
     // Remember that we legalized the chain.
     AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
     break;
@@ -6151,7 +6155,7 @@
     break;
   }
 
-  case ISD::ATOMIC_LCS: {
+  case ISD::ATOMIC_CMP_SWAP: {
     SDOperand Tmp = TLI.LowerOperation(Op, DAG);
     assert(Tmp.Val && "Node must be custom expanded!");
     ExpandOp(Tmp.getValue(0), Lo, Hi);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index abd7272..1454a15 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -430,7 +430,24 @@
     ID.AddInteger(ST->isVolatile());
     break;
   }
+  case ISD::ATOMIC_CMP_SWAP:
+  case ISD::ATOMIC_LOAD_ADD:
+  case ISD::ATOMIC_SWAP:
+  case ISD::ATOMIC_LOAD_SUB:
+  case ISD::ATOMIC_LOAD_AND:
+  case ISD::ATOMIC_LOAD_OR:
+  case ISD::ATOMIC_LOAD_XOR:
+  case ISD::ATOMIC_LOAD_NAND:
+  case ISD::ATOMIC_LOAD_MIN:
+  case ISD::ATOMIC_LOAD_MAX:
+  case ISD::ATOMIC_LOAD_UMIN:
+  case ISD::ATOMIC_LOAD_UMAX: {
+    AtomicSDNode *AT = cast<AtomicSDNode>(N);
+    ID.AddInteger(AT->getAlignment());
+    ID.AddInteger(AT->isVolatile());
+    break;
   }
+  } // end switch (N->getOpcode())
 }
 
 //===----------------------------------------------------------------------===//
@@ -2972,8 +2989,9 @@
 
 SDOperand SelectionDAG::getAtomic(unsigned Opcode, SDOperand Chain, 
                                   SDOperand Ptr, SDOperand Cmp, 
-                                  SDOperand Swp, MVT VT) {
-  assert(Opcode == ISD::ATOMIC_LCS && "Invalid Atomic Op");
+                                  SDOperand Swp, MVT VT, const Value* PtrVal,
+                                  unsigned Alignment) {
+  assert(Opcode == ISD::ATOMIC_CMP_SWAP && "Invalid Atomic Op");
   assert(Cmp.getValueType() == Swp.getValueType() && "Invalid Atomic Op Types");
   SDVTList VTs = getVTList(Cmp.getValueType(), MVT::Other);
   FoldingSetNodeID ID;
@@ -2983,7 +3001,8 @@
   void* IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDOperand(E, 0);
-  SDNode* N = new AtomicSDNode(Opcode, VTs, Chain, Ptr, Cmp, Swp, VT);
+  SDNode* N = new AtomicSDNode(Opcode, VTs, Chain, Ptr, Cmp, Swp, VT,
+                               PtrVal, Alignment);
   CSEMap.InsertNode(N, IP);
   AllNodes.push_back(N);
   return SDOperand(N, 0);
@@ -2991,8 +3010,9 @@
 
 SDOperand SelectionDAG::getAtomic(unsigned Opcode, SDOperand Chain, 
                                   SDOperand Ptr, SDOperand Val, 
-                                  MVT VT) {
-  assert((   Opcode == ISD::ATOMIC_LAS || Opcode == ISD::ATOMIC_LSS
+                                  MVT VT, const Value* PtrVal,
+                                  unsigned Alignment) {
+  assert((   Opcode == ISD::ATOMIC_LOAD_ADD || Opcode == ISD::ATOMIC_LOAD_SUB
           || Opcode == ISD::ATOMIC_SWAP || Opcode == ISD::ATOMIC_LOAD_AND
           || Opcode == ISD::ATOMIC_LOAD_OR || Opcode == ISD::ATOMIC_LOAD_XOR
           || Opcode == ISD::ATOMIC_LOAD_NAND 
@@ -3007,7 +3027,8 @@
   void* IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDOperand(E, 0);
-  SDNode* N = new AtomicSDNode(Opcode, VTs, Chain, Ptr, Val, VT);
+  SDNode* N = new AtomicSDNode(Opcode, VTs, Chain, Ptr, Val, VT,
+                               PtrVal, Alignment);
   CSEMap.InsertNode(N, IP);
   AllNodes.push_back(N);
   return SDOperand(N, 0);
@@ -4171,6 +4192,7 @@
 void CondCodeSDNode::ANCHOR() {}
 void ARG_FLAGSSDNode::ANCHOR() {}
 void VTSDNode::ANCHOR() {}
+void MemSDNode::ANCHOR() {}
 void LoadSDNode::ANCHOR() {}
 void StoreSDNode::ANCHOR() {}
 void AtomicSDNode::ANCHOR() {}
@@ -4193,13 +4215,31 @@
 }
 
 /// getMemOperand - Return a MachineMemOperand object describing the memory
+/// reference performed by this atomic.
+MachineMemOperand AtomicSDNode::getMemOperand() const {
+  int Size = (getVT().getSizeInBits() + 7) >> 3;
+  int Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore;
+  if (isVolatile()) Flags |= MachineMemOperand::MOVolatile;
+  
+  // Check if the atomic references a frame index
+  const FrameIndexSDNode *FI = 
+  dyn_cast<const FrameIndexSDNode>(getBasePtr().Val);
+  if (!getSrcValue() && FI)
+    return MachineMemOperand(PseudoSourceValue::getFixedStack(), Flags,
+                             FI->getIndex(), Size, getAlignment());
+  else
+    return MachineMemOperand(getSrcValue(), Flags, getSrcValueOffset(),
+                             Size, getAlignment());
+}
+
+/// getMemOperand - Return a MachineMemOperand object describing the memory
 /// reference performed by this load or store.
 MachineMemOperand LSBaseSDNode::getMemOperand() const {
   int Size = (getMemoryVT().getSizeInBits() + 7) >> 3;
   int Flags =
     getOpcode() == ISD::LOAD ? MachineMemOperand::MOLoad :
                                MachineMemOperand::MOStore;
-  if (IsVolatile) Flags |= MachineMemOperand::MOVolatile;
+  if (isVolatile()) Flags |= MachineMemOperand::MOVolatile;
 
   // Check if the load references a frame index, and does not have
   // an SV attached.
@@ -4207,10 +4247,10 @@
     dyn_cast<const FrameIndexSDNode>(getBasePtr().Val);
   if (!getSrcValue() && FI)
     return MachineMemOperand(PseudoSourceValue::getFixedStack(), Flags,
-                             FI->getIndex(), Size, Alignment);
+                             FI->getIndex(), Size, getAlignment());
   else
     return MachineMemOperand(getSrcValue(), Flags,
-                             getSrcValueOffset(), Size, Alignment);
+                             getSrcValueOffset(), Size, getAlignment());
 }
 
 /// Profile - Gather unique data for the node.
@@ -4401,9 +4441,9 @@
    
   case ISD::PREFETCH:      return "Prefetch";
   case ISD::MEMBARRIER:    return "MemBarrier";
-  case ISD::ATOMIC_LCS:    return "AtomicLCS";
-  case ISD::ATOMIC_LAS:    return "AtomicLAS";
-  case ISD::ATOMIC_LSS:    return "AtomicLSS";
+  case ISD::ATOMIC_CMP_SWAP:  return "AtomicCmpSwap";
+  case ISD::ATOMIC_LOAD_ADD:  return "AtomicLoadAdd";
+  case ISD::ATOMIC_LOAD_SUB:  return "AtomicLoadSub";
   case ISD::ATOMIC_LOAD_AND:  return "AtomicLoadAnd";
   case ISD::ATOMIC_LOAD_OR:   return "AtomicLoadOr";
   case ISD::ATOMIC_LOAD_XOR:  return "AtomicLoadXor";
@@ -4756,7 +4796,8 @@
     cerr << N->getArgFlags().getArgFlagsString();
   } else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) {
     cerr << ":" << N->getVT().getMVTString();
-  } else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) {
+  }
+  else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) {
     const Value *SrcValue = LD->getSrcValue();
     int SrcOffset = LD->getSrcValueOffset();
     cerr << " <";
@@ -4808,6 +4849,18 @@
     if (ST->isVolatile())
       cerr << " <volatile>";
     cerr << " alignment=" << ST->getAlignment();
+  } else if (const AtomicSDNode* AT = dyn_cast<AtomicSDNode>(this)) {
+    const Value *SrcValue = AT->getSrcValue();
+    int SrcOffset = AT->getSrcValueOffset();
+    cerr << " <";
+    if (SrcValue)
+      cerr << SrcValue;
+    else
+      cerr << "null";
+    cerr << ":" << SrcOffset << ">";
+    if (AT->isVolatile())
+      cerr << " <volatile>";
+    cerr << " alignment=" << AT->getAlignment();
   }
 }
 
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 2671cc3..e20a7a7 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3088,7 +3088,8 @@
   SDOperand O2 = getValue(I.getOperand(2));
   SDOperand L = DAG.getAtomic(Op, Root, 
                               getValue(I.getOperand(1)), 
-                              O2, O2.getValueType());
+                              O2, O2.getValueType(),
+                              I.getOperand(1));
   setValue(&I, L);
   DAG.setRoot(L.getValue(1));
   return 0;
@@ -3518,21 +3519,22 @@
     DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, MVT::Other, &Ops[0], 6));
     return 0;
   }
-  case Intrinsic::atomic_lcs: {
+  case Intrinsic::atomic_cmp_swap: {
     SDOperand Root = getRoot();   
     SDOperand O3 = getValue(I.getOperand(3));
-    SDOperand L = DAG.getAtomic(ISD::ATOMIC_LCS, Root, 
+    SDOperand L = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, Root, 
                                 getValue(I.getOperand(1)), 
                                 getValue(I.getOperand(2)),
-                                O3, O3.getValueType());
+                                O3, O3.getValueType(),
+                                I.getOperand(1));
     setValue(&I, L);
     DAG.setRoot(L.getValue(1));
     return 0;
   }
-  case Intrinsic::atomic_las:
-    return implVisitBinaryAtomic(I, ISD::ATOMIC_LAS);
-  case Intrinsic::atomic_lss:
-    return implVisitBinaryAtomic(I, ISD::ATOMIC_LSS);
+  case Intrinsic::atomic_load_add:
+    return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_ADD);
+  case Intrinsic::atomic_load_sub:
+    return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_SUB);
   case Intrinsic::atomic_load_and:
     return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_AND);
   case Intrinsic::atomic_load_or: