- /* Compute new loop invariant increment and initialization values. */
- if (op_strong == op_Mul) {
- inc = new_r_Mul (current_ir_graph, block_inc, ivi.increment, c, get_irn_mode(c));
- init = new_r_Mul (current_ir_graph, block_init, ivi.init, c, get_irn_mode(ivi.init));
- } else if (op_strong == op_Div) {
- inc = new_r_Div (current_ir_graph, block_inc, get_irg_initial_mem(get_irn_irg(strong)),
- ivi.increment, c);
- init = new_r_Div (current_ir_graph, block_init, get_irg_initial_mem(get_irn_irg(strong)),
- ivi.init, c);
+ if (! ivi->reducible){
+ int reduce_var_pred;
+
+ // Essential condition for the constant of strong.
+ if (get_Block_dom_depth(get_nodes_block(mul_const)) >=
+ get_Block_dom_depth(get_nodes_block(ivi->itervar_phi)))
+ return 0;
+
+ n_made_new_phis++;
+ if (get_opt_strength_red_verbose() && get_firm_verbosity() > 1) {
+ printf("The new Phi node is : "); DDMN(ivi->itervar_phi);
+ printf("reducing operation is : "); DDMN(reduce_var);
+ printf("in graph : "); DDMG(current_ir_graph);
+ }
+
+ ivi->new_increment = new_r_Mul (current_ir_graph, block_inc, ivi->increment, mul_const,
+ get_irn_mode(mul_const));
+ if (!(get_irn_op(mul_init) == op_Phi)){
+ ivi->new_init = new_r_Mul (current_ir_graph, block_init, ivi->init, mul_const,
+ get_irn_mode(mul_const));
+ ivi->new_init = my_new_r_Add(current_ir_graph, block_init, ivi->new_init,
+ ivi->new_increment);
+ } else
+ ivi->new_init = new_r_Mul (current_ir_graph, block_init, ivi->init, mul_const,
+ get_irn_mode(mul_const));
+
+ /* Generate a new basic induction variable. Break the data flow loop
+ initially by using an Unknown node. */
+
+ in[ivi->op_pred_pos] = new_Unknown(get_irn_mode(ivi->new_init));
+
+ in[ivi->init_pred_pos] = ivi->new_init;
+ ivi->new_phi = new_r_Phi(current_ir_graph, get_nodes_block(ivi->itervar_phi), 2, in,
+ get_irn_mode(mul_const));
+ mark_irn_visited(ivi->new_phi);
+
+ if (ivi->operation_code == op_Add)
+ ivi->new_op = my_new_r_Add(current_ir_graph, get_nodes_block(ivi->op),
+ ivi->new_increment,ivi-> new_phi);
+ else if (ivi->operation_code == op_Sub)
+ ivi->new_op = my_new_r_Sub(current_ir_graph, get_nodes_block(ivi->op),ivi-> new_phi,
+ ivi->new_increment);
+
+ set_Phi_pred(ivi->new_phi, ivi->op_pred_pos, ivi->new_op);
+
+
+
+
+
+ // This for search for a reducible successor of reduc_var.
+ reduce_var_pred = get_irn_n_outs(reduce_var);
+ if (reduce_var_pred == 1) {
+ ir_node *old_ind =get_irn_out(reduce_var, 0);
+ if(get_irn_op(old_ind) == op_Add || get_irn_op(old_ind) == op_Sub ||
+ get_irn_op(old_ind) == op_Mul){
+ ivi->reducible = 1;
+ ivi->reducible_node = old_ind;
+ }
+ }
+ /* Replace the use of the strength reduced value. */
+ exchange(reduce_var, ivi->new_phi);
+ return 1;
+ }
+ else { /* ivi->reducible */
+ if(ivi->new_phi == NULL){
+ ivi->init = new_r_Mul (current_ir_graph, get_nodes_block(ivi->init),
+ mul_const, ivi->init,
+ get_irn_mode(mul_const));
+ if(ivi->cmp != NULL)
+ ivi->cmp_const = new_r_Mul (current_ir_graph, ivi->cmp_init_block,
+ ivi->cmp_const, mul_const, get_irn_mode(mul_const));
+ ivi->increment = new_r_Mul (current_ir_graph, block_init,
+ ivi->increment, mul_const, get_irn_mode(mul_const));
+ }else {
+ ivi->new_init = new_r_Mul (current_ir_graph, get_nodes_block(ivi->init),
+ mul_const, ivi->new_init,
+ get_irn_mode(mul_const));
+ ivi->new_increment = new_r_Mul (current_ir_graph, block_init,
+ ivi->new_increment, mul_const,
+ get_irn_mode(mul_const));
+ }
+ if (get_opt_strength_red_verbose() && get_firm_verbosity() > 1) {
+ printf("\nReducing operation is : "); DDMN(reduce_var);
+ printf("in graph : "); DDMG(current_ir_graph);
+ }
+ return 1;