5 File name: ir/ana/pto_comp.c
6 Purpose: Main Implementation of PTO
9 Created: Sat Nov 13 19:35:27 CET 2004
11 Copyright: (c) 1999-2004 Universität Karlsruhe
12 Licence: This file is protected by the GPL - GNU GENERAL PUBLIC LICENSE.
20 pto_comp: Main Implementation of PTO
23 # include <string.h> /* for memset */
25 # include "pto_comp.h"
26 # include "pto_util.h"
32 # include "irmemwalk.h"
34 # include "pto_debug.h"
35 # include "pto_init.h"
41 /* Local Data Types: */
42 typedef struct pto_env_str {
47 /* Local Variables: */
52 /* Local Prototypes: */
53 static void pto_graph (ir_graph*);
54 static void pto_call (ir_graph*, ir_node*, pto_env_t*);
56 /* ===================================================
58 =================================================== */
60 /* Propagation of PTO values */
61 static pto_t *get_pto_proj (ir_node *proj)
63 ir_node *proj_in = get_Proj_pred (proj);
64 const long proj_proj = get_Proj_proj (proj);
65 const opcode in_op = get_irn_opcode (proj_in);
67 pto_t *proj_pto = get_node_pto (proj);
70 case (iro_Start): /* ProjT (Start) */
71 assert (0 && "pto from ProjT(Start) requested");
74 case (iro_Proj): /* ProjT (Start), ProjT (Call) */
75 assert ((pn_Start_T_args == proj_proj) ||
76 (pn_Call_T_result == proj_proj));
77 ir_node *proj_in_in = get_Proj_pred (proj_in);
78 const opcode in_in_op = get_irn_opcode (proj_in_in);
81 case (iro_Start): /* ProjArg (ProjT (Start)) */
82 /* then the pto value must have been set to the node */
86 case (iro_Call): /* ProjV (ProjT (Call)) */
87 if (NULL != proj_pto) {
90 in_pto = get_node_pto (proj_in);
91 set_node_pto (proj, in_pto);
95 default: assert (0 && "Proj(Proj(?))");
97 /* done with case (in_op == iro_Proj) */
99 case (iro_Load): /* ProjV (Load) */
100 assert (pn_Load_res == proj_proj);
102 case (iro_Call): /* ProjT (Call) */
104 case (iro_Alloc): /* ProjV (Alloc) */
105 if (NULL != proj_pto) {
108 in_pto = get_alloc_pto (proj_in);
111 set_node_pto (proj, in_pto);
115 fprintf (stderr, "%s: not handled: proj (%s[%li])\n",
117 get_op_name (get_irn_op (proj_in)),
118 get_irn_node_nr (proj_in));
119 assert (0 && "Proj(?)");
124 static pto_t *get_pto_phi (ir_node *phi)
129 static pto_t *get_pto_ret (ir_node *ret)
131 pto_t *pto = get_node_pto (ret);
134 ir_node *in = get_Return_res (ret, 0);
136 pto = get_node_pto (in);
137 set_node_pto (ret, pto);
144 /* Dispatch to propagate PTO values */
145 static pto_t *get_pto (ir_node *node)
147 const opcode op = get_irn_opcode (node);
150 case (iro_Cast): return (get_pto (get_Cast_op (node)));
151 case (iro_Proj): return (get_pto_proj (node));
152 case (iro_Phi): return (get_pto_phi (node));
153 case (iro_Return): return (get_pto_ret (node));
156 /* stopgap measure */
157 fprintf (stderr, "%s: not handled: node[%li].op = %s\n",
159 get_irn_node_nr (node),
160 get_op_name (get_irn_op (node)));
161 assert (0 && "something not handled");
167 /* Actions for the nodes: */
168 static void pto_load (ir_node *load, pto_env_t *pto_env)
171 DBGPRINT (0, (stdout, "%s (%s[%li])\n", __FUNCTION__, OPNAME (load), OPNUM (load)));
174 static void pto_store (ir_node *store, pto_env_t *pto_env)
177 DBGPRINT (0, (stdout, "%s (%s[%li])\n", __FUNCTION__,
178 OPNAME (store), OPNUM (store)));
181 static void pto_method (ir_node *call, pto_env_t *pto_env)
183 DBGPRINT (0, (stdout, "%s:%i (%s[%li])\n",
184 __FUNCTION__, __LINE__, OPNAME (call), OPNUM (call)));
186 callEd_info_t *callEd_info = ecg_get_callEd_info (call);
189 while (NULL != callEd_info) {
190 DBGPRINT (0, (stdout, "%s:%i (%s[%li]), graph %i\n",
191 __FUNCTION__, __LINE__, OPNAME (call), OPNUM (call), i ++));
193 pto_call (callEd_info->callEd, call, pto_env);
195 callEd_info = callEd_info->prev;
200 /* Continue PTO for one of the graphs called at a Call */
201 static void pto_call (ir_graph *graph, ir_node *call, pto_env_t *pto_env)
204 DBGPRINT (0, (stdout, "%s:%i (%s[%li])\n",
205 __FUNCTION__, __LINE__, OPNAME (call), OPNUM (call)));
207 /* only for debugging stuff: */
208 entity *ent = get_irg_entity (graph);
209 const char *ent_name = (char*) get_entity_name (ent);
210 const char *own_name = (char*) get_type_name (get_entity_owner (ent));
212 if (! get_irg_is_mem_visited (graph)) {
213 graph_info_t *ginfo = ecg_get_info (graph);
216 int ctx_idx = find_ctx_idx (call, ginfo, get_curr_ctx ());
217 ctx_info_t *call_ctx = get_ctx (ginfo, ctx_idx);
218 ctx_info_t *old_ctx = set_curr_ctx (call_ctx);
219 DBGPRINT (1, (stdout, "%s>CTX: ", -- spaces));
220 DBGEXE (1, ecg_print_ctx (call_ctx, stdout));
222 /* Todo: Compute Arguments */
224 /* Initialise Alloc Names and Node values */
225 pto_reset_graph_pto (graph, ctx_idx);
227 /* Visit/Iterate Graph */
231 set_curr_ctx (old_ctx);
233 DBGPRINT (1, (stdout, "%s<CTX: ", spaces ++));
234 DBGEXE (1, ecg_print_ctx (call_ctx, stdout));
236 /* Don't need to reset alloc names unless we handle recursion here */
239 /* Get Return Value from Graph */
241 DBGPRINT (0, (stdout, "%s: recursion into \"%s.%s\"\n",
242 __FUNCTION__, own_name, ent_name));
245 /* Todo: Set 'Unknown' Value as Return Value when the graph is not
249 static void pto_raise (ir_node *raise, pto_env_t *pto_env)
252 DBGPRINT (0, (stdout, "%s (%s[%li])\n", __FUNCTION__,
253 OPNAME (raise), OPNUM (raise)));
256 static void pto_end_block (ir_node *end_block, pto_env_t *pto_env)
258 /* perform end block */
259 DBGPRINT (0, (stdout, "%s (%s[%li])\n", __FUNCTION__,
260 OPNAME (end_block), OPNUM (end_block)));
263 /* Perform the appropriate action on the given node */
264 static void pto_node_node (ir_node *node, pto_env_t *pto_env)
266 const opcode op = get_irn_opcode (node);
269 case (iro_Start): /* nothing */ break;
271 pto_load (node, pto_env);
275 pto_store (node, pto_env);
279 pto_method (node, pto_env);
283 pto_raise (node, pto_env);
295 pto_end_block (node, pto_env);
300 assert (mode_M == get_irn_mode (node));
304 /* uninteresting stuff: */
308 case (iro_DivMod): /* nothing to do */ break;
311 /* stopgap measure */
312 fprintf (stderr, "%s: not handled: node[%li].op = %s\n",
314 get_irn_node_nr (node),
315 get_op_name (get_irn_op (node)));
316 assert (0 && "something not handled");
324 /* Callback function to execute in pre-order */
325 static void pto_node_pre (ir_node *node, void *env)
330 /* Callback function to execute in post-order */
331 static void pto_node_post (ir_node *node, void *env)
333 pto_env_t *pto_env = (pto_env_t*) env;
335 pto_node_node (node, pto_env);
338 /* Perform a single pass over the given graph */
339 static void pto_graph_pass (ir_graph *graph, void *pto_env)
341 entity *ent = get_irg_entity (graph);
342 const char *ent_name = (char*) get_entity_name (ent);
343 const char *own_name = (char*) get_type_name (get_entity_owner (ent));
344 HERE3 ("start", own_name, ent_name);
346 irg_walk_mem (graph, pto_node_pre, pto_node_post, pto_env);
348 HERE3 ("end ", own_name, ent_name);
352 /* Main loop: Initialise and iterate over the given graph */
353 static void pto_graph (ir_graph *graph)
355 pto_env_t *pto_env = xmalloc (sizeof (pto_env_t));
358 /* todo (here): iterate, obey 'changed' attribute */
359 pto_graph_pass (graph, pto_env);
361 memset (pto_env, 0x00, sizeof (pto_env_t));
366 /* "Fake" the arguments to the main method */
367 static void fake_main_args (ir_graph *graph)
370 /* todo: fake the arguments to the main method */
375 /* Helper to pto_init */
376 static void pto_init_graph_wrapper (graph_info_t *ginfo, void *__unused)
378 ir_graph *graph = ginfo->graph;
380 pto_init_graph (graph);
384 /* ===================================================
385 Exported Implementation:
386 =================================================== */
387 /* Set the PTO value for the given non-alloc node */
388 void set_node_pto (ir_node *node, pto_t *pto)
390 assert (iro_Alloc != get_irn_opcode (node));
392 set_irn_link (node, (void*) pto);
395 /*Get the PTO value for the given non-alloc node */
396 pto_t *get_node_pto (ir_node *node)
398 assert (iro_Alloc != get_irn_opcode (node));
400 return ((pto_t*) get_irn_link (node));
403 /* Set the PTO value for the given alloc node */
404 void set_alloc_pto (ir_node *alloc, alloc_pto_t *alloc_pto)
406 assert (iro_Alloc == get_irn_opcode (alloc));
408 set_irn_link (alloc, (void*) alloc_pto);
411 /*Get the current PTO value for the given alloc node */
412 pto_t *get_alloc_pto (ir_node *alloc)
414 alloc_pto_t *alloc_pto = (alloc_pto_t*) get_irn_link (alloc);
416 assert (iro_Alloc == get_irn_opcode (alloc));
418 return (alloc_pto -> curr_pto);
421 /* Initialise the module (not in pto_init.c because it's the entry to pto) */
427 /* todo: initialise globals etc */
428 pto_init_type_names ();
430 /* todo: allocate ctx-sens names for allocs and set ... etc etc */
431 pto_init_type_names ();
433 ecg_iterate_graphs (pto_init_graph_wrapper, NULL);
435 spaces = (char*) xmalloc (512 * sizeof (char));
436 memset (spaces, ' ', 512);
440 /* initialise for the CTX-sensitive ecg-traversal */
441 set_curr_ctx (get_main_ctx ());
445 void pto_run (int dbg_lvl)
448 set_dbg_lvl (dbg_lvl);
450 ir_graph *graph = get_irp_main_irg ();
451 fake_main_args (graph);
453 /* todo: clear entity/type links */
455 DBGPRINT (0, (stdout, "START PTO\n"));
456 DBGPRINT (0, (stdout, "START GRAPH (0x%08x) of \"%s.%s\"\n",
458 get_type_name (get_entity_owner (get_irg_entity (graph))),
459 get_entity_name (get_irg_entity (graph))));
461 /* do we need some kind of environment here? */
464 DBGPRINT (0, (stdout, "END PTO\n"));
471 /* todo: clean up our own mess */
472 spaces -= 511; /* hope that all changes to spaces are
474 memset (spaces, 0x00, 512);
477 /* clean up ecg infos */
485 Revision 1.2 2004/11/20 21:21:56 liekweg
486 Finalise initialisation
488 Revision 1.1 2004/11/18 16:37:34 liekweg