+/*
+ * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
/**
- * Scheduling algorithms.
+ * @file
+ * @brief ILP based instruction scheduling.
+ * @author Christian Wuerdig
+ * @date 22.10.2006
+ * @version $Id$
+ *
* An ILP scheduler based on
* "ILP-based Instruction Scheduling for IA-64"
* by Daniel Kaestner and Sebastian Winkel
* extended with register pressure constraints by Christian Wuerdig
- *
- * @date 22.10.2005
- * @author Christian Wuerdig
- * @cvs-id $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "debug.h"
#include "irtools.h"
#include "irdump.h"
+#include "irprintf.h"
#include "plist.h"
#include "irprintf.h"
#include "beilpsched.h"
#include "beutil.h"
#include "bestat.h"
+#include "beirg_t.h"
+#include "benodesets.h"
typedef struct _ilpsched_options_t {
unsigned regpress;
/* The ILP scheduling environment */
typedef struct {
- phase_t ph; /**< The phase */
+ ir_phase ph; /**< The phase */
ir_graph *irg; /**< The current irg */
heights_t *height; /**< The heights object of the irg */
void *irg_env; /**< An environment for the irg scheduling, provided by the backend */
LC_OPT_ENT_BOOL("regpress", "Use register pressure constraints", &ilp_opts.regpress),
LC_OPT_ENT_INT("time_limit", "ILP time limit per block", &ilp_opts.time_limit),
LC_OPT_ENT_STR("lpp_log", "LPP logfile (stderr and stdout are supported)", ilp_opts.log_file, sizeof(ilp_opts.log_file)),
- { NULL }
+ LC_OPT_LAST
};
/*
/**
* In case there is no phase information for irn, initialize it.
*/
-static void *init_ilpsched_irn(phase_t *ph, ir_node *irn, void *old) {
+static void *init_ilpsched_irn(ir_phase *ph, ir_node *irn, void *old) {
be_ilpsched_irn_t *res = old ? old : phase_alloc(ph, sizeof(res[0]));
if (res == old) {
unsigned n_consumer = 0;
ir_edge_kind_t ekind[2] = { EDGE_KIND_NORMAL, EDGE_KIND_DEP };
ir_node **consumer;
- int idx;
+ unsigned idx;
if (! consider_for_sched(env->arch_env->isa, irn))
return;
DBG((env->dbg, LEVEL_1, "ILP to solve: %u variables, %u constraints\n", lpp->var_next, lpp->cst_next));
/* debug stuff, dump lpp when debugging is on */
- DEBUG_ONLY(
+ DEBUG_ONLY({
if (firm_dbg_get_mask(env->dbg) > 1) {
char buf[1024];
FILE *f;
snprintf(buf, sizeof(buf), "lpp_block_%lu.mps", get_irn_node_nr(block));
lpp_dump(lpp, buf);
}
- );
+ })
/* set solve time limit */
lpp_set_time_limit(lpp, env->opts->time_limit);
char buf[1024];
FILE *f;
- DEBUG_ONLY(
+ DEBUG_ONLY({
if (firm_dbg_get_mask(env->dbg) >= 2) {
snprintf(buf, sizeof(buf), "lpp_block_%lu.infeasible.txt", get_irn_node_nr(block));
f = fopen(buf, "w");
lpp_dump(lpp, buf);
dump_ir_block_graph(env->irg, "-infeasible");
}
- )
+ })
ir_fprintf(stderr, "ILP found no solution within time (%+F, %+F), falling back to heuristics.\n", block, env->irg);
need_heur = 1;
}
/* apply solution */
-#ifdef FIRM_STATISTICS
- if (be_stat_ev_is_active()) {
- be_stat_ev("nodes", ba->block_last_idx);
- be_stat_ev("vars", lpp ? lpp->var_next : 0);
- be_stat_ev("csts", lpp ? lpp->cst_next : 0);
- }
-#endif /* FIRM_STATISTICS */
+ be_stat_ev("nodes", ba->block_last_idx);
+ be_stat_ev("vars", lpp ? lpp->var_next : 0);
+ be_stat_ev("csts", lpp ? lpp->cst_next : 0);
if (need_heur) {
-#ifdef FIRM_STATISTICS
- if (be_stat_ev_is_active()) {
be_stat_ev("time", -1);
be_stat_ev_dbl("opt", 0.0);
- }
-#endif /* FIRM_STATISTICS */
list_sched_single_block(env->birg, block, env->be_opts);
}
else {
-#ifdef FIRM_STATISTICS
- if (be_stat_ev_is_active()) {
- if (lpp) {
- double opt = lpp->sol_state == lpp_optimal ? 100.0 : 100.0 * lpp->best_bound / lpp->objval;
- be_stat_ev_dbl("time", lpp->sol_time);
- be_stat_ev_dbl("opt", opt);
- }
- else {
- be_stat_ev_dbl("time", 0.0);
- be_stat_ev_dbl("opt", 100.0);
- }
+ if (lpp) {
+ double opt = lpp->sol_state == lpp_optimal ? 100.0 : 100.0 * lpp->best_bound / lpp->objval;
+ be_stat_ev_dbl("time", lpp->sol_time);
+ be_stat_ev_dbl("opt", opt);
+ }
+ else {
+ be_stat_ev_dbl("time", 0.0);
+ be_stat_ev_dbl("opt", 100.0);
}
-#endif /* FIRM_STATISTICS */
apply_solution(env, lpp, block);
}
*/
void be_ilp_sched(const be_irg_t *birg, be_options_t *be_opts) {
be_ilpsched_env_t env;
- const char *name = "be ilp scheduling";
- arch_isa_t *isa = birg->main_env->arch_env->isa;
- const ilp_sched_selector_t *sel = isa->impl->get_ilp_sched_selector(isa);
+ const char *name = "be ilp scheduling";
+ ir_graph *irg = be_get_birg_irg(birg);
+ const arch_env_t *arch_env = be_get_birg_arch_env(birg);
+ const arch_isa_t *isa = arch_env->isa;
+ const ilp_sched_selector_t *sel = isa->impl->get_ilp_sched_selector(isa);
FIRM_DBG_REGISTER(env.dbg, "firm.be.sched.ilp");
-#ifdef FIRM_STATISTICS
- if (be_stat_ev_is_active()) {
- be_stat_tags[STAT_TAG_CLS] = "ilpsched";
- be_stat_ev_push(be_stat_tags, STAT_TAG_LAST, be_stat_file);
- }
-#endif /* FIRM_STATISTICS */
+ stat_ev_ctx_push("phase", "ilpsched");
// firm_dbg_set_mask(env.dbg, 1);
- env.irg_env = be_ilp_sched_init_irg_ilp_schedule(sel, birg->irg);
+ env.irg_env = be_ilp_sched_init_irg_ilp_schedule(sel, irg);
env.sel = sel;
- env.irg = birg->irg;
- env.height = heights_new(birg->irg);
+ env.irg = irg;
+ env.height = heights_new(irg);
env.main_env = birg->main_env;
- env.arch_env = birg->main_env->arch_env;
- env.cpu = arch_isa_get_machine(birg->main_env->arch_env->isa);
+ env.arch_env = arch_env;
+ env.cpu = arch_isa_get_machine(arch_env->isa);
env.opts = &ilp_opts;
env.birg = birg;
env.be_opts = be_opts;
- phase_init(&env.ph, name, env.irg, PHASE_DEFAULT_GROWTH, init_ilpsched_irn);
+ phase_init(&env.ph, name, env.irg, PHASE_DEFAULT_GROWTH, init_ilpsched_irn, NULL);
/* assign a unique per block number to all interesting nodes */
irg_walk_in_or_dep_graph(env.irg, NULL, build_block_idx, &env);
/* notify backend */
be_ilp_sched_finish_irg_ilp_schedule(sel, birg->irg, env.irg_env);
-#ifdef FIRM_STATISTICS
- if (be_stat_ev_is_active()) {
- be_stat_ev_pop();
- }
-#endif /* FIRM_STATISTICS */
+ stat_ev_ctx_pop();
}
/**