diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-08-24 20:50:09 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-08-24 20:50:09 +0000 |
commit | 327236cd6c211e54fc6288b0ac2b413901cc0611 (patch) | |
tree | b8413eb9f01313fbcce90df7a1f0ab3bdbc3d6cd /include | |
parent | b05fdd6babada25da2ec3ba54bb462c2ecfc42a8 (diff) | |
download | llvm-327236cd6c211e54fc6288b0ac2b413901cc0611.tar.gz llvm-327236cd6c211e54fc6288b0ac2b413901cc0611.tar.bz2 llvm-327236cd6c211e54fc6288b0ac2b413901cc0611.tar.xz |
Basic x86 code generation for atomic load and store instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138478 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/CodeGen/ISDOpcodes.h | 22 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAG.h | 20 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 14 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAG.td | 32 |
4 files changed, 71 insertions, 17 deletions
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 7c06beb956..7f5625cd5e 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -597,22 +597,22 @@ namespace ISD { // two integer constants: an AtomicOrdering and a SynchronizationScope. ATOMIC_FENCE, + // Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) + // This corresponds to "load atomic" instruction. + ATOMIC_LOAD, + + // OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val) + // This corresponds to "store atomic" instruction. + ATOMIC_STORE, + // Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) - // this corresponds to the atomic.lcs intrinsic. - // cmp is compared to *ptr, and if equal, swap is stored in *ptr. - // the return is always the original value in *ptr + // This corresponds to the cmpxchg instruction. ATOMIC_CMP_SWAP, // Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) - // this corresponds to the atomic.swap intrinsic. - // amt is stored to *ptr atomically. - // the return is always the original value in *ptr - ATOMIC_SWAP, - // Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt) - // this corresponds to the atomic.load.[OpName] intrinsic. - // op(*ptr, amt) is stored to *ptr atomically. - // the return is always the original value in *ptr + // These correspond to the atomicrmw instruction. + ATOMIC_SWAP, ATOMIC_LOAD_ADD, ATOMIC_LOAD_SUB, ATOMIC_LOAD_AND, diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 4ea398339a..c8ccdb23b6 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -598,16 +598,26 @@ public: AtomicOrdering Ordering, SynchronizationScope SynchScope); - /// getAtomic - Gets a node for an atomic op, produces result and chain and - /// takes 2 operands. + /// getAtomic - Gets a node for an atomic op, produces result (if relevant) + /// and chain and takes 2 operands. SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, const Value* PtrVal, + unsigned Alignment, AtomicOrdering Ordering, + SynchronizationScope SynchScope); + SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, + SDValue Ptr, SDValue Val, MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); + + /// getAtomic - Gets a node for an atomic op, produces result and chain and + /// takes 1 operand. + SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT, + SDValue Chain, SDValue Ptr, const Value* PtrVal, unsigned Alignment, AtomicOrdering Ordering, SynchronizationScope SynchScope); - SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, - SDValue Ptr, SDValue Val, - MachineMemOperand *MMO, + SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT, + SDValue Chain, SDValue Ptr, MachineMemOperand *MMO, AtomicOrdering Ordering, SynchronizationScope SynchScope); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index c95fd9c775..2ecdc9a48c 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -976,6 +976,8 @@ public: N->getOpcode() == ISD::ATOMIC_LOAD_MAX || N->getOpcode() == ISD::ATOMIC_LOAD_UMIN || N->getOpcode() == ISD::ATOMIC_LOAD_UMAX || + N->getOpcode() == ISD::ATOMIC_LOAD || + N->getOpcode() == ISD::ATOMIC_STORE || N->isTargetMemoryOpcode(); } }; @@ -1025,6 +1027,14 @@ public: InitAtomic(Ordering, SynchScope); InitOperands(Ops, Chain, Ptr, Val); } + AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT, + SDValue Chain, SDValue Ptr, + MachineMemOperand *MMO, + AtomicOrdering Ordering, SynchronizationScope SynchScope) + : MemSDNode(Opc, dl, VTL, MemVT, MMO) { + InitAtomic(Ordering, SynchScope); + InitOperands(Ops, Chain, Ptr); + } const SDValue &getBasePtr() const { return getOperand(1); } const SDValue &getVal() const { return getOperand(2); } @@ -1048,7 +1058,9 @@ public: N->getOpcode() == ISD::ATOMIC_LOAD_MIN || N->getOpcode() == ISD::ATOMIC_LOAD_MAX || N->getOpcode() == ISD::ATOMIC_LOAD_UMIN || - N->getOpcode() == ISD::ATOMIC_LOAD_UMAX; + N->getOpcode() == ISD::ATOMIC_LOAD_UMAX || + N->getOpcode() == ISD::ATOMIC_LOAD || + N->getOpcode() == ISD::ATOMIC_STORE; } }; diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 6d38d18aec..91db08d83d 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -214,6 +214,12 @@ def SDTAtomic3 : SDTypeProfile<1, 3, [ def SDTAtomic2 : SDTypeProfile<1, 2, [ SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1> ]>; +def SDTAtomicStore : SDTypeProfile<0, 2, [ + SDTCisPtrTy<0>, SDTCisInt<1> +]>; +def SDTAtomicLoad : SDTypeProfile<1, 1, [ + SDTCisInt<0>, SDTCisPtrTy<1> +]>; def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5> @@ -427,6 +433,10 @@ def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; // Do not use ld, st directly. Use load, extload, sextload, zextload, store, // and truncst (see below). @@ -844,6 +854,28 @@ defm atomic_load_min : binary_atomic_op<atomic_load_min>; defm atomic_load_max : binary_atomic_op<atomic_load_max>; defm atomic_load_umin : binary_atomic_op<atomic_load_umin>; defm atomic_load_umax : binary_atomic_op<atomic_load_umax>; +defm atomic_store : binary_atomic_op<atomic_store>; + +def atomic_load_8 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8; +}]>; +def atomic_load_16 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16; +}]>; +def atomic_load_32 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32; +}]>; +def atomic_load_64 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64; +}]>; //===----------------------------------------------------------------------===// // Selection DAG CONVERT_RNDSAT patterns |