aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/trans.c')
-rw-r--r--gcc/fortran/trans.c113
1 files changed, 50 insertions, 63 deletions
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 83fabe2..2f8c7fd 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -582,11 +582,11 @@ gfc_call_malloc (stmtblock_t * block, tree type, tree size)
}
return newmem;
} */
-tree
-gfc_allocate_using_malloc (stmtblock_t * block, tree size, tree status)
+void
+gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
+ tree size, tree status)
{
- stmtblock_t alloc_block;
- tree res, tmp, on_error;
+ tree tmp, on_error, error_cond;
tree status_type = status ? TREE_TYPE (status) : NULL_TREE;
/* Evaluate size only once, and make sure it has the right type. */
@@ -594,19 +594,15 @@ gfc_allocate_using_malloc (stmtblock_t * block, tree size, tree status)
if (TREE_TYPE (size) != TREE_TYPE (size_type_node))
size = fold_convert (size_type_node, size);
- /* Create a variable to hold the result. */
- res = gfc_create_var (prvoid_type_node, NULL);
-
- /* Set the optional status variable to zero. */
+ /* If successful and stat= is given, set status to 0. */
if (status != NULL_TREE)
gfc_add_expr_to_block (block,
fold_build2_loc (input_location, MODIFY_EXPR, status_type,
status, build_int_cst (status_type, 0)));
/* The allocation itself. */
- gfc_start_block (&alloc_block);
- gfc_add_modify (&alloc_block, res,
- fold_convert (prvoid_type_node,
+ gfc_add_modify (block, pointer,
+ fold_convert (TREE_TYPE (pointer),
build_call_expr_loc (input_location,
built_in_decls[BUILT_IN_MALLOC], 1,
fold_build2_loc (input_location,
@@ -623,16 +619,14 @@ gfc_allocate_using_malloc (stmtblock_t * block, tree size, tree status)
gfc_build_localized_cstring_const
("Allocation would exceed memory limit")));
+ error_cond = fold_build2_loc (input_location, EQ_EXPR,
+ boolean_type_node, pointer,
+ build_int_cst (prvoid_type_node, 0));
tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
- fold_build2_loc (input_location, EQ_EXPR,
- boolean_type_node, res,
- build_int_cst (prvoid_type_node, 0)),
- on_error, build_empty_stmt (input_location));
-
- gfc_add_expr_to_block (&alloc_block, tmp);
- gfc_add_expr_to_block (block, gfc_finish_block (&alloc_block));
+ gfc_unlikely(error_cond), on_error,
+ build_empty_stmt (input_location));
- return res;
+ gfc_add_expr_to_block (block, tmp);
}
@@ -648,20 +642,17 @@ gfc_allocate_using_malloc (stmtblock_t * block, tree size, tree status)
newmem = _caf_register ( size, regtype, NULL, &stat, NULL, NULL);
return newmem;
} */
-tree
-gfc_allocate_using_lib (stmtblock_t * block, tree size, tree status,
- tree errmsg, tree errlen)
+void
+gfc_allocate_using_lib (stmtblock_t * block, tree pointer, tree size,
+ tree status, tree errmsg, tree errlen)
{
- tree res, pstat;
+ tree tmp, pstat;
/* Evaluate size only once, and make sure it has the right type. */
size = gfc_evaluate_now (size, block);
if (TREE_TYPE (size) != TREE_TYPE (size_type_node))
size = fold_convert (size_type_node, size);
- /* Create a variable to hold the result. */
- res = gfc_create_var (prvoid_type_node, NULL);
-
/* The allocation itself. */
if (status == NULL_TREE)
pstat = null_pointer_node;
@@ -675,19 +666,20 @@ gfc_allocate_using_lib (stmtblock_t * block, tree size, tree status,
errlen = build_int_cst (integer_type_node, 0);
}
- gfc_add_modify (block, res,
- fold_convert (prvoid_type_node,
- build_call_expr_loc (input_location,
- gfor_fndecl_caf_register, 6,
- fold_build2_loc (input_location,
+ tmp = build_call_expr_loc (input_location,
+ gfor_fndecl_caf_register, 6,
+ fold_build2_loc (input_location,
MAX_EXPR, size_type_node, size,
build_int_cst (size_type_node, 1)),
- build_int_cst (integer_type_node,
+ build_int_cst (integer_type_node,
GFC_CAF_COARRAY_ALLOC),
- null_pointer_node, /* token */
- pstat, errmsg, errlen)));
+ null_pointer_node, /* token */
+ pstat, errmsg, errlen);
- return res;
+ tmp = fold_build2_loc (input_location, MODIFY_EXPR,
+ TREE_TYPE (pointer), pointer,
+ fold_convert ( TREE_TYPE (pointer), tmp));
+ gfc_add_expr_to_block (block, tmp);
}
@@ -705,12 +697,7 @@ gfc_allocate_using_lib (stmtblock_t * block, tree size, tree status,
else
{
if (stat)
- {
- free (mem);
- mem = allocate (size, stat);
stat = LIBERROR_ALLOCATION;
- return mem;
- }
else
runtime_error ("Attempting to allocate already allocated variable");
}
@@ -718,19 +705,17 @@ gfc_allocate_using_lib (stmtblock_t * block, tree size, tree status,
expr must be set to the original expression being allocated for its locus
and variable name in case a runtime error has to be printed. */
-tree
+void
gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size, tree status,
tree errmsg, tree errlen, gfc_expr* expr)
{
stmtblock_t alloc_block;
- tree res, tmp, null_mem, alloc, error;
+ tree tmp, null_mem, alloc, error;
tree type = TREE_TYPE (mem);
if (TREE_TYPE (size) != TREE_TYPE (size_type_node))
size = fold_convert (size_type_node, size);
- /* Create a variable to hold the result. */
- res = gfc_create_var (type, NULL);
null_mem = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR,
boolean_type_node, mem,
build_int_cst (type, 0)));
@@ -741,12 +726,11 @@ gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size, tree status,
if (gfc_option.coarray == GFC_FCOARRAY_LIB
&& gfc_expr_attr (expr).codimension)
- tmp = gfc_allocate_using_lib (&alloc_block, size, status,
- errmsg, errlen);
+ gfc_allocate_using_lib (&alloc_block, mem, size, status,
+ errmsg, errlen);
else
- tmp = gfc_allocate_using_malloc (&alloc_block, size, status);
+ gfc_allocate_using_malloc (&alloc_block, mem, size, status);
- gfc_add_modify (&alloc_block, res, fold_convert (type, tmp));
alloc = gfc_finish_block (&alloc_block);
/* If mem is not NULL, we issue a runtime error or set the
@@ -772,27 +756,14 @@ gfc_allocate_allocatable (stmtblock_t * block, tree mem, tree size, tree status,
if (status != NULL_TREE)
{
tree status_type = TREE_TYPE (status);
- stmtblock_t set_status_block;
-
- gfc_start_block (&set_status_block);
- tmp = build_call_expr_loc (input_location,
- built_in_decls[BUILT_IN_FREE], 1,
- fold_convert (pvoid_type_node, mem));
- gfc_add_expr_to_block (&set_status_block, tmp);
-
- tmp = gfc_allocate_using_malloc (&set_status_block, size, status);
- gfc_add_modify (&set_status_block, res, fold_convert (type, tmp));
- gfc_add_modify (&set_status_block, status,
- build_int_cst (status_type, LIBERROR_ALLOCATION));
- error = gfc_finish_block (&set_status_block);
+ error = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
+ status, build_int_cst (status_type, LIBERROR_ALLOCATION));
}
tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
error, alloc);
gfc_add_expr_to_block (block, tmp);
-
- return res;
}
@@ -1619,3 +1590,19 @@ gfc_unlikely (tree cond)
cond = fold_convert (boolean_type_node, cond);
return cond;
}
+
+
+/* Helper function for marking a boolean expression tree as likely. */
+
+tree
+gfc_likely (tree cond)
+{
+ tree tmp;
+
+ cond = fold_convert (long_integer_type_node, cond);
+ tmp = build_one_cst (long_integer_type_node);
+ cond = build_call_expr_loc (input_location,
+ built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
+ cond = fold_convert (boolean_type_node, cond);
+ return cond;
+}