3 * File name: testprograms/oo_program_example.c
4 * Purpose: A complex example.
5 * Author: Goetz Lindenmaier
9 * Copyright: (c) 1999-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
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, *call, *res, *x;
55 ir_node *self, *par1, *a_ptr;
58 int o_pos, self_pos, e_pos;
64 set_opt_constant_folding(1);
66 set_opt_dead_node_elimination(1);
68 /*** Make basic type information for primitive type int. ***/
69 prim_t_int = new_type_primitive(new_id_from_chars ("int", 3), mode_Is);
71 /*** Make type information for the class (PRIMA). ***/
72 /* The type of the class */
73 class_prima = new_type_class(new_id_from_chars ("PRIMA", 5));
74 /* We need type information for pointers to the class: */
75 class_p_ptr = new_type_pointer (new_id_from_chars("class_prima_ptr", 15),
77 /* An entity for the field (a). The entity constructor automatically adds
78 the entity as member of the owner. */
79 a_e = new_entity(class_prima, new_id_from_chars ("a", 1), prim_t_int);
80 /* An entity for the method set_a. But first we need 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 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_PROGRAM_EXAMPLE...\n");
97 /* Main is not modeled as part of an explicit class here. Therefore the
98 owner is the global 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_PROGRAM_EXAMPLE_main", 23), 0, 1);
102 /* The result type is int. */
103 set_method_res_type(proc_main, 0, prim_t_int);
105 /* The entity for main. */
106 proc_main_e = new_entity (owner, new_id_from_chars ("OO_PROGRAM_EXAMPLE_main", 23), 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 type information. */
122 symconst_symbol sym = {class_prima};
123 obj_size = new_SymConst(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, 0)); /* make the changed memory visible */
126 obj_o = new_Proj(obj_o, mode_P, 2); /* 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 call = new_Call(get_store(), proc_ptr, 2, in, proc_set_a);
141 /* Make the change to memory visible. There are no results. */
142 set_store(new_Proj(call, mode_M, 0));
144 /* Get the pointer to the nest procedure from the object. */
145 proc_ptr = new_simpleSel(get_store(), get_value(o_pos, mode_P), proc_c_e);
147 /* call procedure c, first built array with parameters */
150 in[0] = get_value(o_pos, mode_P);
152 call = new_Call(get_store(), proc_ptr, 2, in, proc_c);
154 /* make the change to memory visible */
155 set_store(new_Proj(call, mode_M, 0));
156 /* Get the result of the procedure: select the result tuple from the call,
157 then the proper result from the tuple. */
158 res = new_Proj(new_Proj(call, mode_T, 2), mode_Is, 0);
160 /* return the results of procedure main */
164 x = new_Return (get_store(), 1, in);
166 mature_immBlock (get_irg_current_block(main_irg));
168 /* complete the end_block */
169 add_immBlock_pred (get_irg_end_block(main_irg), x);
170 mature_immBlock (get_irg_end_block(main_irg));
173 irg_finalize_cons (main_irg);
175 /****************************************************************************/
177 printf("Creating IR graph for set_a: \n");
179 /* Local variables: self, e */
180 set_a_irg = new_ir_graph (proc_set_a_e, 2);
181 self_pos = 0; e_pos = 1;
183 /* get the procedure parameter */
184 self = new_Proj(get_irg_args(set_a_irg), mode_P, 0);
185 set_value(self_pos, self);
186 par1 = new_Proj(get_irg_args(set_a_irg), mode_Is, 1);
187 set_value(e_pos, par1);
188 /* Create and select the entity to set */
189 a_ptr = new_simpleSel(get_store(), self, a_e);
190 /* perform the assignment */
191 set_store(new_Proj(new_Store(get_store(), a_ptr, par1), mode_M, 0));
194 x = new_Return (get_store (), 0, NULL);
195 mature_immBlock (get_irg_current_block(set_a_irg));
197 /* complete the end_block */
198 add_immBlock_pred (get_irg_end_block(set_a_irg), x);
199 mature_immBlock (get_irg_end_block(set_a_irg));
201 /* verify the graph */
203 irg_finalize_cons (set_a_irg);
205 /****************************************************************************/
207 printf("Creating IR graph for c: \n");
209 /* Local variables self, d */
210 c_irg = new_ir_graph (proc_c_e, 2);
212 /* get the procedure parameter */
213 self = new_Proj(get_irg_args(c_irg), mode_P, 0);
214 par1 = new_Proj(get_irg_args(c_irg), mode_Is, 1);
216 /* Select the entity and load the value */
217 a_ptr = new_simpleSel(get_store(), self, a_e);
218 a_val = new_Load(get_store(), a_ptr, mode_Is);
219 set_store(new_Proj(a_val, mode_M, 0));
220 a_val = new_Proj(a_val, mode_Is, 2);
222 /* return the result */
225 in[0] = new_Add(par1, a_val, mode_Is);
227 x = new_Return (get_store (), 1, in);
229 mature_immBlock (get_irg_current_block(c_irg));
231 /* complete the end_block */
232 add_immBlock_pred (get_irg_end_block(c_irg), x);
233 mature_immBlock (get_irg_end_block(c_irg));
235 /* verify the graph */
237 irg_finalize_cons (c_irg);
239 /****************************************************************************/
241 printf("Optimizing ...\n");
242 for (i = 0; i < get_irp_n_irgs(); i++) {
243 local_optimize_graph(get_irp_irg(i));
244 dead_node_elimination(get_irp_irg(i));
247 printf("Dumping graphs of all procedures and a type graph.\n");
248 /* Touch ld names to distinguish names from oo_inline names. */
249 get_entity_ld_ident(proc_set_a_e);
250 get_entity_ld_ident(proc_c_e);
252 dump_consts_local(1);
253 turn_off_edge_labels();
255 dump_all_ir_graphs(dump_ir_graph, "");
256 dump_all_ir_graphs(dump_ir_block_graph, "");
257 dump_all_ir_graphs(dump_ir_graph_w_types, "");
258 dump_all_ir_graphs(dump_ir_block_graph_w_types, "");
259 dump_all_ir_graphs(dump_type_graph, "");
260 dump_all_ir_graphs(dump_graph_as_text, "");
262 dump_class_hierarchy (1, "");
264 entity **free_methods;
266 cgana(&arr_len, &free_methods);
267 cg_construct(arr_len, free_methods);
269 set_interprocedural_view(1);
270 dump_ir_graph(main_irg, "");
271 dump_ir_block_graph(main_irg, "");
272 dump_ir_graph_w_types(main_irg, "");
273 dump_ir_block_graph_w_types(main_irg, "");
274 dump_all_cg_block_graph("");
276 printf("Use xvcg to view these graphs:\n");
277 printf("/ben/goetz/bin/xvcg GRAPHNAME\n\n");