GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
for more details.
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, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
{
enum tree_code code = TREE_CODE (type);
return (code == INTEGER_TYPE || code == REAL_TYPE || code == VECTOR_TYPE
+ || code == FIXED_POINT_TYPE
|| code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
|| code == POINTER_TYPE || code == OFFSET_TYPE
|| code == REFERENCE_TYPE);
void (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi);
/* Invoked when we have a copy between one scalarizable reference ELT
- and one non-scalarizable reference OTHER. IS_OUTPUT is true if ELT
- is on the left-hand side. */
+ and one non-scalarizable reference OTHER without side-effects.
+ IS_OUTPUT is true if ELT is on the left-hand side. */
void (*ldst) (struct sra_elt *elt, tree other,
block_stmt_iterator *bsi, bool is_output);
/* If the RHS is scalarizable, handle it. There are only two cases. */
if (rhs_elt)
{
- if (!rhs_elt->is_scalar)
+ if (!rhs_elt->is_scalar && !TREE_SIDE_EFFECTS (lhs))
fns->ldst (rhs_elt, lhs, bsi, false);
else
fns->use (rhs_elt, &GIMPLE_STMT_OPERAND (expr, 1), bsi, false, false);
The lvalue requirement prevents us from trying to directly scalarize
the result of a function call. Which would result in trying to call
the function multiple times, and other evil things. */
- else if (!lhs_elt->is_scalar && is_gimple_addressable (rhs))
+ else if (!lhs_elt->is_scalar
+ && !TREE_SIDE_EFFECTS (rhs) && is_gimple_addressable (rhs))
fns->ldst (lhs_elt, rhs, bsi, true);
/* Otherwise we're being used in some context that requires the
DECL_IGNORED_P (var) = 0;
TREE_NO_WARNING (var) = TREE_NO_WARNING (base);
+ if (elt->element && TREE_NO_WARNING (elt->element))
+ TREE_NO_WARNING (var) = 1;
}
else
{
}
bitmap_clear (&done_head);
- if (!bitmap_empty_p (sra_candidates))
- todoflags |= TODO_update_smt_usage;
-
mark_set_for_renaming (sra_candidates);
if (dump_file)
}
case ARRAY_TYPE:
- todoflags |= TODO_update_smt_usage;
if (TREE_CODE (elt->element) == RANGE_EXPR)
return build4 (ARRAY_RANGE_REF, elt->type, base,
TREE_OPERAND (elt->element, 0), NULL, NULL);
return elt->element;
}
+/* Create an assignment statement from SRC to DST. */
+
static tree
sra_build_assignment (tree dst, tree src)
{
- gcc_assert (TYPE_CANONICAL (TYPE_MAIN_VARIANT (TREE_TYPE (dst)))
- == TYPE_CANONICAL (TYPE_MAIN_VARIANT (TREE_TYPE (src))));
- return build2 (GIMPLE_MODIFY_STMT, void_type_node, dst, src);
+ /* It was hoped that we could perform some type sanity checking
+ here, but since front-ends can emit accesses of fields in types
+ different from their nominal types and copy structures containing
+ them as a whole, we'd have to handle such differences here.
+ Since such accesses under different types require compatibility
+ anyway, there's little point in making tests and/or adding
+ conversions to ensure the types of src and dst are the same.
+ So we just assume type differences at this point are ok. */
+ return build_gimple_modify_stmt (dst, src);
}
/* Generate a set of assignment statements in *LIST_P to copy all
scan_function ();
decide_instantiations ();
scalarize_function ();
+ if (!bitmap_empty_p (sra_candidates))
+ todoflags |= TODO_rebuild_alias;
}
/* Free allocated memory. */
ret = tree_sra ();
early_sra = false;
- return ret;
+ return ret & ~TODO_rebuild_alias;
}
static bool