Commit a0f6a8cb by Feng Xue

Generalized value pass-through for self-recusive function (PR ipa/93203)

Besides simple pass-through (aggregate) jump function, arithmetic (aggregate)
jump function could also bring same (aggregate) value as parameter passed-in
for self-feeding recursive call.  For example,

      f1 (int i)    /*  normal jump function */
         {
            f1 (i & 1);
         }

Suppose i is 0, recursive propagation via (i & 1) also gets 0, which
can be seen as a simple pass-through of i.

      f2 (int *p)  /* aggregate jump function */
         {
            int t = *p & 1;
            f2 (&t);
         }
Likewise, if *p is 0, (*p & 1) is also 0, and &t is an aggregate simple
pass-through of p.

2020-02-10  Feng Xue  <fxue@os.amperecomputing.com>

        PR ipa/93203
        * ipa-cp.c (ipcp_lattice::add_value): Add source with same call edge
        but different source value.
        (adjust_callers_for_value_intersection): New function.
        (gather_edges_for_value): Adjust order of callers to let a
        non-self-recursive caller be the first element.
        (self_recursive_pass_through_p): Add a new parameter "simple", and
        check generalized self-recursive pass-through jump function.
        (self_recursive_agg_pass_through_p): Likewise.
        (find_more_scalar_values_for_callers_subset): Compute value from
        pass-through jump function for self-recursive.
        (intersect_with_plats): Cleanup previous implementation code for value
        itersection with self-recursive call edge.
        (intersect_with_agg_replacements): Likewise.
        (intersect_aggregates_with_edge): Deduce value from pass-through jump
        function for self-recursive call edge.  Cleanup previous implementation
        code for value intersection with self-recursive call edge.
        (decide_whether_version_node): Remove dead callers and adjust order
        to let a non-self-recursive caller be the first element.

        PR ipa/93203
        * g++.dg/ipa/pr93203.C: New test.
parent 04c3a1f2
2020-02-10 Feng Xue <fxue@os.amperecomputing.com>
PR ipa/93203
* ipa-cp.c (ipcp_lattice::add_value): Add source with same call edge
but different source value.
(adjust_callers_for_value_intersection): New function.
(gather_edges_for_value): Adjust order of callers to let a
non-self-recursive caller be the first element.
(self_recursive_pass_through_p): Add a new parameter "simple", and
check generalized self-recursive pass-through jump function.
(self_recursive_agg_pass_through_p): Likewise.
(find_more_scalar_values_for_callers_subset): Compute value from
pass-through jump function for self-recursive.
(intersect_with_plats): Cleanup previous implementation code for value
itersection with self-recursive call edge.
(intersect_with_agg_replacements): Likewise.
(intersect_aggregates_with_edge): Deduce value from pass-through jump
function for self-recursive call edge. Cleanup previous implementation
code for value intersection with self-recursive call edge.
(decide_whether_version_node): Remove dead callers and adjust order
to let a non-self-recursive caller be the first element.
2020-02-09 Uroš Bizjak <ubizjak@gmail.com>
* recog.c: Move pass_split_before_sched2 code in front of
......
2020-02-10 Feng Xue <fxue@os.amperecomputing.com>
PR ipa/93203
* g++.dg/ipa/pr93203.C: New test.
2020-02-09 Uroš Bizjak <ubizjak@gmail.com>
* gcc.target/i386/pr91333.c (dg-do): Fix target selector.
......
/* { dg-do compile } */
/* { dg-options "-O3 -w -std=gnu++11" } */
class a {
public:
a(char *);
};
class ad {
public:
ad(a *);
};
class b {};
using ah = class ak {
using al = char;
public:
ak(b) : ak(0) {}
ak an() { return ap & 1; }
al ap;
ak(al af) : ap(af) {}
};
struct at {
ah au;
int av;
char aw;
char ax;
};
class az {
public:
struct ba {
void bb(ak am) {
ak bc = am.an();
bb(bc);
}
};
void bd(ak am) { be.bb(am); }
ba be;
};
class bg {
public:
int bh;
at bi;
};
int bj;
int *bk;
int c;
class bl {
bool bm();
bg bn;
az bo;
int e;
int bq;
};
class bs {
public:
bs(int *, ah *, char *, char *, int);
};
template < typename bt > class bu : bs {
using bv = typename bt::bv;
public:
template < typename... bx >
bu(a *by, int *bz, at body, bx...)
: bs(bz, &body.au, &body.aw, &body.ax, body.av), ca(bx()...), cb(by),
cc(by), cd(by), ce(by) {}
void cf() {
auto cg = ch();
auto ci = *cj();
ca.ck(this, cg, &ci);
}
bt ca;
ad cb;
ad cc;
ad cd;
ad ce;
bv *cj();
bv ch();
};
class cl {
public:
using bv = struct {};
cl(az *, int, int, int, int, a *, int, int **);
void ck(bs *, bv, bv *) {
b d;
ak ci(d);
bo.bd(ci);
}
az bo;
};
bool bl::bm() {
a by("");
bu< cl > cn(&by, &bj, bn.bi, &bo, c, bn.bh, e, 0, &by, bq, &bk);
cn.cf();
}
......@@ -45,7 +45,7 @@ main (int argc, char *argv[])
}
/* { dg-final { scan-ipa-dump "Creating a specialized node of f.*for all known contexts" "cp" } } */
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
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