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

Daniel Sanders daniel.sanders at imgtec.com
Fri Apr 25 11:19:38 PDT 2014


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 at mac.com]
> Sent: 25 April 2014 17:30
> To: reviews+D3506+public+2168deb848d01400 at reviews.llvm.org
> Cc: Daniel Sanders; llvm-commits at 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
>

http://reviews.llvm.org/D3506






More information about the llvm-commits mailing list