ir_node *be_complete_Phi(ir_node *const phi, unsigned const n_ins, ir_node **const ins) { assert(is_Phi(phi) && get_Phi_n_preds(phi) == 0); ir_graph *const irg = get_irn_irg(phi); phi->attr.phi.u.backedge = new_backedge_arr(get_irg_obstack(irg), n_ins); set_irn_in(phi, n_ins, ins); arch_register_req_t const **const in_reqs = be_allocate_in_reqs(irg, n_ins); arch_register_req_t const *const req = arch_get_irn_register_req(phi); for (unsigned i = 0; i < n_ins; ++i) { in_reqs[i] = req; } backend_info_t *const info = be_get_info(phi); info->in_reqs = in_reqs; verify_new_node(phi); return phi; }
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); } }