ir_node *get_atomic_ent_value(const ir_entity *entity) { ir_initializer_t *initializer = get_entity_initializer(entity); assert(is_atomic_entity(entity)); if (initializer == NULL) { ir_type *type = get_entity_type(entity); return new_r_Unknown(get_const_code_irg(), get_type_mode(type)); } switch (get_initializer_kind(initializer)) { case IR_INITIALIZER_NULL: { ir_type *type = get_entity_type(entity); ir_mode *mode = get_type_mode(type); return new_r_Const(get_const_code_irg(), get_mode_null(mode)); } case IR_INITIALIZER_TARVAL: { ir_tarval *tv = get_initializer_tarval_value(initializer); return new_r_Const(get_const_code_irg(), tv); } case IR_INITIALIZER_CONST: return get_initializer_const_value(initializer); case IR_INITIALIZER_COMPOUND: panic("compound initializer in atomic entity not allowed (%+F)", entity); } panic("invalid initializer kind (%+F)", entity); }
/** * This function returns the last definition of a value. In case * this value was last defined in a previous block, Phi nodes are * inserted. If the part of the firm graph containing the definition * is not yet constructed, a dummy Phi node is returned. * * @param block the current block * @param pos the value number of the value searched * @param mode the mode of this value (needed for Phi construction) */ static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode) { ir_node *res = block->attr.block.graph_arr[pos]; if (res != NULL) return res; /* in a matured block we can immediately determine the phi arguments */ if (get_Block_matured(block)) { ir_graph *const irg = get_irn_irg(block); int const arity = get_irn_arity(block); /* no predecessors: use unknown value */ if (arity == 0) { if (block == get_irg_start_block(irg)) { if (default_initialize_local_variable != NULL) { ir_node *rem = get_r_cur_block(irg); set_r_cur_block(irg, block); res = default_initialize_local_variable(irg, mode, pos - 1); set_r_cur_block(irg, rem); } else { res = new_r_Unknown(irg, mode); } } else { goto bad; /* unreachable block, use Bad */ } /* one predecessor just use its value */ } else if (arity == 1) { ir_node *cfgpred = get_Block_cfgpred(block, 0); if (is_Bad(cfgpred)) { bad: res = new_r_Bad(irg, mode); } else { ir_node *cfgpred_block = get_nodes_block(cfgpred); res = get_r_value_internal(cfgpred_block, pos, mode); } } else { /* multiple predecessors construct Phi */ res = new_rd_Phi0(NULL, block, mode, pos); /* enter phi0 into our variable value table to break cycles * arising from set_phi_arguments */ block->attr.block.graph_arr[pos] = res; res = set_phi_arguments(res, pos); } } else { /* in case of immature block we have to keep a Phi0 */ res = new_rd_Phi0(NULL, block, mode, pos); /* enqueue phi so we can set arguments once the block matures */ res->attr.phi.next = block->attr.block.phis; block->attr.block.phis = res; } block->attr.block.graph_arr[pos] = res; return res; }
ir_node *copy_const_value(dbg_info *dbg, ir_node *n, ir_node *block) { ir_graph *irg = get_irn_irg(block); /* @@@ GL I think we should implement this using the routines from irgopt * for dead node elimination/inlineing. */ ir_mode *m = get_irn_mode(n); ir_node *nn; switch (get_irn_opcode(n)) { case iro_Const: nn = new_rd_Const(dbg, irg, get_Const_tarval(n)); break; case iro_SymConst: nn = new_rd_SymConst(dbg, irg, get_irn_mode(n), get_SymConst_symbol(n), get_SymConst_kind(n)); break; case iro_Add: nn = new_rd_Add(dbg, block, copy_const_value(dbg, get_Add_left(n), block), copy_const_value(dbg, get_Add_right(n), block), m); break; case iro_Sub: nn = new_rd_Sub(dbg, block, copy_const_value(dbg, get_Sub_left(n), block), copy_const_value(dbg, get_Sub_right(n), block), m); break; case iro_Mul: nn = new_rd_Mul(dbg, block, copy_const_value(dbg, get_Mul_left(n), block), copy_const_value(dbg, get_Mul_right(n), block), m); break; case iro_And: nn = new_rd_And(dbg, block, copy_const_value(dbg, get_And_left(n), block), copy_const_value(dbg, get_And_right(n), block), m); break; case iro_Or: nn = new_rd_Or(dbg, block, copy_const_value(dbg, get_Or_left(n), block), copy_const_value(dbg, get_Or_right(n), block), m); break; case iro_Eor: nn = new_rd_Eor(dbg, block, copy_const_value(dbg, get_Eor_left(n), block), copy_const_value(dbg, get_Eor_right(n), block), m); break; case iro_Conv: nn = new_rd_Conv(dbg, block, copy_const_value(dbg, get_Conv_op(n), block), m); break; case iro_Minus: nn = new_rd_Minus(dbg, block, copy_const_value(dbg, get_Minus_op(n), block), m); break; case iro_Not: nn = new_rd_Not(dbg, block, copy_const_value(dbg, get_Not_op(n), block), m); break; case iro_Unknown: nn = new_r_Unknown(irg, m); break; default: panic("opcode invalid or not implemented %+F", n); } return nn; }