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: