Commit d1e88988 authored by Andreas Zwinkau's avatar Andreas Zwinkau
Browse files

Add optimization: occult_consts

Now we have a simple optimization actually using DCA.
parent b4e4b196
......@@ -851,6 +851,12 @@ FIRM_API ir_graph_pass_t *place_code_pass(const char *name);
*/
FIRM_API void fixpoint_vrp(ir_graph*);
/**
* This optimization finds values where the bits are either constant or irrelevant
* and exchanges them for a corresponding constant.
*/
FIRM_API void occult_consts(ir_graph*);
/**
* Creates an ir_graph pass for fixpoint_vrp().
* This pass dDetermines information about the values of nodes
......
/*
* This file is part of libFirm.
* Copyright (C) 2013 University of Karlsruhe.
*/
/**
* @brief optimize nodes to const, where non-const bits are irrelevant
* @author Andreas Seltenreich, Andreas Zwinkau
*/
// TODO might make sense to merge this optimization with fp-vrp
#include "config.h"
#include "iroptimize.h"
#include <stdbool.h>
#include "debug.h"
#include "ircons.h"
#include "irgmod.h"
#include "irgopt.h"
#include "irnode_t.h"
#include "iropt_t.h"
#include "irdump_t.h"
#include "iredges_t.h"
#include "irgwalk.h"
#include "irpass_t.h"
#include "tv.h"
#include "irnodemap.h"
#include "dca.h"
#include "fp-vrp.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
typedef struct env_t {
bool changed;
ir_nodemap dca;
ir_nodemap vrp;
struct obstack obst;
} env_t;
static void occult_const_opt_walker(ir_node *node, void *data)
{
/* Ignore already const nodes */
if (is_Const(node) || is_SymConst(node)) return;
/* Ignore mode_BB, mode_X, etc */
if (!mode_is_data(get_irn_mode(node))) return;
env_t *env = (env_t *)data;
vrp_bitinfo *vrp = ir_nodemap_get(vrp_bitinfo, &env->vrp, node);
if (vrp == NULL) {
DB((dbg, LEVEL_4, "No VRP info: %+F\n", node));
return;
}
ir_tarval *dc = ir_nodemap_get(ir_tarval, &env->dca, node);
ir_tarval *not_const_bits = tarval_eor(vrp->o, vrp->z);
ir_tarval *relevant_not_const_bits = tarval_and(dc, not_const_bits);
if (!tarval_is_null(relevant_not_const_bits)) {
DB((dbg, LEVEL_4, "Not occult: %+F dc=%T, z=%T, o=%T\n", node, dc, vrp->z, vrp->o));
return;
}
ir_graph *irg = get_irn_irg(node);
ir_node *cnst = new_r_Const(irg, vrp->z);
DB((dbg, LEVEL_2, "Occult Const found: %+F -> %+F dc=%T, z=%T, o=%T\n", node, cnst, dc, vrp->z, vrp->o));
exchange(node, cnst);
env->changed = true;
}
static void fill_nodemap(ir_node *node, void *data) {
ir_nodemap *map = data;
ir_nodemap_insert_fast(map, node, get_irn_link(node));
}
void occult_consts(ir_graph *irg)
{
FIRM_DBG_REGISTER(dbg, "firm.opt.occults");
assure_irg_properties(irg,
IR_GRAPH_PROPERTY_NO_BADS
| IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE
| IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE
| IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES);
env_t env;
obstack_init(&env.obst);
env.changed = false;
fp_vrp_analyze(irg, &env.obst);
ir_nodemap_init(&env.vrp, irg);
irg_walk_graph(irg, fill_nodemap, 0, &env.vrp);
dca_analyze(irg);
ir_nodemap_init(&env.dca, irg);
irg_walk_graph(irg, fill_nodemap, 0, &env.dca);
irg_walk_graph(irg, occult_const_opt_walker, 0, &env);
ir_nodemap_destroy(&env.dca);
ir_nodemap_destroy(&env.vrp);
obstack_free(&env.obst, NULL);
confirm_irg_properties(irg,
env.changed ? IR_GRAPH_PROPERTIES_NONE : IR_GRAPH_PROPERTIES_ALL);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment