Small fixes, typos, style.
[libfirm] / testprograms / irr_loop_example.c
1 /*
2  * Project:     libFIRM
3  * File name:   testprograms/irr_loop_example.c
4  * Purpose:     Test Phi construction with irregular control flow.
5  * Author:      Christian Schaefer, Goetz Lindenmaier
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1999-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #include <stdio.h>
14 #include <string.h>
15
16 #include <libfirm/firm.h>
17
18 /**
19  *  This file constructs a control flow of following shape:
20  *
21  * method loop1:
22  *
23  *         firstBlock
24  *          /      \
25  *         /        \
26  *       |/_        _\|
27  *            ---->
28  * LoopBlock1       LoopBlock2
29  *            <----
30  *        \              /
31  *         \            /
32  *         _\|        |/_
33  *           nextBlock
34  *
35  * method loop2:
36  *
37  *         scndBlock  <---------- firstBlock
38  *          /      \                  \
39  *         /        \                  \
40  *       |/_        _\|                _\|
41  *            ---->              ---->
42  * LoopBlock1       LoopBlock2 1       LoopBlock3
43  *            <----              <----
44  *        \                             /
45  *         \                           /
46  *         _\|                        /
47  *           nextBlock   <---------- /
48  *
49  *
50  **/
51
52 int main(void)
53 {
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;
60   int       i;
61
62
63   /* init library */
64   init_firm(NULL);
65   set_opt_constant_folding(0);  /* so that the stupid tests are not optimized. */
66   set_opt_cse(1);
67   turn_off_edge_labels();
68
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.
74    */
75 #define CLASSNAME "IRR_LOOP"
76 #define METHOD_TP_NAME "METH_TP_NOARG_NORES"
77 #define NRARGS 0
78 #define NRES 0
79 #define NUM_OF_LOCAL_VARS 0
80
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);
84
85   /* --- method loop1 ------------------------------------------------------ */
86
87 #define METHODNAME "loop1"
88
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 */
91
92   irg = new_ir_graph(ent, NUM_OF_LOCAL_VARS);
93
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));
99
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));
104
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);
110
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);
116
117   add_immBlock_pred(loopBlock1, t_l2);
118   add_immBlock_pred(loopBlock2, t_l1);
119   mature_immBlock(loopBlock1);
120   mature_immBlock(loopBlock2);
121
122   new_immBlock();
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));
127
128   add_immBlock_pred(get_irg_end_block(irg), x);
129   mature_immBlock(get_irg_end_block(irg));
130
131   irg_finalize_cons(irg);
132
133   /* --- method loop2 ------------------------------------------------------ */
134
135 #undef METHODNAME
136 #define METHODNAME "loop2"
137
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 */
140
141   irg = new_ir_graph(ent, NUM_OF_LOCAL_VARS);
142
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));
150
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));
155
156   new_immBlock();
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));
162
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);
168
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);
174
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);
180
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);
188
189   new_immBlock();
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));
194
195   add_immBlock_pred(get_irg_end_block(irg), x);
196   mature_immBlock(get_irg_end_block(irg));
197
198   irg_finalize_cons(irg);
199
200   /* --- more ...  ------------------------------------------------------ */
201
202   printf("Optimizing ...\n");
203
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, "");
210
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");
216   }
217   /* Error for loop2 */
218   compute_execution_frequency(get_irp_irg(0), 10, 0.001);
219   dump_interval_graph(get_irp_irg(0), "");
220
221   return 0;
222 }