From mboxrd@z Thu Jan 1 00:00:00 1970 From: john@feith.com (John Wehle) To: egcs@cygnus.com Cc: egcs-patches@cygnus.com Subject: local alloc / global alloc / reload problem Date: Mon, 13 Jul 1998 01:48:00 -0000 Message-id: <199807130430.AAA17950@jwlab.FEITH.COM> X-SW-Source: 1998-07/msg00439.html It appears that i386 performance regression resulting from the June 11 regmove change is due to regmove turning: (insn 29 27 31 (set (reg:SI 28) (xor:SI (reg/v:SI 21) (const_int 1))) -1 (nil) (nil)) (insn 31 29 33 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp))) (reg:SI 28)) -1 (insn_list 29 (nil)) (expr_list:REG_DEAD (reg:SI 28) (nil))) into: (insn 280 27 29 (set (reg:SI 28) (reg/v:SI 21)) 54 {movsi+2} (nil) (nil)) (insn 29 280 31 (set (reg:SI 28) (xor:SI (reg:SI 28) (const_int 1))) 189 {xorsi3} (nil) (nil)) (insn 31 29 33 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp))) (reg:SI 28)) 50 {movsi-2} (insn_list 29 (nil)) (expr_list:REG_DEAD (reg:SI 28) (nil))) Local register allocation allocates hard register 0 for reg 28. This is noticed by: for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) if (REG_N_REFS (i) != 0 && reg_renumber[i] < 0 && REG_LIVE_LENGTH (i) != -1 && (! current_function_has_nonlocal_label || REG_N_CALLS_CROSSED (i) == 0)) { [ ... ] } else reg_allocno[i] = -1; in global_alloc so reg_allocno[28] is set to -1. Global register allocation is performed and reload is called. Hard register 0 is spilled and retry_global_alloc is called for reg 28. As a result of reg_allocno equaling -1 retry_global_alloc doesn't do anything and reg 28 ends up on the stack even though a hard register may of been available. The enclosed patch is intended ONLY as food for thought ... it does NOT survive a bootstrap. Hopefully someone more knowledgeable about these issues will chime in. ChangeLog: Sun Jul 12 23:25:04 EDT 1998 John Wehle (john@feith.com) * global.c (global_alloc): Assign allocation-numbers even for registers allocated by local_alloc in case they are later spilled and retry_global_alloc is called. Enjoy! -- John Wehle ------------------8<------------------------8<------------------------ *** gcc/global.c.ORIGINAL Sun Jun 21 15:54:56 1998 --- gcc/global.c Sun Jul 12 23:22:36 1998 *************** *** 389,395 **** /* Note that reg_live_length[i] < 0 indicates a "constant" reg that we are supposed to refrain from putting in a hard reg. -2 means do make an allocno but don't allocate it. */ ! if (REG_N_REFS (i) != 0 && reg_renumber[i] < 0 && REG_LIVE_LENGTH (i) != -1 /* Don't allocate pseudos that cross calls, if this function receives a nonlocal goto. */ && (! current_function_has_nonlocal_label --- 389,395 ---- /* Note that reg_live_length[i] < 0 indicates a "constant" reg that we are supposed to refrain from putting in a hard reg. -2 means do make an allocno but don't allocate it. */ ! if (REG_N_REFS (i) != 0 && REG_LIVE_LENGTH (i) != -1 /* Don't allocate pseudos that cross calls, if this function receives a nonlocal goto. */ && (! current_function_has_nonlocal_label *************** *** 433,439 **** bzero ((char *) local_reg_live_length, sizeof local_reg_live_length); bzero ((char *) local_reg_n_refs, sizeof local_reg_n_refs); for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) ! if (reg_allocno[i] < 0 && reg_renumber[i] >= 0) { int regno = reg_renumber[i]; int endregno = regno + HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i)); --- 433,439 ---- bzero ((char *) local_reg_live_length, sizeof local_reg_live_length); bzero ((char *) local_reg_n_refs, sizeof local_reg_n_refs); for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) ! if (reg_renumber[i] >= 0) { int regno = reg_renumber[i]; int endregno = regno + HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i)); *************** *** 561,567 **** except for parameters marked with reg_live_length[regno] == -2. */ for (i = 0; i < max_allocno; i++) ! if (REG_LIVE_LENGTH (allocno_reg[allocno_order[i]]) >= 0) { /* If we have more than one register class, first try allocating in the class that is cheapest --- 561,568 ---- except for parameters marked with reg_live_length[regno] == -2. */ for (i = 0; i < max_allocno; i++) ! if (reg_renumber[allocno_reg[allocno_order[i]]] < 0 ! && REG_LIVE_LENGTH (allocno_reg[allocno_order[i]]) >= 0) { /* If we have more than one register class, first try allocating in the class that is cheapest ------------------------------------------------------------------------- | Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com | | John Wehle | Fax: 1-215-540-5495 | | -------------------------------------------------------------------------