Lower memory barriers to sync instructions.
authorAkira Hatanaka <ahatanak@gmail.com>
Tue, 19 Jul 2011 23:30:50 +0000 (23:30 +0000)
committerAkira Hatanaka <ahatanak@gmail.com>
Tue, 19 Jul 2011 23:30:50 +0000 (23:30 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135537 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsISelLowering.h
lib/Target/Mips/MipsInstrInfo.td
test/CodeGen/Mips/atomic.ll

index bb67cb9b8e4aecf09b7c11b79508dedba025ab7b..106d923eab1ce7bd3448d0c66dfc34f6c20899a2 100644 (file)
@@ -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
 //===----------------------------------------------------------------------===//
index bda26a229e72e1f0ecbeedcfcd30b98ce07a8982..e030435a898a1f0616f98e4dc8297152d1a1932f 100644 (file)
@@ -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,
index 72265d0f224ee8255cc397b5181b49aa38eb5281..57867b50920433e8143f90f3ab4b79ba5184a60d 100644 (file)
@@ -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),
index e110602aab3c32122e623ceac04b76d63de952fd..50bcc0915c268c87cdb521f0c638bf046f7e16ba 100644 (file)
@@ -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
+}
+