X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fvarasm.c;h=83f47ac486e8c32d29af0b3e1f7b065fecbab3e4;hb=cc9012f7c74cf3452cdb1b6cde3cf6455e889cd3;hp=e4d30974ddc9eb3230d4332f4cb112dada22dd4f;hpb=c75b4594282e6b33803b8332acba704d057f8d97;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/varasm.c b/gcc/varasm.c index e4d30974ddc..83f47ac486e 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -60,6 +60,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #endif /* The (assembler) name of the first globally-visible object output. */ +extern GTY(()) const char *first_global_object_name; +extern GTY(()) const char *weak_global_object_name; + const char *first_global_object_name; const char *weak_global_object_name; @@ -841,7 +844,8 @@ decode_reg_name (const char *asmspec) = ADDITIONAL_REGISTER_NAMES; for (i = 0; i < (int) ARRAY_SIZE (table); i++) - if (! strcmp (asmspec, table[i].name)) + if (table[i].name[0] + && ! strcmp (asmspec, table[i].name)) return table[i].number; } #endif /* ADDITIONAL_REGISTER_NAMES */ @@ -919,10 +923,16 @@ make_decl_rtl (tree decl) } name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - - if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl)) + + if (name[0] != '*' && TREE_CODE (decl) != FUNCTION_DECL + && DECL_REGISTER (decl)) + { + error ("register name not specified for %q+D", decl); + } + else if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl)) { - reg_number = decode_reg_name (name); + const char *asmspec = name+1; + reg_number = decode_reg_name (asmspec); /* First detect errors in declaring global registers. */ if (reg_number == -1) error ("register name not specified for %q+D", decl); @@ -1207,11 +1217,11 @@ notice_global_symbol (tree decl) if (!*type) { const char *p; - char *name; + const char *name; rtx decl_rtl = DECL_RTL (decl); p = targetm.strip_name_encoding (XSTR (XEXP (decl_rtl, 0), 0)); - name = xstrdup (p); + name = ggc_strdup (p); *type = name; } @@ -1271,11 +1281,13 @@ assemble_start_function (tree decl, const char *fnname) unlikely_text_section (); assemble_align (FUNCTION_BOUNDARY); ASM_OUTPUT_LABEL (asm_out_file, cfun->cold_section_label); - if (BB_PARTITION (ENTRY_BLOCK_PTR->next_bb) == BB_COLD_PARTITION) + + /* When the function starts with a cold section, we need to explicitly + align the hot section and write out the hot section label. + But if the current function is a thunk, we do not have a CFG. */ + if (!current_function_is_thunk + && BB_PARTITION (ENTRY_BLOCK_PTR->next_bb) == BB_COLD_PARTITION) { - /* Since the function starts with a cold section, we need to - explicitly align the hot section and write out the hot - section label. */ text_section (); assemble_align (FUNCTION_BOUNDARY); ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label); @@ -1357,8 +1369,6 @@ assemble_start_function (tree decl, const char *fnname) /* Standard thing is just output label for the function. */ ASM_OUTPUT_LABEL (asm_out_file, fnname); #endif /* ASM_DECLARE_FUNCTION_NAME */ - - insert_section_boundary_note (); } /* Output assembler code associated with defining the size of the @@ -1368,6 +1378,9 @@ void assemble_end_function (tree decl, const char *fnname) { #ifdef ASM_DECLARE_FUNCTION_SIZE + /* We could have switched section in the middle of the function. */ + if (flag_reorder_blocks_and_partition) + function_section (decl); ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl); #endif if (! CONSTANT_POOL_BEFORE_FUNCTION) @@ -3628,7 +3641,7 @@ initializer_constant_valid_p (tree value, tree endtype) if (value && TREE_CODE (value) == FUNCTION_DECL && ((decl_function_context (value) && !DECL_NO_STATIC_CHAIN (value)) - || DECL_NON_ADDR_CONST_P (value))) + || DECL_DLLIMPORT_P (value))) return NULL_TREE; return value; @@ -3838,12 +3851,50 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align) if (size == 0 || flag_syntax_only) return; + /* See if we're trying to initialize a pointer in a non-default mode + to the address of some declaration somewhere. If the target says + the mode is valid for pointers, assume the target has a way of + resolving it. */ + if (TREE_CODE (exp) == NOP_EXPR + && POINTER_TYPE_P (TREE_TYPE (exp)) + && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp)))) + { + tree saved_type = TREE_TYPE (exp); + + /* Peel off any intermediate conversions-to-pointer for valid + pointer modes. */ + while (TREE_CODE (exp) == NOP_EXPR + && POINTER_TYPE_P (TREE_TYPE (exp)) + && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp)))) + exp = TREE_OPERAND (exp, 0); + + /* If what we're left with is the address of something, we can + convert the address to the final type and output it that + way. */ + if (TREE_CODE (exp) == ADDR_EXPR) + exp = build1 (ADDR_EXPR, saved_type, TREE_OPERAND (exp, 0)); + } + /* Eliminate any conversions since we'll be outputting the underlying constant. */ while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR || TREE_CODE (exp) == NON_LVALUE_EXPR || TREE_CODE (exp) == VIEW_CONVERT_EXPR) - exp = TREE_OPERAND (exp, 0); + { + HOST_WIDE_INT type_size = int_size_in_bytes (TREE_TYPE (exp)); + HOST_WIDE_INT op_size = int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp, 0))); + + /* Make sure eliminating the conversion is really a no-op, except with + VIEW_CONVERT_EXPRs to allow for wild Ada unchecked conversions and + union types to allow for Ada unchecked unions. */ + if (type_size > op_size + && TREE_CODE (exp) != VIEW_CONVERT_EXPR + && TREE_CODE (TREE_TYPE (exp)) != UNION_TYPE) + internal_error ("no-op convert from %wd to %wd bytes in initializer", + op_size, type_size); + + exp = TREE_OPERAND (exp, 0); + } code = TREE_CODE (TREE_TYPE (exp)); thissize = int_size_in_bytes (TREE_TYPE (exp)); @@ -4507,27 +4558,28 @@ find_decl_and_mark_needed (tree decl, tree target) struct cgraph_node *fnode = NULL; struct cgraph_varpool_node *vnode = NULL; - /* C++ thunk emitting code produces aliases late in the game. - Avoid confusing cgraph code in that case. */ - if (!cgraph_global_info_ready) + if (TREE_CODE (decl) == FUNCTION_DECL) { - if (TREE_CODE (decl) == FUNCTION_DECL) - { - fnode = cgraph_node_for_asm (target); - if (fnode == NULL) - vnode = cgraph_varpool_node_for_asm (target); - } - else - { - vnode = cgraph_varpool_node_for_asm (target); - if (vnode == NULL) - fnode = cgraph_node_for_asm (target); - } + fnode = cgraph_node_for_asm (target); + if (fnode == NULL) + vnode = cgraph_varpool_node_for_asm (target); + } + else + { + vnode = cgraph_varpool_node_for_asm (target); + if (vnode == NULL) + fnode = cgraph_node_for_asm (target); } if (fnode) { - cgraph_mark_needed_node (fnode); + /* We can't mark function nodes as used after cgraph global info + is finished. This wouldn't generally be necessary, but C++ + virtual table thunks are introduced late in the game and + might seem like they need marking, although in fact they + don't. */ + if (! cgraph_global_info_ready) + cgraph_mark_needed_node (fnode); return fnode->decl; } else if (vnode) @@ -5009,47 +5061,7 @@ default_select_section (tree decl, int reloc, data_section (); } -/* A helper function for default_elf_select_section and - default_elf_unique_section. Categorizes the DECL. */ - enum section_category -{ - SECCAT_TEXT, - - SECCAT_RODATA, - SECCAT_RODATA_MERGE_STR, - SECCAT_RODATA_MERGE_STR_INIT, - SECCAT_RODATA_MERGE_CONST, - SECCAT_SRODATA, - - SECCAT_DATA, - - /* To optimize loading of shared programs, define following subsections - of data section: - _REL Contains data that has relocations, so they get grouped - together and dynamic linker will visit fewer pages in memory. - _RO Contains data that is otherwise read-only. This is useful - with prelinking as most relocations won't be dynamically - linked and thus stay read only. - _LOCAL Marks data containing relocations only to local objects. - These relocations will get fully resolved by prelinking. */ - SECCAT_DATA_REL, - SECCAT_DATA_REL_LOCAL, - SECCAT_DATA_REL_RO, - SECCAT_DATA_REL_RO_LOCAL, - - SECCAT_SDATA, - SECCAT_TDATA, - - SECCAT_BSS, - SECCAT_SBSS, - SECCAT_TBSS -}; - -static enum section_category -categorize_decl_for_section (tree, int, int); - -static enum section_category categorize_decl_for_section (tree decl, int reloc, int shlib) { enum section_category ret;