[llvm-commits] [llvm] r138478 - in /llvm/trunk: include/llvm/CodeGen/ISDOpcodes.h include/llvm/CodeGen/SelectionDAG.h include/llvm/CodeGen/SelectionDAGNodes.h include/llvm/Target/TargetSelectionDAG.td lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/
Chandler Carruth
chandlerc at google.com
Wed Aug 24 15:02:58 PDT 2011
On Wed, Aug 24, 2011 at 1:50 PM, Eli Friedman <eli.friedman at gmail.com>wrote:
> Author: efriedma
> Date: Wed Aug 24 15:50:09 2011
> New Revision: 138478
>
> URL: http://llvm.org/viewvc/llvm-project?rev=138478&view=rev
> Log:
> Basic x86 code generation for atomic load and store instructions.
>
>
> Modified:
> llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
> llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
> llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
> llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
> llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> llvm/trunk/lib/Target/X86/X86InstrCompiler.td
>
Wait, no tests? None at all? =[
>
> Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Wed Aug 24 15:50:09 2011
> @@ -597,22 +597,22 @@
> // 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,
>
> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Wed Aug 24 15:50:09 2011
> @@ -598,16 +598,26 @@
> 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);
>
>
> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Wed Aug 24 15:50:09
> 2011
> @@ -976,6 +976,8 @@
> 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 @@
> 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 @@
> 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;
> }
> };
>
>
> Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original)
> +++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Wed Aug 24
> 15:50:09 2011
> @@ -214,6 +214,12 @@
> 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 @@
> [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_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
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Aug 24 15:50:09
> 2011
> @@ -819,6 +819,11 @@
> Action = TLI.getOperationAction(Node->getOpcode(), InnerType);
> break;
> }
> + case ISD::ATOMIC_STORE: {
> + Action = TLI.getOperationAction(Node->getOpcode(),
> + Node->getOperand(2).getValueType());
> + break;
> + }
> case ISD::SELECT_CC:
> case ISD::SETCC:
> case ISD::BR_CC: {
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Aug 24
> 15:50:09 2011
> @@ -432,7 +432,9 @@
> case ISD::ATOMIC_LOAD_MIN:
> case ISD::ATOMIC_LOAD_MAX:
> case ISD::ATOMIC_LOAD_UMIN:
> - case ISD::ATOMIC_LOAD_UMAX: {
> + case ISD::ATOMIC_LOAD_UMAX:
> + case ISD::ATOMIC_LOAD:
> + case ISD::ATOMIC_STORE: {
> const AtomicSDNode *AT = cast<AtomicSDNode>(N);
> ID.AddInteger(AT->getMemoryVT().getRawBits());
> ID.AddInteger(AT->getRawSubclassData());
> @@ -3904,12 +3906,14 @@
> Opcode == ISD::ATOMIC_LOAD_MAX ||
> Opcode == ISD::ATOMIC_LOAD_UMIN ||
> Opcode == ISD::ATOMIC_LOAD_UMAX ||
> - Opcode == ISD::ATOMIC_SWAP) &&
> + Opcode == ISD::ATOMIC_SWAP ||
> + Opcode == ISD::ATOMIC_STORE) &&
> "Invalid Atomic Op");
>
> EVT VT = Val.getValueType();
>
> - SDVTList VTs = getVTList(VT, MVT::Other);
> + SDVTList VTs = Opcode == ISD::ATOMIC_STORE ? getVTList(MVT::Other) :
> + getVTList(VT, MVT::Other);
> FoldingSetNodeID ID;
> ID.AddInteger(MemVT.getRawBits());
> SDValue Ops[] = {Chain, Ptr, Val};
> @@ -3927,6 +3931,55 @@
> return SDValue(N, 0);
> }
>
> +SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
> + EVT VT, SDValue Chain,
> + SDValue Ptr,
> + const Value* PtrVal,
> + unsigned Alignment,
> + AtomicOrdering Ordering,
> + SynchronizationScope SynchScope) {
> + if (Alignment == 0) // Ensure that codegen never sees alignment 0
> + Alignment = getEVTAlignment(MemVT);
> +
> + MachineFunction &MF = getMachineFunction();
> + unsigned Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore;
> +
> + // For now, atomics are considered to be volatile always.
> + Flags |= MachineMemOperand::MOVolatile;
> +
> + MachineMemOperand *MMO =
> + MF.getMachineMemOperand(MachinePointerInfo(PtrVal), Flags,
> + MemVT.getStoreSize(), Alignment);
> +
> + return getAtomic(Opcode, dl, MemVT, VT, Chain, Ptr, MMO,
> + Ordering, SynchScope);
> +}
> +
> +SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
> + EVT VT, SDValue Chain,
> + SDValue Ptr,
> + MachineMemOperand *MMO,
> + AtomicOrdering Ordering,
> + SynchronizationScope SynchScope) {
> + assert(Opcode == ISD::ATOMIC_LOAD && "Invalid Atomic Op");
> +
> + SDVTList VTs = getVTList(VT, MVT::Other);
> + FoldingSetNodeID ID;
> + ID.AddInteger(MemVT.getRawBits());
> + SDValue Ops[] = {Chain, Ptr};
> + AddNodeIDNode(ID, Opcode, VTs, Ops, 2);
> + void* IP = 0;
> + if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {
> + cast<AtomicSDNode>(E)->refineAlignment(MMO);
> + return SDValue(E, 0);
> + }
> + SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl, VTs, MemVT,
> Chain,
> + Ptr, MMO, Ordering,
> SynchScope);
> + CSEMap.InsertNode(N, IP);
> + AllNodes.push_back(N);
> + return SDValue(N, 0);
> +}
> +
> /// getMergeValues - Create a MERGE_VALUES node from the given operands.
> SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps,
> DebugLoc dl) {
> @@ -5795,6 +5848,8 @@
> case ISD::ATOMIC_LOAD_MAX: return "AtomicLoadMax";
> case ISD::ATOMIC_LOAD_UMIN: return "AtomicLoadUMin";
> case ISD::ATOMIC_LOAD_UMAX: return "AtomicLoadUMax";
> + case ISD::ATOMIC_LOAD: return "AtomicLoad";
> + case ISD::ATOMIC_STORE: return "AtomicStore";
> case ISD::PCMARKER: return "PCMarker";
> case ISD::READCYCLECOUNTER: return "ReadCycleCounter";
> case ISD::SRCVALUE: return "SrcValue";
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Aug 24
> 15:50:09 2011
> @@ -3149,6 +3149,9 @@
> }
>
> void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
> + if (I.isAtomic())
> + return visitAtomicLoad(I);
> +
> const Value *SV = I.getOperand(0);
> SDValue Ptr = getValue(SV);
>
> @@ -3226,6 +3229,9 @@
> }
>
> void SelectionDAGBuilder::visitStore(const StoreInst &I) {
> + if (I.isAtomic())
> + return visitAtomicStore(I);
> +
> const Value *SrcV = I.getOperand(0);
> const Value *PtrV = I.getOperand(1);
>
> @@ -3277,6 +3283,7 @@
> }
>
> static SDValue InsertFenceForAtomic(SDValue Chain, AtomicOrdering Order,
> + SynchronizationScope Scope,
> bool Before, DebugLoc dl,
> SelectionDAG &DAG,
> const TargetLowering &TLI) {
> @@ -3294,19 +3301,21 @@
> }
> SDValue Ops[3];
> Ops[0] = Chain;
> - Ops[1] = DAG.getConstant(SequentiallyConsistent, TLI.getPointerTy());
> - Ops[2] = DAG.getConstant(Order, TLI.getPointerTy());
> + Ops[1] = DAG.getConstant(Order, TLI.getPointerTy());
> + Ops[2] = DAG.getConstant(Scope, TLI.getPointerTy());
> return DAG.getNode(ISD::ATOMIC_FENCE, dl, MVT::Other, Ops, 3);
> }
>
> void SelectionDAGBuilder::visitAtomicCmpXchg(const AtomicCmpXchgInst &I) {
> DebugLoc dl = getCurDebugLoc();
> AtomicOrdering Order = I.getOrdering();
> + SynchronizationScope Scope = I.getSynchScope();
>
> SDValue InChain = getRoot();
>
> if (TLI.getInsertFencesForAtomic())
> - InChain = InsertFenceForAtomic(InChain, Order, true, dl, DAG, TLI);
> + InChain = InsertFenceForAtomic(InChain, Order, Scope, true, dl,
> + DAG, TLI);
>
> SDValue L =
> DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, dl,
> @@ -3316,12 +3325,14 @@
> getValue(I.getCompareOperand()),
> getValue(I.getNewValOperand()),
> MachinePointerInfo(I.getPointerOperand()), 0 /* Alignment
> */,
> - I.getOrdering(), I.getSynchScope());
> + TLI.getInsertFencesForAtomic() ? Monotonic : Order,
> + Scope);
>
> SDValue OutChain = L.getValue(1);
>
> if (TLI.getInsertFencesForAtomic())
> - OutChain = InsertFenceForAtomic(OutChain, Order, false, dl, DAG, TLI);
> + OutChain = InsertFenceForAtomic(OutChain, Order, Scope, false, dl,
> + DAG, TLI);
>
> setValue(&I, L);
> DAG.setRoot(OutChain);
> @@ -3345,11 +3356,13 @@
> case AtomicRMWInst::UMin: NT = ISD::ATOMIC_LOAD_UMIN; break;
> }
> AtomicOrdering Order = I.getOrdering();
> + SynchronizationScope Scope = I.getSynchScope();
>
> SDValue InChain = getRoot();
>
> if (TLI.getInsertFencesForAtomic())
> - InChain = InsertFenceForAtomic(InChain, Order, true, dl, DAG, TLI);
> + InChain = InsertFenceForAtomic(InChain, Order, Scope, true, dl,
> + DAG, TLI);
>
> SDValue L =
> DAG.getAtomic(NT, dl,
> @@ -3359,12 +3372,13 @@
> getValue(I.getValOperand()),
> I.getPointerOperand(), 0 /* Alignment */,
> TLI.getInsertFencesForAtomic() ? Monotonic : Order,
> - I.getSynchScope());
> + Scope);
>
> SDValue OutChain = L.getValue(1);
>
> if (TLI.getInsertFencesForAtomic())
> - OutChain = InsertFenceForAtomic(OutChain, Order, false, dl, DAG, TLI);
> + OutChain = InsertFenceForAtomic(OutChain, Order, Scope, false, dl,
> + DAG, TLI);
>
> setValue(&I, L);
> DAG.setRoot(OutChain);
> @@ -3379,6 +3393,65 @@
> DAG.setRoot(DAG.getNode(ISD::ATOMIC_FENCE, dl, MVT::Other, Ops, 3));
> }
>
> +void SelectionDAGBuilder::visitAtomicLoad(const LoadInst &I) {
> + DebugLoc dl = getCurDebugLoc();
> + AtomicOrdering Order = I.getOrdering();
> + SynchronizationScope Scope = I.getSynchScope();
> +
> + SDValue InChain = getRoot();
> +
> + if (TLI.getInsertFencesForAtomic())
> + InChain = InsertFenceForAtomic(InChain, Order, Scope, true, dl,
> + DAG, TLI);
> +
> + EVT VT = EVT::getEVT(I.getType());
> +
> + SDValue L =
> + DAG.getAtomic(ISD::ATOMIC_LOAD, dl, VT, VT, InChain,
> + getValue(I.getPointerOperand()),
> + I.getPointerOperand(), I.getAlignment(),
> + TLI.getInsertFencesForAtomic() ? Monotonic : Order,
> + Scope);
> +
> + SDValue OutChain = L.getValue(1);
> +
> + if (TLI.getInsertFencesForAtomic())
> + OutChain = InsertFenceForAtomic(OutChain, Order, Scope, false, dl,
> + DAG, TLI);
> +
> + setValue(&I, L);
> + DAG.setRoot(OutChain);
> +}
> +
> +void SelectionDAGBuilder::visitAtomicStore(const StoreInst &I) {
> + DebugLoc dl = getCurDebugLoc();
> +
> + AtomicOrdering Order = I.getOrdering();
> + SynchronizationScope Scope = I.getSynchScope();
> +
> + SDValue InChain = getRoot();
> +
> + if (TLI.getInsertFencesForAtomic())
> + InChain = InsertFenceForAtomic(InChain, Order, Scope, true, dl,
> + DAG, TLI);
> +
> + SDValue OutChain =
> + DAG.getAtomic(ISD::ATOMIC_STORE, dl,
> +
> getValue(I.getValueOperand()).getValueType().getSimpleVT(),
> + InChain,
> + getValue(I.getPointerOperand()),
> + getValue(I.getValueOperand()),
> + I.getPointerOperand(), I.getAlignment(),
> + TLI.getInsertFencesForAtomic() ? Monotonic : Order,
> + Scope);
> +
> + if (TLI.getInsertFencesForAtomic())
> + OutChain = InsertFenceForAtomic(OutChain, Order, Scope, false, dl,
> + DAG, TLI);
> +
> + DAG.setRoot(OutChain);
> +}
> +
> /// visitTargetIntrinsic - Lower a call of a target intrinsic to an
> INTRINSIC
> /// node.
> void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Wed Aug 24
> 15:50:09 2011
> @@ -526,7 +526,9 @@
> void visitPHI(const PHINode &I);
> void visitCall(const CallInst &I);
> bool visitMemCmpCall(const CallInst &I);
> -
> + void visitAtomicLoad(const LoadInst &I);
> + void visitAtomicStore(const StoreInst &I);
> +
> void visitInlineAsm(ImmutableCallSite CS);
> const char *visitIntrinsicCall(const CallInst &I, unsigned Intrinsic);
> void visitTargetIntrinsic(const CallInst &I, unsigned Intrinsic);
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Aug 24 15:50:09 2011
> @@ -464,6 +464,7 @@
> MVT VT = IntVTs[i];
> setOperationAction(ISD::ATOMIC_CMP_SWAP, VT, Custom);
> setOperationAction(ISD::ATOMIC_LOAD_SUB, VT, Custom);
> + setOperationAction(ISD::ATOMIC_STORE, VT, Custom);
> }
>
> if (!Subtarget->is64Bit()) {
> @@ -9999,6 +10000,26 @@
> cast<AtomicSDNode>(Node)->getSynchScope());
> }
>
> +static SDValue LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) {
> + SDNode *Node = Op.getNode();
> + DebugLoc dl = Node->getDebugLoc();
> +
> + // Convert seq_cst store -> xchg
> + if (cast<AtomicSDNode>(Node)->getOrdering() == SequentiallyConsistent) {
> + SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl,
> + cast<AtomicSDNode>(Node)->getMemoryVT(),
> + Node->getOperand(0),
> + Node->getOperand(1),
> Node->getOperand(2),
> +
> cast<AtomicSDNode>(Node)->getSrcValue(),
> +
> cast<AtomicSDNode>(Node)->getAlignment(),
> +
> cast<AtomicSDNode>(Node)->getOrdering(),
> +
> cast<AtomicSDNode>(Node)->getSynchScope());
> + return Swap.getValue(1);
> + }
> + // Other atomic stores have a simple pattern.
> + return Op;
> +}
> +
> static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op, SelectionDAG &DAG) {
> EVT VT = Op.getNode()->getValueType(0);
>
> @@ -10035,6 +10056,7 @@
> case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op,DAG);
> case ISD::ATOMIC_CMP_SWAP: return LowerCMP_SWAP(Op,DAG);
> case ISD::ATOMIC_LOAD_SUB: return LowerLOAD_SUB(Op,DAG);
> + case ISD::ATOMIC_STORE: return LowerATOMIC_STORE(Op,DAG);
> case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
> case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
> case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
>
> Modified: llvm/trunk/lib/Target/X86/X86InstrCompiler.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrCompiler.td?rev=138478&r1=138477&r2=138478&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86InstrCompiler.td (original)
> +++ llvm/trunk/lib/Target/X86/X86InstrCompiler.td Wed Aug 24 15:50:09 2011
> @@ -1691,3 +1691,17 @@
> (AND64ri8 GR64:$src1, i64immSExt8:$src2)>;
> def : Pat<(and GR64:$src1, i64immSExt32:$src2),
> (AND64ri32 GR64:$src1, i64immSExt32:$src2)>;
> +
> +def : Pat<(atomic_load_8 addr:$src), (MOV8rm addr:$src)>;
> +def : Pat<(atomic_load_16 addr:$src), (MOV16rm addr:$src)>;
> +def : Pat<(atomic_load_32 addr:$src), (MOV32rm addr:$src)>;
> +def : Pat<(atomic_load_64 addr:$src), (MOV64rm addr:$src)>;
> +
> +def : Pat<(atomic_store_8 addr:$ptr, GR8:$val),
> + (MOV8mr addr:$ptr, GR8:$val)>;
> +def : Pat<(atomic_store_16 addr:$ptr, GR16:$val),
> + (MOV16mr addr:$ptr, GR16:$val)>;
> +def : Pat<(atomic_store_32 addr:$ptr, GR32:$val),
> + (MOV32mr addr:$ptr, GR32:$val)>;
> +def : Pat<(atomic_store_64 addr:$ptr, GR64:$val),
> + (MOV64mr addr:$ptr, GR64:$val)>;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20110824/1add7ec7/attachment.html>
More information about the llvm-commits
mailing list