* @brief Operator Strength Reduction.
* @date 12.5.2006
* @author Michael Beck
- * @version $Id$
* @brief
* Implementation of the Operator Strength Reduction algorithm
* by Keith D. Cooper, L. Taylor Simpson, Christopher A. Vick.
#include "set.h"
#include "tv.h"
#include "hashptr.h"
+#include "util.h"
#include "irtools.h"
#include "irloop_t.h"
#include "array.h"
*/
static int check_users_for_reg_pressure(ir_node *iv, iv_env *env)
{
- ir_node *irn, *header;
+ ir_node *irn;
ir_node *have_user = NULL;
ir_node *have_cmp = NULL;
node_entry *e = get_irn_ne(iv, env);
scc *pscc = e->pscc;
- header = e->header;
for (irn = pscc->head; irn != NULL; irn = e->next) {
const ir_edge_t *edge;
panic("Unsupported opcode");
}
+ if (tv == tarval_bad || tv_init == tarval_bad) {
+ tarval_set_integer_overflow_mode(ovmode);
+ DB((dbg, LEVEL_4, " = OVERFLOW"));
+ return NULL;
+ }
+
if (pscc->code == iro_Add) {
tv_end = tarval_add(tv, tv_incr);
} else {
tarval_set_integer_overflow_mode(ovmode);
- if (tv == tarval_bad || tv_init == tarval_bad || tv_end == tarval_bad) {
+ if (tv_end == tarval_bad) {
DB((dbg, LEVEL_4, " = OVERFLOW"));
return NULL;
}
*/
static void clear_and_fix(ir_node *irn, void *env)
{
- int *moved = (int*)env;
+ (void)env;
+
set_irn_link(irn, NULL);
if (is_Proj(irn)) {
if (get_nodes_block(irn) != pred_block) {
set_nodes_block(irn, pred_block);
- *moved = 1;
}
}
} /* clear_and_fix */
void remove_phi_cycles(ir_graph *irg)
{
iv_env env;
- int projs_moved;
FIRM_DBG_REGISTER(dbg, "firm.opt.remove_phi");
* the same block as their predecessors.
* This can improve the placement of new nodes.
*/
- projs_moved = 0;
- irg_walk_graph(irg, NULL, clear_and_fix, &projs_moved);
- if (projs_moved)
- set_irg_outs_inconsistent(irg);
+ irg_walk_graph(irg, NULL, clear_and_fix, NULL);
/* we need outs for calculating the post order */
assure_irg_outs(irg);
ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
if (env.replaced) {
- set_irg_outs_inconsistent(irg);
DB((dbg, LEVEL_1, "remove_phi_cycles: %u Cycles removed\n\n", env.replaced));
}
set_Sub_right(irn, right);
}
}
+ } else if (mode_is_reference(mode)) {
+ ir_node *left = get_Sub_left(irn);
+ ir_node *right = get_Sub_right(irn);
+ ir_mode *l_mode = get_irn_mode(left);
+ ir_mode *r_mode = get_irn_mode(right);
+ if (mode_is_int(l_mode)) {
+ /* Usually, Sub(I*,P) is an error, hence the verifier rejects it.
+ * However, it is correct in this case, so add Conv to make verifier happy. */
+ ir_node *block = get_nodes_block(right);
+ ir_node *lconv = new_r_Conv(block, left, r_mode);
+ assert(mode_is_reference(r_mode));
+ set_Sub_left(irn, lconv);
+ }
}
}
} /* fix_adds_and_subs */
{
iv_env env;
int edges;
- int projs_moved;
FIRM_DBG_REGISTER(dbg, "firm.opt.osr");
env.process_scc = process_scc;
/* Clear all links and move Proj nodes into the
- the same block as it's predecessors.
- This can improve the placement of new nodes.
+ * the same block as its predecessors.
+ * This can improve the placement of new nodes.
*/
- projs_moved = 0;
- irg_walk_graph(irg, NULL, clear_and_fix, &projs_moved);
- if (projs_moved)
- set_irg_outs_inconsistent(irg);
+ irg_walk_graph(irg, NULL, clear_and_fix, NULL);
/* we need dominance */
assure_doms(irg);
lftr(irg, &env);
(void)lftr;
- set_irg_outs_inconsistent(irg);
DB((dbg, LEVEL_1, "Replacements: %u + %u (lftr)\n\n", env.replaced, env.lftr_replaced));
}
ir_free_resources(irg, IR_RESOURCE_IRN_LINK);