From db54826f20c6cbcb9b195c4b49c946d6488156dd Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 19 Jul 2011 23:30:50 +0000 Subject: [PATCH] Lower memory barriers to sync instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135537 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 13 ++++++++++++- lib/Target/Mips/MipsISelLowering.h | 5 ++++- lib/Target/Mips/MipsInstrInfo.td | 12 ++++++++++++ test/CodeGen/Mips/atomic.ll | 19 +++++++++++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index bb67cb9b8e4..106d923eab1 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -61,6 +61,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; case MipsISD::WrapperPIC: return "MipsISD::WrapperPIC"; case MipsISD::DynAlloc: return "MipsISD::DynAlloc"; + case MipsISD::Sync: return "MipsISD::Sync"; default: return NULL; } } @@ -159,7 +160,7 @@ MipsTargetLowering(MipsTargetMachine &TM) // Use the default for now setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); - setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); + setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom); if (Subtarget->isSingleFloat()) setOperationAction(ISD::SELECT_CC, MVT::f64, Expand); @@ -527,6 +528,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const case ISD::VASTART: return LowerVASTART(Op, DAG); case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); + case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG); } return SDValue(); } @@ -1525,6 +1527,15 @@ LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { return FrameAddr; } +// TODO: set SType according to the desired memory barrier behavior. +SDValue MipsTargetLowering::LowerMEMBARRIER(SDValue Op, + SelectionDAG& DAG) const { + unsigned SType = 0; + DebugLoc dl = Op.getDebugLoc(); + return DAG.getNode(MipsISD::Sync, dl, MVT::Other, Op.getOperand(0), + DAG.getConstant(SType, MVT::i32)); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index bda26a229e7..e030435a898 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -81,7 +81,9 @@ namespace llvm { WrapperPIC, - DynAlloc + DynAlloc, + + Sync }; } @@ -128,6 +130,7 @@ namespace llvm { SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const; virtual SDValue LowerFormalArguments(SDValue Chain, diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 72265d0f224..57867b50920 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -41,6 +41,7 @@ def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; def SDT_MipsDynAlloc : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, iPTR>]>; +def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; // Call def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, @@ -106,6 +107,8 @@ def MipsWrapperPIC : SDNode<"MipsISD::WrapperPIC", SDTIntUnaryOp>; def MipsDynAlloc : SDNode<"MipsISD::DynAlloc", SDT_MipsDynAlloc, [SDNPHasChain, SDNPInGlue]>; +def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // Mips Instruction Predicate Definitions. //===----------------------------------------------------------------------===// @@ -589,6 +592,15 @@ def SB : StoreM<0x28, "sb", truncstorei8>; def SH : StoreM<0x29, "sh", truncstorei16>; def SW : StoreM<0x2b, "sw", store>; +let hasSideEffects = 1 in +def SYNC : MipsInst<(outs), (ins i32imm:$stype), "sync $stype", + [(MipsSync imm:$stype)], NoItinerary> +{ + let opcode = 0; + let Inst{25-11} = 0; + let Inst{5-0} = 15; +} + /// Load-linked, Store-conditional let mayLoad = 1, hasDelaySlot = 1 in def LL : FI<0x30, (outs CPURegs:$dst), (ins mem:$addr), diff --git a/test/CodeGen/Mips/atomic.ll b/test/CodeGen/Mips/atomic.ll index e110602aab3..50bcc0915c2 100644 --- a/test/CodeGen/Mips/atomic.ll +++ b/test/CodeGen/Mips/atomic.ll @@ -12,6 +12,7 @@ declare i8 @llvm.atomic.load.nand.i8.p0i8(i8* nocapture, i8) nounwind declare i8 @llvm.atomic.swap.i8.p0i8(i8* nocapture, i8) nounwind declare i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* nocapture, i8, i8) nounwind +declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind @x = common global i32 0, align 4 @@ -239,3 +240,21 @@ entry: ; CHECK: sll $[[R17:[0-9]+]], $[[R16]], 24 ; CHECK: sra $2, $[[R17]], 24 } + +@countsint = common global i32 0, align 4 + +define i32 @CheckSync(i32 %v) nounwind noinline { +entry: + tail call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + %0 = tail call i32 @llvm.atomic.load.add.i32.p0i32(i32* @countsint, i32 %v) + tail call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + ret i32 %0 + +; CHECK: CheckSync: +; CHECK: sync 0 +; CHECK: ll +; CHECK: sc +; CHECK: beq +; CHECK: sync 0 +} +