fix another illegal usage of compound_graph_path stuff
[libfirm] / ir / lower / lower_intrinsics.c
index f748f43..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"
@@ -173,44 +174,32 @@ struct pass_t {
 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 */
        return 0;
-}  /* pass_wrapper */
+}
 
 /**
  * Creates an ir_prog pass for lower_intrinsics.
  *
  * @param name             the name of this pass or NULL
- * @param verify           should this pass be verified?
- * @param dump             should this pass result be dumped?
  * @param list             an array of intrinsic map records
  * @param length           the length of the array
  * @param part_block_used  set to true if part_block() must be using during lowering
  */
 ir_prog_pass_t *lower_intrinsics_pass(
        const char *name,
-       int verify,
-       int dump,
        i_record *list, int length, int part_block_used)
 {
        struct pass_t *pass = xmalloc(sizeof(*pass) + (length-1) * sizeof(pass->list[0]));
 
-       memset(&pass->pass, 0, sizeof(pass->pass));
-       pass->pass.kind          = k_ir_prog_pass;
-       pass->pass.run_on_irprog = pass_wrapper;
-       pass->pass.context       = pass;
-       pass->pass.name          = name ? name : "lower_intrinsics";
-       pass->pass.verify        = verify != 0;
-       pass->pass.dump          = dump != 0;
-
-       INIT_LIST_HEAD(&pass->pass.list);
-
        memcpy(pass->list, list, sizeof(list[0]) * length);
        pass->length          = length;
        pass->part_block_used = part_block_used;
 
-       return &pass->pass;
+       return def_prog_pass_constructor(
+               &pass->pass, name ? name : "lower_intrinsics", pass_wrapper);
 }  /* lower_intrinsics_pass*/
 
 /**
@@ -237,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 */
 
@@ -578,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.
  *
@@ -590,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;
@@ -603,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 */
 
@@ -739,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;
@@ -755,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 */
@@ -1113,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)
@@ -1121,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)