/** * Pre-Walker called by compute_callgraph(), analyses all Call nodes. */ static void ana_Call(ir_node *n, void *env) { (void)env; if (!is_Call(n)) return; ir_graph *irg = get_irn_irg(n); for (size_t i = 0, n_callees = cg_get_call_n_callees(n); i < n_callees; ++i) { ir_entity *callee_e = cg_get_call_callee(n, i); ir_graph *callee = get_entity_linktime_irg(callee_e); if (callee) { cg_callee_entry buf; buf.irg = callee; pset_insert((pset *)callee->callers, irg, hash_ptr(irg)); cg_callee_entry *found = (cg_callee_entry*) pset_find((pset *)irg->callees, &buf, hash_ptr(callee)); if (found) { /* add Call node to list, compute new nesting. */ ir_node **arr = found->call_list; ARR_APP1(ir_node *, arr, n); found->call_list = arr; } else { /* New node, add Call node and init nesting. */ found = OALLOC(get_irg_obstack(irg), cg_callee_entry); found->irg = callee; found->call_list = NEW_ARR_F(ir_node *, 1); found->call_list[0] = n; found->max_depth = 0; pset_insert((pset *)irg->callees, found, hash_ptr(callee)); } unsigned depth = get_loop_depth(get_irn_loop(get_nodes_block(n))); found->max_depth = MAX(found->max_depth, depth); } } }
/** * Process a call node. * * @param call A ir_node to be checked. * @param callee The entity of the callee * @param hmap The quadruple-set containing the calls with constant parameters */ static void process_call(ir_node *call, ir_entity *callee, q_set *hmap) { /* TODO * Beware: We cannot clone variadic parameters as well as the * last non-variadic one, which might be needed for the va_start() * magic. */ /* In this for loop we collect the calls, that have a constant parameter. */ size_t const n_params = get_Call_n_params(call); for (size_t i = n_params; i-- > 0;) { ir_node *const call_param = get_Call_param(call, i); if (is_Const(call_param)) { /* we have found a Call to collect and we save the information * we need.*/ if (!hmap->map) hmap->map = new_pset(entry_cmp, 8); entry_t *const key = OALLOC(&hmap->obst, entry_t); key->q.ent = callee; key->q.pos = i; key->q.tv = get_Const_tarval(call_param); key->q.calls = NULL; key->weight = 0.0F; key->next = NULL; /* Insert entry or get existing equivalent entry */ entry_t *const entry = (entry_t*)pset_insert(hmap->map, key, hash_entry(key)); /* Free memory if entry already is in set */ if (entry != key) obstack_free(&hmap->obst, key); /* add the call to the list */ if (!entry->q.calls) { entry->q.calls = NEW_ARR_F(ir_node*, 1); entry->q.calls[0] = call; } else { ARR_APP1(ir_node *, entry->q.calls, call); } }
__pset_pointer pset_add( pset_h pset, const __pset_pointer ptr ) { return (pset->count < pset->max ) ? (pset->ptrs[ pset->count++ ] = ptr) : pset_insert( pset, ptr) ; }