* expr.c (expand_expr_real_1): Don't handle non-local variables.
* expr.h (fix_lexical_addr): Remove.
* function.c (NEED_SEPARATE_AP): Remove.
(fix_lexical_addr): Remove.
* tree-alias-common.c (get_alias_var_decl): Check TREE_STATIC,
not null decl_function_context.
(create_alias_vars): Likewise.
* tree-cfg.c (make_ctrl_stmt_edges): Don't check for non-local labels.
(simple_goto_p): Likewise.
* tree-dfa.c (add_referenced_var): Don't check for non-local variables.
* tree-ssa-ccp.c (get_default_value): Likewise.
* tree-tailcall.c (suitable_for_tail_opt_p): Likewise.
* tree.c (needs_to_live_in_memory): Likewise.
* tree-flow-inline.h (may_be_aliased): Move...
* tree-ssa-alias.c (may_be_aliased): ... here. Enhance check for
when TREE_STATIC variables may be addressable.
From-SVN: r85099
+2004-07-23 Richard Henderson <rth@redhat.com>
+
+ * expr.c (expand_expr_real_1): Don't handle non-local variables.
+ * expr.h (fix_lexical_addr): Remove.
+ * function.c (NEED_SEPARATE_AP): Remove.
+ (fix_lexical_addr): Remove.
+ * tree-alias-common.c (get_alias_var_decl): Check TREE_STATIC,
+ not null decl_function_context.
+ (create_alias_vars): Likewise.
+ * tree-cfg.c (make_ctrl_stmt_edges): Don't check for non-local labels.
+ (simple_goto_p): Likewise.
+ * tree-dfa.c (add_referenced_var): Don't check for non-local variables.
+ * tree-ssa-ccp.c (get_default_value): Likewise.
+ * tree-tailcall.c (suitable_for_tail_opt_p): Likewise.
+ * tree.c (needs_to_live_in_memory): Likewise.
+ * tree-flow-inline.h (may_be_aliased): Move...
+ * tree-ssa-alias.c (may_be_aliased): ... here. Enhance check for
+ when TREE_STATIC variables may be addressable.
+
2004-07-24 Jakub Jelinek <jakub@redhat.com>
* Makefile.in (site.exp): Add HOSTCC and HOSTCFLAGS to site.exp.
/* Show we haven't gotten RTL for this yet. */
temp = 0;
- /* Handle variables inherited from containing functions. */
+ /* Variables inherited from containing functions should have
+ been lowered by this point. */
context = decl_function_context (exp);
-
- if (context != 0 && context != current_function_decl
- /* If var is static, we don't need a static chain to access it. */
- && ! (MEM_P (DECL_RTL (exp))
- && CONSTANT_P (XEXP (DECL_RTL (exp), 0))))
- {
- rtx addr;
-
- /* Mark as non-local and addressable. */
- DECL_NONLOCAL (exp) = 1;
- if (DECL_NO_STATIC_CHAIN (current_function_decl))
- abort ();
- lang_hooks.mark_addressable (exp);
- if (!MEM_P (DECL_RTL (exp)))
- abort ();
- addr = XEXP (DECL_RTL (exp), 0);
- if (MEM_P (addr))
- addr
- = replace_equiv_address (addr,
- fix_lexical_addr (XEXP (addr, 0), exp));
- else
- addr = fix_lexical_addr (addr, exp);
-
- temp = replace_equiv_address (DECL_RTL (exp), addr);
- }
+ if (context != 0
+ && context != current_function_decl
+ && !TREE_STATIC (exp)
+ /* ??? C++ creates functions that are not TREE_STATIC. */
+ && TREE_CODE (exp) != FUNCTION_DECL)
+ abort ();
/* This is the case of an array whose size is to be determined
from its initializer, while the initializer is still being parsed.
if the size can vary or is larger than an integer. */
extern HOST_WIDE_INT int_expr_size (tree);
-/* Convert a stack slot address ADDR valid in function FNDECL
- into an address valid in this function (using a static chain). */
-extern rtx fix_lexical_addr (rtx, tree);
-
/* Return the address of the trampoline for entering nested fn FUNCTION. */
extern rtx trampoline_address (tree);
alignment. */
#define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
-/* NEED_SEPARATE_AP means that we cannot derive ap from the value of fp
- during rtl generation. If they are different register numbers, this is
- always true. It may also be true if
- FIRST_PARM_OFFSET - STARTING_FRAME_OFFSET is not a constant during rtl
- generation. See fix_lexical_addr for details. */
-
-#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
-#define NEED_SEPARATE_AP
-#endif
-
/* Nonzero if function being compiled doesn't contain any calls
(ignoring the prologue and epilogue). This is set prior to
local register allocation and is valid for the remaining
decl, decl);
}
-\f
-/* Convert a stack slot address ADDR for variable VAR
- (from a containing function)
- into an address valid in this function (using a static chain). */
-
-rtx
-fix_lexical_addr (rtx addr, tree var)
-{
- rtx basereg;
- HOST_WIDE_INT displacement;
- tree context = decl_function_context (var);
- struct function *fp;
- rtx base = 0;
-
- /* If this is the present function, we need not do anything. */
- if (context == current_function_decl)
- return addr;
-
- fp = find_function_data (context);
-
- /* Decode given address as base reg plus displacement. */
- if (REG_P (addr))
- basereg = addr, displacement = 0;
- else if (GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 1)) == CONST_INT)
- basereg = XEXP (addr, 0), displacement = INTVAL (XEXP (addr, 1));
- else
- abort ();
-
- if (base == 0)
- abort ();
-
- /* Use same offset, relative to appropriate static chain or argument
- pointer. */
- return plus_constant (base, displacement);
-}
\f
/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
and create duplicate blocks. */
newvar = create_alias_var (decl);
/* Assign globals to global var for purposes of intraprocedural
analysis. */
- if ((DECL_CONTEXT (decl) == NULL
- || TREE_PUBLIC (decl)
- || TREE_STATIC (decl)
- || decl_function_context (decl) == NULL)
- && decl != pta_global_var)
+ if (TREE_STATIC (decl) && decl != pta_global_var)
{
current_alias_ops->addr_assign (current_alias_ops,
get_alias_var (pta_global_var),
{
var = TREE_VALUE (vars);
if (TREE_CODE (var) != LABEL_DECL
- && decl_function_context (var) == NULL
+ && TREE_STATIC (var)
&& DECL_INITIAL (var))
find_func_aliases (var);
}
make_ctrl_stmt_edges (basic_block bb)
{
tree last = last_stmt (bb);
- tree first = first_stmt (bb);
#if defined ENABLE_CHECKING
if (last == NULL_TREE)
abort();
#endif
- if (TREE_CODE (first) == LABEL_EXPR
- && DECL_NONLOCAL (LABEL_EXPR_LABEL (first)))
- make_edge (ENTRY_BLOCK_PTR, bb, EDGE_ABNORMAL);
-
switch (TREE_CODE (last))
{
case GOTO_EXPR:
bool
simple_goto_p (tree expr)
{
- return (TREE_CODE (expr) == GOTO_EXPR
- && TREE_CODE (GOTO_DESTINATION (expr)) == LABEL_DECL
- && (decl_function_context (GOTO_DESTINATION (expr))
- == current_function_decl));
+ return (TREE_CODE (expr) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (expr)) == LABEL_DECL);
}
/* Global and static variables are call-clobbered, always. */
if (needs_to_live_in_memory (var))
mark_call_clobbered (var);
-
- /* DECL_NONLOCAL variables should not be removed, as they are needed
- to emit nested functions. */
- if (DECL_NONLOCAL (var))
- v_ann->used = 1;
}
}
return bb->loop_father;
}
-/* Return true if VAR may be aliased. */
-static inline bool
-may_be_aliased (tree var)
-{
- return (TREE_ADDRESSABLE (var)
- || decl_function_context (var) != current_function_decl);
-}
-
/* Return true if VAR is a clobbered by function calls. */
static inline bool
is_call_clobbered (tree var)
static inline dataflow_t get_immediate_uses (tree);
static inline void set_default_def (tree, tree);
static inline tree default_def (tree);
-static inline bool may_be_aliased (tree);
/*---------------------------------------------------------------------------
Structure representing predictions in tree level.
extern void debug_points_to_info (void);
extern void dump_points_to_info_for (FILE *, tree);
extern void debug_points_to_info_for (tree);
+extern bool may_be_aliased (tree);
/* Call-back function for walk_use_def_chains(). At each reaching
definition, a function with this prototype is called. */
{
dump_may_aliases_for (stderr, var);
}
+
+/* Return true if VAR may be aliased. */
+
+bool
+may_be_aliased (tree var)
+{
+ /* Obviously. */
+ if (TREE_ADDRESSABLE (var))
+ return true;
+
+ /* Automatic variables can't have their addresses escape any other way. */
+ if (!TREE_STATIC (var))
+ return false;
+
+ /* Globally visible variables can have their addresses taken by other
+ translation units. */
+ if (DECL_EXTERNAL (var) || TREE_PUBLIC (var))
+ return true;
+
+ /* If we're in unit-at-a-time mode, then we must have seen all occurrences
+ of address-of operators, and so we can trust TREE_ADDRESSABLE. Otherwise
+ we can only be sure the variable isn't addressable if it's local to the
+ current function. */
+ if (flag_unit_at_a_time)
+ return false;
+ if (decl_function_context (var) == current_function_decl)
+ return false;
+
+ return true;
+}
+
/* Function arguments and volatile variables are considered VARYING. */
val.lattice_val = VARYING;
}
- else if (decl_function_context (sym) != current_function_decl
- || TREE_STATIC (sym))
+ else if (TREE_STATIC (sym))
{
/* Globals and static variables are considered UNKNOWN_VAL,
unless they are declared 'const'. */
{
tree var = VARRAY_TREE (referenced_vars, i);
- if (decl_function_context (var) == current_function_decl
- && !TREE_STATIC (var)
+ if (!TREE_STATIC (var)
&& var_ann (var)->mem_tag_kind == NOT_A_TAG
&& is_call_clobbered (var))
return false;
return (DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (t)
|| TREE_STATIC (t)
|| DECL_EXTERNAL (t)
- || DECL_NONLOCAL (t)
|| (TREE_CODE (t) == RESULT_DECL
- && aggregate_value_p (t, current_function_decl))
- || decl_function_context (t) != current_function_decl);
+ && aggregate_value_p (t, current_function_decl)));
}
/* There are situations in which a language considers record types