From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25849 invoked by alias); 29 Jul 2002 18:36:57 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 25809 invoked from network); 29 Jul 2002 18:36:51 -0000 Received: from unknown (HELO overta.ru) (217.23.68.3) by sources.redhat.com with SMTP; 29 Jul 2002 18:36:51 -0000 Received: from [217.23.69.101] (HELO localhost.localdomain) by overta.ru (CommuniGate Pro SMTP 3.4.7) with ESMTP id 3239536; Mon, 29 Jul 2002 22:36:47 +0400 From: Denis Chertykov To: Michael Matz Cc: gcc-patches@gcc.gnu.org, denisc@overta.ru Subject: [new-regalloc] is_death/subregs patch Date: Mon, 29 Jul 2002 12:03:00 -0000 Message-ID: X-SW-Source: 2002-07/txt/msg01713.txt.bz2 2002-07-29 Denis Chertykov * ra-rewrite.c (set_web_live, reset_web_live, is_partly_dead): New functions. (is_partly_live): Walk only on one subweb or all subwebs of super web. (emit_loads): Use set_web_live, reset_web_live. (detect_deaths_in_bb): Likewise. (reloads_to_loads): Use is_partly_dead instead of is_death .... Use set_web_live, reset_web_live. (rewrite_program2): Likewise. Index: ra-rewrite.c =================================================================== RCS file: /cvs/gcc/egcs/gcc/ra-rewrite.c,v retrieving revision 1.1.2.3 diff -c -3 -p -r1.1.2.3 ra-rewrite.c *** ra-rewrite.c 16 Jul 2002 19:52:44 -0000 1.1.2.3 --- ra-rewrite.c 29 Jul 2002 18:24:02 -0000 *************** static void detect_web_parts_to_rebuild *** 69,74 **** --- 69,77 ---- static void delete_useless_defs PARAMS ((void)); static void detect_non_changed_webs PARAMS ((void)); static void reset_changed_flag PARAMS ((void)); + static void set_web_live PARAMS ((sbitmap, struct web *)); + static void reset_web_live PARAMS ((sbitmap, struct web *)); + static int is_partly_dead PARAMS ((sbitmap, struct web *)); /* For tracking some statistics, we count the number (and cost) of deleted move insns. */ *************** is_partly_live_1 (live, web) *** 809,816 **** } /* Fast version in case WEB has no subwebs. */ ! #define is_partly_live(live, web) ((!web->subreg_next) \ ! ? TEST_BIT (live, web->id) \ : is_partly_live_1 (live, web)) /* Change the set of currently IN_USE colors according to --- 812,819 ---- } /* Fast version in case WEB has no subwebs. */ ! #define is_partly_live(live, web) ((!web->subreg_next || web->parent_web) \ ! ? TEST_BIT (live, web->id) \ : is_partly_live_1 (live, web)) /* Change the set of currently IN_USE colors according to *************** emit_loads (ri, nl_first_reload, last_bl *** 918,923 **** --- 921,927 ---- struct web *supweb; struct web *aweb; rtx ni, slot, reg; + enum machine_mode innermode; rtx before = NULL_RTX, after = NULL_RTX; basic_block bb; /* When spilltemps were spilled for the last insns, their *************** emit_loads (ri, nl_first_reload, last_bl *** 941,947 **** } web->in_load = 0; /* The adding of reloads doesn't depend on liveness. */ ! if (j < nl_first_reload && !TEST_BIT (ri->live, web->id)) continue; aweb = alias (supweb); aweb->changed = 1; --- 945,951 ---- } web->in_load = 0; /* The adding of reloads doesn't depend on liveness. */ ! if (j < nl_first_reload && !is_partly_live (ri->live, web)) continue; aweb = alias (supweb); aweb->changed = 1; *************** emit_loads (ri, nl_first_reload, last_bl *** 956,982 **** if (aweb != supweb) abort (); slot = copy_rtx (supweb->pattern); ! reg = copy_rtx (supweb->orig_x); ! /* Sanity check. orig_x should be a REG rtx, which should be ! shared over all RTL, so copy_rtx should have no effect. */ ! if (reg != supweb->orig_x) ! abort (); } else { allocate_spill_web (aweb); slot = aweb->stack_slot; ! ! /* If we don't copy the RTL there might be some SUBREG ! rtx shared in the next iteration although being in ! different webs, which leads to wrong code. */ ! reg = copy_rtx (web->orig_x); ! if (GET_CODE (reg) == SUBREG) ! /*slot = adjust_address (slot, GET_MODE (reg), SUBREG_BYTE ! (reg));*/ ! slot = simplify_gen_subreg (GET_MODE (reg), slot, GET_MODE (slot), ! SUBREG_BYTE (reg)); } ra_emit_move_insn (reg, slot); ni = get_insns (); end_sequence (); --- 960,980 ---- if (aweb != supweb) abort (); slot = copy_rtx (supweb->pattern); ! innermode = GET_MODE (supweb->orig_x); } else { allocate_spill_web (aweb); slot = aweb->stack_slot; ! innermode = GET_MODE (slot); } + /* If we don't copy the RTL there might be some SUBREG + rtx shared in the next iteration although being in + different webs, which leads to wrong code. */ + reg = copy_rtx (web->orig_x); + if (GET_CODE (reg) == SUBREG) + slot = simplify_gen_subreg (GET_MODE (reg), slot, innermode, + SUBREG_BYTE (reg)); ra_emit_move_insn (reg, slot); ni = get_insns (); end_sequence (); *************** emit_loads (ri, nl_first_reload, last_bl *** 1025,1031 **** emitted_spill_loads++; spill_load_cost += bb->frequency + 1; } ! RESET_BIT (ri->live, web->id); /* In the special case documented above only emit the reloads and one load. */ if (ri->need_load == 2 && j < nl_first_reload) --- 1023,1029 ---- emitted_spill_loads++; spill_load_cost += bb->frequency + 1; } ! reset_web_live (ri->live, web); /* In the special case documented above only emit the reloads and one load. */ if (ri->need_load == 2 && j < nl_first_reload) *************** detect_bbs_for_rewrite (changed_bbs) *** 1053,1058 **** --- 1051,1104 ---- } } + /* Test LIVE for partial WEB live. */ + static int + is_partly_dead (live, web) + sbitmap live; + struct web *web; + { + struct web *sweb; + + if (web->subreg_next && !web->parent_web) + { + for (sweb = web->subreg_next; sweb; sweb = sweb->subreg_next) + if (!TEST_BIT (live, sweb->id)) + return 1; + return 0; + } + return !TEST_BIT (live, web->id); + } + + /* Set live bit in LIVE for WEB or all his subwebs. */ + static void + set_web_live (live, web) + sbitmap live; + struct web *web; + { + struct web *sweb; + + if (web->subreg_next && !web->parent_web) + for (sweb = web->subreg_next; sweb; sweb = sweb->subreg_next) + SET_BIT (live, sweb->id); + else + SET_BIT (live, web->id); + } + + /* Reset live bit in LIVE for WEB or all his subwebs. */ + static void + reset_web_live (live, web) + sbitmap live; + struct web *web; + { + struct web *sweb; + + if (web->subreg_next && !web->parent_web) + for (sweb = web->subreg_next; sweb; sweb = sweb->subreg_next) + RESET_BIT (live, sweb->id); + else + RESET_BIT (live, web->id); + } + /* Fast version of rewrite_program2() for one basic block, where no spill code is necessary. We detect here only insns with deaths. */ static void *************** detect_deaths_in_bb (bb, live, new_death *** 1094,1111 **** info = insn_df[INSN_UID (insn)]; for (n = 0; n < info.num_defs; n++) { struct ref *ref = info.defs[n]; struct web *web = def2web[DF_REF_ID (ref)]; ! rtx reg = DF_REF_REG (ref); int is_non_def = 0; - unsigned int n2; - web = find_web_for_subweb (web); /* Detect rmw webs. */ for (n2 = 0; n2 < info.num_uses; n2++) { struct web *web2 = use2web[DF_REF_ID (info.uses[n2])]; ! if (web == find_web_for_subweb (web2)) { is_non_def = 1; break; --- 1140,1156 ---- info = insn_df[INSN_UID (insn)]; for (n = 0; n < info.num_defs; n++) { + unsigned int n2; struct ref *ref = info.defs[n]; struct web *web = def2web[DF_REF_ID (ref)]; ! struct web *supweb = find_web_for_subweb (web); int is_non_def = 0; /* Detect rmw webs. */ for (n2 = 0; n2 < info.num_uses; n2++) { struct web *web2 = use2web[DF_REF_ID (info.uses[n2])]; ! if (supweb == find_web_for_subweb (web2)) { is_non_def = 1; break; *************** detect_deaths_in_bb (bb, live, new_death *** 1114,1145 **** if (is_non_def) continue; ! if (!is_partly_live (live, web)) bitmap_set_bit (useless_defs, DF_REF_ID (ref)); ! if (GET_CODE (reg) == SUBREG) ! { ! struct web *sweb; ! sweb = find_subweb (web, reg); ! RESET_BIT (live, sweb->id); ! } ! else ! { ! struct web *sweb; ! RESET_BIT (live, web->id); ! for (sweb = web->subreg_next; sweb; ! sweb = sweb->subreg_next) ! RESET_BIT (live, sweb->id); ! } } for (n = 0; n < info.num_uses; n++) { struct web *web = use2web[DF_REF_ID (info.uses[n])]; ! struct web *supweb = find_web_for_subweb (web); ! int is_death = !TEST_BIT (live, supweb->id); ! is_death &= !TEST_BIT (live, web->id); ! if (is_death) { bitmap_set_bit (new_deaths, INSN_UID (insn)); break; --- 1159,1174 ---- if (is_non_def) continue; ! if (!is_partly_live (live, supweb)) bitmap_set_bit (useless_defs, DF_REF_ID (ref)); ! reset_web_live (live, web); } for (n = 0; n < info.num_uses; n++) { struct web *web = use2web[DF_REF_ID (info.uses[n])]; ! if (is_partly_dead (live, web)) { bitmap_set_bit (new_deaths, INSN_UID (insn)); break; *************** detect_deaths_in_bb (bb, live, new_death *** 1149,1155 **** for (n = 0; n < info.num_uses; n++) { struct web *web = use2web[DF_REF_ID (info.uses[n])]; ! SET_BIT (live, web->id); } } } --- 1178,1184 ---- for (n = 0; n < info.num_uses; n++) { struct web *web = use2web[DF_REF_ID (info.uses[n])]; ! set_web_live (live, web); } } } *************** reloads_to_loads (ri, refs, num_refs, re *** 1174,1180 **** { struct web *web = ref2web[DF_REF_ID (refs[n])]; struct web *supweb = find_web_for_subweb (web); - int is_death; int j; /* Only emit reloads when entering their interference region. A use of a spilled web never opens an --- 1203,1208 ---- *************** reloads_to_loads (ri, refs, num_refs, re *** 1185,1195 **** && TEST_HARD_REG_BIT (never_use_colors, supweb->color)) continue; /* Note, that if web (and supweb) are DEFs, we already cleared ! the corresponding bits in live. I.e. is_death becomes true, which ! is what we want. */ ! is_death = !TEST_BIT (ri->live, supweb->id); ! is_death &= !TEST_BIT (ri->live, web->id); ! if (is_death) { int old_num_r = num_reloads; bitmap_clear (ri->scratch); --- 1213,1221 ---- && TEST_HARD_REG_BIT (never_use_colors, supweb->color)) continue; /* Note, that if web (and supweb) are DEFs, we already cleared ! the corresponding bits in live. I.e. is_partly_dead becomes true, ! which is what we want. */ ! if (is_partly_dead (ri->live, web)) { int old_num_r = num_reloads; bitmap_clear (ri->scratch); *************** rewrite_program2 (new_deaths) *** 1294,1300 **** Remember to not add to colors_in_use in that case. */ if (aweb->type != SPILLED /*|| aweb->color >= 0*/) { ! SET_BIT (ri.live, web->id); if (aweb->type != SPILLED) update_spill_colors (&(ri.colors_in_use), web, 1); } --- 1320,1326 ---- Remember to not add to colors_in_use in that case. */ if (aweb->type != SPILLED /*|| aweb->color >= 0*/) { ! set_web_live (ri.live, web); if (aweb->type != SPILLED) update_spill_colors (&(ri.colors_in_use), web, 1); } *************** rewrite_program2 (new_deaths) *** 1343,1349 **** struct web *aweb = alias (find_web_for_subweb (web)); if (aweb->type != SPILLED) { ! SET_BIT (ri.live, web->id); update_spill_colors (&(ri.colors_in_use), web, 1); } }); --- 1369,1375 ---- struct web *aweb = alias (find_web_for_subweb (web)); if (aweb->type != SPILLED) { ! set_web_live (ri.live, web); update_spill_colors (&(ri.colors_in_use), web, 1); } }); *************** rewrite_program2 (new_deaths) *** 1407,1413 **** if (!is_partly_live (ri.live, supweb)) bitmap_set_bit (useless_defs, DF_REF_ID (ref)); ! RESET_BIT (ri.live, web->id); if (bitmap_bit_p (ri.need_reload, web->id)) { ri.num_reloads--; --- 1433,1439 ---- if (!is_partly_live (ri.live, supweb)) bitmap_set_bit (useless_defs, DF_REF_ID (ref)); ! reset_web_live (ri.live, web); if (bitmap_bit_p (ri.need_reload, web->id)) { ri.num_reloads--; *************** rewrite_program2 (new_deaths) *** 1436,1442 **** for (sweb = supweb->subreg_next; sweb; sweb = sweb->subreg_next) { - RESET_BIT (ri.live, sweb->id); if (bitmap_bit_p (ri.need_reload, sweb->id)) { ri.num_reloads--; --- 1462,1467 ---- *************** rewrite_program2 (new_deaths) *** 1462,1474 **** { struct web *web = use2web[DF_REF_ID (info.uses[n])]; struct web *supweb = find_web_for_subweb (web); - int is_death; if (supweb->type == PRECOLORED && TEST_HARD_REG_BIT (never_use_colors, supweb->color)) continue; ! is_death = !TEST_BIT (ri.live, supweb->id); ! is_death &= !TEST_BIT (ri.live, web->id); ! if (is_death) { ri.need_load = 1; bitmap_set_bit (new_deaths, INSN_UID (insn)); --- 1487,1496 ---- { struct web *web = use2web[DF_REF_ID (info.uses[n])]; struct web *supweb = find_web_for_subweb (web); if (supweb->type == PRECOLORED && TEST_HARD_REG_BIT (never_use_colors, supweb->color)) continue; ! if (is_partly_dead (ri.live, web)) { ri.need_load = 1; bitmap_set_bit (new_deaths, INSN_UID (insn)); *************** rewrite_program2 (new_deaths) *** 1514,1520 **** struct web *web = use2web[DF_REF_ID (info.uses[n])]; struct web *supweb = find_web_for_subweb (web); struct web *aweb = alias (supweb); ! SET_BIT (ri.live, web->id); if (aweb->type != SPILLED) continue; if (supweb->spill_temp) --- 1536,1542 ---- struct web *web = use2web[DF_REF_ID (info.uses[n])]; struct web *supweb = find_web_for_subweb (web); struct web *aweb = alias (supweb); ! set_web_live (ri.live, web); if (aweb->type != SPILLED) continue; if (supweb->spill_temp)