}
/**
- * Keep all memory edges of the given block.
+ * Keep the current block and memory.
+ * This is necessary for all loops, because they could become infinite.
*/
-static void keep_all_memory(ir_node *block)
+static void keep_loop(void)
{
- ir_node *old = get_cur_block();
-
- set_cur_block(block);
+ keep_alive(get_cur_block());
keep_alive(get_store());
- /* TODO: keep all memory edges from restricted pointers */
- set_cur_block(old);
}
static ir_node *enum_constant_to_firm(reference_expression_t const *const ref)
static ir_node *conditional_to_firm(const conditional_expression_t *expression)
{
- dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
-
/* first try to fold a constant condition */
if (is_constant_expression(expression->condition) == EXPR_CLASS_CONSTANT) {
bool val = fold_constant_to_bool(expression->condition);
ir_node *const false_val = expression_to_firm(expression->false_expression);
jump_to_target(&exit_target);
if (val) {
- ir_node *const in[] = { val, false_val };
+ ir_node *const in[] = { val, false_val };
+ dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
val = new_rd_Phi(dbgi, exit_target.block, lengthof(in), in, get_irn_mode(val));
} else {
val = false_val;
break;
}
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
- ir_node *cond_expr = _expression_to_firm(expression);
- ir_node *condition = create_conv(dbgi, cond_expr, mode_b);
- 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);
-
- /* set branch prediction info based on __builtin_expect */
- if (is_builtin_expect(expression) && is_Cond(cond)) {
- call_argument_t *argument = expression->call.arguments->next;
- if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
- bool const cnst = fold_constant_to_bool(argument->expression);
- cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
- set_Cond_jmp_pred(cond, pred);
+ ir_node *cond_expr = _expression_to_firm(expression);
+ if (is_Const(cond_expr)) {
+ if (tarval_is_null(get_Const_tarval(cond_expr))) {
+ jump_to_target(false_target);
+ } else {
+ jump_to_target(true_target);
+ }
+ } else {
+ dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ ir_node *condition = create_conv(dbgi, cond_expr, mode_b);
+ 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);
+
+ /* set branch prediction info based on __builtin_expect */
+ if (is_builtin_expect(expression) && is_Cond(cond)) {
+ call_argument_t *argument = expression->call.arguments->next;
+ if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
+ bool const cnst = fold_constant_to_bool(argument->expression);
+ cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
+ set_Cond_jmp_pred(cond, pred);
+ }
}
- }
-
- add_pred_to_jump_target(true_target, true_proj);
- add_pred_to_jump_target(false_target, false_proj);
+ add_pred_to_jump_target(true_target, true_proj);
+ add_pred_to_jump_target(false_target, false_proj);
+ }
set_unreachable_now();
return cond_expr;
}
init_jump_target(&body_target, NULL);
jump_to_target(&body_target);
enter_immature_jump_target(&body_target);
+ keep_loop();
statement_to_firm(statement->body);
jump_to_target(&continue_target);
if (enter_jump_target(&continue_target))
init_jump_target(&header_target, NULL);
jump_to_target(&header_target);
enter_immature_jump_target(&header_target);
+ keep_loop();
expression_t *const step = statement->step;
PUSH_BREAK(NULL);
init_jump_target(&body_target, NULL);
create_condition_evaluation(cond, &body_target, &break_target);
enter_jump_target(&body_target);
- } else {
- /* for-ever. */
- keep_alive(header_target.block);
- keep_all_memory(header_target.block);
}
/* Create the loop body. */
enter_jump_target(&label->target);
} else {
enter_immature_jump_target(&label->target);
- keep_alive(label->target.block);
- keep_all_memory(label->target.block);
+ keep_loop();
}
return statement_to_firm(statement->statement);