1#include <stdio.h>
2#include <cloog/cloog.h>
3
4/* Generate code that scans part of the parameter domain of
5 * a given cloog problem, running both a function called "good"
6 * and a function called "test" for each value of the parameters.
7 * These functions are assumed to call the "hash" function,
8 * which is also generated by this program.
9 * If for any given value of the parameters, the final hash
10 * value computed by test is different from that computed by
11 * good, then an error is reported.
12 */
13
14CloogDomain *get_param_domain(CloogOptions *options)
15{
16	CloogDomain *domain;
17	CloogProgram *program;
18
19	program = cloog_program_read(stdin, options);
20
21	domain = cloog_domain_copy(program->context);
22
23	cloog_program_free(program);
24
25	return cloog_domain_from_context(domain);
26}
27
28static const char preamble[] =
29"#include <assert.h>\n"
30"#include <stdio.h>\n"
31"\n"
32"static unsigned h;\n"
33"\n"
34"void hash(int v)\n"
35"{\n"
36"	int i;\n"
37"	union u {\n"
38"		int v;\n"
39"		unsigned char c[1];\n"
40"	} u;\n"
41"	u.v = v;\n"
42"	for (i = 0; i < sizeof(int); ++i) {\n"
43" 		h *= 16777619;\n"
44"		h ^= u.c[i];\n"
45"	}\n"
46"}\n"
47"\n"
48"int main()\n"
49"{\n"
50"	unsigned h_good, h_test;\n";
51;
52
53static const char postamble[] =
54"	return 0;\n"
55"}\n"
56;
57
58static const char *call[] = {"good", "test"};
59
60static void print_macros(FILE *file)
61{
62	fprintf(file, "/* Useful macros. */\n") ;
63	fprintf(file,
64	    "#define floord(n,d) (((n)<0) ? -((-(n)+(d)-1)/(d)) : (n)/(d))\n");
65	fprintf(file,
66	    "#define ceild(n,d) (((n)<0) ? -((-(n))/(d)) : ((n)+(d)-1)/(d))\n");
67	fprintf(file, "#define max(x,y)    ((x) > (y) ? (x) : (y))\n") ;
68	fprintf(file, "#define min(x,y)    ((x) < (y) ? (x) : (y))\n\n") ;
69}
70
71int main()
72{
73	int dim;
74	int range;
75	int i, j;
76	CloogState *state = cloog_state_malloc();
77	CloogOptions *options = cloog_options_malloc(state);
78	CloogDomain *domain;
79	CloogDomain *cube, *tmp;
80	CloogProgram *p;
81	CloogStatement *statement;
82	cloog_int_t m, M;
83
84	options->quiet = 1;
85	domain = get_param_domain(options);
86	dim = cloog_domain_dimension(domain);
87
88	if (dim >= 8)
89		range = 4;
90	else if (dim >= 5)
91		range = 6;
92	else
93		range = 30;
94
95	cloog_int_init(m);
96	cloog_int_init(M);
97	cloog_int_set_si(m, 0);
98	cloog_int_set_si(M, range);
99	cube = cloog_domain_cube(state, dim, m, M);
100	domain = cloog_domain_intersection(tmp = domain, cube);
101	cloog_domain_free(tmp);
102	cloog_domain_free(cube);
103
104	p = cloog_program_malloc();
105	assert(p);
106	p->names = cloog_names_malloc();
107	assert(p->names);
108	p->names->nb_iterators = dim;
109	p->names->iterators = cloog_names_generate_items(dim, "p", 0);
110	p->language = 'c';
111	p->context = cloog_domain_universe(state, 0);
112	statement = cloog_statement_alloc(state, 1);
113	p->loop = cloog_loop_malloc(state);
114	p->loop->domain = domain;
115	p->loop->block = cloog_block_alloc(statement, 0, NULL, dim);
116	p->blocklist = cloog_block_list_alloc(p->loop->block);
117	p = cloog_program_generate(p, options);
118
119	printf("%s", preamble);
120	for (i = 0; i < dim; ++i)
121		printf("\tint %s;\n", p->names->iterators[i]);
122	printf("#define S1(");
123	for (i = 0; i < dim; ++i) {
124		if (i)
125			printf(",");
126		printf("p%d", i);
127	}
128	printf(") do {");
129	for (j = 0; j < 2; ++j) {
130		printf(" h = 2166136261u;");
131		printf(" %s(", call[j]);
132		for (i = 0; i < dim; ++i) {
133			if (i)
134				printf(", ");
135			printf("p%d", i);
136		}
137		printf(");");
138		printf(" h_%s = h;", call[j]);
139	}
140	printf(" assert(h_good == h_test);");
141	printf(" } while (0)\n");
142	print_macros(stdout);
143	cloog_program_pprint(stdout, p, options);
144	printf("%s", postamble);
145
146	cloog_int_clear(m);
147	cloog_int_clear(M);
148	cloog_program_free(p);
149	cloog_options_free(options);
150	cloog_state_free(state);
151
152	return 0;
153}
154