ir_node *new_rd_ASM(dbg_info *db, ir_node *block, ir_node *mem, int arity, ir_node *in[], ir_asm_constraint *inputs, size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber, ident *clobber[], ident *text) { ir_graph *const irg = get_irn_irg(block); int const r_arity = arity + 1; ir_node **const r_in = ALLOCAN(ir_node*, r_arity); r_in[0] = mem; MEMCPY(&r_in[1], in, arity); ir_node *res = new_ir_node(db, irg, block, op_ASM, mode_T, r_arity, r_in); struct obstack *const obst = get_irg_obstack(irg); asm_attr *const a = &res->attr.assem; a->exc.pinned = true; a->input_constraints = NEW_ARR_D(ir_asm_constraint, obst, arity); a->output_constraints = NEW_ARR_D(ir_asm_constraint, obst, n_outs); a->clobbers = NEW_ARR_D(ident*, obst, n_clobber); a->text = text; MEMCPY(a->input_constraints, inputs, arity); MEMCPY(a->output_constraints, outputs, n_outs); MEMCPY(a->clobbers, clobber, n_clobber); verify_new_node(res); res = optimize_node(res); return res; }
/** Creates a Phi node with 0 predecessors. */ static inline ir_node *new_rd_Phi0(dbg_info *dbgi, ir_node *block, ir_mode *mode, int pos) { ir_graph *irg = get_irn_irg(block); ir_node *res = new_ir_node(dbgi, irg, block, op_Phi, mode, 0, NULL); res->attr.phi.u.pos = pos; verify_new_node(res); return res; }
ir_node *be_new_Phi(ir_node *block, int n_ins, ir_node **ins, arch_register_req_t const *req) { ir_graph *irg = get_irn_irg(block); ir_node *phi = new_ir_node(NULL, irg, block, op_Phi, req->cls->mode, n_ins, ins); phi->attr.phi.u.backedge = new_backedge_arr(get_irg_obstack(irg), n_ins); struct obstack *obst = be_get_be_obst(irg); backend_info_t *info = be_get_info(phi); info->out_infos = NEW_ARR_DZ(reg_out_info_t, obst, 1); info->in_reqs = be_allocate_in_reqs(irg, n_ins); info->out_infos[0].req = req; for (int i = 0; i < n_ins; ++i) { info->in_reqs[i] = req; } verify_new_node(phi); return optimize_node(phi); }
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; }
/** * Computes the predecessors for the real phi node, and then * allocates and returns this node. The routine called to allocate the * node might optimize it away and return a real value. * This function must be called with an in-array of proper size. */ static ir_node *set_phi_arguments(ir_node *phi, int pos) { ir_node *block = get_nodes_block(phi); ir_graph *irg = get_irn_irg(block); int arity = get_irn_arity(block); ir_node **in = ALLOCAN(ir_node*, arity); ir_mode *mode = get_irn_mode(phi); /* This loop goes to all predecessor blocks of the block the Phi node * is in and there finds the operands of the Phi node by calling * get_r_value_internal. */ for (int i = 0; i < arity; ++i) { ir_node *cfgpred = get_Block_cfgpred_block(block, i); ir_node *value; if (cfgpred == NULL) { value = new_r_Bad(irg, mode); } else { value = get_r_value_internal(cfgpred, pos, mode); } in[i] = value; } phi->attr.phi.u.backedge = new_backedge_arr(get_irg_obstack(irg), arity); set_irn_in(phi, arity, in); verify_new_node(phi); try_remove_unnecessary_phi(phi); /* To solve the problem of (potentially) endless loops being observable * behaviour we add a keep-alive edge too all PhiM nodes. */ if (mode == mode_M && !is_Id(phi)) { phi->attr.phi.loop = true; keep_alive(phi); } return phi; }