Studying note of GCC-3.4.6 source (59)

4.3.1.7.5.6.      Create nodes of builtin functions

4.3.1.7.5.6.1.              Overview

Now it is time to build node of builtin functions. Similarly, we need define a macro to generate the code from a defining file – builtins.def this time.

 

c_common_nodes_and_builtins (continue)

 

3431   #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE,                   /

3432                   BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT)    /

3433     if (NAME)                                                       /

3434     {                                                              /

3435       tree decl;                                                /

3436                                                                /

3437       if (strncmp (NAME, "__builtin_", strlen ("__builtin_")) != 0) /

3438         abort ();                                             /

3439                                                                /

3440       if (!BOTH_P)                                                /

3441         decl = builtin_function (NAME, builtin_types[TYPE], ENUM,  /

3442                            CLASS,                                 /

3443                            (FALLBACK_P                      /

3444                               ? (NAME + strlen ("__builtin_"))      /

3445                               : NULL),                          /

3446                            built_in_attributes[(int) ATTRS]);    /

3447       else                                                       /

3448         decl = builtin_function_2 (NAME,                      /

3449                              NAME + strlen ("__builtin_"),    /

3450                              builtin_types[TYPE],                  /

3451                              builtin_types[LIBTYPE],            /

3452                              ENUM,                       /

3453                              CLASS,                       /

3454                              FALLBACK_P,                          /

3455                              NONANSI_P,                            /

3456                              built_in_attributes[(int) ATTRS]);       /

3457                                                                /

3458       built_in_decls[(int) ENUM] = decl;                        /

3459       if (IMPLICIT)                                               /

3460         implicit_built_in_decls[(int) ENUM] = decl;               /

3461     }

3462   #include "builtins.def"

3463   #undef DEF_BUILTIN

3464  

3465     (*targetm.init_builtins) ();

3466  

3467     main_identifier_node = get_identifier ("main");

3468   }

 

This macro will be called once for each builtin function. The ENUM will be of type enum built_in_function, and will indicate which builtin function is being processed. The NAME of the builtin function (which will always start with __builtin_) is a string literal. The CLASS is of type enum built_in_class and indicates what kind of builtin is being processed.

Some builtins are actually two separate functions. For example, for strcmp there are two builtin functions; __builtin_strcmp and strcmp itself. Both behave identically. Other builtins define only the __builtin variant. If BOTH_P is TRUE, then this builtin has both variants; otherwise, it is has only the first variant.

TYPE indicates the type of the function. The symbols correspond to enumerals from builtin-types.def. If BOTH_P is true, then LIBTYPE is the type of the non-__builtin_ variant. Otherwise, LIBTYPE should be ignored.

If FALLBACK_P is true then, if for some reason, the compiler cannot expand the builtin function directly, it will call the corresponding library function (which does not have the __builtin_ prefix).

If NONANSI_P is true, then the non-__builtin_ variant is not an ANSI/ISO library function, and so we should pretend it does not exist when compiling in ANSI conformant mode.

ATTRs is an attribute list as defined in builtin-attrs.def that describes the attributes of this builtin function.

IMPLICIT specifies condition when the builtin can be produced by compiler. For instance C90 reserves floorf function, but does not define it's meaning. When user uses floorf we may assume that the floorf has the meaning we expect, but we can't produce floorf by simplifying floor((double)float) since the runtime need not implement it.

To see clearly the producing procedure, we just takes following builtin function as example.

 

484    DEF_LIB_BUILTIN (BUILT_IN_VPRINTF, "vprintf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_1_0)

 

80      #define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS)       /

81        DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, /

82                  true, true, false, ATTRS, true)

 

To make the expansion possible, we still need two more maros. One used to define an enumerator for the builtin functions.

 

90      #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM) ENUM,             in tree.h

91      enum built_in_function

92      {

93      #include "builtins.def"

94     

95        /* Upper bound on non-language-specific builtins.  */

96        END_BUILTINS

97      };

98      #undef DEF_BUILTIN

 

The other is used to generate the string literal as the name for the functions.

 

63      /* Define the names of the builtin function types and codes.  */                   in builtins.c

64      const char *const built_in_class_names[4]

65        = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};

66     

67      #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,

68      const char *const built_in_names[(int) END_BUILTINS] =

69      {

70      #include "builtins.def"

71      };

72      #undef DEF_BUILTIN

4.3.1.7.5.6.2.              Create FUNCTION_DECL

Builtin function vprintf’s BOTH_P is true, indicating it has two variants, one is builtin, the other is a standard library function (strictly speaking, it is the intermeidate form declaration, which is linked to library function vprintf). Thus this builtin needs builtin_function_2 to generate these 2 variants. Besides, vprintf’s IMPLICIT is true, then the generated __builtin version would be set into implicit_built_in_decls, which is the function set supported by the runtime. In fact, in builtin.def, builtin functions are divided into following groups:

 

69      #define DEF_GCC_BUILTIN(ENUM, NAME, TYPE, ATTRS)             /

70        DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, BT_LAST,       /

71                     false, false, false, ATTRS, true)

 

A GCC builtin (like __builtin_saveregs) is provided by the compiler, but does not correspond to a function in the standard library.

And DEF_LIB_BUILTIN in above example is a builtin equivalent of an ANSI/ISO standard library function (like __builtin_strchr). In addition to the `__builtin' version, we will create an ordinary version (e.g, `strchr') as well. If we cannot compute the answer using the builtin function, we will fall back to the standard library version.

 

89      #define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS)      /

90        DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,      /

91                      true, true, true, ATTRS, false)

 

Like DEF_LIB_BUILTIN, except that the function is not one that is specified by ANSI/ISO C.  So, when we're being fully conformant we ignore the version of these builtins that does not begin with __builtin.

 

96      #define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS)       /

97        DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,      /

98                      true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS)

 

Like DEF_LIB_BUILTIN, except that the function is only a part of the standard in C99 or above.

 

104    #define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS)       /

105     DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,      /

106                    true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS)

 

Builtin that is specified by C99 and C90 reserve the name for future use. We can still recognize the builtin in C90 mode but we can't produce it implicitly.

From these macros, we can see clearly that implicit_built_in_decls will include builtins generated by DEF_GCC_BUILTIN DEF_LIB_BUILTIN, DEF_C99_C90RES_BUILTIN, DEF_C99_BUILTIN (the rear two are at time of running C99 compiler).

For builtin vprintf, in its call to builtin_function_2, value for the parameters are:

builtin_name      - “__builtin_vprintf”

name                  - “vprintf”

builtin_type         - builtin_types [BT_FN_INT_CONST_STRING_VALIST_ARG]

type                    - builtin_types [BT_FN_INT_CONST_STRING_VALIST_ARG]

function_code      - BUILT_IN_VPRINTF

class                   - BUILT_IN_NORMAL

library_name_p   - true

nonansi_p           - false

attrs                    - built_in_attributes [ATTR_FORMAT_PRINTF_1_0]

 

3537   static tree

3538   builtin_function_2 (const char *builtin_name, const char *name,          in c-common.c

3539                   tree builtin_type, tree type, int function_code,

3540                   enum built_in_class class, int library_name_p,

3541                   int nonansi_p, tree attrs)

3542   {

3543     tree bdecl = NULL_TREE;

3544     tree decl = NULL_TREE;

3545  

3546     if (builtin_name != 0)

3547       bdecl = builtin_function (builtin_name, builtin_type, function_code,

3548                            class, library_name_p ? name : NULL, attrs);

3549  

3550     if (name != 0 && !flag_no_builtin && !builtin_function_disabled_p (name)

3551         && !(nonansi_p && flag_no_nonansi_builtin))

3552       decl = builtin_function (name, type, function_code, class, NULL, attrs);

3553  

3554     return (bdecl != 0 ? bdecl : decl);

3555   }

 

Using option -fno-builtin can prohibit generating builtin for standard library functions (flag_no_builtin is nonzero). Further, option -fno-builtin-XXX bans builtin of specified standard library function (builtin_function_disabled_p identifies if the specified builtin is banned). Below using __builtin version as example, in call of builtin_funciton, value for the parameters are:

name    - “__builtin_vprintf”

type      - builtin_types [BT_FN_INT_CONST_STRING_VALIST_ARG]

code     - BUILT_IN_VPRINTF

class     - BUILT_IN_NORMAL

libname       - “vprintf”

attrs      - built_in_attributes [ATTR_FORMAT_PRINTF_1_0]

 

3278   tree

3279   builtin_function (const char* name,                                                                 in decl.c

3280                     tree type,

3281                     int code,

3282                     enum built_in_class class,

3283                     const char* libname,

3284                     tree attrs)

3285   {

3286     /* All builtins that don't begin with an '_' should additionally

3287       go in the 'std' namespace.  */

3288     if (name[0] != '_')

3289     {

3290       push_namespace (std_identifier);

3291       builtin_function_1 (name, type, std_node, code, class, libname, attrs);

3292       pop_namespace ();

3293     }

3294  

3295     return builtin_function_1 (name, type, NULL_TREE, code,

3296                           class, libname, attrs);

3297   }

 

Note, for builtin of of standard library function, as the library function is within std namespace, we should make the declaration within the namespace. Continue with builtin of __builtin version, in call of builtin_function_1, the arguments are:

name    - “__builtin_vprintf”

type      - builtin_types [BT_FN_INT_CONST_STRING_VALIST_ARG]

context - NULL_TREE

code     - BUILT_IN_VPRINTF

class     - BUILT_IN_NORMAL

libname       - “vprinft”

attrs      - built_in_attributes [ATTR_FORMAT_PRINTF_1_0]

Notice that context is NULL – the declaration is just inside global namespace.

 

3225   static tree

3226   builtin_function_1 (const char* name,                                                              in decl.c

3227                       tree type,

3228                       tree context,

3229                       int code,

3230                       enum built_in_class class,

3231                       const char* libname,

3232                       tree attrs)

3233   {

3234     tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type);

3235     DECL_BUILT_IN_CLASS (decl) = class;

3236     DECL_FUNCTION_CODE (decl) = code;

3237     DECL_CONTEXT (decl) = context;

 

builtin_function_1 first invokes build_library_fn_1 to create FUNCTION_DECL. Notice that operator_code is ERROR_MARK which is set to SET_OVERLOADED_OPERATOR_CODE to indicate the function is not overloaded operator.

 

3302   static tree

3303   build_library_fn_1 (tree name, enum tree_code operator_code, tree type)            in decl.c

3304   {

3305     tree fn = build_lang_decl (FUNCTION_DECL, name, type);

3306     DECL_EXTERNAL (fn) = 1;

3307     TREE_PUBLIC (fn) = 1;

3308     DECL_ARTIFICIAL (fn) = 1;

3309     TREE_NOTHROW (fn) = 1;

3310     SET_OVERLOADED_OPERATOR_CODE (fn, operator_code);

3311     SET_DECL_LANGUAGE (fn, lang_c);

3312     return fn;

3313   }

 

Above at line 3308, DECL_ARTIFICIAL is set as 1 which means this DECL represents a “compiler-artificial” entity. And set TREE_NOTHROW to indicate a call to the function cannot throw an exception.

4.3.1.7.5.6.3.              Push the FUNCTION_DECL Into current namespace

Next add the created FUNCTION_DECL into current namespace to be effective.

 

builtin_function_1 (continue)

 

3293     pushdecl (decl);

 

566    tree

567    pushdecl (tree x)                                                                               in name-lookup.c

568    {

569      tree t;

570      tree name;

571      int need_new_binding;

572   

573      timevar_push (TV_NAME_LOOKUP);

574   

575      need_new_binding = 1;

        ...

604      name = DECL_NAME (x);

605      if (name)

606      {

607        int different_binding_level = 0;

608   

609        if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))

610          check_default_args (x);

611    

612        if (TREE_CODE (name) == TEMPLATE_ID_EXPR)

613          name = TREE_OPERAND (name, 0);

614   

615        /* In case this decl was explicitly namespace-qualified, look it

616          up in its namespace context.  */

617        if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())

618          t = namespace_binding (name, DECL_CONTEXT (x));

619        else

620          t = lookup_name_current_level (name);

 

Required by C/C++, when appointing a parameter with default value, those parameters following should also be provided with the default values. Otherwise, an error should be issued. For this, check_default_args checks if the declaration is valid.

 

2948   void

2949   check_default_args (tree x)                                                                      in decl2.c

2950   {

2951     tree arg = TYPE_ARG_TYPES (TREE_TYPE (x));

2952     bool saw_def = false;

2953     int i = 0 - (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE);

2954     for (; arg && arg != void_list_node; arg = TREE_CHAIN (arg), ++i)

2955     {

2956       if (TREE_PURPOSE (arg))

2957         saw_def = true;

2958       else if (saw_def)

2959       {

2960         cp_error_at ("default argument missing for parameter %P of `%+#D'",

2961                   i, x);

2962         TREE_PURPOSE (arg) = error_mark_node;

2963       }

2964     }

2965   }

 

In FUNCTION_DECL node, macro TREE_TYPE gives the return type of the function, and TYPE_ARG_TYPES is a TREE_LIST of the argument types. The TREE_VALUE of each node in this list is the type of the corresponding argument; the TREE_PURPOSE is an expression for the default argument value, if any. If the last node in the list is void_list_node (a TREE_LIST node whose TREE_VALUE is the void_type_node), then functions of this type do not take variable arguments. Otherwise, they do take a variable number of arguments.

 

pushdecl (continue)

 

753        if (DECL_NON_THUNK_FUNCTION_P(x) && !DECL_FUNCTION_MEMBER_P(x))

754        {

755          t = push_overloaded_decl (x, PUSH_LOCAL);

756          if (t != x)

757            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);

758          if (!namespace_bindings_p ())

759            /* We do not need to create a binding for this name;

760              push_overloaded_decl will have already done so if

761              necessary.  */

762            need_new_binding = 0;

763        }

 

At line 753, the function should not be a thunk or a member function of class. And parameter flags in calling push_overloaded_decl is PUSH_LOCAL which means to bind decl in the current scope, rather than at namespace scope.

 

1986   static tree

1987   push_overloaded_decl (tree decl, int flags)                                          in name-lookup.c

1988   {

1989     tree name = DECL_NAME (decl);

1990     tree old;

1991     tree new_binding;

1992     int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));

1993  

1994     timevar_push (TV_NAME_LOOKUP);

1995     if (doing_global)

1996       old = namespace_binding (name, DECL_CONTEXT (decl));

1997     else

1998       old = lookup_name_current_level (name);

1999  

2000     if (old)

2001     {

          ...

2040     }

2041  

2042     if (old || TREE_CODE (decl) == TEMPLATE_DECL

2043        /* If it's a using declaration, we always need to build an OVERLOAD,

2044           because it's the only way to remember that the declaration comes

2045            from 'using', and have the lookup behave correctly.  */

2046         || (flags & PUSH_USING))

2047     {

          ...

2054     }

2055     else

2056       /* NAME is not ambiguous.  */

2057       new_binding = decl;

2058  

2059     if (doing_global)

2060       set_namespace_binding (name, current_namespace, new_binding);

2061     else

2062     {

          ...

2099     }

2100  

2101     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);

2102   }

 

Now we are just inside a namespace (the global), doing_global at line 1992 is set as 1 even though flags is PUSH_LOCAL. And for builtin functions, the same identifier should not be found in the namespace.

As set_namespace_binding adds the binding scope into the node of identifier, but still not adding the declaration into the scope, need_new_binding stays 1. Then the last part of pushdecl executed adds the declaration into the name list maintained by the scope.

 

pushdecl (continue)

 

1009   if (need_new_binding)

1010       add_decl_to_level (x,

1011                      DECL_NAMESPACE_SCOPE_P (x)

1012                      ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))

1013                      : current_binding_level);

1014  

1015     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);

1016   }

4.3.1.7.5.6.4.              Create RTX object for builtin

Unlike user-defined function, the compiler knows everything about the builtin. And in later program parsing, for every builtin call, the compiler will expand it by replacing with code snippet in intermediate form (at this time, builtin works more like macro). As we have known, for builtin having library function version, when the expanded code can’t cope, the compiler will call the library function – that is constructing a call, which we can directly build it with RTL. So we only need to hand it to the back-end to generate the assemble.

 

builtin_function_1 (continue)

 

3241     /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,

3242       we cannot change DECL_ASSEMBLER_NAME until we have installed this

3243       function in the namespace.  */

3244     if (libname)

3245       SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname));

3246     make_decl_rtl (decl, NULL);

3247  

3248    /* Warn if a function in the namespace for users

3249       is used without an occasion to consider it declared.  */

3250     if (name[0] != '_' || name[1] != '_')

3251       DECL_ANTICIPATED (decl) = 1;

 

Note, for builtin of library function version, libname at line 3244 is NULL, so code at line 3245 will be skipped. Then as result, in below, though object SYMBOL_REF still will be created, but its name is NULL, the back-end will not generate call instruction for it. And for the __builtin version, libname is the name of the corresponding library function, and in our case, it is “vprintf”.

 

736    void

737    make_decl_rtl (tree decl, const char *asmspec)                                                  in varasm.c

738    {

739      const char *name = 0;

740      int reg_number;

741      rtx x;

742   

743     /* Check that we are not being given an automatic variable.  */

744      /* A weak alias has TREE_PUBLIC set but not the other bits.  */

745      if (TREE_CODE (decl) == PARM_DECL

746          || TREE_CODE (decl) == RESULT_DECL

747          || (TREE_CODE (decl) == VAR_DECL

748           && !TREE_STATIC (decl)

749           && !TREE_PUBLIC (decl)

750           && !DECL_EXTERNAL (decl)

751           && !DECL_REGISTER (decl)))

752        abort ();

753     /* And that we were not given a type or a label.  */

754      else if (TREE_CODE (decl) == TYPE_DECL

755            || TREE_CODE (decl) == LABEL_DECL)

756        abort ();

757   

758      /* For a duplicate declaration, we can be called twice on the

759        same DECL node. Don't discard the RTL already made.  */

760      if (DECL_RTL_SET_P (decl))

761      {

          ...

777      }

778   

779      reg_number = decode_reg_name (asmspec);

780      if (reg_number == -2)

781      {

          ...

788      }

789   

790      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));

791   

792      if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))

793      {

          ...

842      }

        ...

862      x = gen_rtx_SYMBOL_REF (Pmode, name);

863      SYMBOL_REF_WEAK (x) = DECL_WEAK (decl);

864      SYMBOL_REF_DECL (x) = decl;

865   

866      x = gen_rtx_MEM (DECL_MODE (decl), x);

867      if (TREE_CODE (decl) != FUNCTION_DECL)

868        set_mem_attributes (x, decl, 1);

869      SET_DECL_RTL (decl, x);

870   

871     /* Optionally set flags or add text to the name to record information

872        such as that it is a function name.

873        If the name is changed, the macro ASM_OUTPUT_LABELREF

874        will have to know how to strip this information.  */

875      (* targetm.encode_section_info) (decl, DECL_RTL (decl), true);

876    }

 

In make_decl_rtx, the parameter asmspec, if not 0, is the string which the user specified as the assembler symbol name. With asmspec of NULL, at line 779, decode_reg_name does nothing but returns -1. Then at line 790, DECL_ASSEMBLER_NAME accesses assembler_name field of declaration node which is an identifier the assembler will see. Then name points to its name (in C++, mangled names are given to assembler). Next at line 862, constructing a reference for this name (SYMBOL_REF), line 866 builds its memory descriptor (MEM).

d

Figure 38: rtx objects of __builtin _vprintf

Target dependent function encode_section_info determines the attribute of the declaration, then the complier later can decide the sections needed and in which section to put in the declaration.

 

5154   void

5155   default_encode_section_info(tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)    in varasm.c

5156   {

5157     rtx symbol;

5158     int flags;

5159  

5160     /* Careful not to prod global register variables.  */

5161     if (GET_CODE (rtl) != MEM)

5162       return;

5163     symbol = XEXP (rtl, 0);

5164     if (GET_CODE (symbol) != SYMBOL_REF)

5165       return;

5166  

5167     flags = 0;

5168     if (TREE_CODE (decl) == FUNCTION_DECL)

5169       flags |= SYMBOL_FLAG_FUNCTION;

5170     if ((*targetm.binds_local_p) (decl))

5171       flags |= SYMBOL_FLAG_LOCAL;

5172     if ((*targetm.in_small_data_p) (decl))

5173       flags |= SYMBOL_FLAG_SMALL;

5174     if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))

5175       flags |= decl_tls_model (decl) << SYMBOL_FLAG_TLS_SHIFT;

5176     /* ??? Why is DECL_EXTERNAL ever set for non-PUBLIC names? Without

5177       being PUBLIC, the thing *must* be defined in this translation unit.

5178       Prevent this buglet from being propagated into rtl code as well.  */

5179     if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))

5180       flags |= SYMBOL_FLAG_EXTERNAL;

5181  

5182     SYMBOL_REF_FLAGS (symbol) = flags;

5183   }

 

In above function, binds_local_p is not target dependent indeed. In fact, whether a symbol is local or not is determined by the characterisitics of the language but not target.

 

5197   bool

5198   default_binds_local_p (tree exp)                                                                in varasm.c

5199   {

5200     return default_binds_local_p_1 (exp, flag_shlib);

5201   }

 

Pay attention to the order of conditions in below function. At line 5215, if a symbol hasn’t visibility of VISIBILITY_DEFAULT, it should be either VISIBILITY_INTERNAL, or VISIBILITY_HIDDEN, or VISIBILITY_PROTECTED (set by “visibility” attribute, the default value is VISIBILITY_DEFAULT).

 

5203   bool

5204   default_binds_local_p_1 (tree exp, int shlib)                                               in varasm.c

5205   {

5206     bool local_p;

5207  

5208     /* A non-decl is an entry in the constant pool.  */

5209     if (!DECL_P (exp))

5210       local_p = true;

5211     /* Static variables are always local.  */

5212     else if (! TREE_PUBLIC (exp))

5213       local_p = true;

5214    /* A variable is local if the user tells us so.  */

5215     else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)

5216       local_p = true;

5217     /* Otherwise, variables defined outside this object may not be local.  */

5218     else if (DECL_EXTERNAL (exp))

5219       local_p = false;

5220     /* Linkonce and weak data are never local.  */

5221     else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp))

5222       local_p = false;

5223     /* If PIC, then assume that any global name can be overridden by

5224       symbols resolved from other modules.  */

5225     else if (shlib)

5226       local_p = false;

5227     /* Uninitialized COMMON variable may be unified with symbols

5228       resolved from other modules.  */

5229     else if (DECL_COMMON (exp)

5230           && (DECL_INITIAL (exp) == NULL

5231               || DECL_INITIAL (exp) == error_mark_node))

5232       local_p = false;

5233     /* Otherwise we're left with initialized (or non-common) global data

5234       which is of necessity defined locally.  */

5235     else

5236       local_p = true;

5237  

5238     return local_p;

5239   }

 

In default_encode_section_info, at line 5172, the hook in_small_data_p returns true if decl should be placed into a "small data" section. for x86 machine, the target always returns false as default. This function should be defined for certain RISC machine, such as MIPS, which dues to the limited length of instruction, and the bald addressing mode, only quite small range memory can be accessed by offset from certain address in one instruction. For addresses spaned too far, two intructions are needed per accessment. To tell out this situation, can lead compiler to generate more efficient code.

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值