1 //===- SetTheory.cpp - Generate ordered sets from DAG expressions ---------===//
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 // This file implements the SetTheory class that computes ordered sets of
10 // Records from DAG expressions.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/TableGen/SetTheory.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Casting.h"
19 #include "llvm/Support/Format.h"
20 #include "llvm/Support/SMLoc.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include "llvm/TableGen/Error.h"
23 #include "llvm/TableGen/Record.h"
31 // Define the standard operators.
34 using RecSet
= SetTheory::RecSet
;
35 using RecVec
= SetTheory::RecVec
;
37 // (add a, b, ...) Evaluate and union all arguments.
38 struct AddOp
: public SetTheory::Operator
{
39 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
40 ArrayRef
<SMLoc
> Loc
) override
{
41 ST
.evaluate(Expr
->arg_begin(), Expr
->arg_end(), Elts
, Loc
);
45 // (sub Add, Sub, ...) Set difference.
46 struct SubOp
: public SetTheory::Operator
{
47 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
48 ArrayRef
<SMLoc
> Loc
) override
{
49 if (Expr
->arg_size() < 2)
50 PrintFatalError(Loc
, "Set difference needs at least two arguments: " +
53 ST
.evaluate(*Expr
->arg_begin(), Add
, Loc
);
54 ST
.evaluate(Expr
->arg_begin() + 1, Expr
->arg_end(), Sub
, Loc
);
55 for (const auto &I
: Add
)
61 // (and S1, S2) Set intersection.
62 struct AndOp
: public SetTheory::Operator
{
63 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
64 ArrayRef
<SMLoc
> Loc
) override
{
65 if (Expr
->arg_size() != 2)
66 PrintFatalError(Loc
, "Set intersection requires two arguments: " +
69 ST
.evaluate(Expr
->arg_begin()[0], S1
, Loc
);
70 ST
.evaluate(Expr
->arg_begin()[1], S2
, Loc
);
71 for (const auto &I
: S1
)
77 // SetIntBinOp - Abstract base class for (Op S, N) operators.
78 struct SetIntBinOp
: public SetTheory::Operator
{
79 virtual void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
80 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) = 0;
82 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
83 ArrayRef
<SMLoc
> Loc
) override
{
84 if (Expr
->arg_size() != 2)
85 PrintFatalError(Loc
, "Operator requires (Op Set, Int) arguments: " +
88 ST
.evaluate(Expr
->arg_begin()[0], Set
, Loc
);
89 IntInit
*II
= dyn_cast
<IntInit
>(Expr
->arg_begin()[1]);
91 PrintFatalError(Loc
, "Second argument must be an integer: " +
93 apply2(ST
, Expr
, Set
, II
->getValue(), Elts
, Loc
);
97 // (shl S, N) Shift left, remove the first N elements.
98 struct ShlOp
: public SetIntBinOp
{
99 void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
100 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) override
{
102 PrintFatalError(Loc
, "Positive shift required: " +
103 Expr
->getAsString());
104 if (unsigned(N
) < Set
.size())
105 Elts
.insert(Set
.begin() + N
, Set
.end());
109 // (trunc S, N) Truncate after the first N elements.
110 struct TruncOp
: public SetIntBinOp
{
111 void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
112 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) override
{
114 PrintFatalError(Loc
, "Positive length required: " +
115 Expr
->getAsString());
116 if (unsigned(N
) > Set
.size())
118 Elts
.insert(Set
.begin(), Set
.begin() + N
);
122 // Left/right rotation.
123 struct RotOp
: public SetIntBinOp
{
126 RotOp(bool Rev
) : Reverse(Rev
) {}
128 void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
129 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) override
{
132 // N > 0 -> rotate left, N < 0 -> rotate right.
136 N
= Set
.size() - (-N
% Set
.size());
139 Elts
.insert(Set
.begin() + N
, Set
.end());
140 Elts
.insert(Set
.begin(), Set
.begin() + N
);
144 // (decimate S, N) Pick every N'th element of S.
145 struct DecimateOp
: public SetIntBinOp
{
146 void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
147 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) override
{
149 PrintFatalError(Loc
, "Positive stride required: " +
150 Expr
->getAsString());
151 for (unsigned I
= 0; I
< Set
.size(); I
+= N
)
156 // (interleave S1, S2, ...) Interleave elements of the arguments.
157 struct InterleaveOp
: public SetTheory::Operator
{
158 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
159 ArrayRef
<SMLoc
> Loc
) override
{
160 // Evaluate the arguments individually.
161 SmallVector
<RecSet
, 4> Args(Expr
->getNumArgs());
162 unsigned MaxSize
= 0;
163 for (unsigned i
= 0, e
= Expr
->getNumArgs(); i
!= e
; ++i
) {
164 ST
.evaluate(Expr
->getArg(i
), Args
[i
], Loc
);
165 MaxSize
= std::max(MaxSize
, unsigned(Args
[i
].size()));
167 // Interleave arguments into Elts.
168 for (unsigned n
= 0; n
!= MaxSize
; ++n
)
169 for (unsigned i
= 0, e
= Expr
->getNumArgs(); i
!= e
; ++i
)
170 if (n
< Args
[i
].size())
171 Elts
.insert(Args
[i
][n
]);
175 // (sequence "Format", From, To) Generate a sequence of records by name.
176 struct SequenceOp
: public SetTheory::Operator
{
177 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
178 ArrayRef
<SMLoc
> Loc
) override
{
180 if (Expr
->arg_size() > 4)
181 PrintFatalError(Loc
, "Bad args to (sequence \"Format\", From, To): " +
182 Expr
->getAsString());
183 else if (Expr
->arg_size() == 4) {
184 if (IntInit
*II
= dyn_cast
<IntInit
>(Expr
->arg_begin()[3])) {
185 Step
= II
->getValue();
187 PrintFatalError(Loc
, "Stride must be an integer: " +
188 Expr
->getAsString());
192 if (StringInit
*SI
= dyn_cast
<StringInit
>(Expr
->arg_begin()[0]))
193 Format
= std::string(SI
->getValue());
195 PrintFatalError(Loc
, "Format must be a string: " + Expr
->getAsString());
198 if (IntInit
*II
= dyn_cast
<IntInit
>(Expr
->arg_begin()[1]))
199 From
= II
->getValue();
201 PrintFatalError(Loc
, "From must be an integer: " + Expr
->getAsString());
202 if (From
< 0 || From
>= (1 << 30))
203 PrintFatalError(Loc
, "From out of range");
205 if (IntInit
*II
= dyn_cast
<IntInit
>(Expr
->arg_begin()[2]))
208 PrintFatalError(Loc
, "To must be an integer: " + Expr
->getAsString());
209 if (To
< 0 || To
>= (1 << 30))
210 PrintFatalError(Loc
, "To out of range");
212 RecordKeeper
&Records
=
213 cast
<DefInit
>(Expr
->getOperator())->getDef()->getRecords();
215 Step
*= From
<= To
? 1 : -1;
217 if (Step
> 0 && From
> To
)
219 else if (Step
< 0 && From
< To
)
222 raw_string_ostream
OS(Name
);
223 OS
<< format(Format
.c_str(), unsigned(From
));
224 Record
*Rec
= Records
.getDef(OS
.str());
226 PrintFatalError(Loc
, "No def named '" + Name
+ "': " +
227 Expr
->getAsString());
228 // Try to reevaluate Rec in case it is a set.
229 if (const RecVec
*Result
= ST
.expand(Rec
))
230 Elts
.insert(Result
->begin(), Result
->end());
239 // Expand a Def into a set by evaluating one of its fields.
240 struct FieldExpander
: public SetTheory::Expander
{
243 FieldExpander(StringRef fn
) : FieldName(fn
) {}
245 void expand(SetTheory
&ST
, Record
*Def
, RecSet
&Elts
) override
{
246 ST
.evaluate(Def
->getValueInit(FieldName
), Elts
, Def
->getLoc());
250 } // end anonymous namespace
252 // Pin the vtables to this file.
253 void SetTheory::Operator::anchor() {}
254 void SetTheory::Expander::anchor() {}
256 SetTheory::SetTheory() {
257 addOperator("add", std::make_unique
<AddOp
>());
258 addOperator("sub", std::make_unique
<SubOp
>());
259 addOperator("and", std::make_unique
<AndOp
>());
260 addOperator("shl", std::make_unique
<ShlOp
>());
261 addOperator("trunc", std::make_unique
<TruncOp
>());
262 addOperator("rotl", std::make_unique
<RotOp
>(false));
263 addOperator("rotr", std::make_unique
<RotOp
>(true));
264 addOperator("decimate", std::make_unique
<DecimateOp
>());
265 addOperator("interleave", std::make_unique
<InterleaveOp
>());
266 addOperator("sequence", std::make_unique
<SequenceOp
>());
269 void SetTheory::addOperator(StringRef Name
, std::unique_ptr
<Operator
> Op
) {
270 Operators
[Name
] = std::move(Op
);
273 void SetTheory::addExpander(StringRef ClassName
, std::unique_ptr
<Expander
> E
) {
274 Expanders
[ClassName
] = std::move(E
);
277 void SetTheory::addFieldExpander(StringRef ClassName
, StringRef FieldName
) {
278 addExpander(ClassName
, std::make_unique
<FieldExpander
>(FieldName
));
281 void SetTheory::evaluate(Init
*Expr
, RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) {
282 // A def in a list can be a just an element, or it may expand.
283 if (DefInit
*Def
= dyn_cast
<DefInit
>(Expr
)) {
284 if (const RecVec
*Result
= expand(Def
->getDef()))
285 return Elts
.insert(Result
->begin(), Result
->end());
286 Elts
.insert(Def
->getDef());
290 // Lists simply expand.
291 if (ListInit
*LI
= dyn_cast
<ListInit
>(Expr
))
292 return evaluate(LI
->begin(), LI
->end(), Elts
, Loc
);
294 // Anything else must be a DAG.
295 DagInit
*DagExpr
= dyn_cast
<DagInit
>(Expr
);
297 PrintFatalError(Loc
, "Invalid set element: " + Expr
->getAsString());
298 DefInit
*OpInit
= dyn_cast
<DefInit
>(DagExpr
->getOperator());
300 PrintFatalError(Loc
, "Bad set expression: " + Expr
->getAsString());
301 auto I
= Operators
.find(OpInit
->getDef()->getName());
302 if (I
== Operators
.end())
303 PrintFatalError(Loc
, "Unknown set operator: " + Expr
->getAsString());
304 I
->second
->apply(*this, DagExpr
, Elts
, Loc
);
307 const RecVec
*SetTheory::expand(Record
*Set
) {
308 // Check existing entries for Set and return early.
309 ExpandMap::iterator I
= Expansions
.find(Set
);
310 if (I
!= Expansions
.end())
313 // This is the first time we see Set. Find a suitable expander.
314 ArrayRef
<std::pair
<Record
*, SMRange
>> SC
= Set
->getSuperClasses();
315 for (const auto &SCPair
: SC
) {
316 // Skip unnamed superclasses.
317 if (!isa
<StringInit
>(SCPair
.first
->getNameInit()))
319 auto I
= Expanders
.find(SCPair
.first
->getName());
320 if (I
!= Expanders
.end()) {
321 // This breaks recursive definitions.
322 RecVec
&EltVec
= Expansions
[Set
];
324 I
->second
->expand(*this, Set
, Elts
);
325 EltVec
.assign(Elts
.begin(), Elts
.end());
330 // Set is not expandable.