Commit d242d063 by Martin Jambor Committed by Martin Jambor

re PR tree-optimization/44972 (ICE: in load_assign_lhs_subreplacements, at tree-sra.c:2475)

2010-09-10  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/44972
	* tree-sra.c: Include toplev.h.
	(build_ref_for_offset): Entirely reimplemented.
	(build_ref_for_model): New function.
	(build_user_friendly_ref_for_offset): New function.
	(analyze_access_subtree): Removed build_ref_for_offset check.
	(propagate_subaccesses_across_link): Likewise.
	(create_artificial_child_access): Use
	build_user_friendly_ref_for_offset.
	(propagate_subaccesses_across_link): Likewise.
	(ref_expr_for_all_replacements_p): Removed.
	(generate_subtree_copies): Updated comment.  Use build_ref_for_model.
	(sra_modify_expr): Use build_ref_for_model.
	(load_assign_lhs_subreplacements): Likewise.
	(sra_modify_assign): Removed ref_expr_for_all_replacements_p checks,
	checks for return values of build_ref_for_offset.
	* ipa-cp.c (ipcp_lattice_from_jfunc): No need to check return value of
	build_ref_for_offset.
	* ipa-prop.h: Include gimple.h
	* ipa-prop.c (ipa_compute_jump_functions): Update to look for MEM_REFs.
	(ipa_analyze_indirect_call_uses): Update comment.
	* Makefile.in (tree-sra.o): Add $(GIMPLE_H) to dependencies.
	(IPA_PROP_H): Likewise.

	* testsuite/gcc.dg/ipa/ipa-sra-1.c: Adjust scanning expressions.
	* testsuite/gcc.dg/tree-ssa/pr45144.c: Likewise.
	* testsuite/gcc.dg/tree-ssa/forwprop-5.c: Likewise and scan optimzed
	dump instead.
        * testsuite/g++.dg/torture/pr44972.C: New test.

From-SVN: r164136
parent fffe1e40
2010-09-10 Martin Jambor <mjambor@suse.cz> 2010-09-10 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/44972 PR tree-optimization/44972
* tree-sra.c: Include toplev.h.
(build_ref_for_offset): Entirely reimplemented.
(build_ref_for_model): New function.
(build_user_friendly_ref_for_offset): New function.
(analyze_access_subtree): Removed build_ref_for_offset check.
(propagate_subaccesses_across_link): Likewise.
(create_artificial_child_access): Use
build_user_friendly_ref_for_offset.
(propagate_subaccesses_across_link): Likewise.
(ref_expr_for_all_replacements_p): Removed.
(generate_subtree_copies): Updated comment. Use build_ref_for_model.
(sra_modify_expr): Use build_ref_for_model.
(load_assign_lhs_subreplacements): Likewise.
(sra_modify_assign): Removed ref_expr_for_all_replacements_p checks,
checks for return values of build_ref_for_offset.
* ipa-cp.c (ipcp_lattice_from_jfunc): No need to check return value of
build_ref_for_offset.
* ipa-prop.h: Include gimple.h
* ipa-prop.c (ipa_compute_jump_functions): Update to look for MEM_REFs.
(ipa_analyze_indirect_call_uses): Update comment.
* Makefile.in (tree-sra.o): Add $(GIMPLE_H) to dependencies.
(IPA_PROP_H): Likewise.
2010-09-10 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/44972
* ipa-prop.c (ipa_modify_call_arguments): Build MEM_REF instead of * ipa-prop.c (ipa_modify_call_arguments): Build MEM_REF instead of
calling build_ref_for_offset. calling build_ref_for_offset.
......
...@@ -968,7 +968,7 @@ EBITMAP_H = ebitmap.h sbitmap.h ...@@ -968,7 +968,7 @@ EBITMAP_H = ebitmap.h sbitmap.h
LTO_STREAMER_H = lto-streamer.h $(LINKER_PLUGIN_API_H) $(TARGET_H) \ LTO_STREAMER_H = lto-streamer.h $(LINKER_PLUGIN_API_H) $(TARGET_H) \
$(CGRAPH_H) $(VEC_H) vecprim.h $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(VEC_H) vecprim.h $(TREE_H) $(GIMPLE_H)
TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H)
IPA_PROP_H = ipa-prop.h $(TREE_H) $(VEC_H) $(CGRAPH_H) IPA_PROP_H = ipa-prop.h $(TREE_H) $(VEC_H) $(CGRAPH_H) $(GIMPLE_H)
GSTAB_H = gstab.h stab.def GSTAB_H = gstab.h stab.def
BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h
GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h $(CONFIG_H) $(SYSTEM_H) \ GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h $(CONFIG_H) $(SYSTEM_H) \
...@@ -3143,10 +3143,10 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \ ...@@ -3143,10 +3143,10 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \
tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) \ tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) \
$(DBGCNT_H) tree-pretty-print.h gimple-pretty-print.h $(DBGCNT_H) tree-pretty-print.h gimple-pretty-print.h
tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \ tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \
$(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) $(IPA_PROP_H) \ $(TM_H) $(TOPLEV_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) \
$(DIAGNOSTIC_H) statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) $(PARAMS_H) \ $(IPA_PROP_H) $(DIAGNOSTIC_H) statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) \
$(TARGET_H) $(FLAGS_H) $(EXPR_H) tree-pretty-print.h $(DBGCNT_H) \ $(PARAMS_H) $(TARGET_H) $(FLAGS_H) $(EXPR_H) tree-pretty-print.h \
$(TREE_INLINE_H) gimple-pretty-print.h $(DBGCNT_H) $(TREE_INLINE_H) gimple-pretty-print.h
tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \ tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
$(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \ $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \
......
...@@ -327,7 +327,6 @@ ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat, ...@@ -327,7 +327,6 @@ ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
{ {
struct ipcp_lattice *caller_lat; struct ipcp_lattice *caller_lat;
tree t; tree t;
bool ok;
caller_lat = ipcp_get_lattice (info, jfunc->value.ancestor.formal_id); caller_lat = ipcp_get_lattice (info, jfunc->value.ancestor.formal_id);
lat->type = caller_lat->type; lat->type = caller_lat->type;
...@@ -340,16 +339,9 @@ ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat, ...@@ -340,16 +339,9 @@ ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
return; return;
} }
t = TREE_OPERAND (caller_lat->constant, 0); t = TREE_OPERAND (caller_lat->constant, 0);
ok = build_ref_for_offset (&t, TREE_TYPE (t), t = build_ref_for_offset (t, jfunc->value.ancestor.offset,
jfunc->value.ancestor.offset, jfunc->value.ancestor.type, NULL, false);
jfunc->value.ancestor.type, false); lat->constant = build_fold_addr_expr (t);
if (!ok)
{
lat->type = IPA_BOTTOM;
lat->constant = NULL_TREE;
}
else
lat->constant = build_fold_addr_expr (t);
} }
else else
lat->type = IPA_BOTTOM; lat->type = IPA_BOTTOM;
......
...@@ -916,23 +916,27 @@ ipa_compute_jump_functions (struct cgraph_node *node, ...@@ -916,23 +916,27 @@ ipa_compute_jump_functions (struct cgraph_node *node,
static tree static tree
ipa_get_member_ptr_load_param (tree rhs, bool use_delta) ipa_get_member_ptr_load_param (tree rhs, bool use_delta)
{ {
tree rec, fld; tree rec, ref_offset, fld_offset;
tree ptr_field; tree ptr_field;
tree delta_field; tree delta_field;
if (TREE_CODE (rhs) != COMPONENT_REF) if (TREE_CODE (rhs) != MEM_REF)
return NULL_TREE; return NULL_TREE;
rec = TREE_OPERAND (rhs, 0); rec = TREE_OPERAND (rhs, 0);
if (TREE_CODE (rec) != ADDR_EXPR)
return NULL_TREE;
rec = TREE_OPERAND (rec, 0);
if (TREE_CODE (rec) != PARM_DECL if (TREE_CODE (rec) != PARM_DECL
|| !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field)) || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
return NULL_TREE; return NULL_TREE;
fld = TREE_OPERAND (rhs, 1); ref_offset = TREE_OPERAND (rhs, 1);
if (use_delta ? (fld == delta_field) : (fld == ptr_field)) if (use_delta)
return rec; fld_offset = byte_position (delta_field);
else else
return NULL_TREE; fld_offset = byte_position (ptr_field);
return tree_int_cst_equal (ref_offset, fld_offset) ? rec : NULL_TREE;
} }
/* If STMT looks like a statement loading a value from a member pointer formal /* If STMT looks like a statement loading a value from a member pointer formal
...@@ -999,8 +1003,8 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt, ...@@ -999,8 +1003,8 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt,
below, the call is on the last line: below, the call is on the last line:
<bb 2>: <bb 2>:
f$__delta_5 = f.__delta; f$__delta_5 = MEM[(struct *)&f];
f$__pfn_24 = f.__pfn; f$__pfn_24 = MEM[(struct *)&f + 4B];
... ...
......
...@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h" #include "tree.h"
#include "vec.h" #include "vec.h"
#include "cgraph.h" #include "cgraph.h"
#include "gimple.h"
/* The following definitions and interfaces are used by /* The following definitions and interfaces are used by
interprocedural analyses or parameters. */ interprocedural analyses or parameters. */
...@@ -511,6 +512,7 @@ void ipa_prop_read_jump_functions (void); ...@@ -511,6 +512,7 @@ void ipa_prop_read_jump_functions (void);
void ipa_update_after_lto_read (void); void ipa_update_after_lto_read (void);
/* From tree-sra.c: */ /* From tree-sra.c: */
bool build_ref_for_offset (tree *, tree, HOST_WIDE_INT, tree, bool); tree build_ref_for_offset (tree, HOST_WIDE_INT, tree, gimple_stmt_iterator *,
bool);
#endif /* IPA_PROP_H */ #endif /* IPA_PROP_H */
2010-09-10 Martin Jambor <mjambor@suse.cz> 2010-09-10 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/44972 PR tree-optimization/44972
* gcc.dg/ipa/ipa-sra-1.c: Adjust scanning expressions.
* gcc.dg/tree-ssa/pr45144.c: Likewise.
* gcc.dg/tree-ssa/forwprop-5.c: Likewise and scan optimzed dump
instead.
* g++.dg/torture/pr44972.C: New test.
2010-09-10 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/44972
* g++.dg/torture/pr34850.C: Remove expected warning. * g++.dg/torture/pr34850.C: Remove expected warning.
2010-09-09 Steven G. Kargl <kargl@gcc.gnu.org> 2010-09-09 Steven G. Kargl <kargl@gcc.gnu.org>
......
/* { dg-do compile } */
#include<cassert>
#include<new>
#include<utility>
namespace boost {
template<class T>
class optional;
class aligned_storage
{
char data[ 1000 ];
public:
void const* address() const { return &data[0]; }
void * address() { return &data[0]; }
} ;
template<class T>
class optional_base
{
protected :
optional_base(){}
optional_base ( T const& val )
{
construct(val);
}
template<class U>
void assign ( optional<U> const& rhs )
{
if (!is_initialized())
if ( rhs.is_initialized() )
construct(T());
}
public :
bool is_initialized() const { return m_initialized ; }
protected :
void construct ( T const& val )
{
new (m_storage.address()) T(val) ;
}
T const* get_ptr_impl() const
{ return static_cast<T const*>(m_storage.address()); }
private :
bool m_initialized ;
aligned_storage m_storage ;
} ;
template<class T>
class optional : public optional_base<T>
{
typedef optional_base<T> base ;
public :
optional() : base() {}
optional ( T const& val ) : base(val) {}
optional& operator= ( optional const& rhs )
{
this->assign( rhs ) ;
return *this ;
}
T const& get() const ;
T const* operator->() const { ((this->is_initialized()) ? static_cast<void> (0) : __assert_fail ("this->is_initialized()", "pr44972.C", 78, __PRETTY_FUNCTION__)) ; return this->get_ptr_impl() ; }
} ;
} // namespace boost
namespace std
{
template<typename _Tp, std::size_t _Nm>
struct array
{
typedef _Tp value_type;
typedef const value_type* const_iterator;
value_type _M_instance[_Nm];
};
}
class NT
{
double _inf, _sup;
};
template < typename T > inline
std::array<T, 1>
make_array(const T& b1)
{
std::array<T, 1> a = { { b1 } };
return a;
}
class V
{
typedef std::array<NT, 1> Base;
Base base;
public:
V() {}
V(const NT &x)
: base(make_array(x)) {}
};
using boost::optional ;
optional< std::pair< NT, NT > >
linsolve_pointC2() ;
optional< V > construct_normal_offset_lines_isecC2 ( )
{
optional< std::pair<NT,NT> > ip;
ip = linsolve_pointC2();
V a(ip->first) ;
return a;
}
...@@ -36,6 +36,5 @@ main (int argc, char *argv[]) ...@@ -36,6 +36,5 @@ main (int argc, char *argv[])
return 0; return 0;
} }
/* { dg-final { scan-tree-dump "About to replace expr cow.green with ISRA" "eipa_sra" } } */ /* { dg-final { scan-tree-dump-times "About to replace expr" 2 "eipa_sra" } } */
/* { dg-final { scan-tree-dump "About to replace expr cow.blue with ISRA" "eipa_sra" } } */
/* { dg-final { cleanup-tree-dump "eipa_sra" } } */ /* { dg-final { cleanup-tree-dump "eipa_sra" } } */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-esra -w" } */ /* { dg-options "-O1 -fdump-tree-optimized -w" } */
#define vector __attribute__((vector_size(16) )) #define vector __attribute__((vector_size(16) ))
struct VecClass struct VecClass
...@@ -11,12 +11,9 @@ vector float foo( vector float v ) ...@@ -11,12 +11,9 @@ vector float foo( vector float v )
{ {
vector float x = v; vector float x = v;
x = x + x; x = x + x;
struct VecClass y = *(struct VecClass*)&x; struct VecClass disappear = *(struct VecClass*)&x;
return y.v; return disappear.v;
} }
/* We should be able to remove the intermediate struct and directly /* { dg-final { scan-tree-dump-times "disappear" 0 "optimized"} } */
return x. As we do not fold VIEW_CONVERT_EXPR<struct VecClass>(x).v /* { dg-final { cleanup-tree-dump "optimized" } } */
that doesn't happen right now. */
/* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 1 "esra"} } */
/* { dg-final { cleanup-tree-dump "esra" } } */
...@@ -42,5 +42,5 @@ bar (unsigned orig, unsigned *new) ...@@ -42,5 +42,5 @@ bar (unsigned orig, unsigned *new)
*new = foo (&a); *new = foo (&a);
} }
/* { dg-final { scan-tree-dump "x = a;" "optimized"} } */ /* { dg-final { scan-tree-dump " = VIEW_CONVERT_EXPR<unsigned int>\\(a\\);" "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment