OSDN Git Service

2010-04-12 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Apr 2010 15:20:48 +0000 (15:20 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Apr 2010 15:20:48 +0000 (15:20 +0000)
* gsstruct.def (GSS_CALL): New.
* gimple.def (GIMPLE_CALL): Change to GSS_CALL.
* gimple.h: Include tree-ssa-alias.h.
(struct gimple_statement_call): New.
(union gimple_statement_struct_d): Add gimple_call member.
(gimple_call_reset_alias_info): Declare.
(gimple_call_use_set): New function.
(gimple_call_clobber_set): Likewise.
* Makefile.in (GIMPLE_H): Add tree-ssa-alias.h.
* gimple.c (gimple_call_reset_alias_info): New function.
(gimple_build_call_1): Call it.
* lto-streamer-in.c (input_gimple_stmt): Likewise.
* tree-inline.c (remap_gimple_stmt): Likewise.
(expand_call_inline): Remove callused handling.
* cfgexpand.c (update_alias_info_with_stack_vars): Likewise.
* tree-dfa.c (dump_variable): Likewise.
* tree-parloops.c (parallelize_loops): Likewise.
* tree-ssa.c (init_tree_ssa): Likewise.
(delete_tree_ssa): Likewise.
* tree-flow-inline.h (is_call_used): Remove.
* tree-flow.h (struct gimple_df): Remove callused member.
* tree-nrv.c (dest_safe_for_nrv_p): Adjust predicate.
* tree-ssa-alias.c (dump_alias_info): Remove callused handling.
(ref_maybe_used_by_call_p_1): Simplify.
(call_may_clobber_ref_p_1): Likewise.
* tree-ssa-structalias.c (compute_points_to_sets): Set
the call stmt used and clobbered sets.
* tree-tailcall.c (suitable_for_tail_opt_p): Adjust predicate.
(find_tail_calls): Verify the tail call.

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

17 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/gimple.c
gcc/gimple.def
gcc/gimple.h
gcc/gsstruct.def
gcc/lto-streamer-in.c
gcc/tree-dfa.c
gcc/tree-flow-inline.h
gcc/tree-flow.h
gcc/tree-inline.c
gcc/tree-nrv.c
gcc/tree-parloops.c
gcc/tree-ssa-alias.c
gcc/tree-ssa-structalias.c
gcc/tree-ssa.c
gcc/tree-tailcall.c

index 91a18dc..136ffae 100644 (file)
@@ -1,5 +1,37 @@
 2010-04-12  Richard Guenther  <rguenther@suse.de>
 
+       * gsstruct.def (GSS_CALL): New.
+       * gimple.def (GIMPLE_CALL): Change to GSS_CALL.
+       * gimple.h: Include tree-ssa-alias.h.
+       (struct gimple_statement_call): New.
+       (union gimple_statement_struct_d): Add gimple_call member.
+       (gimple_call_reset_alias_info): Declare.
+       (gimple_call_use_set): New function.
+       (gimple_call_clobber_set): Likewise.
+       * Makefile.in (GIMPLE_H): Add tree-ssa-alias.h.
+       * gimple.c (gimple_call_reset_alias_info): New function.
+       (gimple_build_call_1): Call it.
+       * lto-streamer-in.c (input_gimple_stmt): Likewise.
+       * tree-inline.c (remap_gimple_stmt): Likewise.
+       (expand_call_inline): Remove callused handling.
+       * cfgexpand.c (update_alias_info_with_stack_vars): Likewise.
+       * tree-dfa.c (dump_variable): Likewise.
+       * tree-parloops.c (parallelize_loops): Likewise.
+       * tree-ssa.c (init_tree_ssa): Likewise.
+       (delete_tree_ssa): Likewise.
+       * tree-flow-inline.h (is_call_used): Remove.
+       * tree-flow.h (struct gimple_df): Remove callused member.
+       * tree-nrv.c (dest_safe_for_nrv_p): Adjust predicate.
+       * tree-ssa-alias.c (dump_alias_info): Remove callused handling.
+       (ref_maybe_used_by_call_p_1): Simplify.
+       (call_may_clobber_ref_p_1): Likewise.
+       * tree-ssa-structalias.c (compute_points_to_sets): Set
+       the call stmt used and clobbered sets.
+       * tree-tailcall.c (suitable_for_tail_opt_p): Adjust predicate.
+       (find_tail_calls): Verify the tail call.
+
+2010-04-12  Richard Guenther  <rguenther@suse.de>
+
        * ipa.c (cgraph_postorder): Adjust postorder to guarantee
        single-iteration always-inline inlining.
        * ipa-inline.c (cgraph_mark_inline): Do not return anything.
index 99811e7..c1cec39 100644 (file)
@@ -876,7 +876,8 @@ BASIC_BLOCK_H = basic-block.h $(BITMAP_H) sbitmap.h varray.h $(PARTITION_H) \
           hard-reg-set.h $(PREDICT_H) vec.h $(FUNCTION_H) \
           cfghooks.h $(OBSTACK_H)
 GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h vec.h \
-       $(GGC_H) $(BASIC_BLOCK_H) $(TM_H) $(TARGET_H) tree-ssa-operands.h
+       $(GGC_H) $(BASIC_BLOCK_H) $(TM_H) $(TARGET_H) tree-ssa-operands.h \
+       tree-ssa-alias.h
 GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
 COVERAGE_H = coverage.h $(GCOV_IO_H)
 DEMANGLE_H = $(srcdir)/../include/demangle.h
index ae0be4e..ce1f75a 100644 (file)
@@ -198,6 +198,21 @@ gimple_build_return (tree retval)
   return s;
 }
 
+/* Reset alias information on call S.  */
+
+void
+gimple_call_reset_alias_info (gimple s)
+{
+  if (gimple_call_flags (s) & ECF_CONST)
+    memset (gimple_call_use_set (s), 0, sizeof (struct pt_solution));
+  else
+    pt_solution_reset (gimple_call_use_set (s));
+  if (gimple_call_flags (s) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
+    memset (gimple_call_clobber_set (s), 0, sizeof (struct pt_solution));
+  else
+    pt_solution_reset (gimple_call_clobber_set (s));
+}
+
 /* Helper for gimple_build_call, gimple_build_call_vec and
    gimple_build_call_from_tree.  Build the basic components of a
    GIMPLE_CALL statement to function FN with NARGS arguments.  */
@@ -209,6 +224,7 @@ gimple_build_call_1 (tree fn, unsigned nargs)
   if (TREE_CODE (fn) == FUNCTION_DECL)
     fn = build_fold_addr_expr (fn);
   gimple_set_op (s, 1, fn);
+  gimple_call_reset_alias_info (s);
   return s;
 }
 
index 7a1503c..49aa88e 100644 (file)
@@ -122,7 +122,7 @@ DEFGSCODE(GIMPLE_ASM, "gimple_asm", GSS_ASM)
    is_gimple_operand.
 
     CHAIN is the optional static chain link for nested functions.  */
-DEFGSCODE(GIMPLE_CALL, "gimple_call", GSS_WITH_MEM_OPS)
+DEFGSCODE(GIMPLE_CALL, "gimple_call", GSS_CALL)
 
 /* GIMPLE_RETURN <RETVAL> represents return statements.
 
index b09e856..9df6e92 100644 (file)
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hard-reg-set.h"
 #include "basic-block.h"
 #include "tree-ssa-operands.h"
+#include "tree-ssa-alias.h"
 
 DEF_VEC_P(gimple);
 DEF_VEC_ALLOC_P(gimple,heap);
@@ -390,6 +391,25 @@ struct GTY(()) gimple_statement_with_memory_ops
 };
 
 
+/* Call statements that take both memory and register operands.  */
+
+struct GTY(()) gimple_statement_call
+{
+  /* [ WORD 1-8 ]  */
+  struct gimple_statement_with_memory_ops_base membase;
+
+  /* [ WORD 9-12 ]  */
+  struct pt_solution call_used;
+  struct pt_solution call_clobbered;
+
+  /* [ WORD 13 ]
+     Operand vector.  NOTE!  This must always be the last field
+     of this structure.  In particular, this means that this
+     structure cannot be embedded inside another one.  */
+  tree GTY((length ("%h.membase.opbase.gsbase.num_ops"))) op[1];
+};
+
+
 /* OpenMP statements (#pragma omp).  */
 
 struct GTY(()) gimple_statement_omp {
@@ -739,6 +759,7 @@ union GTY ((desc ("gimple_statement_structure (&%h)"))) gimple_statement_d {
   struct gimple_statement_with_ops GTY ((tag ("GSS_WITH_OPS"))) gsops;
   struct gimple_statement_with_memory_ops_base GTY ((tag ("GSS_WITH_MEM_OPS_BASE"))) gsmembase;
   struct gimple_statement_with_memory_ops GTY ((tag ("GSS_WITH_MEM_OPS"))) gsmem;
+  struct gimple_statement_call GTY ((tag ("GSS_CALL"))) gimple_call;
   struct gimple_statement_omp GTY ((tag ("GSS_OMP"))) omp;
   struct gimple_statement_bind GTY ((tag ("GSS_BIND"))) gimple_bind;
   struct gimple_statement_catch GTY ((tag ("GSS_CATCH"))) gimple_catch;
@@ -836,6 +857,7 @@ void gimple_seq_free (gimple_seq);
 void gimple_seq_add_seq (gimple_seq *, gimple_seq);
 gimple_seq gimple_seq_copy (gimple_seq);
 int gimple_call_flags (const_gimple);
+void gimple_call_reset_alias_info (gimple);
 bool gimple_assign_copy_p (gimple);
 bool gimple_assign_ssa_name_copy_p (gimple);
 bool gimple_assign_single_p (gimple);
@@ -2200,6 +2222,28 @@ gimple_call_copy_flags (gimple dest_call, gimple orig_call)
 }
 
 
+/* Return a pointer to the points-to solution for the set of call-used
+   variables of the call CALL.  */
+
+static inline struct pt_solution *
+gimple_call_use_set (gimple call)
+{
+  GIMPLE_CHECK (call, GIMPLE_CALL);
+  return &call->gimple_call.call_used;
+}
+
+
+/* Return a pointer to the points-to solution for the set of call-used
+   variables of the call CALL.  */
+
+static inline struct pt_solution *
+gimple_call_clobber_set (gimple call)
+{
+  GIMPLE_CHECK (call, GIMPLE_CALL);
+  return &call->gimple_call.call_clobbered;
+}
+
+
 /* Returns true if this is a GIMPLE_ASSIGN or a GIMPLE_CALL with a
    non-NULL lhs.  */
 
index 7fd9547..578d2c1 100644 (file)
@@ -29,6 +29,7 @@ DEFGSSTRUCT(GSS_BASE, gimple_statement_base, false)
 DEFGSSTRUCT(GSS_WITH_OPS, gimple_statement_with_ops, true)
 DEFGSSTRUCT(GSS_WITH_MEM_OPS_BASE, gimple_statement_with_memory_ops_base, false)
 DEFGSSTRUCT(GSS_WITH_MEM_OPS, gimple_statement_with_memory_ops, true)
+DEFGSSTRUCT(GSS_CALL, gimple_statement_call, true)
 DEFGSSTRUCT(GSS_ASM, gimple_statement_asm, true)
 DEFGSSTRUCT(GSS_BIND, gimple_statement_bind, false)
 DEFGSSTRUCT(GSS_PHI, gimple_statement_phi, false)
index 53b1c33..6afad5b 100644 (file)
@@ -1157,6 +1157,10 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
        }
     }
 
+  /* Reset alias information.  */
+  if (code == GIMPLE_CALL)
+    gimple_call_reset_alias_info (stmt);
+
   /* Fixup reference tree operands for substituted prevailing decls
      with mismatched types.  */
   maybe_fixup_decls (stmt);
index a918f4b..bd91e3b 100644 (file)
@@ -284,8 +284,6 @@ dump_variable (FILE *file, tree var)
 
   if (is_call_clobbered (var))
     fprintf (file, ", call clobbered");
-  else if (is_call_used (var))
-    fprintf (file, ", call used");
 
   if (ann && ann->noalias_state == NO_ALIAS)
     fprintf (file, ", NO_ALIAS (does not alias other NO_ALIAS symbols)");
index 7faa585..2430f03 100644 (file)
@@ -633,15 +633,6 @@ is_call_clobbered (const_tree var)
              && pt_solution_includes (&cfun->gimple_df->escaped, var)));
 }
 
-/* Return true if VAR is used by function calls.  */
-static inline bool
-is_call_used (const_tree var)
-{
-  return (is_call_clobbered (var)
-         || (may_be_aliased (var)
-             && pt_solution_includes (&cfun->gimple_df->callused, var)));
-}
-
 /*  -----------------------------------------------------------------------  */
 
 /* The following set of routines are used to iterator over various type of
index 7bb5088..82b8109 100644 (file)
@@ -56,9 +56,6 @@ struct GTY(()) gimple_df {
   /* The PTA solution for the ESCAPED artificial variable.  */
   struct pt_solution escaped;
 
-  /* The PTA solution for the CALLUSED artificial variable.  */
-  struct pt_solution callused;
-
   /* A map of decls to artificial ssa-names that point to the partition
      of the decl.  */
   struct pointer_map_t * GTY((skip(""))) decls_to_pointers;
index e0928b9..922ce52 100644 (file)
@@ -1391,6 +1391,13 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
                  default:
                    break;
                  }
+
+             /* Reset alias info.
+                ???  By maintaining DECL_PT_UID this should not
+                be necessary, but the plan is to only maintain
+                it when IPA-PTA was run.  It's not too easy to
+                detect this here ...  */
+             gimple_call_reset_alias_info (copy);
            }
            break;
 
@@ -3724,12 +3731,9 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
             cg_edge->frequency * REG_BR_PROB_BASE / CGRAPH_FREQ_BASE,
             bb, return_block);
 
-  /* Reset the escaped and callused solutions.  */
+  /* Reset the escaped solution.  */
   if (cfun->gimple_df)
-    {
-      pt_solution_reset (&cfun->gimple_df->escaped);
-      pt_solution_reset (&cfun->gimple_df->callused);
-    }
+    pt_solution_reset (&cfun->gimple_df->escaped);
 
   /* Clean up.  */
   if (id->debug_map)
index a825a7a..b85c5a7 100644 (file)
@@ -307,7 +307,7 @@ dest_safe_for_nrv_p (tree dest)
   if (TREE_CODE (dest) == SSA_NAME)
     dest = SSA_NAME_VAR (dest);
 
-  if (is_call_used (dest))
+  if (is_call_clobbered (dest))
     return false;
 
   return true;
index b8a883f..c4ac89b 100644 (file)
@@ -1977,13 +1977,10 @@ parallelize_loops (void)
   htab_delete (reduction_list);
 
   /* Parallelization will cause new function calls to be inserted through
-     which local variables will escape.  Reset the points-to solutions
-     for ESCAPED and CALLUSED.  */
+     which local variables will escape.  Reset the points-to solution
+     for ESCAPED.  */
   if (changed)
-    {
-      pt_solution_reset (&cfun->gimple_df->escaped);
-      pt_solution_reset (&cfun->gimple_df->callused);
-    }
+    pt_solution_reset (&cfun->gimple_df->escaped);
 
   return changed;
 }
index 282148c..7f09df8 100644 (file)
@@ -336,8 +336,6 @@ dump_alias_info (FILE *file)
 
   fprintf (file, "\nESCAPED");
   dump_points_to_solution (file, &cfun->gimple_df->escaped);
-  fprintf (file, "\nCALLUSED");
-  dump_points_to_solution (file, &cfun->gimple_df->callused);
 
   fprintf (file, "\n\nFlow-insensitive points-to information\n\n");
 
@@ -1070,51 +1068,24 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref)
        goto process_args;
     }
 
-  /* If the base variable is call-used or call-clobbered then
-     it may be used.  */
-  if (flags & (ECF_PURE|ECF_CONST|ECF_LOOPING_CONST_OR_PURE|ECF_NOVOPS))
+  /* Check if the base variable is call-used.  */
+  if (DECL_P (base))
     {
-      if (DECL_P (base))
-       {
-         if (is_call_used (base))
-           return true;
-       }
-      else if (INDIRECT_REF_P (base)
-              && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
-       {
-         struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
-         if (!pi)
-           return true;
-
-         if (pt_solution_includes_global (&pi->pt)
-             || pt_solutions_intersect (&cfun->gimple_df->callused, &pi->pt)
-             || pt_solutions_intersect (&cfun->gimple_df->escaped, &pi->pt))
-           return true;
-       }
-      else
+      if (pt_solution_includes (gimple_call_use_set (call), base))
        return true;
     }
-  else
+  else if (INDIRECT_REF_P (base)
+          && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
     {
-      if (DECL_P (base))
-       {
-         if (is_call_clobbered (base))
-           return true;
-       }
-      else if (INDIRECT_REF_P (base)
-              && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
-       {
-         struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
-         if (!pi)
-           return true;
+      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
+      if (!pi)
+       return true;
 
-         if (pt_solution_includes_global (&pi->pt)
-             || pt_solutions_intersect (&cfun->gimple_df->escaped, &pi->pt))
-           return true;
-       }
-      else
+      if (pt_solutions_intersect (gimple_call_use_set (call), &pi->pt))
        return true;
     }
+  else
+    return true;
 
   /* Inspect call arguments for passed-by-value aliases.  */
 process_args:
@@ -1347,8 +1318,9 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
        return false;
     }
 
+  /* Check if the base variable is call-clobbered.  */
   if (DECL_P (base))
-    return is_call_clobbered (base);
+    return pt_solution_includes (gimple_call_clobber_set (call), base);
   else if (INDIRECT_REF_P (base)
           && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
     {
@@ -1356,8 +1328,7 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
       if (!pi)
        return true;
 
-      return (pt_solution_includes_global (&pi->pt)
-             || pt_solutions_intersect (&cfun->gimple_df->escaped, &pi->pt));
+      return pt_solutions_intersect (gimple_call_clobber_set (call), &pi->pt);
     }
 
   return true;
index 2384099..e14b97a 100644 (file)
@@ -5480,6 +5480,7 @@ compute_points_to_sets (void)
   basic_block bb;
   unsigned i;
   varinfo_t vi;
+  struct pt_solution callused;
 
   timevar_push (TV_TREE_PTA);
 
@@ -5516,8 +5517,7 @@ compute_points_to_sets (void)
      call-clobber analysis.  */
   find_what_var_points_to (get_varinfo (escaped_id),
                           &cfun->gimple_df->escaped);
-  find_what_var_points_to (get_varinfo (callused_id),
-                          &cfun->gimple_df->callused);
+  find_what_var_points_to (get_varinfo (callused_id), &callused);
 
   /* Make sure the ESCAPED solution (which is used as placeholder in
      other solutions) does not reference itself.  This simplifies
@@ -5541,6 +5541,48 @@ compute_points_to_sets (void)
        find_what_p_points_to (ptr);
     }
 
+  /* Compute the call-used/clobbered sets.  */
+  FOR_EACH_BB (bb)
+    {
+      gimple_stmt_iterator gsi;
+
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+       {
+         gimple stmt = gsi_stmt (gsi);
+         struct pt_solution *pt;
+         if (!is_gimple_call (stmt))
+           continue;
+
+         pt = gimple_call_use_set (stmt);
+         if (gimple_call_flags (stmt) & ECF_CONST)
+           memset (pt, 0, sizeof (struct pt_solution));
+         else if (gimple_call_flags (stmt) & ECF_PURE)
+           {
+             /* For const calls we should now be able to compute the
+                call-used set per function.  */
+             *pt = callused;
+             /* ???  ESCAPED can be empty even though NONLOCAL
+                always escaped.  */
+             pt->nonlocal = 1;
+             pt->escaped = 1;
+           }
+         else
+           {
+             *pt = cfun->gimple_df->escaped;
+             pt->nonlocal = 1;
+           }
+
+         pt = gimple_call_clobber_set (stmt);
+         if (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE|ECF_NOVOPS))
+           memset (pt, 0, sizeof (struct pt_solution));
+         else
+           {
+             *pt = cfun->gimple_df->escaped;
+             pt->nonlocal = 1;
+           }
+       }
+    }
+
   timevar_pop (TV_TREE_PTA);
 }
 
index 9947e57..7915bb8 100644 (file)
@@ -1123,7 +1123,6 @@ init_tree_ssa (struct function *fn)
   fn->gimple_df->default_defs = htab_create_ggc (20, uid_ssaname_map_hash,
                                                 uid_ssaname_map_eq, NULL);
   pt_solution_reset (&fn->gimple_df->escaped);
-  pt_solution_reset (&fn->gimple_df->callused);
   init_ssanames (fn, 0);
   init_phinodes ();
 }
@@ -1163,7 +1162,6 @@ delete_tree_ssa (void)
   htab_delete (cfun->gimple_df->default_defs);
   cfun->gimple_df->default_defs = NULL;
   pt_solution_reset (&cfun->gimple_df->escaped);
-  pt_solution_reset (&cfun->gimple_df->callused);
   if (cfun->gimple_df->decls_to_pointers != NULL)
     pointer_map_destroy (cfun->gimple_df->decls_to_pointers);
   cfun->gimple_df->decls_to_pointers = NULL;
index 2ecca4a..e0d3f48 100644 (file)
@@ -136,11 +136,23 @@ suitable_for_tail_opt_p (void)
   if (cfun->stdarg)
     return false;
 
-  /* No local variable nor structure field should be call-used.  */
+  /* No local variable nor structure field should escape to callees.  */
   FOR_EACH_REFERENCED_VAR (var, rvi)
     {
       if (!is_global_var (var)
-         && is_call_used (var))
+         /* ???  We do not have a suitable predicate for escaping to
+            callees.  With IPA-PTA the following might be incorrect.
+            We want to catch
+              foo {
+                int i;
+                bar (&i);
+                foo ();
+              }
+            where bar might store &i somewhere and in the next
+            recursion should not be able to tell if it got the
+            same (with tail-recursion applied) or a different
+            address.  */
+         && is_call_clobbered (var))
        return false;
     }
 
@@ -430,7 +442,9 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
   func = gimple_call_fndecl (call);
   if (func == current_function_decl)
     {
-      tree arg;
+      tree arg, var;
+      referenced_var_iterator rvi;
+
       for (param = DECL_ARGUMENTS (func), idx = 0;
           param && idx < gimple_call_num_args (call);
           param = TREE_CHAIN (param), idx ++)
@@ -460,6 +474,15 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
        }
       if (idx == gimple_call_num_args (call) && !param)
        tail_recursion = true;
+
+      /* Make sure the tail invocation of this function does not refer
+        to local variables.  */
+      FOR_EACH_REFERENCED_VAR (var, rvi)
+       {
+         if (!is_global_var (var)
+             && ref_maybe_used_by_stmt_p (call, var))
+           return;
+       }
     }
 
   /* Now check the statements after the call.  None of them has virtual