llvm.org GIT mirror llvm / 9bf66c7
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307877 91177308-0d34-0410-b5e6-96231b3b80d8 Geoff Berry 3 years ago
10 changed file(s) with 135 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
113113 MOInvariant = 1u << 5,
114114
115115 // Reserved for use by target-specific passes.
116 // Targets may override getSerializableMachineMemOperandTargetFlags() to
117 // enable MIR serialization/parsing of these flags. If more of these flags
118 // are added, the MIR printing/parsing code will need to be updated as well.
116119 MOTargetFlag1 = 1u << 6,
117120 MOTargetFlag2 = 1u << 7,
118121 MOTargetFlag3 = 1u << 8,
15441544 return None;
15451545 }
15461546
1547 /// Return an array that contains the MMO target flag values and their
1548 /// names.
1549 ///
1550 /// MIR Serialization is able to serialize only the MMO target flags that are
1551 /// defined by this method.
1552 virtual ArrayRef>
1553 getSerializableMachineMemOperandTargetFlags() const {
1554 return None;
1555 }
1556
15471557 /// Determines whether \p Inst is a tail call instruction. Override this
15481558 /// method on targets that do not properly set MCID::Return and MCID::Call on
15491559 /// tail call instructions."
168168
169169 bool isMemoryOperandFlag() const {
170170 return Kind == kw_volatile || Kind == kw_non_temporal ||
171 Kind == kw_dereferenceable || Kind == kw_invariant;
171 Kind == kw_dereferenceable || Kind == kw_invariant ||
172 Kind == StringConstant;
172173 }
173174
174175 bool is(TokenKind K) const { return Kind == K; }
140140 StringMap Names2DirectTargetFlags;
141141 /// Maps from direct target flag names to the bitmask target flag values.
142142 StringMap Names2BitmaskTargetFlags;
143 /// Maps from MMO target flag names to MMO target flag values.
144 StringMap Names2MMOTargetFlags;
143145
144146 public:
145147 MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
318320 ///
319321 /// Return true if the name isn't a name of a bitmask target flag.
320322 bool getBitmaskTargetFlag(StringRef Name, unsigned &Flag);
323
324 void initNames2MMOTargetFlags();
325
326 /// Try to convert a name of a MachineMemOperand target flag to the
327 /// corresponding target flag.
328 ///
329 /// Return true if the name isn't a name of a target MMO flag.
330 bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag);
321331
322332 /// parseStringConstant
323333 /// ::= StringConstant
20382048 case MIToken::kw_invariant:
20392049 Flags |= MachineMemOperand::MOInvariant;
20402050 break;
2041 // TODO: parse the target specific memory operand flags.
2051 case MIToken::StringConstant: {
2052 MachineMemOperand::Flags TF;
2053 if (getMMOTargetFlag(Token.stringValue(), TF))
2054 return error("use of undefined target MMO flag '" + Token.stringValue() +
2055 "'");
2056 Flags |= TF;
2057 break;
2058 }
20422059 default:
20432060 llvm_unreachable("The current token should be a memory operand flag");
20442061 }
24792496 return false;
24802497 }
24812498
2499 void MIParser::initNames2MMOTargetFlags() {
2500 if (!Names2MMOTargetFlags.empty())
2501 return;
2502 const auto *TII = MF.getSubtarget().getInstrInfo();
2503 assert(TII && "Expected target instruction info");
2504 auto Flags = TII->getSerializableMachineMemOperandTargetFlags();
2505 for (const auto &I : Flags)
2506 Names2MMOTargetFlags.insert(
2507 std::make_pair(StringRef(I.second), I.first));
2508 }
2509
2510 bool MIParser::getMMOTargetFlag(StringRef Name,
2511 MachineMemOperand::Flags &Flag) {
2512 initNames2MMOTargetFlags();
2513 auto FlagInfo = Names2MMOTargetFlags.find(Name);
2514 if (FlagInfo == Names2MMOTargetFlags.end())
2515 return true;
2516 Flag = FlagInfo->second;
2517 return false;
2518 }
2519
24822520 bool MIParser::parseStringConstant(std::string &Result) {
24832521 if (Token.isNot(MIToken::StringConstant))
24842522 return error("expected string constant");
164164 void print(const MachineOperand &Op, const TargetRegisterInfo *TRI,
165165 unsigned I, bool ShouldPrintRegisterTies,
166166 LLT TypeToPrint, bool IsDef = false);
167 void print(const LLVMContext &Context, const MachineMemOperand &Op);
167 void print(const LLVMContext &Context, const TargetInstrInfo &TII,
168 const MachineMemOperand &Op);
168169 void printSyncScope(const LLVMContext &Context, SyncScope::ID SSID);
169170
170171 void print(const MCCFIInstruction &CFI, const TargetRegisterInfo *TRI);
739740 for (const auto *Op : MI.memoperands()) {
740741 if (NeedComma)
741742 OS << ", ";
742 print(Context, *Op);
743 print(Context, *TII, *Op);
743744 NeedComma = true;
744745 }
745746 }
10351036 }
10361037 }
10371038
1038 void MIPrinter::print(const LLVMContext &Context, const MachineMemOperand &Op) {
1039 static const char *getTargetMMOFlagName(const TargetInstrInfo &TII,
1040 unsigned TMMOFlag) {
1041 auto Flags = TII.getSerializableMachineMemOperandTargetFlags();
1042 for (const auto &I : Flags) {
1043 if (I.first == TMMOFlag) {
1044 return I.second;
1045 }
1046 }
1047 return nullptr;
1048 }
1049
1050 void MIPrinter::print(const LLVMContext &Context, const TargetInstrInfo &TII,
1051 const MachineMemOperand &Op) {
10391052 OS << '(';
1040 // TODO: Print operand's target specific flags.
10411053 if (Op.isVolatile())
10421054 OS << "volatile ";
10431055 if (Op.isNonTemporal())
10461058 OS << "dereferenceable ";
10471059 if (Op.isInvariant())
10481060 OS << "invariant ";
1061 if (Op.getFlags() & MachineMemOperand::MOTargetFlag1)
1062 OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag1)
1063 << "\" ";
1064 if (Op.getFlags() & MachineMemOperand::MOTargetFlag2)
1065 OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag2)
1066 << "\" ";
1067 if (Op.getFlags() & MachineMemOperand::MOTargetFlag3)
1068 OS << '"' << getTargetMMOFlagName(TII, MachineMemOperand::MOTargetFlag3)
1069 << "\" ";
10491070 if (Op.isLoad())
10501071 OS << "load ";
10511072 else {
751751 OS << "(dereferenceable)";
752752 if (isInvariant())
753753 OS << "(invariant)";
754 if (getFlags() & MOTargetFlag1)
755 OS << "(flag1)";
756 if (getFlags() & MOTargetFlag2)
757 OS << "(flag2)";
758 if (getFlags() & MOTargetFlag3)
759 OS << "(flag3)";
754760 }
755761
756762 //===----------------------------------------------------------------------===//
44294429 return makeArrayRef(TargetFlags);
44304430 }
44314431
4432 ArrayRef>
4433 AArch64InstrInfo::getSerializableMachineMemOperandTargetFlags() const {
4434 static const std::pair TargetFlags[] =
4435 {{MOSuppressPair, "aarch64-suppress-pair"}};
4436 return makeArrayRef(TargetFlags);
4437 }
4438
44324439 unsigned AArch64InstrInfo::getOutliningBenefit(size_t SequenceSize,
44334440 size_t Occurrences,
44344441 bool CanBeTailCall) const {
288288 getSerializableDirectMachineOperandTargetFlags() const override;
289289 ArrayRef>
290290 getSerializableBitmaskMachineOperandTargetFlags() const override;
291 ArrayRef>
292 getSerializableMachineMemOperandTargetFlags() const override;
291293
292294 bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const override;
293295 unsigned getOutliningBenefit(size_t SequenceSize, size_t Occurrences,
0 # RUN: not llc -mtriple=aarch64-none-linux-gnu -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
1
2 --- |
3
4 define void @target_memoperands_error() {
5 ret void
6 }
7
8 ...
9 ---
10 name: target_memoperands_error
11 body: |
12 bb.0:
13
14 %0:_(p0) = COPY %x0
15 ; CHECK: [[@LINE+1]]:35: use of undefined target MMO flag 'aarch64-invalid'
16 %1:_(s64) = G_LOAD %0(p0) :: ("aarch64-invalid" load 8)
17 RET_ReallyLR
18 ...
0 # RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -o - %s | FileCheck %s
1
2 --- |
3
4 define void @target_memoperands() {
5 ret void
6 }
7
8 ...
9 ---
10 # CHECK-LABEL: name: target_memoperands
11 # CHECK: %1(s64) = G_LOAD %0(p0) :: ("aarch64-suppress-pair" load 8)
12 # CHECK: G_STORE %1(s64), %0(p0) :: ("aarch64-suppress-pair" store 8)
13 name: target_memoperands
14 body: |
15 bb.0:
16
17 %0:_(p0) = COPY %x0
18 %1:_(s64) = G_LOAD %0(p0) :: ("aarch64-suppress-pair" load 8)
19 G_STORE %1(s64), %0(p0) :: ("aarch64-suppress-pair" store 8)
20 RET_ReallyLR
21 ...