From 32e8528c3368d5e0986cb265b436799cc490ea0c Mon Sep 17 00:00:00 2001 From: Robert Lytton Date: Tue, 12 Nov 2013 10:11:26 +0000 Subject: [PATCH] Add XCore support for ATOMIC_FENCE. ATOMIC_FENCE is lowered to a compiler barrier which is codegen only. There is no need to emit an instructions since the XCore provides sequential consistency. Original patch by Richard Osborne git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194464 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/XCore/XCoreISelLowering.cpp | 11 +++++++++++ lib/Target/XCore/XCoreISelLowering.h | 6 +++++- lib/Target/XCore/XCoreInstrInfo.td | 9 +++++++++ test/CodeGen/XCore/atomic.ll | 16 ++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/XCore/atomic.ll diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 489f0a7244c..149652ff733 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -59,6 +59,7 @@ getTargetNodeName(unsigned Opcode) const case XCoreISD::CRC8 : return "XCoreISD::CRC8"; case XCoreISD::BR_JT : return "XCoreISD::BR_JT"; case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32"; + case XCoreISD::MEMBARRIER : return "XCoreISD::MEMBARRIER"; default : return NULL; } } @@ -148,6 +149,9 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); + // Atomic operations + setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); + // TRAMPOLINE is custom lowered. setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom); setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom); @@ -206,6 +210,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG); case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); + case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG); default: llvm_unreachable("unimplemented operand"); } @@ -847,6 +852,12 @@ LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { return SDValue(); } +SDValue XCoreTargetLowering:: +LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const { + SDLoc DL(Op); + return DAG.getNode(XCoreISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0)); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h index 2a6c8748cd6..bc08497b12e 100644 --- a/lib/Target/XCore/XCoreISelLowering.h +++ b/lib/Target/XCore/XCoreISelLowering.h @@ -70,7 +70,10 @@ namespace llvm { BR_JT, // Jumptable branch using long branches for each entry. - BR_JT32 + BR_JT32, + + // Memory barrier. + MEMBARRIER }; } @@ -158,6 +161,7 @@ namespace llvm { SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; // Inline asm support std::pair diff --git a/lib/Target/XCore/XCoreInstrInfo.td b/lib/Target/XCore/XCoreInstrInfo.td index 81fa84d4e24..934a707e785 100644 --- a/lib/Target/XCore/XCoreInstrInfo.td +++ b/lib/Target/XCore/XCoreInstrInfo.td @@ -70,6 +70,11 @@ def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XCoreCallSeqStart, def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XCoreCallSeqEnd, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; +def SDT_XCoreMEMBARRIER : SDTypeProfile<0, 0, []>; + +def XCoreMemBarrier : SDNode<"XCoreISD::MEMBARRIER", SDT_XCoreMEMBARRIER, + [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // Instruction Pattern Stuff //===----------------------------------------------------------------------===// @@ -343,6 +348,10 @@ let usesCustomInserter = 1 in { (select GRRegs:$cond, GRRegs:$T, GRRegs:$F))]>; } +let hasSideEffects = 1 in +def Int_MemBarrier : PseudoInstXCore<(outs), (ins), "#MEMBARRIER", + [(XCoreMemBarrier)]>; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// diff --git a/test/CodeGen/XCore/atomic.ll b/test/CodeGen/XCore/atomic.ll new file mode 100644 index 00000000000..95fca9ac5b2 --- /dev/null +++ b/test/CodeGen/XCore/atomic.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -march=xcore | FileCheck %s + +; CHECK-LABEL: atomic_fence +; CHECK: #MEMBARRIER +; CHECK: #MEMBARRIER +; CHECK: #MEMBARRIER +; CHECK: #MEMBARRIER +; CHECK: retsp 0 +define void @atomic_fence() nounwind { +entry: + fence acquire + fence release + fence acq_rel + fence seq_cst + ret void +}