LCOV - code coverage report
Current view: top level - gcc/rust/backend - rust-builtins.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.1 % 87 81
Test Date: 2024-04-20 14:03:02 Functions: 100.0 % 12 12
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // This file is part of GCC.
       2                 :             : 
       3                 :             : // GCC is free software; you can redistribute it and/or modify it under
       4                 :             : // the terms of the GNU General Public License as published by the Free
       5                 :             : // Software Foundation; either version 3, or (at your option) any later
       6                 :             : // version.
       7                 :             : 
       8                 :             : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
       9                 :             : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      10                 :             : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      11                 :             : // for more details.
      12                 :             : 
      13                 :             : // You should have received a copy of the GNU General Public License
      14                 :             : // along with GCC; see the file COPYING3.  If not see
      15                 :             : // <http://www.gnu.org/licenses/>.
      16                 :             : 
      17                 :             : #include "rust-diagnostics.h"
      18                 :             : #include "rust-system.h"
      19                 :             : #include "rust-builtins.h"
      20                 :             : 
      21                 :             : #include "target.h"
      22                 :             : #include "stringpool.h"
      23                 :             : 
      24                 :             : namespace Rust {
      25                 :             : namespace Compile {
      26                 :             : 
      27                 :             : BuiltinsContext &
      28                 :        4204 : BuiltinsContext::get ()
      29                 :             : {
      30                 :        4204 :   static BuiltinsContext instance;
      31                 :        4204 :   return instance;
      32                 :             : }
      33                 :             : 
      34                 :             : bool
      35                 :        6119 : BuiltinsContext::lookup_simple_builtin (const std::string &name, tree *builtin)
      36                 :             : {
      37                 :        6119 :   auto *to_search = &name;
      38                 :             : 
      39                 :        6119 :   auto it = rust_intrinsic_to_gcc_builtin.find (name);
      40                 :        6119 :   if (it != rust_intrinsic_to_gcc_builtin.end ())
      41                 :         308 :     to_search = &it->second;
      42                 :             : 
      43                 :        6119 :   return lookup_gcc_builtin (*to_search, builtin);
      44                 :             : }
      45                 :             : 
      46                 :        1028 : BuiltinsContext::BuiltinsContext () { setup (); }
      47                 :             : 
      48                 :             : /**
      49                 :             :  * Define a function type according to `builtin-types.def`
      50                 :             :  *
      51                 :             :  * *Heavily* inspired by the D frontend's `def_fn_type` function
      52                 :             :  */
      53                 :             : void
      54                 :      498580 : BuiltinsContext::define_function_type (Type def_idx, Type ret_idx,
      55                 :             :                                        bool is_variadic, size_t n, ...)
      56                 :             : {
      57                 :      498580 :   va_list list;
      58                 :      498580 :   va_start (list, n);
      59                 :             : 
      60                 :      498580 :   auto args = std::vector<tree> ();
      61                 :             : 
      62                 :     1594428 :   for (size_t i = 0; i < n; i++)
      63                 :             :     {
      64                 :             :       // The argument is an enum Type, but it's promoted to int when passed
      65                 :             :       // though '...'.
      66                 :     1095848 :       auto arg_idx = va_arg (list, int);
      67                 :     1095848 :       auto arg_type = builtin_types[arg_idx];
      68                 :             : 
      69                 :     1095848 :       args.emplace_back (arg_type);
      70                 :             :     }
      71                 :             : 
      72                 :      498580 :   auto return_type = builtin_types[ret_idx];
      73                 :      498580 :   if (return_type == error_mark_node)
      74                 :             :     {
      75                 :             :       // Mark the builtin as not available.
      76                 :       13364 :       builtin_types[def_idx] = error_mark_node;
      77                 :       13364 :       va_end (list);
      78                 :       13364 :       return;
      79                 :             :     }
      80                 :             : 
      81                 :      485216 :   auto fn_type = NULL_TREE;
      82                 :      485216 :   if (is_variadic)
      83                 :       30840 :     fn_type = build_varargs_function_type_array (return_type, n, args.data ());
      84                 :             :   else
      85                 :      454376 :     fn_type = build_function_type_array (return_type, n, args.data ());
      86                 :             : 
      87                 :      485216 :   builtin_types[def_idx] = fn_type;
      88                 :      485216 :   va_end (list);
      89                 :      498580 : }
      90                 :             : 
      91                 :             : // Taken directly from the D frontend
      92                 :             : static void
      93                 :        1028 : build_c_type_nodes (void)
      94                 :             : {
      95                 :        1028 :   string_type_node = build_pointer_type (char_type_node);
      96                 :        1028 :   const_string_type_node = build_pointer_type (
      97                 :             :     build_qualified_type (char_type_node, TYPE_QUAL_CONST));
      98                 :             : 
      99                 :        1028 :   if (strcmp (UINTMAX_TYPE, "unsigned int") == 0)
     100                 :             :     {
     101                 :           0 :       intmax_type_node = integer_type_node;
     102                 :           0 :       uintmax_type_node = unsigned_type_node;
     103                 :             :     }
     104                 :        1028 :   else if (strcmp (UINTMAX_TYPE, "long unsigned int") == 0)
     105                 :             :     {
     106                 :        1028 :       intmax_type_node = long_integer_type_node;
     107                 :        1028 :       uintmax_type_node = long_unsigned_type_node;
     108                 :             :     }
     109                 :           0 :   else if (strcmp (UINTMAX_TYPE, "long long unsigned int") == 0)
     110                 :             :     {
     111                 :           0 :       intmax_type_node = long_long_integer_type_node;
     112                 :           0 :       uintmax_type_node = long_long_unsigned_type_node;
     113                 :             :     }
     114                 :             :   else
     115                 :           0 :     gcc_unreachable ();
     116                 :             : 
     117                 :        1028 :   signed_size_type_node = signed_type_for (size_type_node);
     118                 :        1028 :   wint_type_node = unsigned_type_node;
     119                 :        1028 :   pid_type_node = integer_type_node;
     120                 :        1028 : }
     121                 :             : 
     122                 :             : /**
     123                 :             :  * Define all builtin types in the `builtin_types` array
     124                 :             :  */
     125                 :             : void
     126                 :        1028 : BuiltinsContext::define_builtin_types ()
     127                 :             : {
     128                 :             :   // This is taken directly from the D frontend's handling of builtins
     129                 :        1028 :   auto va_list_ref_type_node = build_reference_type (va_list_type_node);
     130                 :        1028 :   auto va_list_arg_type_node = va_list_type_node;
     131                 :             : 
     132                 :        1028 :   build_c_type_nodes ();
     133                 :             : 
     134                 :        1028 :   auto builtin_type_for_size = [] (int size, bool unsignedp) {
     135                 :        5140 :     tree type = lang_hooks.types.type_for_size (size, unsignedp);
     136                 :        5140 :     return type ? type : error_mark_node;
     137                 :             :   };
     138                 :             : 
     139                 :             : #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) builtin_types[ENUM] = VALUE;
     140                 :             : #define DEF_FUNCTION_TYPE_0(ENUM, RETURN)                                      \
     141                 :             :   define_function_type (ENUM, RETURN, 0, 0);
     142                 :             : #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, A1)                                  \
     143                 :             :   define_function_type (ENUM, RETURN, 0, 1, A1);
     144                 :             : #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, A1, A2)                              \
     145                 :             :   define_function_type (ENUM, RETURN, 0, 2, A1, A2);
     146                 :             : #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, A1, A2, A3)                          \
     147                 :             :   define_function_type (ENUM, RETURN, 0, 3, A1, A2, A3);
     148                 :             : #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, A1, A2, A3, A4)                      \
     149                 :             :   define_function_type (ENUM, RETURN, 0, 4, A1, A2, A3, A4);
     150                 :             : #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, A1, A2, A3, A4, A5)                  \
     151                 :             :   define_function_type (ENUM, RETURN, 0, 5, A1, A2, A3, A4, A5);
     152                 :             : #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, A1, A2, A3, A4, A5, A6)              \
     153                 :             :   define_function_type (ENUM, RETURN, 0, 6, A1, A2, A3, A4, A5, A6);
     154                 :             : #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, A1, A2, A3, A4, A5, A6, A7)          \
     155                 :             :   define_function_type (ENUM, RETURN, 0, 7, A1, A2, A3, A4, A5, A6, A7);
     156                 :             : #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, A1, A2, A3, A4, A5, A6, A7, A8)      \
     157                 :             :   define_function_type (ENUM, RETURN, 0, 8, A1, A2, A3, A4, A5, A6, A7, A8);
     158                 :             : #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, A1, A2, A3, A4, A5, A6, A7, A8, A9)  \
     159                 :             :   define_function_type (ENUM, RETURN, 0, 9, A1, A2, A3, A4, A5, A6, A7, A8, A9);
     160                 :             : #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, A1, A2, A3, A4, A5, A6, A7, A8, A9, \
     161                 :             :                              A10)                                              \
     162                 :             :   define_function_type (ENUM, RETURN, 0, 10, A1, A2, A3, A4, A5, A6, A7, A8,   \
     163                 :             :                         A9, A10);
     164                 :             : #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, A1, A2, A3, A4, A5, A6, A7, A8, A9, \
     165                 :             :                              A10, A11)                                         \
     166                 :             :   define_function_type (ENUM, RETURN, 0, 11, A1, A2, A3, A4, A5, A6, A7, A8,   \
     167                 :             :                         A9, A10, A11);
     168                 :             : #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN)                                  \
     169                 :             :   define_function_type (ENUM, RETURN, 1, 0);
     170                 :             : #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, A1)                              \
     171                 :             :   define_function_type (ENUM, RETURN, 1, 1, A1);
     172                 :             : #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, A1, A2)                          \
     173                 :             :   define_function_type (ENUM, RETURN, 1, 2, A1, A2);
     174                 :             : #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, A1, A2, A3)                      \
     175                 :             :   define_function_type (ENUM, RETURN, 1, 3, A1, A2, A3);
     176                 :             : #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, A1, A2, A3, A4)                  \
     177                 :             :   define_function_type (ENUM, RETURN, 1, 4, A1, A2, A3, A4);
     178                 :             : #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, A1, A2, A3, A4, A5)              \
     179                 :             :   define_function_type (ENUM, RETURN, 1, 5, A1, A2, A3, A4, A5);
     180                 :             : #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, A1, A2, A3, A4, A5, A6)          \
     181                 :             :   define_function_type (ENUM, RETURN, 1, 6, A1, A2, A3, A4, A5, A6);
     182                 :             : #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, A1, A2, A3, A4, A5, A6, A7)      \
     183                 :             :   define_function_type (ENUM, RETURN, 1, 7, A1, A2, A3, A4, A5, A6, A7);
     184                 :             : #define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, A1, A2, A3, A4, A5, A6, A7, A8, \
     185                 :             :                                  A9, A10, A11)                                 \
     186                 :             :   define_function_type (ENUM, RETURN, 1, 11, A1, A2, A3, A4, A5, A6, A7, A8,   \
     187                 :             :                         A9, A10, A11);
     188                 :             : #define DEF_POINTER_TYPE(ENUM, TYPE)                                           \
     189                 :             :   builtin_types[ENUM] = build_pointer_type (builtin_types[TYPE]);
     190                 :             : 
     191                 :             : #include "builtin-types.def"
     192                 :             : 
     193                 :             : #undef DEF_PRIMITIVE_TYPE
     194                 :             : #undef DEF_FUNCTION_TYPE_1
     195                 :             : #undef DEF_FUNCTION_TYPE_2
     196                 :             : #undef DEF_FUNCTION_TYPE_3
     197                 :             : #undef DEF_FUNCTION_TYPE_4
     198                 :             : #undef DEF_FUNCTION_TYPE_5
     199                 :             : #undef DEF_FUNCTION_TYPE_6
     200                 :             : #undef DEF_FUNCTION_TYPE_7
     201                 :             : #undef DEF_FUNCTION_TYPE_8
     202                 :             : #undef DEF_FUNCTION_TYPE_9
     203                 :             : #undef DEF_FUNCTION_TYPE_10
     204                 :             : #undef DEF_FUNCTION_TYPE_11
     205                 :             : #undef DEF_FUNCTION_TYPE_VAR_0
     206                 :             : #undef DEF_FUNCTION_TYPE_VAR_1
     207                 :             : #undef DEF_FUNCTION_TYPE_VAR_2
     208                 :             : #undef DEF_FUNCTION_TYPE_VAR_3
     209                 :             : #undef DEF_FUNCTION_TYPE_VAR_4
     210                 :             : #undef DEF_FUNCTION_TYPE_VAR_5
     211                 :             : #undef DEF_FUNCTION_TYPE_VAR_6
     212                 :             : #undef DEF_FUNCTION_TYPE_VAR_7
     213                 :             : #undef DEF_FUNCTION_TYPE_VAR_11
     214                 :             : #undef DEF_POINTER_TYPE
     215                 :             : 
     216                 :        1028 :   builtin_types[Type::BT_LAST] = NULL_TREE;
     217                 :        1028 : }
     218                 :             : 
     219                 :             : /**
     220                 :             :  * Define all builtin attributes in the `builtin_types` array
     221                 :             :  */
     222                 :             : void
     223                 :        1028 : BuiltinsContext::define_builtin_attributes ()
     224                 :             : 
     225                 :             : {
     226                 :        1028 :   auto *built_in_attributes = builtin_attributes;
     227                 :             : 
     228                 :             : #define DEF_ATTR_NULL_TREE(ENUM) built_in_attributes[(int) ENUM] = NULL_TREE;
     229                 :             : #define DEF_ATTR_INT(ENUM, VALUE)                                              \
     230                 :             :   built_in_attributes[ENUM] = build_int_cst (NULL_TREE, VALUE);
     231                 :             : #define DEF_ATTR_STRING(ENUM, VALUE)                                           \
     232                 :             :   built_in_attributes[ENUM] = build_string (strlen (VALUE), VALUE);
     233                 :             : #define DEF_ATTR_IDENT(ENUM, STRING)                                           \
     234                 :             :   built_in_attributes[ENUM] = get_identifier (STRING);
     235                 :             : #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN)                        \
     236                 :             :   built_in_attributes[ENUM]                                                    \
     237                 :             :     = tree_cons (built_in_attributes[PURPOSE], built_in_attributes[VALUE],     \
     238                 :             :                  built_in_attributes[CHAIN]);
     239                 :             : #include "builtin-attrs.def"
     240                 :             : #undef DEF_ATTR_NULL_TREE
     241                 :             : #undef DEF_ATTR_INT
     242                 :             : #undef DEF_ATTR_STRING
     243                 :             : #undef DEF_ATTR_IDENT
     244                 :             : #undef DEF_ATTR_TREE_LIST
     245                 :        1028 : }
     246                 :             : 
     247                 :             : /**
     248                 :             :  * Define all builtin functions during the first initialization of the
     249                 :             :  * `BuiltinsContext`.
     250                 :             :  */
     251                 :             : void
     252                 :        1028 : BuiltinsContext::define_builtins ()
     253                 :             : {
     254                 :        1028 :   auto *built_in_attributes = builtin_attributes;
     255                 :     1439200 :   auto build_builtin = [this] (built_in_function fn_code, const char *fn_name,
     256                 :             :                                built_in_class fn_class, tree fn_type, bool both,
     257                 :             :                                bool fallback, tree attributes, bool implicit) {
     258                 :     1438172 :     if (fn_type == error_mark_node)
     259                 :     1438172 :       return;
     260                 :             : 
     261                 :     1362100 :     static auto to_skip = strlen ("__builtin_");
     262                 :             : 
     263                 :     1362100 :     auto libname = fn_name + to_skip;
     264                 :     1766104 :     auto decl = add_builtin_function (fn_name, fn_type, fn_code, fn_class,
     265                 :     1362100 :                                       fallback ? libname : NULL, attributes);
     266                 :             : 
     267                 :     1362100 :     set_builtin_decl (fn_code, decl, implicit);
     268                 :             : 
     269                 :     1362100 :     builtin_functions.insert ({std::string (fn_name), decl});
     270                 :        1028 :   };
     271                 :             : 
     272                 :             : #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P,      \
     273                 :             :                     NONANSI_P, ATTRS, IMPLICIT, COND)                          \
     274                 :             :   if (NAME && COND)                                                            \
     275                 :             :     build_builtin (ENUM, NAME, CLASS, builtin_types[TYPE], BOTH_P, FALLBACK_P, \
     276                 :             :                    built_in_attributes[ATTRS], IMPLICIT);
     277                 :             : #include "builtins.def"
     278                 :             : #undef DEF_BUILTIN
     279                 :        1028 : }
     280                 :             : 
     281                 :             : /**
     282                 :             :  * Register direct mappings between Rust functions and GCC builtins
     283                 :             :  */
     284                 :             : void
     285                 :        1028 : BuiltinsContext::register_rust_mappings ()
     286                 :             : {
     287                 :       47288 :   rust_intrinsic_to_gcc_builtin = {
     288                 :             :     {"unreachable", "__builtin_unreachable"},
     289                 :             :     {"abort", "__builtin_abort"},
     290                 :             : 
     291                 :             :     // Math intrinsics
     292                 :             :     {"sqrtf32", "__builtin_sqrtf"},
     293                 :             :     {"sqrtf64", "__builtin_sqrt"},
     294                 :             : 
     295                 :             :     {"sinf32", "__builtin_sinf"},
     296                 :             :     {"sinf64", "__builtin_sin"},
     297                 :             : 
     298                 :             :     {"cosf32", "__builtin_cosf"},
     299                 :             :     {"cosf64", "__builtin_cos"},
     300                 :             : 
     301                 :             :     {"powf32", "__builtin_powf"},
     302                 :             :     {"powf64", "__builtin_pow"},
     303                 :             : 
     304                 :             :     {"powif32", "__builtin_powif"},
     305                 :             :     {"powif64", "__builtin_powi"},
     306                 :             : 
     307                 :             :     {"expf32", "__builtin_expf"},
     308                 :             :     {"expf64", "__builtin_exp"},
     309                 :             : 
     310                 :             :     {"exp2f32", "__builtin_exp2f"},
     311                 :             :     {"exp2f64", "__builtin_exp2"},
     312                 :             : 
     313                 :             :     {"logf32", "__builtin_logf"},
     314                 :             :     {"logf64", "__builtin_log"},
     315                 :             : 
     316                 :             :     {"log10f32", "__builtin_log10f"},
     317                 :             :     {"log10f64", "__builtin_log10"},
     318                 :             : 
     319                 :             :     {"log2f32", "__builtin_log2f"},
     320                 :             :     {"log2f64", "__builtin_log2"},
     321                 :             : 
     322                 :             :     {"fmaf32", "__builtin_fmaf"},
     323                 :             :     {"fmaf64", "__builtin_fma"},
     324                 :             : 
     325                 :             :     {"fabsf32", "__builtin_fabsf"},
     326                 :             :     {"fabsf64", "__builtin_fabs"},
     327                 :             : 
     328                 :             :     {"minnumf32", "__builtin_fminf"},
     329                 :             :     {"minnumf64", "__builtin_fmin"},
     330                 :             : 
     331                 :             :     {"maxnumf32", "__builtin_fmaxf"},
     332                 :             :     {"maxnumf64", "__builtin_fmax"},
     333                 :             : 
     334                 :             :     {"copysignf32", "__builtin_copysignf"},
     335                 :             :     {"copysignf64", "__builtin_copysign"},
     336                 :             : 
     337                 :             :     {"floorf32", "__builtin_floorf"},
     338                 :             :     {"floorf64", "__builtin_floor"},
     339                 :             : 
     340                 :             :     {"ceilf32", "__builtin_ceilf"},
     341                 :             :     {"ceilf64", "__builtin_ceil"},
     342                 :             : 
     343                 :             :     {"truncf32", "__builtin_truncf"},
     344                 :             :     {"truncf64", "__builtin_trunc"},
     345                 :             : 
     346                 :             :     {"rintf32", "__builtin_rintf"},
     347                 :             :     {"rintf64", "__builtin_rint"},
     348                 :             : 
     349                 :             :     {"nearbyintf32", "__builtin_nearbyintf"},
     350                 :             :     {"nearbyintf64", "__builtin_nearbyint"},
     351                 :             : 
     352                 :             :     {"roundf32", "__builtin_roundf"},
     353                 :             :     {"roundf64", "__builtin_round"},
     354                 :       91492 :   };
     355                 :        1028 : }
     356                 :             : 
     357                 :             : void
     358                 :        1028 : BuiltinsContext::setup ()
     359                 :             : {
     360                 :        1028 :   define_builtin_types ();
     361                 :        1028 :   define_builtin_attributes ();
     362                 :        1028 :   define_builtins ();
     363                 :             : 
     364                 :        1028 :   register_rust_mappings ();
     365                 :        1028 : }
     366                 :             : 
     367                 :             : bool
     368                 :        6119 : BuiltinsContext::lookup_gcc_builtin (const std::string &name, tree *builtin)
     369                 :             : {
     370                 :        6119 :   auto it = builtin_functions.find (name);
     371                 :        6119 :   if (it == builtin_functions.end ())
     372                 :             :     return false;
     373                 :             : 
     374                 :        4438 :   *builtin = it->second;
     375                 :        4438 :   return true;
     376                 :             : }
     377                 :             : 
     378                 :             : } // namespace Compile
     379                 :             : } // namespace Rust
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.