bug fix in haifa schedule

Weiwen Liu liu@hepunix.physics.yale.edu
Tue Sep 23 07:26:00 GMT 1997


Hi,

The patch in this email fixes a bug in haifa scheduler while running
egcs-970917 on an alpha-dec-osf4.0.

What bug?
If the following program is compiled with haifa scheduler and -O2, the
compiler crashes with a message

gcc: Internal compiler error: program cc1 got fatal signal 6

/* t2.c */
enum Lisp_Type
{
  Lisp_Int                     
  ,Lisp_Record                 
  ,Lisp_Cons                   
  ,Lisp_String                 
  ,Lisp_Vector                 
  ,Lisp_Symbol
  ,Lisp_Char			 
};
typedef
union Lisp_Object
  {
    struct
      {
        enum Lisp_Type type: 3L ;
	unsigned long  markbit: 1;
	unsigned long  val: 60;
      } gu;
    long  i;
  }
Lisp_Object;
extern int initialized;
void
init_device_faces (int *d)
{
  if (initialized)
    {
      Lisp_Object tdevice;
      do {
          tdevice = (union Lisp_Object)
                        { gu:
                          { markbit: 0,
                            type: Lisp_Record,
                            val: ((unsigned long )d)
                          }
                        };
      } while (0);
      call_critical_lisp_code ();
    }
}

Why?
Before the haifa-scheduler is run, the rtl file t2.c.regmove (see
Appendix 1) contains three basic blocks (insn 4,5,6,8,10,12,13,15),
(insn 22,23,24,25,26,27,28,29,30,37,41,43,45,47,49,52) and (insn 55).
While scheduling block 0, haifa moves (insn 22,23,27) from block 1 to
block 0, and block1 is left with 
(insn 24,25,26,28,29,30,37,41,43,45,47,49,52).  Note that insn 37 is a
LOOP_END note, and now block1 starts with a NOTE insn.  When haifa
processes block1, it leaves (insn 24,25,26,28,29,30,37) untouched and
inserts a LOOP_END note (insn 61) while processing (insn 41).  After
processing block1, now we have two LOOP_END note insn's, and the
compiler crashes.

I have other comments on haifa-schedule which will be in the next
message.

Weiwen

Fix:

Tue Sep 23 09:17:40 1997  Weiwen Liu <liu@hepunix.physics.yale.edu>
	* haifa-sched.c (schedule_block): Remove {LOOP,
	EH_REGION}_{BEG, END} and SETJMP insn's from a basic_block.

*** haifa-sched.c.orig	Sat Sep 13 15:00:22 1997
--- haifa-sched.c	Tue Sep 23 09:17:40 1997
*************** schedule_block (bb, rgn, rgn_n_insns)
*** 6601,6606 ****
--- 6601,6635 ----
       had different notions of what the "head" insn was.  */
    get_block_head_tail (bb, &head, &tail);
  
+   /* Remove {LOOP, EH_REGION}_{BEG, END} and SETJMP insn's
+      from a basic_block. */
+   if (basic_block_head[b] != head)
+     {
+       insn = basic_block_head[b];
+       
+       while (insn != basic_block_end[b])
+         {
+           rtx next = NEXT_INSN (insn);
+           rtx prev = PREV_INSN (insn);
+ 
+           if (GET_CODE (insn) == NOTE
+               && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP
+                   || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
+                   || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
+                   || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
+                   || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
+             {
+                   /* Delete the note from its current position.  */
+               if (prev)
+                   NEXT_INSN (prev) = next;
+               if (next)
+                   PREV_INSN (next) = prev;
+             }
+ 
+           insn = next;
+         }
+     }
+   
    next_tail = NEXT_INSN (tail);
    prev_head = PREV_INSN (head);
  
Appendix I
/* t2.c.regmove */
;; Function init_device_faces

Starting forward pass...
Starting backward pass...
Starting backward pass...
(note 2 0 5 "" NOTE_INSN_DELETED)

(note 5 2 8 "" NOTE_INSN_FUNCTION_BEG)

(note 8 5 10 "" NOTE_INSN_BLOCK_BEG)

;; Start of basic block 0, registers live: 15 [$15] 30 [$30] 63 [FP]
(insn 10 8 12 (set (reg:DI 69)
        (symbol_ref:DI ("initialized"))) 254 {movdi-1} (nil)
    (expr_list:REG_EQUAL (symbol_ref:DI ("initialized"))
        (nil)))

(note 12 10 13 "" NOTE_INSN_DELETED)

(insn 13 12 15 (set (reg:DI 71)
        (sign_extend:DI (mem:SI (reg:DI 69)))) 0 {extendsidi2} (insn_list 10 (nil))
    (expr_list:REG_DEAD (reg:DI 69)
        (nil)))

(jump_insn 15 13 17 (set (pc)
        (if_then_else (eq (reg:DI 71)
                (const_int 0))
            (label_ref 47)
            (pc))) 157 {umindi3+2} (insn_list 13 (nil))
    (expr_list:REG_DEAD (reg:DI 71)
        (nil)))
;; End of basic block 0

(note 17 15 19 "" NOTE_INSN_BLOCK_BEG)

(note 19 17 23 "" NOTE_INSN_LOOP_BEG)

;; Start of basic block 1, registers live: 15 [$15] 30 [$30] 63 [FP]
(insn 23 19 24 (clobber (reg/v:DI 73)) -1 (nil)
    (expr_list:REG_UNUSED (reg/v:DI 73)
        (nil)))

(insn 24 23 32 (clobber (reg/v:DI 73)) -1 (nil)
    (expr_list:REG_UNUSED (reg/v:DI 73)
        (nil)))

(note 32 24 39 "" NOTE_INSN_LOOP_CONT)

(note 39 32 44 "" NOTE_INSN_LOOP_END)

(call_insn 44 39 46 (parallel[ 
            (set (reg:DI 0 $0)
                (call (mem:DI (symbol_ref:DI ("call_critical_lisp_code")))
                    (const_int 0)))
            (clobber (reg:DI 27 $27))
            (clobber (reg:DI 26 $26))
        ] ) 225 {untyped_call-3} (nil)
    (expr_list:REG_UNUSED (reg:DI 0 $0)
        (expr_list:REG_UNUSED (reg:DI 27 $27)
            (expr_list:REG_UNUSED (reg:DI 26 $26)
                (nil))))
    (nil))
;; End of basic block 1

(note 46 44 47 "" NOTE_INSN_BLOCK_END)

;; Start of basic block 2, registers live: 15 [$15] 30 [$30] 63 [FP]
(code_label 47 46 49 8 "")
;; End of basic block 2

(note 49 47 0 "" NOTE_INSN_BLOCK_END)

Appendix 2
/* t2.c.sched */

;; Function init_device_faces

;;   ======================================================
;;   -- basic block 0 from 4 to 15 -- before reload
;;   ======================================================

;;	Ready list (t =  1):    4  10  22/b1
;;	Ready list (t =  2):    4  10  23/b1
;;	Ready list (t =  3):    4  10
;;	Ready list (t =  4):    4
;;	Ready list (t =  5):    4
;;	Ready list (t =  7):    13  27/b1
;;	Ready list (t =  8):    13
;;	Ready list (t = 14):    15
;;	Ready list (final):    41/b1

;;   ==================== scheduling visualization for block 0  

;;   clock     ev4_abox                           ev4_bbox                           ev4_ebox                           no-unit 
;;   =====     ==============================     ==============================     ==============================     ======= 
;;   1         ------------------------------     ------------------------------     ------------------------------     22      
;;   2         ------------------------------     ------------------------------     ------------------------------     23      
;;   3         ------------------------------     ------------------------------     10   r69=`initialized'           
;;   4         ------------------------------     ------------------------------     10   r69=`initialized'           
;;   5         ------------------------------     ------------------------------     4    r68=r16                     
;;       .
;;   7         ------------------------------     ------------------------------     27   r74=r68<<4h                 
;;   8         13   r71=sxn([r69])                ------------------------------     27   r74=r68<<4h                 
;;       .....
;;   14        ------------------------------     15   pc={(r71 == 0h)?L55:pc}       ------------------------------   

;;   total time = 14
;;   new basic block head = 5
;;   new basic block end = 15

;;   ======================================================
;;   -- basic block 1 from 24 to 52 -- before reload
;;   ======================================================

;;	Ready list (t =  1):    41
;;	Ready list (t =  5):    45  47
;;	Ready list (t =  6):    45
;;	Ready list (t = 11):    49
;;	Ready list (t = 13):    52
;;	Ready list (final):  

;;   ==================== scheduling visualization for block 1  

;;   clock     ev4_abox                           ev4_bbox                           ev4_ebox                           no-unit 
;;   =====     ==============================     ==============================     ==============================     ======= 
;;   1         ------------------------------     ------------------------------     41   r75=`Qinit_device_faces'    
;;       ...
;;   5         47   r17=[r75]                     ------------------------------     ------------------------------   
;;   6         47   r17=[r75]                     ------------------------------     45   r16=r68                     
;;       ....
;;   11        ------------------------------     ------------------------------     49   r18=r74|1h                  
;;       .
;;   13        ------------------------------     52   r0=call [`call_critical_l     ------------------------------   

;;   total time = 13
;;   new basic block head = 24
;;   new basic block end = 52

;; register 16 life extended from 4 to 7
;; register 17 life extended from 2 to 4
;; register 18 life extended from 1 to 2
;; register 68 life shortened from 16 to 7
;; register 69 life extended from 2 to 4
;; register 74 life extended from 3 to 7
;; register 74 changed basic block from 1 to -2

;; Procedure interblock/speculative motions == 3/3 


(note 2 0 5 "" NOTE_INSN_DELETED)

;; Start of basic block 0, registers live: 16 [$16]
(note 5 2 6 "" NOTE_INSN_FUNCTION_BEG)

(note 6 5 8 "" NOTE_INSN_DELETED)

(note 8 6 12 "" NOTE_INSN_BLOCK_BEG)

(note 12 8 22 "" NOTE_INSN_DELETED)

(insn 22 12 23 (clobber (reg/v:DI 73)) -1 (nil)
    (expr_list:REG_UNUSED (reg/v:DI 73)
        (nil)))

(insn 23 22 10 (clobber (reg/v:DI 73)) -1 (insn_list:REG_DEP_OUTPUT 22 (nil))
    (expr_list:REG_UNUSED (reg/v:DI 73)
        (nil)))

(insn 10 23 4 (set (reg:DI 69)
        (symbol_ref:DI ("initialized"))) 254 {movdi-1} (nil)
    (expr_list:REG_EQUAL (symbol_ref:DI ("initialized"))
        (nil)))

(insn 4 10 27 (set (reg/v:DI 68)
        (reg:DI 16 $16)) 254 {movdi-1} (nil)
    (expr_list:REG_DEAD (reg:DI 16 $16)
        (nil)))

(insn 27 4 13 (set (reg:DI 74)
        (ashift:DI (reg/v:DI 68)
            (const_int 4))) 63 {ashldi3} (insn_list 4 (nil))
    (nil))

(insn 13 27 15 (set (reg:DI 71)
        (sign_extend:DI (mem:SI (reg:DI 69)))) 0 {extendsidi2} (insn_list 10 (nil))
    (expr_list:REG_DEAD (reg:DI 69)
        (nil)))

(jump_insn 15 13 17 (set (pc)
        (if_then_else (eq (reg:DI 71)
                (const_int 0))
            (label_ref 55)
            (pc))) 157 {umindi3+2} (insn_list:REG_DEP_ANTI 4 (insn_list:REG_DEP_ANTI 10 (insn_list 13 (nil))))
    (expr_list:REG_DEAD (reg:DI 71)
        (nil)))
;; End of basic block 0

(note 17 15 19 "" NOTE_INSN_BLOCK_BEG)

(note 19 17 21 "" NOTE_INSN_LOOP_BEG)

(note 21 19 24 "" NOTE_INSN_DELETED)

;; Start of basic block 1, registers live: 68 74
(note 24 21 25 "" NOTE_INSN_DELETED)

(note 25 24 26 "" NOTE_INSN_DELETED)

(note 26 25 28 "" NOTE_INSN_DELETED)

(note 28 26 29 "" NOTE_INSN_DELETED)

(note 29 28 30 "" NOTE_INSN_DELETED)

(note 30 29 37 "" NOTE_INSN_LOOP_CONT)

(note 37 30 43 "" NOTE_INSN_LOOP_END)

(note 43 37 61 "" NOTE_INSN_DELETED)

(note 61 43 41 "" NOTE_INSN_LOOP_END)

(insn 41 61 47 (set (reg:DI 75)
        (symbol_ref:DI ("Qinit_device_faces"))) 254 {movdi-1} (insn_list 23 (insn_list:REG_DEP_ANTI 15 (insn_list 10 (insn_list 13 (insn_list 27 (insn_list 4 (nil)))))))
    (expr_list:REG_EQUAL (symbol_ref:DI ("Qinit_device_faces"))
        (nil)))

(insn 47 41 45 (set (reg:DI 17 $17)
        (mem/s:DI (reg:DI 75))) 254 {movdi-1} (insn_list 41 (nil))
    (expr_list:REG_DEAD (reg:DI 75)
        (nil)))

(insn 45 47 49 (set (reg:DI 16 $16)
        (reg/v:DI 68)) 254 {movdi-1} (insn_list 41 (nil))
    (expr_list:REG_DEAD (reg/v:DI 68)
        (nil)))

(insn 49 45 52 (set (reg:DI 18 $18)
        (ior:DI (reg:DI 74)
            (const_int 1))) 58 {iordi3} (insn_list 41 (insn_list 27 (nil)))
    (expr_list:REG_DEAD (reg:DI 74)
        (nil)))

(call_insn 52 49 54 (parallel[ 
            (set (reg:DI 0 $0)
                (call (mem:DI (symbol_ref:DI ("call_critical_lisp_code")))
                    (const_int 0)))
            (clobber (reg:DI 27 $27))
            (clobber (reg:DI 26 $26))
        ] ) 225 {untyped_call-3} (insn_list:REG_DEP_ANTI 22 (insn_list:REG_DEP_ANTI 23 (insn_list:REG_DEP_ANTI 27 (insn_list:REG_DEP_ANTI 41 (insn_list 45 (insn_list 47 (insn_list 49 (nil))))))))
    (expr_list:REG_DEAD (reg:DI 16 $16)
        (expr_list:REG_DEAD (reg:DI 17 $17)
            (expr_list:REG_DEAD (reg:DI 18 $18)
                (expr_list:REG_UNUSED (reg:DI 0 $0)
                    (expr_list:REG_UNUSED (reg:DI 27 $27)
                        (expr_list:REG_UNUSED (reg:DI 26 $26)
                            (nil)))))))
    (expr_list (use (reg:DI 18 $18))
        (expr_list (use (reg:DI 17 $17))
            (expr_list (use (reg:DI 16 $16))
                (nil)))))
;; End of basic block 1

(note 54 52 55 "" NOTE_INSN_BLOCK_END)

;; Start of basic block 2, registers live:
(code_label 55 54 57 7 "")
;; End of basic block 2

(note 57 55 0 "" NOTE_INSN_BLOCK_END)

Appendix 3
/* new t2.c.sched */
;; Function init_device_faces

;;   ======================================================
;;   -- basic block 0 from 4 to 15 -- before reload
;;   ======================================================

;;	Ready list (t =  1):    4  10  22/b1
;;	Ready list (t =  2):    4  10  23/b1
;;	Ready list (t =  3):    4  10
;;	Ready list (t =  4):    4
;;	Ready list (t =  5):    4
;;	Ready list (t =  7):    13  27/b1
;;	Ready list (t =  8):    13
;;	Ready list (t = 14):    15
;;	Ready list (final):    41/b1

;;   ==================== scheduling visualization for block 0  

;;   clock     ev4_abox                           ev4_bbox                           ev4_ebox                           no-unit 
;;   =====     ==============================     ==============================     ==============================     ======= 
;;   1         ------------------------------     ------------------------------     ------------------------------     22      
;;   2         ------------------------------     ------------------------------     ------------------------------     23      
;;   3         ------------------------------     ------------------------------     10   r69=`initialized'           
;;   4         ------------------------------     ------------------------------     10   r69=`initialized'           
;;   5         ------------------------------     ------------------------------     4    r68=r16                     
;;       .
;;   7         ------------------------------     ------------------------------     27   r74=r68<<4h                 
;;   8         13   r71=sxn([r69])                ------------------------------     27   r74=r68<<4h                 
;;       .....
;;   14        ------------------------------     15   pc={(r71 == 0h)?L55:pc}       ------------------------------   

;;   total time = 14
;;   new basic block head = 5
;;   new basic block end = 15

;;   ======================================================
;;   -- basic block 1 from 24 to 52 -- before reload
;;   ======================================================

;;	Ready list (t =  1):    41
;;	Ready list (t =  5):    45  47
;;	Ready list (t =  6):    45
;;	Ready list (t = 11):    49
;;	Ready list (t = 13):    52
;;	Ready list (final):  

;;   ==================== scheduling visualization for block 1  

;;   clock     ev4_abox                           ev4_bbox                           ev4_ebox                           no-unit 
;;   =====     ==============================     ==============================     ==============================     ======= 
;;   1         ------------------------------     ------------------------------     41   r75=`Qinit_device_faces'    
;;       ...
;;   5         47   r17=[r75]                     ------------------------------     ------------------------------   
;;   6         47   r17=[r75]                     ------------------------------     45   r16=r68                     
;;       ....
;;   11        ------------------------------     ------------------------------     49   r18=r74|1h                  
;;       .
;;   13        ------------------------------     52   r0=call [`call_critical_l     ------------------------------   

;;   total time = 13
;;   new basic block head = 24
;;   new basic block end = 52

;; register 16 life extended from 4 to 7
;; register 17 life extended from 2 to 4
;; register 18 life extended from 1 to 2
;; register 68 life shortened from 16 to 7
;; register 69 life extended from 2 to 4
;; register 74 life extended from 3 to 7
;; register 74 changed basic block from 1 to -2

;; Procedure interblock/speculative motions == 3/3 


(note 2 0 5 "" NOTE_INSN_DELETED)

;; Start of basic block 0, registers live: 16 [$16]
(note 5 2 6 "" NOTE_INSN_FUNCTION_BEG)

(note 6 5 8 "" NOTE_INSN_DELETED)

(note 8 6 12 "" NOTE_INSN_BLOCK_BEG)

(note 12 8 22 "" NOTE_INSN_DELETED)

(insn 22 12 23 (clobber (reg/v:DI 73)) -1 (nil)
    (expr_list:REG_UNUSED (reg/v:DI 73)
        (nil)))

(insn 23 22 10 (clobber (reg/v:DI 73)) -1 (insn_list:REG_DEP_OUTPUT 22 (nil))
    (expr_list:REG_UNUSED (reg/v:DI 73)
        (nil)))

(insn 10 23 4 (set (reg:DI 69)
        (symbol_ref:DI ("initialized"))) 254 {movdi-1} (nil)
    (expr_list:REG_EQUAL (symbol_ref:DI ("initialized"))
        (nil)))

(insn 4 10 27 (set (reg/v:DI 68)
        (reg:DI 16 $16)) 254 {movdi-1} (nil)
    (expr_list:REG_DEAD (reg:DI 16 $16)
        (nil)))

(insn 27 4 13 (set (reg:DI 74)
        (ashift:DI (reg/v:DI 68)
            (const_int 4))) 63 {ashldi3} (insn_list 4 (nil))
    (nil))

(insn 13 27 15 (set (reg:DI 71)
        (sign_extend:DI (mem:SI (reg:DI 69)))) 0 {extendsidi2} (insn_list 10 (nil))
    (expr_list:REG_DEAD (reg:DI 69)
        (nil)))

(jump_insn 15 13 17 (set (pc)
        (if_then_else (eq (reg:DI 71)
                (const_int 0))
            (label_ref 55)
            (pc))) 157 {umindi3+2} (insn_list:REG_DEP_ANTI 4 (insn_list:REG_DEP_ANTI 10 (insn_list 13 (nil))))
    (expr_list:REG_DEAD (reg:DI 71)
        (nil)))
;; End of basic block 0

(note 17 15 19 "" NOTE_INSN_BLOCK_BEG)

(note 19 17 21 "" NOTE_INSN_LOOP_BEG)

(note 21 19 24 "" NOTE_INSN_DELETED)

;; Start of basic block 1, registers live: 68 74
(note 24 21 25 "" NOTE_INSN_DELETED)

(note 25 24 26 "" NOTE_INSN_DELETED)

(note 26 25 28 "" NOTE_INSN_DELETED)

(note 28 26 29 "" NOTE_INSN_DELETED)

(note 29 28 30 "" NOTE_INSN_DELETED)

(note 30 29 43 "" NOTE_INSN_LOOP_CONT)

(note 43 30 61 "" NOTE_INSN_DELETED)

(note 61 43 41 "" NOTE_INSN_LOOP_END)

(insn 41 61 47 (set (reg:DI 75)
        (symbol_ref:DI ("Qinit_device_faces"))) 254 {movdi-1} (insn_list 23 (insn_list:REG_DEP_ANTI 15 (insn_list 10 (insn_list 13 (insn_list 27 (insn_list 4 (nil)))))))
    (expr_list:REG_EQUAL (symbol_ref:DI ("Qinit_device_faces"))
        (nil)))

(insn 47 41 45 (set (reg:DI 17 $17)
        (mem/s:DI (reg:DI 75))) 254 {movdi-1} (insn_list 41 (nil))
    (expr_list:REG_DEAD (reg:DI 75)
        (nil)))

(insn 45 47 49 (set (reg:DI 16 $16)
        (reg/v:DI 68)) 254 {movdi-1} (insn_list 41 (nil))
    (expr_list:REG_DEAD (reg/v:DI 68)
        (nil)))

(insn 49 45 52 (set (reg:DI 18 $18)
        (ior:DI (reg:DI 74)
            (const_int 1))) 58 {iordi3} (insn_list 41 (insn_list 27 (nil)))
    (expr_list:REG_DEAD (reg:DI 74)
        (nil)))

(call_insn 52 49 54 (parallel[ 
            (set (reg:DI 0 $0)
                (call (mem:DI (symbol_ref:DI ("call_critical_lisp_code")))
                    (const_int 0)))
            (clobber (reg:DI 27 $27))
            (clobber (reg:DI 26 $26))
        ] ) 225 {untyped_call-3} (insn_list:REG_DEP_ANTI 22 (insn_list:REG_DEP_ANTI 23 (insn_list:REG_DEP_ANTI 27 (insn_list:REG_DEP_ANTI 41 (insn_list 45 (insn_list 47 (insn_list 49 (nil))))))))
    (expr_list:REG_DEAD (reg:DI 16 $16)
        (expr_list:REG_DEAD (reg:DI 17 $17)
            (expr_list:REG_DEAD (reg:DI 18 $18)
                (expr_list:REG_UNUSED (reg:DI 0 $0)
                    (expr_list:REG_UNUSED (reg:DI 27 $27)
                        (expr_list:REG_UNUSED (reg:DI 26 $26)
                            (nil)))))))
    (expr_list (use (reg:DI 18 $18))
        (expr_list (use (reg:DI 17 $17))
            (expr_list (use (reg:DI 16 $16))
                (nil)))))
;; End of basic block 1

(note 54 52 55 "" NOTE_INSN_BLOCK_END)

;; Start of basic block 2, registers live:
(code_label 55 54 57 7 "")
;; End of basic block 2

(note 57 55 0 "" NOTE_INSN_BLOCK_END)





More information about the Gcc mailing list