1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
4 ** Authors: Goetz Lindenmaier
16 /** This file constructs the IR for the following program:
22 *** return (d + self.a);
25 *** void set_a(e:int) {
44 type *owner, *class_prima;
45 type *proc_main, *proc_set_a, *proc_c;
47 entity *proc_main_e, *proc_set_a_e, *proc_c_e, *a_e;
49 ir_graph *main_irg, *set_a_irg, *c_irg;
50 ir_node *c2, *c5, *obj_o, *obj_size, *proc_ptr, *call, *res, *x;
51 ir_node *self, *par1, *a_ptr;
54 int o_pos, self_pos, e_pos;
60 set_opt_constant_folding(1);
62 set_opt_dead_node_elimination(1);
64 /*** Make basic type information for primitive type int. ***/
65 prim_t_int = new_type_primitive(id_from_str ("int", 3), mode_i);
67 /*** Make type information for the class (PRIMA). ***/
68 /* The type of the class */
69 class_prima = new_type_class(id_from_str ("PRIMA", 5));
70 /* We need type information for pointers to the class: */
71 class_p_ptr = new_type_pointer (id_from_str ("class_prima_ptr", 15),
73 /* An entity for the field (a). The entity constructor automatically adds
74 the entity as member of the owner. */
75 a_e = new_entity(class_prima, id_from_str ("a", 1), prim_t_int);
76 /* An entity for the method set_a. But first we need type information
78 proc_set_a = new_type_method(id_from_str("set_a", 5), 2, 0);
79 set_method_param_type(proc_set_a, 0, class_p_ptr);
80 set_method_param_type(proc_set_a, 1, prim_t_int);
81 proc_set_a_e = new_entity(class_prima, id_from_str ("set_a", 5), proc_set_a);
82 /* An entity for the method c. Implicit argument "self" must be modeled
84 proc_c = new_type_method(id_from_str("c", 1 ), 2, 1);
85 set_method_param_type(proc_c, 0, class_p_ptr);
86 set_method_param_type(proc_c, 1, prim_t_int);
87 set_method_res_type(proc_c, 0, prim_t_int);
88 proc_c_e = new_entity(class_prima, id_from_str ("c", 1), proc_c);
90 /*** Now build procedure main. ***/
91 /** Type information for main. **/
92 printf("\nCreating an IR graph: OO_PROGRAM_EXAMPLE...\n");
93 /* Main is not modeled as part of an explicit class here. Therefore the
94 owner is the global type. */
95 owner = get_glob_type();
96 /* Main has zero parameters and one result. */
97 proc_main = new_type_method(id_from_str("main", 4), 0, 1);
98 /* The result type is int. */
99 set_method_res_type(proc_main, 0, prim_t_int);
101 /* The entity for main. */
102 proc_main_e = new_entity (owner, id_from_str ("main", 4), proc_main);
104 /** Build code for procedure main. **/
105 /* We need one local variable (for "o"). */
106 main_irg = new_ir_graph (proc_main_e, 1);
109 /* Remark that this irg is the main routine of the program. */
110 set_irp_main_irg(main_irg);
112 /* Make the constants. They are independent of a block. */
113 c2 = new_Const (mode_i, tarval_from_long (mode_i, 2));
114 c5 = new_Const (mode_i, tarval_from_long (mode_i, 5));
116 /* There is only one block in main, it contains the allocation and the calls. */
117 /* Allocate the defined object and generate the type information. */
118 obj_size = new_SymConst((type_or_id_p)class_prima, size);
119 obj_o = new_Alloc(get_store(), obj_size, class_prima, heap_alloc);
120 set_store(new_Proj(obj_o, mode_M, 0)); /* make the changed memory visible */
121 obj_o = new_Proj(obj_o, mode_p, 2); /* remember the pointer to the object */
122 set_value(o_pos, obj_o);
124 /* Get the pointer to the procedure from the object. */
125 proc_ptr = new_simpleSel(get_store(), /* The memory containing the object. */
126 get_value(o_pos, mode_p),/* The pointer to the object. */
127 proc_set_a_e ); /* The feature to select. */
129 /* Call procedure set_a, first built array with parameters. */
132 in[0] = get_value(o_pos, mode_p);
134 call = new_Call(get_store(), proc_ptr, 2, in, proc_set_a);
136 /* Make the change to memory visible. There are no results. */
137 set_store(new_Proj(call, mode_M, 0));
139 /* Get the pointer to the nest procedure from the object. */
140 proc_ptr = new_simpleSel(get_store(), get_value(o_pos, mode_p), proc_c_e);
142 /* call procedure c, first built array with parameters */
145 in[0] = get_value(o_pos, mode_p);
147 call = new_Call(get_store(), proc_ptr, 2, in, proc_c);
149 /* make the change to memory visible */
150 set_store(new_Proj(call, mode_M, 0));
151 /* Get the result of the procedure: select the result tuple from the call,
152 then the proper result from the tuple. */
153 res = new_Proj(new_Proj(call, mode_T, 2), mode_i, 0);
155 /* return the results of procedure main */
159 x = new_Return (get_store(), 1, in);
161 mature_block (get_irg_current_block(main_irg));
163 /* complete the end_block */
164 add_in_edge (get_irg_end_block(main_irg), x);
165 mature_block (get_irg_end_block(main_irg));
168 finalize_cons (main_irg);
170 /****************************************************************************/
172 printf("Creating IR graph for set_a: \n");
174 /* Local variables: self, e */
175 set_a_irg = new_ir_graph (proc_set_a_e, 2);
176 self_pos = 0; e_pos = 1;
178 /* get the procedure parameter */
179 self = new_Proj(get_irg_args(set_a_irg), mode_p, 0);
180 set_value(self_pos, self);
181 par1 = new_Proj(get_irg_args(set_a_irg), mode_i, 1);
182 set_value(e_pos, par1);
183 /* Create and select the entity to set */
184 a_ptr = new_simpleSel(get_store(), self, a_e);
185 /* perform the assignment */
186 set_store(new_Proj(new_Store(get_store(), a_ptr, par1), mode_M, 0));
189 x = new_Return (get_store (), 0, NULL);
190 mature_block (get_irg_current_block(set_a_irg));
192 /* complete the end_block */
193 add_in_edge (get_irg_end_block(set_a_irg), x);
194 mature_block (get_irg_end_block(set_a_irg));
196 /* verify the graph */
198 finalize_cons (set_a_irg);
200 /****************************************************************************/
202 printf("Creating IR graph for c: \n");
204 /* Local variables self, d */
205 c_irg = new_ir_graph (proc_c_e, 2);
207 /* get the procedure parameter */
208 self = new_Proj(get_irg_args(c_irg), mode_p, 0);
209 par1 = new_Proj(get_irg_args(c_irg), mode_i, 1);
211 /* Select the entity and load the value */
212 a_ptr = new_simpleSel(get_store(), self, a_e);
213 a_val = new_Load(get_store(), a_ptr);
214 set_store(new_Proj(a_val, mode_M, 0));
215 a_val = new_Proj(a_val, mode_i, 2);
217 /* return the result */
220 in[0] = new_Add(par1, a_val, mode_i);
222 x = new_Return (get_store (), 1, in);
224 mature_block (get_irg_current_block(c_irg));
226 /* complete the end_block */
227 add_in_edge (get_irg_end_block(c_irg), x);
228 mature_block (get_irg_end_block(c_irg));
230 /* verify the graph */
232 finalize_cons (c_irg);
234 /****************************************************************************/
236 printf("Optimizing ...\n");
237 for (i = 0; i < get_irp_n_irgs(); i++) {
238 local_optimize_graph(get_irp_irg(i));
239 dead_node_elimination(get_irp_irg(i));
242 printf("Dumping graphs of all procedures and a type graph.\n");
243 dump_all_ir_graphs(dump_ir_block_graph);
244 dump_all_ir_graphs(dump_ir_block_graph_w_types);
247 printf("Use xvcg to view these graphs:\n");
248 printf("/ben/goetz/bin/xvcg GRAPHNAME\n\n");