aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2004-03-01 12:18:01 -0700
committerJeff Law <law@gcc.gnu.org>2004-03-01 12:18:01 -0700
commit9bf793f93534b672f460149e704869ac1d0f854d (patch)
treebe50a4b46ffe2e6609446e59e988c1df925aa7d5 /gcc
parentc9e0ce371610049698e7af2a065ddea2ede63709 (diff)
downloadgcc-9bf793f93534b672f460149e704869ac1d0f854d.zip
gcc-9bf793f93534b672f460149e704869ac1d0f854d.tar.gz
gcc-9bf793f93534b672f460149e704869ac1d0f854d.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/fold-const.c39
-rw-r--r--gcc/ggc-page.c70
5 files changed, 121 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 512467b..e03c4b0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index da4618a..b9ef593 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 0065244..4a31bd5 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 04452de..cffa2ec 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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);
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index 5628b04..c499dd7 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -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;