Skip to content

Feature/jit target builtins #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions gcc/config/i386/i386-builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,22 @@ static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];

struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];

static void
clear_builtin_types (void)
{
for (int i = 0 ; i < IX86_BT_LAST_CPTR + 1 ; i++)
ix86_builtin_type_tab[i] = NULL;

for (int i = 0 ; i < IX86_BUILTIN_MAX ; i++)
{
ix86_builtins[i] = NULL;
ix86_builtins_isa[i].set_and_not_built_p = true;
}

for (int i = 0 ; i < IX86_BT_LAST_ALIAS + 1 ; i++)
ix86_builtin_func_type_tab[i] = NULL;
}

tree get_ix86_builtin (enum ix86_builtins c)
{
return ix86_builtins[c];
Expand Down Expand Up @@ -1407,6 +1423,8 @@ ix86_init_builtins (void)
{
tree ftype, decl;

clear_builtin_types ();

ix86_init_builtin_types ();

/* Builtins to get CPU type and features. */
Expand Down
214 changes: 214 additions & 0 deletions gcc/jit/dummy-frontend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "jit-playback.h"
#include "stor-layout.h"
#include "debug.h"
Expand All @@ -29,8 +30,14 @@ along with GCC; see the file COPYING3. If not see
#include "options.h"
#include "stringpool.h"
#include "attribs.h"
#include "print-tree.h"
#include "jit-recording.h"

#include <mpfr.h>
#include <unordered_map>
#include <string>

using namespace gcc::jit;

/* Attribute handling. */

Expand Down Expand Up @@ -86,6 +93,10 @@ static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
ATTR_EXCL (NULL, false, false, false)
};

hash_map<nofree_string_hash, tree> target_builtins{};
std::unordered_map<std::string, recording::function_type*> target_function_types{};
recording::context target_builtins_ctxt{NULL};

/* Table of machine-independent attributes supported in libgccjit. */
const struct attribute_spec jit_attribute_table[] =
{
Expand Down Expand Up @@ -608,6 +619,9 @@ jit_langhook_init (void)
eventually be controllable by a command line option. */
mpfr_set_default_prec (256);

target_builtins.empty ();
targetm.init_builtins ();

return true;
}

Expand Down Expand Up @@ -675,11 +689,211 @@ jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
return NULL;
}

recording::type* tree_type_to_jit_type (tree type)
{
if (TREE_CODE (type) == VECTOR_TYPE)
{
tree inner_type = TREE_TYPE (type);
recording::type* element_type = tree_type_to_jit_type (inner_type);
poly_uint64 size = TYPE_VECTOR_SUBPARTS (type);
long constant_size = size.to_constant();
if (element_type != NULL)
return element_type->get_vector (constant_size);
return NULL;
}
if (TREE_CODE (type) == REFERENCE_TYPE)
{
// For __builtin_ms_va_start.
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
}
if (TREE_CODE (type) == RECORD_TYPE)
{
// For __builtin_sysv_va_copy.
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
}
for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
{
if (type == FLOATN_NX_TYPE_NODE (i))
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
}
}
if (type == void_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID);
}
else if (type == ptr_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID_PTR);
}
else if (type == const_ptr_type_node)
{
// Void const ptr.
recording::type* result = new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID_PTR);
return new recording::memento_of_get_const (result);
}
else if (type == unsigned_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UNSIGNED_INT);
}
else if (type == long_unsigned_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UNSIGNED_LONG);
}
else if (type == integer_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_INT);
}
else if (type == long_integer_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_LONG);
}
else if (type == long_long_integer_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_LONG_LONG);
}
else if (type == signed_char_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_SIGNED_CHAR);
}
else if (type == char_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_CHAR);
}
else if (type == unsigned_intQI_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UINT8_T);
}
else if (type == short_integer_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_SHORT);
}
else if (type == short_unsigned_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UNSIGNED_SHORT);
}
else if (type == complex_float_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_COMPLEX_FLOAT);
}
else if (type == complex_double_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_COMPLEX_DOUBLE);
}
else if (type == complex_long_double_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE);
}
else if (type == float_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_FLOAT);
}
else if (type == double_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_DOUBLE);
}
else if (type == long_double_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_LONG_DOUBLE);
}
else if (type == dfloat128_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
}
else if (type == long_long_unsigned_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
}
else if (type == boolean_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_BOOL);
}
else if (type == size_type_node)
{
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_SIZE_T);
}
else if (TREE_CODE (type) == POINTER_TYPE)
{
tree inner_type = TREE_TYPE (type);
recording::type* element_type = tree_type_to_jit_type (inner_type);
return element_type->get_pointer();
}
else
{
// Attempt to find an unqualified type when the current type has qualifiers.
tree tp = TYPE_MAIN_VARIANT (type);
for ( ; tp != NULL ; tp = TYPE_NEXT_VARIANT (tp))
{
if (TYPE_QUALS (tp) == 0)
{
recording::type* result = tree_type_to_jit_type (tp);
if (result != NULL)
{
if (TYPE_READONLY (tp))
result = new recording::memento_of_get_const (result);
if (TYPE_VOLATILE (tp))
result = new recording::memento_of_get_volatile (result);
return result;
}
}
}

fprintf (stderr, "Unknown type:\n");
debug_tree (type);
abort ();
}

return NULL;
}

/* Record a builtin function. We just ignore builtin functions. */

static tree
jit_langhook_builtin_function (tree decl)
{
if (TREE_CODE (decl) == FUNCTION_DECL)
{
const char* name = IDENTIFIER_POINTER (DECL_NAME (decl));
target_builtins.put (name, decl);

std::string string_name(name);
if (target_function_types.count (string_name) == 0)
{
tree function_type = TREE_TYPE (decl);
tree arg = TYPE_ARG_TYPES (function_type);
bool is_variadic = false;

auto_vec <recording::type *> param_types;

while (arg != void_list_node)
{
if (arg == NULL)
{
is_variadic = true;
break;
}
if (arg != void_list_node)
{
recording::type* arg_type = tree_type_to_jit_type(TREE_VALUE (arg));
if (arg_type == NULL)
return decl;
param_types.safe_push (arg_type);
}
arg = TREE_CHAIN (arg);
}

tree result_type = TREE_TYPE (function_type);
recording::type* return_type = tree_type_to_jit_type(result_type);

if (return_type == NULL)
return decl;

recording::function_type* func_type = new recording::function_type (&target_builtins_ctxt, return_type, param_types.length (),
param_types.address (), is_variadic, false);

target_function_types[string_name] = func_type;
}
}
return decl;
}

Expand Down
6 changes: 4 additions & 2 deletions gcc/jit/jit-builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ builtins_manager::make_builtin_function (enum built_in_function builtin_id)
param_types.length (),
params,
func_type->is_variadic (),
builtin_id);
builtin_id,
false);
delete[] params;

/* PR/64020 - If the client code is using builtin cos or sin,
Expand Down Expand Up @@ -584,7 +585,8 @@ builtins_manager::make_fn_type (enum jit_builtin_type,
result = m_ctxt->new_function_type (return_type,
num_args,
param_types,
is_variadic);
is_variadic,
false);

error:
delete[] param_types;
Expand Down
Loading