Hi,

Can someone review the patch for #829:
https://bugs.open64.net/show_bug.cgi?id=829

There is a WHILE_DO loop in the case. In CFG construction, a BB_LOOP
will be created and attached to the following BB_NODE:
_start: BB6 (empty)
_body: BB7 (label for loopback of the WHILE_DO)
_cond: BB10 (cond and TRUEBR to BB7)

The CFG is:
                   BB1
                      |
                    BB2
                  /         \
+----->      BB3      BB4
 |                \           /
 |                   BB5   ---> BB12
 |                    |
 |                  BB6
 |                    |
 |                  BB7 <-------+
 |                    |              |
+---------        BB8           |
                      |              |
                    BB9          |
                      |              |
                    BB10  ------+
                      |
                    BB11
                      |
                    BB12 <-- BB5
                      |
                    BB13 (RETURN)

After MainOPT CFG transformation, BB3 and BB5 is cloned and new CFG is
                   BB1
                      |
                    BB2
                  /         \
              BB14      BB4
                |             |
BB12 <-- BB15      BB17  --> BB12
                |             |
              BB18      BB19
                  \           /
  +----------->    BB6
  |                    |
  |                  BB7 <-------+
  |                    |              |
BB5 <-BB3 <- BB8          |
                       |              |
                     BB9          |
                       |              |
                     BB10  ------+
                       |
                     BB11
                       |
                     BB12 <-- BB5, BB15, BB17
                       |
                     BB13 (RETURN)

There will be two loops (6, 7, 8, 3, 5, 9, 10) and (7, 8, 9, 10).

In CFG::Analyze_loops() in opt_cfg.cxx, when call
Fix_SCF_for_mainopt() on BB7, it will set its start/end/step/merge
with the same BB_LOOP*:
   5466     BB_LOOP *loop = bb->Loop();
   5467     if (loop != NULL && loop->Header() == bb) {
   5468       if (loop->End() != NULL) {
   5469         if(loop->Start())
   5470           loop->Start()->Set_loop(loop);
   5471         else {
   5472           Is_True(loop->Is_flag_set(LOOP_PRE_WHILE),("wrong
non bottom test loop lowering\n"));
   5473         }
   5474         loop->End()->Set_loop(loop);
   5475         loop->Body()->Set_loop(loop);
   5476         if (loop->Step())
   5477           loop->Step()->Set_loop(loop);

After calling this function, BB6 and BB7 will share the same BB_LOOP
info. In Find_real_loops(), Collect_loop_body() will be called on both
BB6 and BB7 with the same BB_LOOP*. BB10 will be added to the
BB_LOOP's True_body_set twice. An assertion will happen in the second
time.

In existing code, we already cleaned some of the fields, like the
child, parent, preheader, tail, loopback, etc
   5397 static BB_LOOP *
   5398 Allocate_loop(BB_NODE *bb, BB_LOOP *parent, CFG *cfg)
   5399 {
   5400   BB_LOOP *loop = bb->Loop();
   5401   if (loop == NULL)
   5402     loop = CXX_NEW( BB_LOOP(NULL, NULL, NULL, NULL, NULL, NULL),
   5403                     cfg->Mem_pool() );
   5404   loop->Set_true_body_set(CXX_NEW(BB_NODE_SET(cfg->Total_bb_count(),
cfg,
   5405                                               cfg->Mem_pool(),
BBNS_EMPTY),
   5406                                   cfg->Mem_pool()));
   5407   loop->Set_body_set(NULL);  // body_set not supported in mainopt
   5408   loop->Set_header(bb);
   5409   loop->Set_child(NULL);
   5410   loop->Set_parent(NULL);
   5411   loop->Set_depth(0);
   5412   loop->Set_max_depth(0);
   5413   Update_loops_for_mainopt(loop);
   5414   return loop;
   5415 }

   5230 void Update_loops_for_mainopt(BB_LOOP *loop)
   5231 {
   5232   //  loop->Header() must be defined
   5233
   5234   loop->Set_loopback(NULL);
   5235   loop->Set_preheader(NULL);
   5236   loop->Set_tail(NULL);
   5237   loop->Reset_well_formed();
   5238
   5239   loop->Set_test_at_entry(false);
   5240   loop->Set_test_at_exit(false);
   5241   loop->Set_exit_early(true);
   5242

To fix this issue, I think we need to clear all necessary field in
BB_LOOP when we call Update_loops_for_mainopt():
Index: ../osprey/be/opt/opt_cfg.cxx
===================================================================
--- ../osprey/be/opt/opt_cfg.cxx        (revision 3648)
+++ ../osprey/be/opt/opt_cfg.cxx        (working copy)
@@ -5231,6 +5231,12 @@
 {
   //  loop->Header() must be defined

+  loop->Set_start(NULL);
+  loop->Set_end(NULL);
+  loop->Set_body(NULL);
+  loop->Set_step(NULL);
+  loop->Set_merge(NULL);
+
   loop->Set_loopback(NULL);
   loop->Set_preheader(NULL);
   loop->Set_tail(NULL);


-- 
Regards,
Lai Jian-Xin

Attachment: 829.patch
Description: Binary data

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to