[TableGen] Introduce a `defvar` statement.

Authored by simon_tatham on Jan 14 2020, 1:10 AM.


[TableGen] Introduce a defvar statement.

This allows you to define a global or local variable to an arbitrary
value, and refer to it in subsequent definitions.

The main use I anticipate for this is if you have to compute some
difficult function of the parameters of a multiclass, and then use it
many times. For example:

multiclass Foo<int i, string s> {
  defvar op = !cast<BaseClass>("whatnot_" # s # "_" # i);
  def myRecord {
    dag a = (op this, (op that, the other), (op x, y, z));
    int b = op.subfield;
  def myOtherRecord<"template params including", op>;

There are a couple of ways to do this already, but they're not really
satisfactory. You can replace defvar x = y with a loop over a
singleton list, foreach x = [y] in { ... } - but that's unintuitive
to someone who hasn't seen that workaround idiom before, and requires
an extra pair of braces that you often didn't really want. Or you can
define a nested pair of multiclasses, with the inner one taking x as
a template parameter, and the outer one instantiating it just once
with the desired value of x computed from its other parameters - but
that makes it awkward to sequentially compute each value based on the
previous ones. I think defvar makes things considerably easier.

You can also use defvar at the top level, where it inserts globals
into the same map used by defset. That allows you to define global
constants without having to make a dummy record for them to live in:

defvar MAX_BUFSIZE = 512;

// previously:
// def Dummy { int MAX_BUFSIZE = 512; }
// and then refer to Dummy.MAX_BUFSIZE everywhere

Reviewers: nhaehnle, hfinkel

Reviewed By: hfinkel

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D71407