diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-27 11:57:01 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-27 11:57:01 +0000 |
commit | 8560c588b8e703a936e09b8b1c5381289b6fe2a8 (patch) | |
tree | 6551aaedcd3c7893355d5933f81fbb2dce9863de /gcc/varpool.c | |
parent | c3986c7ab5d242067928f202cc5f7c661242ce2a (diff) | |
download | gcc-8560c588b8e703a936e09b8b1c5381289b6fe2a8.tar.gz |
2010-09-27 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 164647
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@164648 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/varpool.c')
-rw-r--r-- | gcc/varpool.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/gcc/varpool.c b/gcc/varpool.c index 2b0809456ea..ff3631b3478 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -107,7 +107,7 @@ eq_varpool_node (const void *p1, const void *p2) /* Return varpool node assigned to DECL without creating new one. */ struct varpool_node * -varpool_get_node (tree decl) +varpool_get_node (const_tree decl) { struct varpool_node key, **slot; @@ -116,7 +116,7 @@ varpool_get_node (tree decl) if (!varpool_hash) return NULL; - key.decl = decl; + key.decl = CONST_CAST2 (tree, const_tree, decl); slot = (struct varpool_node **) htab_find_slot (varpool_hash, &key, NO_INSERT); if (!slot) @@ -359,27 +359,37 @@ decide_is_variable_needed (struct varpool_node *node, tree decl) return true; } -/* Return if NODE is constant and its initial value is known (so we can do - constant folding). The decision depends on whole program decisions - and can not be recomputed at ltrans stage for variables from other - partitions. For this reason the new value should be always combined - with the previous knowledge. */ +/* Return if DECL is constant and its initial value is known (so we can do + constant folding using DECL_INITIAL (decl)). */ bool -varpool_decide_const_value_known (struct varpool_node *node) +const_value_known_p (tree decl) { - tree decl = node->decl; + if (TREE_CODE (decl) != VAR_DECL + &&TREE_CODE (decl) != CONST_DECL) + return false; + + if (TREE_CODE (decl) == CONST_DECL + || DECL_IN_CONSTANT_POOL (decl)) + return true; - gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl)); gcc_assert (TREE_CODE (decl) == VAR_DECL); + if (!TREE_READONLY (decl)) return false; + + /* Gimplifier takes away constructors of local vars */ + if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) + return DECL_INITIAL (decl) != NULL; + + gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl)); + /* Variables declared 'const' without an initializer have zero as the initializer if they may not be overridden at link or run time. */ if (!DECL_INITIAL (decl) && (DECL_EXTERNAL (decl) - || DECL_REPLACEABLE_P (decl))) + || decl_replaceable_p (decl))) return false; /* Variables declared `const' with an initializer are considered @@ -423,7 +433,6 @@ varpool_finalize_decl (tree decl) there. */ else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) varpool_mark_needed_node (node); - node->const_value_known |= varpool_decide_const_value_known (node); if (cgraph_global_info_ready) varpool_assemble_pending_decls (); } @@ -441,7 +450,7 @@ cgraph_variable_initializer_availability (struct varpool_node *node) /* If the variable can be overwritten, return OVERWRITABLE. Takes care of at least two notable extensions - the COMDAT variables used to share template instantiations in C++. */ - if (!(*targetm.binds_local_p) (node->decl) && !DECL_COMDAT (node->decl)) + if (!decl_replaceable_p (node->decl)) return AVAIL_OVERWRITABLE; return AVAIL_AVAILABLE; } @@ -653,7 +662,7 @@ add_new_static_var (tree type) /* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful. Extra name aliases are output whenever DECL is output. */ -bool +struct varpool_node * varpool_extra_name_alias (tree alias, tree decl) { struct varpool_node key, *alias_node, *decl_node, **slot; @@ -674,7 +683,7 @@ varpool_extra_name_alias (tree alias, tree decl) /* If the varpool_node has been already created, fail. */ if (*slot) - return false; + return NULL; alias_node = ggc_alloc_cleared_varpool_node (); alias_node->decl = alias; @@ -686,7 +695,26 @@ varpool_extra_name_alias (tree alias, tree decl) decl_node->extra_name->prev = alias_node; decl_node->extra_name = alias_node; *slot = alias_node; - return true; + return alias_node; +} + +/* Return true when NODE is known to be used from other (non-LTO) object file. + Known only when doing LTO via linker plugin. */ + +bool +varpool_used_from_object_file_p (struct varpool_node *node) +{ + struct varpool_node *alias; + + if (!TREE_PUBLIC (node->decl)) + return false; + if (resolution_used_from_other_file_p (node->resolution)) + return true; + for (alias = node->extra_name; alias; alias = alias->next) + if (TREE_PUBLIC (alias->decl) + && resolution_used_from_other_file_p (alias->resolution)) + return true; + return false; } #include "gt-varpool.h" |