xref: /llvm-project/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp (revision 4e8c9d28132039a98feb97cec2759cddeb37d934)
1 //===- CodeGenInstAlias.cpp - CodeGen InstAlias Class Wrapper -------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the CodeGenInstAlias class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "CodeGenInstAlias.h"
14 #include "CodeGenInstruction.h"
15 #include "CodeGenRegisters.h"
16 #include "CodeGenTarget.h"
17 #include "llvm/ADT/StringMap.h"
18 #include "llvm/TableGen/Error.h"
19 #include "llvm/TableGen/Record.h"
20 
21 using namespace llvm;
22 
23 /// tryAliasOpMatch - This is a helper function for the CodeGenInstAlias
24 /// constructor.  It checks if an argument in an InstAlias pattern matches
25 /// the corresponding operand of the instruction.  It returns true on a
26 /// successful match, with ResOp set to the result operand to be used.
27 bool CodeGenInstAlias::tryAliasOpMatch(const DagInit *Result,
28                                        unsigned AliasOpNo,
29                                        const Record *InstOpRec, bool hasSubOps,
30                                        ArrayRef<SMLoc> Loc,
31                                        const CodeGenTarget &T,
32                                        ResultOperand &ResOp) {
33   const Init *Arg = Result->getArg(AliasOpNo);
34   const DefInit *ADI = dyn_cast<DefInit>(Arg);
35   const Record *ResultRecord = ADI ? ADI->getDef() : nullptr;
36 
37   if (ADI && ADI->getDef() == InstOpRec) {
38     // If the operand is a record, it must have a name, and the record type
39     // must match up with the instruction's argument type.
40     if (!Result->getArgName(AliasOpNo))
41       PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
42                                " must have a name!");
43     ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
44                           ResultRecord);
45     return true;
46   }
47 
48   // For register operands, the source register class can be a subclass
49   // of the instruction register class, not just an exact match.
50   if (InstOpRec->isSubClassOf("RegisterOperand"))
51     InstOpRec = InstOpRec->getValueAsDef("RegClass");
52 
53   if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand"))
54     ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit();
55 
56   if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {
57     if (!InstOpRec->isSubClassOf("RegisterClass"))
58       return false;
59     if (!T.getRegisterClass(InstOpRec).hasSubClass(
60             &T.getRegisterClass(ADI->getDef())))
61       return false;
62     ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
63                           ResultRecord);
64     return true;
65   }
66 
67   // Handle explicit registers.
68   if (ADI && ADI->getDef()->isSubClassOf("Register")) {
69     if (InstOpRec->isSubClassOf("OptionalDefOperand")) {
70       const DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");
71       // The operand info should only have a single (register) entry. We
72       // want the register class of it.
73       InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();
74     }
75 
76     if (!InstOpRec->isSubClassOf("RegisterClass"))
77       return false;
78 
79     if (!T.getRegisterClass(InstOpRec).contains(
80             T.getRegBank().getReg(ADI->getDef())))
81       PrintFatalError(Loc, "fixed register " + ADI->getDef()->getName() +
82                                " is not a member of the " +
83                                InstOpRec->getName() + " register class!");
84 
85     if (Result->getArgName(AliasOpNo))
86       PrintFatalError(Loc, "result fixed register argument must "
87                            "not have a name!");
88 
89     ResOp = ResultOperand(ResultRecord);
90     return true;
91   }
92 
93   // Handle "zero_reg" for optional def operands.
94   if (ADI && ADI->getDef()->getName() == "zero_reg") {
95 
96     // Check if this is an optional def.
97     // Tied operands where the source is a sub-operand of a complex operand
98     // need to represent both operands in the alias destination instruction.
99     // Allow zero_reg for the tied portion. This can and should go away once
100     // the MC representation of things doesn't use tied operands at all.
101     // if (!InstOpRec->isSubClassOf("OptionalDefOperand"))
102     //  throw TGError(Loc, "reg0 used for result that is not an "
103     //                "OptionalDefOperand!");
104 
105     ResOp = ResultOperand(nullptr);
106     return true;
107   }
108 
109   // Literal integers.
110   if (const IntInit *II = dyn_cast<IntInit>(Arg)) {
111     if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
112       return false;
113     // Integer arguments can't have names.
114     if (Result->getArgName(AliasOpNo))
115       PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
116                                " must not have a name!");
117     ResOp = ResultOperand(II->getValue());
118     return true;
119   }
120 
121   // Bits<n> (also used for 0bxx literals)
122   if (const BitsInit *BI = dyn_cast<BitsInit>(Arg)) {
123     if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
124       return false;
125     if (!BI->isComplete())
126       return false;
127     // Convert the bits init to an integer and use that for the result.
128     std::optional<int64_t> Value = BI->convertInitializerToInt();
129     if (!Value)
130       return false;
131     ResOp = ResultOperand(*Value);
132     return true;
133   }
134 
135   // If both are Operands with the same MVT, allow the conversion. It's
136   // up to the user to make sure the values are appropriate, just like
137   // for isel Pat's.
138   if (InstOpRec->isSubClassOf("Operand") && ADI &&
139       ADI->getDef()->isSubClassOf("Operand")) {
140     // FIXME: What other attributes should we check here? Identical
141     // MIOperandInfo perhaps?
142     if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))
143       return false;
144     ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
145                           ADI->getDef());
146     return true;
147   }
148 
149   return false;
150 }
151 
152 unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const {
153   if (!isRecord())
154     return 1;
155 
156   const Record *Rec = getRecord();
157   if (!Rec->isSubClassOf("Operand"))
158     return 1;
159 
160   const DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
161   if (MIOpInfo->getNumArgs() == 0) {
162     // Unspecified, so it defaults to 1
163     return 1;
164   }
165 
166   return MIOpInfo->getNumArgs();
167 }
168 
169 CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T)
170     : TheDef(R) {
171   Result = R->getValueAsDag("ResultInst");
172   AsmString = std::string(R->getValueAsString("AsmString"));
173 
174   // Verify that the root of the result is an instruction.
175   const DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
176   if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
177     PrintFatalError(R->getLoc(),
178                     "result of inst alias should be an instruction");
179 
180   ResultInst = &T.getInstruction(DI->getDef());
181 
182   // NameClass - If argument names are repeated, we need to verify they have
183   // the same class.
184   StringMap<const Record *> NameClass;
185   for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
186     const DefInit *ADI = dyn_cast<DefInit>(Result->getArg(i));
187     if (!ADI || !Result->getArgName(i))
188       continue;
189     // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
190     // $foo can exist multiple times in the result list, but it must have the
191     // same type.
192     const Record *&Entry = NameClass[Result->getArgNameStr(i)];
193     if (Entry && Entry != ADI->getDef())
194       PrintFatalError(R->getLoc(), "result value $" + Result->getArgNameStr(i) +
195                                        " is both " + Entry->getName() +
196                                        " and " + ADI->getDef()->getName() +
197                                        "!");
198     Entry = ADI->getDef();
199   }
200 
201   // Decode and validate the arguments of the result.
202   unsigned AliasOpNo = 0;
203   for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
204 
205     // Tied registers don't have an entry in the result dag unless they're part
206     // of a complex operand, in which case we include them anyways, as we
207     // don't have any other way to specify the whole operand.
208     if (ResultInst->Operands[i].MINumOperands == 1 &&
209         ResultInst->Operands[i].getTiedRegister() != -1) {
210       // Tied operands of different RegisterClass should be explicit within an
211       // instruction's syntax and so cannot be skipped.
212       int TiedOpNum = ResultInst->Operands[i].getTiedRegister();
213       if (ResultInst->Operands[i].Rec->getName() ==
214           ResultInst->Operands[TiedOpNum].Rec->getName())
215         continue;
216     }
217 
218     if (AliasOpNo >= Result->getNumArgs())
219       PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
220 
221     const Record *InstOpRec = ResultInst->Operands[i].Rec;
222     unsigned NumSubOps = ResultInst->Operands[i].MINumOperands;
223     ResultOperand ResOp(static_cast<int64_t>(0));
224     if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1),
225                         R->getLoc(), T, ResOp)) {
226       // If this is a simple operand, or a complex operand with a custom match
227       // class, then we can match is verbatim.
228       if (NumSubOps == 1 || (InstOpRec->getValue("ParserMatchClass") &&
229                              InstOpRec->getValueAsDef("ParserMatchClass")
230                                      ->getValueAsString("Name") != "Imm")) {
231         ResultOperands.push_back(std::move(ResOp));
232         ResultInstOperandIndex.emplace_back(i, -1);
233         ++AliasOpNo;
234 
235         // Otherwise, we need to match each of the suboperands individually.
236       } else {
237         const DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
238         for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
239           const Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
240 
241           // Take care to instantiate each of the suboperands with the correct
242           // nomenclature: $foo.bar
243           ResultOperands.emplace_back(
244               Result->getArgName(AliasOpNo)->getAsUnquotedString() + "." +
245                   MIOI->getArgName(SubOp)->getAsUnquotedString(),
246               SubRec);
247           ResultInstOperandIndex.emplace_back(i, SubOp);
248         }
249         ++AliasOpNo;
250       }
251       continue;
252     }
253 
254     // If the argument did not match the instruction operand, and the operand
255     // is composed of multiple suboperands, try matching the suboperands.
256     if (NumSubOps > 1) {
257       const DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo;
258       for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) {
259         if (AliasOpNo >= Result->getNumArgs())
260           PrintFatalError(R->getLoc(), "not enough arguments for instruction!");
261         const Record *SubRec = cast<DefInit>(MIOI->getArg(SubOp))->getDef();
262         if (tryAliasOpMatch(Result, AliasOpNo, SubRec, false, R->getLoc(), T,
263                             ResOp)) {
264           ResultOperands.push_back(ResOp);
265           ResultInstOperandIndex.emplace_back(i, SubOp);
266           ++AliasOpNo;
267         } else {
268           PrintFatalError(
269               R->getLoc(),
270               "result argument #" + Twine(AliasOpNo) +
271                   " does not match instruction operand class " +
272                   (SubOp == 0 ? InstOpRec->getName() : SubRec->getName()));
273         }
274       }
275       continue;
276     }
277     PrintFatalError(R->getLoc(),
278                     "result argument #" + Twine(AliasOpNo) +
279                         " does not match instruction operand class " +
280                         InstOpRec->getName());
281   }
282 
283   if (AliasOpNo != Result->getNumArgs())
284     PrintFatalError(R->getLoc(), "too many operands for instruction!");
285 }
286