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.
21 * @@@ this is no more correct ...
26 * return (d + self.a);
48 type *owner, *class_prima;
49 type *proc_main, *proc_set_a, *proc_c;
51 entity *proc_main_e, *proc_set_a_e, *proc_c_e, *a_e;
53 ir_graph *main_irg, *set_a_irg, *c_irg;
54 ir_node *c2, *c5, *obj_o, *obj_size, *proc_ptr, *res, *x, *set_a_call, *c_call;
55 ir_node *self, *par1, *a_ptr;
56 ir_node *a_val, *r, *t, *b, *f;
58 int o_pos, self_pos, e_pos;
66 set_opt_constant_folding(1);
68 set_opt_dead_node_elimination(1);
70 /*** Make basic type information for primitive type int. ***/
71 prim_t_int = new_type_primitive(new_id_from_chars ("int", 3), mode_Is);
73 /*** Make type information for the class (PRIMA). ***/
74 /* The type of the class */
75 class_prima = new_type_class(new_id_from_str ("PRIMA_INLINE"));
76 /* We need type information for pointers to the class: */
77 class_p_ptr = new_type_pointer (new_id_from_chars ("class_prima_ptr", 15),
79 /* An entity for the field (a). The entity constructor automatically adds
80 the entity as member of the owner. */
81 a_e = new_entity(class_prima, new_id_from_chars ("a", 1), prim_t_int);
82 /* An entity for the method set_a. But first we need type information
84 proc_set_a = new_type_method(new_id_from_chars("set_a", 5), 2, 0);
85 set_method_param_type(proc_set_a, 0, class_p_ptr);
86 set_method_param_type(proc_set_a, 1, prim_t_int);
87 proc_set_a_e = new_entity(class_prima, new_id_from_chars ("set_a", 5), proc_set_a);
88 /* An entity for the method c. Implicit argument "self" must be modeled
90 proc_c = new_type_method(new_id_from_chars("c", 1 ), 2, 1);
91 set_method_param_type(proc_c, 0, class_p_ptr);
92 set_method_param_type(proc_c, 1, prim_t_int);
93 set_method_res_type(proc_c, 0, prim_t_int);
94 proc_c_e = new_entity(class_prima, new_id_from_chars ("c", 1), proc_c);
96 /*** Now build procedure main. ***/
97 /** Type information for main. **/
98 printf("\nCreating an IR graph: OO_INLINE_EXAMPLE...\n");
99 /* Main is not modeled as part of an explicit class here. Therefore the
100 owner is the global type. */
101 owner = get_glob_type();
102 /* Main has zero parameters and one result. */
103 proc_main = new_type_method(new_id_from_chars("OO_INLINE_EXAMPLE_main", 22), 0, 1);
104 /* The result type is int. */
105 set_method_res_type(proc_main, 0, prim_t_int);
107 /* The entity for main. */
108 proc_main_e = new_entity (owner, new_id_from_chars ("OO_INLINE_EXAMPLE_main", 22), proc_main);
110 /** Build code for procedure main. **/
111 /* We need one local variable (for "o"). */
112 main_irg = new_ir_graph (proc_main_e, 1);
115 /* Remark that this irg is the main routine of the program. */
116 set_irp_main_irg(main_irg);
118 /* Make the constants. They are independent of a block. */
119 c2 = new_Const (mode_Is, new_tarval_from_long (2, mode_Is));
120 c5 = new_Const (mode_Is, new_tarval_from_long (5, mode_Is));
122 /* There is only one block in main, it contains the allocation and the calls. */
123 /* Allocate the defined object and generate the type information. */
124 symconst_symbol sym = { class_prima };
125 obj_size = new_SymConst(sym, symconst_size);
126 obj_o = new_Alloc(get_store(), obj_size, class_prima, heap_alloc);
127 set_store(new_Proj(obj_o, mode_M, 0)); /* make the changed memory visible */
128 obj_o = new_Proj(obj_o, mode_P, 2); /* remember the pointer to the object */
129 set_value(o_pos, obj_o);
131 /* Get the pointer to the procedure from the object. */
132 proc_ptr = new_simpleSel(get_store(), /* The memory containing the object. */
133 get_value(o_pos, mode_P),/* The pointer to the object. */
134 proc_set_a_e ); /* The feature to select. */
136 /* Call procedure set_a, first built array with parameters. */
139 in[0] = get_value(o_pos, mode_P);
141 set_a_call = new_Call(get_store(), proc_ptr, 2, in, proc_set_a);
144 /* Make the change to memory visible. There are no results. */
145 set_store(new_Proj(set_a_call, mode_M, 0));
147 /* Get the pointer to the nest procedure from the object. */
148 proc_ptr = new_simpleSel(get_store(), get_value(o_pos, mode_P), proc_c_e);
150 /* call procedure c, first built array with parameters */
153 in[0] = get_value(o_pos, mode_P);
155 c_call = new_Call(get_store(), proc_ptr, 2, in, proc_c);
157 /* make the change to memory visible */
158 set_store(new_Proj(c_call, mode_M, 0));
159 /* Get the result of the procedure: select the result tuple from the call,
160 then the proper result from the tuple. */
161 res = new_Proj(new_Proj(c_call, mode_T, 2), mode_Is, 0);
163 /* return the results of procedure main */
167 x = new_Return (get_store(), 1, in);
169 mature_immBlock (get_irg_current_block(main_irg));
171 /* complete the end_block */
172 add_immBlock_pred (get_irg_end_block(main_irg), x);
173 mature_immBlock (get_irg_end_block(main_irg));
176 irg_finalize_cons (main_irg);
178 /****************************************************************************/
180 printf("Creating IR graph for set_a: \n");
182 /* Local variables: self, e */
183 set_a_irg = new_ir_graph (proc_set_a_e, 2);
184 self_pos = 0; e_pos = 1;
186 /* get the procedure parameter */
187 self = new_Proj(get_irg_args(set_a_irg), mode_P, 0);
188 set_value(self_pos, self);
189 par1 = new_Proj(get_irg_args(set_a_irg), mode_Is, 1);
190 set_value(e_pos, par1);
191 /* Create and select the entity to set */
192 a_ptr = new_simpleSel(get_store(), self, a_e);
193 /* perform the assignment */
194 set_store(new_Proj(new_Store(get_store(), a_ptr, par1), mode_M, 0));
197 x = new_Return (get_store (), 0, NULL);
198 mature_immBlock (get_irg_current_block(set_a_irg));
200 /* complete the end_block */
201 add_immBlock_pred (get_irg_end_block(set_a_irg), x);
202 mature_immBlock (get_irg_end_block(set_a_irg));
204 /* verify the graph */
206 irg_finalize_cons (set_a_irg);
208 /****************************************************************************/
210 printf("Creating IR graph for c: \n");
212 /* Local variables self, d */
213 c_irg = new_ir_graph (proc_c_e, 5);
215 /* get the procedure parameter */
216 self = new_Proj(get_irg_args(c_irg), mode_P, 0);
218 par1 = new_Proj(get_irg_args(c_irg), mode_Is, 1);
220 set_value(2, new_Const (mode_Is, new_tarval_from_long (0, mode_Is)));
223 mature_immBlock (get_irg_current_block(c_irg));
225 /* generate a block for the loop header and the conditional branch */
227 add_immBlock_pred (r, x);
228 x = new_Cond (new_Proj(new_Cmp(new_Const (mode_Is, new_tarval_from_long (0, mode_Is)),
229 new_Const (mode_Is, new_tarval_from_long (0, mode_Is))),
232 /* x = new_Cond (new_Proj(new_Cmp(new_Const (mode_Is, new_tarval_from_long (0, mode_Is)),
233 get_value(1, mode_Is)),
234 mode_b, pn_Cmp_Eq));*/
235 f = new_Proj (x, mode_X, 0);
236 t = new_Proj (x, mode_X, 1);
238 /* generate the block for the loop body */
240 add_immBlock_pred (b, t);
242 /* The code in the loop body,
243 as we are dealing with local variables only the dataflow edges
245 set_value (3, get_value (1, mode_Is));
246 set_value (1, get_value (2, mode_Is));
247 set_value (2, get_value (3, mode_Is));
248 a_ptr = new_simpleSel(get_store(), self, a_e);
249 set_store(new_Proj(new_Store(get_store(), a_ptr, get_value(2, mode_Is)), mode_M, pn_Store_M));
251 add_immBlock_pred(r, x);
255 /* generate the return block */
257 add_immBlock_pred (r, f);
258 /* Select the entity and load the value */
259 a_ptr = new_simpleSel(get_store(), self, a_e);
260 a_val = new_Load(get_store(), a_ptr, mode_Is);
261 set_store(new_Proj(a_val, mode_M, 0));
262 a_val = new_Proj(a_val, mode_Is, 2);
264 /* return the result */
267 in[0] = new_Add(par1, a_val, mode_Is);
269 x = new_Return (get_store (), 1, in);
273 /* complete the end_block */
274 add_immBlock_pred (get_irg_end_block(c_irg), x);
275 mature_immBlock (get_irg_end_block(c_irg));
277 /* verify the graph */
279 irg_finalize_cons (c_irg);
281 /****************************************************************************/
283 collect_phiprojs(main_irg);
284 current_ir_graph = main_irg;
285 printf("Inlining set_a ...\n");
286 inline_method(set_a_call, set_a_irg);
287 printf("Inlineing c ...\n");
288 inline_method(c_call, c_irg);
290 printf("Optimizing ...\n");
292 for (i = 0; i < get_irp_n_irgs(); i++) {
293 local_optimize_graph(get_irp_irg(i));
294 dead_node_elimination(get_irp_irg(i));
297 printf("Dumping graphs of all procedures and a type graph.\n");
298 /* Touch ld names to distinguish names from oo_inline names. */
299 get_entity_ld_ident(proc_set_a_e);
300 get_entity_ld_ident(proc_c_e);
301 turn_off_edge_labels();
303 dump_all_ir_graphs(dump_ir_block_graph, suffix);
304 dump_all_ir_graphs(dump_ir_block_graph_w_types, suffix);
307 printf("Use xvcg to view these graphs:\n");
308 printf("/ben/goetz/bin/xvcg GRAPHNAME\n\n");