Skip to content

Commit

Permalink
[MIR] Add support for printing and parsing target MMO flags
Browse files Browse the repository at this point in the history
Summary: Add target hooks for printing and parsing target MMO flags.
Targets may override getSerializableMachineMemOperandTargetFlags() to
return a mapping from string to flag value for target MMO values that
should be serialized/parsed in MIR output.

Add implementation of this hook for AArch64 SuppressPair MMO flag.

Reviewers: bogner, hfinkel, qcolombet, MatzeB

Subscribers: mcrosier, javed.absar, llvm-commits

Differential Revision: https://reviews.llvm.org/D34962

llvm-svn: 307877
  • Loading branch information
geoffberry committed Jul 13, 2017
1 parent 02d34ad commit 6748abe
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 6 deletions.
3 changes: 3 additions & 0 deletions llvm/include/llvm/CodeGen/MachineMemOperand.h
Expand Up @@ -114,6 +114,9 @@ class MachineMemOperand {
MOInvariant = 1u << 5,

// Reserved for use by target-specific passes.
// Targets may override getSerializableMachineMemOperandTargetFlags() to
// enable MIR serialization/parsing of these flags. If more of these flags
// are added, the MIR printing/parsing code will need to be updated as well.
MOTargetFlag1 = 1u << 6,
MOTargetFlag2 = 1u << 7,
MOTargetFlag3 = 1u << 8,
Expand Down
10 changes: 10 additions & 0 deletions llvm/include/llvm/Target/TargetInstrInfo.h
Expand Up @@ -1545,6 +1545,16 @@ class TargetInstrInfo : public MCInstrInfo {
return None;
}

/// Return an array that contains the MMO target flag values and their
/// names.
///
/// MIR Serialization is able to serialize only the MMO target flags that are
/// defined by this method.
virtual ArrayRef<std::pair<MachineMemOperand::Flags, const char *>>
getSerializableMachineMemOperandTargetFlags() const {
return None;
}

/// Determines whether \p Inst is a tail call instruction. Override this
/// method on targets that do not properly set MCID::Return and MCID::Call on
/// tail call instructions."
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/MIRParser/MILexer.h
Expand Up @@ -169,7 +169,8 @@ struct MIToken {

bool isMemoryOperandFlag() const {
return Kind == kw_volatile || Kind == kw_non_temporal ||
Kind == kw_dereferenceable || Kind == kw_invariant;
Kind == kw_dereferenceable || Kind == kw_invariant ||
Kind == StringConstant;
}

bool is(TokenKind K) const { return Kind == K; }
Expand Down
40 changes: 39 additions & 1 deletion llvm/lib/CodeGen/MIRParser/MIParser.cpp
Expand Up @@ -141,6 +141,8 @@ class MIParser {
StringMap<unsigned> Names2DirectTargetFlags;
/// Maps from direct target flag names to the bitmask target flag values.
StringMap<unsigned> Names2BitmaskTargetFlags;
/// Maps from MMO target flag names to MMO target flag values.
StringMap<MachineMemOperand::Flags> Names2MMOTargetFlags;

public:
MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
Expand Down Expand Up @@ -320,6 +322,14 @@ class MIParser {
/// Return true if the name isn't a name of a bitmask target flag.
bool getBitmaskTargetFlag(StringRef Name, unsigned &Flag);

void initNames2MMOTargetFlags();

/// Try to convert a name of a MachineMemOperand target flag to the
/// corresponding target flag.
///
/// Return true if the name isn't a name of a target MMO flag.
bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag);

/// parseStringConstant
/// ::= StringConstant
bool parseStringConstant(std::string &Result);
Expand Down Expand Up @@ -2039,7 +2049,14 @@ bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) {
case MIToken::kw_invariant:
Flags |= MachineMemOperand::MOInvariant;
break;
// TODO: parse the target specific memory operand flags.
case MIToken::StringConstant: {
MachineMemOperand::Flags TF;
if (getMMOTargetFlag(Token.stringValue(), TF))
return error("use of undefined target MMO flag '" + Token.stringValue() +
"'");
Flags |= TF;
break;
}
default:
llvm_unreachable("The current token should be a memory operand flag");
}
Expand Down Expand Up @@ -2480,6 +2497,27 @@ bool MIParser::getBitmaskTargetFlag(StringRef Name, unsigned &Flag) {
return false;
}

void MIParser::initNames2MMOTargetFlags() {
if (!Names2MMOTargetFlags.empty())
return;
const auto *TII = MF.getSubtarget().getInstrInfo();
assert(TII && "Expected target instruction info");
auto Flags = TII->getSerializableMachineMemOperandTargetFlags();
for (const auto &I : Flags)
Names2MMOTargetFlags.insert(
std::make_pair(StringRef(I.second), I.first));
}

bool MIParser::getMMOTargetFlag(StringRef Name,
MachineMemOperand::Flags &Flag) {
initNames2MMOTargetFlags();
auto FlagInfo = Names2MMOTargetFlags.find(Name);
if (FlagInfo == Names2MMOTargetFlags.end())
return true;
Flag = FlagInfo->second;
return false;
}

bool MIParser::parseStringConstant(std::string &Result) {
if (Token.isNot(MIToken::StringConstant))
return error("expected string constant");
Expand Down
29 changes: 25 additions & 4 deletions llvm/lib/CodeGen/MIRPrinter.cpp
Expand Up @@ -165,7 +165,8 @@ class MIPrinter {
void print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
unsigned I, bool ShouldPrintRegisterTies,
LLT TypeToPrint, bool IsDef = false);
void print(const LLVMContext &Context, const MachineMemOperand &Op);
void print(const LLVMContext &Context, const TargetInstrInfo &TII,
const MachineMemOperand &Op);
void printSyncScope(const LLVMContext &Context, SyncScope::ID SSID);

void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
Expand Down Expand Up @@ -740,7 +741,7 @@ void MIPrinter::print(const MachineInstr &MI) {
for (const auto *Op : MI.memoperands()) {
if (NeedComma)
OS << ", ";
print(Context, *Op);
print(Context, *TII, *Op);
NeedComma = true;
}
}
Expand Down Expand Up @@ -1036,9 +1037,20 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
}
}

void MIPrinter::print(const LLVMContext &Context, const MachineMemOperand &Op) {
static const char *getTargetMMOFlagName(const TargetInstrInfo &TII,
unsigned TMMOFlag) {
auto Flags = TII.getSerializableMachineMemOperandTargetFlags();
for (const auto &I : Flags) {
if (I.first == TMMOFlag) {
return I.second;
}
}
return nullptr;
}

void MIPrinter::print(const LLVMContext &Context, const TargetInstrInfo &TII,
const MachineMemOperand &Op) {
OS << '(';
// TODO: Print operand's target specific flags.
if (Op.isVolatile())
OS << "volatile ";
if (Op.isNonTemporal())
Expand All @@ -1047,6 +1059,15 @@ void MIPrinter::print(const LLVMContext &Context, const MachineMemOperand &Op) {
OS << "dereferenceable ";
if (Op.isInvariant())
OS << "invariant ";
if (Op.getFlags() & MachineMemOperand::MOTargetFlag1)
OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag1)
<< "\" ";
if (Op.getFlags() & MachineMemOperand::MOTargetFlag2)
OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag2)
<< "\" ";
if (Op.getFlags() & MachineMemOperand::MOTargetFlag3)
OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag3)
<< "\" ";
if (Op.isLoad())
OS << "load ";
else {
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/CodeGen/MachineInstr.cpp
Expand Up @@ -752,6 +752,12 @@ void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const {
OS << "(dereferenceable)";
if (isInvariant())
OS << "(invariant)";
if (getFlags() & MOTargetFlag1)
OS << "(flag1)";
if (getFlags() & MOTargetFlag2)
OS << "(flag2)";
if (getFlags() & MOTargetFlag3)
OS << "(flag3)";
}

//===----------------------------------------------------------------------===//
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
Expand Up @@ -4430,6 +4430,13 @@ AArch64InstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
return makeArrayRef(TargetFlags);
}

ArrayRef<std::pair<MachineMemOperand::Flags, const char *>>
AArch64InstrInfo::getSerializableMachineMemOperandTargetFlags() const {
static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
{{MOSuppressPair, "aarch64-suppress-pair"}};
return makeArrayRef(TargetFlags);
}

unsigned AArch64InstrInfo::getOutliningBenefit(size_t SequenceSize,
size_t Occurrences,
bool CanBeTailCall) const {
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.h
Expand Up @@ -289,6 +289,8 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
getSerializableDirectMachineOperandTargetFlags() const override;
ArrayRef<std::pair<unsigned, const char *>>
getSerializableBitmaskMachineOperandTargetFlags() const override;
ArrayRef<std::pair<MachineMemOperand::Flags, const char *>>
getSerializableMachineMemOperandTargetFlags() const override;

bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const override;
unsigned getOutliningBenefit(size_t SequenceSize, size_t Occurrences,
Expand Down
19 changes: 19 additions & 0 deletions llvm/test/CodeGen/MIR/AArch64/invalid-target-memoperands.mir
@@ -0,0 +1,19 @@
# RUN: not llc -mtriple=aarch64-none-linux-gnu -run-pass none -o /dev/null %s 2>&1 | FileCheck %s

--- |

define void @target_memoperands_error() {
ret void
}

...
---
name: target_memoperands_error
body: |
bb.0:
%0:_(p0) = COPY %x0
; CHECK: [[@LINE+1]]:35: use of undefined target MMO flag 'aarch64-invalid'
%1:_(s64) = G_LOAD %0(p0) :: ("aarch64-invalid" load 8)
RET_ReallyLR
...
22 changes: 22 additions & 0 deletions llvm/test/CodeGen/MIR/AArch64/target-memoperands.mir
@@ -0,0 +1,22 @@
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -o - %s | FileCheck %s

--- |

define void @target_memoperands() {
ret void
}

...
---
# CHECK-LABEL: name: target_memoperands
# CHECK: %1(s64) = G_LOAD %0(p0) :: ("aarch64-suppress-pair" load 8)
# CHECK: G_STORE %1(s64), %0(p0) :: ("aarch64-suppress-pair" store 8)
name: target_memoperands
body: |
bb.0:
%0:_(p0) = COPY %x0
%1:_(s64) = G_LOAD %0(p0) :: ("aarch64-suppress-pair" load 8)
G_STORE %1(s64), %0(p0) :: ("aarch64-suppress-pair" store 8)
RET_ReallyLR
...

0 comments on commit 6748abe

Please sign in to comment.