3 * File name: testprograms/strength_red_example.c
4 * Purpose: Shows how strength red works
5 * Author: Beyhan Veliev
9 * Copyright: (c) 2004 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
23 * This file constructs the ir for the following pseudo-program:
37 #define CLASSNAME "STRENGTH_RED_EXAMPLE"
38 #define METHODNAME1 "STRENGTH_RED_EXAMPLE_m1"
39 #define METHODNAME2 "STRENGTH_RED_EXAMPLE_m2"
40 #define METHODNAME3 "STRENGTH_RED_EXAMPLE_m3"
41 #define METHODNAME4 "STRENGTH_RED_EXAMPLE_m4"
42 #define METHODNAME5 "STRENGTH_RED_EXAMPLE_m5"
43 #define METHODTPNAME "STRENGTH_RED_EXAMPLE_meth_tp"
50 #define PRIM_NAME "int"
55 static int arr_pos = 1;
58 static ir_node *r1, *f, *r;
65 static void function_begin(type *owner, type *mtp, char *fct_name, loop_dir_t loop_dir) {
68 /* The entity for the procedure */
69 entity *ent = new_entity (owner, new_id_from_str (fct_name), mtp);
70 /* The parameter and result types of the procedure. */
71 set_method_param_type(mtp, 0, typ);
72 set_method_res_type(mtp, 0, typ);
74 /* make type infromation for the array */
75 type *array_type = new_type_array(new_id_from_chars("array", 5),N_DIMS, typ);
77 /* set the bounds for the array */
78 set_array_bounds(array_type, 0,
79 new_Const(mode_Iu, new_tarval_from_long (L_BOUND, mode_Iu)),
80 new_Const(mode_Iu, new_tarval_from_long (U_BOUND, mode_Iu)));
81 /* The array is an entity of the global typ */
82 entity *array_ent = new_entity( owner, new_id_from_chars("a", 1), array_type);
84 /** The code of the procedure **/
86 /* Generates start and end blocks and nodes, and a first, initial block */
88 new_ir_graph (ent, NRLOCS);
90 /* The value position used for: */
93 /* Generate the constant and assign it to b. The assignment is resolved to a
95 if (loop_dir == loop_forward) {
96 set_value (i_pos, new_Const (mode_Is, new_tarval_from_long (0, mode_Is)));
98 set_value (i_pos, new_Const (mode_Is, new_tarval_from_long (10, mode_Is)));
100 sym.entity_p = array_ent ;
101 set_value (arr_pos, new_SymConst(sym, symconst_addr_ent));
105 /* We know all predecessors of the block and all set_values and set_stores are
106 preformed. We can mature the block. */
107 mature_immBlock (get_irg_current_block(current_ir_graph));
109 /* Generate a conditional branch */
111 add_immBlock_pred(get_irg_current_block(current_ir_graph), x);
113 if (loop_dir == loop_forward) {
114 cmp = new_Cmp(new_Const (mode_Is, new_tarval_from_long(10, mode_Is)),
115 get_value(i_pos, mode_Is));
116 x = new_Cond (new_Proj(cmp, mode_b, Gt));
118 cmp = new_Cmp(new_Const (mode_Is, new_tarval_from_long(0, mode_Is)),
119 get_value(i_pos, mode_Is));
120 x = new_Cond (new_Proj(cmp, mode_b, Lt));
122 f = new_Proj (x, mode_X, 0);
123 t = new_Proj (x, mode_X, 1);
125 /* generate and fill the loop body block */
127 add_immBlock_pred (r, t);
130 static void function_end(ir_node *b) {
131 ir_node *x = new_Jmp ();
133 add_immBlock_pred(r1, x);
137 add_immBlock_pred(get_cur_block(), f);
138 mature_immBlock (get_cur_block());
139 /* The Return statement */
141 ir_node *in[1], *store ;
145 x = new_Return (store, 1, in);
147 add_immBlock_pred(get_irg_end_block(current_ir_graph), x);
149 mature_immBlock (r1);
150 /* finalize the end block generated in new_ir_graph() */
151 mature_immBlock (get_irg_end_block(current_ir_graph));
159 entity *ent, *array_ent;
160 type *proc_tp, *array_type; /* type information for the method main */
161 ir_node *x,*x1 , *r, *t, *f, *f1, *t1, *cmp, *r1, *r2;
164 printf("\nCreating an IR graph: IF_EXAMPLE...\n");
168 do_node_verification(NODE_VERIFICATION_REPORT);
170 typ = new_type_primitive(new_id_from_chars(PRIM_NAME, strlen(PRIM_NAME)), mode_Is);
172 /** The global array variable a **/
175 /** Type information for the procedure **/
176 owner = get_glob_type();
177 /* Type information for the procedure */
178 proc_tp = new_type_method(new_id_from_chars(METHODTPNAME, strlen(METHODTPNAME)),
180 set_method_param_type(proc_tp, 0, typ);
181 set_method_res_type(proc_tp, 0, typ);
184 /* --------------------------------------------------------------------- */
186 /* The entity for the procedure */
187 ent = new_entity (owner,
188 new_id_from_str (METHODNAME1),
190 /* The parameter and result types of the procedure. */
192 /* make type infromation for the array */
193 array_type = new_type_array(new_id_from_chars("array", 5),N_DIMS, typ);
195 /* set the bounds for the array */
196 set_array_bounds(array_type, 0,
197 new_Const(mode_Iu, new_tarval_from_long (L_BOUND, mode_Iu)),
198 new_Const(mode_Iu, new_tarval_from_long (U_BOUND, mode_Iu)));
199 /* The array is an entity of the global typ */
200 array_ent = new_entity( owner, new_id_from_chars("a", 1), array_type);
202 /** The code of the procedure **/
205 /* Generates start and end blocks and nodes, and a first, initial block */
208 irg = new_ir_graph (ent, NRLOCS);
210 /* The value position used for: */
213 /* Generate the constant and assign it to b. The assignment is resovled to a
215 set_value (i_pos, new_Const (mode_Is, new_tarval_from_long (0, mode_Is)));
218 /* We know all predecessors of the block and all set_values and set_stores are
219 preformed. We can mature the block. */
220 mature_immBlock (get_irg_current_block(irg));
222 /* Generate a conditional branch */
224 add_immBlock_pred(get_irg_current_block(irg), x);
225 cmp = new_Cmp(new_Const (mode_Is, new_tarval_from_long(10, mode_Is)),
226 get_value(i_pos, mode_Is));
227 x = new_Cond (new_Proj(cmp, mode_b, Gt));
228 f = new_Proj (x, mode_X, 0);
229 t = new_Proj (x, mode_X, 1);
231 /* generate and fill the then block */
233 add_immBlock_pred (r, t);
235 ir_node *b, *c, *d, *res;
237 c = new_Const (mode_Is, new_tarval_from_long (1, mode_Is));
238 b = new_Const (mode_Is, new_tarval_from_long (4, mode_Is));
239 sym.entity_p = array_ent ;
240 d = new_SymConst(sym, symconst_addr_ent);
241 res = new_Add(d, new_Mul(get_value(i_pos, mode_Is), b, mode_Is), mode_P);
242 set_store (new_Proj (new_Store (get_store (), res, new_Const (mode_Is,
243 new_tarval_from_long (19,mode_Is))),
245 set_value (i_pos, new_Add(get_value(i_pos, mode_Is), c , mode_Is));
250 add_immBlock_pred(r1, x);
251 mature_immBlock (r1);
254 add_immBlock_pred(get_irg_current_block(irg), f);
255 cmp = new_Cmp(new_Const (mode_Is, new_tarval_from_long(0, mode_Is)),get_value(i_pos, mode_Is));
256 x = new_Cond (new_Proj(cmp, mode_b, Lt));
257 f1 = new_Proj (x, mode_X, 0);
258 t1 = new_Proj (x, mode_X, 1);
260 ir_node *block = new_immBlock();
261 add_immBlock_pred(block, t1);
263 res = new_Add(d, new_Mul(get_value(i_pos, mode_Is), b, mode_Is), mode_P);
264 set_store (new_Proj (new_Store (get_store (), res, new_Const (mode_Is,
265 new_tarval_from_long (19, mode_Is))), mode_M, 0));
266 set_value (i_pos, new_Sub(get_value(i_pos, mode_Is), c , mode_Is));
270 mature_immBlock (block);
272 add_immBlock_pred(r2, x1);
273 mature_immBlock (r2);
275 block = new_immBlock();
276 add_immBlock_pred(block, f1);
277 mature_immBlock (block);
278 /* The Return statement */
280 ir_node *in[1], *store ;
281 in[0] = get_value (i_pos, mode_Is);
284 x = new_Return (store, 1, in);
286 add_immBlock_pred(get_irg_end_block(irg), x);
288 /* finalize the end block generated in new_ir_graph() */
289 mature_immBlock (get_irg_end_block(irg));
292 /* -------------------------------------------------------------------------------- */
294 function_begin(owner, proc_tp, METHODNAME2, loop_forward);
296 c = new_Const (mode_Is, new_tarval_from_long (1, mode_Is));
297 b = new_Const (mode_Is, new_tarval_from_long (4, mode_Is));
299 res = new_Add(get_value(arr_pos, mode_P), new_Mul(get_value(i_pos, mode_Is), b, mode_Is), mode_P);
300 set_store (new_Proj (new_Store (get_store (), res, new_Const (mode_Is,
301 new_tarval_from_long (19, mode_Is))),
304 set_value (i_pos, new_Add(get_value(i_pos, mode_Is), c, mode_Is));
308 /* -------------------------------------------------------------------------- */
310 function_begin(owner, proc_tp, METHODNAME3, loop_backward);
312 c = new_Const (mode_Is, new_tarval_from_long (1, mode_Is));
313 b = new_Const (mode_Is, new_tarval_from_long (4, mode_Is));
316 res = new_Add(get_value(arr_pos, mode_P), new_Mul(get_value(i_pos, mode_Is), b, mode_Is), mode_P);
317 set_store (new_Proj (new_Store (get_store (), res, get_value(i_pos, mode_Is)), mode_M, 0));
319 set_value (i_pos, new_Sub(get_value(i_pos, mode_Is), c, mode_Is));
323 /* -------------------------------------------------------------------------- */
325 function_begin(owner, proc_tp, METHODNAME4, loop_forward);
327 c = new_Const (mode_Is, new_tarval_from_long (1, mode_Is));
328 b = new_Const (mode_Is, new_tarval_from_long (4, mode_Is));
330 set_value (i_pos, new_Add(get_value(i_pos, mode_Is), c, mode_Is));
332 res = new_Add(get_value(arr_pos, mode_P), new_Mul(get_value(i_pos, mode_Is), b, mode_Is), mode_P);
333 set_store (new_Proj (new_Store (get_store (), res,get_value(i_pos, mode_Is)),
338 /* -------------------------------------------------------------------------- */
340 function_begin(owner, proc_tp, METHODNAME5, loop_backward);
342 c = new_Const (mode_Is, new_tarval_from_long (1, mode_Is));
343 b = new_Const (mode_Is, new_tarval_from_long (4, mode_Is));
345 set_value (i_pos, new_Sub(get_value(i_pos, mode_Is), c, mode_Is));
348 res = new_Add(get_value(arr_pos, mode_P), new_Mul(get_value(i_pos, mode_Is), b, mode_Is), mode_P);
349 set_store (new_Proj (new_Store (get_store (), res, new_Const (mode_Is,
350 new_tarval_from_long (19, mode_Is))),
355 /* -------------------------------------------------------------------------- */
357 int i, n_irgs = get_irp_n_irgs();
359 printf("Done building the graph. Dumping and optimizing it.\n");
360 dump_consts_local(1);
361 turn_off_edge_labels();
362 for (i = 0; i < n_irgs; ++i) {
363 current_ir_graph = get_irp_irg(i);
364 irg_vrfy(current_ir_graph);
365 finalize_cons (current_ir_graph);
367 /* output the vcg file */
368 //dump_ir_block_graph (current_ir_graph, "-early");
369 construct_backedges(current_ir_graph);
370 //dump_ir_block_graph (current_ir_graph, 0);
372 set_opt_strength_red_verbose(2);
373 set_firm_verbosity(2);
374 reduce_strength(current_ir_graph);
376 //dump_loop_tree(current_ir_graph, "");
377 dump_ir_block_graph (current_ir_graph, "-strength_reduced");
379 //printf("use xvcg to view this graph:\n");
380 //printf("/ben/goetz/bin/xvcg GRAPHNAME\n\n");