Skip to content

Commit 4d715c5

Browse files
committed
Add support for machine-dependent builtins
1 parent 5a50919 commit 4d715c5

File tree

10 files changed

+1038
-34
lines changed

10 files changed

+1038
-34
lines changed

gcc/config/i386/i386-builtins.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,22 @@ static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];
224224

225225
struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
226226

227+
static void
228+
clear_builtin_types (void)
229+
{
230+
for (int i = 0 ; i < IX86_BT_LAST_CPTR + 1 ; i++)
231+
ix86_builtin_type_tab[i] = NULL;
232+
233+
for (int i = 0 ; i < IX86_BUILTIN_MAX ; i++)
234+
{
235+
ix86_builtins[i] = NULL;
236+
ix86_builtins_isa[i].set_and_not_built_p = true;
237+
}
238+
239+
for (int i = 0 ; i < IX86_BT_LAST_ALIAS + 1 ; i++)
240+
ix86_builtin_func_type_tab[i] = NULL;
241+
}
242+
227243
tree get_ix86_builtin (enum ix86_builtins c)
228244
{
229245
return ix86_builtins[c];
@@ -1407,6 +1423,8 @@ ix86_init_builtins (void)
14071423
{
14081424
tree ftype, decl;
14091425

1426+
clear_builtin_types ();
1427+
14101428
ix86_init_builtin_types ();
14111429

14121430
/* Builtins to get CPU type and features. */

gcc/jit/dummy-frontend.cc

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
2020
#include "config.h"
2121
#include "system.h"
2222
#include "coretypes.h"
23+
#include "target.h"
2324
#include "jit-playback.h"
2425
#include "stor-layout.h"
2526
#include "debug.h"
@@ -29,8 +30,14 @@ along with GCC; see the file COPYING3. If not see
2930
#include "options.h"
3031
#include "stringpool.h"
3132
#include "attribs.h"
33+
#include "print-tree.h"
34+
#include "jit-recording.h"
3235

3336
#include <mpfr.h>
37+
#include <unordered_map>
38+
#include <string>
39+
40+
using namespace gcc::jit;
3441

3542
/* Attribute handling. */
3643

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

96+
hash_map<nofree_string_hash, tree> target_builtins{};
97+
std::unordered_map<std::string, recording::function_type*> target_function_types{};
98+
recording::context target_builtins_ctxt{NULL};
99+
89100
/* Table of machine-independent attributes supported in libgccjit. */
90101
const struct attribute_spec jit_attribute_table[] =
91102
{
@@ -608,6 +619,9 @@ jit_langhook_init (void)
608619
eventually be controllable by a command line option. */
609620
mpfr_set_default_prec (256);
610621

622+
target_builtins.empty ();
623+
targetm.init_builtins ();
624+
611625
return true;
612626
}
613627

@@ -675,11 +689,211 @@ jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
675689
return NULL;
676690
}
677691

692+
recording::type* tree_type_to_jit_type (tree type)
693+
{
694+
if (TREE_CODE (type) == VECTOR_TYPE)
695+
{
696+
tree inner_type = TREE_TYPE (type);
697+
recording::type* element_type = tree_type_to_jit_type (inner_type);
698+
poly_uint64 size = TYPE_VECTOR_SUBPARTS (type);
699+
long constant_size = size.to_constant();
700+
if (element_type != NULL)
701+
return element_type->get_vector (constant_size);
702+
return NULL;
703+
}
704+
if (TREE_CODE (type) == REFERENCE_TYPE)
705+
{
706+
// For __builtin_ms_va_start.
707+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
708+
}
709+
if (TREE_CODE (type) == RECORD_TYPE)
710+
{
711+
// For __builtin_sysv_va_copy.
712+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
713+
}
714+
for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
715+
{
716+
if (type == FLOATN_NX_TYPE_NODE (i))
717+
{
718+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
719+
}
720+
}
721+
if (type == void_type_node)
722+
{
723+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID);
724+
}
725+
else if (type == ptr_type_node)
726+
{
727+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID_PTR);
728+
}
729+
else if (type == const_ptr_type_node)
730+
{
731+
// Void const ptr.
732+
recording::type* result = new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID_PTR);
733+
return new recording::memento_of_get_const (result);
734+
}
735+
else if (type == unsigned_type_node)
736+
{
737+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UNSIGNED_INT);
738+
}
739+
else if (type == long_unsigned_type_node)
740+
{
741+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UNSIGNED_LONG);
742+
}
743+
else if (type == integer_type_node)
744+
{
745+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_INT);
746+
}
747+
else if (type == long_integer_type_node)
748+
{
749+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_LONG);
750+
}
751+
else if (type == long_long_integer_type_node)
752+
{
753+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_LONG_LONG);
754+
}
755+
else if (type == signed_char_type_node)
756+
{
757+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_SIGNED_CHAR);
758+
}
759+
else if (type == char_type_node)
760+
{
761+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_CHAR);
762+
}
763+
else if (type == unsigned_intQI_type_node)
764+
{
765+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UINT8_T);
766+
}
767+
else if (type == short_integer_type_node)
768+
{
769+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_SHORT);
770+
}
771+
else if (type == short_unsigned_type_node)
772+
{
773+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UNSIGNED_SHORT);
774+
}
775+
else if (type == complex_float_type_node)
776+
{
777+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_COMPLEX_FLOAT);
778+
}
779+
else if (type == complex_double_type_node)
780+
{
781+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_COMPLEX_DOUBLE);
782+
}
783+
else if (type == complex_long_double_type_node)
784+
{
785+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE);
786+
}
787+
else if (type == float_type_node)
788+
{
789+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_FLOAT);
790+
}
791+
else if (type == double_type_node)
792+
{
793+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_DOUBLE);
794+
}
795+
else if (type == long_double_type_node)
796+
{
797+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_LONG_DOUBLE);
798+
}
799+
else if (type == dfloat128_type_node)
800+
{
801+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
802+
}
803+
else if (type == long_long_unsigned_type_node)
804+
{
805+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
806+
}
807+
else if (type == boolean_type_node)
808+
{
809+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_BOOL);
810+
}
811+
else if (type == size_type_node)
812+
{
813+
return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_SIZE_T);
814+
}
815+
else if (TREE_CODE (type) == POINTER_TYPE)
816+
{
817+
tree inner_type = TREE_TYPE (type);
818+
recording::type* element_type = tree_type_to_jit_type (inner_type);
819+
return element_type->get_pointer();
820+
}
821+
else
822+
{
823+
// Attempt to find an unqualified type when the current type has qualifiers.
824+
tree tp = TYPE_MAIN_VARIANT (type);
825+
for ( ; tp != NULL ; tp = TYPE_NEXT_VARIANT (tp))
826+
{
827+
if (TYPE_QUALS (tp) == 0)
828+
{
829+
recording::type* result = tree_type_to_jit_type (tp);
830+
if (result != NULL)
831+
{
832+
if (TYPE_READONLY (tp))
833+
result = new recording::memento_of_get_const (result);
834+
if (TYPE_VOLATILE (tp))
835+
result = new recording::memento_of_get_volatile (result);
836+
return result;
837+
}
838+
}
839+
}
840+
841+
fprintf (stderr, "Unknown type:\n");
842+
debug_tree (type);
843+
abort ();
844+
}
845+
846+
return NULL;
847+
}
848+
678849
/* Record a builtin function. We just ignore builtin functions. */
679850

680851
static tree
681852
jit_langhook_builtin_function (tree decl)
682853
{
854+
if (TREE_CODE (decl) == FUNCTION_DECL)
855+
{
856+
const char* name = IDENTIFIER_POINTER (DECL_NAME (decl));
857+
target_builtins.put (name, decl);
858+
859+
std::string string_name(name);
860+
if (target_function_types.count (string_name) == 0)
861+
{
862+
tree function_type = TREE_TYPE (decl);
863+
tree arg = TYPE_ARG_TYPES (function_type);
864+
bool is_variadic = false;
865+
866+
auto_vec <recording::type *> param_types;
867+
868+
while (arg != void_list_node)
869+
{
870+
if (arg == NULL)
871+
{
872+
is_variadic = true;
873+
break;
874+
}
875+
if (arg != void_list_node)
876+
{
877+
recording::type* arg_type = tree_type_to_jit_type(TREE_VALUE (arg));
878+
if (arg_type == NULL)
879+
return decl;
880+
param_types.safe_push (arg_type);
881+
}
882+
arg = TREE_CHAIN (arg);
883+
}
884+
885+
tree result_type = TREE_TYPE (function_type);
886+
recording::type* return_type = tree_type_to_jit_type(result_type);
887+
888+
if (return_type == NULL)
889+
return decl;
890+
891+
recording::function_type* func_type = new recording::function_type (&target_builtins_ctxt, return_type, param_types.length (),
892+
param_types.address (), is_variadic, false);
893+
894+
target_function_types[string_name] = func_type;
895+
}
896+
}
683897
return decl;
684898
}
685899

gcc/jit/jit-builtins.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ builtins_manager::make_builtin_function (enum built_in_function builtin_id)
217217
param_types.length (),
218218
params,
219219
func_type->is_variadic (),
220-
builtin_id);
220+
builtin_id,
221+
false);
221222
delete[] params;
222223

223224
/* PR/64020 - If the client code is using builtin cos or sin,
@@ -584,7 +585,8 @@ builtins_manager::make_fn_type (enum jit_builtin_type,
584585
result = m_ctxt->new_function_type (return_type,
585586
num_args,
586587
param_types,
587-
is_variadic);
588+
is_variadic,
589+
false);
588590

589591
error:
590592
delete[] param_types;

0 commit comments

Comments
 (0)