This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[rtlopt] var-tracking.c: delete registers destroyed by called function
- From: Josef Zlomek <zlomj9am at artax dot karlin dot mff dot cuni dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 26 Feb 2003 13:47:34 +0100
- Subject: [rtlopt] var-tracking.c: delete registers destroyed by called function
Hi,
this patch deletes the registers whose values are destroyed by called
function.
Bootstrapped x86-64.
Joe
2003-02-26 Josef Zlomek <zlomekj at suse dot cz>
* var-tracking.c (LT_CALL_INSN): New element of enum location_type.
(compute_bb_dataflow): Delete registers destroyed by called function.
(process_bb): Likewise.
(var_tracking_initialize): Add the call insn to the list of locations.
Index: var-tracking.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/var-tracking.c,v
retrieving revision 1.1.4.24
diff -c -3 -p -r1.1.4.24 var-tracking.c
*** var-tracking.c 26 Feb 2003 10:04:47 -0000 1.1.4.24
--- var-tracking.c 26 Feb 2003 11:53:07 -0000
***************
*** 95,104 ****
#include "tm.h"
#include "rtl.h"
#include "tree.h"
! #include "basic-block.h"
! #include "output.h"
#include "insn-config.h"
#include "reload.h"
#include "sbitmap.h"
#include "alloc-pool.h"
#include "fibheap.h"
--- 95,105 ----
#include "tm.h"
#include "rtl.h"
#include "tree.h"
! #include "hard-reg-set.h"
#include "insn-config.h"
#include "reload.h"
+ #include "basic-block.h"
+ #include "output.h"
#include "sbitmap.h"
#include "alloc-pool.h"
#include "fibheap.h"
*************** enum location_type
*** 109,115 ****
{
LT_USE, /* Location is used in instruction. */
LT_SET, /* Location is set by instruction. */
! LT_CLOBBER /* Location is clobbered by instruction. */
};
/* Where shall the note be emitted? BEFORE or AFTER the instruction. */
--- 110,117 ----
{
LT_USE, /* Location is used in instruction. */
LT_SET, /* Location is set by instruction. */
! LT_CLOBBER, /* Location is clobbered by instruction. */
! LT_CALL_INSN /* Actually this is not a location, it is a call insn. */
};
/* Where shall the note be emitted? BEFORE or AFTER the instruction. */
*************** static bool
*** 859,865 ****
compute_bb_dataflow (bb)
basic_block bb;
{
! int i, n;
bool changed;
attrs old_out[FIRST_PSEUDO_REGISTER];
--- 861,867 ----
compute_bb_dataflow (bb)
basic_block bb;
{
! int i, n, r;
bool changed;
attrs old_out[FIRST_PSEUDO_REGISTER];
*************** compute_bb_dataflow (bb)
*** 883,889 ****
{
rtx loc = VTI (bb)->locs[i].loc;
! if (GET_CODE (loc) == REG)
{
attrs_list_clear (&out[REGNO (loc)]);
if (VTI (bb)->locs[i].type == LT_USE
--- 885,898 ----
{
rtx loc = VTI (bb)->locs[i].loc;
! if (VTI (bb)->locs[i].type == LT_CALL_INSN)
! {
! /* Kill the registers which do not survive function call. */
! for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
! if (TEST_HARD_REG_BIT (call_used_reg_set, r))
! attrs_list_clear (&out[r]);
! }
! else if (GET_CODE (loc) == REG)
{
attrs_list_clear (&out[REGNO (loc)]);
if (VTI (bb)->locs[i].type == LT_USE
*************** compute_bb_dataflow (bb)
*** 900,906 ****
&& MEM_EXPR (loc)
&& track_expr_p (MEM_EXPR (loc)))
{
- int j;
tree decl = MEM_EXPR (loc);
HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
--- 909,914 ----
*************** compute_bb_dataflow (bb)
*** 912,919 ****
has several equivalent locations keep only the memory
location. So remove variable's occurrences from registers.
*/
! for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
! attrs_list_delete (&out[j], decl, offset);
attrs_htab_insert (VTI (bb)->mem_out, decl, offset, loc);
}
}
--- 920,927 ----
has several equivalent locations keep only the memory
location. So remove variable's occurrences from registers.
*/
! for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
! attrs_list_delete (&out[r], decl, offset);
attrs_htab_insert (VTI (bb)->mem_out, decl, offset, loc);
}
}
*************** process_bb (bb)
*** 1396,1402 ****
rtx insn = VTI (bb)->locs[i].insn;
rtx loc = VTI (bb)->locs[i].loc;
! if (GET_CODE (loc) == REG)
{
tree decl = REG_EXPR (loc);
HOST_WIDE_INT offset = REG_OFFSET (loc);
--- 1404,1427 ----
rtx insn = VTI (bb)->locs[i].insn;
rtx loc = VTI (bb)->locs[i].loc;
! if (VTI (bb)->locs[i].type == LT_CALL_INSN)
! {
! int r;
!
! /* Kill the registers which do not survive function call. */
! for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
! if (TEST_HARD_REG_BIT (call_used_reg_set, r))
! {
! /* Emit the notes before call insn because when user
! changes frame in debugger the registers already do not have
! original values. */
! for (l = reg[r]; l; l = l->next)
! delete_location_part (l->decl, l->offset, insn,
! EMIT_NOTE_BEFORE_INSN);
! attrs_list_clear (®[r]);
! }
! }
! else if (GET_CODE (loc) == REG)
{
tree decl = REG_EXPR (loc);
HOST_WIDE_INT offset = REG_OFFSET (loc);
*************** process_bb (bb)
*** 1431,1436 ****
--- 1456,1464 ----
EMIT_NOTE_AFTER_INSN);
attrs_list_clear (®[REGNO (loc)]);
break;
+
+ default:
+ break;
}
}
else if (GET_CODE (loc) == MEM
*************** process_bb (bb)
*** 1459,1464 ****
--- 1487,1495 ----
process_bb_delete (reg, mem, true, decl, offset, insn,
EMIT_NOTE_AFTER_INSN);
break;
+
+ default:
+ break;
}
}
}
*************** var_tracking_initialize ()
*** 1650,1656 ****
{
rtx insn;
! /* Count the number of stores. */
VTI (bb)->n_locs = 0;
for (insn = bb->head; insn != NEXT_INSN (bb->end);
insn = NEXT_INSN (insn))
--- 1681,1687 ----
{
rtx insn;
! /* Count the number of locations. */
VTI (bb)->n_locs = 0;
for (insn = bb->head; insn != NEXT_INSN (bb->end);
insn = NEXT_INSN (insn))
*************** var_tracking_initialize ()
*** 1659,1668 ****
{
note_all_uses (PATTERN (insn), count_uses, insn);
note_stores (PATTERN (insn), count_stores, insn);
}
}
! /* Add the stores to the array. */
VTI (bb)->locs = xmalloc (VTI (bb)->n_locs
* sizeof (struct location_def));
VTI (bb)->n_locs = 0;
--- 1690,1704 ----
{
note_all_uses (PATTERN (insn), count_uses, insn);
note_stores (PATTERN (insn), count_stores, insn);
+ if (GET_CODE (insn) == CALL_INSN)
+ VTI (bb)->n_locs++;
}
}
! /* Add the locations to the array. Order them so that the locations
! which cause emitting a note before insn are before locations
! which cause emitting a note after insn, and the uses are before
! stores in each group. */
VTI (bb)->locs = xmalloc (VTI (bb)->n_locs
* sizeof (struct location_def));
VTI (bb)->n_locs = 0;
*************** var_tracking_initialize ()
*** 1673,1704 ****
{
int n1, n2;
- n1 = VTI (bb)->n_locs;
note_all_uses (PATTERN (insn), add_uses, insn);
! note_stores (PATTERN (insn), add_stores, insn);
! n2 = VTI (bb)->n_locs - 1;
!
! /* Order the locations so that the locations of type LT_USE are
! before others. */
! while (n1 < n2)
{
! while (n1 < n2 && VTI (bb)->locs[n1].type == LT_USE)
! n1++;
! while (n1 < n2 && VTI (bb)->locs[n2].type != LT_USE)
! n2--;
! if (n1 < n2)
! {
! location sw;
!
! sw = VTI (bb)->locs[n1];
! VTI (bb)->locs[n1] = VTI (bb)->locs[n2];
! VTI (bb)->locs[n2] = sw;
! }
}
! /* Now the LT_USEs are first, order the rest so that LT_SETs are
! before LT_CLOBBERs. */
n2 = VTI (bb)->n_locs - 1;
while (n1 < n2)
{
while (n1 < n2 && VTI (bb)->locs[n1].type == LT_SET)
--- 1709,1729 ----
{
int n1, n2;
note_all_uses (PATTERN (insn), add_uses, insn);
! if (GET_CODE (insn) == CALL_INSN)
{
! location *l = VTI (bb)->locs + VTI (bb)->n_locs++;
!
! l->loc = NULL_RTX;
! l->insn = insn;
! l->type = LT_CALL_INSN;
}
! n1 = VTI (bb)->n_locs;
! note_stores (PATTERN (insn), add_stores, insn);
n2 = VTI (bb)->n_locs - 1;
+ /* Order the stores so that the locations of type LT_SET are
+ before LT_CLOBBER. */
while (n1 < n2)
{
while (n1 < n2 && VTI (bb)->locs[n1].type == LT_SET)