[ARM] Use the load-acquire/store-release instructions optimally in AArch32.

Patch by Artyom Skrobov.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191428 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Amara Emerson
2013-09-26 12:22:36 +00:00
parent 9637da6083
commit 268c743a3b
12 changed files with 1913 additions and 389 deletions

View File

@@ -604,11 +604,17 @@ namespace ISD {
ATOMIC_STORE,
/// Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
/// For double-word atomic operations:
/// ValLo, ValHi, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmpLo, cmpHi,
/// swapLo, swapHi)
/// This corresponds to the cmpxchg instruction.
ATOMIC_CMP_SWAP,
/// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
/// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
/// For double-word atomic operations:
/// ValLo, ValHi, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amtLo, amtHi)
/// ValLo, ValHi, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amtLo, amtHi)
/// These correspond to the atomicrmw instruction.
ATOMIC_SWAP,
ATOMIC_LOAD_ADD,

View File

@@ -677,6 +677,13 @@ public:
AtomicOrdering Ordering,
SynchronizationScope SynchScope);
/// getAtomic - Gets a node for an atomic op, produces result and chain and
/// takes N operands.
SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTList,
SDValue* Ops, unsigned NumOps, MachineMemOperand *MMO,
AtomicOrdering Ordering,
SynchronizationScope SynchScope);
/// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a
/// result and takes a list of operands. Opcode may be INTRINSIC_VOID,
/// INTRINSIC_W_CHAIN, or a target-specific opcode with a value not

View File

@@ -1073,6 +1073,7 @@ public:
///
class AtomicSDNode : public MemSDNode {
SDUse Ops[4];
SDUse* DynOps;
void InitAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope) {
// This must match encodeMemSDNodeFlags() in SelectionDAG.cpp.
@@ -1100,7 +1101,7 @@ public:
SDValue Chain, SDValue Ptr,
SDValue Cmp, SDValue Swp, MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope)
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO), DynOps(NULL) {
InitAtomic(Ordering, SynchScope);
InitOperands(Ops, Chain, Ptr, Cmp, Swp);
}
@@ -1109,7 +1110,7 @@ public:
SDValue Chain, SDValue Ptr,
SDValue Val, MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope)
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO), DynOps(NULL) {
InitAtomic(Ordering, SynchScope);
InitOperands(Ops, Chain, Ptr, Val);
}
@@ -1118,10 +1119,22 @@ public:
SDValue Chain, SDValue Ptr,
MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope)
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO), DynOps(NULL) {
InitAtomic(Ordering, SynchScope);
InitOperands(Ops, Chain, Ptr);
}
AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT,
SDValue* AllOps, unsigned NumOps,
MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope)
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
DynOps = new SDUse[NumOps];
InitAtomic(Ordering, SynchScope);
InitOperands(DynOps, AllOps, NumOps);
}
~AtomicSDNode() {
delete[] DynOps;
}
const SDValue &getBasePtr() const { return getOperand(1); }
const SDValue &getVal() const { return getOperand(2); }
@@ -1852,7 +1865,7 @@ template <> struct GraphTraits<SDNode*> {
/// LargestSDNode - The largest SDNode class.
///
typedef LoadSDNode LargestSDNode;
typedef AtomicSDNode LargestSDNode;
/// MostAlignedSDNode - The SDNode class with the greatest alignment
/// requirement.