@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
20
20
#include " config.h"
21
21
#include " system.h"
22
22
#include " coretypes.h"
23
+ #include " target.h"
23
24
#include " jit-playback.h"
24
25
#include " stor-layout.h"
25
26
#include " debug.h"
@@ -29,8 +30,14 @@ along with GCC; see the file COPYING3. If not see
29
30
#include " options.h"
30
31
#include " stringpool.h"
31
32
#include " attribs.h"
33
+ #include " jit-recording.h"
34
+ #include " print-tree.h"
32
35
33
36
#include < mpfr.h>
37
+ #include < unordered_map>
38
+ #include < string>
39
+
40
+ using namespace gcc ::jit;
34
41
35
42
/* Attribute handling. */
36
43
@@ -86,6 +93,10 @@ static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
86
93
ATTR_EXCL (NULL , false , false , false )
87
94
};
88
95
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
+
89
100
/* Table of machine-independent attributes supported in libgccjit. */
90
101
const struct attribute_spec jit_attribute_table[] =
91
102
{
@@ -609,6 +620,8 @@ jit_langhook_init (void)
609
620
eventually be controllable by a command line option. */
610
621
mpfr_set_default_prec (256 );
611
622
623
+ targetm.init_builtins ();
624
+
612
625
return true ;
613
626
}
614
627
@@ -676,11 +689,216 @@ jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
676
689
return NULL ;
677
690
}
678
691
679
- /* Record a builtin function. We just ignore builtin functions. */
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 == bfloat16_type_node)
800
+ {
801
+ return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_BFLOAT16);
802
+ }
803
+ else if (type == dfloat128_type_node)
804
+ {
805
+ return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); // FIXME: wrong type.
806
+ }
807
+ else if (type == long_long_unsigned_type_node)
808
+ {
809
+ return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
810
+ }
811
+ else if (type == boolean_type_node)
812
+ {
813
+ return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_BOOL);
814
+ }
815
+ else if (type == size_type_node)
816
+ {
817
+ return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_SIZE_T);
818
+ }
819
+ else if (TREE_CODE (type) == POINTER_TYPE)
820
+ {
821
+ tree inner_type = TREE_TYPE (type);
822
+ recording::type* element_type = tree_type_to_jit_type (inner_type);
823
+ return element_type->get_pointer ();
824
+ }
825
+ else
826
+ {
827
+ // Attempt to find an unqualified type when the current type has qualifiers.
828
+ tree tp = TYPE_MAIN_VARIANT (type);
829
+ for ( ; tp != NULL ; tp = TYPE_NEXT_VARIANT (tp))
830
+ {
831
+ if (TYPE_QUALS (tp) == 0 && type != tp)
832
+ {
833
+ recording::type* result = tree_type_to_jit_type (tp);
834
+ if (result != NULL )
835
+ {
836
+ if (TYPE_READONLY (tp))
837
+ result = new recording::memento_of_get_const (result);
838
+ if (TYPE_VOLATILE (tp))
839
+ result = new recording::memento_of_get_volatile (result);
840
+ return result;
841
+ }
842
+ }
843
+ }
844
+
845
+ fprintf (stderr, " Unknown type:\n " );
846
+ debug_tree (type);
847
+ abort ();
848
+ }
849
+
850
+ return NULL ;
851
+ }
852
+
853
+ /* Record a builtin function. We save their types to be able to check types
854
+ in recording and for reflection. */
680
855
681
856
static tree
682
857
jit_langhook_builtin_function (tree decl)
683
858
{
859
+ if (TREE_CODE (decl) == FUNCTION_DECL)
860
+ {
861
+ const char * name = IDENTIFIER_POINTER (DECL_NAME (decl));
862
+ target_builtins.put (name, decl);
863
+
864
+ std::string string_name (name);
865
+ if (target_function_types.count (string_name) == 0 )
866
+ {
867
+ tree function_type = TREE_TYPE (decl);
868
+ tree arg = TYPE_ARG_TYPES (function_type);
869
+ bool is_variadic = false ;
870
+
871
+ auto_vec <recording::type *> param_types;
872
+
873
+ while (arg != void_list_node)
874
+ {
875
+ if (arg == NULL )
876
+ {
877
+ is_variadic = true ;
878
+ break ;
879
+ }
880
+ if (arg != void_list_node)
881
+ {
882
+ recording::type* arg_type = tree_type_to_jit_type (TREE_VALUE (arg));
883
+ if (arg_type == NULL )
884
+ return decl;
885
+ param_types.safe_push (arg_type);
886
+ }
887
+ arg = TREE_CHAIN (arg);
888
+ }
889
+
890
+ tree result_type = TREE_TYPE (function_type);
891
+ recording::type* return_type = tree_type_to_jit_type (result_type);
892
+
893
+ if (return_type == NULL )
894
+ return decl;
895
+
896
+ recording::function_type* func_type = new recording::function_type (&target_builtins_ctxt, return_type, param_types.length (),
897
+ param_types.address (), is_variadic, false );
898
+
899
+ target_function_types[string_name] = func_type;
900
+ }
901
+ }
684
902
return decl;
685
903
}
686
904
0 commit comments