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/ADT/ArrayRef.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/STLExtras.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"
24 #include "llvm/TableGen/SetTheory.h"
32 // Define the standard operators.
35 using RecSet
= SetTheory::RecSet
;
36 using RecVec
= SetTheory::RecVec
;
38 // (add a, b, ...) Evaluate and union all arguments.
39 struct AddOp
: public SetTheory::Operator
{
40 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
41 ArrayRef
<SMLoc
> Loc
) override
{
42 ST
.evaluate(Expr
->arg_begin(), Expr
->arg_end(), Elts
, Loc
);
46 // (sub Add, Sub, ...) Set difference.
47 struct SubOp
: public SetTheory::Operator
{
48 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
49 ArrayRef
<SMLoc
> Loc
) override
{
50 if (Expr
->arg_size() < 2)
51 PrintFatalError(Loc
, "Set difference needs at least two arguments: " +
54 ST
.evaluate(*Expr
->arg_begin(), Add
, Loc
);
55 ST
.evaluate(Expr
->arg_begin() + 1, Expr
->arg_end(), Sub
, Loc
);
56 for (RecSet::iterator I
= Add
.begin(), E
= Add
.end(); I
!= E
; ++I
)
62 // (and S1, S2) Set intersection.
63 struct AndOp
: public SetTheory::Operator
{
64 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
65 ArrayRef
<SMLoc
> Loc
) override
{
66 if (Expr
->arg_size() != 2)
67 PrintFatalError(Loc
, "Set intersection requires two arguments: " +
70 ST
.evaluate(Expr
->arg_begin()[0], S1
, Loc
);
71 ST
.evaluate(Expr
->arg_begin()[1], S2
, Loc
);
72 for (RecSet::iterator I
= S1
.begin(), E
= S1
.end(); I
!= E
; ++I
)
78 // SetIntBinOp - Abstract base class for (Op S, N) operators.
79 struct SetIntBinOp
: public SetTheory::Operator
{
80 virtual void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
81 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) = 0;
83 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
84 ArrayRef
<SMLoc
> Loc
) override
{
85 if (Expr
->arg_size() != 2)
86 PrintFatalError(Loc
, "Operator requires (Op Set, Int) arguments: " +
89 ST
.evaluate(Expr
->arg_begin()[0], Set
, Loc
);
90 IntInit
*II
= dyn_cast
<IntInit
>(Expr
->arg_begin()[1]);
92 PrintFatalError(Loc
, "Second argument must be an integer: " +
94 apply2(ST
, Expr
, Set
, II
->getValue(), Elts
, Loc
);
98 // (shl S, N) Shift left, remove the first N elements.
99 struct ShlOp
: public SetIntBinOp
{
100 void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
101 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) override
{
103 PrintFatalError(Loc
, "Positive shift required: " +
104 Expr
->getAsString());
105 if (unsigned(N
) < Set
.size())
106 Elts
.insert(Set
.begin() + N
, Set
.end());
110 // (trunc S, N) Truncate after the first N elements.
111 struct TruncOp
: public SetIntBinOp
{
112 void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
113 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) override
{
115 PrintFatalError(Loc
, "Positive length required: " +
116 Expr
->getAsString());
117 if (unsigned(N
) > Set
.size())
119 Elts
.insert(Set
.begin(), Set
.begin() + N
);
123 // Left/right rotation.
124 struct RotOp
: public SetIntBinOp
{
127 RotOp(bool Rev
) : Reverse(Rev
) {}
129 void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
130 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) override
{
133 // N > 0 -> rotate left, N < 0 -> rotate right.
137 N
= Set
.size() - (-N
% Set
.size());
140 Elts
.insert(Set
.begin() + N
, Set
.end());
141 Elts
.insert(Set
.begin(), Set
.begin() + N
);
145 // (decimate S, N) Pick every N'th element of S.
146 struct DecimateOp
: public SetIntBinOp
{
147 void apply2(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Set
, int64_t N
,
148 RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) override
{
150 PrintFatalError(Loc
, "Positive stride required: " +
151 Expr
->getAsString());
152 for (unsigned I
= 0; I
< Set
.size(); I
+= N
)
157 // (interleave S1, S2, ...) Interleave elements of the arguments.
158 struct InterleaveOp
: public SetTheory::Operator
{
159 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
160 ArrayRef
<SMLoc
> Loc
) override
{
161 // Evaluate the arguments individually.
162 SmallVector
<RecSet
, 4> Args(Expr
->getNumArgs());
163 unsigned MaxSize
= 0;
164 for (unsigned i
= 0, e
= Expr
->getNumArgs(); i
!= e
; ++i
) {
165 ST
.evaluate(Expr
->getArg(i
), Args
[i
], Loc
);
166 MaxSize
= std::max(MaxSize
, unsigned(Args
[i
].size()));
168 // Interleave arguments into Elts.
169 for (unsigned n
= 0; n
!= MaxSize
; ++n
)
170 for (unsigned i
= 0, e
= Expr
->getNumArgs(); i
!= e
; ++i
)
171 if (n
< Args
[i
].size())
172 Elts
.insert(Args
[i
][n
]);
176 // (sequence "Format", From, To) Generate a sequence of records by name.
177 struct SequenceOp
: public SetTheory::Operator
{
178 void apply(SetTheory
&ST
, DagInit
*Expr
, RecSet
&Elts
,
179 ArrayRef
<SMLoc
> Loc
) override
{
181 if (Expr
->arg_size() > 4)
182 PrintFatalError(Loc
, "Bad args to (sequence \"Format\", From, To): " +
183 Expr
->getAsString());
184 else if (Expr
->arg_size() == 4) {
185 if (IntInit
*II
= dyn_cast
<IntInit
>(Expr
->arg_begin()[3])) {
186 Step
= II
->getValue();
188 PrintFatalError(Loc
, "Stride must be an integer: " +
189 Expr
->getAsString());
193 if (StringInit
*SI
= dyn_cast
<StringInit
>(Expr
->arg_begin()[0]))
194 Format
= SI
->getValue();
196 PrintFatalError(Loc
, "Format must be a string: " + Expr
->getAsString());
199 if (IntInit
*II
= dyn_cast
<IntInit
>(Expr
->arg_begin()[1]))
200 From
= II
->getValue();
202 PrintFatalError(Loc
, "From must be an integer: " + Expr
->getAsString());
203 if (From
< 0 || From
>= (1 << 30))
204 PrintFatalError(Loc
, "From out of range");
206 if (IntInit
*II
= dyn_cast
<IntInit
>(Expr
->arg_begin()[2]))
209 PrintFatalError(Loc
, "To must be an integer: " + Expr
->getAsString());
210 if (To
< 0 || To
>= (1 << 30))
211 PrintFatalError(Loc
, "To out of range");
213 RecordKeeper
&Records
=
214 cast
<DefInit
>(Expr
->getOperator())->getDef()->getRecords();
216 Step
*= From
<= To
? 1 : -1;
218 if (Step
> 0 && From
> To
)
220 else if (Step
< 0 && From
< To
)
223 raw_string_ostream
OS(Name
);
224 OS
<< format(Format
.c_str(), unsigned(From
));
225 Record
*Rec
= Records
.getDef(OS
.str());
227 PrintFatalError(Loc
, "No def named '" + Name
+ "': " +
228 Expr
->getAsString());
229 // Try to reevaluate Rec in case it is a set.
230 if (const RecVec
*Result
= ST
.expand(Rec
))
231 Elts
.insert(Result
->begin(), Result
->end());
240 // Expand a Def into a set by evaluating one of its fields.
241 struct FieldExpander
: public SetTheory::Expander
{
244 FieldExpander(StringRef fn
) : FieldName(fn
) {}
246 void expand(SetTheory
&ST
, Record
*Def
, RecSet
&Elts
) override
{
247 ST
.evaluate(Def
->getValueInit(FieldName
), Elts
, Def
->getLoc());
251 } // end anonymous namespace
253 // Pin the vtables to this file.
254 void SetTheory::Operator::anchor() {}
255 void SetTheory::Expander::anchor() {}
257 SetTheory::SetTheory() {
258 addOperator("add", std::make_unique
<AddOp
>());
259 addOperator("sub", std::make_unique
<SubOp
>());
260 addOperator("and", std::make_unique
<AndOp
>());
261 addOperator("shl", std::make_unique
<ShlOp
>());
262 addOperator("trunc", std::make_unique
<TruncOp
>());
263 addOperator("rotl", std::make_unique
<RotOp
>(false));
264 addOperator("rotr", std::make_unique
<RotOp
>(true));
265 addOperator("decimate", std::make_unique
<DecimateOp
>());
266 addOperator("interleave", std::make_unique
<InterleaveOp
>());
267 addOperator("sequence", std::make_unique
<SequenceOp
>());
270 void SetTheory::addOperator(StringRef Name
, std::unique_ptr
<Operator
> Op
) {
271 Operators
[Name
] = std::move(Op
);
274 void SetTheory::addExpander(StringRef ClassName
, std::unique_ptr
<Expander
> E
) {
275 Expanders
[ClassName
] = std::move(E
);
278 void SetTheory::addFieldExpander(StringRef ClassName
, StringRef FieldName
) {
279 addExpander(ClassName
, std::make_unique
<FieldExpander
>(FieldName
));
282 void SetTheory::evaluate(Init
*Expr
, RecSet
&Elts
, ArrayRef
<SMLoc
> Loc
) {
283 // A def in a list can be a just an element, or it may expand.
284 if (DefInit
*Def
= dyn_cast
<DefInit
>(Expr
)) {
285 if (const RecVec
*Result
= expand(Def
->getDef()))
286 return Elts
.insert(Result
->begin(), Result
->end());
287 Elts
.insert(Def
->getDef());
291 // Lists simply expand.
292 if (ListInit
*LI
= dyn_cast
<ListInit
>(Expr
))
293 return evaluate(LI
->begin(), LI
->end(), Elts
, Loc
);
295 // Anything else must be a DAG.
296 DagInit
*DagExpr
= dyn_cast
<DagInit
>(Expr
);
298 PrintFatalError(Loc
, "Invalid set element: " + Expr
->getAsString());
299 DefInit
*OpInit
= dyn_cast
<DefInit
>(DagExpr
->getOperator());
301 PrintFatalError(Loc
, "Bad set expression: " + Expr
->getAsString());
302 auto I
= Operators
.find(OpInit
->getDef()->getName());
303 if (I
== Operators
.end())
304 PrintFatalError(Loc
, "Unknown set operator: " + Expr
->getAsString());
305 I
->second
->apply(*this, DagExpr
, Elts
, Loc
);
308 const RecVec
*SetTheory::expand(Record
*Set
) {
309 // Check existing entries for Set and return early.
310 ExpandMap::iterator I
= Expansions
.find(Set
);
311 if (I
!= Expansions
.end())
314 // This is the first time we see Set. Find a suitable expander.
315 ArrayRef
<std::pair
<Record
*, SMRange
>> SC
= Set
->getSuperClasses();
316 for (const auto &SCPair
: SC
) {
317 // Skip unnamed superclasses.
318 if (!isa
<StringInit
>(SCPair
.first
->getNameInit()))
320 auto I
= Expanders
.find(SCPair
.first
->getName());
321 if (I
!= Expanders
.end()) {
322 // This breaks recursive definitions.
323 RecVec
&EltVec
= Expansions
[Set
];
325 I
->second
->expand(*this, Set
, Elts
);
326 EltVec
.assign(Elts
.begin(), Elts
.end());
331 // Set is not expandable.