-static pto_t *compute_pto (ir_node *node, void *env)
-{
- pto_t *node_pto = get_pto (node);
-
- if (NULL == node_pto) {
- DBGPRINT (1, (stdout, "%s: must compute pto for %s[%li]\n",
- __FUNCTION__,
- get_op_name (get_irn_op (node)),
- get_irn_node_nr (node)));
-
- pto_node (node, env);
-
- node_pto = get_pto (node);
- }
-
- assert (node_pto);
-
- return (node_pto);
-}
-
-/*
- Transfer the actual arguments to the given call's formal arguments
-*/
-static void set_call_args (ir_node *call, ir_graph *graph, void *env)
-{
- ir_node **args = find_irg_args (graph);
- int i;
-
- const int n_call_args = get_irn_arity (call);
-
- /* call: M x meth_ptr x Arg x Arg x ... x Arg */
- /* projT(start): Arg x Arg x ... x Arg */
- /* projM(start): M */
-
- for (i = 2; i < n_call_args; i ++) {
- if (NULL != args [i-2]) {
- if (mode_P == get_irn_mode (args [i-2])) {
- pto_t *arg_pto = compute_pto (get_irn_n (call, i), env);
- /* off-by-one because of ProjT bd */
- set_pto (args [i-2], arg_pto);
- } else {
- /* nothing */
- }
- }
- }
- free (args);
-}
-
-/*
- Transfer the return value of a call to the callR node
-*/
-static void get_call_ret (ir_node *call, ir_graph *graph, void *env)
-{
- entity *ent = get_irg_ent (graph);
- type *ent_tp = get_entity_type (ent);
-
- if (0 != get_method_n_ress (ent_tp)) {
- type *ent_ret_tp = get_method_res_type (ent_tp, 0);
-
- if (mode_P == get_type_mode (ent_ret_tp)) {
- pto_t *res_pto = get_pto (get_irg_end_block (graph));
-
- set_pto (call, res_pto);
- }
- }
-}
-
-
-/*
- Take care of a single proj node. Basically a multiplex/dispatch for the
- different node types that a proj can have as a predecessor.
-*/
-static void pto_node_proj (ir_node *proj, void *env)
-{
- /*
- pto for proj({proj(start),load,call,alloc,raise?,...}) node
- */
- ir_node *in = get_Proj_pred (proj);
- const opcode in_op = get_irn_opcode (in);
- const long proj_proj = get_Proj_proj (proj);
-
- DBGPRINT (3, (stdout, "%s: --> Proj[%li] (%s)\n",
- __FUNCTION__,
- get_irn_node_nr (proj),
- get_op_name (get_irn_op (in))));
-
- switch (in_op) {
- case (iro_Start): {
- /* nothing (handled by proj(proj)) */
- } break;
-
- case (iro_Load): {
- /* copy from load */
- if (pn_Load_res == proj_proj) {
- set_pto (proj, compute_pto (in, env));
- } else {
- /* ProjM(load) or ProjX(load) - do nothing */
- }
- } break;
-
- case (iro_Store): {
- /* ProjM (store) or ProjX (store) - nothing */
- } break;
-
- case (iro_Alloc): {
- /* copy from alloc */
- if (pn_Alloc_res == proj_proj) {
- set_pto (proj, compute_pto (in, env));
- } else {
- /* ProjM(alloc) or ProjX (alloc) -- nothing */
- }
- } break;
-
- case (iro_Raise): {
- /* ProjX (raise), ProjM (raise) -- nothing */
- } break;
-
- case (iro_Call): {
- if (pn_Call_M_regular == proj_proj) {
- /* ProjM(call) -- nothing */
- } else if (pn_Call_T_result == proj_proj) {
- /* copy return value of call */
- pto_t *call_pto = get_pto (in); /* get result from call */
- assert (call_pto);
- set_pto (proj, call_pto);
- } else if (pn_Call_P_value_res_base == proj_proj) {
- /* wtf? */
- assert (0 && "what's with pn_Call_P_value_res_base?");
- } else {
- /* ProjX (call) or ProjM_exc (call) -- nothing */
- }
-
- } break;
-
- case (iro_Proj): {
- const ir_node *in_in = get_Proj_pred (in);
- const opcode in_in_op = get_irn_opcode (in_in);
-
- switch (in_in_op) {
- case (iro_Call): {
- /* projP (projT (call)) */
- /* copy from projT to projP */
- pto_t *in_pto = compute_pto (in, env);
- set_pto (proj, in_pto);
- } break;
- case (iro_Start): {
- /* proj(proj(start)) - make sure the arguments are initialised */
- assert (get_pto (proj));
- } break;
- default: {
- DBGPRINT (1, (stdout, "%s:%i: proj(proj(%s)) not handled\n",
- __FILE__, __LINE__, get_op_name (get_irn_op (in_in))));
- assert (0);
- }
- }
- } break;
-
- case (iro_Cast): {
- /* make sure the input has been analysed */
- pto_t *cast_pto = compute_pto (in, env);
- set_pto (proj, cast_pto);
-
- } break;
-
- default: {
- fprintf (stderr, "%s: opcode %s of Node %ld not handled\n",
- __FUNCTION__,
- get_op_name (get_irn_op (in)),
- get_irn_node_nr (in));
-
- assert (0 && "something not handled");
- }
- }
-
- DBGPRINT (2, (stdout, "%s: Proj (%s)\n",
- __FUNCTION__,
- get_op_name (get_irn_op (in))));
-}
-
-static void pto_node_obj_load (ir_node *load, ir_node *ptr,
- entity *ent, void *env)
-{
- /*
- pto for obj load node
-
- so far:
- load.ptr analysed
- todo:
- look up
- */
- const char *ent_name = (char*) get_entity_name (ent);
- const char *own_name = (char*) get_type_name (get_entity_owner (ent));
-
- DBGPRINT (1, (stdout, "%s for (%s[%li])\n",
- __FUNCTION__,
- get_op_name (get_irn_op (ptr)),
- get_irn_node_nr (ptr)));
- if (! is_pointer_type (get_entity_type (ent))) {
- return;
- }
-
- DBGPRINT (2, (stdout, "%s: obj load from ent (0x%08x) \"%s.%s\"\n",
- __FUNCTION__,
- (int) ent,
- own_name,
- ent_name));
-
- pto_t *ptr_objs = compute_pto (ptr, env);
- qset_t *objs = ptr_objs->objs;
-
- pto_t *res = pto_new_empty (load);
-
- /* todo: iterate over 'objs' ... for each obj in objs, perform
- lookup using 'ent' ... assemble results in new qset ... return
- that as the new value */
-
- obj_desc_t *obj_desc = (obj_desc_t*) qset_start (objs);
-
- while (NULL != obj_desc) {
- qset_t *cnts = pto_lookup (obj_desc, ent);
-
- pto_add_all_names (res, cnts);
-
- obj_desc = (obj_desc_t*) qset_next (objs);
- }
-
- set_pto (load, res);
-}
-
-static void pto_node_arr_load (ir_node *load, ir_node *ptr,
- entity *ent, void *env)
-{
- /*
- pto for array load node
-
- so far:
- load.ptr analysed or can be computed on-the-fly
- todo:
- look up
- */
- const char *ent_name = (char*) get_entity_name (ent);
- const char *own_name = (char*) get_type_name (get_entity_owner (ent));
-
- /* load from array */
- DBGPRINT (1, (stdout, "%s for (%s[%li])\n",
- __FUNCTION__,
- get_op_name (get_irn_op (ptr)),
- get_irn_node_nr (ptr)));
-
- if (! is_pointer_type (get_entity_type (ent))) {
- return;
- }
-
- DBGPRINT (2, (stdout, "%s: array load from ent (0x%08x) \"%s.%s\"\n",
- __FUNCTION__,
- (int) ent,
- own_name,
- ent_name));
-
- pto_t *ptr_objs = compute_pto (ptr, env);
- qset_t *objs = ptr_objs->objs;
- pto_t *res = pto_new_empty (load);
-
- obj_desc_t *obj_desc = (obj_desc_t*) qset_start (objs);
-
- while (NULL != obj_desc) {
- qset_t *cnts = pto_lookup (obj_desc, NULL);
-
- pto_add_all_names (res, cnts);
-
- obj_desc = (obj_desc_t*) qset_next (objs);
- }
-
- set_pto (load, res);
-}
-
-static void pto_node_load (ir_node *load, void *env)
-{
- /*
- pto for load node
-
- so far:
- load.ptr analysed or can be computed on-the-fly
- todo:
- look up
- */
- ir_node *ptr = get_Load_ptr (load);
- const opcode op = get_irn_opcode (ptr);
- entity *ent = NULL;
-
- /* check the funny cases */
- if (iro_Proj == op) {
- /* then it's an unused Load(this) (or whatever) and we don't need to look at it */
- DBGPRINT (1, (stderr, "%s: %s[%li] ignored\n",
- __FUNCTION__,
- get_op_name (get_irn_op (ptr)),
- get_irn_node_nr (ptr)));
- return;
- } else if (iro_Cast == op) {
- /* then it's (whatever) and we don't know where to look at */
- DBGPRINT (1, (stderr, "%s: %s[%li] ignored\n",
- __FUNCTION__,
- get_op_name (get_irn_op (ptr)),
- get_irn_node_nr (ptr)));
- return;
- }
-
- ent = get_ptr_ent (ptr);
-
- assert (ent);
-
- /* array load or obj load? */
- if ((iro_Sel == op) && (3 == get_irn_arity (ptr))) {
- pto_node_arr_load (load, ptr, ent, env);
- } else {
- pto_node_obj_load (load, ptr, ent, env);
- }
-
-}
-
-static void pto_node_obj_store (ir_node *store,
- ir_node *ptr,
- entity *ent,
- ir_node *val,
- void *env)
-{
- /*
- pto for obj store node
-
- so far: ptr analysed or can be computed on-the-fly
- todo:
- update
- */
-
-
- const char *ent_name = (char*) get_entity_name (ent);
- const char *own_name = (char*) get_type_name (get_entity_owner (ent));
-
- DBGPRINT (1, (stdout, "%s: obj store from ent (0x%08x) \"%s.%s\"\n",
- __FUNCTION__,
- (int) ent, own_name, ent_name));
-
- pto_t *ptr_pto = compute_pto (ptr, env);
- pto_t *val_pto = compute_pto (val, env);
- qset_t *objs = ptr_pto->objs;
- qset_t *vals = val_pto->objs;
-
- obj_desc_t *obj_desc = (obj_desc_t*) qset_start (objs);
-
- while (NULL != obj_desc) {
- qset_t *cnts = pto_lookup (obj_desc, ent);
-
- qset_insert_all (cnts, vals);
-
- obj_desc = (obj_desc_t*) qset_next (objs);
- }
-}
-
-static void pto_node_arr_store (ir_node *store,
- ir_node *ptr,
- entity *ent,
- ir_node *val,
- void *env)
-{
- /*
- pto for array store node
-
- so far: ptr analysed or can be computed on-the-fly
- todo:
- update
- */
-
- const char *ent_name = (char*) get_entity_name (ent);
- const char *own_name = (char*) get_type_name (get_entity_owner (ent));
-
- DBGPRINT (1, (stdout, "%s: array store from ent (0x%08x) \"%s.%s\"\n",
- __FUNCTION__,
- (int) ent, own_name, ent_name));
-
- pto_t *ptr_pto = compute_pto (ptr, env);
- pto_t *val_pto = compute_pto (val, env);
- qset_t *objs = ptr_pto->objs;
- qset_t *vals = val_pto->objs;
-
- obj_desc_t *obj_desc = (obj_desc_t*) qset_start (objs);