You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
/* This file mark functions as being either const (TREE_READONLY) or
pure (DECL_IS_PURE).
#include "timevar.h"
#include "diagnostic.h"
#include "langhooks.h"
+#include "target.h"
static struct pointer_set_t *visited_nodes;
if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
return;
+ /* Any tree which is volatile disqualifies thie function from being
+ const or pure. */
+ if (TREE_THIS_VOLATILE (t))
+ {
+ local->pure_const_state = IPA_NEITHER;
+ return;
+ }
+
while (TREE_CODE (t) == REALPART_EXPR
|| TREE_CODE (t) == IMAGPART_EXPR
|| handled_component_p (t))
/* Any indirect reference that occurs on the lhs
disqualifies the function from being pure or const. Any
- indirect reference that occurs on the rhs disqualifies
- the function from being const. */
+ indirect reference that occurs on the rhs disqualifies the
+ function from being const. */
if (checking_write)
- local->pure_const_state = IPA_NEITHER;
- else
- if (local->pure_const_state == IPA_CONST)
- local->pure_const_state = IPA_PURE;
+ {
+ local->pure_const_state = IPA_NEITHER;
+ return;
+ }
+ else if (local->pure_const_state == IPA_CONST)
+ local->pure_const_state = IPA_PURE;
}
if (SSA_VAR_P (t))
*walk_subtrees = 0;
break;
- case MODIFY_EXPR:
+ case GIMPLE_MODIFY_STMT:
{
/* First look on the lhs and see what variable is stored to */
- tree lhs = TREE_OPERAND (t, 0);
- tree rhs = TREE_OPERAND (t, 1);
+ tree lhs = GIMPLE_STMT_OPERAND (t, 0);
+ tree rhs = GIMPLE_STMT_OPERAND (t, 1);
check_lhs_var (local, lhs);
/* For the purposes of figuring out what the cast affects */
static void
analyze_function (struct cgraph_node *fn)
{
- funct_state l = xcalloc (1, sizeof (struct funct_state_d));
+ funct_state l = XCNEW (struct funct_state_d);
tree decl = fn->decl;
struct ipa_dfs_info * w_info = fn->aux;
l->pure_const_state = IPA_CONST;
l->state_set_in_source = false;
- /* If this is a volatile function, do not touch this unless it has
- been marked as const or pure by the front end. */
- if (TREE_THIS_VOLATILE (decl))
+ /* If this function does not return normally or does not bind local,
+ do not touch this unless it has been marked as const or pure by the
+ front end. */
+ if (TREE_THIS_VOLATILE (decl)
+ || !targetm.binds_local_p (decl))
{
l->pure_const_state = IPA_NEITHER;
return;
walk_tree (bsi_stmt_ptr (bsi), scan_function,
fn, visited_nodes);
if (l->pure_const_state == IPA_NEITHER)
- return;
+ goto end;
}
}
pop_cfun ();
}
}
+
+end:
+ if (dump_file)
+ {
+ fprintf (dump_file, "after local analysis of %s with initial value = %d\n ",
+ cgraph_node_name (fn),
+ l->pure_const_state);
+ }
}
\f
on the local information that was produced by ipa_analyze_function
and ipa_analyze_variable. */
-static void
+static unsigned int
static_execute (void)
{
struct cgraph_node *node;
struct cgraph_node *w;
struct cgraph_node **order =
- xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
+ XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
int order_pos = order_pos = ipa_utils_reduced_inorder (order, true, false);
int i;
struct ipa_dfs_info * w_info;
/* Get rid of the aux information. */
if (node->aux)
{
+ w_info = node->aux;
+ if (w_info->aux)
+ free (w_info->aux);
free (node->aux);
node->aux = NULL;
}
free (order);
+ return 0;
}
static bool
struct tree_opt_pass pass_ipa_pure_const =
{
- "ipa-pure-const", /* name */
+ "pure-const", /* name */
gate_pure_const, /* gate */
static_execute, /* execute */
NULL, /* sub */