Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1
libgcj41
nov189571-2.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File nov189571-2.diff of Package libgcj41
Also for nov #189571 for gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> * var-tracking.c (enum micro_operation_type): Add MO_COPY. (var_debug_decl): New function. (var_reg_set): Follow debug decl link. Add location even if reg is already known to hold some other variable. (var_mem_set): Follow debug decl link. (var_reg_delete_and_set, var_mem_delete_and_set): Follow debug decl link. Delete other known locations of the variable part if requested. (var_reg_delete, var_mem_delete): Delete other known locations of the variable part if requested. (same_variable_part_p): New function. (add_stores): Select MO_COPY when appropriate. (vt_initialize): Handle it. (compute_bb_dataflow, emit_notes_in_bb): Likewise. Delete known locations for MO_SET and MO_CLOBBER. (find_variable_location_part): New function. (set_variable_part, delete_variable_part): Use it. (clobber_variable_part): New function. * dwarf2out.c (dwarf2out_var_location): Do not follow debug decl link. Index: gcc/var-tracking.c =================================================================== *** gcc/var-tracking.c.orig 2008-06-12 13:25:26.000000000 +0200 --- gcc/var-tracking.c 2008-06-12 13:31:37.000000000 +0200 *************** enum micro_operation_type *** 114,119 **** --- 114,121 ---- MO_USE_NO_VAR,/* Use location which is not associated with a variable or the variable is not trackable. */ MO_SET, /* Set location. */ + MO_COPY, /* Copy the same portion of a variable from one + loation to another. */ MO_CLOBBER, /* Clobber location. */ MO_CALL, /* Call insn. */ MO_ADJUST /* Adjust stack pointer. */ *************** static void vars_clear (htab_t); *** 298,310 **** static variable unshare_variable (dataflow_set *set, variable var); static int vars_copy_1 (void **, void *); static void vars_copy (htab_t, htab_t); static void var_reg_set (dataflow_set *, rtx); ! static void var_reg_delete_and_set (dataflow_set *, rtx); ! static void var_reg_delete (dataflow_set *, rtx); static void var_regno_delete (dataflow_set *, int); static void var_mem_set (dataflow_set *, rtx); ! static void var_mem_delete_and_set (dataflow_set *, rtx); ! static void var_mem_delete (dataflow_set *, rtx); static void dataflow_set_init (dataflow_set *, int); static void dataflow_set_clear (dataflow_set *); --- 300,313 ---- static variable unshare_variable (dataflow_set *set, variable var); static int vars_copy_1 (void **, void *); static void vars_copy (htab_t, htab_t); + static tree var_debug_decl (tree); static void var_reg_set (dataflow_set *, rtx); ! static void var_reg_delete_and_set (dataflow_set *, rtx, bool); ! static void var_reg_delete (dataflow_set *, rtx, bool); static void var_regno_delete (dataflow_set *, int); static void var_mem_set (dataflow_set *, rtx); ! static void var_mem_delete_and_set (dataflow_set *, rtx, bool); ! static void var_mem_delete (dataflow_set *, rtx, bool); static void dataflow_set_init (dataflow_set *, int); static void dataflow_set_clear (dataflow_set *); *************** static void dataflow_set_destroy (datafl *** 321,326 **** --- 324,330 ---- static bool contains_symbol_ref (rtx); static bool track_expr_p (tree); + static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT); static int count_uses (rtx *, void *); static void count_uses_1 (rtx *, void *); static void count_stores (rtx, rtx, void *); *************** static void dump_dataflow_sets (void); *** 338,343 **** --- 342,348 ---- static void variable_was_changed (variable, htab_t); static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT); + static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT); static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT); static int emit_note_insn_var_location (void **, void *); static void emit_notes_for_changes (rtx, enum emit_note_where); *************** vars_copy (htab_t dst, htab_t src) *** 801,806 **** --- 806,824 ---- htab_traverse (src, vars_copy_1, dst); } + /* Map a decl to its main debug decl. */ + + static inline tree + var_debug_decl (tree decl) + { + if (decl && DECL_P (decl) + && DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl) + && DECL_P (DECL_DEBUG_EXPR (decl))) + decl = DECL_DEBUG_EXPR (decl); + + return decl; + } + /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */ static void *************** var_reg_set (dataflow_set *set, rtx loc) *** 808,830 **** { tree decl = REG_EXPR (loc); HOST_WIDE_INT offset = REG_OFFSET (loc); ! if (set->regs[REGNO (loc)] == NULL) attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc); set_variable_part (set, loc, decl, offset); } ! /* Delete current content of register LOC in dataflow set SET ! and set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */ static void ! var_reg_delete_and_set (dataflow_set *set, rtx loc) { tree decl = REG_EXPR (loc); HOST_WIDE_INT offset = REG_OFFSET (loc); attrs node, next; attrs *nextp; nextp = &set->regs[REGNO (loc)]; for (node = *nextp; node; node = next) { --- 826,860 ---- { tree decl = REG_EXPR (loc); HOST_WIDE_INT offset = REG_OFFSET (loc); + attrs node; + + decl = var_debug_decl (decl); ! for (node = set->regs[REGNO (loc)]; node; node = node->next) ! if (node->decl == decl && node->offset == offset) ! break; ! if (!node) attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc); set_variable_part (set, loc, decl, offset); } ! /* Delete current content of register LOC in dataflow set SET and set ! the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). If ! MODIFY is true, any other live copies of the same variable part are ! also deleted from the dataflow set, otherwise the variable part is ! assumed to be copied from another location holding the same ! part. */ static void ! var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify) { tree decl = REG_EXPR (loc); HOST_WIDE_INT offset = REG_OFFSET (loc); attrs node, next; attrs *nextp; + decl = var_debug_decl (decl); + nextp = &set->regs[REGNO (loc)]; for (node = *nextp; node; node = next) { *************** var_reg_delete_and_set (dataflow_set *se *** 841,857 **** nextp = &node->next; } } var_reg_set (set, loc); } ! /* Delete current content of register LOC in dataflow set SET. */ static void ! var_reg_delete (dataflow_set *set, rtx loc) { attrs *reg = &set->regs[REGNO (loc)]; attrs node, next; for (node = *reg; node; node = next) { next = node->next; --- 871,901 ---- nextp = &node->next; } } + if (modify) + clobber_variable_part (set, loc, decl, offset); var_reg_set (set, loc); } ! /* Delete current content of register LOC in dataflow set SET. If ! CLOBBER is true, also delete any other live copies of the same ! variable part. */ static void ! var_reg_delete (dataflow_set *set, rtx loc, bool clobber) { attrs *reg = &set->regs[REGNO (loc)]; attrs node, next; + if (clobber) + { + tree decl = REG_EXPR (loc); + HOST_WIDE_INT offset = REG_OFFSET (loc); + + decl = var_debug_decl (decl); + + clobber_variable_part (set, NULL, decl, offset); + } + for (node = *reg; node; node = next) { next = node->next; *************** var_mem_set (dataflow_set *set, rtx loc) *** 888,915 **** tree decl = MEM_EXPR (loc); HOST_WIDE_INT offset = INT_MEM_OFFSET (loc); set_variable_part (set, loc, decl, offset); } ! /* Delete and set the location part of variable MEM_EXPR (LOC) ! in dataflow set SET to LOC. Adjust the address first if it is stack pointer based. */ static void ! var_mem_delete_and_set (dataflow_set *set, rtx loc) { var_mem_set (set, loc); } ! /* Delete the location part LOC from dataflow set SET. Adjust the address first if it is stack pointer based. */ static void ! var_mem_delete (dataflow_set *set, rtx loc) { tree decl = MEM_EXPR (loc); HOST_WIDE_INT offset = INT_MEM_OFFSET (loc); delete_variable_part (set, loc, decl, offset); } --- 932,975 ---- tree decl = MEM_EXPR (loc); HOST_WIDE_INT offset = INT_MEM_OFFSET (loc); + decl = var_debug_decl (decl); + set_variable_part (set, loc, decl, offset); } ! /* Delete and set the location part of variable MEM_EXPR (LOC) in ! dataflow set SET to LOC. If MODIFY is true, any other live copies ! of the same variable part are also deleted from the dataflow set, ! otherwise the variable part is assumed to be copied from another ! location holding the same part. Adjust the address first if it is stack pointer based. */ static void ! var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify) { + tree decl = MEM_EXPR (loc); + HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0; + + decl = var_debug_decl (decl); + + if (modify) + clobber_variable_part (set, NULL, decl, offset); var_mem_set (set, loc); } ! /* Delete the location part LOC from dataflow set SET. If CLOBBER is ! true, also delete any other live copies of the same variable part. Adjust the address first if it is stack pointer based. */ static void ! var_mem_delete (dataflow_set *set, rtx loc, bool clobber) { tree decl = MEM_EXPR (loc); HOST_WIDE_INT offset = INT_MEM_OFFSET (loc); + decl = var_debug_decl (decl); + if (clobber) + clobber_variable_part (set, NULL, decl, offset); delete_variable_part (set, loc, decl, offset); } *************** offset_valid_for_tracked_p (HOST_WIDE_IN *** 1494,1499 **** --- 1554,1594 ---- return (-MAX_VAR_PARTS < offset) && (offset < MAX_VAR_PARTS); } + /* Determine whether a given LOC refers to the same variable part as + EXPR+OFFSET. */ + + static bool + same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset) + { + tree expr2; + HOST_WIDE_INT offset2; + + if (! DECL_P (expr)) + return false; + + if (REG_P (loc)) + { + expr2 = REG_EXPR (loc); + offset2 = REG_OFFSET (loc); + } + else if (MEM_P (loc)) + { + expr2 = MEM_EXPR (loc); + offset2 = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0; + } + else + return false; + + if (! expr2 || ! DECL_P (expr2)) + return false; + + expr = var_debug_decl (expr); + expr2 = var_debug_decl (expr2); + + return (expr == expr2 && offset == offset2); + } + + /* Count uses (register and memory references) LOC which will be tracked. INSN is instruction which the LOC is part of. */ *************** add_stores (rtx loc, rtx expr, void *ins *** 1591,1603 **** basic_block bb = BLOCK_FOR_INSN ((rtx) insn); micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; ! if (GET_CODE (expr) != CLOBBER ! && REG_EXPR (loc) ! && track_expr_p (REG_EXPR (loc)) ! && offset_valid_for_tracked_p (REG_OFFSET (loc))) ! mo->type = MO_SET; ! else mo->type = MO_CLOBBER; mo->u.loc = loc; mo->insn = NEXT_INSN ((rtx) insn); } --- 1686,1704 ---- basic_block bb = BLOCK_FOR_INSN ((rtx) insn); micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; ! if (GET_CODE (expr) == CLOBBER ! || ! REG_EXPR (loc) ! || ! track_expr_p (REG_EXPR (loc)) ! || ! offset_valid_for_tracked_p (REG_OFFSET (loc))) mo->type = MO_CLOBBER; + else if (GET_CODE (expr) == SET + && SET_DEST (expr) == loc + && same_variable_part_p (SET_SRC (expr), + REG_EXPR (loc), + REG_OFFSET (loc))) + mo->type = MO_COPY; + else + mo->type = MO_SET; mo->u.loc = loc; mo->insn = NEXT_INSN ((rtx) insn); } *************** add_stores (rtx loc, rtx expr, void *ins *** 1609,1615 **** basic_block bb = BLOCK_FOR_INSN ((rtx) insn); micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; ! mo->type = GET_CODE (expr) == CLOBBER ? MO_CLOBBER : MO_SET; mo->u.loc = loc; mo->insn = NEXT_INSN ((rtx) insn); } --- 1710,1726 ---- basic_block bb = BLOCK_FOR_INSN ((rtx) insn); micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; ! if (GET_CODE (expr) == CLOBBER) ! mo->type = MO_CLOBBER; ! else if (GET_CODE (expr) == SET ! && SET_DEST (expr) == loc ! && same_variable_part_p (SET_SRC (expr), ! MEM_EXPR (loc), ! MEM_OFFSET (loc) ! ? INTVAL (MEM_OFFSET (loc)) : 0)) ! mo->type = MO_COPY; ! else ! mo->type = MO_SET; mo->u.loc = loc; mo->insn = NEXT_INSN ((rtx) insn); } *************** compute_bb_dataflow (basic_block bb) *** 1657,1677 **** rtx loc = VTI (bb)->mos[i].u.loc; if (REG_P (loc)) ! var_reg_delete_and_set (out, loc); else if (MEM_P (loc)) ! var_mem_delete_and_set (out, loc); } break; case MO_USE_NO_VAR: case MO_CLOBBER: { rtx loc = VTI (bb)->mos[i].u.loc; if (REG_P (loc)) ! var_reg_delete (out, loc); else if (MEM_P (loc)) ! var_mem_delete (out, loc); } break; --- 1768,1809 ---- rtx loc = VTI (bb)->mos[i].u.loc; if (REG_P (loc)) ! var_reg_delete_and_set (out, loc, true); else if (MEM_P (loc)) ! var_mem_delete_and_set (out, loc, true); ! } ! break; ! ! case MO_COPY: ! { ! rtx loc = VTI (bb)->mos[i].u.loc; ! ! if (REG_P (loc)) ! var_reg_delete_and_set (out, loc, false); ! else if (MEM_P (loc)) ! var_mem_delete_and_set (out, loc, false); } break; case MO_USE_NO_VAR: + { + rtx loc = VTI (bb)->mos[i].u.loc; + + if (REG_P (loc)) + var_reg_delete (out, loc, false); + else if (MEM_P (loc)) + var_mem_delete (out, loc, false); + } + break; + case MO_CLOBBER: { rtx loc = VTI (bb)->mos[i].u.loc; if (REG_P (loc)) ! var_reg_delete (out, loc, true); else if (MEM_P (loc)) ! var_mem_delete (out, loc, true); } break; *************** variable_was_changed (variable var, htab *** 1929,1934 **** --- 2061,2099 ---- } } + /* Look for the index in VAR->var_part corresponding to OFFSET. + Return -1 if not found. If INSERTION_POINT is non-NULL, the + referenced int will be set to the index that the part has or should + have, if it should be inserted. */ + + static inline int + find_variable_location_part (variable var, HOST_WIDE_INT offset, + int *insertion_point) + { + int pos, low, high; + + /* Find the location part. */ + low = 0; + high = var->n_var_parts; + while (low != high) + { + pos = (low + high) / 2; + if (var->var_part[pos].offset < offset) + low = pos + 1; + else + high = pos; + } + pos = low; + + if (insertion_point) + *insertion_point = pos; + + if (pos < var->n_var_parts && var->var_part[pos].offset == offset) + return pos; + + return -1; + } + /* Set the part of variable's location in the dataflow set SET. The variable part is specified by variable's declaration DECL and offset OFFSET and the part's location by LOC. */ *************** variable_was_changed (variable var, htab *** 1936,1942 **** static void set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset) { ! int pos, low, high; location_chain node, next; location_chain *nextp; variable var; --- 2101,2107 ---- static void set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset) { ! int pos; location_chain node, next; location_chain *nextp; variable var; *************** set_variable_part (dataflow_set *set, rt *** 1959,1980 **** } else { var = (variable) *slot; ! /* Find the location part. */ ! low = 0; ! high = var->n_var_parts; ! while (low != high) ! { ! pos = (low + high) / 2; ! if (var->var_part[pos].offset < offset) ! low = pos + 1; ! else ! high = pos; ! } ! pos = low; ! if (pos < var->n_var_parts && var->var_part[pos].offset == offset) { node = var->var_part[pos].loc_chain; --- 2124,2136 ---- } else { + int inspos = 0; + var = (variable) *slot; ! pos = find_variable_location_part (var, offset, &inspos); ! if (pos >= 0) { node = var->var_part[pos].loc_chain; *************** set_variable_part (dataflow_set *set, rt *** 2006,2015 **** thus there are at most MAX_VAR_PARTS different offsets. */ gcc_assert (var->n_var_parts < MAX_VAR_PARTS); ! /* We have to move the elements of array starting at index low to the ! next position. */ ! for (high = var->n_var_parts; high > low; high--) ! var->var_part[high] = var->var_part[high - 1]; var->n_var_parts++; var->var_part[pos].offset = offset; --- 2162,2171 ---- thus there are at most MAX_VAR_PARTS different offsets. */ gcc_assert (var->n_var_parts < MAX_VAR_PARTS); ! /* We have to move the elements of array starting at index ! inspos to the next position. */ ! for (pos = var->n_var_parts; pos > inspos; pos--) ! var->var_part[pos] = var->var_part[pos - 1]; var->n_var_parts++; var->var_part[pos].offset = offset; *************** set_variable_part (dataflow_set *set, rt *** 2049,2054 **** --- 2205,2247 ---- } } + /* Remove all recorded register locations for the given variable part + from dataflow set SET, except for those that are identical to loc. + The variable part is specified by variable's declaration DECL and + offset OFFSET. */ + + static void + clobber_variable_part (dataflow_set *set, rtx loc, tree decl, + HOST_WIDE_INT offset) + { + void **slot; + + if (! decl || ! DECL_P (decl)) + return; + + slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl), + NO_INSERT); + if (slot) + { + variable var = (variable) *slot; + int pos = find_variable_location_part (var, offset, NULL); + + if (pos >= 0) + { + location_chain node, next; + + /* Remove the register locations from the dataflow set. */ + next = var->var_part[pos].loc_chain; + for (node = next; node; node = next) + { + next = node->next; + if (REG_P (node->loc) && node->loc != loc) + var_reg_delete (set, node->loc, false); + } + } + } + } + /* Delete the part of variable's location from dataflow set SET. The variable part is specified by variable's declaration DECL and offset OFFSET and the part's location by LOC. */ *************** static void *** 2057,2063 **** delete_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset) { - int pos, low, high; void **slot; slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl), --- 2250,2255 ---- *************** delete_variable_part (dataflow_set *set, *** 2065,2085 **** if (slot) { variable var = (variable) *slot; ! /* Find the location part. */ ! low = 0; ! high = var->n_var_parts; ! while (low != high) ! { ! pos = (low + high) / 2; ! if (var->var_part[pos].offset < offset) ! low = pos + 1; ! else ! high = pos; ! } ! pos = low; ! ! if (pos < var->n_var_parts && var->var_part[pos].offset == offset) { location_chain node, next; location_chain *nextp; --- 2257,2265 ---- if (slot) { variable var = (variable) *slot; + int pos = find_variable_location_part (var, offset, NULL); ! if (pos >= 0) { location_chain node, next; location_chain *nextp; *************** delete_variable_part (dataflow_set *set, *** 2145,2151 **** } } if (changed) ! variable_was_changed (var, set->vars); } } } --- 2325,2331 ---- } } if (changed) ! variable_was_changed (var, set->vars); } } } *************** emit_notes_in_bb (basic_block bb) *** 2436,2463 **** rtx loc = VTI (bb)->mos[i].u.loc; if (REG_P (loc)) ! var_reg_delete_and_set (&set, loc); else ! var_mem_delete_and_set (&set, loc); emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN); } break; case MO_USE_NO_VAR: - case MO_CLOBBER: { rtx loc = VTI (bb)->mos[i].u.loc; if (REG_P (loc)) ! var_reg_delete (&set, loc); else ! var_mem_delete (&set, loc); ! if (VTI (bb)->mos[i].type == MO_USE_NO_VAR) ! emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN); else ! emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN); } break; --- 2616,2665 ---- rtx loc = VTI (bb)->mos[i].u.loc; if (REG_P (loc)) ! var_reg_delete_and_set (&set, loc, true); else ! var_mem_delete_and_set (&set, loc, true); ! ! emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN); ! } ! break; ! ! case MO_COPY: ! { ! rtx loc = VTI (bb)->mos[i].u.loc; ! ! if (REG_P (loc)) ! var_reg_delete_and_set (&set, loc, false); ! else ! var_mem_delete_and_set (&set, loc, false); emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN); } break; case MO_USE_NO_VAR: { rtx loc = VTI (bb)->mos[i].u.loc; if (REG_P (loc)) ! var_reg_delete (&set, loc, false); else ! var_mem_delete (&set, loc, false); ! ! emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN); ! } ! break; ! case MO_CLOBBER: ! { ! rtx loc = VTI (bb)->mos[i].u.loc; ! ! if (REG_P (loc)) ! var_reg_delete (&set, loc, true); else ! var_mem_delete (&set, loc, true); ! ! emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN); } break; *************** vt_initialize (void) *** 2682,2688 **** { while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER) n1++; ! while (n1 < n2 && VTI (bb)->mos[n2].type == MO_SET) n2--; if (n1 < n2) { --- 2884,2891 ---- { while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER) n1++; ! while (n1 < n2 && (VTI (bb)->mos[n2].type == MO_SET ! || VTI (bb)->mos[n2].type == MO_COPY)) n2--; if (n1 < n2) { Index: gcc/dwarf2out.c =================================================================== *** gcc/dwarf2out.c.orig 2007-11-27 16:21:38.000000000 +0100 --- gcc/dwarf2out.c 2008-06-12 13:25:31.000000000 +0200 *************** dwarf2out_var_location (rtx loc_note) *** 13593,13601 **** last_insn = loc_note; last_label = newloc->label; decl = NOTE_VAR_LOCATION_DECL (loc_note); - if (DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl) - && DECL_P (DECL_DEBUG_EXPR (decl))) - decl = DECL_DEBUG_EXPR (decl); add_var_loc_to_decl (decl, newloc); } --- 13593,13598 ----
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor