3 * File name: testprograms/irr_loop_example.c
4 * Purpose: Test Phi construction with irregular control flow.
5 * Author: Christian Schaefer, Goetz Lindenmaier
9 * Copyright: (c) 1999-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
16 #include <libfirm/firm.h>
19 * This file constructs a control flow of following shape:
28 * LoopBlock1 LoopBlock2
37 * scndBlock <---------- firstBlock
42 * LoopBlock1 LoopBlock2 1 LoopBlock3
47 * nextBlock <---------- /
54 ir_graph *irg; /* this variable contains the irgraph */
55 ir_type *owner; /* the class in which this method is defined */
56 ir_type *proc_tp; /* typeinformation for the method main */
57 ir_entity *ent; /* represents this method as ir_entity of owner */
58 ir_node *expr, *c1, *c2, *c3, *c4, *c5, *cond, *f, *t, *f2, *loopBlock1, *f_l1, *t_l1,
59 *loopBlock2, *f_l2, *t_l2, *loopBlock3, *f_l3, *t_l3, *x;
65 set_opt_constant_folding(0); /* so that the stupid tests are not optimized. */
67 turn_off_edge_labels();
69 /* FIRM was designed for oo languages where all methods belong to a class.
70 * For imperative languages like C we view a file as a large class containing
71 * all functions as methods in this file.
72 * Therefore we define a class "empty" according to the file name
73 * with a method main as an ir_entity.
75 #define CLASSNAME "IRR_LOOP"
76 #define METHOD_TP_NAME "METH_TP_NOARG_NORES"
79 #define NUM_OF_LOCAL_VARS 0
81 owner = new_type_class(new_id_from_str(CLASSNAME));
82 printf("\nCreating testprogram: %s...\n", CLASSNAME);
83 proc_tp = new_type_method(new_id_from_str(METHOD_TP_NAME), NRARGS, NRES);
85 /* --- method loop1 ------------------------------------------------------ */
87 #define METHODNAME "loop1"
89 ent = new_entity(owner, new_id_from_str(METHODNAME), proc_tp);
90 get_entity_ld_name(ent); /* To enforce name mangling for vcg graph name */
92 irg = new_ir_graph(ent, NUM_OF_LOCAL_VARS);
94 /* to make three conditionals */
95 expr = new_Const(mode_Is, new_tarval_from_long(0, mode_Is));
96 c1 = new_Const(mode_Is, new_tarval_from_long(1, mode_Is));
97 c2 = new_Const(mode_Is, new_tarval_from_long(2, mode_Is));
98 c3 = new_Const(mode_Is, new_tarval_from_long(2, mode_Is));
100 cond = new_Cond(new_Proj(new_Cmp(expr, c1), mode_b, pn_Cmp_Eq));
101 f = new_Proj(cond, mode_X, pn_Cond_false);
102 t = new_Proj(cond, mode_X, pn_Cond_true);
103 mature_immBlock(get_irg_current_block(irg));
105 loopBlock1 = new_immBlock();
106 add_immBlock_pred(loopBlock1, t);
107 cond = new_Cond(new_Proj(new_Cmp(expr, c2), mode_b, pn_Cmp_Eq));
108 f_l1 = new_Proj(cond, mode_X, pn_Cond_false);
109 t_l1 = new_Proj(cond, mode_X, pn_Cond_true);
111 loopBlock2 = new_immBlock();
112 add_immBlock_pred(loopBlock2, f);
113 cond = new_Cond(new_Proj(new_Cmp(expr, c3), mode_b, pn_Cmp_Eq));
114 f_l2 = new_Proj(cond, mode_X, pn_Cond_false);
115 t_l2 = new_Proj(cond, mode_X, pn_Cond_true);
117 add_immBlock_pred(loopBlock1, t_l2);
118 add_immBlock_pred(loopBlock2, t_l1);
119 mature_immBlock(loopBlock1);
120 mature_immBlock(loopBlock2);
123 add_immBlock_pred(get_irg_current_block(irg), f_l2);
124 add_immBlock_pred(get_irg_current_block(irg), f_l1);
125 x = new_Return(get_store(), 0, NULL);
126 mature_immBlock(get_irg_current_block(irg));
128 add_immBlock_pred(get_irg_end_block(irg), x);
129 mature_immBlock(get_irg_end_block(irg));
131 irg_finalize_cons(irg);
133 /* --- method loop2 ------------------------------------------------------ */
136 #define METHODNAME "loop2"
138 ent = new_entity(owner, new_id_from_str(METHODNAME), proc_tp);
139 get_entity_ld_name(ent); /* To enforce name mangling for vcg graph name */
141 irg = new_ir_graph(ent, NUM_OF_LOCAL_VARS);
143 /* to make several conditionals */
144 expr = new_Const(mode_Is, new_tarval_from_long(0, mode_Is));
145 c1 = new_Const(mode_Is, new_tarval_from_long(1, mode_Is));
146 c2 = new_Const(mode_Is, new_tarval_from_long(2, mode_Is));
147 c3 = new_Const(mode_Is, new_tarval_from_long(3, mode_Is));
148 c4 = new_Const(mode_Is, new_tarval_from_long(4, mode_Is));
149 c5 = new_Const(mode_Is, new_tarval_from_long(5, mode_Is));
151 cond = new_Cond(new_Proj(new_Cmp(expr, c1), mode_b, pn_Cmp_Eq));
152 f2 = new_Proj(cond, mode_X, pn_Cond_false);
153 t = new_Proj(cond, mode_X, pn_Cond_true);
154 mature_immBlock(get_irg_current_block(irg));
157 add_immBlock_pred(get_irg_current_block(irg), t);
158 cond = new_Cond(new_Proj(new_Cmp(expr, c5), mode_b, pn_Cmp_Eq));
159 f = new_Proj(cond, mode_X, pn_Cond_false);
160 t = new_Proj(cond, mode_X, pn_Cond_true);
161 mature_immBlock(get_irg_current_block(irg));
163 loopBlock1 = new_immBlock();
164 add_immBlock_pred(loopBlock1, t);
165 cond = new_Cond(new_Proj(new_Cmp(expr, c2), mode_b, pn_Cmp_Eq));
166 f_l1 = new_Proj(cond, mode_X, pn_Cond_false);
167 t_l1 = new_Proj(cond, mode_X, pn_Cond_true);
169 loopBlock2 = new_immBlock();
170 add_immBlock_pred(loopBlock2, f);
171 cond = new_Cond(new_Proj(new_Cmp(expr, c3), mode_b, pn_Cmp_Eq));
172 f_l2 = new_Proj(cond, mode_X, pn_Cond_false);
173 t_l2 = new_Proj(cond, mode_X, pn_Cond_true);
175 loopBlock3 = new_immBlock();
176 add_immBlock_pred(loopBlock3, f2);
177 cond = new_Cond(new_Proj(new_Cmp(expr, c4), mode_b, pn_Cmp_Eq));
178 f_l3 = new_Proj(cond, mode_X, pn_Cond_false);
179 t_l3 = new_Proj(cond, mode_X, pn_Cond_true);
181 add_immBlock_pred(loopBlock1, t_l2);
182 add_immBlock_pred(loopBlock2, t_l1);
183 add_immBlock_pred(loopBlock3, f_l2);
184 add_immBlock_pred(loopBlock2, t_l3);
185 mature_immBlock(loopBlock1);
186 mature_immBlock(loopBlock2);
187 mature_immBlock(loopBlock3);
190 add_immBlock_pred(get_irg_current_block(irg), f_l1);
191 add_immBlock_pred(get_irg_current_block(irg), f_l3);
192 x = new_Return(get_store(), 0, NULL);
193 mature_immBlock(get_irg_current_block(irg));
195 add_immBlock_pred(get_irg_end_block(irg), x);
196 mature_immBlock(get_irg_end_block(irg));
198 irg_finalize_cons(irg);
200 /* --- more ... ------------------------------------------------------ */
202 printf("Optimizing ...\n");
204 for (i = 0; i < get_irp_n_irgs(); ++i) {
205 current_ir_graph = get_irp_irg(i);
206 /* verify the graph */
207 irg_vrfy(current_ir_graph);
208 construct_cf_backedges(current_ir_graph);
209 dump_loop_tree(current_ir_graph, "");
211 printf("Dumping the graph and a control flow graph.\n");
212 dump_ir_block_graph(current_ir_graph, "");
213 dump_cfg(current_ir_graph, "");
214 printf("Use ycomp to view these graphs:\n");
215 printf("ycomp GRAPHNAME\n\n");
217 /* Error for loop2 */
218 compute_execution_frequency(get_irp_irg(0), 10, 0.001);
219 dump_interval_graph(get_irp_irg(0), "");