Skip to content

Commit 91ccbc6

Browse files
committed
[TableGen] Support named arguments
We provide a way to specify arguments in the form of `name=value` so that we don't have to specify all optional arguments before the one we'd like to change. Required arguments can alse be specified in this way. Note that the argument can only be specified once regardless of the way (named or positional) to specify and positional arguments should be put before named arguments. Reviewed By: reames Differential Revision: https://reviews.llvm.org/D152998
1 parent 82b4368 commit 91ccbc6

File tree

8 files changed

+328
-64
lines changed

8 files changed

+328
-64
lines changed

llvm/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ Changes to building LLVM
9999
Changes to TableGen
100100
-------------------
101101

102+
* Named arguments are supported. Arguments can be specified in the form of
103+
``name=value``.
104+
102105
Changes to Interprocedural Optimizations
103106
----------------------------------------
104107

llvm/docs/TableGen/ProgRef.rst

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ sense after reading the remainder of this guide.
475475
def Foo#i;
476476

477477
.. productionlist::
478-
SimpleValue8: `ClassID` "<" `ValueListNE` ">"
478+
SimpleValue8: `ClassID` "<" `ArgValueList` ">"
479479

480480
This form creates a new anonymous record definition (as would be created by an
481481
unnamed ``def`` inheriting from the given class with the given template
@@ -642,12 +642,31 @@ of the fields of the class or record.
642642
RecordBody: `ParentClassList` `Body`
643643
ParentClassList: [":" `ParentClassListNE`]
644644
ParentClassListNE: `ClassRef` ("," `ClassRef`)*
645-
ClassRef: (`ClassID` | `MultiClassID`) ["<" [`ValueList`] ">"]
645+
ClassRef: (`ClassID` | `MultiClassID`) ["<" [`ArgValueList`] ">"]
646+
ArgValueList: `PostionalArgValueList` [","] `NamedArgValueList`
647+
PostionalArgValueList: [`Value` {"," `Value`}*]
648+
NamedArgValueList: [`NameValue` "=" `Value` {"," `NameValue` "=" `Value`}*]
646649

647650
A :token:`ParentClassList` containing a :token:`MultiClassID` is valid only
648651
in the class list of a ``defm`` statement. In that case, the ID must be the
649652
name of a multiclass.
650653

654+
The argument values can be specified in two forms:
655+
656+
* Positional argument (``value``). The value is assigned to the argument in the
657+
corresponding position. For ``Foo<a0, a1>``, ``a0`` will be assigned to first
658+
argument and ``a1`` will be assigned to second argument.
659+
* Named argument (``name=value``). The value is assigned to the argument with
660+
the specified name. For ``Foo<a=a0, b=a1>``, ``a0`` will be assigned to the
661+
argument with name ``a`` and ``a1`` will be assigned to the argument with
662+
name ``b``.
663+
664+
Required arguments can alse be specified as named argument.
665+
666+
Note that the argument can only be specified once regardless of the way (named
667+
or positional) to specify and positional arguments should be put before named
668+
arguments.
669+
651670
.. productionlist::
652671
Body: ";" | "{" `BodyItem`* "}"
653672
BodyItem: (`Type` | "code") `TokIdentifier` ["=" `Value`] ";"

llvm/include/llvm/TableGen/Record.h

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <optional>
3737
#include <string>
3838
#include <utility>
39+
#include <variant>
3940
#include <vector>
4041

4142
namespace llvm {
@@ -482,11 +483,21 @@ class UnsetInit : public Init {
482483
};
483484

484485
// Represent an argument.
486+
using ArgAuxType = std::variant<unsigned, Init *>;
485487
class ArgumentInit : public Init, public FoldingSetNode {
488+
public:
489+
enum Kind {
490+
Positional,
491+
Named,
492+
};
493+
494+
private:
486495
Init *Value;
496+
ArgAuxType Aux;
487497

488498
protected:
489-
explicit ArgumentInit(Init *Value) : Init(IK_ArgumentInit), Value(Value) {}
499+
explicit ArgumentInit(Init *Value, ArgAuxType Aux)
500+
: Init(IK_ArgumentInit), Value(Value), Aux(Aux) {}
490501

491502
public:
492503
ArgumentInit(const ArgumentInit &) = delete;
@@ -496,14 +507,33 @@ class ArgumentInit : public Init, public FoldingSetNode {
496507

497508
RecordKeeper &getRecordKeeper() const { return Value->getRecordKeeper(); }
498509

499-
static ArgumentInit *get(Init *Value);
510+
static ArgumentInit *get(Init *Value, ArgAuxType Aux);
511+
512+
bool isPositional() const { return Aux.index() == Positional; }
513+
bool isNamed() const { return Aux.index() == Named; }
500514

501515
Init *getValue() const { return Value; }
516+
unsigned getIndex() const {
517+
assert(isPositional() && "Should be positional!");
518+
return std::get<Positional>(Aux);
519+
}
520+
Init *getName() const {
521+
assert(isNamed() && "Should be named!");
522+
return std::get<Named>(Aux);
523+
}
524+
ArgumentInit *cloneWithValue(Init *Value) const { return get(Value, Aux); }
502525

503526
void Profile(FoldingSetNodeID &ID) const;
504527

505528
Init *resolveReferences(Resolver &R) const override;
506-
std::string getAsString() const override { return Value->getAsString(); }
529+
std::string getAsString() const override {
530+
if (isPositional())
531+
return utostr(getIndex()) + ": " + Value->getAsString();
532+
if (isNamed())
533+
return getName()->getAsString() + ": " + Value->getAsString();
534+
llvm_unreachable("Unsupported argument type!");
535+
return "";
536+
}
507537

508538
bool isComplete() const override { return false; }
509539
bool isConcrete() const override { return false; }

llvm/lib/TableGen/Record.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -367,33 +367,40 @@ Init *UnsetInit::convertInitializerTo(RecTy *Ty) const {
367367
return const_cast<UnsetInit *>(this);
368368
}
369369

370-
static void ProfileArgumentInit(FoldingSetNodeID &ID, Init *Value) {
370+
static void ProfileArgumentInit(FoldingSetNodeID &ID, Init *Value,
371+
ArgAuxType Aux) {
372+
auto I = Aux.index();
373+
ID.AddInteger(I);
374+
if (I == ArgumentInit::Positional)
375+
ID.AddInteger(std::get<ArgumentInit::Positional>(Aux));
376+
if (I == ArgumentInit::Named)
377+
ID.AddPointer(std::get<ArgumentInit::Named>(Aux));
371378
ID.AddPointer(Value);
372379
}
373380

374381
void ArgumentInit::Profile(FoldingSetNodeID &ID) const {
375-
ProfileArgumentInit(ID, Value);
382+
ProfileArgumentInit(ID, Value, Aux);
376383
}
377384

378-
ArgumentInit *ArgumentInit::get(Init *Value) {
385+
ArgumentInit *ArgumentInit::get(Init *Value, ArgAuxType Aux) {
379386
FoldingSetNodeID ID;
380-
ProfileArgumentInit(ID, Value);
387+
ProfileArgumentInit(ID, Value, Aux);
381388

382389
RecordKeeper &RK = Value->getRecordKeeper();
383390
detail::RecordKeeperImpl &RKImpl = RK.getImpl();
384391
void *IP = nullptr;
385392
if (ArgumentInit *I = RKImpl.TheArgumentInitPool.FindNodeOrInsertPos(ID, IP))
386393
return I;
387394

388-
ArgumentInit *I = new (RKImpl.Allocator) ArgumentInit(Value);
395+
ArgumentInit *I = new (RKImpl.Allocator) ArgumentInit(Value, Aux);
389396
RKImpl.TheArgumentInitPool.InsertNode(I, IP);
390397
return I;
391398
}
392399

393400
Init *ArgumentInit::resolveReferences(Resolver &R) const {
394401
Init *NewValue = Value->resolveReferences(R);
395402
if (NewValue != Value)
396-
return ArgumentInit::get(NewValue);
403+
return cloneWithValue(NewValue);
397404

398405
return const_cast<ArgumentInit *>(this);
399406
}
@@ -2219,13 +2226,16 @@ DefInit *VarDefInit::instantiate() {
22192226
ArrayRef<Init *> TArgs = Class->getTemplateArgs();
22202227
MapResolver R(NewRec);
22212228

2222-
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
2223-
if (i < args_size())
2224-
R.set(TArgs[i], getArg(i)->getValue());
2225-
else
2226-
R.set(TArgs[i], NewRec->getValue(TArgs[i])->getValue());
2229+
for (unsigned I = 0, E = TArgs.size(); I != E; ++I) {
2230+
R.set(TArgs[I], NewRec->getValue(TArgs[I])->getValue());
2231+
NewRec->removeValue(TArgs[I]);
2232+
}
22272233

2228-
NewRec->removeValue(TArgs[i]);
2234+
for (auto *Arg : args()) {
2235+
if (Arg->isPositional())
2236+
R.set(TArgs[Arg->getIndex()], Arg->getValue());
2237+
if (Arg->isNamed())
2238+
R.set(Arg->getName(), Arg->getValue());
22292239
}
22302240

22312241
NewRec->resolveReferences(R);

0 commit comments

Comments
 (0)