Fixed some bugs
authorSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Tue, 1 Aug 2006 15:32:13 +0000 (15:32 +0000)
committerSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Tue, 1 Aug 2006 15:32:13 +0000 (15:32 +0000)
Several changes

ir/be/bechordal.c
ir/be/bechordal_main.c
ir/be/bechordal_t.h
ir/be/becopyheur3.c
ir/be/becopyopt.c
ir/be/becopyopt.h
ir/be/bejavacoal.c
ir/be/belive.h

index 7094576..914d17e 100644 (file)
@@ -207,17 +207,58 @@ static bitset_t *get_decisive_partner_regs(bitset_t *bs, const be_operand_t *o1,
        return res;
 }
 
        return res;
 }
 
-static be_insn_t *chordal_scan_insn(be_chordal_alloc_env_t *env, ir_node *irn)
+static be_insn_t *chordal_scan_insn(be_chordal_env_t *env, ir_node *irn)
 {
        be_insn_env_t ie;
 
 {
        be_insn_env_t ie;
 
-       ie.ignore_colors = env->chordal_env->ignore_colors;
-       ie.aenv          = env->chordal_env->birg->main_env->arch_env;
-       ie.obst          = &env->chordal_env->obst;
-       ie.cls           = env->chordal_env->cls;
+       ie.ignore_colors = env->ignore_colors;
+       ie.aenv          = env->birg->main_env->arch_env;
+       ie.obst          = &env->obst;
+       ie.cls           = env->cls;
        return be_scan_insn(&ie, irn);
 }
 
        return be_scan_insn(&ie, irn);
 }
 
+static ir_node *prepare_constr_insn(be_chordal_env_t *env, ir_node *irn)
+{
+       be_insn_t *insn = chordal_scan_insn(env, irn);
+       int n_uses      = be_insn_n_uses(insn);
+       int n_defs      = be_insn_n_defs(insn);
+       int i;
+
+       if(!insn->has_constraints)
+               goto end;
+
+       for(i = insn->use_start; i < insn->n_ops; ++i) {
+               be_operand_t *op = &insn->ops[i];
+               if(op->has_constraints && values_interfere(env->lv, insn->irn, op->carrier)) {
+                       ir_node *bl   = get_nodes_block(insn->irn);
+                       ir_node *copy = be_new_Copy(env->cls, env->irg, bl, op->carrier);
+
+                       sched_add_before(insn->irn, copy);
+                       set_irn_n(insn->irn, op->pos, copy);
+                       DBG((env->dbg, LEVEL_3, "inserting constr copy %+F for %+F pos %d\n", copy, insn->irn, op->pos));
+                       be_liveness_update(env->lv, op->carrier);
+               }
+       }
+
+end:
+       obstack_free(&env->obst, insn);
+       return insn->next_insn;
+}
+
+static void pre_spill_prepare_constr_walker(ir_node *bl, void *data)
+{
+       be_chordal_env_t *env = data;
+       ir_node *irn;
+       for(irn = sched_first(bl); !sched_is_end(irn);) {
+               irn = prepare_constr_insn(env, irn);
+       }
+}
+
+void be_pre_spill_prepare_constr(be_chordal_env_t *cenv) {
+       irg_block_walk_graph(cenv->irg, pre_spill_prepare_constr_walker, NULL, (void *) cenv);
+}
+
 static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, be_insn_t *insn)
 {
        const be_chordal_env_t *env = alloc_env->chordal_env;
 static void pair_up_operands(const be_chordal_alloc_env_t *alloc_env, be_insn_t *insn)
 {
        const be_chordal_env_t *env = alloc_env->chordal_env;
@@ -305,6 +346,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_in
                Now, figure out which input operand must be copied since it has input
                constraints which are also output constraints.
        */
                Now, figure out which input operand must be copied since it has input
                constraints which are also output constraints.
        */
+#if 0
        for(i = insn->use_start; i < insn->n_ops; ++i) {
                be_operand_t *op = &insn->ops[i];
                if(op->has_constraints && (values_interfere(env->lv, op->carrier, insn->irn) || arch_irn_is(aenv, op->carrier, ignore))) {
        for(i = insn->use_start; i < insn->n_ops; ++i) {
                be_operand_t *op = &insn->ops[i];
                if(op->has_constraints && (values_interfere(env->lv, op->carrier, insn->irn) || arch_irn_is(aenv, op->carrier, ignore))) {
@@ -325,6 +367,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_in
                        }
                }
        }
                        }
                }
        }
+#endif
 
        /*
                Make the Perm, recompute liveness and re-scan the insn since the
 
        /*
                Make the Perm, recompute liveness and re-scan the insn since the
@@ -348,7 +391,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, be_in
                */
                // be_liveness_recompute(env->lv);
                obstack_free(&env->obst, insn);
                */
                // be_liveness_recompute(env->lv);
                obstack_free(&env->obst, insn);
-               *the_insn = insn = chordal_scan_insn(alloc_env, insn->irn);
+               *the_insn = insn = chordal_scan_insn(env, insn->irn);
 
                /*
                        Copy the input constraints of the insn to the Perm as output
 
                /*
                        Copy the input constraints of the insn to the Perm as output
@@ -374,7 +417,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i
 {
        be_chordal_env_t *env  = alloc_env->chordal_env;
        void *base             = obstack_base(&env->obst);
 {
        be_chordal_env_t *env  = alloc_env->chordal_env;
        void *base             = obstack_base(&env->obst);
-       be_insn_t *insn        = chordal_scan_insn(alloc_env, irn);
+       be_insn_t *insn        = chordal_scan_insn(env, irn);
        ir_node *res           = insn->next_insn;
        int be_silent          = *silent;
 
        ir_node *res           = insn->next_insn;
        int be_silent          = *silent;
 
index bf8b4d1..45af413 100644 (file)
@@ -30,6 +30,7 @@
 #include "irgraph_t.h"
 #include "irprintf_t.h"
 #include "irgwalk.h"
 #include "irgraph_t.h"
 #include "irprintf_t.h"
 #include "irgwalk.h"
+#include "ircons.h"
 #include "irdump.h"
 #include "irdom.h"
 #include "ircons.h"
 #include "irdump.h"
 #include "irdom.h"
 #include "ircons.h"
@@ -465,9 +466,11 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi)
                BE_TIMER_PUSH(ra_timer.t_live);
                be_liveness_recompute(chordal_env.lv);
                BE_TIMER_POP(ra_timer.t_live);
                BE_TIMER_PUSH(ra_timer.t_live);
                be_liveness_recompute(chordal_env.lv);
                BE_TIMER_POP(ra_timer.t_live);
-
                dump(BE_CH_DUMP_LIVE, irg, chordal_env.cls, "-live", dump_ir_block_graph_sched);
 
                dump(BE_CH_DUMP_LIVE, irg, chordal_env.cls, "-live", dump_ir_block_graph_sched);
 
+               be_pre_spill_prepare_constr(&chordal_env);
+               dump(BE_CH_DUMP_CONSTR, irg, chordal_env.cls, "-constr-pre", dump_ir_block_graph_sched);
+
                BE_TIMER_PUSH(ra_timer.t_spill);
 
                /* spilling */
                BE_TIMER_PUSH(ra_timer.t_spill);
 
                /* spilling */
@@ -497,9 +500,9 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi)
                    );
 
                dump(BE_CH_DUMP_SPILL, irg, chordal_env.cls, "-spill", dump_ir_block_graph_sched);
                    );
 
                dump(BE_CH_DUMP_SPILL, irg, chordal_env.cls, "-spill", dump_ir_block_graph_sched);
-               be_abi_fix_stack_nodes(bi->abi, chordal_env.lv);
                be_compute_spill_offsets(&chordal_env);
                check_for_memory_operands(&chordal_env);
                be_compute_spill_offsets(&chordal_env);
                check_for_memory_operands(&chordal_env);
+               be_abi_fix_stack_nodes(bi->abi, chordal_env.lv);
 
                BE_TIMER_PUSH(ra_timer.t_verify);
 
 
                BE_TIMER_PUSH(ra_timer.t_verify);
 
@@ -568,11 +571,8 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi)
                        co_build_ou_structure(co);
                        co_build_graph_structure(co);
                        if(be_copymin_stats) {
                        co_build_ou_structure(co);
                        co_build_graph_structure(co);
                        if(be_copymin_stats) {
-                               ir_printf("%40F %20s\n", current_ir_graph, chordal_env.cls->name);
-                               printf("max copy costs:         %d\n", co_get_max_copy_costs(co));
-                               printf("init copy costs:        %d\n", co_get_copy_costs(co));
-                               printf("inevit copy costs:      %d\n", co_get_inevit_copy_costs(co));
-                               printf("copy costs lower bound: %d\n", co_get_lower_bound(co));
+                               ir_printf("%30F %10s %7d%7d%7d%7d", current_ir_graph, chordal_env.cls->name,
+                                               co_get_max_copy_costs(co), co_get_copy_costs(co), co_get_inevit_copy_costs(co), co_get_lower_bound(co));
                        }
 
                        /* Dump the interference graph in Appel's format. */
                        }
 
                        /* Dump the interference graph in Appel's format. */
@@ -611,7 +611,14 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi)
 
                if (co) {
                        if(be_copymin_stats) {
 
                if (co) {
                        if(be_copymin_stats) {
-                               printf("final copy costs      : %d\n", co_get_copy_costs(co));
+                               int optimizable_costs = co_get_max_copy_costs(co) - co_get_lower_bound(co);
+                               int remaining         = co_get_copy_costs(co);
+                               int evitable          = remaining - co_get_lower_bound(co);
+
+                               if(optimizable_costs > 0)
+                                       printf("%5d %5.2f\n", remaining, (evitable * 100.0) / optimizable_costs);
+                               else
+                                       printf("%5d %5s\n", remaining, "-");
                        }
                        co_free_graph_structure(co);
                        co_free_ou_structure(co);
                        }
                        co_free_graph_structure(co);
                        co_free_ou_structure(co);
index ecd1014..dc911cb 100644 (file)
@@ -160,4 +160,6 @@ struct _be_ra_chordal_opts_t {
  */
 FILE *be_chordal_open(const be_chordal_env_t *env, const char *prefix, const char *suffix);
 
  */
 FILE *be_chordal_open(const be_chordal_env_t *env, const char *prefix, const char *suffix);
 
+void be_pre_spill_prepare_constr(be_chordal_env_t *cenv);
+
 #endif /* _BECHORDAL_T_H */
 #endif /* _BECHORDAL_T_H */
index d14f066..1c2decd 100644 (file)
@@ -107,7 +107,6 @@ void co_solve_heuristic_java(copy_opt_t *co)
        int *inv_node_map;
 
        java_coal_t *coal;
        int *inv_node_map;
 
        java_coal_t *coal;
-       ir_node *irn;
        ir_node *n, *m;
        int max_idx = 0;
 
        ir_node *n, *m;
        int max_idx = 0;
 
@@ -183,6 +182,12 @@ void co_solve_heuristic_java(copy_opt_t *co)
                }
        }
 
                }
        }
 
+       if(dump_flags & DUMP_BEFORE) {
+               char fn[512];
+               ir_snprintf(fn, sizeof(fn), "%F-%s-before.dot", co->cenv->irg, co->cenv->cls->name);
+               java_coal_dump(coal, fn);
+       }
+
        java_coal_coalesce(coal);
 
        be_ifg_foreach_node(ifg, nodes_it, n) {
        java_coal_coalesce(coal);
 
        be_ifg_foreach_node(ifg, nodes_it, n) {
@@ -195,6 +200,12 @@ void co_solve_heuristic_java(copy_opt_t *co)
                }
        }
 
                }
        }
 
+       if(dump_flags & DUMP_AFTER) {
+               char fn[512];
+               ir_snprintf(fn, sizeof(fn), "%F-%s-after.dot", co->cenv->irg, co->cenv->cls->name);
+               java_coal_dump(coal, fn);
+       }
+
        java_coal_destroy(coal);
        bitset_free(nodes);
 }
        java_coal_destroy(coal);
        bitset_free(nodes);
 }
index 0bf32f1..55fe514 100644 (file)
@@ -26,6 +26,8 @@
 #include "phiclass.h"
 #include "irbitset.h"
 #include "irphase_t.h"
 #include "phiclass.h"
 #include "irbitset.h"
 #include "irphase_t.h"
+#include "irprintf_t.h"
+
 
 #include "bearch.h"
 #include "benode_t.h"
 
 #include "bearch.h"
 #include "benode_t.h"
@@ -1064,6 +1066,132 @@ void co_dump_appel_graph_cliques(const copy_opt_t *co, FILE *f)
        obstack_free(&env.obst, NULL);
 }
 
        obstack_free(&env.obst, NULL);
 }
 
+/*
+___ _____ ____   ____   ___ _____   ____                        _
+|_ _|  ___/ ___| |  _ \ / _ \_   _| |  _ \ _   _ _ __ ___  _ __ (_)_ __   __ _
+| || |_ | |  _  | | | | | | || |   | | | | | | | '_ ` _ \| '_ \| | '_ \ / _` |
+| ||  _|| |_| | | |_| | |_| || |   | |_| | |_| | | | | | | |_) | | | | | (_| |
+|___|_|   \____| |____/ \___/ |_|   |____/ \__,_|_| |_| |_| .__/|_|_| |_|\__, |
+|_|            |___/
+*/
+
+static const char *get_dot_color_name(int col)
+{
+       static const char *names[] = {
+               "blue",
+               "red",
+               "green",
+               "yellow",
+               "cyan",
+               "magenta",
+               "orange",
+               "chocolate",
+               "beige",
+               "navy",
+               "darkgreen",
+               "darkred",
+               "lightPink",
+               "chartreuse",
+               "lightskyblue",
+               "linen",
+               "pink",
+               "lightslateblue",
+               "mintcream",
+               "red",
+               "darkolivegreen",
+               "mediumblue",
+               "mistyrose",
+               "salmon",
+               "darkseagreen",
+               "mediumslateblue"
+               "moccasin",
+               "tomato",
+               "forestgreen",
+               "darkturquoise",
+               "palevioletred"
+       };
+
+       return col < sizeof(names)/sizeof(names[0]) ? names[col] : "white";
+}
+
+typedef struct _co_ifg_dump_t {
+       const copy_opt_t *co;
+       unsigned flags;
+} co_ifg_dump_t;
+
+static const char *get_dot_shape_name(co_ifg_dump_t *cod, ir_node *irn)
+{
+       arch_register_req_t req;
+
+       arch_get_register_req(cod->co->aenv, &req, irn, BE_OUT_POS(0));
+       if(arch_register_req_is(&req, limited))
+               return "diamond";
+
+       return "ellipse";
+}
+
+static void ifg_dump_graph_attr(FILE *f, void *self)
+{
+       fprintf(f, "overlay=false");
+}
+
+static int ifg_is_dump_node(void *self, ir_node *irn)
+{
+       co_ifg_dump_t *cod = self;
+       return !arch_irn_is(cod->co->aenv, irn, ignore);
+}
+
+static void ifg_dump_node_attr(FILE *f, void *self, ir_node *irn)
+{
+       co_ifg_dump_t *env         = self;
+       const arch_register_t *reg = arch_get_irn_register(env->co->aenv, irn);
+
+       ir_fprintf(f, "label=\"%+F\" style=filled color=%s shape=%s", irn, get_dot_color_name(reg->index), get_dot_shape_name(env, irn));
+}
+
+static void ifg_dump_at_end(FILE *file, void *self)
+{
+       co_ifg_dump_t *env = self;
+       affinity_node_t *a;
+
+       co_gs_foreach_aff_node(env->co, a) {
+               const arch_register_t *ar = arch_get_irn_register(env->co->aenv, a->irn);
+               unsigned aidx = get_irn_idx(a->irn);
+               neighb_t *n;
+
+               co_gs_foreach_neighb(a, n) {
+                       const arch_register_t *nr = arch_get_irn_register(env->co->aenv, n->irn);
+                       int nidx = get_irn_idx(n->irn);
+
+                       if(aidx < nidx) {
+                               const char *color = nr == ar ? "blue" : "red";
+                               fprintf(file, "\tn%d -- n%d [label=\"%d\" style=dashed color=%s];\n", aidx, nidx, n->costs, color);
+                       }
+               }
+       }
+}
+
+
+static be_ifg_dump_dot_cb_t ifg_dot_cb = {
+       ifg_is_dump_node,
+       ifg_dump_graph_attr,
+       ifg_dump_node_attr,
+       NULL,
+       NULL,
+       ifg_dump_at_end
+};
+
+
+
+void co_dump_ifg_dot(const copy_opt_t *co, FILE *f, unsigned flags)
+{
+       co_ifg_dump_t cod;
+
+       cod.co    = co;
+       cod.flags = flags;
+       be_ifg_dump_dot(co->cenv->ifg, co->irg, f, &ifg_dot_cb, &cod);
+}
+
 
 void co_solve_park_moon(copy_opt_t *opt)
 {
 
 void co_solve_park_moon(copy_opt_t *opt)
 {
index e7ff65a..eea0819 100644 (file)
@@ -159,6 +159,16 @@ void co_dump_appel_graph(const copy_opt_t *co, FILE *f);
  */
 void co_dump_appel_graph_cliques(const copy_opt_t *co, FILE *f);
 
  */
 void co_dump_appel_graph_cliques(const copy_opt_t *co, FILE *f);
 
+enum {
+       CO_IFG_DUMP_COLORS = 1,
+       CO_IFG_DUMP_LABELS = 2
+};
+
+/**
+ * Dump the interference graph with the affinity edges and the coloring.
+ */
+void co_dump_ifg_dot(const copy_opt_t *co, FILE *f, unsigned flags);
+
 /**
  * Constructs another internal representation of the affinity edges
  */
 /**
  * Constructs another internal representation of the affinity edges
  */
index d367590..bd5d67c 100644 (file)
@@ -15,6 +15,7 @@
 #endif
 
 
 #endif
 
 
+#include <signal.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <stdio.h>
@@ -153,11 +154,28 @@ static void stop_vm(jni_env_t *env)
 
 static int jvm_inited = 0;
 static jni_env_t env;
 
 static int jvm_inited = 0;
 static jni_env_t env;
+void (*old_int_handler)(int);
+void (*old_abrt_handler)(int);
 
 
-static void jvm_destroy_at_exit(void)
+static void sig_jvm_destroy_at_exit(int signal)
 {
        if(jvm_inited)
                stop_vm(&env);
 {
        if(jvm_inited)
                stop_vm(&env);
+
+       switch(signal) {
+       case SIGABRT:
+               old_abrt_handler(signal);
+               break;
+       case SIGINT:
+               old_int_handler(signal);
+               break;
+       default:;
+       }
+}
+
+static void jvm_destroy_at_exit(void)
+{
+       sig_jvm_destroy_at_exit(0);
 }
 
 static jni_env_t *get_jvm(void)
 }
 
 static jni_env_t *get_jvm(void)
@@ -178,6 +196,8 @@ static jni_env_t *get_jvm(void)
                args[0] = cp_param;
                start_vm(&env, sizeof(args) / sizeof(args[0]), args);
                jvm_inited = 1;
                args[0] = cp_param;
                start_vm(&env, sizeof(args) / sizeof(args[0]), args);
                jvm_inited = 1;
+               old_int_handler  = signal(SIGINT,  sig_jvm_destroy_at_exit);
+               old_abrt_handler = signal(SIGABRT, sig_jvm_destroy_at_exit);
                atexit(jvm_destroy_at_exit);
        }
 
                atexit(jvm_destroy_at_exit);
        }
 
index 5a66463..fddbcdb 100644 (file)
@@ -68,6 +68,13 @@ void be_liveness_remove(be_lv_t *lv, ir_node *irn);
  */
 void be_liveness_introduce(be_lv_t *lv, ir_node *irn);
 
  */
 void be_liveness_introduce(be_lv_t *lv, ir_node *irn);
 
+/**
+ * Add all nodes which are missing in the current liveness data.
+ * The liveness data of the already existing nodes (in the liveness data) is not touched.
+ * @param The liveness info.
+ */
+void be_liveness_add_missing(be_lv_t *lv);
+
 /**
  * Dump the liveness information for a graph.
  * @param f The output.
 /**
  * Dump the liveness information for a graph.
  * @param f The output.