lb = get_array_lower_bound(arr_ty, dim);
ub = get_array_upper_bound(arr_ty, dim);
- assert(irg == current_ir_graph);
if (! is_Unknown(lb))
lb = new_rd_Conv(dbg, bl, copy_const_value(get_irn_dbg_info(sel), lb, bl), mode_Int);
else
}
}
-/**
- * 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;
-}
-
-/**
- * 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 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);
-}
-
/**
* lowers IR-nodes, called from walker
*/
case iro_SymConst:
lower_symconst(irn);
break;
- case iro_Cast:
- exchange(irn, get_Cast_op(irn));
- break;
- default:
- break;
- }
-}
-
-/**
- * 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;
}
*/
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. */
+ /* Finally: lower SymConst-Size and Sel nodes, unaligned Load/Stores. */
irg_walk_graph(irg, NULL, lower_irnode, NULL);
}