fix another illegal usage of compound_graph_path stuff
[libfirm] / ir / lower / lower_intrinsics.c
index 41b9b20..d9cf47e 100644 (file)
  * @author  Michael Beck
  * @version $Id$
  */
-
 #include "config.h"
 
+#include <stdbool.h>
+
 #include "lowering.h"
 #include "irop_t.h"
 #include "irprog_t.h"
@@ -170,13 +171,14 @@ struct pass_t {
 /**
  * Wrapper for running lower_intrinsics() as an ir_prog pass.
  */
-static void pass_wrapper(ir_prog *irp, void *context)
+static int pass_wrapper(ir_prog *irp, void *context)
 {
        struct pass_t *pass = context;
        (void) irp; /* TODO: set current irp, or remove parameter */
        lower_intrinsics(pass->list, pass->length, pass->part_block_used);
        /* probably this pass should not run again */
-}  /* pass_wrapper */
+       return 0;
+}
 
 /**
  * Creates an ir_prog pass for lower_intrinsics.
@@ -224,11 +226,10 @@ static void replace_call(ir_node *irn, ir_node *call, ir_node *mem, ir_node *reg
        irn = new_r_Tuple(block, 1, &irn);
 
        turn_into_tuple(call, pn_Call_max);
-       set_Tuple_pred(call, pn_Call_M_regular, mem);
+       set_Tuple_pred(call, pn_Call_M, mem);
        set_Tuple_pred(call, pn_Call_X_regular, reg_jmp);
        set_Tuple_pred(call, pn_Call_X_except, exc_jmp);
        set_Tuple_pred(call, pn_Call_T_result, irn);
-       set_Tuple_pred(call, pn_Call_M_except, mem);
        set_Tuple_pred(call, pn_Call_P_value_res_base, new_Bad());
 }  /* replace_call */
 
@@ -565,6 +566,27 @@ static ir_entity *get_const_entity(ir_node *ptr) {
        return NULL;
 }  /* get_const_entity */
 
+static bool initializer_val_is_null(ir_initializer_t *init)
+{
+       tarval *tv;
+
+       if (get_initializer_kind(init) == IR_INITIALIZER_NULL)
+               return true;
+
+       if (get_initializer_kind(init) == IR_INITIALIZER_TARVAL) {
+               tv = get_initializer_tarval_value(init);
+       } else if (get_initializer_kind(init) == IR_INITIALIZER_CONST) {
+               ir_node *irn = get_initializer_const_value(init);
+               if (!is_Const(irn))
+                       return false;
+               tv = get_Const_tarval(irn);
+       } else {
+               return false;
+       }
+
+       return tarval_is_null(tv);
+}
+
 /**
  * Calculate the value of strlen if possible.
  *
@@ -577,7 +599,9 @@ static ir_entity *get_const_entity(ir_node *ptr) {
 static ir_node *eval_strlen(ir_entity *ent, ir_type *res_tp) {
        ir_type *tp = get_entity_type(ent);
        ir_mode *mode;
-       int     i, n, len = -1;
+       ir_initializer_t *initializer;
+       unsigned          size;
+       unsigned          i;
 
        if (! is_Array_type(tp))
                return NULL;
@@ -590,23 +614,47 @@ static ir_node *eval_strlen(ir_entity *ent, ir_type *res_tp) {
        if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
                return NULL;
 
-       n = get_compound_ent_n_values(ent);
-       for (i = 0; i < n; ++i) {
-               ir_node *irn = get_compound_ent_value(ent, i);
+       if (!has_entity_initializer(ent)) {
+               int len;
+               int n;
+               int i = -1;
 
-               if (! is_Const(irn))
-                       return NULL;
+               n = get_compound_ent_n_values(ent);
+               for (i = 0; i < n; ++i) {
+                       ir_node *irn = get_compound_ent_value(ent, i);
 
-               if (is_Const_null(irn)) {
-                       /* found the length */
-                       len = i;
-                       break;
+                       if (! is_Const(irn))
+                               return NULL;
+
+                       if (is_Const_null(irn)) {
+                               /* found the length */
+                               len = i;
+                               break;
+                       }
+               }
+               if (len >= 0) {
+                       tarval *tv = new_tarval_from_long(len, get_type_mode(res_tp));
+                       return new_Const_type(tv, res_tp);
                }
+               return NULL;
        }
-       if (len >= 0) {
-               tarval *tv = new_tarval_from_long(len, get_type_mode(res_tp));
-               return new_Const_type(tv, res_tp);
+
+       if (!has_entity_initializer(ent))
+               return NULL;
+
+       initializer = get_entity_initializer(ent);
+       if (get_initializer_kind(initializer) != IR_INITIALIZER_COMPOUND)
+               return NULL;
+
+       size = get_initializer_compound_n_entries(initializer);
+       for (i = 0; i < size; ++i) {
+               ir_initializer_t *val = get_initializer_compound_value(initializer, i);
+               if (initializer_val_is_null(val)) {
+                       tarval *tv = new_tarval_from_long(i, get_type_mode(res_tp));
+                       return new_Const_type(tv, res_tp);
+               }
        }
+
        return NULL;
 }  /* eval_strlen */
 
@@ -726,10 +774,11 @@ static ir_node *eval_strcmp(ir_entity *left, ir_entity *right, ir_type *res_tp)
  * @return non-zero if ent represents the empty string
  */
 static int is_empty_string(ir_entity *ent) {
-       ir_type *tp = get_entity_type(ent);
-       ir_mode *mode;
-       int     n;
-       ir_node *irn;
+       ir_type          *tp = get_entity_type(ent);
+       ir_mode          *mode;
+       ir_node          *irn;
+       ir_initializer_t *initializer;
+       ir_initializer_t *init0;
 
        if (! is_Array_type(tp))
                return 0;
@@ -742,12 +791,25 @@ static int is_empty_string(ir_entity *ent) {
        if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
                return 0;
 
-       n = get_compound_ent_n_values(ent);
-       if (n < 1)
+       if (!has_entity_initializer(ent)) {
+               /* code for deprecated compound_graph_path stuff */
+               int n = get_compound_ent_n_values(ent);
+               if (n < 1)
+                       return 0;
+               irn = get_compound_ent_value(ent, 0);
+
+               return is_Const(irn) && is_Const_null(irn);
+       }
+
+       initializer = get_entity_initializer(ent);
+       if (get_initializer_kind(initializer) != IR_INITIALIZER_COMPOUND)
+               return 0;
+
+       if (get_initializer_compound_n_entries(initializer) < 1)
                return 0;
-       irn = get_compound_ent_value(ent, 0);
 
-       return is_Const(irn) && is_Const_null(irn);
+       init0 = get_initializer_compound_value(initializer, 0);
+       return initializer_val_is_null(init0);
 }  /* is_empty_string */
 
 /* A mapper for strcmp */
@@ -1100,7 +1162,7 @@ int i_mapper_RuntimeCall(ir_node *node, runtime_rt *rt) {
                for (i = 0; i < n_proj; ++i)
                        set_Tuple_pred(node, i, new_r_Bad(irg));
                if (rt->mem_proj_nr >= 0)
-                       set_Tuple_pred(node, rt->mem_proj_nr, new_r_Proj(bl, call, mode_M, pn_Call_M_regular));
+                       set_Tuple_pred(node, rt->mem_proj_nr, new_r_Proj(bl, call, mode_M, pn_Call_M));
                if (!is_NoMem(mem)) {
                        /* Exceptions can only be handled with real memory */
                        if (rt->regular_proj_nr >= 0)
@@ -1108,7 +1170,7 @@ int i_mapper_RuntimeCall(ir_node *node, runtime_rt *rt) {
                        if (rt->exc_proj_nr >= 0)
                                set_Tuple_pred(node, rt->exc_proj_nr, new_r_Proj(bl, call, mode_X, pn_Call_X_except));
                        if (rt->exc_mem_proj_nr >= 0)
-                               set_Tuple_pred(node, rt->mem_proj_nr, new_r_Proj(bl, call, mode_M, pn_Call_M_except));
+                               set_Tuple_pred(node, rt->mem_proj_nr, new_r_Proj(bl, call, mode_M, pn_Call_M));
                }
 
                if (rt->res_proj_nr >= 0)