cfgexpand: Handle integral vector types and constructors for scope conflicts [PR105769]
This is an expansion of the last patch to also track pointers via vector types and the constructor that are used with vector types. In this case we had: ``` _15 = (long unsigned int) &bias; _10 = (long unsigned int) &cov_jn; _12 = {_10, _15}; ... MEM[(struct vec *)&cov_jn] ={v} {CLOBBER(bob)}; bias ={v} {CLOBBER(bob)}; MEM[(struct function *)&D.6156] ={v} {CLOBBER(bob)}; ... MEM <vector(2) long unsigned int> [(void *)&D.6172 + 32B] = _12; MEM[(struct function *)&D.6157] ={v} {CLOBBER(bob)}; ``` Anyways tracking the pointers via vector types to say they are alive at the point where the store of the vector happens fixes the bug by saying it is alive at the same time as another variable is alive. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/105769 gcc/ChangeLog: * cfgexpand.cc (vars_ssa_cache::operator()): For constructors walk over the elements. gcc/testsuite/ChangeLog: * g++.dg/torture/pr105769-1.C: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
This commit is contained in:
parent
0014a858a1
commit
4f4722b072
2 changed files with 83 additions and 4 deletions
|
@ -728,7 +728,7 @@ vars_ssa_cache::operator() (tree name)
|
|||
gcc_assert (TREE_CODE (name) == SSA_NAME);
|
||||
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (name))
|
||||
&& !INTEGRAL_TYPE_P (TREE_TYPE (name)))
|
||||
&& !ANY_INTEGRAL_TYPE_P (TREE_TYPE (name)))
|
||||
return empty;
|
||||
|
||||
if (exists (name))
|
||||
|
@ -758,7 +758,7 @@ vars_ssa_cache::operator() (tree name)
|
|||
continue;
|
||||
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (use))
|
||||
&& !INTEGRAL_TYPE_P (TREE_TYPE (use)))
|
||||
&& !ANY_INTEGRAL_TYPE_P (TREE_TYPE (use)))
|
||||
continue;
|
||||
|
||||
/* Mark the old ssa name needs to be update from the use. */
|
||||
|
@ -772,10 +772,22 @@ vars_ssa_cache::operator() (tree name)
|
|||
so we don't go into an infinite loop for some phi nodes with loops. */
|
||||
create (use);
|
||||
|
||||
gimple *g = SSA_NAME_DEF_STMT (use);
|
||||
|
||||
/* CONSTRUCTOR here is always a vector initialization,
|
||||
walk each element too. */
|
||||
if (gimple_assign_single_p (g)
|
||||
&& TREE_CODE (gimple_assign_rhs1 (g)) == CONSTRUCTOR)
|
||||
{
|
||||
tree ctr = gimple_assign_rhs1 (g);
|
||||
unsigned i;
|
||||
tree elm;
|
||||
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctr), i, elm)
|
||||
work_list.safe_push (std::make_pair (elm, use));
|
||||
}
|
||||
/* For assignments, walk each operand for possible addresses.
|
||||
For PHI nodes, walk each argument. */
|
||||
gimple *g = SSA_NAME_DEF_STMT (use);
|
||||
if (gassign *a = dyn_cast <gassign *> (g))
|
||||
else if (gassign *a = dyn_cast <gassign *> (g))
|
||||
{
|
||||
/* operand 0 is the lhs. */
|
||||
for (unsigned i = 1; i < gimple_num_ops (g); i++)
|
||||
|
|
67
gcc/testsuite/g++.dg/torture/pr105769-1.C
Normal file
67
gcc/testsuite/g++.dg/torture/pr105769-1.C
Normal file
|
@ -0,0 +1,67 @@
|
|||
// { dg-do run }
|
||||
|
||||
// PR tree-optimization/105769
|
||||
|
||||
// The partitioning code would incorrectly have bias
|
||||
// and a temporary in the same partitioning because
|
||||
// it was thought bias was not alive when those were alive
|
||||
// do to vectorization of a store of pointers (that included bias).
|
||||
|
||||
#include <functional>
|
||||
|
||||
template<size_t n, class T>
|
||||
struct vec {
|
||||
T dat[n];
|
||||
vec() {}
|
||||
explicit vec(const T& x) { for(size_t i = 0; i < n; i++) dat[i] = x; }
|
||||
T& operator [](size_t i) { return dat[i]; }
|
||||
const T& operator [](size_t i) const { return dat[i]; }
|
||||
};
|
||||
|
||||
template<size_t m, size_t n, class T>
|
||||
using mat = vec<m, vec<n, T>>;
|
||||
template<size_t n, class T>
|
||||
using sq_mat = mat<n, n, T>;
|
||||
using map_t = std::function<size_t(size_t)>;
|
||||
template<class T_v>
|
||||
using est_t = std::function<T_v(map_t map)>;
|
||||
template<class T_v> using est2_t = std::function<T_v(map_t map)>;
|
||||
map_t id_map() { return [](size_t j) -> size_t { return j; }; }
|
||||
|
||||
template<size_t n, class T>
|
||||
est2_t<void> jacknife(const est_t<vec<n, T>> est, sq_mat<n, T>& cov, vec<n, T>& bias) {
|
||||
return [est, &cov, &bias](map_t map) -> void
|
||||
{
|
||||
bias = est(map);
|
||||
for(size_t i = 0; i < n; i++)
|
||||
{
|
||||
bias[i].print();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void print_cov_ratio() {
|
||||
sq_mat<2, T> cov_jn;
|
||||
vec<2, T> bias;
|
||||
jacknife<2, T>([](map_t map) -> vec<2, T> { vec<2, T> retv; retv[0] = 1; retv[1] = 1; return retv; }, cov_jn, bias)(id_map());
|
||||
}
|
||||
struct ab {
|
||||
long long unsigned a;
|
||||
short unsigned b;
|
||||
double operator()() { return a; }
|
||||
ab& operator=(double rhs) { a = rhs; return *this; }
|
||||
void print();
|
||||
};
|
||||
|
||||
void
|
||||
ab::print()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
print_cov_ratio<ab>();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue