From 1e7ccff032250868e233a0e9c843ba0be9c763fa Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Thu, 18 Sep 2008 22:16:47 +0000 Subject: [PATCH] - can handle some hidden reinterpret casts when doing const load replacement [r22099] --- include/libfirm/irmode.h | 7 +++++++ ir/ir/irmode.c | 19 +++++++++++++++++++ ir/opt/ldstopt.c | 27 +++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/libfirm/irmode.h b/include/libfirm/irmode.h index 46e1e10be..d1b4e88c6 100644 --- a/include/libfirm/irmode.h +++ b/include/libfirm/irmode.h @@ -468,4 +468,11 @@ ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode); */ void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode); +/** + * Returns non-zero if the cast from mode src to mode dst is a + * reinterpret cast (ie. only the bit pattern is reinterpreted, + * no conversion is done) + */ +int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst); + #endif diff --git a/ir/ir/irmode.c b/ir/ir/irmode.c index b59c13cd3..55108bbea 100644 --- a/ir/ir/irmode.c +++ b/ir/ir/irmode.c @@ -907,6 +907,25 @@ int mode_wrap_around(const ir_mode *mode) { return mode_is_int(mode); } +/* + * Returns non-zero if the cast from mode src to mode dst is a + * reinterpret cast (ie. only the bit pattern is reinterpreted, + * no conversion is done) + */ +int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst) { + ir_mode_arithmetic ma; + + if (src == dst) + return 1; + if (get_mode_size_bits(src) != get_mode_size_bits(dst)) + return 0; + ma = get_mode_arithmetic(src); + if (ma != get_mode_arithmetic(dst)) + return 0; + + return ma == irma_twos_complement || ma == irma_ones_complement; +} + void finish_mode(void) { obstack_free(&modes, 0); DEL_ARR_F(mode_list); diff --git a/ir/opt/ldstopt.c b/ir/opt/ldstopt.c index f5e2cb428..841f3b9a1 100644 --- a/ir/opt/ldstopt.c +++ b/ir/opt/ldstopt.c @@ -1052,7 +1052,7 @@ static unsigned optimize_load(ir_node *load) /* check if we can determine the entity that will be loaded */ ent = find_constant_entity(ptr); - if (ent) { + if (ent != NULL) { if ((allocation_static == get_entity_allocation(ent)) && (visibility_external_allocated != get_entity_visibility(ent))) { /* a static allocation that is not external: there should be NO exception @@ -1114,13 +1114,36 @@ static unsigned optimize_load(ir_node *load) free_compound_graph_path(path); } } + if (c != NULL) { + /* check, if the mode matches OR can be easily converted info */ + ir_mode *c_mode = get_irn_mode(c); + ir_mode *l_mode = get_Load_mode(load); + + if (c_mode != l_mode) { + if (is_reinterpret_cast(c_mode, l_mode)) { + /* we can safely cast */ + dbg_info *dbg = get_irn_dbg_info(load); + ir_node *block = get_nodes_block(load); + + /* copy the value from the const code irg and cast it */ + c = copy_const_value(dbg, c); + c = new_rd_Conv(dbg, current_ir_graph, block, c, l_mode); + } else { + /* must be some operation */ + c = NULL; + } + } else { + /* copy the value from the const code irg */ + c = copy_const_value(get_irn_dbg_info(load), c); + } + } if (c != NULL) { if (info->projs[pn_Load_M]) { exchange(info->projs[pn_Load_M], mem); res |= DF_CHANGED; } if (info->projs[pn_Load_res]) { - exchange(info->projs[pn_Load_res], copy_const_value(get_irn_dbg_info(load), c)); + exchange(info->projs[pn_Load_res], c); res |= DF_CHANGED; } kill_node(load); -- 2.20.1