3 * File name: testprograms/oo_inline_example.c
4 * Purpose: Test inlineing.
5 * Author: 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 is no more correct ...
24 * return (d + self.a);
45 const char *suffix = "";
47 ir_type *owner, *class_prima;
48 ir_type *proc_main, *proc_set_a, *proc_c;
50 ir_entity *proc_main_e, *proc_set_a_e, *proc_c_e, *a_e;
52 ir_graph *main_irg, *set_a_irg, *c_irg;
53 ir_node *c2, *c5, *obj_o, *obj_size, *proc_ptr, *res, *x, *set_a_call, *c_call;
54 ir_node *self, *par1, *a_ptr;
55 ir_node *a_val, *r, *t, *b, *f;
58 int o_pos, self_pos, e_pos;
65 set_opt_constant_folding(1);
68 /*** Make basic ir_type information for primitive ir_type int. ***/
69 prim_t_int = new_type_primitive(new_id_from_chars("int", 3), mode_Is);
71 /*** Make ir_type information for the class (PRIMA). ***/
72 /* The ir_type of the class */
73 class_prima = new_type_class(new_id_from_str("PRIMA_INLINE"));
74 /* We need ir_type information for pointers to the class: */
75 class_p_ptr = new_type_pointer(new_id_from_chars("class_prima_ptr", 15),
77 /* An ir_entity for the field (a). The ir_entity constructor automatically adds
78 the ir_entity as member of the owner. */
79 a_e = new_entity(class_prima, new_id_from_chars("a", 1), prim_t_int);
80 /* An ir_entity for the method set_a. But first we need ir_type information
82 proc_set_a = new_type_method(new_id_from_chars("set_a", 5), 2, 0);
83 set_method_param_type(proc_set_a, 0, class_p_ptr);
84 set_method_param_type(proc_set_a, 1, prim_t_int);
85 proc_set_a_e = new_entity(class_prima, new_id_from_chars("set_a", 5), proc_set_a);
86 /* An ir_entity for the method c. Implicit argument "self" must be modeled
88 proc_c = new_type_method(new_id_from_chars("c", 1 ), 2, 1);
89 set_method_param_type(proc_c, 0, class_p_ptr);
90 set_method_param_type(proc_c, 1, prim_t_int);
91 set_method_res_type(proc_c, 0, prim_t_int);
92 proc_c_e = new_entity(class_prima, new_id_from_chars("c", 1), proc_c);
94 /*** Now build procedure main. ***/
95 /** Type information for main. **/
96 printf("\nCreating an IR graph: OO_INLINE_EXAMPLE...\n");
97 /* Main is not modeled as part of an explicit class here. Therefore the
98 owner is the global ir_type. */
99 owner = get_glob_type();
100 /* Main has zero parameters and one result. */
101 proc_main = new_type_method(new_id_from_chars("OO_INLINE_EXAMPLE_main", 22), 0, 1);
102 /* The result ir_type is int. */
103 set_method_res_type(proc_main, 0, prim_t_int);
105 /* The ir_entity for main. */
106 proc_main_e = new_entity(owner, new_id_from_chars("OO_INLINE_EXAMPLE_main", 22), proc_main);
108 /** Build code for procedure main. **/
109 /* We need one local variable (for "o"). */
110 main_irg = new_ir_graph(proc_main_e, 1);
113 /* Remark that this irg is the main routine of the program. */
114 set_irp_main_irg(main_irg);
116 /* Make the constants. They are independent of a block. */
117 c2 = new_Const(mode_Is, new_tarval_from_long(2, mode_Is));
118 c5 = new_Const(mode_Is, new_tarval_from_long(5, mode_Is));
120 /* There is only one block in main, it contains the allocation and the calls. */
121 /* Allocate the defined object and generate the ir_type information. */
122 sym.type_p = class_prima;
123 obj_size = new_SymConst(mode_Iu, sym, symconst_type_size);
124 obj_o = new_Alloc(get_store(), obj_size, class_prima, heap_alloc);
125 set_store(new_Proj(obj_o, mode_M, pn_Alloc_M)); /* make the changed memory visible */
126 obj_o = new_Proj(obj_o, mode_P, pn_Alloc_res); /* remember the pointer to the object */
127 set_value(o_pos, obj_o);
129 /* Get the pointer to the procedure from the object. */
130 proc_ptr = new_simpleSel(get_store(), /* The memory containing the object. */
131 get_value(o_pos, mode_P),/* The pointer to the object. */
132 proc_set_a_e ); /* The feature to select. */
134 /* Call procedure set_a, first built array with parameters. */
137 in[0] = get_value(o_pos, mode_P);
139 set_a_call = new_Call(get_store(), proc_ptr, 2, in, proc_set_a);
142 /* Make the change to memory visible. There are no results. */
143 set_store(new_Proj(set_a_call, mode_M, pn_Call_M));
145 /* Get the pointer to the nest procedure from the object. */
146 proc_ptr = new_simpleSel(get_store(), get_value(o_pos, mode_P), proc_c_e);
148 /* call procedure c, first built array with parameters */
151 in[0] = get_value(o_pos, mode_P);
153 c_call = new_Call(get_store(), proc_ptr, 2, in, proc_c);
155 /* make the change to memory visible */
156 set_store(new_Proj(c_call, mode_M, pn_Call_M));
157 /* Get the result of the procedure: select the result tuple from the call,
158 then the proper result from the tuple. */
159 res = new_Proj(new_Proj(c_call, mode_T, pn_Call_T_result), mode_Is, 0);
161 /* return the results of procedure main */
165 x = new_Return(get_store(), 1, in);
167 mature_immBlock(get_irg_current_block(main_irg));
169 /* complete the end_block */
170 add_immBlock_pred(get_irg_end_block(main_irg), x);
171 mature_immBlock(get_irg_end_block(main_irg));
174 irg_finalize_cons(main_irg);
176 /****************************************************************************/
178 printf("Creating IR graph for set_a: \n");
180 /* Local variables: self, e */
181 set_a_irg = new_ir_graph(proc_set_a_e, 2);
182 self_pos = 0; e_pos = 1;
184 /* get the procedure parameter */
185 self = new_Proj(get_irg_args(set_a_irg), mode_P, 0);
186 set_value(self_pos, self);
187 par1 = new_Proj(get_irg_args(set_a_irg), mode_Is, 1);
188 set_value(e_pos, par1);
189 /* Create and select the ir_entity to set */
190 a_ptr = new_simpleSel(get_store(), self, a_e);
191 /* perform the assignment */
192 set_store(new_Proj(new_Store(get_store(), a_ptr, par1), mode_M, pn_Store_M));
195 x = new_Return(get_store(), 0, NULL);
196 mature_immBlock(get_irg_current_block(set_a_irg));
198 /* complete the end_block */
199 add_immBlock_pred(get_irg_end_block(set_a_irg), x);
200 mature_immBlock(get_irg_end_block(set_a_irg));
202 /* verify the graph */
204 irg_finalize_cons(set_a_irg);
206 /****************************************************************************/
208 printf("Creating IR graph for c: \n");
210 /* Local variables self, d */
211 c_irg = new_ir_graph(proc_c_e, 5);
213 /* get the procedure parameter */
214 self = new_Proj(get_irg_args(c_irg), mode_P, 0);
216 par1 = new_Proj(get_irg_args(c_irg), mode_Is, 1);
218 set_value(2, new_Const(mode_Is, new_tarval_from_long(0, mode_Is)));
221 mature_immBlock(get_irg_current_block(c_irg));
223 /* generate a block for the loop header and the conditional branch */
225 add_immBlock_pred(r, x);
226 x = new_Cond(new_Proj(new_Cmp(new_Const(mode_Is, new_tarval_from_long(0, mode_Is)),
227 new_Const(mode_Is, new_tarval_from_long(0, mode_Is))),
230 /* x = new_Cond(new_Proj(new_Cmp(new_Const(mode_Is, new_tarval_from_long(0, mode_Is)),
231 get_value(1, mode_Is)),
232 mode_b, pn_Cmp_Eq));*/
233 f = new_Proj(x, mode_X, pn_Cond_false);
234 t = new_Proj(x, mode_X, pn_Cond_true);
236 /* generate the block for the loop body */
238 add_immBlock_pred(b, t);
240 /* The code in the loop body,
241 as we are dealing with local variables only the dataflow edges
243 set_value(3, get_value(1, mode_Is));
244 set_value(1, get_value(2, mode_Is));
245 set_value(2, get_value(3, mode_Is));
246 a_ptr = new_simpleSel(get_store(), self, a_e);
247 set_store(new_Proj(new_Store(get_store(), a_ptr, get_value(2, mode_Is)), mode_M, pn_Store_M));
249 add_immBlock_pred(r, x);
253 /* generate the return block */
255 add_immBlock_pred(r, f);
256 /* Select the ir_entity and load the value */
257 a_ptr = new_simpleSel(get_store(), self, a_e);
258 a_val = new_Load(get_store(), a_ptr, mode_Is);
259 set_store(new_Proj(a_val, mode_M, pn_Load_M));
260 a_val = new_Proj(a_val, mode_Is, pn_Load_res);
262 /* return the result */
265 in[0] = new_Add(par1, a_val, mode_Is);
267 x = new_Return(get_store(), 1, in);
271 /* complete the end_block */
272 add_immBlock_pred(get_irg_end_block(c_irg), x);
273 mature_immBlock(get_irg_end_block(c_irg));
275 /* verify the graph */
277 irg_finalize_cons(c_irg);
279 /****************************************************************************/
281 collect_phiprojs(main_irg);
282 current_ir_graph = main_irg;
283 printf("Inlining set_a ...\n");
284 inline_method(set_a_call, set_a_irg);
285 printf("Inlineing c ...\n");
286 inline_method(c_call, c_irg);
288 printf("Optimizing ...\n");
290 for (i = 0; i < get_irp_n_irgs(); i++) {
291 local_optimize_graph(get_irp_irg(i));
292 dead_node_elimination(get_irp_irg(i));
295 printf("Dumping graphs of all procedures and a ir_type graph.\n");
296 /* Touch ld names to distinguish names from oo_inline names. */
297 get_entity_ld_ident(proc_set_a_e);
298 get_entity_ld_ident(proc_c_e);
299 turn_off_edge_labels();
300 dump_all_ir_graphs(dump_ir_block_graph, suffix);
301 dump_all_ir_graphs(dump_ir_block_graph_w_types, suffix);
304 printf("Use ycomp to view these graphs:\n");
305 printf("ycomp GRAPHNAME\n\n");