OSDN Git Service

2010-06-25 Martin Jambor <mjambor@suse.cz>
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 Jun 2010 12:46:41 +0000 (12:46 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 Jun 2010 12:46:41 +0000 (12:46 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161377 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ipa-prop.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/iinline-2.C [new file with mode: 0644]

index 5a63014..c0768ae 100644 (file)
@@ -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
index 38eb3c0..8b537f4 100644 (file)
@@ -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
index 7f20137..08dc827 100644 (file)
@@ -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 (file)
index 0000000..670a5dd
--- /dev/null
@@ -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" } } */