diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-04-26 20:47:54 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2009-04-26 20:47:54 +0200 |
commit | 77f2a97066c469e868d6518e96c353f71aa28813 (patch) | |
tree | 2115d30581d9d9182f2b8de566ba08dcd3742e3b /gcc/gimplify.c | |
parent | 4561e242764a1d0e8f260a432dea56d429e6ae3e (diff) | |
download | gcc-77f2a97066c469e868d6518e96c353f71aa28813.zip gcc-77f2a97066c469e868d6518e96c353f71aa28813.tar.gz gcc-77f2a97066c469e868d6518e96c353f71aa28813.tar.bz2 |
tree-nested.c (get_nonlocal_vla_type): If not optimizing, call note_nonlocal_vla_type for nonlocal VLAs.
* tree-nested.c (get_nonlocal_vla_type): If not optimizing, call
note_nonlocal_vla_type for nonlocal VLAs.
(note_nonlocal_vla_type, note_nonlocal_block_vlas,
contains_remapped_vars, remap_vla_decls): New functions.
(convert_nonlocal_reference_stmt): If not optimizing, call
note_nonlocal_block_vlas on GIMPLE_BIND block vars.
(nesting_copy_decl): Return {VAR,PARM,RESULT}_DECL unmodified
if it wasn't found in var_map.
(finalize_nesting_tree_1): Call remap_vla_decls. If outermost
GIMPLE_BIND doesn't have gimple_bind_block, chain debug_var_chain
to BLOCK_VARS (DECL_INITIAL (root->context)) instead of calling
declare_vars.
* gimplify.c (nonlocal_vlas): New variable.
(gimplify_var_or_parm_decl): Add debug VAR_DECLs for non-local
referenced VLAs.
(gimplify_body): Create and destroy nonlocal_vlas.
* trans-decl.c: Include pointer-set.h.
(nonlocal_dummy_decl_pset, tree nonlocal_dummy_decls): New variables.
(gfc_nonlocal_dummy_array_decl): New function.
(gfc_get_symbol_decl): Call it for non-local dummy args with saved
descriptor.
(gfc_get_symbol_decl): Set DECL_BY_REFERENCE when needed.
(gfc_generate_function_code): Initialize nonlocal_dummy_decl{s,_pset},
chain it to outermost block's vars, destroy it afterwards.
* Make-lang.in (trans-decl.o): Depend on pointer-set.h.
From-SVN: r146810
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 870cd1b..f831e47 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1851,6 +1851,9 @@ gimplify_conversion (tree *expr_p) return GS_OK; } +/* Nonlocal VLAs seen in the current function. */ +static struct pointer_set_t *nonlocal_vlas; + /* Gimplify a VAR_DECL or PARM_DECL. Returns GS_OK if we expanded a DECL_VALUE_EXPR, and it's worth re-examining things. */ @@ -1881,7 +1884,36 @@ gimplify_var_or_parm_decl (tree *expr_p) /* If the decl is an alias for another expression, substitute it now. */ if (DECL_HAS_VALUE_EXPR_P (decl)) { - *expr_p = unshare_expr (DECL_VALUE_EXPR (decl)); + tree value_expr = DECL_VALUE_EXPR (decl); + + /* For referenced nonlocal VLAs add a decl for debugging purposes + to the current function. */ + if (TREE_CODE (decl) == VAR_DECL + && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST + && nonlocal_vlas != NULL + && TREE_CODE (value_expr) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (value_expr, 0)) == VAR_DECL + && decl_function_context (decl) != current_function_decl) + { + struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; + while (ctx && ctx->region_type == ORT_WORKSHARE) + ctx = ctx->outer_context; + if (!ctx && !pointer_set_insert (nonlocal_vlas, decl)) + { + tree copy = copy_node (decl), block; + + lang_hooks.dup_lang_specific_decl (copy); + SET_DECL_RTL (copy, NULL_RTX); + TREE_USED (copy) = 1; + block = DECL_INITIAL (current_function_decl); + TREE_CHAIN (copy) = BLOCK_VARS (block); + BLOCK_VARS (block) = copy; + SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr)); + DECL_HAS_VALUE_EXPR_P (copy) = 1; + } + } + + *expr_p = unshare_expr (value_expr); return GS_OK; } @@ -7367,6 +7399,9 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms) unshare_body (body_p, fndecl); unvisit_body (body_p, fndecl); + if (cgraph_node (fndecl)->origin) + nonlocal_vlas = pointer_set_create (); + /* Make sure input_location isn't set to something weird. */ input_location = DECL_SOURCE_LOCATION (fndecl); @@ -7402,6 +7437,12 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms) gimple_bind_set_body (outer_bind, parm_stmts); } + if (nonlocal_vlas) + { + pointer_set_destroy (nonlocal_vlas); + nonlocal_vlas = NULL; + } + pop_gimplify_context (outer_bind); gcc_assert (gimplify_ctxp == NULL); |