/** * lower Alloca nodes to allocate "bytes" instead of a certain type */ static void lower_alloca_free(ir_node *node, void *data) { (void) data; if (is_Alloc(node)) { } else if (is_Proj(node)) { ir_node *proj_pred = get_Proj_pred(node); if (is_Alloc(proj_pred)) { transform_Proj_Alloc(node); } return; } else { return; } if (!ir_nodeset_insert(&transformed, node)) return; if (stack_alignment <= 1) return; ir_node *const size = get_Alloc_size(node); ir_node *const mem = get_Alloc_mem(node); ir_node *const block = get_nodes_block(node); dbg_info *const dbgi = get_irn_dbg_info(node); ir_node *const new_size = adjust_alloc_size(dbgi, size, block); ir_node *const new_node = new_rd_Alloc(dbgi, block, mem, new_size, 1); ir_nodeset_insert(&transformed, new_node); if (new_node != node) exchange(node, new_node); }
void dmemory_lower_Alloc(ir_node *node) { assert(is_Alloc(node)); if (get_Alloc_where(node) != heap_alloc) return; ir_graph *irg = get_irn_irg(node); ir_type *type = get_Alloc_type(node); ir_node *count = get_Alloc_count(node); ir_node *res = NULL; ir_node *cur_mem = get_Alloc_mem(node); ir_node *block = get_nodes_block(node); if (is_Class_type(type)) { res = (*dmemory_model.alloc_object)(type, irg, block, &cur_mem); ddispatch_prepare_new_instance(type, res, irg, block, &cur_mem); } else if (is_Array_type(type)) { ir_type *eltype = get_array_element_type(type); res = (*dmemory_model.alloc_array)(eltype, count, irg, block, &cur_mem); } else { assert (0); } turn_into_tuple(node, pn_Alloc_max); set_irn_n(node, pn_Alloc_M, cur_mem); set_irn_n(node, pn_Alloc_res, res); }
static void check_omit_fp(ir_node *node, void *env) { /* omit-fp is not possible if: * - we have allocations on the stack */ if (is_Alloc(node) || is_Free(node)) { bool *can_omit_fp = (bool*) env; *can_omit_fp = false; } }
static void check_omit_fp(ir_node *node, void *env) { /* omit-fp is not possible if: * - we have allocations on the stack * - we have calls (with the exception of tail-calls once we support them) */ if (is_Alloc(node) || is_Free(node) || is_Call(node)) { bool *can_omit_fp = (bool*) env; *can_omit_fp = false; } }
/* * Check, if the value of a node cannot represent a NULL pointer. * * - Sels are skipped * - A SymConst(entity) is NEVER a NULL pointer * - Confirms are evaluated */ int value_not_null(const ir_node *n, const ir_node **confirm) { ir_tarval *tv; *confirm = NULL; tv = value_of(n); if (tarval_is_constant(tv) && ! tarval_is_null(tv)) return 1; assert(mode_is_reference(get_irn_mode(n))); /* skip all Sel nodes */ while (is_Sel(n)) { n = get_Sel_ptr(n); } while (1) { if (is_Proj(n)) { n = get_Proj_pred(n); continue; } break; } if (is_SymConst_addr_ent(n)) { /* global references are never NULL */ return 1; } else if (n == get_irg_frame(get_irn_irg(n))) { /* local references are never NULL */ return 1; } else if (is_Alloc(n)) { /* alloc never returns NULL (it throws an exception instead) */ return 1; } else { /* check for more Confirms */ for (; is_Confirm(n); n = get_Confirm_value(n)) { if (get_Confirm_relation(n) == ir_relation_less_greater) { ir_node *bound = get_Confirm_bound(n); ir_tarval *tv = value_of(bound); if (tarval_is_null(tv)) { *confirm = n; return 1; } } } } return 0; }
/** * lower Alloca nodes to allocate "bytes" instead of a certain type */ static void lower_node(ir_node *node, void *data) { bool *changed = (bool*)data; if (!is_Alloc(node)) return; ir_node *const size = get_Alloc_size(node); ir_node *const mem = get_Alloc_mem(node); ir_node *const block = get_nodes_block(node); dbg_info *const dbgi = get_irn_dbg_info(node); ir_node *const new_size = adjust_alloc_size(dbgi, size, block); ir_node *const new_node = new_rd_Alloc(dbgi, block, mem, new_size, 1); if (new_node != node) exchange(node, new_node); *changed = true; }
static void infer_typeinfo_walker(ir_node *irn, void *env) { bool *changed = (bool*) env; // A node's type needs only to be calculated once. if (get_irn_typeinfo_type(irn) != initial_type) return; if (is_Alloc(irn)) { // this one is easy, we know the exact dynamic type. ir_type *type = get_Alloc_type(irn); if (! is_Class_type(type)) return; set_irn_typeinfo_type(irn, type); *changed = true; } else if (is_Sel(irn) || is_SymConst_addr_ent(irn)) { // the type we determine here is the one of the entity we select or reference. // the transform_Sel method below will use the type incoming on the Sel_ptr input. ir_type *type = get_Sel_or_SymConst_type(irn); if (! type) return; ir_type *one_alive = get_alive_subclass(type); if (! one_alive) return; set_irn_typeinfo_type(irn, one_alive); *changed = true; } else if (is_Call(irn)) { // the dynamic type of the call result is the return type of the called entity. ir_node *call_pred = get_Call_ptr(irn); ir_type *pred_type = get_irn_typeinfo_type(call_pred); if (pred_type == initial_type) return; set_irn_typeinfo_type(irn, pred_type); *changed = true; } else if (is_Load(irn)) { // the dynamic type of the Load result is the type of the loaded entity. ir_node *load_pred = get_Load_ptr(irn); if (! is_Sel(load_pred) && !is_SymConst_addr_ent(load_pred)) return; ir_type *pred_type = get_irn_typeinfo_type(load_pred); if (pred_type == initial_type) return; set_irn_typeinfo_type(irn, pred_type); *changed = true; } else if (is_Proj(irn)) { // Types have to be propagated through Proj nodes (XXX: and also through Cast and Confirm ir_mode *pmode = get_irn_mode(irn); if (pmode != mode_P) return; ir_node *proj_pred = get_Proj_pred(irn); if (is_Proj(proj_pred) && get_irn_mode(proj_pred) == mode_T && get_Proj_proj(proj_pred) == pn_Call_T_result && is_Call(get_Proj_pred(proj_pred))) proj_pred = get_Proj_pred(proj_pred); // skip the result tuple ir_type *pred_type = get_irn_typeinfo_type(proj_pred); if (pred_type == initial_type) return; set_irn_typeinfo_type(irn, pred_type); *changed = true; } else if (is_Phi(irn)) { // Phi nodes are a special case because the incoming type information must be merged // A Phi node's type is unknown until all inputs are known to be the same dynamic type. ir_mode *pmode = get_irn_mode(irn); if (pmode != mode_P) return; int phi_preds = get_Phi_n_preds(irn); ir_type *last = NULL; for (int p = 0; p < phi_preds; p++) { ir_node *pred = get_Phi_pred(irn, p); ir_type *pred_type = get_irn_typeinfo_type(pred); if (pred_type == initial_type) return; if (p && last != pred_type) return; last = pred_type; } set_irn_typeinfo_type(irn, last); } }