New still buggy version:
[libfirm] / ir / opt / opt_inline.c
index ccd33dc..522456c 100644 (file)
@@ -164,15 +164,10 @@ static void copy_node(ir_node *n, void *env) {
        }
        copy_node_attr(n, nn);
 
-#ifdef DEBUG_libfirm
-       {
-               int copy_node_nr = env != NULL;
-               if (copy_node_nr) {
-                       /* for easier debugging, we want to copy the node numbers too */
-                       nn->node_nr = n->node_nr;
-               }
+       if (env != NULL) {
+               /* for easier debugging, we want to copy the node numbers too */
+               nn->node_nr = n->node_nr;
        }
-#endif
 
        set_new_node(n, nn);
        hook_dead_node_elim_subst(current_ir_graph, n, nn);
@@ -221,9 +216,10 @@ static void copy_preds(ir_node *n, void *env) {
                   in array contained Bads.  Now it's possible.
                   We don't call optimize_in_place as it requires
                   that the fields in ir_graph are set properly. */
-               if ((get_opt_control_flow_straightening()) &&
-                       (get_Block_n_cfgpreds(nn) == 1) &&
-                       is_Jmp(get_Block_cfgpred(nn, 0))) {
+               if (!has_Block_label(nn) &&
+                   get_opt_control_flow_straightening() &&
+                   get_Block_n_cfgpreds(nn) == 1 &&
+                   is_Jmp(get_Block_cfgpred(nn, 0))) {
                        ir_node *old = get_nodes_block(get_Block_cfgpred(nn, 0));
                        if (nn == old) {
                                /* Jmp jumps into the block it is in -- deal self cycle. */
@@ -767,10 +763,16 @@ static void copy_preds_inline(ir_node *n, void *env) {
  */
 static void find_addr(ir_node *node, void *env) {
        int *allow_inline = env;
-       if (is_Proj(node) &&
-                       is_Start(get_Proj_pred(node)) &&
-                       get_Proj_proj(node) == pn_Start_P_value_arg_base) {
-               *allow_inline = 0;
+       if (is_Sel(node)) {
+               ir_graph *irg = current_ir_graph;
+               if (get_Sel_ptr(node) == get_irg_frame(irg)) {
+                       /* access to frame */
+                       ir_entity *ent = get_Sel_entity(node);
+                       if (get_entity_owner(ent) != get_irg_frame_type(irg)) {
+                               /* access to value_type */
+                               *allow_inline = 0;
+                       }
+               }
        } else if (is_Alloc(node) && get_Alloc_where(node) == stack_alloc) {
                /* From GCC:
                 * Refuse to inline alloca call unless user explicitly forced so as this
@@ -860,17 +862,16 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
        mtp = get_entity_type(ent);
        ctp = get_Call_type(call);
        if (get_method_n_params(mtp) > get_method_n_params(ctp)) {
-               /* this is a bad feature of C: without a prototype, we can can call a function with less
-               parameters than needed. Currently we don't support this, although it would be
-               to use Unknown than. */
+               /* this is a bad feature of C: without a prototype, we can
+                * call a function with less parameters than needed. Currently
+                * we don't support this, although we could use Unknown than. */
                return 0;
        }
 
        /* Argh, compiling C has some bad consequences:
-          the call type AND the method type might be different.
-          It is implementation defendant what happens in that case.
-          We support inlining, if the bitsize of the types matches AND
-          the same arithmetic is used. */
+        * It is implementation dependent what happens in that case.
+        * We support inlining, if the bitsize of the types matches AND
+        * the same arithmetic is used. */
        n_params = get_method_n_params(mtp);
        for (i = n_params - 1; i >= 0; --i) {
                ir_type *param_tp = get_method_param_type(mtp, i);
@@ -925,6 +926,7 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
        set_irg_doms_inconsistent(irg);
        set_irg_loopinfo_inconsistent(irg);
        set_irg_callee_info_state(irg, irg_callee_info_inconsistent);
+       set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
 
        /* -- Check preconditions -- */
        assert(is_Call(call));
@@ -977,9 +979,7 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
        in[pn_Start_P_frame_base]     = get_irg_frame(irg);
        in[pn_Start_P_tls]            = get_irg_tls(irg);
        in[pn_Start_T_args]           = new_Tuple(n_params, args_in);
-       /* in[pn_Start_P_value_arg_base] = ??? */
-       assert(pn_Start_P_value_arg_base == pn_Start_max - 1 && "pn_Start_P_value_arg_base not supported, fix");
-       pre_call = new_Tuple(pn_Start_max - 1, in);
+       pre_call = new_Tuple(pn_Start_max, in);
        post_call = call;
 
        /* --
@@ -1166,7 +1166,9 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
                        }
                }
                if (n_exc > 0) {
-                       new_Block(n_exc, cf_pred);      /* watch it: current_block is changed! */
+                       ir_node *block = new_Block(n_exc, cf_pred);
+                       set_cur_block(block);
+
                        set_Tuple_pred(call, pn_Call_X_except, new_Jmp());
                        /* The Phi for the memories with the exception objects */
                        n_exc = 0;