cleanup: complex conditional creation style
[cparser] / ast2firm.c
index abdc86a..9a78945 100644 (file)
@@ -1770,21 +1770,14 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
        const call_argument_t *argument = call->arguments;
        for (int n = 0; n < n_parameters; ++n) {
                expression_t *expression = argument->expression;
-               type_t       *arg_type   = skip_typeref(expression->base.type);
-               ir_node      *arg_node;
+               type_t *const arg_type = skip_typeref(expression->base.type);
                if (is_type_complex(arg_type)) {
                        complex_value value = expression_to_complex(expression);
-                       arg_node = complex_to_memory(dbgi, arg_type, value);
+                       in[n] = complex_to_memory(dbgi, arg_type, value);
                } else {
-                       arg_node = expression_to_value(expression);
-                       if (!is_type_compound(arg_type)) {
-                               ir_mode *const mode = get_ir_mode_storage(arg_type);
-                               arg_node = create_conv(dbgi, arg_node, mode);
-                       }
+                       in[n] = conv_to_storage_type(dbgi, expression_to_value(expression), arg_type);
                }
 
-               in[n] = arg_node;
-
                argument = argument->next;
        }
 
@@ -3333,9 +3326,9 @@ static void complex_equality_evaluation(const binary_expression_t *binexpr,
        jump_target *const true_target, jump_target *const false_target,
        ir_relation relation);
 
-static complex_value create_complex_condition_evaluation(
-       const expression_t *const expression, jump_target *const true_target,
-       jump_target *const false_target);
+static complex_value complex_to_control_flow(const expression_t *expression,
+                                             jump_target *true_target,
+                                             jump_target *false_target);
 
 /**
  * create a short-circuit expression evaluation that tries to construct
@@ -3370,11 +3363,6 @@ static ir_node *expression_to_control_flow(expression_t const *const expr, jump_
                evaluate_expression_discard_result(expr->binary.left);
                return expression_to_control_flow(expr->binary.right, true_target, false_target);
 
-               ir_node    *val;
-               ir_node    *left;
-               ir_node    *right;
-               ir_relation relation;
-
        case EXPR_BINARY_EQUAL:
        case EXPR_BINARY_GREATER:
        case EXPR_BINARY_GREATEREQUAL:
@@ -3387,21 +3375,20 @@ static ir_node *expression_to_control_flow(expression_t const *const expr, jump_
        case EXPR_BINARY_LESS:
        case EXPR_BINARY_LESSEQUAL:
        case EXPR_BINARY_NOTEQUAL: {
-               type_t *const type = skip_typeref(expr->binary.left->base.type);
-               relation = get_relation(expr->kind);
+               type_t     *const type     = skip_typeref(expr->binary.left->base.type);
+               ir_relation const relation = get_relation(expr->kind);
                if (is_type_complex(type)) {
                        complex_equality_evaluation(&expr->binary, true_target,
                                                    false_target, relation);
-                       /* TODO return something sensible */
                        return NULL;
                }
 
-               dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
-               ir_mode  *const mode = get_ir_mode_arithmetic(type);
-               val      = NULL;
-               left     = create_conv(dbgi, expression_to_value(expr->binary.left),  mode);
-               right    = create_conv(dbgi, expression_to_value(expr->binary.right), mode);
-               goto make_cmp;
+               dbg_info *const dbgi  = get_dbg_info(&expr->base.pos);
+               ir_mode  *const mode  = get_ir_mode_arithmetic(type);
+               ir_node  *const left  = create_conv(dbgi, expression_to_value(expr->binary.left),  mode);
+               ir_node  *const right = create_conv(dbgi, expression_to_value(expr->binary.right), mode);
+               compare_to_control_flow(expr, left, right, relation, true_target, false_target);
+               return NULL;
        }
 
        case EXPR_UNARY_CAST:
@@ -3412,17 +3399,16 @@ static ir_node *expression_to_control_flow(expression_t const *const expr, jump_
        default:;
                        type_t *const type = skip_typeref(expr->base.type);
                        if (is_type_complex(type)) {
-                               create_complex_condition_evaluation(expr, true_target, false_target);
+                               complex_to_control_flow(expr, true_target, false_target);
                                return NULL;
                        }
 
-                       dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
-                       ir_mode  *const mode = get_ir_mode_arithmetic(type);
-                       val      = create_conv(dbgi, expression_to_value(expr), mode);
-                       left     = val;
-                       right    = new_Const(get_mode_null(get_irn_mode(val)));
-                       relation = ir_relation_unordered_less_greater;
-make_cmp:
+                       dbg_info   *const dbgi  = get_dbg_info(&expr->base.pos);
+                       ir_mode    *const mode  = get_ir_mode_arithmetic(type);
+                       ir_node    *const val   = create_conv(dbgi, expression_to_value(expr), mode);
+                       ir_node    *const left  = val;
+                       ir_node    *const right = new_Const(get_mode_null(get_irn_mode(val)));
+                       ir_relation const relation = ir_relation_unordered_less_greater;
                        compare_to_control_flow(expr, left, right, relation, true_target, false_target);
                        return val;
                }
@@ -3449,39 +3435,37 @@ static void store_complex(dbg_info *dbgi, ir_node *addr, type_t *type,
                           complex_value value)
 {
        value = complex_conv_to_storage(dbgi, value, type);
-       ir_graph  *irg       = current_ir_graph;
-       ir_type   *irtype    = get_ir_type(type);
-       ir_node   *mem       = get_store();
-       ir_node   *nomem     = get_irg_no_mem(irg);
-       ir_mode   *mode      = get_complex_mode_storage(type);
-       ir_node   *real      = create_conv(dbgi, value.real, mode);
-       ir_node   *imag      = create_conv(dbgi, value.imag, mode);
-       ir_node   *storer    = new_d_Store(dbgi, mem, addr, real, cons_floats);
-       ir_node   *memr      = new_Proj(storer, mode_M, pn_Store_M);
-       set_store(memr);
-       ir_node   *mem2      = get_store();
-       ir_mode   *mode_uint = atomic_modes[ATOMIC_TYPE_UINT];
-       ir_node   *one       = new_Const(get_mode_one(mode_uint));
-       ir_node   *in[1]     = { one };
-       ir_entity *arrent    = get_array_element_entity(irtype);
-       ir_node   *addri     = new_d_Sel(dbgi, nomem, addr, 1, in, arrent);
-       ir_node   *storei    = new_d_Store(dbgi, mem2, addri, imag, cons_floats);
-       ir_node   *memi      = new_Proj(storei, mode_M, pn_Store_M);
+       ir_graph  *const irg    = current_ir_graph;
+       ir_type   *const irtype = get_ir_type(type);
+       ir_node   *const mem    = get_store();
+       ir_node   *const nomem  = get_irg_no_mem(irg);
+       ir_mode   *const mode   = get_complex_mode_storage(type);
+       ir_node   *const real   = create_conv(dbgi, value.real, mode);
+       ir_node   *const imag   = create_conv(dbgi, value.imag, mode);
+       ir_node   *const storer = new_d_Store(dbgi, mem, addr, real, cons_floats);
+       ir_node   *const memr   = new_Proj(storer, mode_M, pn_Store_M);
+       ir_mode   *const muint  = atomic_modes[ATOMIC_TYPE_UINT];
+       ir_node   *const one    = new_Const(get_mode_one(muint));
+       ir_node   *const in[1]  = { one };
+       ir_entity *const arrent = get_array_element_entity(irtype);
+       ir_node   *const addri  = new_d_Sel(dbgi, nomem, addr, 1, in, arrent);
+       ir_node   *const storei = new_d_Store(dbgi, memr, addri, imag, cons_floats);
+       ir_node   *const memi   = new_Proj(storei, mode_M, pn_Store_M);
        set_store(memi);
 }
 
 static ir_node *complex_to_memory(dbg_info *dbgi, type_t *type,
                                   complex_value value)
 {
-       ir_graph  *irg         = current_ir_graph;
-       ir_type   *frame_type  = get_irg_frame_type(irg);
-       ident     *id          = id_unique("cmplex_tmp.%u");
-       ir_type   *irtype      = get_ir_type(type);
-       ir_entity *tmp_storage = new_entity(frame_type, id, irtype);
+       ir_graph  *const irg         = current_ir_graph;
+       ir_type   *const frame_type  = get_irg_frame_type(irg);
+       ident     *const id          = id_unique("cmplex_tmp.%u");
+       ir_type   *const irtype      = get_ir_type(type);
+       ir_entity *const tmp_storage = new_entity(frame_type, id, irtype);
+       ir_node   *const frame       = get_irg_frame(irg);
+       ir_node   *const nomem       = get_irg_no_mem(irg);
+       ir_node   *const addr        = new_simpleSel(nomem, frame, tmp_storage);
        set_entity_compiler_generated(tmp_storage, 1);
-       ir_node   *frame       = get_irg_frame(irg);
-       ir_node   *nomem       = get_irg_no_mem(irg);
-       ir_node   *addr        = new_simpleSel(nomem, frame, tmp_storage);
        store_complex(dbgi, addr, type, value);
        return addr;
 }
@@ -3510,12 +3494,11 @@ static complex_value complex_deref_address(dbg_info *const dbgi,
 
        if (type->base.qualifiers & TYPE_QUALIFIER_VOLATILE)
                flags |= cons_volatile;
-       ir_mode *const mode     = get_complex_mode_storage(type);
-       ir_node *const memory   = get_store();
-       ir_node *const load     = new_d_Load(dbgi, memory, addr, mode, flags);
-       ir_node *const load_mem = new_Proj(load, mode_M, pn_Load_M);
-       ir_node *const load_res = new_Proj(load, mode,   pn_Load_res);
-       set_store(load_mem);
+       ir_mode   *const mode      = get_complex_mode_storage(type);
+       ir_node   *const memory    = get_store();
+       ir_node   *const load      = new_d_Load(dbgi, memory, addr, mode, flags);
+       ir_node   *const load_mem  = new_Proj(load, mode_M, pn_Load_M);
+       ir_node   *const load_res  = new_Proj(load, mode,   pn_Load_res);
 
        ir_type   *const irtype    = get_ir_type(type);
        ir_mode   *const mode_uint = atomic_modes[ATOMIC_TYPE_UINT];
@@ -3523,8 +3506,7 @@ static complex_value complex_deref_address(dbg_info *const dbgi,
        ir_entity *const entity    = get_array_element_entity(irtype);
        ir_node   *const nomem     = get_irg_no_mem(current_ir_graph);
        ir_node   *const addr2     = new_Sel(nomem, addr, 1, in, entity);
-       ir_node   *const mem2      = get_store();
-       ir_node   *const load2     = new_d_Load(dbgi, mem2, addr2, mode, flags);
+       ir_node   *const load2     = new_d_Load(dbgi, load_mem, addr2, mode, flags);
        ir_node   *const load_mem2 = new_Proj(load2, mode_M, pn_Load_M);
        ir_node   *const load_res2 = new_Proj(load2, mode, pn_Load_res);
        set_store(load_mem2);
@@ -3551,10 +3533,9 @@ static complex_value complex_reference_to_firm(const reference_expression_t *ref
 
 static complex_value complex_select_to_firm(const select_expression_t *select)
 {
-       dbg_info *dbgi = get_dbg_info(&select->base.pos);
-       ir_node  *addr = select_addr(select);
-       type_t   *type = skip_typeref(select->base.type);
-       assert(is_type_complex(type));
+       dbg_info *const dbgi = get_dbg_info(&select->base.pos);
+       ir_node  *const addr = select_addr(select);
+       type_t   *const type = skip_typeref(select->base.type);
        return complex_deref_address(dbgi, type, addr, cons_none);
 }
 
@@ -3592,21 +3573,19 @@ static complex_value get_complex_from_lvalue(const expression_t *expression,
 
 static complex_value complex_cast_to_firm(const unary_expression_t *expression)
 {
-       const expression_t *value     = expression->value;
-       dbg_info           *dbgi      = get_dbg_info(&expression->base.pos);
-       type_t             *from_type = skip_typeref(value->base.type);
-       type_t             *to_type   = skip_typeref(expression->base.type);
-       ir_mode            *mode      = get_complex_mode_storage(to_type);
-
-       assert(is_type_complex(to_type));
+       const expression_t *const value     = expression->value;
+       dbg_info           *const dbgi      = get_dbg_info(&expression->base.pos);
+       type_t             *const from_type = skip_typeref(value->base.type);
+       type_t             *const to_type   = skip_typeref(expression->base.type);
+       ir_mode            *const mode      = get_complex_mode_storage(to_type);
 
        if (is_type_complex(from_type)) {
                complex_value cvalue = expression_to_complex(value);
                return complex_conv(dbgi, cvalue, mode);
        } else {
-               ir_node *value_node = expression_to_value(value);
-               ir_node *zero       = new_Const(get_mode_null(mode));
-               ir_node *casted     = create_conv(dbgi, value_node, mode);
+               ir_node *const value_node = expression_to_value(value);
+               ir_node *const zero       = new_Const(get_mode_null(mode));
+               ir_node *const casted     = create_conv(dbgi, value_node, mode);
                return (complex_value) { casted, zero };
        }
 }
@@ -3701,12 +3680,10 @@ static void set_complex_value_for_expression(dbg_info *dbgi,
                                              complex_value value,
                                              ir_node *addr)
 {
-       type_t *type = skip_typeref(expression->base.type);
-       assert(is_type_complex(type));
-
-       ir_mode  *mode = get_complex_mode_storage(type);
-       ir_node  *real = create_conv(dbgi, value.real, mode);
-       ir_node  *imag = create_conv(dbgi, value.imag, mode);
+       type_t  *const type = skip_typeref(expression->base.type);
+       ir_mode *const mode = get_complex_mode_storage(type);
+       ir_node *const real = create_conv(dbgi, value.real, mode);
+       ir_node *const imag = create_conv(dbgi, value.imag, mode);
 
        if (expression->kind == EXPR_REFERENCE) {
                const reference_expression_t *ref = &expression->reference;
@@ -3846,13 +3823,25 @@ static void complex_equality_evaluation(const binary_expression_t *binexpr,
        set_unreachable_now();
 }
 
-static complex_value create_complex_condition_evaluation(
+static complex_value complex_to_control_flow(
        const expression_t *const expression, jump_target *const true_target,
        jump_target *const false_target)
 {
        jump_target extra_target;
        init_jump_target(&extra_target, NULL);
        complex_value       value      = expression_to_complex(expression);
+       if (is_Const(value.real) && is_Const(value.imag)) {
+               ir_tarval *tv_real = get_Const_tarval(value.real);
+               ir_tarval *tv_imag = get_Const_tarval(value.imag);
+               if (tarval_is_null(tv_real) && tarval_is_null(tv_imag)) {
+                       jump_to_target(false_target);
+               } else {
+                       jump_to_target(true_target);
+               }
+               set_unreachable_now();
+               return value;
+       }
+
        dbg_info     *const dbgi       = get_dbg_info(&expression->base.pos);
        type_t       *const type       = expression->base.type;
        ir_mode      *const mode       = get_complex_mode_arithmetic(type);
@@ -3883,23 +3872,6 @@ static complex_value create_complex_condition_evaluation(
 static complex_value complex_conditional_to_firm(
        const conditional_expression_t *const expression)
 {
-       /* first try to fold a constant condition */
-       if (is_constant_expression(expression->condition) == EXPR_CLASS_CONSTANT) {
-               bool val = fold_constant_to_bool(expression->condition);
-               if (val) {
-                       expression_t *true_expression = expression->true_expression;
-                       if (true_expression == NULL) {
-                               /* we will evaluate true_expression a second time here, but in
-                                * this case it is harmless since constant expression have no
-                                * side effects */
-                               true_expression = expression->condition;
-                       }
-                       return expression_to_complex(true_expression);
-               } else {
-                       return expression_to_complex(expression->false_expression);
-               }
-       }
-
        jump_target true_target;
        jump_target false_target;
        init_jump_target(&true_target,  NULL);
@@ -3908,17 +3880,19 @@ static complex_value complex_conditional_to_firm(
        memset(&cond_val, 0, sizeof(cond_val));
        if (expression->true_expression == NULL) {
                assert(is_type_complex(skip_typeref(expression->condition->base.type)));
-               cond_val
-                       = create_complex_condition_evaluation(expression->condition,
-                                                             &true_target, &false_target);
+               cond_val = complex_to_control_flow(expression->condition,
+                                                  &true_target, &false_target);
        } else {
                expression_to_control_flow(expression->condition, &true_target, &false_target);
        }
 
-       complex_value val;
+       complex_value  val;
        memset(&val, 0, sizeof(val));
-       jump_target   exit_target;
+       jump_target    exit_target;
        init_jump_target(&exit_target, NULL);
+       type_t   *const type = skip_typeref(expression->base.type);
+       ir_mode  *const mode = get_complex_mode_arithmetic(type);
+       dbg_info *const dbgi = get_dbg_info(&expression->base.pos);
 
        if (enter_jump_target(&true_target)) {
                if (expression->true_expression) {
@@ -3927,19 +3901,18 @@ static complex_value complex_conditional_to_firm(
                        assert(cond_val.real != NULL);
                        val = cond_val;
                }
+               val = complex_conv(dbgi, val, mode);
                jump_to_target(&exit_target);
        }
 
-       type_t *const type = skip_typeref(expression->base.type);
        if (enter_jump_target(&false_target)) {
                complex_value false_val
                        = expression_to_complex(expression->false_expression);
+               false_val = complex_conv(dbgi, false_val, mode);
                jump_to_target(&exit_target);
                if (val.real != NULL) {
                        ir_node  *const inr[] = { val.real, false_val.real };
                        ir_node  *const ini[] = { val.imag, false_val.imag };
-                       dbg_info *const dbgi  = get_dbg_info(&expression->base.pos);
-                       ir_mode  *const mode  = get_complex_mode_arithmetic(type);
                        ir_node  *const block = exit_target.block;
                        val.real = new_rd_Phi(dbgi, block, lengthof(inr), inr, mode);
                        val.imag = new_rd_Phi(dbgi, block, lengthof(ini), ini, mode);
@@ -3951,9 +3924,7 @@ static complex_value complex_conditional_to_firm(
        if (!enter_jump_target(&exit_target)) {
                set_cur_block(new_Block(0, NULL));
                assert(!is_type_void(type));
-               ir_mode *mode = get_complex_mode_arithmetic(type);
-               val.real = new_Unknown(mode);
-               val.imag = val.real;
+               val.real = val.imag = new_Bad(mode);
        }
        return val;
 }
@@ -3961,7 +3932,7 @@ static complex_value complex_conditional_to_firm(
 static void create_local_declarations(entity_t*);
 
 static complex_value compound_statement_to_firm_complex(
-       compound_statement_t *compound)
+       const compound_statement_t *compound)
 {
        create_local_declarations(compound->scope.entities);
 
@@ -3987,10 +3958,19 @@ static complex_value compound_statement_to_firm_complex(
        return result;
 }
 
+static complex_value complex_assign_to_firm(const binary_expression_t *expr)
+{
+       dbg_info     *const dbgi  = get_dbg_info(&expr->base.pos);
+       complex_value const value = expression_to_complex(expr->right);
+       ir_node      *const addr  = expression_to_addr(expr->left);
+       set_complex_value_for_expression(dbgi, expr->left, value, addr);
+       return value;
+}
+
 static complex_value complex_statement_expression_to_firm(
        const statement_expression_t *const expr)
 {
-       statement_t *statement = expr->statement;
+       const statement_t *const statement = expr->statement;
        assert(statement->kind == STATEMENT_COMPOUND);
 
        return compound_statement_to_firm_complex(&statement->compound);
@@ -4044,14 +4024,8 @@ static complex_value expression_to_complex(const expression_t *expression)
                return complex_negate_to_firm(&expression->unary);
        case EXPR_UNARY_COMPLEMENT:
                return complex_complement_to_firm(&expression->unary);
-       case EXPR_BINARY_ASSIGN: {
-               const binary_expression_t *binexpr = &expression->binary;
-               dbg_info                  *dbgi   = get_dbg_info(&binexpr->base.pos);
-               complex_value value = expression_to_complex(binexpr->right);
-               ir_node      *addr  = expression_to_addr(binexpr->left);
-               set_complex_value_for_expression(dbgi, binexpr->left, value, addr);
-               return value;
-       }
+       case EXPR_BINARY_ASSIGN:
+               return complex_assign_to_firm(&expression->binary);
        case EXPR_LITERAL_CASES:
                return complex_literal_to_firm(&expression->literal);
        case EXPR_CALL:
@@ -4060,11 +4034,9 @@ static complex_value expression_to_complex(const expression_t *expression)
                return complex_conditional_to_firm(&expression->conditional);
        case EXPR_STATEMENT:
                return complex_statement_expression_to_firm(&expression->statement);
-
        default:
-               break;
+               panic("unexpected complex expression");
        }
-       panic("complex expression not implemented yet");
 }
 
 
@@ -4973,7 +4945,7 @@ static ir_node *expression_statement_to_firm(expression_statement_t *statement)
        type_t       *type       = skip_typeref(expression->base.type);
        if (is_type_complex(type)) {
                expression_to_complex(expression);
-               return NULL; /* TODO */
+               return NULL;
        } else {
                return expression_to_value(statement->expression);
        }
@@ -5695,9 +5667,8 @@ static int count_local_variables(const entity_t *entity,
        for (; entity != end; entity = entity->base.next) {
                if ((entity->kind == ENTITY_VARIABLE || entity->kind == ENTITY_PARAMETER) &&
                    !var_needs_entity(&entity->variable)) {
-                       ++count;
-                       if (is_type_complex(skip_typeref(entity->declaration.type)))
-                               ++count;
+                   type_t *type = skip_typeref(entity->declaration.type);
+                       count += is_type_complex(type) ? 2 : 1;
                }
        }
        return count;