This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch for PR39557


See the attached.

David

On Wed, Mar 25, 2009 at 11:30 PM, Paolo Bonzini <bonzini@gnu.org> wrote:
>> Index: testsuite/g++.dg/tree-ssa/dom-invalid.C
>
> Same concern for the test size.  Otherwise seems ok to me, even though I
> cannot approve it.
>
> Paolo
>
Index: tree-ssa.c
===================================================================
--- tree-ssa.c	(revision 145035)
+++ tree-ssa.c	(working copy)
@@ -1589,6 +1589,11 @@ warn_uninitialized_vars (bool warn_possi
 	  walk_gimple_op (gsi_stmt (gsi), warn_uninitialized_var, &wi);
 	}
     }
+
+  /* Post-dominator information can not be reliably updated. Free it
+     after the use.  */
+
+  free_dominance_info (CDI_POST_DOMINATORS);
   return 0;
 }
 
Index: dominance.c
===================================================================
--- dominance.c	(revision 145035)
+++ dominance.c	(working copy)
@@ -47,6 +47,7 @@
 #include "vecprim.h"
 #include "pointer-set.h"
 #include "graphds.h"
+#include "params.h"
 
 /* We name our nodes with integers, beginning with 1.  Zero is reserved for
    'undefined' or 'end of list'.  The name of each node is given by the dfs
@@ -666,6 +667,10 @@ calculate_dominance_info (enum cdi_direc
       free_dom_info (&di);
       dom_computed[dir_index] = DOM_NO_FAST_QUERY;
     }
+#ifdef ENABLE_CHECKING
+  else if (PARAM_VALUE (PARAM_CHECK_DOM))
+    verify_dominators (dir);
+#endif
 
   compute_dom_fast_query (dir);
 
Index: params.def
===================================================================
--- params.def	(revision 145035)
+++ params.def	(working copy)
@@ -771,6 +771,13 @@ DEFPARAM (PARAM_LOOP_INVARIANT_MAX_BBS_I
 	  "max basic blocks number in loop for loop invariant motion",
 	  10000, 0, 0)
 
+/* Enable dominance information validation.  */
+
+DEFPARAM (PARAM_CHECK_DOM,
+	  "verify-dom",
+	  "enable verficiation of dominance information",
+	  0, 0, 1)
+
 /*
 Local variables:
 mode:c
Index: ira.c
===================================================================
--- ira.c	(revision 145035)
+++ ira.c	(working copy)
@@ -3055,6 +3055,7 @@ ira (FILE *f)
   int rebuild_p;
   int saved_flag_ira_share_spill_slots;
   basic_block bb;
+  bool cfg_changed = false;
 
   timevar_push (TV_IRA);
 
@@ -3153,7 +3154,7 @@ ira (FILE *f)
       
   ira_max_point_before_emit = ira_max_point;
       
-  ira_emit (loops_p);
+  cfg_changed = ira_emit (loops_p);
   
   if (ira_conflicts_p)
     {
@@ -3175,6 +3176,9 @@ ira (FILE *f)
 	     info.  */
 	  df_analyze ();
 	  
+          if (cfg_changed)
+            /* Edge split in ira_emit might have invalidated the dom info.  */
+            free_dominance_info (CDI_DOMINATORS);
 	  flow_loops_find (&ira_loops);
 	  current_loops = &ira_loops;
 
Index: ira-emit.c
===================================================================
--- ira-emit.c	(revision 145035)
+++ ira-emit.c	(working copy)
@@ -1047,8 +1047,8 @@ add_ranges_and_copies (void)
 
 /* The entry function changes code and generates shuffling allocnos on
    region borders for the regional (LOOPS_P is TRUE in this case)
-   register allocation.  */
-void
+   register allocation.  Returns true of any changes are made in cfg.   */
+bool
 ira_emit (bool loops_p)
 {
   basic_block bb;
@@ -1057,11 +1057,12 @@ ira_emit (bool loops_p)
   edge e;
   ira_allocno_t a;
   ira_allocno_iterator ai;
+  bool cfg_changed = false;
 
   FOR_EACH_ALLOCNO (a, ai)
     ALLOCNO_REG (a) = regno_reg_rtx[ALLOCNO_REGNO (a)];
   if (! loops_p)
-    return;
+    return false;
   at_bb_start = (move_t *) ira_allocate (sizeof (move_t) * last_basic_block);
   memset (at_bb_start, 0, sizeof (move_t) * last_basic_block);
   at_bb_end = (move_t *) ira_allocate (sizeof (move_t) * last_basic_block);
@@ -1112,7 +1113,7 @@ ira_emit (bool loops_p)
   VEC_free (move_t, heap, move_vec);
   ira_free (allocno_last_set_check);
   ira_free (allocno_last_set);
-  commit_edge_insertions ();
+  cfg_changed = commit_edge_insertions ();
   /* Fix insn codes.  It is necessary to do it before reload because
      reload assumes initial insn codes defined.  The insn codes can be
      invalidated by CFG infrastructure for example in jump
@@ -1123,4 +1124,5 @@ ira_emit (bool loops_p)
 	recog_memoized (insn);
   ira_free (at_bb_end);
   ira_free (at_bb_start);
+  return cfg_changed;
 }
Index: cfgrtl.c
===================================================================
--- cfgrtl.c	(revision 145035)
+++ cfgrtl.c	(working copy)
@@ -1459,9 +1459,10 @@ commit_one_edge_insertion (edge e)
     bb->aux = &bb->aux;
 }
 
-/* Update the CFG for all queued instructions.  */
+/* Update the CFG for all queued instructions.  Returns true
+   if there is any change.  */
 
-void
+bool
 commit_edge_insertions (void)
 {
   basic_block bb;
@@ -1486,14 +1487,14 @@ commit_edge_insertions (void)
     }
 
   if (!changed)
-    return;
+    return false;
 
   /* In the old rtl CFG API, it was OK to insert control flow on an
      edge, apparently?  In cfglayout mode, this will *not* work, and
      the caller is responsible for making sure that control flow is
      valid at all times.  */
   if (current_ir_type () == IR_RTL_CFGLAYOUT)
-    return;
+    return true;
 
   blocks = sbitmap_alloc (last_basic_block);
   sbitmap_zero (blocks);
@@ -1508,6 +1509,7 @@ commit_edge_insertions (void)
       }
   find_many_sub_basic_blocks (blocks);
   sbitmap_free (blocks);
+  return true;
 }
 
 
Index: ira-int.h
===================================================================
--- ira-int.h	(revision 145035)
+++ ira-int.h	(working copy)
@@ -937,7 +937,7 @@ extern void ira_finish_assign (void);
 extern void ira_color (void);
 
 /* ira-emit.c */
-extern void ira_emit (bool);
+extern bool ira_emit (bool);
 
 
 
Index: basic-block.h
===================================================================
--- basic-block.h	(revision 145035)
+++ basic-block.h	(working copy)
@@ -512,7 +512,7 @@ extern void update_bb_for_insn (basic_bl
 extern void insert_insn_on_edge (rtx, edge);
 basic_block split_edge_and_insert (edge, rtx);
 
-extern void commit_edge_insertions (void);
+extern bool commit_edge_insertions (void);
 
 extern void remove_fake_edges (void);
 extern void remove_fake_exit_edges (void);
Index: testsuite/g++.dg/tree-ssa/dom-invalid.C
===================================================================
--- testsuite/g++.dg/tree-ssa/dom-invalid.C	(revision 0)
+++ testsuite/g++.dg/tree-ssa/dom-invalid.C	(revision 0)
@@ -0,0 +1,96 @@
+// PR 39557 : invalid post-dom info leads to infinite loop
+// { dg-do run }
+/* { dg-options " -Wall -fno-exceptions -O2 -fprofile-use=/blah  -fno-rtti " } */
+
+  typedef long int ptrdiff_t;
+   namespace std __attribute__ ((__visibility__ ("default"))) {
+    struct input_iterator_tag {
+ };
+    struct forward_iterator_tag : public input_iterator_tag {
+ };
+    struct bidirectional_iterator_tag : public forward_iterator_tag {
+ };
+    struct random_access_iterator_tag : public bidirectional_iterator_tag {
+ };
+    template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t,            typename _Pointer = _Tp*, typename _Reference = _Tp&>     struct iterator     {
+     };
+  }
+ namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) {
+    template<typename _CharT>     struct _Char_types     {
+       typedef _CharT char_type;
+       typedef typename _Char_types<_CharT>::int_type int_type;
+       static int_type       to_int_type(const char_type& __c)       {
+ }
+     };
+  }
+  namespace base {
+  template<typename T> struct remove_pointer {
+ };
+  }
+    template<typename It> class fooPtrArrayIterator     : public std::iterator<           std::random_access_iterator_tag,           typename base::remove_pointer<               typename base::remove_pointer<It>::type>::type> {
+ };
+
+  class fooVoidPtrArray {
+  public:   fooVoidPtrArray() : space_(initial_space_),                         avail_(INIT_SIZE),                         alloc_(0),                         size_(0) {   }
+    inline int size() const {     return size_;   }
+   static const int INIT_SIZE = 4;
+   void* initial_space_[INIT_SIZE];
+   void** space_;
+   int avail_;
+   int alloc_;
+   int size_;
+ };
+  template <class T> class fooPtrArray : public fooVoidPtrArray {
+  public:   typedef fooPtrArrayIterator<T**> iterator;
+   inline const T& get(int i) const {     (static_cast<void> (0));     (static_cast<void> (0));     return *(space_as_T()[i]);   }
+  private:   inline T** space_as_T() const { return reinterpret_cast<T**>(space_); }
+ };
+  class blah_1  { 
+  public:   blah_1() {};
+   virtual const char* bar() const;
+ };
+ blah_1 th;
+
+  class blah_3 {
+  public:   friend class _blah_3_NameInfoInit;
+   virtual const char* bar() const;
+ };
+  class blah_2 { 
+  private:   unsigned char hasbits_[2];
+   fooPtrArray<blah_3> exp_info_;
+   static const int kHasBit_ar = 8;
+   const blah_1& ar() const;
+   const blah_1& au() const;
+  public:   bool has_ar() const { return ((hasbits_[kHasBit_ar/8] & (1 << (kHasBit_ar & 0x7)))!=0); }
+   virtual const char* bar() const __attribute__((noinline));
+ };
+  inline const blah_1& blah_2::ar() const {
+  return th;
+ }
+  inline const blah_1& blah_2::au ()const {
+  return th;
+ }
+  const char* blah_1::bar() const {
+   return 0;
+ }
+  const char* blah_3::bar() const {
+   const char* e = __null;
+   return e;
+ }
+  const char* blah_2::bar() const {
+   const char* e = __null;
+   if (has_ar() && ((e=ar().blah_1::bar()))) return e;
+   for (int i = 0, n = exp_info_.size(); i < n; i++) {     
+     if ((e=exp_info_.get(i).blah_3::bar())) return e;   
+    }
+   return e;
+ }
+
+
+ int main(void)
+ {
+  blah_2 b;
+
+  b.bar();
+  return 0;
+ } /* { dg-message  "note: file" ""  } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]