From: Peter Bergner Date: Tue, 13 Nov 2018 22:14:11 +0000 (+0000) Subject: re PR middle-end/87899 (r264897 cause mis-compiled native arm-linux-gnueabihf toolchain) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=874e50cbd5b254f1f171bf04ecdfeedc405dff5b;p=gcc.git re PR middle-end/87899 (r264897 cause mis-compiled native arm-linux-gnueabihf toolchain) gcc/ PR rtl-optimization/87899 * lra-lives.c (start_living): Update white space in comment. (enum point_type): New. (sparseset_contains_pseudos_p): New function. (update_pseudo_point): Likewise. (make_hard_regno_live): Use HARD_REGISTER_NUM_P macro. (make_hard_regno_dead): Likewise. Remove ignore_reg_for_conflicts handling. Move early exit after adding conflicts. (mark_pseudo_live): Use HARD_REGISTER_NUM_P macro. Add early exit if regno is already live. Remove all handling of program points. (mark_pseudo_dead): Use HARD_REGISTER_NUM_P macro. Add early exit after adding conflicts. Remove all handling of program points and ignore_reg_for_conflicts. (mark_regno_live): Use HARD_REGISTER_NUM_P macro. Remove return value and do not guard call to mark_pseudo_live. (mark_regno_dead): Use HARD_REGISTER_NUM_P macro. Remove return value and do not guard call to mark_pseudo_dead. (check_pseudos_live_through_calls): Use HARD_REGISTER_NUM_P macro. (process_bb_lives): Use HARD_REGISTER_NUM_P and HARD_REGISTER_P macros. Use new function update_pseudo_point. Handle register copies by removing the source register from the live set. Handle INOUT operands. Update to the next program point using the unused_set, dead_set and start_dying sets. (lra_create_live_ranges_1): Use HARD_REGISTER_NUM_P macro. From-SVN: r266086 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9f474bb0075..da5a5382f56 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2018-11-13 Peter Bergner + + PR rtl-optimization/87899 + * lra-lives.c (start_living): Update white space in comment. + (enum point_type): New. + (sparseset_contains_pseudos_p): New function. + (update_pseudo_point): Likewise. + (make_hard_regno_live): Use HARD_REGISTER_NUM_P macro. + (make_hard_regno_dead): Likewise. Remove ignore_reg_for_conflicts + handling. Move early exit after adding conflicts. + (mark_pseudo_live): Use HARD_REGISTER_NUM_P macro. Add early exit + if regno is already live. Remove all handling of program points. + (mark_pseudo_dead): Use HARD_REGISTER_NUM_P macro. Add early exit + after adding conflicts. Remove all handling of program points and + ignore_reg_for_conflicts. + (mark_regno_live): Use HARD_REGISTER_NUM_P macro. Remove return value + and do not guard call to mark_pseudo_live. + (mark_regno_dead): Use HARD_REGISTER_NUM_P macro. Remove return value + and do not guard call to mark_pseudo_dead. + (check_pseudos_live_through_calls): Use HARD_REGISTER_NUM_P macro. + (process_bb_lives): Use HARD_REGISTER_NUM_P and HARD_REGISTER_P macros. + Use new function update_pseudo_point. Handle register copies by + removing the source register from the live set. Handle INOUT operands. + Update to the next program point using the unused_set, dead_set and + start_dying sets. + (lra_create_live_ranges_1): Use HARD_REGISTER_NUM_P macro. + 2018-11-13 David Malcolm * builtins.c: Replace "source_location" with "location_t". diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 0bf8cd06a30..da47692c904 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -83,7 +83,7 @@ static HARD_REG_SET hard_regs_live; /* Set of pseudos and hard registers start living/dying in the current insn. These sets are used to update REG_DEAD and REG_UNUSED notes - in the insn. */ + in the insn. */ static sparseset start_living, start_dying; /* Set of pseudos and hard regs dead and unused in the current @@ -96,10 +96,6 @@ static bitmap_head temp_bitmap; /* Pool for pseudo live ranges. */ static object_allocator lra_live_range_pool ("live ranges"); -/* If non-NULL, the source operand of a register to register copy for which - we should not add a conflict with the copy's destination operand. */ -static rtx ignore_reg_for_conflicts; - /* Free live range list LR. */ static void free_live_range_list (lra_live_range_t lr) @@ -224,6 +220,57 @@ lra_intersected_live_ranges_p (lra_live_range_t r1, lra_live_range_t r2) return false; } +enum point_type { + DEF_POINT, + USE_POINT +}; + +/* Return TRUE if set A contains a pseudo register, otherwise, return FALSE. */ +static bool +sparseset_contains_pseudos_p (sparseset a) +{ + int regno; + EXECUTE_IF_SET_IN_SPARSESET (a, regno) + if (!HARD_REGISTER_NUM_P (regno)) + return true; + return false; +} + +/* Mark pseudo REGNO as living or dying at program point POINT, depending on + whether TYPE is a definition or a use. If this is the first reference to + REGNO that we've encountered, then create a new live range for it. */ + +static void +update_pseudo_point (int regno, int point, enum point_type type) +{ + lra_live_range_t p; + + /* Don't compute points for hard registers. */ + if (HARD_REGISTER_NUM_P (regno)) + return; + + if (complete_info_p || lra_get_regno_hard_regno (regno) < 0) + { + if (type == DEF_POINT) + { + if (sparseset_bit_p (pseudos_live, regno)) + { + p = lra_reg_info[regno].live_ranges; + lra_assert (p != NULL); + p->finish = point; + } + } + else /* USE_POINT */ + { + if (!sparseset_bit_p (pseudos_live, regno) + && ((p = lra_reg_info[regno].live_ranges) == NULL + || (p->finish != point && p->finish + 1 != point))) + lra_reg_info[regno].live_ranges + = create_live_range (regno, point, -1, p); + } + } +} + /* The corresponding bitmaps of BB currently being processed. */ static bitmap bb_killed_pseudos, bb_gen_pseudos; @@ -232,7 +279,7 @@ static bitmap bb_killed_pseudos, bb_gen_pseudos; static void make_hard_regno_live (int regno) { - lra_assert (regno < FIRST_PSEUDO_REGISTER); + lra_assert (HARD_REGISTER_NUM_P (regno)); if (TEST_HARD_REG_BIT (hard_regs_live, regno)) return; SET_HARD_REG_BIT (hard_regs_live, regno); @@ -247,19 +294,15 @@ make_hard_regno_live (int regno) static void make_hard_regno_dead (int regno) { - lra_assert (regno < FIRST_PSEUDO_REGISTER); - if (! TEST_HARD_REG_BIT (hard_regs_live, regno)) - return; - sparseset_set_bit (start_dying, regno); + lra_assert (HARD_REGISTER_NUM_P (regno)); unsigned int i; EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) - { - if (ignore_reg_for_conflicts != NULL_RTX - && REGNO (ignore_reg_for_conflicts) == i) - continue; - SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); - } + SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); + + if (! TEST_HARD_REG_BIT (hard_regs_live, regno)) + return; CLEAR_HARD_REG_BIT (hard_regs_live, regno); + sparseset_set_bit (start_dying, regno); if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno)) { bitmap_clear_bit (bb_gen_pseudos, regno); @@ -267,130 +310,69 @@ make_hard_regno_dead (int regno) } } -/* Mark pseudo REGNO as living at program point POINT, update START_LIVING - and start a new live range for the pseudo corresponding to REGNO if it - is necessary. */ +/* Mark pseudo REGNO as now being live and update START_LIVING. */ static void -mark_pseudo_live (int regno, int point) +mark_pseudo_live (int regno) { - lra_live_range_t p; + lra_assert (!HARD_REGISTER_NUM_P (regno)); + if (sparseset_bit_p (pseudos_live, regno)) + return; - lra_assert (regno >= FIRST_PSEUDO_REGISTER); - lra_assert (! sparseset_bit_p (pseudos_live, regno)); sparseset_set_bit (pseudos_live, regno); - - if ((complete_info_p || lra_get_regno_hard_regno (regno) < 0) - && ((p = lra_reg_info[regno].live_ranges) == NULL - || (p->finish != point && p->finish + 1 != point))) - lra_reg_info[regno].live_ranges - = create_live_range (regno, point, -1, p); sparseset_set_bit (start_living, regno); } -/* Mark pseudo REGNO as not living at program point POINT and update - START_DYING. - This finishes the current live range for the pseudo corresponding - to REGNO. */ +/* Mark pseudo REGNO as now being dead and update START_DYING. */ static void -mark_pseudo_dead (int regno, int point) +mark_pseudo_dead (int regno) { - lra_live_range_t p; - int ignore_regno = -1; - int end_regno = -1; + lra_assert (!HARD_REGISTER_NUM_P (regno)); + IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live); + if (!sparseset_bit_p (pseudos_live, regno)) + return; - lra_assert (regno >= FIRST_PSEUDO_REGISTER); - lra_assert (sparseset_bit_p (pseudos_live, regno)); sparseset_clear_bit (pseudos_live, regno); sparseset_set_bit (start_dying, regno); - - /* Check whether any part of IGNORE_REG_FOR_CONFLICTS already conflicts - with REGNO. */ - if (ignore_reg_for_conflicts != NULL_RTX - && REGNO (ignore_reg_for_conflicts) < FIRST_PSEUDO_REGISTER) - { - end_regno = END_REGNO (ignore_reg_for_conflicts); - int src_regno = ignore_regno = REGNO (ignore_reg_for_conflicts); - - while (src_regno < end_regno) - { - if (TEST_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, - src_regno)) - { - ignore_regno = end_regno = -1; - break; - } - src_regno++; - } - } - - IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live); - - /* If IGNORE_REG_FOR_CONFLICTS did not already conflict with REGNO, make - sure it still doesn't. */ - for (; ignore_regno < end_regno; ignore_regno++) - CLEAR_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, ignore_regno); - - if (complete_info_p || lra_get_regno_hard_regno (regno) < 0) - { - p = lra_reg_info[regno].live_ranges; - lra_assert (p != NULL); - p->finish = point; - } } -/* Mark register REGNO (pseudo or hard register) in MODE as live at - program point POINT. Update BB_GEN_PSEUDOS. - Return TRUE if the liveness tracking sets were modified, or FALSE - if nothing changed. */ -static bool -mark_regno_live (int regno, machine_mode mode, int point) +/* Mark register REGNO (pseudo or hard register) in MODE as being live + and update BB_GEN_PSEUDOS. */ +static void +mark_regno_live (int regno, machine_mode mode) { int last; - bool changed = false; - if (regno < FIRST_PSEUDO_REGISTER) + if (HARD_REGISTER_NUM_P (regno)) { for (last = end_hard_regno (mode, regno); regno < last; regno++) make_hard_regno_live (regno); } else { - if (! sparseset_bit_p (pseudos_live, regno)) - { - mark_pseudo_live (regno, point); - changed = true; - } + mark_pseudo_live (regno); bitmap_set_bit (bb_gen_pseudos, regno); } - return changed; } -/* Mark register REGNO in MODE as dead at program point POINT. Update - BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS. Return TRUE if the liveness - tracking sets were modified, or FALSE if nothing changed. */ -static bool -mark_regno_dead (int regno, machine_mode mode, int point) +/* Mark register REGNO (pseudo or hard register) in MODE as being dead + and update BB_GEN_PSEUDOS and BB_KILLED_PSEUDOS. */ +static void +mark_regno_dead (int regno, machine_mode mode) { int last; - bool changed = false; - if (regno < FIRST_PSEUDO_REGISTER) + if (HARD_REGISTER_NUM_P (regno)) { for (last = end_hard_regno (mode, regno); regno < last; regno++) make_hard_regno_dead (regno); } else { - if (sparseset_bit_p (pseudos_live, regno)) - { - mark_pseudo_dead (regno, point); - changed = true; - } + mark_pseudo_dead (regno); bitmap_clear_bit (bb_gen_pseudos, regno); bitmap_set_bit (bb_killed_pseudos, regno); } - return changed; } @@ -607,7 +589,7 @@ check_pseudos_live_through_calls (int regno, IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, last_call_used_reg_set); - for (hr = 0; hr < FIRST_PSEUDO_REGISTER; hr++) + for (hr = 0; HARD_REGISTER_NUM_P (hr); hr++) if (targetm.hard_regno_call_part_clobbered (hr, PSEUDO_REGNO_MODE (regno))) add_to_hard_reg_set (&lra_reg_info[regno].conflict_hard_regs, @@ -653,7 +635,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) rtx link, *link_loc; bool need_curr_point_incr; HARD_REG_SET last_call_used_reg_set; - + reg_live_out = df_get_live_out (bb); sparseset_clear (pseudos_live); sparseset_clear (pseudos_live_through_calls); @@ -662,7 +644,10 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out); AND_COMPL_HARD_REG_SET (hard_regs_live, eliminable_regset); EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi) - mark_pseudo_live (j, curr_point); + { + update_pseudo_point (j, curr_point, USE_POINT); + mark_pseudo_live (j); + } bb_gen_pseudos = &get_bb_data (bb)->gen_pseudos; bb_killed_pseudos = &get_bb_data (bb)->killed_pseudos; @@ -702,7 +687,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) set = single_set (curr_insn); if (dead_insn_p && set != NULL_RTX - && REG_P (SET_DEST (set)) && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER + && REG_P (SET_DEST (set)) && !HARD_REGISTER_P (SET_DEST (set)) && find_reg_note (curr_insn, REG_EH_REGION, NULL_RTX) == NULL_RTX && ! may_trap_p (PATTERN (curr_insn)) /* Don't do premature remove of pic offset pseudo as we can @@ -759,7 +744,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (partial_subreg_p (lra_reg_info[regno].biggest_mode, reg->biggest_mode)) lra_reg_info[regno].biggest_mode = reg->biggest_mode; - if (regno < FIRST_PSEUDO_REGISTER) + if (HARD_REGISTER_NUM_P (regno)) { lra_hard_reg_usage[regno] += freq; /* A hard register explicitly can be used in small mode, @@ -775,7 +760,26 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) } call_p = CALL_P (curr_insn); - ignore_reg_for_conflicts = non_conflicting_reg_copy_p (curr_insn); + + /* If we have a simple register copy and the source reg is live after + this instruction, then remove the source reg from the live set so + that it will not conflict with the destination reg. */ + rtx ignore_reg = non_conflicting_reg_copy_p (curr_insn); + if (ignore_reg != NULL_RTX) + { + int ignore_regno = REGNO (ignore_reg); + if (HARD_REGISTER_NUM_P (ignore_regno) + && TEST_HARD_REG_BIT (hard_regs_live, ignore_regno)) + CLEAR_HARD_REG_BIT (hard_regs_live, ignore_regno); + else if (!HARD_REGISTER_NUM_P (ignore_regno) + && sparseset_bit_p (pseudos_live, ignore_regno)) + sparseset_clear_bit (pseudos_live, ignore_regno); + else + /* We don't need any special handling of the source reg if + it is dead after this instruction. */ + ignore_reg = NULL_RTX; + } + src_regno = (set != NULL_RTX && REG_P (SET_SRC (set)) ? REGNO (SET_SRC (set)) : -1); dst_regno = (set != NULL_RTX && REG_P (SET_DEST (set)) @@ -785,13 +789,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) /* Check that source regno does not conflict with destination regno to exclude most impossible preferences. */ - && (((src_regno >= FIRST_PSEUDO_REGISTER + && (((!HARD_REGISTER_NUM_P (src_regno) && (! sparseset_bit_p (pseudos_live, src_regno) - || (dst_regno >= FIRST_PSEUDO_REGISTER + || (!HARD_REGISTER_NUM_P (dst_regno) && lra_reg_val_equal_p (src_regno, lra_reg_info[dst_regno].val, lra_reg_info[dst_regno].offset)))) - || (src_regno < FIRST_PSEUDO_REGISTER + || (HARD_REGISTER_NUM_P (src_regno) && ! TEST_HARD_REG_BIT (hard_regs_live, src_regno))) /* It might be 'inheritance pseudo <- reload pseudo'. */ || (src_regno >= lra_constraint_new_regno_start @@ -816,13 +820,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) } else if (dst_regno >= lra_constraint_new_regno_start) { - if ((hard_regno = src_regno) >= FIRST_PSEUDO_REGISTER) + if (!HARD_REGISTER_NUM_P (hard_regno = src_regno)) hard_regno = reg_renumber[src_regno]; regno = dst_regno; } else if (src_regno >= lra_constraint_new_regno_start) { - if ((hard_regno = dst_regno) >= FIRST_PSEUDO_REGISTER) + if (!HARD_REGISTER_NUM_P (hard_regno = dst_regno)) hard_regno = reg_renumber[dst_regno]; regno = src_regno; } @@ -833,12 +837,6 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) sparseset_clear (start_living); - /* Try to avoid unnecessary program point increments, this saves - a lot of time in remove_some_program_points_and_update_live_ranges. - We only need an increment if something becomes live or dies at this - program point. */ - need_curr_point_incr = false; - /* Mark each defined value as live. We need to do this for unused values because they still conflict with quantities that are live at the time of the definition. */ @@ -846,14 +844,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) { if (reg->type != OP_IN) { - need_curr_point_incr - |= mark_regno_live (reg->regno, reg->biggest_mode, - curr_point); + update_pseudo_point (reg->regno, curr_point, USE_POINT); + mark_regno_live (reg->regno, reg->biggest_mode); check_pseudos_live_through_calls (reg->regno, last_call_used_reg_set); } - if (reg->regno >= FIRST_PSEUDO_REGISTER) + if (!HARD_REGISTER_NUM_P (reg->regno)) for (hr = curr_static_id->hard_regs; hr != NULL; hr = hr->next) if (hr->clobber_high && maybe_gt (GET_MODE_SIZE (PSEUDO_REGNO_MODE (reg->regno)), @@ -868,7 +865,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (curr_id->arg_hard_regs != NULL) for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) - if (regno >= FIRST_PSEUDO_REGISTER) + if (!HARD_REGISTER_NUM_P (regno)) /* It is a clobber. */ make_hard_regno_live (regno - FIRST_PSEUDO_REGISTER); @@ -878,20 +875,22 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) /* See which defined values die here. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) - if (reg->type == OP_OUT + if (reg->type != OP_IN && ! reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p) - need_curr_point_incr - |= mark_regno_dead (reg->regno, reg->biggest_mode, - curr_point); + { + if (reg->type == OP_OUT) + update_pseudo_point (reg->regno, curr_point, DEF_POINT); + mark_regno_dead (reg->regno, reg->biggest_mode); + } for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) - if (reg->type == OP_OUT + if (reg->type != OP_IN && ! reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p) make_hard_regno_dead (reg->regno); if (curr_id->arg_hard_regs != NULL) for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) - if (regno >= FIRST_PSEUDO_REGISTER) + if (!HARD_REGISTER_NUM_P (regno)) /* It is a clobber. */ make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER); @@ -931,50 +930,70 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) } /* Increment the current program point if we must. */ - if (need_curr_point_incr) + if (sparseset_contains_pseudos_p (unused_set) + || sparseset_contains_pseudos_p (start_dying)) next_program_point (curr_point, freq); - sparseset_clear (start_living); + /* If we removed the source reg from a simple register copy from the + live set above, then add it back now so we don't accidentally add + it to the start_living set below. */ + if (ignore_reg != NULL_RTX) + { + int ignore_regno = REGNO (ignore_reg); + if (HARD_REGISTER_NUM_P (ignore_regno)) + SET_HARD_REG_BIT (hard_regs_live, ignore_regno); + else + sparseset_set_bit (pseudos_live, ignore_regno); + } - need_curr_point_incr = false; + sparseset_clear (start_living); /* Mark each used value as live. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) - if (reg->type == OP_IN) + if (reg->type != OP_OUT) { - need_curr_point_incr - |= mark_regno_live (reg->regno, reg->biggest_mode, - curr_point); + if (reg->type == OP_IN) + update_pseudo_point (reg->regno, curr_point, USE_POINT); + mark_regno_live (reg->regno, reg->biggest_mode); check_pseudos_live_through_calls (reg->regno, last_call_used_reg_set); } for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) - if (reg->type == OP_IN) + if (reg->type != OP_OUT) make_hard_regno_live (reg->regno); if (curr_id->arg_hard_regs != NULL) /* Make argument hard registers live. */ for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) - if (regno < FIRST_PSEUDO_REGISTER) + if (HARD_REGISTER_NUM_P (regno)) make_hard_regno_live (regno); sparseset_and_compl (dead_set, start_living, start_dying); + sparseset_clear (start_dying); + /* Mark early clobber outputs dead. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) - if (reg->type == OP_OUT + if (reg->type != OP_IN && reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p) - need_curr_point_incr - |= mark_regno_dead (reg->regno, reg->biggest_mode, - curr_point); + { + if (reg->type == OP_OUT) + update_pseudo_point (reg->regno, curr_point, DEF_POINT); + mark_regno_dead (reg->regno, reg->biggest_mode); + + /* We're done processing inputs, so make sure early clobber + operands that are both inputs and outputs are still live. */ + if (reg->type == OP_INOUT) + mark_regno_live (reg->regno, reg->biggest_mode); + } for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) - if (reg->type == OP_OUT + if (reg->type != OP_IN && reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p) { struct lra_insn_reg *reg2; - + /* We can have early clobbered non-operand hard reg and the same hard reg as an insn input. Don't make hard reg dead before the insns. */ @@ -985,7 +1004,9 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) make_hard_regno_dead (reg->regno); } - if (need_curr_point_incr) + /* Increment the current program point if we must. */ + if (sparseset_contains_pseudos_p (dead_set) + || sparseset_contains_pseudos_p (start_dying)) next_program_point (curr_point, freq); /* Update notes. */ @@ -1017,7 +1038,6 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) EXECUTE_IF_SET_IN_SPARSESET (unused_set, j) add_reg_note (curr_insn, REG_UNUSED, regno_reg_rtx[j]); } - ignore_reg_for_conflicts = NULL_RTX; if (bb_has_eh_pred (bb)) for (j = 0; ; ++j) @@ -1047,7 +1067,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) allocate such regs in this case. */ if (!cfun->has_nonlocal_label && has_abnormal_call_or_eh_pred_edge_p (bb)) - for (px = 0; px < FIRST_PSEUDO_REGISTER; px++) + for (px = 0; HARD_REGISTER_NUM_P (px); px++) if (call_used_regs[px] #ifdef REAL_PIC_OFFSET_TABLE_REGNUM /* We should create a conflict of PIC pseudo with PIC @@ -1057,7 +1077,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) pseudo will also have a wrong value. */ || (px == REAL_PIC_OFFSET_TABLE_REGNUM && pic_offset_table_rtx != NULL_RTX - && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) + && !HARD_REGISTER_P (pic_offset_table_rtx)) #endif ) make_hard_regno_live (px); @@ -1095,7 +1115,10 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) need_curr_point_incr = (sparseset_cardinality (pseudos_live) > 0); EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) - mark_pseudo_dead (i, curr_point); + { + update_pseudo_point (i, curr_point, DEF_POINT); + mark_pseudo_dead (i); + } EXECUTE_IF_SET_IN_BITMAP (df_get_live_in (bb), FIRST_PSEUDO_REGISTER, j, bi) { @@ -1105,7 +1128,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) check_pseudos_live_through_calls (j, last_call_used_reg_set); } - for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) + for (i = 0; HARD_REGISTER_NUM_P (i); ++i) { if (!TEST_HARD_REG_BIT (hard_regs_live, i)) continue; @@ -1332,12 +1355,12 @@ lra_create_live_ranges_1 (bool all_p, bool dead_insn_p) conservative because of recent transformation. Here in this file we recalculate it again as it costs practically nothing. */ - if (i >= FIRST_PSEUDO_REGISTER && regno_reg_rtx[i] != NULL_RTX) + if (!HARD_REGISTER_NUM_P (i) && regno_reg_rtx[i] != NULL_RTX) lra_reg_info[i].biggest_mode = GET_MODE (regno_reg_rtx[i]); else lra_reg_info[i].biggest_mode = VOIDmode; lra_reg_info[i].call_p = false; - if (i >= FIRST_PSEUDO_REGISTER + if (!HARD_REGISTER_NUM_P (i) && lra_reg_info[i].nrefs != 0) { if ((hard_regno = reg_renumber[i]) >= 0) @@ -1394,7 +1417,7 @@ lra_create_live_ranges_1 (bool all_p, bool dead_insn_p) } /* As we did not change CFG since LRA start we can use DF-infrastructure solver to solve live data flow problem. */ - for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i) + for (int i = 0; HARD_REGISTER_NUM_P (i); ++i) { if (TEST_HARD_REG_BIT (hard_regs_spilled_into, i)) bitmap_clear_bit (&all_hard_regs_bitmap, i);