brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.9 KiB · b98b72b Raw
745 lines · c
1#include <isl/id.h>2#include <isl/val.h>3#include <isl/schedule.h>4#include <isl/stream.h>5#include <isl_schedule_private.h>6#include <isl_schedule_tree.h>7 8/* An enumeration of the various keys that may appear in a YAML mapping9 * of a schedule.10 */11enum isl_schedule_key {12	isl_schedule_key_error = -1,13	isl_schedule_key_child,14	isl_schedule_key_coincident,15	isl_schedule_key_context,16	isl_schedule_key_contraction,17	isl_schedule_key_domain,18	isl_schedule_key_expansion,19	isl_schedule_key_extension,20	isl_schedule_key_filter,21	isl_schedule_key_guard,22	isl_schedule_key_leaf,23	isl_schedule_key_mark,24	isl_schedule_key_options,25	isl_schedule_key_permutable,26	isl_schedule_key_schedule,27	isl_schedule_key_sequence,28	isl_schedule_key_set,29	isl_schedule_key_end30};31 32/* Textual representations of the YAML keys for an isl_schedule object.33 */34static char *key_str[] = {35	[isl_schedule_key_child] = "child",36	[isl_schedule_key_coincident] = "coincident",37	[isl_schedule_key_context] = "context",38	[isl_schedule_key_contraction] = "contraction",39	[isl_schedule_key_domain] = "domain",40	[isl_schedule_key_expansion] = "expansion",41	[isl_schedule_key_extension] = "extension",42	[isl_schedule_key_filter] = "filter",43	[isl_schedule_key_guard] = "guard",44	[isl_schedule_key_leaf] = "leaf",45	[isl_schedule_key_mark] = "mark",46	[isl_schedule_key_options] = "options",47	[isl_schedule_key_permutable] = "permutable",48	[isl_schedule_key_schedule] = "schedule",49	[isl_schedule_key_sequence] = "sequence",50	[isl_schedule_key_set] = "set",51};52 53#undef KEY54#define KEY enum isl_schedule_key55#undef KEY_ERROR56#define KEY_ERROR isl_schedule_key_error57#undef KEY_END58#define KEY_END isl_schedule_key_end59#undef KEY_STR60#define KEY_STR key_str61#undef KEY_EXTRACT62#define KEY_EXTRACT extract_key63#undef KEY_GET64#define KEY_GET get_key65#include "extract_key.c"66 67static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree(68	__isl_keep isl_stream *s);69 70/* Read a subtree with context root node from "s".71 */72static __isl_give isl_schedule_tree *read_context(__isl_keep isl_stream *s)73{74	isl_set *context = NULL;75	isl_schedule_tree *tree;76	isl_ctx *ctx;77	struct isl_token *tok;78	enum isl_schedule_key key;79	char *str;80	isl_bool more;81 82	ctx = isl_stream_get_ctx(s);83 84	key = get_key(s);85 86	if (isl_stream_yaml_next(s) < 0)87		return NULL;88 89	tok = isl_stream_next_token(s);90	if (!tok) {91		isl_stream_error(s, NULL, "unexpected EOF");92		return NULL;93	}94	str = isl_token_get_str(ctx, tok);95	context = isl_set_read_from_str(ctx, str);96	free(str);97	isl_token_free(tok);98 99	more = isl_stream_yaml_next(s);100	if (more < 0)101		goto error;102	if (!more) {103		tree = isl_schedule_tree_from_context(context);104	} else {105		key = get_key(s);106		if (key != isl_schedule_key_child)107			isl_die(ctx, isl_error_invalid, "expecting child",108				goto error);109		if (isl_stream_yaml_next(s) < 0)110			goto error;111		tree = isl_stream_read_schedule_tree(s);112		tree = isl_schedule_tree_insert_context(tree, context);113	}114 115	return tree;116error:117	isl_set_free(context);118	return NULL;119}120 121/* Read a subtree with domain root node from "s".122 */123static __isl_give isl_schedule_tree *read_domain(__isl_keep isl_stream *s)124{125	isl_union_set *domain = NULL;126	isl_schedule_tree *tree;127	isl_ctx *ctx;128	struct isl_token *tok;129	enum isl_schedule_key key;130	char *str;131	isl_bool more;132 133	ctx = isl_stream_get_ctx(s);134 135	key = get_key(s);136 137	if (isl_stream_yaml_next(s) < 0)138		return NULL;139 140	tok = isl_stream_next_token(s);141	if (!tok) {142		isl_stream_error(s, NULL, "unexpected EOF");143		return NULL;144	}145	str = isl_token_get_str(ctx, tok);146	domain = isl_union_set_read_from_str(ctx, str);147	free(str);148	isl_token_free(tok);149 150	more = isl_stream_yaml_next(s);151	if (more < 0)152		goto error;153	if (!more) {154		tree = isl_schedule_tree_from_domain(domain);155	} else {156		key = get_key(s);157		if (key != isl_schedule_key_child)158			isl_die(ctx, isl_error_invalid, "expecting child",159				goto error);160		if (isl_stream_yaml_next(s) < 0)161			goto error;162		tree = isl_stream_read_schedule_tree(s);163		tree = isl_schedule_tree_insert_domain(tree, domain);164	}165 166	return tree;167error:168	isl_union_set_free(domain);169	return NULL;170}171 172/* Read a subtree with expansion root node from "s".173 */174static __isl_give isl_schedule_tree *read_expansion(isl_stream *s)175{176	isl_ctx *ctx;177	isl_union_pw_multi_aff *contraction = NULL;178	isl_union_map *expansion = NULL;179	isl_schedule_tree *tree = NULL;180	isl_bool more;181 182	ctx = isl_stream_get_ctx(s);183 184	do {185		struct isl_token *tok;186		enum isl_schedule_key key;187		char *str;188 189		key = get_key(s);190		if (isl_stream_yaml_next(s) < 0)191			goto error;192 193		switch (key) {194		case isl_schedule_key_contraction:195			isl_union_pw_multi_aff_free(contraction);196			tok = isl_stream_next_token(s);197			str = isl_token_get_str(ctx, tok);198			contraction = isl_union_pw_multi_aff_read_from_str(ctx,199									str);200			free(str);201			isl_token_free(tok);202			if (!contraction)203				goto error;204			break;205		case isl_schedule_key_expansion:206			isl_union_map_free(expansion);207			tok = isl_stream_next_token(s);208			str = isl_token_get_str(ctx, tok);209			expansion = isl_union_map_read_from_str(ctx, str);210			free(str);211			isl_token_free(tok);212			if (!expansion)213				goto error;214			break;215		case isl_schedule_key_child:216			isl_schedule_tree_free(tree);217			tree = isl_stream_read_schedule_tree(s);218			if (!tree)219				goto error;220			break;221		default:222			isl_die(ctx, isl_error_invalid, "unexpected key",223				goto error);224		}225	} while ((more = isl_stream_yaml_next(s)) == isl_bool_true);226 227	if (more < 0)228		goto error;229 230	if (!contraction)231		isl_die(ctx, isl_error_invalid, "missing contraction",232			goto error);233	if (!expansion)234		isl_die(ctx, isl_error_invalid, "missing expansion",235			goto error);236 237	if (!tree)238		return isl_schedule_tree_from_expansion(contraction, expansion);239	return isl_schedule_tree_insert_expansion(tree, contraction, expansion);240error:241	isl_schedule_tree_free(tree);242	isl_union_pw_multi_aff_free(contraction);243	isl_union_map_free(expansion);244	return NULL;245}246 247/* Read a subtree with extension root node from "s".248 */249static __isl_give isl_schedule_tree *read_extension(isl_stream *s)250{251	isl_union_map *extension = NULL;252	isl_schedule_tree *tree;253	isl_ctx *ctx;254	struct isl_token *tok;255	enum isl_schedule_key key;256	char *str;257	isl_bool more;258 259	ctx = isl_stream_get_ctx(s);260 261	key = get_key(s);262 263	if (isl_stream_yaml_next(s) < 0)264		return NULL;265 266	tok = isl_stream_next_token(s);267	if (!tok) {268		isl_stream_error(s, NULL, "unexpected EOF");269		return NULL;270	}271	str = isl_token_get_str(ctx, tok);272	extension = isl_union_map_read_from_str(ctx, str);273	free(str);274	isl_token_free(tok);275 276	more = isl_stream_yaml_next(s);277	if (more < 0)278		goto error;279	if (!more) {280		tree = isl_schedule_tree_from_extension(extension);281	} else {282		key = get_key(s);283		if (key != isl_schedule_key_child)284			isl_die(ctx, isl_error_invalid, "expecting child",285				goto error);286		if (isl_stream_yaml_next(s) < 0)287			goto error;288		tree = isl_stream_read_schedule_tree(s);289		tree = isl_schedule_tree_insert_extension(tree, extension);290	}291 292	return tree;293error:294	isl_union_map_free(extension);295	return NULL;296}297 298/* Read a subtree with filter root node from "s".299 */300static __isl_give isl_schedule_tree *read_filter(__isl_keep isl_stream *s)301{302	isl_union_set *filter = NULL;303	isl_schedule_tree *tree;304	isl_ctx *ctx;305	struct isl_token *tok;306	enum isl_schedule_key key;307	char *str;308	isl_bool more;309 310	ctx = isl_stream_get_ctx(s);311 312	key = get_key(s);313 314	if (isl_stream_yaml_next(s) < 0)315		return NULL;316 317	tok = isl_stream_next_token(s);318	if (!tok) {319		isl_stream_error(s, NULL, "unexpected EOF");320		return NULL;321	}322	str = isl_token_get_str(ctx, tok);323	filter = isl_union_set_read_from_str(ctx, str);324	free(str);325	isl_token_free(tok);326 327	more = isl_stream_yaml_next(s);328	if (more < 0)329		goto error;330	if (!more) {331		tree = isl_schedule_tree_from_filter(filter);332	} else {333		key = get_key(s);334		if (key != isl_schedule_key_child)335			isl_die(ctx, isl_error_invalid, "expecting child",336				goto error);337		if (isl_stream_yaml_next(s) < 0)338			goto error;339		tree = isl_stream_read_schedule_tree(s);340		tree = isl_schedule_tree_insert_filter(tree, filter);341	}342 343	return tree;344error:345	isl_union_set_free(filter);346	return NULL;347}348 349/* Read a subtree with guard root node from "s".350 */351static __isl_give isl_schedule_tree *read_guard(isl_stream *s)352{353	isl_set *guard = NULL;354	isl_schedule_tree *tree;355	isl_ctx *ctx;356	struct isl_token *tok;357	enum isl_schedule_key key;358	char *str;359	isl_bool more;360 361	ctx = isl_stream_get_ctx(s);362 363	key = get_key(s);364 365	if (isl_stream_yaml_next(s) < 0)366		return NULL;367 368	tok = isl_stream_next_token(s);369	if (!tok) {370		isl_stream_error(s, NULL, "unexpected EOF");371		return NULL;372	}373	str = isl_token_get_str(ctx, tok);374	guard = isl_set_read_from_str(ctx, str);375	free(str);376	isl_token_free(tok);377 378	more = isl_stream_yaml_next(s);379	if (more < 0)380		goto error;381	if (!more) {382		tree = isl_schedule_tree_from_guard(guard);383	} else {384		key = get_key(s);385		if (key != isl_schedule_key_child)386			isl_die(ctx, isl_error_invalid, "expecting child",387				goto error);388		if (isl_stream_yaml_next(s) < 0)389			goto error;390		tree = isl_stream_read_schedule_tree(s);391		tree = isl_schedule_tree_insert_guard(tree, guard);392	}393 394	return tree;395error:396	isl_set_free(guard);397	return NULL;398}399 400/* Read a subtree with mark root node from "s".401 */402static __isl_give isl_schedule_tree *read_mark(isl_stream *s)403{404	isl_id *mark;405	isl_schedule_tree *tree;406	isl_ctx *ctx;407	struct isl_token *tok;408	enum isl_schedule_key key;409	char *str;410	isl_bool more;411 412	ctx = isl_stream_get_ctx(s);413 414	key = get_key(s);415 416	if (isl_stream_yaml_next(s) < 0)417		return NULL;418 419	tok = isl_stream_next_token(s);420	if (!tok) {421		isl_stream_error(s, NULL, "unexpected EOF");422		return NULL;423	}424	str = isl_token_get_str(ctx, tok);425	mark = isl_id_alloc(ctx, str, NULL);426	free(str);427	isl_token_free(tok);428 429	more = isl_stream_yaml_next(s);430	if (more < 0)431		goto error;432	if (!more) {433		isl_die(ctx, isl_error_invalid, "expecting child",434			goto error);435	} else {436		key = get_key(s);437		if (key != isl_schedule_key_child)438			isl_die(ctx, isl_error_invalid, "expecting child",439				goto error);440		if (isl_stream_yaml_next(s) < 0)441			goto error;442		tree = isl_stream_read_schedule_tree(s);443		tree = isl_schedule_tree_insert_mark(tree, mark);444	}445 446	return tree;447error:448	isl_id_free(mark);449	return NULL;450}451 452#undef EL_BASE453#define EL_BASE val454 455#include <isl_list_read_yaml_templ.c>456 457/* Read a sequence of integers from "s" (representing the coincident458 * property of a band node).459 */460static __isl_give isl_val_list *read_coincident(__isl_keep isl_stream *s)461{462	return isl_stream_yaml_read_val_list(s);463}464 465/* Set the (initial) coincident properties of "band" according to466 * the (initial) elements of "coincident".467 */468static __isl_give isl_schedule_band *set_coincident(469	__isl_take isl_schedule_band *band, __isl_take isl_val_list *coincident)470{471	int i;472	isl_size n, m;473 474	n = isl_schedule_band_n_member(band);475	m = isl_val_list_n_val(coincident);476	if (n < 0 || m < 0)477		band = isl_schedule_band_free(band);478 479	for (i = 0; i < n && i < m; ++i) {480		isl_val *v;481 482		v = isl_val_list_get_val(coincident, i);483		if (!v)484			band = isl_schedule_band_free(band);485		band = isl_schedule_band_member_set_coincident(band, i,486							!isl_val_is_zero(v));487		isl_val_free(v);488	}489	isl_val_list_free(coincident);490	return band;491}492 493/* Read a subtree with band root node from "s".494 */495static __isl_give isl_schedule_tree *read_band(isl_stream *s)496{497	isl_multi_union_pw_aff *schedule = NULL;498	isl_schedule_tree *tree = NULL;499	isl_val_list *coincident = NULL;500	isl_union_set *options = NULL;501	isl_ctx *ctx;502	isl_schedule_band *band;503	int permutable = 0;504	isl_bool more;505 506	ctx = isl_stream_get_ctx(s);507 508	do {509		struct isl_token *tok;510		enum isl_schedule_key key;511		char *str;512		isl_val *v;513 514		key = get_key(s);515		if (isl_stream_yaml_next(s) < 0)516			goto error;517 518		switch (key) {519		case isl_schedule_key_schedule:520			schedule = isl_multi_union_pw_aff_free(schedule);521			tok = isl_stream_next_token(s);522			if (!tok) {523				isl_stream_error(s, NULL, "unexpected EOF");524				goto error;525			}526			str = isl_token_get_str(ctx, tok);527			schedule = isl_multi_union_pw_aff_read_from_str(ctx,528									str);529			free(str);530			isl_token_free(tok);531			if (!schedule)532				goto error;533			break;534		case isl_schedule_key_coincident:535			coincident = read_coincident(s);536			if (!coincident)537				goto error;538			break;539		case isl_schedule_key_permutable:540			v = isl_stream_read_val(s);541			permutable = !isl_val_is_zero(v);542			isl_val_free(v);543			break;544		case isl_schedule_key_options:545			isl_union_set_free(options);546			tok = isl_stream_next_token(s);547			str = isl_token_get_str(ctx, tok);548			options = isl_union_set_read_from_str(ctx, str);549			free(str);550			isl_token_free(tok);551			if (!options)552				goto error;553			break;554		case isl_schedule_key_child:555			isl_schedule_tree_free(tree);556			tree = isl_stream_read_schedule_tree(s);557			if (!tree)558				goto error;559			break;560		default:561			isl_die(ctx, isl_error_invalid, "unexpected key",562				goto error);563		}564	} while ((more = isl_stream_yaml_next(s)) == isl_bool_true);565 566	if (more < 0)567		goto error;568 569	if (!schedule)570		isl_die(ctx, isl_error_invalid, "missing schedule", goto error);571 572	band = isl_schedule_band_from_multi_union_pw_aff(schedule);573	band = isl_schedule_band_set_permutable(band, permutable);574	if (coincident)575		band = set_coincident(band, coincident);576	if (options)577		band = isl_schedule_band_set_ast_build_options(band, options);578	if (tree)579		tree = isl_schedule_tree_insert_band(tree, band);580	else581		tree = isl_schedule_tree_from_band(band);582 583	return tree;584error:585	isl_val_list_free(coincident);586	isl_union_set_free(options);587	isl_schedule_tree_free(tree);588	isl_multi_union_pw_aff_free(schedule);589	return NULL;590}591 592#undef EL_BASE593#define EL_BASE schedule_tree594 595#include <isl_list_read_yaml_templ.c>596 597/* Read a subtree with root node of type "type" from "s".598 * The node is represented by a sequence of children.599 */600static __isl_give isl_schedule_tree *read_children(isl_stream *s,601	enum isl_schedule_node_type type)602{603	isl_schedule_tree_list *list;604 605	isl_token_free(isl_stream_next_token(s));606 607	if (isl_stream_yaml_next(s) < 0)608		return NULL;609 610	list = isl_stream_yaml_read_schedule_tree_list(s);611 612	return isl_schedule_tree_from_children(type, list);613}614 615/* Read a subtree with sequence root node from "s".616 */617static __isl_give isl_schedule_tree *read_sequence(isl_stream *s)618{619	return read_children(s, isl_schedule_node_sequence);620}621 622/* Read a subtree with set root node from "s".623 */624static __isl_give isl_schedule_tree *read_set(isl_stream *s)625{626	return read_children(s, isl_schedule_node_set);627}628 629/* Read a schedule (sub)tree from "s".630 *631 * We first determine the type of the root node based on the first632 * mapping key and then hand over to a function tailored to reading633 * nodes of this type.634 */635static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree(636	struct isl_stream *s)637{638	enum isl_schedule_key key;639	struct isl_token *tok;640	isl_schedule_tree *tree = NULL;641	isl_bool more;642 643	if (isl_stream_yaml_read_start_mapping(s) < 0)644		return NULL;645	more = isl_stream_yaml_next(s);646	if (more < 0)647		return NULL;648	if (!more) {649		isl_stream_error(s, NULL, "missing key");650		return NULL;651	}652 653	tok = isl_stream_next_token(s);654	key = extract_key(s, tok);655	isl_stream_push_token(s, tok);656	if (key < 0)657		return NULL;658	switch (key) {659	case isl_schedule_key_context:660		tree = read_context(s);661		break;662	case isl_schedule_key_domain:663		tree = read_domain(s);664		break;665	case isl_schedule_key_contraction:666	case isl_schedule_key_expansion:667		tree = read_expansion(s);668		break;669	case isl_schedule_key_extension:670		tree = read_extension(s);671		break;672	case isl_schedule_key_filter:673		tree = read_filter(s);674		break;675	case isl_schedule_key_guard:676		tree = read_guard(s);677		break;678	case isl_schedule_key_leaf:679		isl_token_free(isl_stream_next_token(s));680		tree = isl_schedule_tree_leaf(isl_stream_get_ctx(s));681		break;682	case isl_schedule_key_mark:683		tree = read_mark(s);684		break;685	case isl_schedule_key_sequence:686		tree = read_sequence(s);687		break;688	case isl_schedule_key_set:689		tree = read_set(s);690		break;691	case isl_schedule_key_schedule:692	case isl_schedule_key_coincident:693	case isl_schedule_key_options:694	case isl_schedule_key_permutable:695		tree = read_band(s);696		break;697	case isl_schedule_key_child:698		isl_die(isl_stream_get_ctx(s), isl_error_unsupported,699			"cannot identify node type", return NULL);700	case isl_schedule_key_end:701	case isl_schedule_key_error:702		return NULL;703	}704 705	if (isl_stream_yaml_read_end_mapping(s) < 0)706		return isl_schedule_tree_free(tree);707 708	return tree;709}710 711/* Read an isl_schedule from "s".712 */713__isl_give isl_schedule *isl_stream_read_schedule(isl_stream *s)714{715	isl_ctx *ctx;716	isl_schedule_tree *tree;717 718	if (!s)719		return NULL;720 721	ctx = isl_stream_get_ctx(s);722	tree = isl_stream_read_schedule_tree(s);723	return isl_schedule_from_schedule_tree(ctx, tree);724}725 726/* Read an isl_schedule from "input".727 */728__isl_give isl_schedule *isl_schedule_read_from_file(isl_ctx *ctx, FILE *input)729{730	struct isl_stream *s;731	isl_schedule *schedule;732 733	s = isl_stream_new_file(ctx, input);734	if (!s)735		return NULL;736	schedule = isl_stream_read_schedule(s);737	isl_stream_free(s);738 739	return schedule;740}741 742#undef TYPE_BASE743#define TYPE_BASE	schedule744#include "isl_read_from_str_templ.c"745