X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Flower%2Flower_mode_b.c;h=9d42f7ca8e605f8bc8475a489e6a9beed752f1df;hb=30d3b0bd1a6cfec7d24c23fee7e63108664927d0;hp=078fa8938a2072a12e4f793d7f9fd5f724945103;hpb=eb0672129c35f41c7d1e9efdeb4835585947d33b;p=libfirm diff --git a/ir/lower/lower_mode_b.c b/ir/lower/lower_mode_b.c index 078fa8938..9d42f7ca8 100644 --- a/ir/lower/lower_mode_b.c +++ b/ir/lower/lower_mode_b.c @@ -35,10 +35,10 @@ #include "tv.h" #include "error.h" #include "lowering.h" -#include "benode_t.h" static ir_mode *lowered_mode = NULL; static int lower_direct_cmp = 0; +static ir_type *lowered_type = NULL; static ir_node *create_not(dbg_info *dbgi, ir_node *node) { @@ -50,6 +50,47 @@ static ir_node *create_not(dbg_info *dbgi, ir_node *node) return new_rd_Eor(dbgi, irg, block, node, one, lowered_mode); } +static ir_node *create_convb(ir_node *node) +{ + ir_graph *irg = current_ir_graph; + ir_node *block = get_nodes_block(node); + ir_node *conv = new_rd_Conv(NULL, irg, block, node, mode_b); + + return conv; +} + +static ir_type *create_lowered_type(void) +{ + if(lowered_type == NULL) { + lowered_type = new_type_primitive(new_id_from_str("__lowered_mode_b"), + lowered_mode); + } + return lowered_type; +} + +static void adjust_method_type(ir_type *method_type) +{ + int i; + int n_params; + int n_res; + + n_params = get_method_n_params(method_type); + for(i = 0; i < n_params; ++i) { + ir_type *param = get_method_param_type(method_type, i); + if(get_type_mode(param) == mode_b) { + set_method_param_type(method_type, i, create_lowered_type()); + } + } + + n_res = get_method_n_ress(method_type); + for(i = 0; i < n_res; ++i) { + ir_type *res_type = get_method_res_type(method_type, i); + if(get_type_mode(res_type) == mode_b) { + set_method_res_type(method_type, i, create_lowered_type()); + } + } +} + static ir_node *lower_node(ir_node *node) { ir_graph *irg = current_ir_graph; @@ -141,11 +182,12 @@ static ir_node *lower_node(ir_node *node) ir_node *one = new_d_Const(dbgi, lowered_mode, tv_one); tarval *tv_zero = get_tarval_null(lowered_mode); ir_node *zero = new_d_Const(dbgi, lowered_mode, tv_zero); - ir_mode *mode = get_irn_mode(node); + ir_node *pred = get_Conv_op(node); + ir_mode *mode = get_irn_mode(pred); tarval *tv_zeroc = get_tarval_null(mode); ir_node *zero_cmp = new_d_Const(dbgi, mode, tv_zeroc); - ir_node *cmp = new_rd_Cmp(dbgi, irg, block, node, zero_cmp); + ir_node *cmp = new_rd_Cmp(dbgi, irg, block, pred, zero_cmp); ir_node *proj = new_rd_Proj(dbgi, irg, block, cmp, mode_b, pn_Cmp_Lg); ir_node *vals[2] = { one, zero }; @@ -156,17 +198,17 @@ static ir_node *lower_node(ir_node *node) return psi; } if(op == op_Proj) { - ir_node *pred = get_Proj_pred(node); + ir_node *pred = get_Proj_pred(node); - assert(!is_Load(pred)); if(is_Cmp(pred)) { - ir_mode *mode = get_irn_mode(pred); ir_node *left = get_Cmp_left(pred); ir_node *right = get_Cmp_right(pred); + ir_mode *mode = get_irn_mode(left); - if( (mode_is_int(mode) || mode_is_reference(mode)) && - (get_mode_size_bits(mode) < get_mode_size_bits(lowered_mode) - || classify_Const(right) == CNST_NULL)) { + if ((mode_is_int(mode) || mode_is_reference(mode)) && ( + get_mode_size_bits(mode) < get_mode_size_bits(lowered_mode) || + (is_Const(right) && is_Const_null(right)) + )) { int pnc = get_Proj_proj(node); int need_not = 0; ir_node *a = NULL; @@ -227,8 +269,16 @@ static ir_node *lower_node(ir_node *node) set_irn_link(node, psi); return psi; } - } else if (be_is_Barrier(pred)) { - /* nothing to do */ + } else if(is_Proj(pred) && is_Call(get_Proj_pred(pred))) { + ir_type *type = get_Call_type(get_Proj_pred(pred)); + adjust_method_type(type); + set_irn_mode(node, lowered_mode); + return node; + } else if(is_Proj(pred) && is_Start(get_Proj_pred(pred))) { + ir_entity *entity = get_irg_entity(irg); + ir_type *type = get_entity_type(entity); + adjust_method_type(type); + set_irn_mode(node, lowered_mode); return node; } @@ -252,15 +302,6 @@ static ir_node *lower_node(ir_node *node) panic("didn't expect %+F to have mode_b", node); } -static ir_node *create_convb(ir_node *node) -{ - ir_graph *irg = current_ir_graph; - ir_node *block = get_nodes_block(node); - ir_node *conv = new_rd_Conv(NULL, irg, block, node, mode_b); - - return conv; -} - static void lower_mode_b_walker(ir_node *node, void *env) { int i, arity; @@ -285,7 +326,17 @@ static void lower_mode_b_walker(ir_node *node, void *env) } lowered_in = lower_node(in); - lowered_in = create_convb(lowered_in); + + if(is_Return(node)) { + ir_entity *entity = get_irg_entity(current_ir_graph); + ir_type *type = get_entity_type(entity); + adjust_method_type(type); + } else if(is_Call(node)) { + ir_type *type = get_Call_type(node); + adjust_method_type(type); + } else { + lowered_in = create_convb(lowered_in); + } set_irn_n(node, i, lowered_in); } }