X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=6726dc7413c0948177041a6237fd6b33a261edaf;hb=48b7436f2c91934d56b21196de2da3c94b1805cd;hp=604e86b97fead1885dae295a657aef7f47dfbc2c;hpb=f12dad2ea4aac0f7033d837b8f69cd59814274f6;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 604e86b..6726dc7 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -540,7 +540,6 @@ static ir_entity* get_function_entity(declaration_t *declaration) static ir_node *expression_to_firm(const expression_t *expression); -static ir_node *expression_to_modeb(const expression_t *expression); static dbg_info *get_dbg_info(const source_position_t *pos) { @@ -605,17 +604,25 @@ static ir_node *string_literal_to_firm(const string_literal_t* literal) return create_symconst(dbgi, entity); } -static ir_node *load_from_expression_addr(type_t *type, ir_node *addr, - dbg_info *dbgi) +static ir_node *deref_address(type_t *const type, ir_node *const addr, + dbg_info *const dbgi) { - ir_mode *mode = get_ir_mode(type); - ir_node *memory = get_store(); - ir_node *load = new_d_Load(dbgi, memory, addr, mode); - ir_node *load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M); - ir_node *load_res = new_d_Proj(dbgi, load, mode, pn_Load_res); - set_store(load_mem); + switch (type->type) { + case TYPE_ARRAY: + case TYPE_COMPOUND_STRUCT: + case TYPE_COMPOUND_UNION: + return addr; - return load_res; + default: { + ir_mode *const mode = get_ir_mode(type); + ir_node *const memory = get_store(); + ir_node *const load = new_d_Load(dbgi, memory, addr, mode); + ir_node *const load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M); + ir_node *const load_res = new_d_Proj(dbgi, load, mode, pn_Load_res); + set_store(load_mem); + return load_res; + } + } } static ir_node *reference_expression_to_firm(const reference_expression_t *ref) @@ -637,24 +644,13 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref) case DECLARATION_TYPE_GLOBAL_VARIABLE: { ir_entity *entity = declaration->v.entity; ir_node *symconst = create_symconst(dbgi, entity); - - if(type->type == TYPE_ARRAY) { - return symconst; - } else { - return load_from_expression_addr(type, symconst, dbgi); - } + return deref_address(type, symconst, dbgi); } case DECLARATION_TYPE_LOCAL_VARIABLE_ENTITY: { ir_entity *entity = declaration->v.entity; ir_node *frame = get_irg_frame(current_ir_graph); ir_node *sel = new_d_simpleSel(dbgi, new_NoMem(), frame, entity); - - if(type->type == TYPE_ARRAY || type->type == TYPE_COMPOUND_STRUCT - || type->type == TYPE_COMPOUND_UNION) { - return sel; - } else { - return load_from_expression_addr(type, sel, dbgi); - } + return deref_address(type, sel, dbgi); } case DECLARATION_TYPE_COMPOUND_MEMBER: @@ -705,8 +701,15 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) expression_t *function = call->function; ir_node *callee = expression_to_firm(function); - assert(function->datatype->type == TYPE_FUNCTION); - function_type_t *function_type = (function_type_t*) function->datatype; + function_type_t *function_type; + if (function->datatype->type == TYPE_POINTER) { + pointer_type_t *const ptr_type = (pointer_type_t*)function->datatype; + assert(ptr_type->points_to->type == TYPE_FUNCTION); + function_type = (function_type_t*)ptr_type->points_to; + } else { + assert(function->datatype->type == TYPE_FUNCTION); + function_type = (function_type_t*)function->datatype; + } int n_parameters = 0; call_argument_t *argument = call->arguments; @@ -772,6 +775,9 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) } static ir_node *expression_to_addr(const expression_t *expression); +static void create_condition_evaluation(const expression_t *expression, + ir_node *true_block, + ir_node *false_block); static void set_value_for_expression(const expression_t *expression, ir_node *value) @@ -813,11 +819,58 @@ static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode) return new_d_Conv(dbgi, value, dest_mode); } +static ir_node *create_incdec(const unary_expression_t *expression) +{ + dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); + type_t *type = expression->expression.datatype; + ir_mode *mode = get_ir_mode(type); + expression_t *value = expression->value; + + ir_node *value_node = expression_to_firm(value); + + ir_node *offset; + if(type->type == TYPE_POINTER) { + pointer_type_t *pointer_type = (pointer_type_t*) type; + unsigned elem_size = get_type_size(pointer_type->points_to); + offset = new_Const_long(mode_Is, elem_size); + } else { + assert(is_type_arithmetic(type)); + offset = new_Const(mode, get_mode_one(mode)); + } + + ir_node *new_value; + switch(expression->type) { + case UNEXPR_POSTFIX_INCREMENT: { + ir_node *new_value = new_d_Add(dbgi, value_node, offset, mode); + set_value_for_expression(value, new_value); + return value_node; + } + case UNEXPR_POSTFIX_DECREMENT: { + ir_node *new_value = new_d_Sub(dbgi, value_node, offset, mode); + set_value_for_expression(value, new_value); + return value_node; + } + case UNEXPR_PREFIX_INCREMENT: { + ir_node *new_value = new_d_Add(dbgi, value_node, offset, mode); + set_value_for_expression(value, new_value); + return new_value; + } + case UNEXPR_PREFIX_DECREMENT: { + ir_node *new_value = new_d_Sub(dbgi, value_node, offset, mode); + set_value_for_expression(value, new_value); + return new_value; + } + default: + panic("no incdec expr in create_incdec"); + } + + return new_value; +} + static ir_node *unary_expression_to_firm(const unary_expression_t *expression) { dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); type_t *type = expression->expression.datatype; - ir_mode *mode = get_ir_mode(type); if(expression->type == UNEXPR_TAKE_ADDRESS) return expression_to_addr(expression->value); @@ -827,48 +880,31 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression) switch(expression->type) { case UNEXPR_NEGATE: - return new_d_Minus(dbgi, value_node, mode); + return new_d_Minus(dbgi, value_node, get_ir_mode(type)); case UNEXPR_PLUS: return value_node; case UNEXPR_BITWISE_NEGATE: - return new_d_Not(dbgi, value_node, mode); - case UNEXPR_NOT: + return new_d_Not(dbgi, value_node, get_ir_mode(type)); + case UNEXPR_NOT: { if(get_irn_mode(value_node) != mode_b) { value_node = create_conv(dbgi, value_node, mode_b); } value_node = new_d_Not(dbgi, value_node, mode_b); + ir_mode *const mode = get_ir_mode(type); if(mode != mode_b) { value_node = create_conv(dbgi, value_node, mode); } return value_node; - case UNEXPR_DEREFERENCE: - return load_from_expression_addr(type, value_node, dbgi); - case UNEXPR_POSTFIX_INCREMENT: { - ir_node *one = new_Const(mode, get_mode_one(mode)); - ir_node *new_value = new_d_Add(dbgi, value_node, one, mode); - set_value_for_expression(value, new_value); - return value_node; - } - case UNEXPR_POSTFIX_DECREMENT: { - ir_node *one = new_Const(mode, get_mode_one(mode)); - ir_node *new_value = new_d_Sub(dbgi, value_node, one, mode); - set_value_for_expression(value, new_value); - return value_node; - } - case UNEXPR_PREFIX_INCREMENT: { - ir_node *one = new_Const(mode, get_mode_one(mode)); - ir_node *new_value = new_d_Add(dbgi, value_node, one, mode); - set_value_for_expression(value, new_value); - return new_value; - } - case UNEXPR_PREFIX_DECREMENT: { - ir_node *one = new_Const(mode, get_mode_one(mode)); - ir_node *new_value = new_d_Sub(dbgi, value_node, one, mode); - set_value_for_expression(value, new_value); - return new_value; } + case UNEXPR_DEREFERENCE: + return deref_address(type, value_node, dbgi); + case UNEXPR_POSTFIX_INCREMENT: + case UNEXPR_POSTFIX_DECREMENT: + case UNEXPR_PREFIX_INCREMENT: + case UNEXPR_PREFIX_DECREMENT: + return create_incdec(expression); case UNEXPR_CAST: - return create_conv(dbgi, value_node, mode); + return create_conv(dbgi, value_node, get_ir_mode(type)); case UNEXPR_TAKE_ADDRESS: case UNEXPR_INVALID: @@ -895,48 +931,32 @@ static long get_pnc(binary_expression_type_t type) static ir_node *create_lazy_op(const binary_expression_t *expression) { dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); + type_t *type = expression->expression.datatype; + ir_mode *mode = get_ir_mode(type); - bool is_or = (expression->type == BINEXPR_LOGICAL_OR); - assert(is_or || expression->type == BINEXPR_LOGICAL_AND); - - ir_node *val1 = expression_to_modeb(expression->left); - ir_node *cond = new_d_Cond(dbgi, val1); - ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true); - ir_node *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false); + ir_node *cur_block = get_cur_block(); - ir_node *fallthrough_block = new_immBlock(); + ir_node *one_block = new_immBlock(); + ir_node *one = new_Const(mode, get_mode_one(mode)); + ir_node *jmp_one = new_d_Jmp(dbgi); - /* the true case */ - ir_node *calc_val2_block = new_immBlock(); - if(is_or) { - add_immBlock_pred(calc_val2_block, false_proj); - } else { - add_immBlock_pred(calc_val2_block, true_proj); - } + ir_node *zero_block = new_immBlock(); + ir_node *zero = new_Const(mode, get_mode_null(mode)); + ir_node *jmp_zero = new_d_Jmp(dbgi); - mature_immBlock(calc_val2_block); + set_cur_block(cur_block); + create_condition_evaluation((const expression_t*) expression, + one_block, zero_block); + mature_immBlock(one_block); + mature_immBlock(zero_block); - ir_node *val2 = expression_to_modeb(expression->right); - if(get_cur_block() != NULL) { - ir_node *jmp = new_d_Jmp(dbgi); - add_immBlock_pred(fallthrough_block, jmp); - } - - /* fallthrough */ - ir_node *constb; - if(is_or) { - constb = new_d_Const(dbgi, mode_b, get_tarval_b_true()); - add_immBlock_pred(fallthrough_block, true_proj); - } else { - constb = new_d_Const(dbgi, mode_b, get_tarval_b_false()); - add_immBlock_pred(fallthrough_block, false_proj); - } - mature_immBlock(fallthrough_block); - - set_cur_block(fallthrough_block); + ir_node *common_block = new_immBlock(); + add_immBlock_pred(common_block, jmp_one); + add_immBlock_pred(common_block, jmp_zero); + mature_immBlock(common_block); - ir_node *in[2] = { val2, constb }; - ir_node *val = new_d_Phi(dbgi, 2, in, mode_b); + ir_node *in[2] = { one, zero }; + ir_node *val = new_d_Phi(dbgi, 2, in, mode); return val; } @@ -960,16 +980,44 @@ static ir_node *create_arithmetic_binop(const binary_expression_t *expression, return res; } +static ir_node *pointer_arithmetic(ir_node *const pointer, + ir_node * integer, + type_t *const type, + dbg_info *const dbgi, + const create_arithmetic_func func) +{ + pointer_type_t *const pointer_type = (pointer_type_t*)type; + type_t *const points_to = pointer_type->points_to; + const unsigned elem_size = get_type_size(points_to); + + assert(elem_size >= 1); + if (elem_size > 1) { + integer = create_conv(dbgi, integer, mode_Is); + ir_node *const cnst = new_Const_long(mode_Is, (long)elem_size); + ir_node *const mul = new_d_Mul(dbgi, integer, cnst, mode_Is); + integer = mul; + } + + ir_mode *const mode = get_ir_mode(type); + return func(dbgi, pointer, integer, mode); +} + static ir_node *create_arithmetic_assign_binop( const binary_expression_t *expression, create_arithmetic_func func) { - dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); - ir_node *value = create_arithmetic_binop(expression, func); - type_t *type = expression->expression.datatype; - ir_mode *mode = get_ir_mode(type); + dbg_info *const dbgi = get_dbg_info(&expression->expression.source_position); + type_t *const type = expression->expression.datatype; + ir_node *value; - assert(type->type != TYPE_POINTER); + if (type->type == TYPE_POINTER) { + ir_node *const pointer = expression_to_firm(expression->left); + ir_node * integer = expression_to_firm(expression->right); + value = pointer_arithmetic(pointer, integer, type, dbgi, func); + } else { + value = create_arithmetic_binop(expression, func); + } + ir_mode *const mode = get_ir_mode(type); value = create_conv(dbgi, value, mode); set_value_for_expression(expression->left, value); @@ -982,7 +1030,6 @@ static ir_node *create_add(const binary_expression_t *expression) ir_node *left = expression_to_firm(expression->left); ir_node *right = expression_to_firm(expression->right); type_t *type = expression->expression.datatype; - ir_mode *mode = get_ir_mode(type); expression_t *expr_left = expression->left; expression_t *expr_right = expression->right; @@ -990,76 +1037,37 @@ static ir_node *create_add(const binary_expression_t *expression) type_t *type_right = skip_typeref(expr_right->datatype); if(is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) { + ir_mode *const mode = get_ir_mode(type); return new_d_Add(dbgi, left, right, mode); } - ir_node *pointer; - ir_node *integer; - pointer_type_t *pointer_type; - if(type_left->type == TYPE_POINTER) { - pointer = left; - integer = right; - pointer_type = (pointer_type_t*) type_left; + if (type_left->type == TYPE_POINTER || type_left->type == TYPE_ARRAY) { + return pointer_arithmetic(left, right, type, dbgi, new_d_Add); } else { - assert(type_right->type == TYPE_POINTER); - pointer = right; - integer = left; - pointer_type = (pointer_type_t*) type_right; + assert(type_right->type == TYPE_POINTER || type_right->type == TYPE_ARRAY); + return pointer_arithmetic(right, left, type, dbgi, new_d_Add); } - - type_t *points_to = pointer_type->points_to; - unsigned elem_size = get_type_size(points_to); - - assert(elem_size >= 1); - if(elem_size > 1) { - integer = create_conv(dbgi, integer, mode_Is); - ir_node *cnst = new_Const_long(mode_Is, (int) elem_size); - ir_node *mul = new_d_Mul(dbgi, integer, cnst, mode_Is); - integer = mul; - } - - ir_node *res = new_d_Add(dbgi, pointer, integer, mode); - - return res; } static ir_node *create_sub(const binary_expression_t *expression) { - dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); - ir_node *left = expression_to_firm(expression->left); - ir_node *right = expression_to_firm(expression->right); - type_t *type = expression->expression.datatype; - ir_mode *mode = get_ir_mode(type); - - expression_t *expr_left = expression->left; - expression_t *expr_right = expression->right; - type_t *type_left = skip_typeref(expr_left->datatype); - type_t *type_right = skip_typeref(expr_right->datatype); - - if((is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) - || (type_left->type == TYPE_POINTER - && type_right->type == TYPE_POINTER)) { + dbg_info *const dbgi = get_dbg_info(&expression->expression.source_position); + expression_t *const expr_left = expression->left; + expression_t *const expr_right = expression->right; + ir_node *const left = expression_to_firm(expr_left); + ir_node *const right = expression_to_firm(expr_right); + type_t *const type = expression->expression.datatype; + type_t *const type_left = skip_typeref(expr_left->datatype); + type_t *const type_right = skip_typeref(expr_right->datatype); + + if ((is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) || + (type_left->type == TYPE_POINTER && type_right->type == TYPE_POINTER)) { + ir_mode *const mode = get_ir_mode(type); return new_d_Sub(dbgi, left, right, mode); } - assert(type_right->type == TYPE_POINTER); - ir_node *pointer = left; - ir_node *integer = right; - pointer_type_t *pointer_type = (pointer_type_t*) type_right; - - type_t *points_to = pointer_type->points_to; - unsigned elem_size = get_type_size(points_to); - - assert(elem_size >= 1); - if(elem_size > 1) { - ir_node *cnst = new_Const_long(mode_Iu, elem_size); - ir_node *mul = new_d_Mul(dbgi, integer, cnst, mode_Iu); - integer = mul; - } - - ir_node *res = new_d_Sub(dbgi, pointer, integer, mode); - - return res; + assert(type_left->type == TYPE_POINTER); + return pointer_arithmetic(left, right, type_left, dbgi, new_d_Sub); } static ir_node *create_shift(const binary_expression_t *expression) @@ -1244,8 +1252,7 @@ static ir_node *array_access_to_firm( dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); ir_node *addr = array_access_addr(expression); type_t *type = expression->expression.datatype; - - return load_from_expression_addr(type, addr, dbgi); + return deref_address(type, addr, dbgi); } static ir_node *sizeof_to_firm(const sizeof_expression_t *expression) @@ -1267,27 +1274,26 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression) { dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); - ir_node *condition = expression_to_modeb(expression->condition); - ir_node *cond = new_d_Cond(dbgi, condition); - ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true); - ir_node *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false); + ir_node *cur_block = get_cur_block(); /* create the true block */ - ir_node *true_block = new_immBlock(); - add_immBlock_pred(true_block, true_proj); - mature_immBlock(true_block); + ir_node *true_block = new_immBlock(); ir_node *true_val = expression_to_firm(expression->true_expression); ir_node *true_jmp = new_Jmp(); /* create the false block */ ir_node *false_block = new_immBlock(); - add_immBlock_pred(false_block, false_proj); - mature_immBlock(false_block); ir_node *false_val = expression_to_firm(expression->false_expression); ir_node *false_jmp = new_Jmp(); + /* create the condition evaluation */ + set_cur_block(cur_block); + create_condition_evaluation(expression->condition, true_block, false_block); + mature_immBlock(true_block); + mature_immBlock(false_block); + /* create the common block */ ir_node *common_block = new_immBlock(); add_immBlock_pred(common_block, true_jmp); @@ -1323,9 +1329,8 @@ static ir_node *select_to_firm(const select_expression_t *expression) { dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); ir_node *addr = select_addr(expression); - type_t *type = expression->expression.datatype; - - return load_from_expression_addr(type, addr, dbgi); + type_t *type = skip_typeref(expression->expression.datatype); + return deref_address(type, addr, dbgi); } static ir_node *dereference_addr(const unary_expression_t *const expression) @@ -1418,6 +1423,69 @@ static ir_node *expression_to_modeb(const expression_t *expression) return res; } +/** + * create a short-circuit expression evaluation that tries to construct + * efficient control flow structures for &&, || and ! expressions + */ +static void create_condition_evaluation(const expression_t *expression, + ir_node *true_block, + ir_node *false_block) +{ + switch(expression->type) { + case EXPR_UNARY: { + unary_expression_t *unary_expression = (unary_expression_t*) expression; + if(unary_expression->type == UNEXPR_NOT) { + create_condition_evaluation(unary_expression->value, false_block, + true_block); + return; + } + break; + } + case EXPR_BINARY: { + binary_expression_t *binary_expression + = (binary_expression_t*) expression; + if(binary_expression->type == BINEXPR_LOGICAL_AND) { + ir_node *cur_block = get_cur_block(); + ir_node *extra_block = new_immBlock(); + set_cur_block(cur_block); + create_condition_evaluation(binary_expression->left, extra_block, + false_block); + mature_immBlock(extra_block); + set_cur_block(extra_block); + create_condition_evaluation(binary_expression->right, true_block, + false_block); + return; + } + if(binary_expression->type == BINEXPR_LOGICAL_OR) { + ir_node *cur_block = get_cur_block(); + ir_node *extra_block = new_immBlock(); + set_cur_block(cur_block); + create_condition_evaluation(binary_expression->left, true_block, + extra_block); + mature_immBlock(extra_block); + set_cur_block(extra_block); + create_condition_evaluation(binary_expression->right, true_block, + false_block); + return; + } + break; + } + default: + break; + } + + dbg_info *dbgi = get_dbg_info(&expression->source_position); + ir_node *condition = expression_to_modeb(expression); + ir_node *cond = new_d_Cond(dbgi, condition); + ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true); + ir_node *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false); + + add_immBlock_pred(true_block, true_proj); + add_immBlock_pred(false_block, false_proj); + + set_cur_block(NULL); +} + static void statement_to_firm(statement_t *statement); static void return_statement_to_firm(return_statement_t *statement) @@ -1462,32 +1530,27 @@ static void expression_statement_to_firm(expression_statement_t *statement) static void if_statement_to_firm(if_statement_t *statement) { - dbg_info *dbgi = get_dbg_info(&statement->statement.source_position); - ir_node *condition = expression_to_modeb(statement->condition); - - /* make sure we have a mode_b condition */ - ir_node *cond = new_d_Cond(dbgi, condition); - ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true); - ir_node *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false); + ir_node *cur_block = get_cur_block(); ir_node *fallthrough_block = new_immBlock(); /* the true (blocks) */ - ir_node *true_block = new_immBlock(); - add_immBlock_pred(true_block, true_proj); - mature_immBlock(true_block); - - statement_to_firm(statement->true_statement); - if(get_cur_block() != NULL) { - ir_node *jmp = new_Jmp(); - add_immBlock_pred(fallthrough_block, jmp); + ir_node *true_block; + if (statement->true_statement != NULL) { + true_block = new_immBlock(); + statement_to_firm(statement->true_statement); + if(get_cur_block() != NULL) { + ir_node *jmp = new_Jmp(); + add_immBlock_pred(fallthrough_block, jmp); + } + } else { + true_block = fallthrough_block; } /* the false (blocks) */ + ir_node *false_block; if(statement->false_statement != NULL) { - ir_node *false_block = new_immBlock(); - add_immBlock_pred(false_block, false_proj); - mature_immBlock(false_block); + false_block = new_immBlock(); statement_to_firm(statement->false_statement); if(get_cur_block() != NULL) { @@ -1495,7 +1558,19 @@ static void if_statement_to_firm(if_statement_t *statement) add_immBlock_pred(fallthrough_block, jmp); } } else { - add_immBlock_pred(fallthrough_block, false_proj); + false_block = fallthrough_block; + } + + /* create the condition */ + if(cur_block != NULL) { + set_cur_block(cur_block); + create_condition_evaluation(statement->condition, true_block, + false_block); + } + + mature_immBlock(true_block); + if(false_block != fallthrough_block) { + mature_immBlock(false_block); } mature_immBlock(fallthrough_block); @@ -1504,8 +1579,6 @@ static void if_statement_to_firm(if_statement_t *statement) static void while_statement_to_firm(while_statement_t *statement) { - dbg_info *dbgi = get_dbg_info(&statement->statement.source_position); - ir_node *jmp = NULL; if(get_cur_block() != NULL) { jmp = new_Jmp(); @@ -1517,48 +1590,46 @@ static void while_statement_to_firm(while_statement_t *statement) add_immBlock_pred(header_block, jmp); } - /* create the condition */ - ir_node *condition = expression_to_modeb(statement->condition); - ir_node *cond = new_d_Cond(dbgi, condition); - ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true); - ir_node *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false); - /* the false block */ ir_node *false_block = new_immBlock(); - add_immBlock_pred(false_block, false_proj); /* the loop body */ - ir_node *body_block = new_immBlock(); - add_immBlock_pred(body_block, true_proj); - mature_immBlock(body_block); + ir_node *body_block; + if (statement->body != NULL) { + ir_node *old_continue_label = continue_label; + ir_node *old_break_label = break_label; + continue_label = header_block; + break_label = false_block; - ir_node *old_continue_label = continue_label; - ir_node *old_break_label = break_label; - continue_label = header_block; - break_label = false_block; + body_block = new_immBlock(); + statement_to_firm(statement->body); - statement_to_firm(statement->body); + assert(continue_label == header_block); + assert(break_label == false_block); + continue_label = old_continue_label; + break_label = old_break_label; - assert(continue_label == header_block); - assert(break_label == false_block); - continue_label = old_continue_label; - break_label = old_break_label; - - if(get_cur_block() != NULL) { - ir_node *jmp = new_Jmp(); - add_immBlock_pred(header_block, jmp); + if(get_cur_block() != NULL) { + ir_node *jmp = new_Jmp(); + add_immBlock_pred(header_block, jmp); + } + } else { + body_block = header_block; } - mature_immBlock(header_block); + /* create the condition */ + set_cur_block(header_block); + + create_condition_evaluation(statement->condition, body_block, false_block); + mature_immBlock(body_block); mature_immBlock(false_block); + mature_immBlock(header_block); set_cur_block(false_block); } static void do_while_statement_to_firm(do_while_statement_t *statement) { - dbg_info *dbgi = get_dbg_info(&statement->statement.source_position); - ir_node *jmp = NULL; if(get_cur_block() != NULL) { jmp = new_Jmp(); @@ -1576,23 +1647,25 @@ static void do_while_statement_to_firm(do_while_statement_t *statement) add_immBlock_pred(body_block, jmp); } - ir_node *old_continue_label = continue_label; - ir_node *old_break_label = break_label; - continue_label = header_block; - break_label = false_block; + if (statement->body != NULL) { + ir_node *old_continue_label = continue_label; + ir_node *old_break_label = break_label; + continue_label = header_block; + break_label = false_block; - statement_to_firm(statement->body); + statement_to_firm(statement->body); - assert(continue_label == header_block); - assert(break_label == false_block); - continue_label = old_continue_label; - break_label = old_break_label; + assert(continue_label == header_block); + assert(break_label == false_block); + continue_label = old_continue_label; + break_label = old_break_label; - if(get_cur_block() == NULL) { - mature_immBlock(header_block); - mature_immBlock(body_block); - mature_immBlock(false_block); - return; + if (get_cur_block() == NULL) { + mature_immBlock(header_block); + mature_immBlock(body_block); + mature_immBlock(false_block); + return; + } } ir_node *body_jmp = new_Jmp(); @@ -1601,24 +1674,17 @@ static void do_while_statement_to_firm(do_while_statement_t *statement) /* create the condition */ set_cur_block(header_block); - ir_node *condition = expression_to_modeb(statement->condition); - ir_node *cond = new_d_Cond(dbgi, condition); - ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true); - ir_node *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false); - add_immBlock_pred(body_block, true_proj); + create_condition_evaluation(statement->condition, body_block, false_block); mature_immBlock(body_block); - - add_immBlock_pred(false_block, false_proj); mature_immBlock(false_block); + mature_immBlock(header_block); set_cur_block(false_block); } static void for_statement_to_firm(for_statement_t *statement) { - dbg_info *const dbgi = get_dbg_info(&statement->statement.source_position); - ir_node *jmp = NULL; if (get_cur_block() != NULL) { if(statement->initialisation != NULL) { @@ -1632,7 +1698,7 @@ static void for_statement_to_firm(for_statement_t *statement) if (statement->step != NULL) { expression_to_firm(statement->step); } - ir_node *const step_jmp = new_Jmp(); + ir_node *const step_jmp = new_Jmp(); /* create the header block */ ir_node *const header_block = new_immBlock(); @@ -1641,48 +1707,46 @@ static void for_statement_to_firm(for_statement_t *statement) } add_immBlock_pred(header_block, step_jmp); - /* create the condition */ - ir_node *true_proj; - ir_node *false_proj; - if (statement->condition != NULL) { - ir_node *const condition = expression_to_modeb(statement->condition); - ir_node *const cond = new_d_Cond(dbgi, condition); - true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true); - false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false); - } else { - keep_alive(header_block); - true_proj = new_Jmp(); - false_proj = NULL; - } - /* the false block */ ir_node *const false_block = new_immBlock(); - if (false_proj != NULL) { - add_immBlock_pred(false_block, false_proj); - } /* the loop body */ - ir_node *const body_block = new_immBlock(); - add_immBlock_pred(body_block, true_proj); - mature_immBlock(body_block); - - ir_node *const old_continue_label = continue_label; - ir_node *const old_break_label = break_label; - continue_label = step_block; - break_label = false_block; - - statement_to_firm(statement->body); - - assert(continue_label == step_block); - assert(break_label == false_block); - continue_label = old_continue_label; - break_label = old_break_label; + ir_node * body_block; + if (statement->body != NULL) { + ir_node *const old_continue_label = continue_label; + ir_node *const old_break_label = break_label; + continue_label = step_block; + break_label = false_block; + + body_block = new_immBlock(); + statement_to_firm(statement->body); + + assert(continue_label == step_block); + assert(break_label == false_block); + continue_label = old_continue_label; + break_label = old_break_label; + + if (get_cur_block() != NULL) { + ir_node *const jmp = new_Jmp(); + add_immBlock_pred(step_block, jmp); + } + } else { + body_block = step_block; + } - if (get_cur_block() != NULL) { - ir_node *const jmp = new_Jmp(); - add_immBlock_pred(step_block, jmp); + /* create the condition */ + set_cur_block(header_block); + if (statement->condition != NULL) { + create_condition_evaluation(statement->condition, body_block, + false_block); + } else { + keep_alive(header_block); + ir_node *jmp = new_Jmp(); + add_immBlock_pred(body_block, jmp); } + mature_immBlock(body_block); + mature_immBlock(false_block); mature_immBlock(step_block); mature_immBlock(header_block); mature_immBlock(false_block);