Provide a routine to pick out the ssa-names from interesting statements.
* gimple-range-fold.cc (gimple_range_ssa_names): New.
* gimple-range-fold.h (gimple_range_ssa_names): New prototype.
* gimple-range-gori.cc (range_def_chain::get_def_chain): Move
code to new routine.
}
}
}
+
+// Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
+// on the statement. For efficiency, it is an error to not pass in enough
+// elements for the vector. Return the number of ssa-names.
+
+unsigned
+gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt)
+{
+ tree ssa;
+ int count = 0;
+
+ if (range_op_handler (stmt))
+ {
+ gcc_checking_assert (vec_size >= 2);
+ if ((ssa = gimple_range_ssa_p (gimple_range_operand1 (stmt))))
+ vec[count++] = ssa;
+ if ((ssa = gimple_range_ssa_p (gimple_range_operand2 (stmt))))
+ vec[count++] = ssa;
+ }
+ else if (is_a<gassign *> (stmt)
+ && gimple_assign_rhs_code (stmt) == COND_EXPR)
+ {
+ gcc_checking_assert (vec_size >= 3);
+ gassign *st = as_a<gassign *> (stmt);
+ if ((ssa = gimple_range_ssa_p (gimple_assign_rhs1 (st))))
+ vec[count++] = ssa;
+ if ((ssa = gimple_range_ssa_p (gimple_assign_rhs2 (st))))
+ vec[count++] = ssa;
+ if ((ssa = gimple_range_ssa_p (gimple_assign_rhs3 (st))))
+ vec[count++] = ssa;
+ }
+ return count;
+}
&& TYPE_SIGN (type1) == TYPE_SIGN (type2));
}
+extern tree gimple_range_operand1 (const gimple *s);
+extern tree gimple_range_operand2 (const gimple *s);
+
+// Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
+// on the statement. For efficiency, it is an error to not pass in enough
+// elements for the vector. Return the number of ssa-names.
+
+unsigned gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt);
// Source of all operands for fold_using_range and gori_compute.
// It abstracts out the source of an operand so it can come from a stmt or
relation_oracle *m_oracle;
};
-extern tree gimple_range_operand1 (const gimple *s);
-extern tree gimple_range_operand2 (const gimple *s);
-
// This class uses ranges to fold a gimple statement producinf a range for
// the LHS. The source of all operands is supplied via the fur_source class
// which provides a range_query as well as a source location and any other
bitmap
range_def_chain::get_def_chain (tree name)
{
- tree ssa1, ssa2, ssa3;
+ tree ssa[3];
unsigned v = SSA_NAME_VERSION (name);
// If it has already been processed, just return the cached value.
}
gimple *stmt = SSA_NAME_DEF_STMT (name);
- if (range_op_handler (stmt))
+ unsigned count = gimple_range_ssa_names (ssa, 3, stmt);
+ if (count == 0)
{
- ssa1 = gimple_range_ssa_p (gimple_range_operand1 (stmt));
- ssa2 = gimple_range_ssa_p (gimple_range_operand2 (stmt));
- ssa3 = NULL_TREE;
- }
- else if (is_a<gassign *> (stmt)
- && gimple_assign_rhs_code (stmt) == COND_EXPR)
- {
- gassign *st = as_a<gassign *> (stmt);
- ssa1 = gimple_range_ssa_p (gimple_assign_rhs1 (st));
- ssa2 = gimple_range_ssa_p (gimple_assign_rhs2 (st));
- ssa3 = gimple_range_ssa_p (gimple_assign_rhs3 (st));
- }
- else
- {
- // Stmts not understood are always imports.
+ // Stmts not understood or with no operands are always imports.
set_import (m_def_chain[v], name, NULL);
return NULL;
}
return NULL;
// Increase the depth if we have a pair of ssa-names.
- if (ssa1 && ssa2)
+ if (count > 1)
m_logical_depth++;
- register_dependency (name, ssa1, gimple_bb (stmt));
- register_dependency (name, ssa2, gimple_bb (stmt));
- register_dependency (name, ssa3, gimple_bb (stmt));
- // Stmts with no understandable operands are also imports.
- if (!ssa1 && !ssa2 & !ssa3)
- set_import (m_def_chain[v], name, NULL);
+ for (unsigned x = 0; x < count; x++)
+ register_dependency (name, ssa[x], gimple_bb (stmt));
- if (ssa1 && ssa2)
+ if (count > 1)
m_logical_depth--;
return m_def_chain[v].bm;