X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Flower%2Flower_hl.c;h=88da2fd686c6991598e3007217a18a3bfa987ffb;hb=10927999e0da0ff6e4b816018291eea9cc265a31;hp=e54e777a9fe85be1fb3f24e395b3658bce7a7477;hpb=f8cc15664f571aa7ef89d6f6bc8d5bd2b8ca7d53;p=libfirm diff --git a/ir/lower/lower_hl.c b/ir/lower/lower_hl.c index e54e777a9..88da2fd68 100644 --- a/ir/lower/lower_hl.c +++ b/ir/lower/lower_hl.c @@ -212,9 +212,6 @@ static void lower_symconst(ir_node *symc) ir_graph *irg; switch (get_SymConst_kind(symc)) { - case symconst_type_tag: - assert(!"SymConst kind symconst_type_tag not implemented"); - break; case symconst_type_size: /* rewrite the SymConst node by a Const node */ irg = get_irn_irg(symc); @@ -271,195 +268,7 @@ static void lower_symconst(ir_node *symc) assert(!"unknown SymConst kind"); break; } -} /* lower_symconst */ - -/** - * Checks, whether a size is an integral size - * - * @param size the size on bits - */ -static int is_integral_size(int size) -{ - /* must be a 2^n */ - if (size & (size-1)) - return 0; - /* must be at least byte size */ - return size >= 8; -} /* is_integral_size */ - -/** - * lower bitfield load access. - * - * @param proj the Proj(result) node - * @param load the Load node - */ -static void lower_bitfields_loads(ir_node *proj, ir_node *load) -{ - ir_node *sel = get_Load_ptr(load); - ir_node *block, *res, *ptr; - ir_graph *irg; - ir_entity *ent; - ir_type *bf_type; - ir_mode *bf_mode, *mode; - int offset, bit_offset, bits, bf_bits, old_cse; - dbg_info *db; - - if (!is_Sel(sel)) - return; - - ent = get_Sel_entity(sel); - bf_type = get_entity_type(ent); - - /* must be a bitfield type */ - if (!is_Primitive_type(bf_type) || get_primitive_base_type(bf_type) == NULL) - return; - - /* We have a bitfield access, if either a bit offset is given, or - the size is not integral. */ - bf_mode = get_type_mode(bf_type); - if (! bf_mode) - return; - - mode = get_irn_mode(proj); - block = get_nodes_block(proj); - bf_bits = get_mode_size_bits(bf_mode); - bit_offset = get_entity_offset_bits_remainder(ent); - - if (bit_offset == 0 && is_integral_size(bf_bits) && bf_mode == get_Load_mode(load)) - return; - - bits = get_mode_size_bits(mode); - offset = get_entity_offset(ent); - - /* - * ok, here we are: now convert the Proj_mode_bf(Load) into And(Shr(Proj_mode(Load)) for unsigned - * and Shr(Shl(Proj_mode(load)) for signed - */ - - /* abandon bitfield sel */ - irg = get_irn_irg(sel); - ptr = get_Sel_ptr(sel); - db = get_irn_dbg_info(sel); - ptr = new_rd_Add(db, block, ptr, new_r_Const_long(irg, mode_Is, offset), get_irn_mode(ptr)); - - set_Load_ptr(load, ptr); - set_Load_mode(load, mode); - - - /* create new proj, switch off CSE or we may get the old one back */ - old_cse = get_opt_cse(); - set_opt_cse(0); - res = new_r_Proj(load, mode, pn_Load_res); - set_opt_cse(old_cse); - - if (mode_is_signed(mode)) { /* signed */ - int shift_count_up = bits - (bf_bits + bit_offset); - int shift_count_down = bits - bf_bits; - - if (shift_count_up) { - res = new_r_Shl(block, res, new_r_Const_long(irg, mode_Iu, shift_count_up), mode); - } - if (shift_count_down) { - res = new_r_Shrs(block, res, new_r_Const_long(irg, mode_Iu, shift_count_down), mode); - } - } else { /* unsigned */ - int shift_count_down = bit_offset; - unsigned mask = ((unsigned)-1) >> (bits - bf_bits); - - if (shift_count_down) { - res = new_r_Shr(block, res, new_r_Const_long(irg, mode_Iu, shift_count_down), mode); - } - if (bits != bf_bits) { - res = new_r_And(block, res, new_r_Const_long(irg, mode, mask), mode); - } - } - - exchange(proj, res); -} /* lower_bitfields_loads */ - -/** - * lower bitfield store access. - * - * @todo: It adds a load which may produce an exception! - */ -static void lower_bitfields_stores(ir_node *store) -{ - ir_node *sel = get_Store_ptr(store); - ir_node *ptr, *value; - ir_entity *ent; - ir_type *bf_type; - ir_mode *bf_mode, *mode; - ir_node *mem, *irn, *block; - ir_graph *irg; - unsigned mask, neg_mask; - int bf_bits, bits_mask, offset, bit_offset; - dbg_info *db; - - /* check bitfield access */ - if (!is_Sel(sel)) - return; - - ent = get_Sel_entity(sel); - bf_type = get_entity_type(ent); - - /* must be a bitfield type */ - if (!is_Primitive_type(bf_type) || get_primitive_base_type(bf_type) == NULL) - return; - - /* We have a bitfield access, if either a bit offset is given, or - the size is not integral. */ - bf_mode = get_type_mode(bf_type); - if (! bf_mode) - return; - - value = get_Store_value(store); - mode = get_irn_mode(value); - block = get_nodes_block(store); - - bf_bits = get_mode_size_bits(bf_mode); - bit_offset = get_entity_offset_bits_remainder(ent); - - if (bit_offset == 0 && is_integral_size(bf_bits) && bf_mode == get_irn_mode(value)) - return; - - /* - * ok, here we are: now convert the Store(Sel(), value) into Or(And(Load(Sel),c), And(Value,c)) - */ - mem = get_Store_mem(store); - offset = get_entity_offset(ent); - - bits_mask = get_mode_size_bits(mode) - bf_bits; - mask = ((unsigned)-1) >> bits_mask; - mask <<= bit_offset; - neg_mask = ~mask; - - /* abandon bitfield sel */ - irg = get_irn_irg(sel); - ptr = get_Sel_ptr(sel); - db = get_irn_dbg_info(sel); - ptr = new_rd_Add(db, block, ptr, new_r_Const_long(irg, mode_Is, offset), get_irn_mode(ptr)); - - if (neg_mask) { - /* there are some bits, normal case */ - irn = new_r_Load(block, mem, ptr, mode, cons_none); - mem = new_r_Proj(irn, mode_M, pn_Load_M); - irn = new_r_Proj(irn, mode, pn_Load_res); - - irn = new_r_And(block, irn, new_r_Const_long(irg, mode, neg_mask), mode); - - if (bit_offset > 0) { - value = new_r_Shl(block, value, new_r_Const_long(irg, mode_Iu, bit_offset), mode); - } - - value = new_r_And(block, value, new_r_Const_long(irg, mode, mask), mode); - - value = new_r_Or(block, value, irn, mode); - } - - set_Store_mem(store, mem); - set_Store_value(store, value); - set_Store_ptr(store, ptr); -} /* lower_bitfields_stores */ +} /** * lowers IR-nodes, called from walker @@ -482,31 +291,6 @@ static void lower_irnode(ir_node *irn, void *env) } } -/** - * Walker: lowers IR-nodes for bitfield access - */ -static void lower_bf_access(ir_node *irn, void *env) -{ - (void) env; - switch (get_irn_opcode(irn)) { - case iro_Proj: - { - long proj = get_Proj_proj(irn); - ir_node *pred = get_Proj_pred(irn); - - if (proj == pn_Load_res && is_Load(pred)) - lower_bitfields_loads(irn, pred); - break; - } - case iro_Store: - lower_bitfields_stores(irn); - break; - - default: - break; - } -} - /* * Replaces SymConsts by a real constant if possible. * Replace Sel nodes by address computation. Also resolves array access. @@ -514,12 +298,6 @@ static void lower_bf_access(ir_node *irn, void *env) */ void lower_highlevel_graph(ir_graph *irg) { - if (is_irg_state(irg, IR_GRAPH_STATE_IMPLICIT_BITFIELD_MASKING)) { - /* First step: lower bitfield access: must be run as long as Sels still - * exists. */ - irg_walk_graph(irg, NULL, lower_bf_access, NULL); - } - /* Finally: lower SymConst-Size and Sel nodes, Casts, unaligned Load/Stores. */ irg_walk_graph(irg, NULL, lower_irnode, NULL); } @@ -537,7 +315,7 @@ static int lower_highlevel_graph_wrapper(ir_graph *irg, void *context) lower_highlevel_graph(irg); return 0; -} /* lower_highlevel_graph_wrapper */ +} ir_graph_pass_t *lower_highlevel_graph_pass(const char *name) { @@ -545,7 +323,7 @@ ir_graph_pass_t *lower_highlevel_graph_pass(const char *name) return def_graph_pass_constructor( &pass->pass, name ? name : "lower_hl", lower_highlevel_graph_wrapper); -} /* lower_highlevel_graph_pass */ +} /* * does the same as lower_highlevel() for all nodes on the const code irg @@ -553,7 +331,7 @@ ir_graph_pass_t *lower_highlevel_graph_pass(const char *name) void lower_const_code(void) { walk_const_code(NULL, lower_irnode, NULL); -} /* lower_const_code */ +} ir_prog_pass_t *lower_const_code_pass(const char *name) { @@ -575,4 +353,4 @@ void lower_highlevel() lower_highlevel_graph(irg); } lower_const_code(); -} /* lower_highlevel */ +}