|
@@ -288,6 +288,129 @@ handle_pragma_wait (struct cpp_reader *reader)
|
|
|
add_stmt (build_call_expr (fndecl, 0));
|
|
|
}
|
|
|
|
|
|
+/* Process `#pragma starpu register VAR [COUNT]' and emit the corresponding
|
|
|
+ `starpu_vector_data_register' call.
|
|
|
+
|
|
|
+ FIXME: Currently processing happens before macro expansion, even though
|
|
|
+ the docstring of `cpp_get_token' says otherwise. */
|
|
|
+
|
|
|
+static void
|
|
|
+handle_pragma_register (struct cpp_reader *reader)
|
|
|
+{
|
|
|
+ const cpp_token *token;
|
|
|
+
|
|
|
+ token = cpp_peek_token (reader, 0);
|
|
|
+ if (token->type == CPP_PRAGMA_EOL)
|
|
|
+ error_at (token->src_loc, "unterminated %<starpu register%> pragma");
|
|
|
+
|
|
|
+ token = cpp_get_token (reader);
|
|
|
+ if (token->type != CPP_NAME)
|
|
|
+ error_at (token->src_loc, "identifier expected");
|
|
|
+
|
|
|
+ /* Get the variable name. */
|
|
|
+ tree var_name = get_identifier ((char *) cpp_token_as_text (reader, token));
|
|
|
+
|
|
|
+ tree var = lookup_name (var_name);
|
|
|
+ if (var == NULL_TREE || !DECL_P (var))
|
|
|
+ error_at (token->src_loc, "unbound variable %qE", var_name);
|
|
|
+
|
|
|
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (var))
|
|
|
+ || TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE);
|
|
|
+
|
|
|
+ if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
|
|
|
+ && !DECL_EXTERNAL (var)
|
|
|
+ && !TREE_STATIC (var)
|
|
|
+ && !MAIN_NAME_P (DECL_NAME (current_function_decl)))
|
|
|
+ warning_at (token->src_loc, 0, "using an on-stack array as a task input "
|
|
|
+ "considered unsafe");
|
|
|
+
|
|
|
+ /* Determine the number of elements in the vector. */
|
|
|
+ tree count = NULL_TREE;
|
|
|
+
|
|
|
+ if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
|
|
|
+ {
|
|
|
+ tree domain = TYPE_DOMAIN (TREE_TYPE (var));
|
|
|
+
|
|
|
+ if (domain != NULL_TREE)
|
|
|
+ {
|
|
|
+ count = build_binary_op (token->src_loc, MINUS_EXPR,
|
|
|
+ TYPE_MAX_VALUE (domain),
|
|
|
+ TYPE_MIN_VALUE (domain),
|
|
|
+ false);
|
|
|
+ count = build_binary_op (token->src_loc, PLUS_EXPR,
|
|
|
+ count,
|
|
|
+ build_int_cstu (integer_type_node, 1),
|
|
|
+ false);
|
|
|
+ count = fold_convert (size_type_node, count);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ token = cpp_peek_token (reader, 0);
|
|
|
+ if (token->type == CPP_PRAGMA_EOL)
|
|
|
+ {
|
|
|
+ /* End of line reached: don't consume TOKEN and check whether the array
|
|
|
+ size was determined. */
|
|
|
+ if (count == NULL_TREE)
|
|
|
+ error_at (token->src_loc, "cannot determine size of array %qE",
|
|
|
+ var_name);
|
|
|
+ }
|
|
|
+ else if (token->type == CPP_NUMBER)
|
|
|
+ {
|
|
|
+ /* TOKEN is a number, consume it. */
|
|
|
+ token = cpp_get_token (reader);
|
|
|
+
|
|
|
+ unsigned int flags = cpp_classify_number (reader, token);
|
|
|
+ if ((flags & CPP_N_CATEGORY) != CPP_N_INTEGER)
|
|
|
+ error_at (token->src_loc, "invalid integer");
|
|
|
+
|
|
|
+ cpp_num value = cpp_interpret_integer (reader, token, CPP_N_UNSIGNED);
|
|
|
+ tree count_arg = build_int_cst_wide (size_type_node, value.low, value.high);
|
|
|
+
|
|
|
+ if (count != NULL_TREE)
|
|
|
+ {
|
|
|
+ /* The number of elements of this array was already determined. */
|
|
|
+ inform (token->src_loc,
|
|
|
+ "element count can be omitted for bounded array %qE",
|
|
|
+ var_name);
|
|
|
+
|
|
|
+ if (!tree_int_cst_equal (count, count_arg))
|
|
|
+ error_at (token->src_loc,
|
|
|
+ "specified element count differs from actual size of array %qE",
|
|
|
+ var_name);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ count = count_arg;
|
|
|
+
|
|
|
+ if (cpp_peek_token (reader, 0)->type != CPP_PRAGMA_EOL)
|
|
|
+ error_at (token->src_loc, "junk after %<starpu register%> pragma");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ error_at (token->src_loc, "integer expected");
|
|
|
+
|
|
|
+ /* If VAR is an array, take its address. */
|
|
|
+ tree pointer =
|
|
|
+ POINTER_TYPE_P (TREE_TYPE (var))
|
|
|
+ ? var
|
|
|
+ : build_addr (var, current_function_decl);
|
|
|
+
|
|
|
+ /* Introduce a local variable to hold the handle. */
|
|
|
+ tree handle_var = create_tmp_var (ptr_type_node, ".handle");
|
|
|
+
|
|
|
+ tree register_fn =
|
|
|
+ lookup_name (get_identifier ("starpu_vector_data_register"));
|
|
|
+
|
|
|
+ /* Build `starpu_vector_data_register (&HANDLE_VAR, 0, POINTER,
|
|
|
+ COUNT, sizeof *POINTER)' */
|
|
|
+ tree call =
|
|
|
+ build_call_expr (register_fn, 5,
|
|
|
+ build_addr (handle_var, current_function_decl),
|
|
|
+ build_zero_cst (uintptr_type_node), /* home node */
|
|
|
+ pointer, count,
|
|
|
+ size_in_bytes (TREE_TYPE (TREE_TYPE (var))));
|
|
|
+
|
|
|
+ add_stmt (call);
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
register_pragmas (void *gcc_data, void *user_data)
|
|
|
{
|
|
@@ -295,6 +418,8 @@ register_pragmas (void *gcc_data, void *user_data)
|
|
|
handle_pragma_hello);
|
|
|
c_register_pragma (STARPU_PRAGMA_NAME_SPACE, "wait",
|
|
|
handle_pragma_wait);
|
|
|
+ c_register_pragma (STARPU_PRAGMA_NAME_SPACE, "register",
|
|
|
+ handle_pragma_register);
|
|
|
}
|
|
|
|
|
|
|