static ir_type *ir_type_char;
static ir_type *ir_type_const_char;
static ir_type *ir_type_wchar_t;
-static ir_type *ir_type_void;
-static ir_type *ir_type_int;
/* architecture specific floating point arithmetic mode (if any) */
static ir_mode *mode_float_arithmetic;
int n_parameters = count_parameters(function_type)
+ (for_closure ? 1 : 0);
- int n_results = return_type == type_void ? 0 : 1;
+ int n_results = is_type_void(return_type) ? 0 : 1;
type_dbg_info *dbgi = get_type_dbg_info_((const type_t*) function_type);
ir_type *irtype = new_d_type_method(n_parameters, n_results, dbgi);
- if (return_type != type_void) {
+ if (!is_type_void(return_type)) {
ir_type *restype = get_ir_type(return_type);
set_method_res_type(irtype, 0, restype);
}
continue;
type_t *return_type = skip_typeref(function_type->return_type);
- int n_res = return_type != type_void ? 1 : 0;
+ int n_res = is_type_void(return_type) ? 0 : 1;
if (n_res != rts_data[i].n_res)
continue;
set_store(mem);
}
- if (!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
+ if (!is_type_void(return_type)) {
assert(is_type_scalar(return_type));
ir_mode *mode = get_ir_mode_storage(return_type);
result = new_Proj(node, mode, pn_Builtin_max+1);
set_store(mem);
}
- if (!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
+ if (!is_type_void(return_type)) {
ir_node *resproj = new_Proj(node, mode_T, pn_Call_T_result);
if (is_type_scalar(return_type)) {
type_t *from_type, type_t *type)
{
type = skip_typeref(type);
- if (type == type_void) {
+ if (is_type_void(type)) {
/* make sure firm type is constructed */
(void) get_ir_type(type);
return NULL;
return NULL;
}
-/* Create a jump node which jumps into target_block, if the current block is
- * reachable. */
-static void jump_if_reachable(ir_node *const target_block)
+/**
+ * Add an unconditional jump to the target block. If the source block is not
+ * reachable, then a Bad predecessor is created to prevent Phi-less unreachable
+ * loops. This is necessary if the jump potentially enters a loop.
+ */
+static void jump_to(ir_node *const target_block)
{
ir_node *const pred = currently_reachable() ? new_Jmp() : new_Bad(mode_X);
add_immBlock_pred(target_block, pred);
}
+/**
+ * Add an unconditional jump to the target block, if the current block is
+ * reachable and do nothing otherwise. This is only valid if the jump does not
+ * enter a loop (a back edge is ok).
+ */
+static void jump_if_reachable(ir_node *const target_block)
+{
+ if (currently_reachable())
+ add_immBlock_pred(target_block, new_Jmp());
+}
+
static ir_node *while_statement_to_firm(while_statement_t *statement)
{
/* Create the header block */
ir_node *const header_block = new_immBlock();
- jump_if_reachable(header_block);
+ jump_to(header_block);
/* Create the condition. */
ir_node * body_block;
/* the loop body */
ir_node *body_block = new_immBlock();
- jump_if_reachable(body_block);
+ jump_to(body_block);
ir_node *old_continue_label = continue_label;
ir_node *old_break_label = break_label;
/* Create the header block */
ir_node *const header_block = new_immBlock();
- jump_if_reachable(header_block);
+ jump_to(header_block);
/* Create the condition. */
ir_node *body_block;
static ir_node *switch_statement_to_firm(switch_statement_t *statement)
{
- ir_node *first_block = NULL;
dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
ir_node *switch_node = NULL;
unsigned n_outs = (unsigned)ir_switch_table_get_n_entries(table) + 1;
switch_node = new_d_Switch(dbgi, expression, n_outs, table);
- first_block = get_cur_block();
}
set_unreachable_now();
statement_to_firm(statement->body);
- jump_if_reachable(get_break_label());
+ if (currently_reachable()) {
+ add_immBlock_pred(get_break_label(), new_Jmp());
+ }
- if (!saw_default_label && first_block != NULL) {
- set_cur_block(first_block);
+ if (!saw_default_label && switch_node) {
ir_node *proj = new_d_Proj(dbgi, switch_node, mode_X, pn_Switch_default);
add_immBlock_pred(get_break_label(), proj);
}
static ir_node *label_to_firm(const label_statement_t *statement)
{
ir_node *block = get_label_block(statement->label);
- jump_if_reachable(block);
+ jump_to(block);
set_cur_block(block);
keep_alive(block);
= skip_typeref(func_type->return_type);
ir_node *ret;
- if (is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
+ if (is_type_void(return_type)) {
ret = new_Return(get_store(), 0, NULL);
} else {
ir_mode *mode;
return;
ir_types_initialized = 1;
- ir_type_int = get_ir_type(type_int);
ir_type_char = get_ir_type(type_char);
ir_type_const_char = get_ir_type(type_const_char);
ir_type_wchar_t = get_ir_type(type_wchar_t);
- ir_type_void = get_ir_type(type_void);
be_params = be_get_backend_param();
mode_float_arithmetic = be_params->mode_float_arithmetic;