fixed classify_value() function
[libfirm] / ir / opt / strength_red.c
index 5697379..6592acf 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 
-
 /*
 
 reducible(o)
@@ -46,31 +45,6 @@ reduce_itervar(induct_var_info *iv)
 # include "firmstat.h"
 
 
-/* The information needed for an induction variable */
-typedef struct _induct_var_info {
-  ir_op   *operation_code;              /**< the opcode of the induction variable, either op_Add or op_Sub */
-  ir_node *increment;                   /**< the increment/decrement expression of the induction vriable */
-  ir_node *init;                        /**< the init expression */
-  ir_node *op;                          /**< the modify expression of the induction variable, ie the Add/Sub */
-  ir_node *itervar_phi;                 /**< the Phi operation of the induction variable */
-  ir_node *c, *new_phi, *new_increment, *new_init;
-  ir_node *new_op, *new_add, *reducible_node;
-  ir_node *old_ind, *symconst, *new_cmp;
-  ir_node *cmp_const;                   /**< the (loop invariant) expression that compared with the induction variable */
-  ir_node *cmp_init_block;
-  ir_node *cmp;                         /**< if set, the cmp at the end of the loop using the induction variable */
-  ir_loop *l_itervar_phi;               /**< the loop of the induction variable */
-  int      strong_reduced;
-  int      init_pred_pos;               /**< the position of the init expression in the inductions Phi */
-  int      op_pred_pos;                 /**< the position of the induction operation in the inductions Phi */
-  int      out_loop_res;
-  int      phi_pred;                    /**< number of users of the induction variable's phi */
-  int      reducible;                   /**< set if reducible */
-} induct_var_info;
-
-
-
-
 /** Counter for verbose information about optimization. */
 static int n_reduced_expressions;
 static int n_made_new_phis;
@@ -93,11 +67,13 @@ static int n_made_new_phis;
  * op or loop invariant.
  *
  * @param n     A phi node.
- * @param info  After call contains the induction variable information
+ * @param info  After call contains the induction variable information.
  */
-static induct_var_info *is_induction_variable (induct_var_info *info) {
+
+induct_var_info *is_induction_variable (induct_var_info *info) {
 
   int i;
+  int op_pred, Store_in_op, Store_in_phi, cmp_in_phi;
 
   info->c                = NULL;
   info->cmp              = NULL;
@@ -175,7 +151,10 @@ static induct_var_info *is_induction_variable (induct_var_info *info) {
   }
 
   /* This "for" marks if the iteration operation have a Store successor .*/
-  int op_pred = get_irn_n_outs(info->op), Store_in_op = 0, Store_in_phi = 0, cmp_in_phi = 0;
+  op_pred      = get_irn_n_outs(info->op);
+  Store_in_op  = 0;
+  Store_in_phi = 0;
+  cmp_in_phi   = 0;
   for (i = 0; i < op_pred; ++i){
     ir_node *out  = get_irn_out(info->op, i);
     ir_op *out_op = get_irn_op(out);
@@ -186,7 +165,7 @@ static induct_var_info *is_induction_variable (induct_var_info *info) {
   /* Information about loop of itervar_phi. */
   info->l_itervar_phi = get_irn_loop(get_nodes_block(info->itervar_phi));
 
-  /* This "for" searchs for the Cmp successor of the
+  /* This "for" searches for the Cmp successor of the
      iter_var to reduce and marks if the iter_var have a Store
      successor or a successor out of loop.*/
   info->phi_pred = get_irn_n_outs(info->itervar_phi);
@@ -213,13 +192,15 @@ static induct_var_info *is_induction_variable (induct_var_info *info) {
     info->reducible = 1;
 
   // Search for loop invariant of Cmp.
-  if (info->cmp != NULL){
+  if (info->cmp != NULL) {
+    ir_node *cmp_const_block;
+
     if (get_Cmp_left(info->cmp) == info->itervar_phi)
       info->cmp_const = get_Cmp_right(info->cmp);
     else
       info->cmp_const = get_Cmp_left(info->cmp);
 
-    ir_node *cmp_const_block = get_nodes_block(info->cmp_const);
+    cmp_const_block = get_nodes_block(info->cmp_const);
     if (get_Block_dom_depth(get_nodes_block(info->init)) >=
         get_Block_dom_depth(cmp_const_block))
       info->cmp_init_block = get_nodes_block(info->init);
@@ -269,8 +250,6 @@ static int reduce(ir_node *reduce_var, induct_var_info *ivi)
     return 0;
 
   if (get_irn_op(reduce_var) == op_Mul) {
-    n_reduced_expressions++;
-
     ir_node *mul_init  = NULL;
     ir_node *mul_const = NULL;
 
@@ -280,6 +259,15 @@ static int reduce(ir_node *reduce_var, induct_var_info *ivi)
     ir_op *mul_right_op = get_irn_op(mul_right);
     ir_op  *mul_left_op = get_irn_op(mul_left);
 
+    ir_node *in[2], *block_init;
+    ir_node *block_inc;
+
+    ir_node *init_block;
+    ir_node *increment_block;
+    ir_node *c_block;
+
+    n_reduced_expressions++;
+
     if (mul_right_op == op_Const) {
       mul_const = mul_right;
       mul_init  = mul_left;
@@ -292,12 +280,9 @@ static int reduce(ir_node *reduce_var, induct_var_info *ivi)
     if (mul_const == NULL || mul_init == NULL)
       return 0;
 
-    ir_node *in[2], *block_init;
-    ir_node *block_inc;
-
-    ir_node *init_block      = get_nodes_block(mul_init);
-    ir_node *increment_block = get_nodes_block(ivi->increment);
-    ir_node *c_block         = get_nodes_block(mul_const);
+    init_block      = get_nodes_block(mul_init);
+    increment_block = get_nodes_block(ivi->increment);
+    c_block         = get_nodes_block(mul_const);
 
     if (get_Block_dom_depth(increment_block) >= get_Block_dom_depth(c_block))
       block_inc = increment_block;
@@ -310,6 +295,8 @@ static int reduce(ir_node *reduce_var, induct_var_info *ivi)
       block_init = c_block;
 
     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)))
@@ -357,8 +344,8 @@ static int reduce(ir_node *reduce_var, induct_var_info *ivi)
 
 
       // This for search for a reducible successor of reduc_var.
-      int reduce_var_pred =  get_irn_n_outs(reduce_var);
-      if(reduce_var_pred == 1){
+      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){
@@ -396,7 +383,6 @@ static int reduce(ir_node *reduce_var, induct_var_info *ivi)
     }
 
   }else if (get_irn_op (reduce_var) == op_Add){
-    n_reduced_expressions++;
     ir_node *add_init  = NULL;
     ir_node *add_const = NULL;
 
@@ -405,22 +391,25 @@ static int reduce(ir_node *reduce_var, induct_var_info *ivi)
     ir_node  *add_left  = get_Add_left(reduce_var);
     ir_op *add_right_op = get_irn_op(add_right);
     ir_op  *add_left_op = get_irn_op(add_left);
-    if(add_right_op != op_Const)
+
+    n_reduced_expressions++;
+
+    if (add_right_op != op_Const)
       add_init = add_right;
-    else  if(add_left_op != op_Const )
+    else if (add_left_op != op_Const)
       add_init = add_left;
-    if(add_right_op == op_Const || add_right_op == op_SymConst)
+    if (add_right_op == op_Const || add_right_op == op_SymConst)
       add_const = add_right;
-    else if(add_left_op == op_Const || add_left_op == op_SymConst)
+    else if (add_left_op == op_Const || add_left_op == op_SymConst)
       add_const = add_left;
-    if(add_const == NULL) return 0;
-    if(ivi->new_phi == NULL){
+    if (add_const == NULL) return 0;
+    if (ivi->new_phi == NULL){
       ivi->init = my_new_r_Add (current_ir_graph, get_nodes_block(ivi->init),
                                 add_const, ivi->init);
       if(ivi->cmp != NULL)
         ivi->cmp_const = my_new_r_Add (current_ir_graph, ivi->cmp_init_block,
                                        add_const, ivi->cmp_const);
-    }else{
+    } else{
       ivi->new_init = my_new_r_Add (current_ir_graph, get_nodes_block(ivi->init),
                                     add_const, ivi->new_init);
     }
@@ -429,8 +418,7 @@ static int reduce(ir_node *reduce_var, induct_var_info *ivi)
       printf("in graph : "); DDMG(current_ir_graph);
     }
     return 1;
-  }else if(get_irn_op(reduce_var) == op_Sub ){
-    n_reduced_expressions++;
+  } else if(get_irn_op(reduce_var) == op_Sub ){
     ir_node *sub_init  = NULL;
     ir_node *sub_const = NULL;
     // Search for constant of sub.
@@ -438,24 +426,27 @@ static int reduce(ir_node *reduce_var, induct_var_info *ivi)
     ir_node  *sub_left  = get_Sub_left(reduce_var);
     ir_op *sub_right_op = get_irn_op(sub_right);
     ir_op  *sub_left_op = get_irn_op(sub_left);
-    if(sub_right_op != op_Const)
+
+    n_reduced_expressions++;
+
+    if (sub_right_op != op_Const)
       sub_init = sub_right;
-    else  if(sub_left_op != op_Const)
+    else if (sub_left_op != op_Const)
       sub_init = sub_left;
-    if(sub_right_op == op_Const)
+    if (sub_right_op == op_Const)
       sub_const = sub_right;
-    else if(sub_left_op == op_Const)
+    else if (sub_left_op == op_Const)
       sub_const = sub_left;
 
-    if(sub_const == NULL ) return 0;
+    if (sub_const == NULL) return 0;
 
-    if(ivi->new_phi == NULL){
-    ivi->init = my_new_r_Sub (current_ir_graph, get_nodes_block(ivi->init),
-                              ivi->init, sub_const);
-    if (ivi->cmp != NULL)
-      ivi->cmp_const =my_new_r_Sub (current_ir_graph, get_nodes_block(ivi->init),
-                                    ivi->cmp_const,sub_const);
-    }else
+    if (ivi->new_phi == NULL) {
+      ivi->init = my_new_r_Sub (current_ir_graph, get_nodes_block(ivi->init),
+                                ivi->init, sub_const);
+      if (ivi->cmp != NULL)
+        ivi->cmp_const =my_new_r_Sub (current_ir_graph, get_nodes_block(ivi->init),
+                                      ivi->cmp_const,sub_const);
+    } else
       ivi->new_init = my_new_r_Sub (current_ir_graph, get_nodes_block(ivi->init),
                                     ivi->new_init, sub_const);
     if (get_opt_strength_red_verbose() && get_firm_verbosity() > 1) {
@@ -497,7 +488,7 @@ static void reduce_itervar(ir_node *itervar_phi, void *env)
 
   ivi.itervar_phi = itervar_phi;
 
-  /* This "if" finds the interation variable. */
+  /* This "if" finds the iteration variable. */
   if (is_induction_variable(&ivi)) {
     int i, op_out;