fold-const.c (fold): An equality comparison of a non-weak object against zero has a known result.

* fold-const.c (fold): An equality comparison of a non-weak object
	against zero has a known result.  Similarly an equality comparison
	of the address of two non-weak, unaliased symbols has a known result.

	* ggc-page.c (struct page_entry): New field PREV.
	(ggc_alloc): Update PREV field appropriately.
	(sweep_pages): Likewise.
	(ggc_free): Likewise.  Use PREV field rather than loop to
	improve ggc_free performance.

cp/
	* init.c (build_vec_delete_1): Convert 2nd argument to NE_EXPR to
	the proper type.

From-SVN: r78713
This commit is contained in:
Jeff Law 2004-03-01 12:18:01 -07:00 committed by Jeff Law
parent c9e0ce3716
commit 9bf793f935
5 changed files with 121 additions and 8 deletions

View File

@ -1,3 +1,15 @@
2004-03-01 Jeff Law <law@redhat.com>
* fold-const.c (fold): An equality comparison of a non-weak object
against zero has a known result. Similarly an equality comparison
of the address of two non-weak, unaliased symbols has a known result.
* ggc-page.c (struct page_entry): New field PREV.
(ggc_alloc): Update PREV field appropriately.
(sweep_pages): Likewise.
(ggc_free): Likewise. Use PREV field rather than loop to
improve ggc_free performance.
2004-03-01 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips.c (mips_output_division): Use the division

View File

@ -1,3 +1,8 @@
2004-03-01 Jeff Law <law@redhat.com>
* init.c (build_vec_delete_1): Convert 2nd argument to NE_EXPR to
the proper type.
2004-02-29 Mark Mitchell <mark@codesourcery.com>
PR c++/14138

View File

@ -2436,7 +2436,8 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
/* Outermost wrapper: If pointer is null, punt. */
body = fold (build (COND_EXPR, void_type_node,
fold (build (NE_EXPR, boolean_type_node, base,
integer_zero_node)),
convert (TREE_TYPE (base),
integer_zero_node))),
body, integer_zero_node));
body = build1 (NOP_EXPR, void_type_node, body);

View File

@ -7183,6 +7183,45 @@ fold (tree expr)
if (tree_swap_operands_p (arg0, arg1, true))
return fold (build (swap_tree_comparison (code), type, arg1, arg0));
/* If this is an equality comparison of the address of a non-weak
object against zero, then we know the result. */
if ((code == EQ_EXPR || code == NE_EXPR)
&& TREE_CODE (arg0) == ADDR_EXPR
&& DECL_P (TREE_OPERAND (arg0, 0))
&& ! DECL_WEAK (TREE_OPERAND (arg0, 0))
&& integer_zerop (arg1))
{
if (code == EQ_EXPR)
return integer_zero_node;
else
return integer_one_node;
}
/* If this is an equality comparison of the address of two non-weak,
unaliased symbols neither of which are extern (since we do not
have access to attributes for externs), then we know the result. */
if ((code == EQ_EXPR || code == NE_EXPR)
&& TREE_CODE (arg0) == ADDR_EXPR
&& DECL_P (TREE_OPERAND (arg0, 0))
&& ! DECL_WEAK (TREE_OPERAND (arg0, 0))
&& ! lookup_attribute ("alias",
DECL_ATTRIBUTES (TREE_OPERAND (arg0, 0)))
&& ! DECL_EXTERNAL (TREE_OPERAND (arg0, 0))
&& TREE_CODE (arg1) == ADDR_EXPR
&& DECL_P (TREE_OPERAND (arg1, 0))
&& ! DECL_WEAK (TREE_OPERAND (arg1, 0))
&& ! lookup_attribute ("alias",
DECL_ATTRIBUTES (TREE_OPERAND (arg1, 0)))
&& ! DECL_EXTERNAL (TREE_OPERAND (arg1, 0)))
{
if (code == EQ_EXPR)
return (operand_equal_p (arg0, arg1, 0)
? integer_one_node : integer_zero_node);
else
return (operand_equal_p (arg0, arg1, 0)
? integer_zero_node : integer_one_node);
}
if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
{
tree targ0 = strip_float_extensions (arg0);

View File

@ -247,6 +247,11 @@ typedef struct page_entry
this is the last page-entry. */
struct page_entry *next;
/* The previous page-entry with objects of the same size, or NULL if
this is the first page-entry. The PREV pointer exists solely to
keep the cost of ggc_free managable. */
struct page_entry *prev;
/* The number of bytes allocated. (This will always be a multiple
of the host system page size.) */
size_t bytes;
@ -1092,12 +1097,18 @@ ggc_alloc (size_t size)
while (new_entry->context_depth >= G.depth_in_use)
push_depth (G.by_depth_in_use-1);
/* If this is the only entry, it's also the tail. */
/* If this is the only entry, it's also the tail. If it is not
the only entry, then we must update the PREV pointer of the
ENTRY (G.pages[order]) to point to our new page entry. */
if (entry == NULL)
G.page_tails[order] = new_entry;
else
entry->prev = new_entry;
/* Put new pages at the head of the page list. */
/* Put new pages at the head of the page list. By definition the
entry at the head of the list always has a NULL pointer. */
new_entry->next = entry;
new_entry->prev = NULL;
entry = new_entry;
G.pages[order] = new_entry;
@ -1146,8 +1157,17 @@ ggc_alloc (size_t size)
&& entry->next != NULL
&& entry->next->num_free_objects > 0)
{
/* We have a new head for the list. */
G.pages[order] = entry->next;
/* We are moving ENTRY to the end of the page table list.
The new page at the head of the list will have NULL in
its PREV field and ENTRY will have NULL in its NEXT field. */
entry->next->prev = NULL;
entry->next = NULL;
/* Append ENTRY to the tail of the list. */
entry->prev = G.page_tails[order];
G.page_tails[order]->next = entry;
G.page_tails[order] = entry;
}
@ -1339,22 +1359,34 @@ ggc_free (void *p)
if (pe->num_free_objects++ == 0)
{
page_entry *p, *q;
/* If the page is completely full, then it's supposed to
be after all pages that aren't. Since we've freed one
object from a page that was full, we need to move the
page to the head of the list. */
page to the head of the list.
page_entry *p, *q;
for (q = NULL, p = G.pages[order]; ; q = p, p = p->next)
if (p == pe)
break;
PE is the node we want to move. Q is the previous node
and P is the next node in the list. */
q = pe->prev;
if (q && q->num_free_objects == 0)
{
p = pe->next;
q->next = p;
/* If PE was at the end of the list, then Q becomes the
new end of the list. If PE was not the end of the
list, then we need to update the PREV field for P. */
if (!p)
G.page_tails[order] = q;
else
p->prev = q;
/* Move PE to the head of the list. */
pe->next = G.pages[order];
pe->prev = NULL;
G.pages[order]->prev = pe;
G.pages[order] = pe;
}
@ -1741,10 +1773,17 @@ sweep_pages (void)
/* Remove the page if it's empty. */
else if (live_objects == 0)
{
/* If P was the first page in the list, then NEXT
becomes the new first page in the list, otherwise
splice P out of the forward pointers. */
if (! previous)
G.pages[order] = next;
else
previous->next = next;
/* Splice P out of the back pointers too. */
if (next)
next->prev = previous;
/* Are we removing the last element? */
if (p == G.page_tails[order])
@ -1761,6 +1800,7 @@ sweep_pages (void)
{
/* Move p to the end of the list. */
p->next = NULL;
p->prev = G.page_tails[order];
G.page_tails[order]->next = p;
/* Update the tail pointer... */
@ -1771,6 +1811,11 @@ sweep_pages (void)
G.pages[order] = next;
else
previous->next = next;
/* And update the backpointer in NEXT if necessary. */
if (next)
next->prev = previous;
p = previous;
}
}
@ -1782,8 +1827,19 @@ sweep_pages (void)
else if (p != G.pages[order])
{
previous->next = p->next;
/* Update the backchain in the next node if it exists. */
if (p->next)
p->next->prev = previous;
/* Move P to the head of the list. */
p->next = G.pages[order];
p->prev = NULL;
G.pages[order]->prev = p;
/* Update the head pointer. */
G.pages[order] = p;
/* Are we moving the last element? */
if (G.page_tails[order] == p)
G.page_tails[order] = previous;