#include <stdlib.h>
+#include "bitset.h"
#include "debug.h"
#include "bechordal.h"
#include "bephicongr_t.h"
#include "bephicoal_t.h"
-
-static firm_dbg_module_t *dbgmod = NULL;
-
+static firm_dbg_module_t *dbgphi = NULL;
void be_phi_coal_init(void) {
- dbgmod = firm_dbg_register("Phi coalescing");
- firm_dbg_set_mask(dbgmod, 1);
- DBG((dbgmod, 1, "Phi coalescing dbg enabled"));
+ dbgphi = firm_dbg_register("Phi coalescing");
+ firm_dbg_set_mask(dbgphi, 1);
}
// members = pset_to_array(phi_class);
/* how many phi nodes are in this class? */
- DBG((dbgmod, 1, "Checking phi count\n"));
+ DBG((dbgphi, 1, "Checking phi count\n"));
phi_count = 0;
for (n = (ir_node *)pset_first(pc); n; n = (ir_node *)pset_next(pc)) {
if (is_Phi(n)) {
}
if (phi_count > 1) {
- DBG((dbgmod, 1, "Dropped: Too many phis\n"));
+ DBG((dbgphi, 1, "Dropped: Too many phis\n"));
goto exit;
}
assert(phi_count == 1 && phi);
/* where is the definition of the arguments? */
- DBG((dbgmod, 1, "Checking arg def\n"));
+ DBG((dbgphi, 1, "Checking arg def\n"));
arity = get_irn_arity(phi);
for (i = 0; i < arity; ++i) {
ir_node *block_of_arg, *block_ith_pred;
ir_node *arg = get_irn_n(phi, i);
- /* TODO: check next few lines after const node copy placement */
-// if (iro_Const == get_irn_opcode(arg) && CONSTS_SPLIT_PHI_CLASSES)
-// continue;
-
block_of_arg = get_nodes_block(arg);
block_ith_pred = get_nodes_block(get_irn_n(get_nodes_block(phi), i));
if (block_of_arg != block_ith_pred) {
- DBG((dbgmod, 1, "Dropped: Arg-def not in pred-block\n"));
+ DBG((dbgphi, 1, "Dropped: Arg-def not in pred-block\n"));
goto exit;
}
}
/* determine a greedy set of non-interfering members
* crucial: starting with the phi node
*/
- DBG((dbgmod, 1, "Building greedy non-interfering set\n"));
+ DBG((dbgphi, 1, "Building greedy non-interfering set\n"));
intffree = pset_new_ptr(4);
pset_remove_ptr(pc, phi);
pset_insert_ptr(intffree, phi);
while (m = (ir_node *)pset_first(pc), m) {
- DBG((dbgmod, 1, "Checking %n\n", m));
+ DBG((dbgphi, 1, "Checking %n\n", m));
pset_break(pc);
pset_remove_ptr(pc, m);
intf_det = 0;
for (n = (ir_node *)pset_first(intffree); n; n = (ir_node *)pset_next(intffree)) {
- DBG((dbgmod, 1, "\t%n", n));
+ DBG((dbgphi, 1, "\t%n", n));
if (phi_ops_interfere(m, n)) {
- DBG((dbgmod, 1, "\tinterf\n"));
+ DBG((dbgphi, 1, "\tinterf\n"));
intf_det = 1;
} else {
- DBG((dbgmod, 1, "\tclean\n"));
+ DBG((dbgphi, 1, "\tclean\n"));
}
}
if (!intf_det) {
- DBG((dbgmod, 1, "Added to set\n"));
+ DBG((dbgphi, 1, "Added to set\n"));
pset_insert_ptr(intffree, m);
}
}
/*
* color the non interfering set
*/
- DBG((dbgmod, 1, "Coloring...\n"));
+ DBG((dbgphi, 1, "Coloring...\n"));
phi_col = get_irn_color(phi);
- DBG((dbgmod, 1, "phi-color: %d\n", grnfxt));
+ DBG((dbgphi, 1, "phi-color: %d\n", phi_col));
/* check if phi color is free in blocks of all members */
allfree = 1;
for (n = (ir_node *)pset_first(intffree); n; n = (ir_node *)pset_next(intffree)) {
ir_node *block;
+ bitset_t *used_colors;
+
if (n == phi)
continue;
block = get_nodes_block(n);
-/* TODO
- if (! COLORFREE(block, phi_col)) {
+
+ used_colors = get_ra_block_info(block)->used_colors;
+
+ if (bitset_is_set(used_colors, phi_col)) {
allfree = 0;
break;
}
-*/
}
-/*
+
if (allfree) {
for (n = (ir_node *)pset_first(intffree); n; n = (ir_node *)pset_next(intffree))
set_irn_color(n, phi_col);
+ printf("KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK\n");
} else {
}
-*/
exit:
del_pset(pc);
}
-void be_phi_coalesce_locals(pset *all_phi_classes, dominfo_t *dominfo) {
+void be_phi_coalesce(pset *all_phi_classes, dominfo_t *dominfo) {
pset *phi_class;
for (phi_class = (pset *)pset_first(all_phi_classes); phi_class; phi_class = (pset *)pset_next(all_phi_classes))
#include "domtree.h"
void be_phi_coal_init(void);
-void be_phi_coalesce_locals(pset *all_phi_classes, dominfo_t *dominfo);
+void be_phi_coalesce(pset *all_phi_classes, dominfo_t *dominfo);
#endif
size_t phi_irn_data_offset = 0;
-static firm_dbg_module_t *dbgmod = NULL;
+static firm_dbg_module_t *dbgphi = NULL;
void be_phi_congr_class_init(void) {
- dbgmod = firm_dbg_register("Phi congruence classes");
- firm_dbg_set_mask(dbgmod, 1);
+ dbgphi = firm_dbg_register("Phi classes");
+ firm_dbg_set_mask(dbgphi, 1);
phi_irn_data_offset = register_additional_node_data(sizeof(phi_info_t));
}
* @param arg Node which gets assigned to the class
*/
static INLINE void phi_class_insert(pset *class, ir_node *phi, ir_node *member) {
- DBG((dbgmod, 1, "\tinsert %n in %n\n", member, phi));
+ DBG((dbgphi, 1, "\tinsert %n in %n\n", member, phi));
if (!(is_Const(member) && CONSTS_SPLIT_PHI_CLASSES))
set_phi(member, phi);
pset_insert_ptr(class, member);
pset *src, *tgt;
assert(is_Phi(n) && is_Phi(new_tgt) && "These must be phi nodes.");
- DBG((dbgmod, 1, "\tcorrect %n\n", n));
+ DBG((dbgphi, 1, "\tcorrect %n\n", n));
/* copy all class members from n to new_tgt. Duplicates eliminated by pset */
src = get_phi_class(n);
pset *pc;
int i, n;
assert(is_Phi(curr_phi) && "This must be a phi node.");
- DBG((dbgmod, 1, "Det. phi class of %n.\n", curr_phi));
+ DBG((dbgphi, 1, "Det. phi class of %n.\n", curr_phi));
pc = get_phi_class(curr_phi);
if (!pc) {
pc = pset_new_ptr(2);
- set_phi_class(curr_phi, pc);\
+ set_phi_class(curr_phi, pc);
phi_class_insert(pc, curr_phi, curr_phi);
}
ir_node *arg, *phi;
arg = get_irn_n(curr_phi, i);
- DBG((dbgmod, 1, " Arg %n\n", arg));
+ DBG((dbgphi, 1, " Arg %n\n", arg));
phi = get_phi(arg);
if (phi == NULL) { /* Argument is not assigned to another phi class. */
phi_class_union(phi, curr_phi);
}
}
- DBG((dbgmod, 1, "Size now: %d\n", pset_count(get_phi_class(curr_phi))));
+ DBG((dbgphi, 1, "Size now: %d\n", pset_count(get_phi_class(curr_phi))));
}
#ifndef _BEPHICONGR_T_H
#define _BEPHICONGR_T_H
-#include "irnode.h"
#include "pset.h"
-
+#include "irnode.h"
typedef struct _phi_info_t {
ir_node *phi; /* only set in args of phi nodes (which could be a phi itslef). Points to a phi node or NULL */
* A non zero value results in splitting phi congruence
* classes at all const nodes (except they do share
* some non-const nodes too)
- *
- * A non zero value can only be set if copies of const
- * nodes are placed correctly.
*/
-#define CONSTS_SPLIT_PHI_CLASSES 1
+#define CONSTS_SPLIT_PHI_CLASSES 0
#define get_irn_phi_info(irn) get_irn_data(irn, phi_info_t, phi_irn_data_offset)
#define get_phi_class(irn) get_irn_phi_info(irn)->phi_class /* Only for phi nodes */
#define CUMULATIVE_FILE "~/all.phistat"
+static firm_dbg_module_t *dbgphi = NULL;
+
static void phi_node_walker(ir_node *node, void *env) {
if (is_Phi(node) && mode_is_datab(get_irn_mode(node)))
pset_insert_ptr((pset *)env, node);
pset *all_phi_nodes, *all_phi_classes;
char buf[1024];
+
+
/* get all phi nodes */
printf("-----------------------> Collecting phi nodes <-----------------------\n");
all_phi_nodes = pset_new_ptr(64);
void be_phi_opt_init(void) {
+ dbgphi = firm_dbg_register("Phi optimizer");
+ firm_dbg_set_mask(dbgphi, 1);
+
be_phi_congr_class_init();
be_phi_coal_init();
}
#ifndef _BEPHIOPT_H
#define _BEPHIOPT_H
+#include "debug.h"
#include "irgraph.h"
void be_phi_opt_init(void);
for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
ir_node *op = get_irn_n(irn, i);
if(get_irn_opcode(op) == iro_Const) {
+ ir_node *tgt_block, *cnst;
+
+ /* Special treatment for phi nodes, because phi-usage is different */
+ tgt_block = get_nodes_block(irn);
+ if (is_Phi(irn))
+ tgt_block = get_nodes_block(get_irn_n(tgt_block, i));
+
/*
* We have to create the const node by ourselves, since the
* firmcons implementation always places it in the start block.
*/
- ir_node *cnst = new_ir_node(NULL, get_irn_irg(irn),
- get_nodes_block(irn), op_Const, get_irn_mode(op), 0, NULL);
+ cnst = new_ir_node(NULL, get_irn_irg(irn),
+ tgt_block, op_Const, get_irn_mode(op), 0, NULL);
cnst->attr.con.tv = get_Const_tarval(op);
set_irn_n(irn, i, cnst);
}
#include "domtree.h"
+struct _domtree_t {
+ ir_node *block;
+ struct _domtree_t *up, *right, *down;
+};
+
+struct _dominfo_t {
+ domtree_t *root;
+ pmap *b2dom;
+};
+
+
domtree_t *domtree_find(dominfo_t *dom, ir_node *block) {
assert(is_Block(block));
return (domtree_t *)pmap_find(dom->b2dom, block);
#include "irgraph.h"
#include "irnode.h"
-typedef struct _domtree_t {
- ir_node *block;
- struct _domtree_t *up, *right, *down;
-} domtree_t;
-
-typedef struct _dominfo_t {
- domtree_t *root;
- pmap *b2dom;
-} dominfo_t;
+typedef struct _domtree_t domtree_t;
+typedef struct _dominfo_t dominfo_t;
dominfo_t *domtree_create(ir_graph *irg);
domtree_t *domtree_find(dominfo_t *dom, ir_node *block);
int i;
if (! (file = fopen(filename, "wt"))) {
- //TODO DBG((dbgmod, 0, "Cannot open file for writing\n"));
+ fprintf(stderr, "Cannot open file for writing\n");
return;
}
FILE *out;
if (! (out = fopen(filename, "wt"))) {
- //TODO DBG((dbgmod, 0, "Cannot open file for writing\n"));
+ fprintf(stderr, "Cannot open file for writing\n");
return;
}