Backport from mainline
2012-07-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53844
* tree-ssa-dse.c (dse_possible_dead_store_p): Properly handle
the loop virtual PHI.
* g++.dg/tree-ssa/pr53844.C: New testcase.
2012-12-13 Richard Biener <rguenther@suse.de>
PR lto/55660
* tree-streamer.c (record_common_node): Check that we are not
recursively pre-loading nodes we want to skip. Handle
char_type_node appearing as part of va_list_type_node.
* gcc.dg/lto/pr55660_0.c: New testcase.
* gcc.dg/lto/pr55660_1.c: Likewise.
2013-02-04 Richard Biener <rguenther@suse.de>
PR middle-end/55890
* gimple.h (gimple_call_builtin_class_p): New function.
* gimple.c (validate_call): New function.
(gimple_call_builtin_class_p): Likewise.
* tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
Use gimple_call_builtin_class_p.
(find_func_clobbers): Likewise.
* tree-ssa-strlen.c (adjust_last_stmt): Likewise.
(strlen_optimize_stmt): Likewise.
* gcc.dg/torture/pr55890-1.c: New testcase.
* gcc.dg/torture/pr55890-2.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@195708
138bc75d-0d04-0410-961f-
82ee72b054a4
+2013-02-04 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2012-07-04 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/53844
+ * tree-ssa-dse.c (dse_possible_dead_store_p): Properly handle
+ the loop virtual PHI.
+
+ 2012-12-13 Richard Biener <rguenther@suse.de>
+
+ PR lto/55660
+ * tree-streamer.c (record_common_node): Check that we are not
+ recursively pre-loading nodes we want to skip. Handle
+ char_type_node appearing as part of va_list_type_node.
+
+2013-02-04 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/55890
+ * gimple.h (gimple_call_builtin_class_p): New function.
+ * gimple.c (validate_call): New function.
+ (gimple_call_builtin_class_p): Likewise.
+ * tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
+ Use gimple_call_builtin_class_p.
+ (find_func_clobbers): Likewise.
+ * tree-ssa-strlen.c (adjust_last_stmt): Likewise.
+ (strlen_optimize_stmt): Likewise.
+
2013-02-01 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
return IDENTIFIER_POINTER (DECL_NAME (decl));
}
-/* Return true when STMT is builtins call to CODE. */
+/* Return true when STMTs arguments match those of FNDECL. */
+
+static bool
+validate_call (gimple stmt, tree fndecl)
+{
+ tree arg, targs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+ unsigned nargs = gimple_call_num_args (stmt);
+ unsigned i;
+ for (i = 0; i < nargs; ++i)
+ {
+ /* Variadic args follow. */
+ if (!targs)
+ return true;
+ arg = gimple_call_arg (stmt, i);
+ if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
+ && INTEGRAL_TYPE_P (TREE_VALUE (targs)))
+ ;
+ else if (POINTER_TYPE_P (TREE_TYPE (arg))
+ && POINTER_TYPE_P (TREE_VALUE (targs)))
+ ;
+ else if (TREE_CODE (TREE_TYPE (arg))
+ != TREE_CODE (TREE_VALUE (targs)))
+ return false;
+ targs = TREE_CHAIN (targs);
+ }
+ if (targs && !VOID_TYPE_P (TREE_VALUE (targs)))
+ return false;
+ return true;
+}
+
+/* Return true when STMT is builtins call to CLASS. */
+
+bool
+gimple_call_builtin_class_p (gimple stmt, enum built_in_class klass)
+{
+ tree fndecl;
+ if (is_gimple_call (stmt)
+ && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
+ && DECL_BUILT_IN_CLASS (fndecl) == klass)
+ return validate_call (stmt, fndecl);
+ return false;
+}
+
+/* Return true when STMT is builtins call to CODE of CLASS. */
bool
gimple_call_builtin_p (gimple stmt, enum built_in_function code)
{
tree fndecl;
- return (is_gimple_call (stmt)
- && (fndecl = gimple_call_fndecl (stmt)) != NULL
- && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (fndecl) == code);
+ if (is_gimple_call (stmt)
+ && (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
+ && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (fndecl) == code)
+ return validate_call (stmt, fndecl);
+ return false;
}
/* Return true if STMT clobbers memory. STMT is required to be a
bool (*)(gimple, tree, void *),
bool (*)(gimple, tree, void *));
extern bool gimple_ior_addresses_taken (bitmap, gimple);
+extern bool gimple_call_builtin_class_p (gimple, enum built_in_class);
extern bool gimple_call_builtin_p (gimple, enum built_in_function);
extern bool gimple_asm_clobbers_memory_p (const_gimple);
+2013-02-04 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2012-07-04 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/53844
+ * g++.dg/tree-ssa/pr53844.C: New testcase.
+
+ 2012-12-13 Richard Biener <rguenther@suse.de>
+
+ PR lto/55660
+ * gcc.dg/lto/pr55660_0.c: New testcase.
+ * gcc.dg/lto/pr55660_1.c: Likewise.
+
+2013-02-04 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/55890
+ * gcc.dg/torture/pr55890-1.c: New testcase.
+ * gcc.dg/torture/pr55890-2.c: Likewise.
+
2013-02-02 Thomas Koenig <tkoenig@gcc.gnu.org>
Backport from trunk
--- /dev/null
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-optimized-vops" }
+
+struct VBase;
+
+//Very minimal numeric vector class where Base provides the policy
+template<typename Base=VBase>
+struct Vector : public Base{
+
+ inline Vector(const Base& b)
+ :Base(b)
+ {
+ }
+
+ //Assignment from any other sort of Vector
+ template<typename Base2>
+ void operator= (const Vector<Base2>& from)
+ {
+ for(int i=0; i<100; i++){
+ (*this)[i]=from[i];
+ }
+ }
+};
+
+
+//Base class to represent pointer as a Vector
+struct VBase{
+ double * const my_data;
+
+ double& operator[](int i) {
+ return my_data[i];
+ }
+
+ const double& operator[](int i) const {
+ return my_data[i];
+ }
+};
+
+//Base class providing very minimalistic expression template
+template<class B2> struct ScalarMulExpr
+{
+ const int& mul;
+ const Vector<B2>& vec;
+
+ int size() const
+ {
+ return vec.size();
+ }
+
+ double operator[](int i) const
+ {
+ return vec[i]*mul;
+ }
+
+ ScalarMulExpr(const Vector<B2>& vec_, const int& m)
+ :mul(m),vec(vec_)
+ {
+ }
+};
+
+//Allow vector to be multiplied by a scalar
+template<class B2>
+Vector<ScalarMulExpr<B2> > operator*(const Vector<B2>& lhs, const int& rhs)
+{
+ return ScalarMulExpr<B2>(lhs, rhs);
+}
+
+//Test function producing suboptimal asm code
+void test(const Vector<>& in, Vector<>& out, int i)
+{
+ out=in*1*1*1*1*1*1*1*1*1*1*1;
+}
+
+// There should be a single store remaining, inside the loops. All
+// dead stores to unused temporaries should have been removed.
+
+// { dg-final { scan-tree-dump-times "VDEF" 1 "optimized" } }
+// { dg-final { cleanup-tree-dump "optimized" } }
--- /dev/null
+/* { dg-lto-do run } */
+/* { dg-extra-ld-options { -funsigned-char } } */
+
+char n[3] = {'a','b','c'};
+int foo(char *x)
+{
+ if (*x == 'b')
+ return (int)*x;
+ *x = 'y';
+ return 0;
+}
--- /dev/null
+extern int foo (char*);
+extern void abort (void);
+
+extern char n[3];
+
+int main ()
+{
+ int i, m = 0;
+ for (i = 0; i < 3; i++)
+ m += foo(&n[i]);
+
+ if (m != 'b')
+ abort ();
+ return 0;
+}
--- /dev/null
+/* { dg-do compile } */
+
+extern void *memmove(void *, void *, __SIZE_TYPE__);
+typedef int (*_TEST_fun_) ();
+static _TEST_fun_ i = (_TEST_fun_) memmove;
+main() { i(); }
--- /dev/null
+/* { dg-do compile } */\r
+\r
+extern void *memcpy();\r
+main() { memcpy(); }\r
temp = stmt;
do
{
- gimple use_stmt;
+ gimple use_stmt, defvar_def;
imm_use_iterator ui;
bool fail = false;
tree defvar;
defvar = PHI_RESULT (temp);
else
defvar = gimple_vdef (temp);
+ defvar_def = temp;
temp = NULL;
FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
{
fail = true;
BREAK_FROM_IMM_USE_STMT (ui);
}
- temp = use_stmt;
+ /* Do not consider the PHI as use if it dominates the
+ stmt defining the virtual operand we are processing,
+ we have processed it already in this case. */
+ if (gimple_bb (defvar_def) != gimple_bb (use_stmt)
+ && !dominated_by_p (CDI_DOMINATORS,
+ gimple_bb (defvar_def),
+ gimple_bb (use_stmt)))
+ temp = use_stmt;
}
/* If the statement is a use the store is not dead. */
else if (ref_maybe_used_by_stmt_p (use_stmt,
if (!is_gimple_call (last.stmt))
return;
- callee = gimple_call_fndecl (last.stmt);
- if (callee == NULL_TREE || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
+ if (!gimple_call_builtin_class_p (last.stmt, BUILT_IN_NORMAL))
return;
+ callee = gimple_call_fndecl (last.stmt);
switch (DECL_FUNCTION_CODE (callee))
{
case BUILT_IN_MEMCPY:
if (is_gimple_call (stmt))
{
tree callee = gimple_call_fndecl (stmt);
- if (callee && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
+ if (gimple_call_builtin_class_p (stmt, BUILT_IN_NORMAL))
switch (DECL_FUNCTION_CODE (callee))
{
case BUILT_IN_STRLEN:
VEC(ce_s, heap) *rhsc = NULL;
varinfo_t fi;
- if (fndecl != NULL_TREE
- && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ if (gimple_call_builtin_class_p (t, BUILT_IN_NORMAL))
/* ??? All builtins that are handled here need to be handled
in the alias-oracle query functions explicitly! */
switch (DECL_FUNCTION_CODE (fndecl))
/* For builtins we do not have separate function info. For those
we do not generate escapes for we have to generate clobbers/uses. */
- if (decl
- && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+ if (gimple_call_builtin_class_p (t, BUILT_IN_NORMAL))
switch (DECL_FUNCTION_CODE (decl))
{
/* The following functions use and clobber memory pointed to
static void
record_common_node (struct streamer_tree_cache_d *cache, tree node)
{
+ /* If we recursively end up at nodes we do not want to preload simply don't.
+ ??? We'd want to verify that this doesn't happen, or alternatively
+ do not recurse at all. */
+ if (node == char_type_node)
+ return;
+
+ gcc_checking_assert (node != boolean_type_node
+ && node != boolean_true_node
+ && node != boolean_false_node);
+
/* We have to make sure to fill exactly the same number of
elements for all frontends. That can include NULL trees.
As our hash table can't deal with zero entries we'll simply stream