/** * Adds a control dependence from node to dep_on. */ static void add_cdep(ir_node *node, ir_node *dep_on) { ir_cdep *dep = find_cdep(node); assert(is_Block(dep_on)); if (dep == NULL) { ir_cdep *newdep = OALLOC(&cdep_data->obst, ir_cdep); newdep->node = dep_on; newdep->next = NULL; pmap_insert(cdep_data->cdep_map, node, newdep); } else { ir_cdep *newdep; for (;;) { if (get_cdep_node(dep) == dep_on) return; if (dep->next == NULL) break; dep = dep->next; } newdep = OALLOC(&cdep_data->obst, ir_cdep); newdep->node = dep_on; newdep->next = NULL; dep->next = newdep; } }
/** * 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); } } }
ir_initializer_t *create_initializer_const(ir_node *value) { struct obstack *obst = get_irg_obstack(get_const_code_irg()); ir_initializer_t *initializer = (ir_initializer_t*)OALLOC(obst, ir_initializer_const_t); initializer->kind = IR_INITIALIZER_CONST; initializer->consti.value = value; return initializer; }
ir_initializer_t *create_initializer_tarval(ir_tarval *tv) { struct obstack *obst = get_irg_obstack(get_const_code_irg()); ir_initializer_t *initializer = (ir_initializer_t*)OALLOC(obst, ir_initializer_tarval_t); initializer->kind = IR_INITIALIZER_TARVAL; initializer->tarval.value = tv; return initializer; }
/** * emit the ROOT instruction */ static instruction *emit_ROOT(mul_env *env, ir_node *root_op) { instruction *res = OALLOC(&env->obst, instruction); res->kind = ROOT; res->in[0] = NULL; res->in[1] = NULL; res->shift_count = 0; res->irn = root_op; res->costs = 0; return res; }
/** * emit a SUB instruction */ static instruction *emit_SUB(mul_env *env, instruction *a, instruction *b) { instruction *res = OALLOC(&env->obst, instruction); res->kind = SUB; res->in[0] = a; res->in[1] = b; res->shift_count = 0; res->irn = NULL; res->costs = -1; return res; }
/** * emit a LEA (or an Add) instruction */ static instruction *emit_LEA(mul_env *env, instruction *a, instruction *b, unsigned shift) { instruction *res = OALLOC(&env->obst, instruction); res->kind = shift > 0 ? LEA : ADD; res->in[0] = a; res->in[1] = b; res->shift_count = shift; res->irn = NULL; res->costs = -1; return res; }
/** * Allocate a new DAG entry. */ static dag_entry_t *new_dag_entry(dag_env_t *dag_env, ir_node *node) { dag_entry_t *entry = OALLOC(&dag_env->obst, dag_entry_t); entry->num_nodes = 1; entry->num_roots = 1; entry->num_inner_nodes = 0; entry->root = node; entry->is_dead = 0; entry->is_tree = 1; entry->is_ext_ref = 0; entry->next = dag_env->list_of_dags; entry->link = NULL; ++dag_env->num_of_dags; dag_env->list_of_dags = entry; set_irn_dag_entry(node, entry); return entry; }
/** * 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); } }
/** * emit a SHIFT (or an Add or a Zero) instruction */ static instruction *emit_SHIFT(mul_env *env, instruction *a, unsigned shift) { instruction *res = OALLOC(&env->obst, instruction); if (shift == env->bits) { /* a 2^bits with bits resolution is a zero */ res->kind = ZERO; res->in[0] = NULL; res->in[1] = NULL; res->shift_count = 0; } else if (shift != 1) { res->kind = SHIFT; res->in[0] = a; res->in[1] = NULL; res->shift_count = shift; } else { res->kind = ADD; res->in[0] = a; res->in[1] = a; res->shift_count = 0; } res->irn = NULL; res->costs = -1; return res; }