5 * File name: ir/ana2/pto.c
9 * Created: Mon 18 Oct 2004
11 * Copyright: (c) 1999-2004 Universität Karlsruhe
12 * Licence: This file is protected by GPL - GNU GENERAL PUBLIC LICENSE.
21 # include "pto_util.h"
25 # include "irnode_t.h"
26 # include "irprog_t.h"
28 /* # include "eset.h" */
36 # include "irmemwalk.h"
41 # endif /* not defined TRUE */
43 typedef struct pto_str
51 static void pto_node (ir_node*, void*);
56 static int verbose = TRUE;
59 Create a new pto value
61 static pto_t *new_pto (void)
63 pto_t *pto = (pto_t*) xmalloc (sizeof (pto_t));
70 Get the pto infos of a node
72 static pto_t *get_pto (ir_node *node)
74 return ((pto_t*) node->link);
77 static pto_t *compute_pto (ir_node *node, void *env)
79 pto_t *node_pto = get_pto (node);
81 if (NULL == node_pto) {
84 node_pto = get_pto (node);
92 static void set_pto (ir_node *node, pto_t *ptrs)
94 node->link = (void*) ptrs;
98 Take care of a single proj node. Basically a multiplex/dispatch for the
99 different node types that a proj can have as a predecessor.
101 static void pto_node_proj (ir_node *proj, void *env)
104 pto for proj({proj(start),load,call,alloc,raise?,...}) node
107 whatever it is we have in front of us, it's analyzed.
109 we just pick up the pointer.
111 ir_node *in = get_Proj_pred (proj);
112 const opcode in_op = get_irn_opcode (in);
113 const long proj_proj = get_Proj_proj (proj);
115 fprintf (stdout, "%s: --> Proj[%li] (%s)\n",
117 get_irn_node_nr (proj),
118 get_op_name (get_irn_op (in)));
122 /* nothing (handled by proj(proj)) */
127 if (pn_Load_res == proj_proj) {
128 set_pto (proj, compute_pto (in, env));
130 /* ProjM(load) or ProjX(load) - do nothing */
135 /* ProjM (store) or ProjX (store) - nothing */
139 /* copy from alloc */
140 if (pn_Alloc_res == proj_proj) {
141 set_pto (proj, compute_pto (in, env));
143 /* ProjM(alloc) or ProjX (alloc) -- nothing */
148 /* ProjX (raise), ProjM (raise) -- nothing */
152 if (pn_Call_M_regular == proj_proj) {
153 /* ProjM(call) -- nothing */
154 } else if (pn_Call_T_result == proj_proj) {
155 /* copy return value of call */
156 set_pto (proj, compute_pto (in, env));
157 } else if (pn_Call_P_value_res_base == proj_proj) {
159 assert (0 && "what's with pn_Call_P_value_res_base?");
161 /* ProjX (call) or ProjM_exc (call) -- nothing */
167 const ir_node *in_in = get_Proj_pred (in);
168 const opcode in_in_op = get_irn_opcode (in_in);
170 assert (iro_Start == in_in_op && "proj (proj (X)) but not X != Start");
171 /* proj(proj(start)) - make sure the arguments are initialised */
172 fprintf (stdout, "pto (proj(%li)) = 0x%08x\n",
173 get_irn_node_nr (proj),
174 (int) get_pto (proj));
175 set_pto (proj, NULL);
179 /* make sure the input has been analysed */
180 pto_t *cast_pto = compute_pto (in, env);
181 set_pto (proj, cast_pto);
186 fprintf (stderr, "Opcode %s of Node %ld not handled\n",
187 get_op_name (get_irn_op (in)),
188 get_irn_node_nr (in));
190 assert (0 && "something not handled");
195 fprintf (stdout, "---> Proj (%s)\n", get_op_name (get_irn_op (in)));
200 static void pto_node_load (ir_node *load, void *env)
211 /* right now, just copy something */
212 ir_node *ptr = get_Load_ptr (load);
213 const opcode op = get_irn_opcode (ptr);
217 ent = get_Sel_entity (ptr);
218 } else if (iro_SymConst == op) {
219 ent = get_SymConst_entity (ptr);
220 } else if (iro_Proj == op) {
221 /* then it's an unused Load(this) (or whatever) and we don't need to look at it */
223 } else if (iro_Cast == op) {
224 /* then it's whatever and we don't know where to look at */
227 fprintf (stdout, "%s: %s[%li] not handled\n",
229 get_op_name (get_irn_op (ptr)),
230 get_irn_node_nr (ptr));
231 assert (0 && "told ya");
235 pto_t *ptr_pto = compute_pto (ptr, env);
238 /* todo: use 'ent' to look up */
239 set_pto (load, ptr_pto); /* for now */
243 static void pto_node_store (ir_node *store, void *env)
254 /* right now, just copy something */
255 ir_node *ptr = get_Store_ptr (store);
256 const opcode op = get_irn_opcode (ptr);
260 ent = get_Sel_entity (ptr);
261 } else if (iro_SymConst == op) {
262 ent = get_SymConst_entity (ptr);
264 fprintf (stdout, "%s: opcode %s not handled\n",
265 __FUNCTION__, get_op_name (get_irn_op (ptr)));
266 assert (0 && "told ya");
269 pto_t *ptr_pto = compute_pto (ptr, env);
270 /* todo: use 'ent' to look up */
271 fprintf (stdout, "%s: pto (store[%li]) = 0x%08d\n",
272 __FUNCTION__, get_irn_node_nr (ptr), (int) ptr_pto);
275 static void pto_node_alloc (ir_node *alloc, void *env)
286 pto_t *alloc_pto = (pto_t*) xmalloc (sizeof (pto_t));
288 set_pto (alloc, alloc_pto);
291 static void pto_node_free (ir_node *free, void *env)
301 /* still, copy somthing */
302 ir_node *ptr = get_Free_ptr (free);
304 pto_t *ptr_pto = compute_pto (ptr, env);
305 set_pto (free, ptr_pto);
308 static void pto_node_raise (ir_node *raise, void *env)
319 /* right now, just copy something */
320 ir_node *ptr = get_Raise_exo_ptr (raise);
322 pto_t *ptr_pto = compute_pto (ptr, env);
324 set_pto (raise, ptr_pto);
327 static void pto_node_sel (ir_node *sel, void *env)
338 ir_node *sel_in = get_Sel_ptr (sel);
339 pto_t *sel_pto = compute_pto (sel_in, env);
341 if (NULL == sel_pto) {
342 fprintf (stdout, "%s:%i: sel.in = %s[%li]\n",
343 __FUNCTION__, __LINE__,
344 get_op_name (get_irn_op (sel_in)),
345 get_irn_node_nr (sel_in));
349 set_pto (sel, sel_pto);
353 static void pto_node_call (ir_node *call, void *env)
356 int n_ins = get_irn_arity (call);
359 for (i = 0; i < n_ins; i ++) {
360 in = get_irn_n (call, i);
362 if (mode_P == get_irn_mode (in)) {
363 fprintf (stdout, "--> IN CALL Node (%ld) (%s)\n",
364 get_irn_node_nr (in),
365 get_op_name (get_irn_op (in)));
369 # endif /* defined UNSINN */
371 static void pto_node_ret (ir_node *ret, void *env)
377 input should be availlable
382 if (mode_P == get_irn_mode (ret)) {
383 ir_node *ret_in = get_Return_res_arr (ret) [0];
385 pto_t *ret_pto = compute_pto (ret_in, env);
387 set_pto (ret, ret_pto);
389 /* set_pto (ret, NULL); */
394 static void pto_node_phi (ir_node *phi, void *env)
400 all ins present (or?)
406 int n_ins = get_irn_arity (phi);
409 if (mode_P != get_irn_mode (phi)) {
413 for (i = 0; i < n_ins; i ++) {
414 in = get_irn_n (phi, i);
416 pto_t *in_pto = compute_pto (in, env);
418 fprintf (stdout, "--> IN PHI Node (%ld) (%s) (pto = 0x%08x)\n",
419 get_irn_node_nr (in),
420 get_op_name (get_irn_op (in)),
423 /* must 'merge', but just set something now: */
424 set_pto (phi, in_pto);
429 static void pto_node_cnst (ir_node *cnst, void *env)
437 if this represents something nameable, name it
439 pto_t *cnst_pto = new_pto ();
442 set_pto (cnst, cnst_pto);
445 static void pto_node_sym_cnst (ir_node *sym_cnst, void *env)
453 if this represents something nameable, name it
455 pto_t *sym_cnst_pto = new_pto ();
458 set_pto (sym_cnst, sym_cnst_pto);
463 Take care of a single node. Basically a multiplex/dispatch for the
464 different node types.
466 static void pto_node (ir_node *node, void *env)
468 const opcode op = get_irn_opcode (node);
471 fprintf (stdout, "-> Node (%ld) (%s)\n",
472 get_irn_node_nr (node),
473 get_op_name (get_irn_op (node)));
478 /* pto_node_start (node, env); */
483 pto_node_load (node, env);
487 pto_node_store (node, env);
491 pto_node_alloc (node, env);
495 pto_node_free (node, env);
499 pto_node_raise (node, env);
503 pto_node_sel (node, env);
507 assert (0 && "calls must be handled in main loop");
508 /* pto_node_call (node, env); */
509 /* also, we should at best look at the ProjV hanging off a call */
513 if (0 < get_Return_n_ress (node)) {
514 pto_node_ret (node, env);
518 pto_node_proj (node, env);
521 pto_node_phi (node, env);
524 pto_node_cnst (node, env);
526 case (iro_SymConst): {
527 pto_node_sym_cnst (node, env);
530 pto_t *cast_pto = compute_pto (get_Cast_op (node), env);
531 set_pto (node, cast_pto);
537 set_pto (node, NULL);
540 fprintf (stdout, "%s: not handled: node[%li].op = %s\n",
542 get_irn_node_nr (node),
543 get_op_name (get_irn_op (node)));
544 assert (0 && "something not handled");
549 static void pto_node_post (ir_node *node, void *env)
551 const opcode op = get_irn_opcode (node);
554 if (iro_Call == op) {
555 ir_node *call = node;
558 ir_graph *graph = NULL;
559 ir_node *ptr = get_Call_ptr (call);
562 fprintf (stdout, "POST MEM Call Node (%ld)\n",
563 get_irn_node_nr (call));
566 if (iro_Sel == get_irn_opcode (ptr)) {
567 ent = get_Sel_entity (ptr);
568 } else if (iro_SymConst == get_irn_opcode (ptr)) {
569 if (get_SymConst_kind(ptr) == symconst_addr_ent) {
570 ent = get_SymConst_entity (ptr);
574 assert (NULL != ent && "No ent to call");
576 /* Todo: Iterate over all graphs in 'get_implementing_graphs' */
577 graph = get_entity_irg (ent);
579 const char *ent_name = (char*) get_entity_name (ent);
580 const char *own_name = (char*) get_type_name (get_entity_owner (ent));
582 if (! get_irg_is_mem_visited (graph)) {
584 fprintf (stdout, " -> visit graph (0x%08x) of \"%s.%s\"\n",
591 ent_tp = get_entity_type (ent);
593 get_method_n_params (ent_tp);
594 ir_node **args = find_irg_args (graph);
597 const int n_call_args = get_irn_arity (call);
599 assert (n_call_args == n_call_args);
601 /* Set args for graph */
603 for (i = 0; i < n_args; i ++) {
604 if (NULL != args [i]) {
605 if (mode_P == get_irn_mode (args [i])) {
606 pto_t *arg_pto = compute_pto (get_irn_n (call, i+1), env);
607 /* off-by-one because of ProjT bd */
608 set_pto (args [i], arg_pto);
610 /* set_pto (args [i], NULL); */
618 irg_walk_mem (graph, NULL, pto_node_post, NULL);
620 /* maybe get result from called graph */
621 if (0 != get_method_n_ress (ent_tp)) {
622 type *ent_ret_tp = get_method_res_type (ent_tp, 0);
624 if (mode_P == get_type_mode (ent_ret_tp)) {
625 pto_t *res_pto = get_pto (get_irg_end (graph));
626 set_pto (call, res_pto);
629 fprintf (stdout, "%s:%i: no return value for \"%s.%s\"\n",
630 __FUNCTION__, __LINE__,
631 get_type_name (get_entity_owner (ent)),
632 get_entity_name (ent));
637 fprintf (stdout, "%s:%i: Warning: no graph for ent \"%s.%s\"\n",
638 __FUNCTION__, __LINE__,
639 get_type_name (get_entity_owner (ent)),
640 get_entity_name (ent));
645 pto_node (node, env);
652 void pto_run (int do_verbose)
655 verbose = do_verbose;
658 fprintf (stdout, "START PTO\n");
661 ir_graph *graph = get_irp_main_irg ();
664 fprintf (stdout, "START GRAPH (0x%08x) of \"%s.%s\"\n",
666 get_type_name (get_entity_owner (get_irg_entity (graph))),
667 get_entity_name (get_irg_entity (graph)));
671 pto_t *main_pto = new_pto ();
673 get_method_n_params (get_entity_type (get_irg_entity (graph)));
674 ir_node **args = find_irg_args (graph);
678 Todo: Set args for MAIN graph!!!
681 for (i = 0; i < n_args; i ++) {
682 fprintf (stdout, "arg [%i] = %ld\n", i,
683 args [i] ? get_irn_node_nr (args [i]) : -1);
685 set_pto (args [1], main_pto);
690 irg_walk_mem (graph, NULL, pto_node_post, NULL);
693 fprintf (stdout, "END GRAPH (0x%08x)\n", (int) graph);
697 fprintf (stdout, "END PTO\n");
713 * Revision 1.3 2004/10/25 11:59:45 liekweg
716 * Revision 1.2 2004/10/21 11:09:37 liekweg
717 * Moved memwalk stuf into irmemwalk
718 * Moved lset stuff into lset
719 * Moved typalise stuff into typalise
721 * Revision 1.1 2004/10/20 14:59:42 liekweg
722 * Added ana2, added ecg and pto