xref: /freebsd/contrib/llvm-project/llvm/lib/TableGen/SetTheory.cpp (revision 1edc20b76953d9ef571b0bcf89b206b98ed13d9b)
1  //===- SetTheory.cpp - Generate ordered sets from DAG expressions ---------===//
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 SetTheory class that computes ordered sets of
10  // Records from DAG expressions.
11  //
12  //===----------------------------------------------------------------------===//
13  
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"
24  #include <algorithm>
25  #include <cstdint>
26  #include <string>
27  #include <utility>
28  
29  using namespace llvm;
30  
31  // Define the standard operators.
32  namespace {
33  
34  using RecSet = SetTheory::RecSet;
35  using RecVec = SetTheory::RecVec;
36  
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);
42    }
43  };
44  
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: " +
51          Expr->getAsString());
52      RecSet Add, Sub;
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)
56        if (!Sub.count(I))
57          Elts.insert(I);
58    }
59  };
60  
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: " +
67          Expr->getAsString());
68      RecSet S1, S2;
69      ST.evaluate(Expr->arg_begin()[0], S1, Loc);
70      ST.evaluate(Expr->arg_begin()[1], S2, Loc);
71      for (const auto &I : S1)
72        if (S2.count(I))
73          Elts.insert(I);
74    }
75  };
76  
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;
81  
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: " +
86          Expr->getAsString());
87      RecSet Set;
88      ST.evaluate(Expr->arg_begin()[0], Set, Loc);
89      IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[1]);
90      if (!II)
91        PrintFatalError(Loc, "Second argument must be an integer: " +
92          Expr->getAsString());
93      apply2(ST, Expr, Set, II->getValue(), Elts, Loc);
94    }
95  };
96  
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 {
101      if (N < 0)
102        PrintFatalError(Loc, "Positive shift required: " +
103          Expr->getAsString());
104      if (unsigned(N) < Set.size())
105        Elts.insert(Set.begin() + N, Set.end());
106    }
107  };
108  
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 {
113      if (N < 0)
114        PrintFatalError(Loc, "Positive length required: " +
115          Expr->getAsString());
116      if (unsigned(N) > Set.size())
117        N = Set.size();
118      Elts.insert(Set.begin(), Set.begin() + N);
119    }
120  };
121  
122  // Left/right rotation.
123  struct RotOp : public SetIntBinOp {
124    const bool Reverse;
125  
126    RotOp(bool Rev) : Reverse(Rev) {}
127  
128    void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N,
129                RecSet &Elts, ArrayRef<SMLoc> Loc) override {
130      if (Reverse)
131        N = -N;
132      // N > 0 -> rotate left, N < 0 -> rotate right.
133      if (Set.empty())
134        return;
135      if (N < 0)
136        N = Set.size() - (-N % Set.size());
137      else
138        N %= Set.size();
139      Elts.insert(Set.begin() + N, Set.end());
140      Elts.insert(Set.begin(), Set.begin() + N);
141    }
142  };
143  
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 {
148      if (N <= 0)
149        PrintFatalError(Loc, "Positive stride required: " +
150          Expr->getAsString());
151      for (unsigned I = 0; I < Set.size(); I += N)
152        Elts.insert(Set[I]);
153    }
154  };
155  
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()));
166      }
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]);
172    }
173  };
174  
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 {
179      int Step = 1;
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();
186        } else
187          PrintFatalError(Loc, "Stride must be an integer: " +
188            Expr->getAsString());
189      }
190  
191      std::string Format;
192      if (StringInit *SI = dyn_cast<StringInit>(Expr->arg_begin()[0]))
193        Format = std::string(SI->getValue());
194      else
195        PrintFatalError(Loc,  "Format must be a string: " + Expr->getAsString());
196  
197      int64_t From, To;
198      if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[1]))
199        From = II->getValue();
200      else
201        PrintFatalError(Loc, "From must be an integer: " + Expr->getAsString());
202      if (From < 0 || From >= (1 << 30))
203        PrintFatalError(Loc, "From out of range");
204  
205      if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[2]))
206        To = II->getValue();
207      else
208        PrintFatalError(Loc, "To must be an integer: " + Expr->getAsString());
209      if (To < 0 || To >= (1 << 30))
210        PrintFatalError(Loc, "To out of range");
211  
212      RecordKeeper &Records =
213        cast<DefInit>(Expr->getOperator())->getDef()->getRecords();
214  
215      Step *= From <= To ? 1 : -1;
216      while (true) {
217        if (Step > 0 && From > To)
218          break;
219        else if (Step < 0 && From < To)
220          break;
221        std::string Name;
222        raw_string_ostream OS(Name);
223        OS << format(Format.c_str(), unsigned(From));
224        Record *Rec = Records.getDef(OS.str());
225        if (!Rec)
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());
231        else
232          Elts.insert(Rec);
233  
234        From += Step;
235      }
236    }
237  };
238  
239  // Expand a Def into a set by evaluating one of its fields.
240  struct FieldExpander : public SetTheory::Expander {
241    StringRef FieldName;
242  
243    FieldExpander(StringRef fn) : FieldName(fn) {}
244  
245    void expand(SetTheory &ST, Record *Def, RecSet &Elts) override {
246      ST.evaluate(Def->getValueInit(FieldName), Elts, Def->getLoc());
247    }
248  };
249  
250  } // end anonymous namespace
251  
252  // Pin the vtables to this file.
253  void SetTheory::Operator::anchor() {}
254  void SetTheory::Expander::anchor() {}
255  
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>());
267  }
268  
269  void SetTheory::addOperator(StringRef Name, std::unique_ptr<Operator> Op) {
270    Operators[Name] = std::move(Op);
271  }
272  
273  void SetTheory::addExpander(StringRef ClassName, std::unique_ptr<Expander> E) {
274    Expanders[ClassName] = std::move(E);
275  }
276  
277  void SetTheory::addFieldExpander(StringRef ClassName, StringRef FieldName) {
278    addExpander(ClassName, std::make_unique<FieldExpander>(FieldName));
279  }
280  
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());
287      return;
288    }
289  
290    // Lists simply expand.
291    if (ListInit *LI = dyn_cast<ListInit>(Expr))
292      return evaluate(LI->begin(), LI->end(), Elts, Loc);
293  
294    // Anything else must be a DAG.
295    DagInit *DagExpr = dyn_cast<DagInit>(Expr);
296    if (!DagExpr)
297      PrintFatalError(Loc, "Invalid set element: " + Expr->getAsString());
298    DefInit *OpInit = dyn_cast<DefInit>(DagExpr->getOperator());
299    if (!OpInit)
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);
305  }
306  
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())
311      return &I->second;
312  
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()))
318        continue;
319      auto I = Expanders.find(SCPair.first->getName());
320      if (I != Expanders.end()) {
321        // This breaks recursive definitions.
322        RecVec &EltVec = Expansions[Set];
323        RecSet Elts;
324        I->second->expand(*this, Set, Elts);
325        EltVec.assign(Elts.begin(), Elts.end());
326        return &EltVec;
327      }
328    }
329  
330    // Set is not expandable.
331    return nullptr;
332  }
333