Skip to content

Commit 94fd630

Browse files
committed
Add support for machine-dependent builtins
1 parent cd57a24 commit 94fd630

File tree

10 files changed

+1012
-28
lines changed

10 files changed

+1012
-28
lines changed

gcc/config/i386/i386-builtins.cc

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

227227
struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
228228

229+
static void
230+
clear_builtin_types (void)
231+
{
232+
for (int i = 0 ; i < IX86_BT_LAST_CPTR + 1 ; i++)
233+
ix86_builtin_type_tab[i] = NULL;
234+
235+
for (int i = 0 ; i < IX86_BUILTIN_MAX ; i++)
236+
{
237+
ix86_builtins[i] = NULL;
238+
ix86_builtins_isa[i].set_and_not_built_p = true;
239+
}
240+
241+
for (int i = 0 ; i < IX86_BT_LAST_ALIAS + 1 ; i++)
242+
ix86_builtin_func_type_tab[i] = NULL;
243+
}
244+
229245
tree get_ix86_builtin (enum ix86_builtins c)
230246
{
231247
return ix86_builtins[c];
@@ -1443,6 +1459,8 @@ ix86_init_builtins (void)
14431459
{
14441460
tree ftype, decl;
14451461

1462+
clear_builtin_types ();
1463+
14461464
ix86_init_builtin_types ();
14471465

14481466
/* 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
{
@@ -601,6 +612,9 @@ jit_langhook_init (void)
601612
eventually be controllable by a command line option. */
602613
mpfr_set_default_prec (256);
603614

615+
target_builtins.empty ();
616+
targetm.init_builtins ();
617+
604618
return true;
605619
}
606620

@@ -668,11 +682,211 @@ jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
668682
return NULL;
669683
}
670684

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

673844
static tree
674845
jit_langhook_builtin_function (tree decl)
675846
{
847+
if (TREE_CODE (decl) == FUNCTION_DECL)
848+
{
849+
const char* name = IDENTIFIER_POINTER (DECL_NAME (decl));
850+
target_builtins.put (name, decl);
851+
852+
std::string string_name(name);
853+
if (target_function_types.count (string_name) == 0)
854+
{
855+
tree function_type = TREE_TYPE (decl);
856+
tree arg = TYPE_ARG_TYPES (function_type);
857+
bool is_variadic = false;
858+
859+
auto_vec <recording::type *> param_types;
860+
861+
while (arg != void_list_node)
862+
{
863+
if (arg == NULL)
864+
{
865+
is_variadic = true;
866+
break;
867+
}
868+
if (arg != void_list_node)
869+
{
870+
recording::type* arg_type = tree_type_to_jit_type(TREE_VALUE (arg));
871+
if (arg_type == NULL)
872+
return decl;
873+
param_types.safe_push (arg_type);
874+
}
875+
arg = TREE_CHAIN (arg);
876+
}
877+
878+
tree result_type = TREE_TYPE (function_type);
879+
recording::type* return_type = tree_type_to_jit_type(result_type);
880+
881+
if (return_type == NULL)
882+
return decl;
883+
884+
recording::function_type* func_type = new recording::function_type (&target_builtins_ctxt, return_type, param_types.length (),
885+
param_types.address (), is_variadic, false);
886+
887+
target_function_types[string_name] = func_type;
888+
}
889+
}
676890
return decl;
677891
}
678892

gcc/jit/jit-builtins.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ builtins_manager::make_builtin_function (enum built_in_function builtin_id)
215215
param_types.length (),
216216
params,
217217
func_type->is_variadic (),
218-
builtin_id);
218+
builtin_id,
219+
false);
219220
delete[] params;
220221

221222
/* PR/64020 - If the client code is using builtin cos or sin,
@@ -582,7 +583,8 @@ builtins_manager::make_fn_type (enum jit_builtin_type,
582583
result = m_ctxt->new_function_type (return_type,
583584
num_args,
584585
param_types,
585-
is_variadic);
586+
is_variadic,
587+
false);
586588

587589
error:
588590
delete[] param_types;

0 commit comments

Comments
 (0)