]> granicus.if.org Git - llvm/commitdiff
MIR: parse & print the atomic parts of a MachineMemOperand.
authorTim Northover <tnorthover@apple.com>
Mon, 13 Feb 2017 22:14:08 +0000 (22:14 +0000)
committerTim Northover <tnorthover@apple.com>
Mon, 13 Feb 2017 22:14:08 +0000 (22:14 +0000)
We're going to need them very soon for GlobalISel.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294992 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MIRParser/MIParser.cpp
lib/CodeGen/MIRPrinter.cpp
test/CodeGen/MIR/AArch64/atomic-memoperands.mir [new file with mode: 0644]
test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation.mir

index e302de26d1fb7897c29e09df76cbdab4a81d594c..5e268fb84c7b04582ac5972d59ccb82efcc5557f 100644 (file)
@@ -188,6 +188,7 @@ public:
   bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags);
   bool parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV);
   bool parseMachinePointerInfo(MachinePointerInfo &Dest);
+  bool parseOptionalAtomicOrdering(AtomicOrdering &Order);
   bool parseMachineMemoryOperand(MachineMemOperand *&Dest);
 
 private:
@@ -2040,6 +2041,28 @@ bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) {
   return false;
 }
 
+bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) {
+  Order = AtomicOrdering::NotAtomic;
+  if (Token.isNot(MIToken::Identifier))
+    return false;
+
+  Order = StringSwitch<AtomicOrdering>(Token.stringValue())
+              .Case("unordered", AtomicOrdering::Unordered)
+              .Case("monotonic", AtomicOrdering::Monotonic)
+              .Case("acquire", AtomicOrdering::Acquire)
+              .Case("release", AtomicOrdering::Release)
+              .Case("acq_rel", AtomicOrdering::AcquireRelease)
+              .Case("seq_cst", AtomicOrdering::SequentiallyConsistent)
+              .Default(AtomicOrdering::NotAtomic);
+
+  if (Order != AtomicOrdering::NotAtomic) {
+    lex();
+    return false;
+  }
+
+  return error("expected an atomic scope, ordering or a size integer literal");
+}
+
 bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
   if (expectAndConsume(MIToken::lparen))
     return true;
@@ -2057,6 +2080,21 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
     Flags |= MachineMemOperand::MOStore;
   lex();
 
+  // Optional "singlethread" scope.
+  SynchronizationScope Scope = SynchronizationScope::CrossThread;
+  if (Token.is(MIToken::Identifier) && Token.stringValue() == "singlethread") {
+    Scope = SynchronizationScope::SingleThread;
+    lex();
+  }
+
+  // Up to two atomic orderings (cmpxchg provides guarantees on failure).
+  AtomicOrdering Order, FailureOrder;
+  if (parseOptionalAtomicOrdering(Order))
+    return true;
+
+  if (parseOptionalAtomicOrdering(FailureOrder))
+    return true;
+
   if (Token.isNot(MIToken::IntegerLiteral))
     return error("expected the size integer literal after memory operation");
   uint64_t Size;
@@ -2111,8 +2149,8 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
   }
   if (expectAndConsume(MIToken::rparen))
     return true;
-  Dest =
-      MF.getMachineMemOperand(Ptr, Flags, Size, BaseAlignment, AAInfo, Range);
+  Dest = MF.getMachineMemOperand(Ptr, Flags, Size, BaseAlignment, AAInfo, Range,
+                                 Scope, Order, FailureOrder);
   return false;
 }
 
index db87092177cad9a1bd0164a63ca3596ded81f9a7..469844666ec1f20632d7dbb33badc46771d19d34 100644 (file)
@@ -926,6 +926,15 @@ void MIPrinter::print(const MachineMemOperand &Op) {
     assert(Op.isStore() && "Non load machine operand must be a store");
     OS << "store ";
   }
+
+  if (Op.getSynchScope() == SynchronizationScope::SingleThread)
+    OS << "singlethread ";
+
+  if (Op.getOrdering() != AtomicOrdering::NotAtomic)
+    OS << toIRString(Op.getOrdering()) << ' ';
+  if (Op.getFailureOrdering() != AtomicOrdering::NotAtomic)
+    OS << toIRString(Op.getFailureOrdering()) << ' ';
+
   OS << Op.getSize();
   if (const Value *Val = Op.getValue()) {
     OS << (Op.isLoad() ? " from " : " into ");
diff --git a/test/CodeGen/MIR/AArch64/atomic-memoperands.mir b/test/CodeGen/MIR/AArch64/atomic-memoperands.mir
new file mode 100644 (file)
index 0000000..1fe42a7
--- /dev/null
@@ -0,0 +1,30 @@
+# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -o - %s | FileCheck %s
+
+--- |
+
+  define void @atomic_memoperands() {
+    ret void
+  }
+
+...
+---
+# CHECK-LABEL: name: atomic_memoperands
+# CHECK: %1(s64) = G_LOAD %0(p0) :: (load unordered 8)
+# CHECK: %2(s32) = G_LOAD %0(p0) :: (load monotonic 4)
+# CHECK: %3(s16) = G_LOAD %0(p0) :: (load acquire 2)
+# CHECK: G_STORE %3(s16), %0(p0) :: (store release 2)
+# CHECK: G_STORE %2(s32), %0(p0) :: (store acq_rel 4)
+# CHECK: G_STORE %1(s64), %0(p0) :: (store singlethread seq_cst 8)
+name:            atomic_memoperands
+body: |
+  bb.0:
+
+    %0:_(p0) = COPY %x0
+    %1:_(s64) = G_LOAD %0(p0) :: (load unordered 8)
+    %2:_(s32) = G_LOAD %0(p0) :: (load monotonic 4)
+    %3:_(s16) = G_LOAD %0(p0) :: (load acquire 2)
+    G_STORE %3(s16), %0(p0) :: (store release 2)
+    G_STORE %2(s32), %0(p0) :: (store acq_rel 4)
+    G_STORE %1(s64), %0(p0) :: (store singlethread seq_cst 8)
+    RET_ReallyLR
+...
index cfa03247e31f8105502641e2364bc400e4b277e0..57e11d39723a1ff606badbc172287c26d613eab1 100644 (file)
@@ -17,7 +17,7 @@ liveins:
 body: |
   bb.0.entry:
     liveins: %rdi
-  ; CHECK: [[@LINE+1]]:53: expected the size integer literal after memory operation
+  ; CHECK: [[@LINE+1]]:53: expected an atomic scope, ordering or a size integer literal
     %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (load from %ir.a)
     RETQ %eax
 ...