From: Tim Northover Date: Mon, 13 Feb 2017 22:14:08 +0000 (+0000) Subject: MIR: parse & print the atomic parts of a MachineMemOperand. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1a3fe2bfe650d3cf8f1ae185b42ab459fd82c60a;p=llvm MIR: parse & print the atomic parts of a MachineMemOperand. 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 --- diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index e302de26d1f..5e268fb84c7 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -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(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; } diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index db87092177c..469844666ec 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -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 index 00000000000..1fe42a73148 --- /dev/null +++ b/test/CodeGen/MIR/AArch64/atomic-memoperands.mir @@ -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 +... diff --git a/test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation.mir b/test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation.mir index cfa03247e31..57e11d39723 100644 --- a/test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation.mir +++ b/test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation.mir @@ -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 ...