diff options
author | Martin Jambor <mjambor@suse.cz> | 2010-06-25 14:46:41 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2010-06-25 14:46:41 +0200 |
commit | 8aa29647d374a66e695423659a6607ec63c4675a (patch) | |
tree | 82fbcbdeb6c7649ca76ce539f4c5d1b7d2957cd7 /gcc | |
parent | 7a2eceff8f1f275c2cda0ac25db354697bf33f7d (diff) | |
download | gcc-8aa29647d374a66e695423659a6607ec63c4675a.zip gcc-8aa29647d374a66e695423659a6607ec63c4675a.tar.gz gcc-8aa29647d374a66e695423659a6607ec63c4675a.tar.bz2 |
ipa-prop.c (determine_cst_member_ptr): Ignore non-clobbering statements instead of bailing out on them.
2010-06-25 Martin Jambor <mjambor@suse.cz>
* ipa-prop.c (determine_cst_member_ptr): Ignore non-clobbering
statements instead of bailing out on them.
(ipa_analyze_indirect_call_uses): Do not require that loads from the
parameter are in the same BB as the condition. Update comments.
* testsuite/g++.dg/ipa/iinline-2.C: New test.
From-SVN: r161377
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/iinline-2.C | 61 |
4 files changed, 85 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a63014..c0768ae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2010-06-25 Martin Jambor <mjambor@suse.cz> + + * ipa-prop.c (determine_cst_member_ptr): Ignore non-clobbering + statements instead of bailing out on them. + (ipa_analyze_indirect_call_uses): Do not require that loads from the + parameter are in the same BB as the condition. Update comments. + 2010-06-25 Jakub Jelinek <jakub@redhat.com> PR middle-end/43866 diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 38eb3c0..8b537f4 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -806,6 +806,8 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field, gimple stmt = gsi_stmt (gsi); tree lhs, rhs, fld; + if (!stmt_may_clobber_ref_p (stmt, arg)) + continue; if (!gimple_assign_single_p (stmt)) return; @@ -814,7 +816,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field, if (TREE_CODE (lhs) != COMPONENT_REF || TREE_OPERAND (lhs, 0) != arg) - continue; + return; fld = TREE_OPERAND (lhs, 1); if (!method && fld == method_field) @@ -1030,6 +1032,10 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt, <bb 2>: f$__delta_5 = f.__delta; f$__pfn_24 = f.__pfn; + + ... + + <bb 5> D.2496_3 = (int) f$__pfn_24; D.2497_4 = D.2496_3 & 1; if (D.2497_4 != 0) @@ -1037,7 +1043,7 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt, else goto <bb 4>; - <bb 3>: + <bb 6>: D.2500_7 = (unsigned int) f$__delta_5; D.2501_8 = &S + D.2500_7; D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8; @@ -1048,7 +1054,7 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt, D.2507_15 = *D.2506_14; iftmp.11_16 = (String:: *) D.2507_15; - <bb 4>: + <bb 7>: # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)> D.2500_19 = (unsigned int) f$__delta_5; D.2508_20 = &S + D.2500_19; @@ -1109,17 +1115,18 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, d1 = SSA_NAME_DEF_STMT (n1); d2 = SSA_NAME_DEF_STMT (n2); + join = gimple_bb (def); if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false))) { if (ipa_get_stmt_member_ptr_load_param (d2, false)) return; - bb = gimple_bb (d1); + bb = EDGE_PRED (join, 0)->src; virt_bb = gimple_bb (d2); } else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false))) { - bb = gimple_bb (d2); + bb = EDGE_PRED (join, 1)->src; virt_bb = gimple_bb (d1); } else @@ -1128,7 +1135,6 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, /* Second, we need to check that the basic blocks are laid out in the way corresponding to the pattern. */ - join = gimple_bb (def); if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb) || single_pred (virt_bb) != bb || single_succ (virt_bb) != join) @@ -1138,7 +1144,7 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, significant bit of the pfn. */ branch = last_stmt (bb); - if (gimple_code (branch) != GIMPLE_COND) + if (!branch || gimple_code (branch) != GIMPLE_COND) return; if (gimple_cond_code (branch) != NE_EXPR diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7f20137..08dc827 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-06-25 Martin Jambor <mjambor@suse.cz> + + * g++.dg/ipa/iinline-2.C: New test. + 2010-06-25 Jakub Jelinek <jakub@redhat.com> PR middle-end/43866 diff --git a/gcc/testsuite/g++.dg/ipa/iinline-2.C b/gcc/testsuite/g++.dg/ipa/iinline-2.C new file mode 100644 index 0000000..670a5dd --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/iinline-2.C @@ -0,0 +1,61 @@ +/* Verify that simple indirect calls are inlined even without early + inlining.. */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining" } */ +/* { dg-add-options bind_pic_locally } */ + +extern void non_existent (const char *, int); + +class String +{ +private: + const char *data; + +public: + String (const char *d) : data(d) + {} + + int funcOne (int delim) const; + int printStuffTwice (int delim) const; +}; + + +int String::funcOne (int delim) const +{ + int i; + for (i = 0; i < delim; i++) + non_existent(data, i); + + return 1; +} + +extern int global; + +int docalling (int c, int (String::* f)(int delim) const) +{ + String S ("muhehehe"); + + if (c > 2) + global = 3; + else + global = 5; + + return (S.*f)(4); +} + +int __attribute__ ((noinline,noclone)) get_input (void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + int i = 0; + while (i < 1000) + i += docalling (get_input (), &String::funcOne); + non_existent ("done", i); + return 0; +} + +/* { dg-final { scan-ipa-dump "String::funcOne\[^\\n\]*inline copy in int main" "inline" } } */ +/* { dg-final { cleanup-ipa-dump "inline" } } */ |