forked from OSchip/llvm-project
[MIR] Add support for printing and parsing target MMO flags
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
This commit is contained in:
parent
02d34adfd8
commit
6748abe24d
|
@ -114,6 +114,9 @@ public:
|
|||
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,
|
||||
|
|
|
@ -1545,6 +1545,16 @@ public:
|
|||
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."
|
||||
|
|
|
@ -169,7 +169,8 @@ public:
|
|||
|
||||
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; }
|
||||
|
|
|
@ -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,
|
||||
|
@ -320,6 +322,14 @@ private:
|
|||
/// 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);
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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");
|
||||
|
|
|
@ -165,7 +165,8 @@ public:
|
|||
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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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)";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -289,6 +289,8 @@ public:
|
|||
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,
|
||||
|
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
...
|
Loading…
Reference in New Issue