* Frees all interprocedural loop information. */
void gc_irgs(int n_keep, ir_entity *keep_arr[]);
+/**
+ * Creates an ir_prog pass for gc_irgs().
+ *
+ * @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 params The parameters for the if conversion.
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_prog_pass_t *gc_irgs_pass(const char *name, int verify, int dump);
+
#endif
*/
void construct_confirms(ir_graph *irg);
+/**
+ * Creates an ir_graph pass for construct_confirms().
+ *
+ * @param name the name of this pass or NULL
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_graph_pass_t *construct_confirms_pass(const char *name, int verify, int dump);
+
/**
* Remove all Confirm nodes from a graph.
*
*/
void remove_confirms(ir_graph *irg);
+/**
+ * Creates an ir_graph pass for remove_confirms().
+ *
+ * @param name the name of this pass or NULL
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_graph_pass_t *remove_confirms_pass(const char *name, int verify, int dump);
+
#endif
*/
void place_code(ir_graph *irg);
+/**
+ * Creates an ir_graph pass for place_code().
+ * This pass enables GCSE, runs optimize_graph_df() and finally
+ * place_code();
+ *
+ * @param name the name of this pass or NULL
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_graph_pass_t *place_code_pass(const char *name, int verify, int dump);
+
/** Places an empty basic block on critical control flow edges thereby
* removing them.
*
*/
int optimize_reassociation(ir_graph *irg);
+/**
+ * Creates an ir_graph pass for optimize_reassociation().
+ *
+ * @param name the name of this pass or NULL
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_graph_pass_t *optimize_reassociation_pass(const char *name, int verify, int dump);
+
/**
* Normalize the Returns of a graph by creating a new End block
* with One Return(Phi).
*/
void normalize_one_return(ir_graph *irg);
+/**
+ * Creates an ir_graph pass for normalize_one_return().
+ *
+ * @param name the name of this pass or NULL
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_graph_pass_t *normalize_one_return_pass(const char *name, int verify, int dump);
+
/**
* Normalize the Returns of a graph by moving
* the Returns upwards as much as possible.
*/
void normalize_n_returns(ir_graph *irg);
+/**
+ * Creates an ir_graph pass for normalize_n_returns().
+ *
+ * @param name the name of this pass or NULL
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_graph_pass_t *normalize_n_returns_pass(const char *name, int verify, int dump);
+
/**
* Do the scalar replacement optimization.
* Replace local compound entities (like structures and arrays)
*/
int scalar_replacement_opt(ir_graph *irg);
+/**
+ * Creates an ir_graph pass for scalar_replacement_opt().
+ *
+ * @param name the name of this pass or NULL
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_graph_pass_t *scalar_replacement_opt_pass(const char *name, int verify, int dump);
+
/** Performs strength reduction for the passed graph. */
void reduce_strength(ir_graph *irg);
*/
int opt_tail_rec_irg(ir_graph *irg);
+/**
+ * Creates an ir_graph pass for opt_tail_rec_irg().
+ *
+ * @param name the name of this pass or NULL
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_graph_pass_t *opt_tail_rec_irg_pass(const char *name, int verify, int dump);
+
/**
* Optimize tail-recursion calls for all IR-Graphs.
* Can currently handle:
*/
void opt_tail_recursion(void);
+/**
+ * Creates an ir_prog pass for opt_tail_recursion().
+ *
+ * @param name the name of this pass or NULL
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ *
+ * @return the newly created ir_prog pass
+ */
+ir_prog_pass_t *opt_tail_recursion_pass(const char *name, int verify, int dump);
+
/** This is the type for a method, that returns a pointer type to
* tp. This is needed in the normalization. */
typedef ir_type *(*gen_pointer_type_to_func)(ir_type *tp);
*/
void normalize_irp_class_casts(gen_pointer_type_to_func gppt_fct);
-
/** Insert Casts so that class type casts conform exactly with the type hierarchy
* in given graph.
*
*/
void normalize_irg_class_casts(ir_graph *irg, gen_pointer_type_to_func gppt_fct);
-
/** Optimize casting between class types.
*
* class A { m(); }
void ir_prog_pass_mgr_add_graph_mgr(
ir_prog_pass_manager_t *mgr, ir_graph_pass_manager_t *graph_mgr);
+/**
+ * Add an ir_graph_pass as a pass to an ir_prog pass manager.
+ *
+ * @param mgr the ir_prog pass manager
+ * @param pass the ir_graph pass to be added
+ */
+void ir_prog_pass_mgr_add_graph_pass(
+ ir_prog_pass_manager_t *mgr, ir_graph_pass_t *pass);
+
/**
* Run all passes of an ir_prog pass manager.
*
*/
void lower_const_code(void);
+/**
+ * Creates an ir_prog pass for lower_const_code().
+ *
+ * @param name the name of this pass or NULL
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_prog_pass_t *lower_const_code_pass(const char *name);
+
typedef struct lower_mode_b_config_t {
/* mode that is used to transport 0/1 values */
ir_mode *lowered_mode;
/* preferred mode for the "set" operations (a psi that produces a 0 or 1) */
ir_mode *lowered_set_mode;
- /* wether direct Cond -> Cmps should also be lowered */
+ /* whether direct Cond -> Cmps should also be lowered */
int lower_direct_cmp;
} lower_mode_b_config_t;
edges_deactivate(irg);
} /* construct_confirms */
+/* Construct a pass. */
+ir_graph_pass_t *construct_confirms_pass(const char *name, int verify, int dump) {
+ return def_graph_pass(name ? name : "confirm", verify, dump, construct_confirms);
+} /* construct_confirms_pass */
+
#if 0
/**
* Post-walker: Remove Confirm nodes
optimize_graph_df(irg);
set_opt_remove_confirm(rem);
} /* remove_confirms */
+
+/* Construct a pass. */
+ir_graph_pass_t *remove_confirms_pass(const char *name, int verify, int dump) {
+ return def_graph_pass(name ? name : "rem_confirm", verify, dump, remove_confirms);
+} /* remove_confirms_pass */
/**
* Wrapper for running void function(ir_graph *irg) as an ir_graph pass.
*/
-static int void_pass_wrapper(ir_graph *irg, void *context) {
+static int void_graph_wrapper(ir_graph *irg, void *context) {
void (*function)(ir_graph *irg) = context;
function(irg);
return 0;
-} /* void_pass_wrapper */
+} /* void_graph_wrapper */
/* Creates an ir_graph pass for running void function(ir_graph *irg). */
ir_graph_pass_t *def_graph_pass(
{
struct ir_graph_pass_t *pass = XMALLOCZ(ir_graph_pass_t);
- pass->kind = k_ir_prog_pass;
- pass->run_on_irg = void_pass_wrapper;
+ pass->kind = k_ir_graph_pass;
+ pass->run_on_irg = void_graph_wrapper;
pass->context = function;
pass->name = name;
pass->verify = verify != 0;
/**
* Wrapper for running void function(ir_graph *irg) as an ir_graph pass.
*/
-static int int_pass_wrapper(ir_graph *irg, void *context) {
+static int int_graph_wrapper(ir_graph *irg, void *context) {
int (*function)(ir_graph *irg) = context;
return function(irg);
-} /* int_pass_wrapper */
+} /* int_graph_wrapper */
/* Creates an ir_graph pass for running void function(ir_graph *irg). */
ir_graph_pass_t *def_graph_pass_ret(
{
struct ir_graph_pass_t *pass = XMALLOCZ(ir_graph_pass_t);
- pass->kind = k_ir_prog_pass;
- pass->run_on_irg = int_pass_wrapper;
+ pass->kind = k_ir_graph_pass;
+ pass->run_on_irg = int_graph_wrapper;
pass->context = function;
pass->name = name;
pass->verify = verify != 0;
return pass;
} /* def_graph_pass_ret */
+
+/**
+ * Wrapper for running void function(void) as an ir_prog pass.
+ */
+static int void_prog_wrapper(ir_prog *irp, void *context) {
+ void (*function)(void) = context;
+
+ (void)irp;
+ function();
+ return 0;
+} /* void_graph_wrapper */
+
+/* Creates an ir_prog pass for running void function(void). */
+ir_prog_pass_t *def_prog_pass(
+ const char *name, int verify, int dump,
+ void (*function)(void))
+{
+ struct ir_prog_pass_t *pass = XMALLOCZ(ir_prog_pass_t);
+
+ pass->kind = k_ir_prog_pass;
+ pass->run_on_irprog = void_prog_wrapper;
+ pass->context = function;
+ pass->name = name;
+ pass->verify = verify != 0;
+ pass->dump = dump != 0;
+
+ INIT_LIST_HEAD(&pass->list);
+
+ return pass;
+} /* def_prog_pass */
* Uses the default verifier and dumper.
* The pass returns always 0.
*
- * @param name the name of this pass
- * @param verify should this pass be verified?
- * @param dump should this pass result be dumped?
- * @param params The parameters for the if conversion.
+ * @param name the name of this pass
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ * @param function the function to run
*
* @return the newly created ir_graph pass
*/
* Uses the default verifier and dumper.
* The pass returns the return value of function.
*
- * @param name the name of this pass
- * @param verify should this pass be verified?
- * @param dump should this pass result be dumped?
- * @param params The parameters for the if conversion.
+ * @param name the name of this pass
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ * @param function the function to run
*
* @return the newly created ir_graph pass
*/
const char *name, int verify, int dump,
int (*function)(ir_graph *irg));
+/**
+ * Creates an ir_prog pass for running void function().
+ * Uses the default verifier and dumper.
+ * The pass returns always 0.
+ *
+ * @param name the name of this pass
+ * @param verify should this pass be verified?
+ * @param dump should this pass result be dumped?
+ * @param function the function to run
+ *
+ * @return the newly created ir_graph pass
+ */
+ir_prog_pass_t *def_prog_pass(
+ const char *name, int verify, int dump,
+ void (*function)(void));
+
#endif
(void)idx;
}
-/* Add an ir_graph_pass_manager as a pass to an irprog pass manager. */
-void ir_prog_pass_mgr_add_graph_mgr(
- ir_prog_pass_manager_t *mgr, ir_graph_pass_manager_t *graph_mgr)
+/**
+ * Term warpper for a wrapped ir_graph pass manager.
+ */
+static void term_wrapper(void *context)
{
+ ir_graph_pass_manager_t *mgr = context;
+ term_graph_pass_mgr(mgr);
+}
+
+/**
+ * Create a wrapper ir_prog pass for an ir_graph manager.
+ */
+static ir_prog_pass_t *create_wrapper_pass(ir_graph_pass_manager_t *graph_mgr)
+{
+ /* create a wrapper pass */
ir_prog_pass_t *pass = XMALLOCZ(ir_prog_pass_t);
pass->run_on_irprog = run_wrapper;
pass->dump_irprog = no_dump;
pass->dump = 0;
pass->verify = 0;
+ pass->is_wrapper = 1;
pass->add_to_mgr = NULL;
- pass->rem_from_mgr = NULL;
+ pass->rem_from_mgr = term_wrapper;
+
+ return pass;
+}
+
+/* Add an ir_graph_pass as a pass to an ir_prog pass manager. */
+void ir_prog_pass_mgr_add_graph_pass(
+ ir_prog_pass_manager_t *mgr, ir_graph_pass_t *pass)
+{
+ ir_graph_pass_manager_t *graph_mgr;
+ ir_prog_pass_t *wrapper;
+
+ /* check if the last pass is a graph_pass wrapper */
+ if (! list_empty(&mgr->passes)) {
+ wrapper = list_entry(mgr->passes.prev, ir_prog_pass_t, list);
+ if (wrapper->is_wrapper) {
+ graph_mgr = wrapper->context;
+
+ ir_graph_pass_mgr_add(graph_mgr, pass);
+ return;
+ }
+ }
+
+ /* not found, create a new wrapper */
+ graph_mgr = new_graph_pass_mgr("wrapper", mgr->verify_all, mgr->dump_all);
+ ir_graph_pass_mgr_add(graph_mgr, pass);
+
+ wrapper = create_wrapper_pass(graph_mgr);
+ ir_prog_pass_mgr_add(mgr, wrapper);
+}
+
+/* Add an ir_graph_pass_manager as a pass to an ir_prog pass manager. */
+void ir_prog_pass_mgr_add_graph_mgr(
+ ir_prog_pass_manager_t *mgr, ir_graph_pass_manager_t *graph_mgr)
+{
+ ir_prog_pass_t *pass = create_wrapper_pass(graph_mgr);
if (mgr->dump_all)
graph_mgr->dump_all = 1;
return res;
}
-/* Run all passes of an irprog pass manager. */
+/* Run all passes of an ir_prog pass manager. */
int ir_prog_pass_mgr_run(ir_prog_pass_manager_t *mgr)
{
ir_prog_pass_t *pass;
dump_all_ir_graphs(dump_ir_block_graph, suffix);
}
}
- ++idx;
+ if (pass->is_wrapper) {
+ ir_graph_pass_manager_t *graph_mgr = pass->context;
+ idx += graph_mgr->n_passes;
+ } else
+ ++idx;
}
return res;
}
return res;
}
-/* Terminate a graph pass manager and all owned passes. */
+/* Terminate an ir_graph pass manager and all owned passes. */
void term_graph_pass_mgr(ir_graph_pass_manager_t *mgr)
{
ir_graph_pass_t *pass, *next;
unsigned verify:1; /**< Set if this pass should be verified. */
unsigned dump:1; /**< Set if this pass should be dumped. */
+ unsigned is_wrapper:1; /**< set if this is a wrapper pass. */
};
/**
walk_const_code(NULL, lower_irnode, NULL);
} /* lower_const_code */
+ir_prog_pass_t *lower_const_code_pass(const char *name) {
+ return def_prog_pass(name ? name : "lower_const_code", 0, 0, lower_const_code);
+}
+
/*
* Replaces SymConsts by a real constant if possible.
* Replace Sel nodes by address computation. Also resolves array access.
#include "irnode_t.h"
#include "irouts.h"
#include "irgopt.h"
+#include "irtools.h"
/**
* Returns non-zero, is a block is not reachable from Start.
del_waitq(worklist);
current_ir_graph = rem;
}
+
+/**
+ * Wrapper for place_code() inside the place_code pass.
+ */
+static void place_code_wrapper(ir_graph *irg) {
+ set_opt_global_cse(1);
+ optimize_graph_df(irg);
+ place_code(irg);
+ set_opt_global_cse(0);
+}
+
+ir_graph_pass_t *place_code_pass(const char *name, int verify, int dump) {
+ return def_graph_pass(name ? name : "place", verify, dump, place_code_wrapper);
+}
/**
* Wrapper for running optimize_funccalls() as an ir_prog pass.
*/
-static int pass_wrapper(ir_graph *irg, void *context) {
+static int pass_wrapper(ir_prog *irp, void *context) {
struct pass_t *pass = context;
+
+ (void)irp;
optimize_funccalls(pass->force_run, pass->callback);
return 0;
} /* pass_wrapper */
#include "irloop_t.h"
#include "irflag_t.h"
#include "ircons.h"
+#include "cgana.h"
#include "irtools.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg);
set_entity_link(ent, NULL);
}
}
+
+/**
+ * Wrapper for running gc_irgs() as an ir_prog pass.
+ */
+static void pass_wrapper(void)
+{
+ ir_entity **keep_methods;
+ int arr_len;
+
+ /* Analysis that finds the free methods,
+ i.e. methods that are dereferenced.
+ Optimizes polymorphic calls :-). */
+ cgana(&arr_len, &keep_methods);
+
+ /* Remove methods that are never called. */
+ gc_irgs(arr_len, keep_methods);
+
+ free(keep_methods);
+}
+
+ir_prog_pass_t *gc_irgs_pass(const char *name, int verify, int dump)
+{
+ return def_prog_pass(name ? name : "cgana", verify, dump, pass_wrapper);
+}
#include "irloop.h"
#include "pdeq.h"
#include "debug.h"
+#include "irtools.h"
//#define NEW_REASSOC
return env.changes;
} /* optimize_reassociation */
+/* create a pass for the reassociation */
+ir_graph_pass_t *optimize_reassociation_pass(const char *name, int verify, int dump) {
+ return def_graph_pass_ret(name ? name : "reassoc", verify, dump, optimize_reassociation);
+} /* optimize_reassociation_pass */
+
/* Sets the default reassociation operation for an ir_op_ops. */
ir_op_ops *firm_set_default_reassoc(ir_opcode code, ir_op_ops *ops)
{
set_irg_loopinfo_inconsistent(irg);
}
+/* Create a graph pass. */
+ir_graph_pass_t *normalize_one_return_pass(const char *name, int verify, int dump)
+{
+ return def_graph_pass(name ? name : "one_ret", verify, dump, normalize_one_return);
+}
+
/**
* Check, whether a Return can be moved on block upwards.
*
set_irg_outs_inconsistent(irg);
set_irg_loopinfo_inconsistent(current_ir_graph);
}
+
+/* Create a graph pass. */
+ir_graph_pass_t *normalize_n_returns_pass(const char *name, int verify, int dump)
+{
+ return def_graph_pass(name ? name : "n_rets", verify, dump, normalize_n_returns);
+}
return res;
}
+ir_graph_pass_t *scalar_replacement_opt_pass(const char *name, int verify, int dump) {
+ return def_graph_pass(name ? name : "scalar_rep", verify, dump, scalar_replacement_opt);
+}
+
void firm_init_scalar_replace(void) {
FIRM_DBG_REGISTER(dbg, "firm.opt.scalar_replace");
}
#include "irouts.h"
#include "irhooks.h"
#include "ircons_t.h"
+#include "irtools.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg);
return n_tail_calls;
}
+ir_graph_pass_t *opt_tail_rec_irg_pass(const char *name, int verify, int dump)
+{
+ return def_graph_pass_ret(name ? name : "tailrec", verify, dump, opt_tail_rec_irg);
+}
+
/*
* optimize tail recursion away
*/
DB((dbg, LEVEL_1, "Performed tail recursion for %d of %d graphs\n",
n_opt_applications, get_irp_n_irgs()));
}
+
+ir_prog_pass_t *opt_tail_recursion_pass(const char *name, int verify, int dump)
+{
+ return def_prog_pass(name ? name : "tailrec", verify, dump, opt_tail_recursion);
+}