This is an archive of the discontinued LLVM Phabricator instance.

[tablegen] Add !listconcat operator with the similar semantics as !strconcat
ClosedPublic

Authored by dsanders on Apr 25 2014, 4:41 AM.

Details

Summary

It concatenates two or more lists. In addition to the !strconcat semantics
the lists must have the same element type.

My overall aim is to make it easy to append to Instruction.Predicates
rather than override it. This can be done by concatenating lists passed as
arguments, or by concatenating lists passed in additional fields.

Diff Detail

Event Timeline

dsanders updated this revision to Diff 8836.Apr 25 2014, 4:41 AM
dsanders retitled this revision from to [tablegen] Add !listconcat operator with the similar semantics as !strconcat.
dsanders updated this object.
dsanders edited the test plan for this revision. (Show Details)
dsanders added a subscriber: Unknown Object (MLST).

Unfortunately it's not possible to do something like:
let Predicates = !listconcat(Predicates, [Foo])
this is a general problem with let statements. Tablegen expands all references after overwriting the value so it expands to:
let Predicates = !listconcat(!listconcat(?, Predicates), [Foo])
which isn't very useful. I had follow-on patches that evaluated self-references before overwriting the old value (to give an overall bottom-up left-to-right evaluation order) but I've since found there are a number of nasty corner cases (mostly involving multiclasses) which seem unsolvable.

The code style I'm now aiming for is a compromise that works around this issue:
class PredicateControl {

		list<Predicate> ISAPredicates = [];
		list<Predicate> EncodingPredicates = [];
		list<Predicate> AdditionalPredicates = [];
		list<Predicate> Predicates = !listconcat(ISAPredicates, EncodingPredicates, AdditionalPredicates);

}

class InstSE<...> { let EncodingPredicates = [StandardEncoding]; }
class InstMicromips<...> { let EncodingPredicates = [MicromipsEncoding]; }

let AdditionalPredicates = [SomePredicate] in {

		def ADD<...> : InstSE<...> { let ISAPredicates = [Mips32]; }
		def DADD<...> : InstSE<...> { let ISAPredicates = [Mips64]; }
		def ADD_Micromips<...> : InstMicromips<...> { let ISAPredicates = [Mips32]; }

}

Each field corresponds to the mutually exclusive groups of predicates. Variable references are evaluated after all the let statements so the defs in this example expand to:
def ADD {

		list<Predicate> ISAPredicates = [Mips32];
		list<Predicate> EncodingPredicates = [StandardEncoding];
		list<Predicate> AdditionalPredicates = [SomePredicate];
		list<Predicate> Predicates = [Mips32, StandardEncoding, SomePredicate];

}
def DADD {

		list<Predicate> ISAPredicates = [Mips64];
		list<Predicate> EncodingPredicates = [StandardEncoding];
		list<Predicate> AdditionalPredicates = [SomePredicate];
		list<Predicate> Predicates = [Mips64, StandardEncoding, SomePredicate];

}
def ADD_Micromips {

		list<Predicate> ISAPredicates = [Mips32];
		list<Predicate> EncodingPredicates = [MicromipsEncoding];
		list<Predicate> AdditionalPredicates = [SomePredicate];
		list<Predicate> Predicates = [Mips32, MicromipsEncoding, SomePredicate];

}

-----Original Message-----
From: Owen Anderson [mailto:resistor@mac.com]
Sent: 25 April 2014 17:30
To: reviews+D3506+public+2168deb848d01400@reviews.llvm.org
Cc: Daniel Sanders; llvm-commits@cs.uiuc.edu
Subject: Re: [PATCH] [tablegen] Add !listconcat operator with the similar
semantics as !strconcat

What are the evaluation order semantics of this? If I have several levels of
class/multiclass hierarchy, each doing a concatenation, what order do they
happen in?

-Owen

dsanders updated this revision to Diff 9038.May 2 2014, 11:43 AM
  • !listconcat(a, b) -> !listconcat(a, b, ...) following a suggestion in the review of D3485 (!strconcat)

I'm sorry to ping this patch again so soon but it's a bottleneck for a patch-series that adds assembler-only implementations of MIPS-I, MIPS-II, MIPS-III, and MIPS-V which has become quite important. It has become important because the it is itself a bottleneck for the minimal, functionally correct MIPS64r6 compiler we are urgently working on (we currently aim to get minimal MIPS64r6 support upstream by the end of the month). I could potentially re-work the dependent patch-series to override Instruction.Predicates instead of sublists that are concatenated to form the full predicates list but this is rather bug prone (while implementing MIPS-I to MIPS-V I found several cases of accidentally removing HasStdEnc with a 'let Predicates = ...' statement) and will require a significant amount of time.

Could someone review this patch which adds a !listconcat operator?

hfinkel added a subscriber: hfinkel.May 7 2014, 2:29 AM

LGTM. Thanks!

docs/TableGen/LangIntro.rst
170

While you're here, can you also add a comment about what strconcat does with multiple arguments (a separate commit is fine).

dsanders accepted this revision.May 7 2014, 3:04 AM
dsanders added a reviewer: dsanders.

Thanks!

docs/TableGen/LangIntro.rst
170

Already done in r207865.

This revision is now accepted and ready to land.May 7 2014, 3:04 AM
dsanders closed this revision.May 7 2014, 3:20 AM