From 55ba816883842e793cdeb32fcb805c4e011b527f Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 29 Jul 2011 03:05:32 +0000 Subject: Misc optimizer+codegen work for 'cmpxchg' and 'atomicrmw'. They appear to be working on x86 (at least for trivial testcases); other architectures will need more work so that they actually emit the appropriate instructions for orderings stricter than 'monotonic'. (As far as I can tell, the ARM, PPC, Mips, and Alpha backends need such changes.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136457 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 43 ++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp') diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 498e1d3..7d45d29 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3257,9 +3257,46 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) { } void SelectionDAGBuilder::visitAtomicCmpXchg(const AtomicCmpXchgInst &I) { + SDValue Root = getRoot(); + SDValue L = + DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, getCurDebugLoc(), + getValue(I.getCompareOperand()).getValueType().getSimpleVT(), + Root, + getValue(I.getPointerOperand()), + getValue(I.getCompareOperand()), + getValue(I.getNewValOperand()), + MachinePointerInfo(I.getPointerOperand()), 0 /* Alignment */, + I.getOrdering(), I.getSynchScope()); + setValue(&I, L); + DAG.setRoot(L.getValue(1)); } void SelectionDAGBuilder::visitAtomicRMW(const AtomicRMWInst &I) { + ISD::NodeType NT; + switch (I.getOperation()) { + default: llvm_unreachable("Unknown atomicrmw operation"); return; + case AtomicRMWInst::Xchg: NT = ISD::ATOMIC_SWAP; break; + case AtomicRMWInst::Add: NT = ISD::ATOMIC_LOAD_ADD; break; + case AtomicRMWInst::Sub: NT = ISD::ATOMIC_LOAD_SUB; break; + case AtomicRMWInst::And: NT = ISD::ATOMIC_LOAD_AND; break; + case AtomicRMWInst::Nand: NT = ISD::ATOMIC_LOAD_NAND; break; + case AtomicRMWInst::Or: NT = ISD::ATOMIC_LOAD_OR; break; + case AtomicRMWInst::Xor: NT = ISD::ATOMIC_LOAD_XOR; break; + case AtomicRMWInst::Max: NT = ISD::ATOMIC_LOAD_MAX; break; + case AtomicRMWInst::Min: NT = ISD::ATOMIC_LOAD_MIN; break; + case AtomicRMWInst::UMax: NT = ISD::ATOMIC_LOAD_UMAX; break; + case AtomicRMWInst::UMin: NT = ISD::ATOMIC_LOAD_UMIN; break; + } + SDValue L = + DAG.getAtomic(NT, getCurDebugLoc(), + getValue(I.getValOperand()).getValueType().getSimpleVT(), + getRoot(), + getValue(I.getPointerOperand()), + getValue(I.getValOperand()), + I.getPointerOperand(), 0 /* Alignment */, + I.getOrdering(), I.getSynchScope()); + setValue(&I, L); + DAG.setRoot(L.getValue(1)); } void SelectionDAGBuilder::visitFence(const FenceInst &I) { @@ -3410,7 +3447,8 @@ SelectionDAGBuilder::implVisitBinaryAtomic(const CallInst& I, Root, getValue(I.getArgOperand(0)), getValue(I.getArgOperand(1)), - I.getArgOperand(0)); + I.getArgOperand(0), 0 /* Alignment */, + Monotonic, CrossThread); setValue(&I, L); DAG.setRoot(L.getValue(1)); return 0; @@ -4935,7 +4973,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { getValue(I.getArgOperand(0)), getValue(I.getArgOperand(1)), getValue(I.getArgOperand(2)), - MachinePointerInfo(I.getArgOperand(0))); + MachinePointerInfo(I.getArgOperand(0)), 0 /* Alignment */, + Monotonic, CrossThread); setValue(&I, L); DAG.setRoot(L.getValue(1)); return 0; -- cgit v1.1