Commit d92c4035 authored by Michael Beck's avatar Michael Beck
Browse files

- graph passes can be added to prog managers now

- more passes implemented
- small fixes

[r26356]
parent 8f530048
......@@ -43,4 +43,16 @@
* 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
......@@ -51,6 +51,17 @@
*/
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.
*
......@@ -59,4 +70,15 @@ void construct_confirms(ir_graph *irg);
*/
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
......@@ -175,6 +175,19 @@ int inline_method(ir_node *call, ir_graph *called_graph);
*/
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.
*
......
......@@ -554,6 +554,17 @@ void proc_cloning(float threshold);
*/
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).
......@@ -576,6 +587,17 @@ int optimize_reassociation(ir_graph *irg);
*/
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.
......@@ -598,6 +620,17 @@ void normalize_one_return(ir_graph *irg);
*/
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)
......@@ -609,6 +642,17 @@ void normalize_n_returns(ir_graph *irg);
*/
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);
......@@ -630,6 +674,17 @@ 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:
......@@ -643,6 +698,17 @@ int opt_tail_rec_irg(ir_graph *irg);
*/
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);
......@@ -674,7 +740,6 @@ 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.
*
......@@ -684,7 +749,6 @@ void normalize_irp_class_casts(gen_pointer_type_to_func gppt_fct);
*/
void normalize_irg_class_casts(ir_graph *irg, gen_pointer_type_to_func gppt_fct);
/** Optimize casting between class types.
*
* class A { m(); }
......
......@@ -93,6 +93,15 @@ void ir_prog_pass_mgr_add(ir_prog_pass_manager_t *mgr, ir_prog_pass_t *pass);
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.
*
......
......@@ -228,12 +228,21 @@ void lower_highlevel(int lower_bitfields);
*/
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;
......
......@@ -600,6 +600,11 @@ void construct_confirms(ir_graph *irg) {
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
......@@ -631,3 +636,8 @@ void remove_confirms(ir_graph *irg) {
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 */
......@@ -170,11 +170,11 @@ void firm_pset_dump(pset *set) {
/**
* 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(
......@@ -183,8 +183,8 @@ 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;
......@@ -198,10 +198,10 @@ ir_graph_pass_t *def_graph_pass(
/**
* 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(
......@@ -210,8 +210,8 @@ 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;
......@@ -221,3 +221,33 @@ ir_graph_pass_t *def_graph_pass_ret(
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 */
......@@ -110,10 +110,10 @@ ir_node *exact_copy(const ir_node *n);
* 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
*/
......@@ -126,10 +126,10 @@ ir_graph_pass_t *def_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
*/
......@@ -137,4 +137,20 @@ ir_graph_pass_t *def_graph_pass_ret(
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
......@@ -84,10 +84,21 @@ static void no_dump(ir_prog *prog, void *ctx, unsigned idx)
(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;
......@@ -99,9 +110,45 @@ void ir_prog_pass_mgr_add_graph_mgr(
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;
......@@ -172,7 +219,7 @@ static int irp_verify_irgs(ir_prog *irp, int flags) {
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;
......@@ -202,7 +249,11 @@ int ir_prog_pass_mgr_run(ir_prog_pass_manager_t *mgr)
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;
}
......@@ -237,7 +288,7 @@ ir_prog_pass_manager_t *new_prog_pass_mgr(
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;
......
......@@ -111,6 +111,7 @@ struct ir_prog_pass_t {
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. */
};
/**
......
......@@ -583,6 +583,10 @@ void lower_const_code(void) {
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.
......
......@@ -31,6 +31,7 @@
#include "irnode_t.h"
#include "irouts.h"
#include "irgopt.h"
#include "irtools.h"
/**
* Returns non-zero, is a block is not reachable from Start.
......@@ -537,3 +538,17 @@ void place_code(ir_graph *irg) {
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);
}
......@@ -1084,8 +1084,10 @@ struct pass_t {
/**
* 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 */
......
......@@ -41,6 +41,7 @@
#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);
......@@ -151,3 +152,27 @@ void gc_irgs(int n_keep, ir_entity ** keep_arr) {
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);
}
......@@ -40,6 +40,7 @@
#include "irloop.h"
#include "pdeq.h"
#include "debug.h"
#include "irtools.h"
//#define NEW_REASSOC
......@@ -932,6 +933,11 @@ int optimize_reassociation(ir_graph *irg)
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)
{
......
......@@ -166,6 +166,12 @@ void normalize_one_return(ir_graph *irg) {
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.
*
......@@ -373,3 +379,9 @@ void normalize_n_returns(ir_graph *irg) {
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);
}
......@@ -771,6 +771,10 @@ int scalar_replacement_opt(ir_graph *irg) {
return res;
}