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(id_from_str ("int", 3), mode_Is);
71 /*** Make type information for the class (PRIMA). ***/
72 /* The type of the class */
73 class_prima = new_type_class(id_from_str ("PRIMA", 5));
74 /* We need type information for pointers to the class: */
75 class_p_ptr = new_type_pointer (id_from_str ("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, id_from_str ("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(id_from_str("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, id_from_str ("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(id_from_str("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, id_from_str ("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(id_from_str("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, id_from_str ("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 obj_size = new_SymConst((type_or_id_p)class_prima, size);
123 obj_o = new_Alloc(get_store(), obj_size, class_prima, heap_alloc);
124 set_store(new_Proj(obj_o, mode_M, 0)); /* make the changed memory visible */
125 obj_o = new_Proj(obj_o, mode_P, 2); /* remember the pointer to the object */
126 set_value(o_pos, obj_o);
128 /* Get the pointer to the procedure from the object. */
129 proc_ptr = new_simpleSel(get_store(), /* The memory containing the object. */
130 get_value(o_pos, mode_P),/* The pointer to the object. */
131 proc_set_a_e ); /* The feature to select. */
133 /* Call procedure set_a, first built array with parameters. */
136 in[0] = get_value(o_pos, mode_P);
138 call = new_Call(get_store(), proc_ptr, 2, in, proc_set_a);
140 /* Make the change to memory visible. There are no results. */
141 set_store(new_Proj(call, mode_M, 0));
143 /* Get the pointer to the nest procedure from the object. */
144 proc_ptr = new_simpleSel(get_store(), get_value(o_pos, mode_P), proc_c_e);
146 /* call procedure c, first built array with parameters */
149 in[0] = get_value(o_pos, mode_P);
151 call = new_Call(get_store(), proc_ptr, 2, in, proc_c);
153 /* make the change to memory visible */
154 set_store(new_Proj(call, mode_M, 0));
155 /* Get the result of the procedure: select the result tuple from the call,
156 then the proper result from the tuple. */
157 res = new_Proj(new_Proj(call, mode_T, 2), mode_Is, 0);
159 /* return the results of procedure main */
163 x = new_Return (get_store(), 1, in);
165 mature_block (get_irg_current_block(main_irg));
167 /* complete the end_block */
168 add_in_edge (get_irg_end_block(main_irg), x);
169 mature_block (get_irg_end_block(main_irg));
172 finalize_cons (main_irg);
174 /****************************************************************************/
176 printf("Creating IR graph for set_a: \n");
178 /* Local variables: self, e */
179 set_a_irg = new_ir_graph (proc_set_a_e, 2);
180 self_pos = 0; e_pos = 1;
182 /* get the procedure parameter */
183 self = new_Proj(get_irg_args(set_a_irg), mode_P, 0);
184 set_value(self_pos, self);
185 par1 = new_Proj(get_irg_args(set_a_irg), mode_Is, 1);
186 set_value(e_pos, par1);
187 /* Create and select the entity to set */
188 a_ptr = new_simpleSel(get_store(), self, a_e);
189 /* perform the assignment */
190 set_store(new_Proj(new_Store(get_store(), a_ptr, par1), mode_M, 0));
193 x = new_Return (get_store (), 0, NULL);
194 mature_block (get_irg_current_block(set_a_irg));
196 /* complete the end_block */
197 add_in_edge (get_irg_end_block(set_a_irg), x);
198 mature_block (get_irg_end_block(set_a_irg));
200 /* verify the graph */
202 finalize_cons (set_a_irg);
204 /****************************************************************************/
206 printf("Creating IR graph for c: \n");
208 /* Local variables self, d */
209 c_irg = new_ir_graph (proc_c_e, 2);
211 /* get the procedure parameter */
212 self = new_Proj(get_irg_args(c_irg), mode_P, 0);
213 par1 = new_Proj(get_irg_args(c_irg), mode_Is, 1);
215 /* Select the entity and load the value */
216 a_ptr = new_simpleSel(get_store(), self, a_e);
217 a_val = new_Load(get_store(), a_ptr);
218 set_store(new_Proj(a_val, mode_M, 0));
219 a_val = new_Proj(a_val, mode_Is, 2);
221 /* return the result */
224 in[0] = new_Add(par1, a_val, mode_Is);
226 x = new_Return (get_store (), 1, in);
228 mature_block (get_irg_current_block(c_irg));
230 /* complete the end_block */
231 add_in_edge (get_irg_end_block(c_irg), x);
232 mature_block (get_irg_end_block(c_irg));
234 /* verify the graph */
236 finalize_cons (c_irg);
238 /****************************************************************************/
240 printf("Optimizing ...\n");
241 for (i = 0; i < get_irp_n_irgs(); i++) {
242 local_optimize_graph(get_irp_irg(i));
243 dead_node_elimination(get_irp_irg(i));
246 printf("Dumping graphs of all procedures and a type graph.\n");
247 /* Touch ld names to distinguish names from oo_inline names. */
248 get_entity_ld_ident(proc_set_a_e);
249 get_entity_ld_ident(proc_c_e);
252 dump_all_ir_graphs(dump_ir_graph);
253 dump_all_ir_graphs(dump_ir_block_graph);
254 dump_all_ir_graphs(dump_ir_graph_w_types);
255 dump_all_ir_graphs(dump_ir_block_graph_w_types);
256 dump_all_ir_graphs(dump_type_graph);
258 dump_class_hierarchy (true);
261 entity **free_methods;
263 cgana(&arr_len, &free_methods);
264 cg_construct(arr_len, free_methods);
266 interprocedural_view = 1;
267 dump_ir_graph(main_irg);
268 dump_ir_block_graph(main_irg);
269 dump_ir_graph_w_types(main_irg);
270 dump_ir_block_graph_w_types(main_irg);
271 dump_all_cg_block_graph();
273 printf("Use xvcg to view these graphs:\n");
274 printf("/ben/goetz/bin/xvcg GRAPHNAME\n\n");