1 //===- PatternParser.cpp ----------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "Common/GlobalISel/PatternParser.h"
10 #include "Basic/CodeGenIntrinsics.h"
11 #include "Common/CodeGenTarget.h"
12 #include "Common/GlobalISel/CombinerUtils.h"
13 #include "Common/GlobalISel/Patterns.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Support/PrettyStackTrace.h"
16 #include "llvm/Support/SaveAndRestore.h"
17 #include "llvm/TableGen/Error.h"
18 #include "llvm/TableGen/Record.h"
22 static constexpr StringLiteral MIFlagsEnumClassName
= "MIFlagEnum";
25 class PrettyStackTraceParse
: public PrettyStackTraceEntry
{
29 PrettyStackTraceParse(const Record
&Def
) : Def(Def
) {}
31 void print(raw_ostream
&OS
) const override
{
32 if (Def
.isSubClassOf("GICombineRule"))
33 OS
<< "Parsing GICombineRule '" << Def
.getName() << '\'';
34 else if (Def
.isSubClassOf(PatFrag::ClassName
))
35 OS
<< "Parsing " << PatFrag::ClassName
<< " '" << Def
.getName() << '\'';
37 OS
<< "Parsing '" << Def
.getName() << '\'';
43 bool PatternParser::parsePatternList(
45 function_ref
<bool(std::unique_ptr
<Pattern
>)> ParseAction
,
46 StringRef Operator
, StringRef AnonPatNamePrefix
) {
47 if (List
.getOperatorAsDef(DiagLoc
)->getName() != Operator
) {
48 PrintError(DiagLoc
, "Expected " + Operator
+ " operator");
52 if (List
.getNumArgs() == 0) {
53 PrintError(DiagLoc
, Operator
+ " pattern list is empty");
57 // The match section consists of a list of matchers and predicates. Parse each
58 // one and add the equivalent GIMatchDag nodes, predicates, and edges.
59 for (unsigned I
= 0; I
< List
.getNumArgs(); ++I
) {
60 const Init
*Arg
= List
.getArg(I
);
61 std::string Name
= List
.getArgName(I
)
62 ? List
.getArgName(I
)->getValue().str()
63 : ("__" + AnonPatNamePrefix
+ "_" + Twine(I
)).str();
65 if (auto Pat
= parseInstructionPattern(*Arg
, Name
)) {
66 if (!ParseAction(std::move(Pat
)))
71 if (auto Pat
= parseWipMatchOpcodeMatcher(*Arg
, Name
)) {
72 if (!ParseAction(std::move(Pat
)))
77 // Parse arbitrary C++ code
78 if (const auto *StringI
= dyn_cast
<StringInit
>(Arg
)) {
79 auto CXXPat
= std::make_unique
<CXXPattern
>(*StringI
, insertStrRef(Name
));
80 if (!ParseAction(std::move(CXXPat
)))
86 "Failed to parse pattern: '" + Arg
->getAsString() + '\'');
93 static const CodeGenInstruction
&
94 getInstrForIntrinsic(const CodeGenTarget
&CGT
, const CodeGenIntrinsic
*I
) {
96 if (I
->isConvergent
) {
97 Opc
= I
->hasSideEffects
? "G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS"
98 : "G_INTRINSIC_CONVERGENT";
100 Opc
= I
->hasSideEffects
? "G_INTRINSIC_W_SIDE_EFFECTS" : "G_INTRINSIC";
103 RecordKeeper
&RK
= I
->TheDef
->getRecords();
104 return CGT
.getInstruction(RK
.getDef(Opc
));
107 std::unique_ptr
<Pattern
>
108 PatternParser::parseInstructionPattern(const Init
&Arg
, StringRef Name
) {
109 const DagInit
*DagPat
= dyn_cast
<DagInit
>(&Arg
);
113 std::unique_ptr
<InstructionPattern
> Pat
;
114 if (const DagInit
*IP
= getDagWithOperatorOfSubClass(Arg
, "Instruction")) {
115 auto &Instr
= CGT
.getInstruction(IP
->getOperatorAsDef(DiagLoc
));
117 std::make_unique
<CodeGenInstructionPattern
>(Instr
, insertStrRef(Name
));
118 } else if (const DagInit
*IP
=
119 getDagWithOperatorOfSubClass(Arg
, "Intrinsic")) {
120 const Record
*TheDef
= IP
->getOperatorAsDef(DiagLoc
);
121 const CodeGenIntrinsic
*Intrin
= &CGT
.getIntrinsic(TheDef
);
122 const CodeGenInstruction
&Instr
= getInstrForIntrinsic(CGT
, Intrin
);
124 std::make_unique
<CodeGenInstructionPattern
>(Instr
, insertStrRef(Name
));
125 cast
<CodeGenInstructionPattern
>(*Pat
).setIntrinsic(Intrin
);
126 } else if (const DagInit
*PFP
=
127 getDagWithOperatorOfSubClass(Arg
, PatFrag::ClassName
)) {
128 const Record
*Def
= PFP
->getOperatorAsDef(DiagLoc
);
129 const PatFrag
*PF
= parsePatFrag(Def
);
131 return nullptr; // Already diagnosed by parsePatFrag
132 Pat
= std::make_unique
<PatFragPattern
>(*PF
, insertStrRef(Name
));
133 } else if (const DagInit
*BP
=
134 getDagWithOperatorOfSubClass(Arg
, BuiltinPattern::ClassName
)) {
135 Pat
= std::make_unique
<BuiltinPattern
>(*BP
->getOperatorAsDef(DiagLoc
),
140 for (unsigned K
= 0; K
< DagPat
->getNumArgs(); ++K
) {
141 const Init
*Arg
= DagPat
->getArg(K
);
142 if (auto *DagArg
= getDagWithSpecificOperator(*Arg
, "MIFlags")) {
143 if (!parseInstructionPatternMIFlags(*Pat
, DagArg
))
148 if (!parseInstructionPatternOperand(*Pat
, Arg
, DagPat
->getArgName(K
)))
152 if (!Pat
->checkSemantics(DiagLoc
))
155 return std::move(Pat
);
158 std::unique_ptr
<Pattern
>
159 PatternParser::parseWipMatchOpcodeMatcher(const Init
&Arg
, StringRef Name
) {
160 const DagInit
*Matcher
= getDagWithSpecificOperator(Arg
, "wip_match_opcode");
164 if (Matcher
->getNumArgs() == 0) {
165 PrintError(DiagLoc
, "Empty wip_match_opcode");
169 // Each argument is an opcode that can match.
170 auto Result
= std::make_unique
<AnyOpcodePattern
>(insertStrRef(Name
));
171 for (const auto &Arg
: Matcher
->getArgs()) {
172 const Record
*OpcodeDef
= getDefOfSubClass(*Arg
, "Instruction");
174 Result
->addOpcode(&CGT
.getInstruction(OpcodeDef
));
178 PrintError(DiagLoc
, "Arguments to wip_match_opcode must be instructions");
182 return std::move(Result
);
185 bool PatternParser::parseInstructionPatternOperand(InstructionPattern
&IP
,
187 const StringInit
*OpName
) {
188 const auto ParseErr
= [&]() {
190 "cannot parse operand '" + OpInit
->getAsUnquotedString() + "' ");
193 "operand name is '" + OpName
->getAsUnquotedString() + '\'');
197 // untyped immediate, e.g. 0
198 if (const auto *IntImm
= dyn_cast
<IntInit
>(OpInit
)) {
199 std::string Name
= OpName
? OpName
->getAsUnquotedString() : "";
200 IP
.addOperand(IntImm
->getValue(), insertStrRef(Name
), PatternType());
204 // typed immediate, e.g. (i32 0)
205 if (const auto *DagOp
= dyn_cast
<DagInit
>(OpInit
)) {
206 if (DagOp
->getNumArgs() != 1)
209 const Record
*TyDef
= DagOp
->getOperatorAsDef(DiagLoc
);
210 auto ImmTy
= PatternType::get(DiagLoc
, TyDef
,
211 "cannot parse immediate '" +
212 DagOp
->getAsUnquotedString() + '\'');
216 if (!IP
.hasAllDefs()) {
217 PrintError(DiagLoc
, "out operand of '" + IP
.getInstName() +
218 "' cannot be an immediate");
222 const auto *Val
= dyn_cast
<IntInit
>(DagOp
->getArg(0));
226 std::string Name
= OpName
? OpName
->getAsUnquotedString() : "";
227 IP
.addOperand(Val
->getValue(), insertStrRef(Name
), *ImmTy
);
231 // Typed operand e.g. $x/$z in (G_FNEG $x, $z)
232 if (auto *DefI
= dyn_cast
<DefInit
>(OpInit
)) {
234 PrintError(DiagLoc
, "expected an operand name after '" +
235 OpInit
->getAsString() + '\'');
238 const Record
*Def
= DefI
->getDef();
239 auto Ty
= PatternType::get(DiagLoc
, Def
, "cannot parse operand type");
242 IP
.addOperand(insertStrRef(OpName
->getAsUnquotedString()), *Ty
);
246 // Untyped operand e.g. $x/$z in (G_FNEG $x, $z)
247 if (isa
<UnsetInit
>(OpInit
)) {
248 assert(OpName
&& "Unset w/ no OpName?");
249 IP
.addOperand(insertStrRef(OpName
->getAsUnquotedString()), PatternType());
256 bool PatternParser::parseInstructionPatternMIFlags(InstructionPattern
&IP
,
258 auto *CGIP
= dyn_cast
<CodeGenInstructionPattern
>(&IP
);
261 "matching/writing MIFlags is only allowed on CodeGenInstruction "
266 const auto CheckFlagEnum
= [&](const Record
*R
) {
267 if (!R
->isSubClassOf(MIFlagsEnumClassName
)) {
268 PrintError(DiagLoc
, "'" + R
->getName() + "' is not a subclass of '" +
269 MIFlagsEnumClassName
+ "'");
276 if (CGIP
->getMIFlagsInfo()) {
277 PrintError(DiagLoc
, "MIFlags can only be present once on an instruction");
281 auto &FI
= CGIP
->getOrCreateMIFlagsInfo();
282 for (unsigned K
= 0; K
< Op
->getNumArgs(); ++K
) {
283 const Init
*Arg
= Op
->getArg(K
);
285 // Match/set a flag: (MIFlags FmNoNans)
286 if (const auto *Def
= dyn_cast
<DefInit
>(Arg
)) {
287 const Record
*R
= Def
->getDef();
288 if (!CheckFlagEnum(R
))
295 // Do not match a flag/unset a flag: (MIFlags (not FmNoNans))
296 if (const DagInit
*NotDag
= getDagWithSpecificOperator(*Arg
, "not")) {
297 for (const Init
*NotArg
: NotDag
->getArgs()) {
298 const DefInit
*DefArg
= dyn_cast
<DefInit
>(NotArg
);
300 PrintError(DiagLoc
, "cannot parse '" + NotArg
->getAsUnquotedString() +
301 "': expected a '" + MIFlagsEnumClassName
+
306 const Record
*R
= DefArg
->getDef();
307 if (!CheckFlagEnum(R
))
316 // Copy flags from a matched instruction: (MIFlags $mi)
317 if (isa
<UnsetInit
>(Arg
)) {
318 FI
.addCopyFlag(insertStrRef(Op
->getArgName(K
)->getAsUnquotedString()));
326 std::unique_ptr
<PatFrag
> PatternParser::parsePatFragImpl(const Record
*Def
) {
327 auto StackTrace
= PrettyStackTraceParse(*Def
);
328 if (!Def
->isSubClassOf(PatFrag::ClassName
))
331 const DagInit
*Ins
= Def
->getValueAsDag("InOperands");
332 if (Ins
->getOperatorAsDef(Def
->getLoc())->getName() != "ins") {
333 PrintError(Def
, "expected 'ins' operator for " + PatFrag::ClassName
+
334 " in operands list");
338 const DagInit
*Outs
= Def
->getValueAsDag("OutOperands");
339 if (Outs
->getOperatorAsDef(Def
->getLoc())->getName() != "outs") {
340 PrintError(Def
, "expected 'outs' operator for " + PatFrag::ClassName
+
341 " out operands list");
345 auto Result
= std::make_unique
<PatFrag
>(*Def
);
346 if (!parsePatFragParamList(*Outs
, [&](StringRef Name
, unsigned Kind
) {
347 Result
->addOutParam(insertStrRef(Name
), (PatFrag::ParamKind
)Kind
);
352 if (!parsePatFragParamList(*Ins
, [&](StringRef Name
, unsigned Kind
) {
353 Result
->addInParam(insertStrRef(Name
), (PatFrag::ParamKind
)Kind
);
358 const ListInit
*Alts
= Def
->getValueAsListInit("Alternatives");
360 for (const Init
*Alt
: *Alts
) {
361 const auto *PatDag
= dyn_cast
<DagInit
>(Alt
);
363 PrintError(Def
, "expected dag init for PatFrag pattern alternative");
367 PatFrag::Alternative
&A
= Result
->addAlternative();
368 const auto AddPat
= [&](std::unique_ptr
<Pattern
> Pat
) {
369 A
.Pats
.push_back(std::move(Pat
));
373 SaveAndRestore
<ArrayRef
<SMLoc
>> DiagLocSAR(DiagLoc
, Def
->getLoc());
374 if (!parsePatternList(
375 *PatDag
, AddPat
, "pattern",
377 (Def
->getName() + "_alt" + Twine(AltIdx
++) + "_pattern").str()))
381 if (!Result
->buildOperandsTables() || !Result
->checkSemantics())
387 bool PatternParser::parsePatFragParamList(
388 const DagInit
&OpsList
,
389 function_ref
<bool(StringRef
, unsigned)> ParseAction
) {
390 for (unsigned K
= 0; K
< OpsList
.getNumArgs(); ++K
) {
391 const StringInit
*Name
= OpsList
.getArgName(K
);
392 const Init
*Ty
= OpsList
.getArg(K
);
395 PrintError(DiagLoc
, "all operands must be named'");
398 const std::string NameStr
= Name
->getAsUnquotedString();
400 PatFrag::ParamKind OpKind
;
401 if (isSpecificDef(*Ty
, "gi_imm"))
402 OpKind
= PatFrag::PK_Imm
;
403 else if (isSpecificDef(*Ty
, "root"))
404 OpKind
= PatFrag::PK_Root
;
405 else if (isa
<UnsetInit
>(Ty
) ||
406 isSpecificDef(*Ty
, "gi_mo")) // no type = gi_mo.
407 OpKind
= PatFrag::PK_MachineOperand
;
412 "' operand type was expected to be 'root', 'gi_imm' or 'gi_mo'");
416 if (!ParseAction(NameStr
, (unsigned)OpKind
))
423 const PatFrag
*PatternParser::parsePatFrag(const Record
*Def
) {
424 // Cache already parsed PatFrags to avoid doing extra work.
425 static DenseMap
<const Record
*, std::unique_ptr
<PatFrag
>> ParsedPatFrags
;
427 auto It
= ParsedPatFrags
.find(Def
);
428 if (It
!= ParsedPatFrags
.end()) {
429 SeenPatFrags
.insert(It
->second
.get());
430 return It
->second
.get();
433 std::unique_ptr
<PatFrag
> NewPatFrag
= parsePatFragImpl(Def
);
435 PrintError(Def
, "Could not parse " + PatFrag::ClassName
+ " '" +
436 Def
->getName() + "'");
437 // Put a nullptr in the map so we don't attempt parsing this again.
438 ParsedPatFrags
[Def
] = nullptr;
442 const auto *Res
= NewPatFrag
.get();
443 ParsedPatFrags
[Def
] = std::move(NewPatFrag
);
444 SeenPatFrags
.insert(Res
);