Deleted Added
full compact
70a71,72
> #include "profile.h"
> #include "cfglayout.h"
100a103,108
> #if defined(READONLY_DATA_SECTION) || defined(READONLY_DATA_SECTION_ASM_OP)
> #define HAVE_READONLY_DATA_SECTION 1
> #else
> #define HAVE_READONLY_DATA_SECTION 0
> #endif
>
117,119d124
< /* Number of instrumented arcs when profile_arc_flag is set. */
< extern int count_instrumented_edges;
<
125c130
< static rtx this_is_asm_operands;
---
> rtx this_is_asm_operands;
200a206,216
> struct function_list
> {
> struct function_list *next; /* next function */
> const char *name; /* function name */
> long cfg_checksum; /* function checksum */
> long count_edges; /* number of intrumented edges in this function */
> };
>
> static struct function_list *functions_head = 0;
> static struct function_list **functions_tail = &functions_head;
>
208a225
> static void output_alternate_entry_point PARAMS ((FILE *, rtx));
240c257
< to output the block-profiling table for this entire compilation. */
---
> to output the arc-profiling table for this entire compilation. */
246c263
< if (profile_arc_flag)
---
> if (profile_arc_flag && profile_info.count_instrumented_edges)
249,254c266,269
< int align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
< int size, rounded;
< int long_bytes = LONG_TYPE_SIZE / BITS_PER_UNIT;
< int gcov_type_bytes = GCOV_TYPE_SIZE / BITS_PER_UNIT;
< int pointer_bytes = POINTER_SIZE / BITS_PER_UNIT;
< unsigned int align2 = LONG_TYPE_SIZE;
---
> tree string_type, string_cst;
> tree structure_decl, structure_value, structure_pointer_type;
> tree field_decl, decl_chain, value_chain;
> tree sizeof_field_value, domain_type;
256,257c271,272
< size = gcov_type_bytes * count_instrumented_edges;
< rounded = size;
---
> /* Build types. */
> string_type = build_pointer_type (char_type_node);
259,261c274,276
< rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
< rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
< * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
---
> /* Libgcc2 bb structure. */
> structure_decl = make_node (RECORD_TYPE);
> structure_pointer_type = build_pointer_type (structure_decl);
263,267c278,283
< /* ??? This _really_ ought to be done with a structure layout
< and with assemble_constructor. If long_bytes != pointer_bytes
< we'll be emitting unaligned data at some point. */
< if (long_bytes != pointer_bytes)
< abort ();
---
> /* Output the main header, of 7 words:
> 0: 1 if this file is initialized, else 0.
> 1: address of file name (LPBX1).
> 2: address of table of counts (LPBX2).
> 3: number of counts in the table.
> 4: always 0, libgcc2 uses this as a pointer to next ``struct bb''
269c285
< data_section ();
---
> The following are GNU extensions:
271,276c287,288
< /* Output the main header, of 11 words:
< 0: 1 if this file is initialized, else 0.
< 1: address of file name (LPBX1).
< 2: address of table of counts (LPBX2).
< 3: number of counts in the table.
< 4: always 0, for compatibility with Sun.
---
> 5: Number of bytes in this header.
> 6: address of table of function checksums (LPBX7). */
278c290,296
< The following are GNU extensions:
---
> /* The zero word. */
> decl_chain =
> build_decl (FIELD_DECL, get_identifier ("zero_word"),
> long_integer_type_node);
> value_chain = build_tree_list (decl_chain,
> convert (long_integer_type_node,
> integer_zero_node));
280,285c298,301
< 5: address of table of start addrs of basic blocks (LPBX3).
< 6: Number of bytes in this header.
< 7: address of table of function names (LPBX4).
< 8: address of table of line numbers (LPBX5) or 0.
< 9: address of table of file names (LPBX6) or 0.
< 10: space reserved for basic block profiling. */
---
> /* Address of filename. */
> {
> char *cwd, *da_filename;
> int da_filename_len;
287c303,306
< ASM_OUTPUT_ALIGN (asm_out_file, align);
---
> field_decl =
> build_decl (FIELD_DECL, get_identifier ("filename"), string_type);
> TREE_CHAIN (field_decl) = decl_chain;
> decl_chain = field_decl;
289c308,323
< ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 0);
---
> cwd = getpwd ();
> da_filename_len = strlen (filename) + strlen (cwd) + 4 + 1;
> da_filename = (char *) alloca (da_filename_len);
> strcpy (da_filename, cwd);
> strcat (da_filename, "/");
> strcat (da_filename, filename);
> strcat (da_filename, ".da");
> da_filename_len = strlen (da_filename);
> string_cst = build_string (da_filename_len + 1, da_filename);
> domain_type = build_index_type (build_int_2 (da_filename_len, 0));
> TREE_TYPE (string_cst)
> = build_array_type (char_type_node, domain_type);
> value_chain = tree_cons (field_decl,
> build1 (ADDR_EXPR, string_type, string_cst),
> value_chain);
> }
291,292c325,336
< /* Zero word. */
< assemble_integer (const0_rtx, long_bytes, align2, 1);
---
> /* Table of counts. */
> {
> tree gcov_type_type = make_unsigned_type (GCOV_TYPE_SIZE);
> tree gcov_type_pointer_type = build_pointer_type (gcov_type_type);
> tree domain_tree
> = build_index_type (build_int_2 (profile_info.
> count_instrumented_edges - 1, 0));
> tree gcov_type_array_type
> = build_array_type (gcov_type_type, domain_tree);
> tree gcov_type_array_pointer_type
> = build_pointer_type (gcov_type_array_type);
> tree counts_table;
294,297c338,342
< /* Address of filename. */
< ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 1);
< assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name), pointer_bytes,
< align2, 1);
---
> field_decl =
> build_decl (FIELD_DECL, get_identifier ("counts"),
> gcov_type_pointer_type);
> TREE_CHAIN (field_decl) = decl_chain;
> decl_chain = field_decl;
299,302c344,350
< /* Address of count table. */
< ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2);
< assemble_integer (gen_rtx_SYMBOL_REF (Pmode, name), pointer_bytes,
< align2, 1);
---
> /* No values. */
> counts_table
> = build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
> TREE_STATIC (counts_table) = 1;
> ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2);
> DECL_NAME (counts_table) = get_identifier (name);
> assemble_variable (counts_table, 0, 0, 0);
303a352,357
> value_chain = tree_cons (field_decl,
> build1 (ADDR_EXPR,
> gcov_type_array_pointer_type,
> counts_table), value_chain);
> }
>
305,306c359,363
< assemble_integer (GEN_INT (count_instrumented_edges),
< long_bytes, align2, 1);
---
> field_decl
> = build_decl (FIELD_DECL, get_identifier ("ncounts"),
> long_integer_type_node);
> TREE_CHAIN (field_decl) = decl_chain;
> decl_chain = field_decl;
308,309c365,375
< /* Zero word (link field). */
< assemble_integer (const0_rtx, pointer_bytes, align2, 1);
---
> value_chain = tree_cons (field_decl,
> convert (long_integer_type_node,
> build_int_2 (profile_info.
> count_instrumented_edges,
> 0)), value_chain);
> /* Pointer to the next bb. */
> field_decl
> = build_decl (FIELD_DECL, get_identifier ("next"),
> structure_pointer_type);
> TREE_CHAIN (field_decl) = decl_chain;
> decl_chain = field_decl;
311c377
< assemble_integer (const0_rtx, pointer_bytes, align2, 1);
---
> value_chain = tree_cons (field_decl, null_pointer_node, value_chain);
313,314c379,385
< /* Byte count for extended structure. */
< assemble_integer (GEN_INT (11 * UNITS_PER_WORD), long_bytes, align2, 1);
---
> /* sizeof(struct bb). We'll set this after entire structure
> is laid out. */
> field_decl
> = build_decl (FIELD_DECL, get_identifier ("sizeof_bb"),
> long_integer_type_node);
> TREE_CHAIN (field_decl) = decl_chain;
> decl_chain = field_decl;
316,317c387,388
< /* Address of function name table. */
< assemble_integer (const0_rtx, pointer_bytes, align2, 1);
---
> sizeof_field_value = tree_cons (field_decl, NULL, value_chain);
> value_chain = sizeof_field_value;
319,321c390,401
< /* Address of line number and filename tables if debugging. */
< assemble_integer (const0_rtx, pointer_bytes, align2, 1);
< assemble_integer (const0_rtx, pointer_bytes, align2, 1);
---
> /* struct bb_function []. */
> {
> struct function_list *item;
> int num_nodes;
> tree checksum_field, arc_count_field, name_field;
> tree domain;
> tree array_value_chain = NULL_TREE;
> tree bb_fn_struct_type;
> tree bb_fn_struct_array_type;
> tree bb_fn_struct_array_pointer_type;
> tree bb_fn_struct_pointer_type;
> tree field_value, field_value_chain;
323,324c403
< /* Space for extension ptr (link field). */
< assemble_integer (const0_rtx, UNITS_PER_WORD, align2, 1);
---
> bb_fn_struct_type = make_node (RECORD_TYPE);
326,332c405,406
< /* Output the file name changing the suffix to .d for
< Sun tcov compatibility. */
< ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 1);
< {
< char *cwd = getpwd ();
< int len = strlen (filename) + strlen (cwd) + 1;
< char *data_file = (char *) alloca (len + 4);
---
> checksum_field = build_decl (FIELD_DECL, get_identifier ("checksum"),
> long_integer_type_node);
334,339c408,496
< strcpy (data_file, cwd);
< strcat (data_file, "/");
< strcat (data_file, filename);
< strip_off_ending (data_file, len);
< strcat (data_file, ".da");
< assemble_string (data_file, strlen (data_file) + 1);
---
> arc_count_field
> = build_decl (FIELD_DECL, get_identifier ("arc_count"),
> integer_type_node);
> TREE_CHAIN (checksum_field) = arc_count_field;
>
> name_field
> = build_decl (FIELD_DECL, get_identifier ("name"), string_type);
> TREE_CHAIN (arc_count_field) = name_field;
>
> TYPE_FIELDS (bb_fn_struct_type) = checksum_field;
>
> num_nodes = 0;
>
> for (item = functions_head; item != 0; item = item->next)
> num_nodes++;
>
> /* Note that the array contains a terminator, hence no - 1. */
> domain = build_index_type (build_int_2 (num_nodes, 0));
>
> bb_fn_struct_pointer_type = build_pointer_type (bb_fn_struct_type);
> bb_fn_struct_array_type
> = build_array_type (bb_fn_struct_type, domain);
> bb_fn_struct_array_pointer_type
> = build_pointer_type (bb_fn_struct_array_type);
>
> layout_type (bb_fn_struct_type);
> layout_type (bb_fn_struct_pointer_type);
> layout_type (bb_fn_struct_array_type);
> layout_type (bb_fn_struct_array_pointer_type);
>
> for (item = functions_head; item != 0; item = item->next)
> {
> size_t name_len;
>
> /* create constructor for structure. */
> field_value_chain
> = build_tree_list (checksum_field,
> convert (long_integer_type_node,
> build_int_2 (item->cfg_checksum, 0)));
> field_value_chain
> = tree_cons (arc_count_field,
> convert (integer_type_node,
> build_int_2 (item->count_edges, 0)),
> field_value_chain);
>
> name_len = strlen (item->name);
> string_cst = build_string (name_len + 1, item->name);
> domain_type = build_index_type (build_int_2 (name_len, 0));
> TREE_TYPE (string_cst)
> = build_array_type (char_type_node, domain_type);
> field_value_chain = tree_cons (name_field,
> build1 (ADDR_EXPR, string_type,
> string_cst),
> field_value_chain);
>
> /* Add to chain. */
> array_value_chain
> = tree_cons (NULL_TREE, build (CONSTRUCTOR,
> bb_fn_struct_type, NULL_TREE,
> nreverse (field_value_chain)),
> array_value_chain);
> }
>
> /* Add terminator. */
> field_value = build_tree_list (arc_count_field,
> convert (integer_type_node,
> build_int_2 (-1, 0)));
>
> array_value_chain = tree_cons (NULL_TREE,
> build (CONSTRUCTOR, bb_fn_struct_type,
> NULL_TREE, field_value),
> array_value_chain);
>
>
> /* Create constructor for array. */
> field_decl
> = build_decl (FIELD_DECL, get_identifier ("function_infos"),
> bb_fn_struct_pointer_type);
> value_chain = tree_cons (field_decl,
> build1 (ADDR_EXPR,
> bb_fn_struct_array_pointer_type,
> build (CONSTRUCTOR,
> bb_fn_struct_array_type,
> NULL_TREE,
> nreverse
> (array_value_chain))),
> value_chain);
> TREE_CHAIN (field_decl) = decl_chain;
> decl_chain = field_decl;
342,370c499,518
< /* Make space for the table of counts. */
< if (size == 0)
< {
< /* Realign data section. */
< ASM_OUTPUT_ALIGN (asm_out_file, align);
< ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LPBX", 2);
< if (size != 0)
< assemble_zeros (size);
< }
< else
< {
< ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2);
< #ifdef ASM_OUTPUT_SHARED_LOCAL
< if (flag_shared_data)
< ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded);
< else
< #endif
< #ifdef ASM_OUTPUT_ALIGNED_DECL_LOCAL
< ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, NULL_TREE, name,
< size, BIGGEST_ALIGNMENT);
< #else
< #ifdef ASM_OUTPUT_ALIGNED_LOCAL
< ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
< BIGGEST_ALIGNMENT);
< #else
< ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
< #endif
< #endif
< }
---
> /* Finish structure. */
> TYPE_FIELDS (structure_decl) = nreverse (decl_chain);
> layout_type (structure_decl);
>
> structure_value
> = build (VAR_DECL, structure_decl, NULL_TREE, NULL_TREE);
> DECL_INITIAL (structure_value)
> = build (CONSTRUCTOR, structure_decl, NULL_TREE,
> nreverse (value_chain));
> TREE_STATIC (structure_value) = 1;
> ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
> DECL_NAME (structure_value) = get_identifier (name);
>
> /* Size of this structure. */
> TREE_VALUE (sizeof_field_value)
> = convert (long_integer_type_node,
> build_int_2 (int_size_in_bytes (structure_decl), 0));
>
> /* Build structure. */
> assemble_variable (structure_value, 0, 0, 0);
441d588
< #ifdef HAVE_ATTR_length
443d589
< #endif
530c676
< if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
---
> if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
790d935
< int i;
791a937
> basic_block bb;
808c954
< for (i = 0; i < n_basic_blocks; i++)
---
> FOR_EACH_BB (bb)
810d955
< basic_block bb = BASIC_BLOCK (i);
840,841c985,986
< || (bb->frequency > BASIC_BLOCK (i - 1)->frequency * 10
< && (BASIC_BLOCK (i - 1)->frequency
---
> || (bb->frequency > bb->prev_bb->frequency * 10
> && (bb->prev_bb->frequency
852c997
< align it. It is most likely an first block of loop. */
---
> align it. It is most likely a first block of loop. */
855c1000
< && branch_frequency > fallthru_frequency * 5)
---
> && branch_frequency > fallthru_frequency * 2)
977,981c1122
< if (JUMP_TABLES_IN_TEXT_SECTION
< #if !defined(READONLY_DATA_SECTION)
< || 1
< #endif
< )
---
> if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
1131c1272
< INSN_ADDRESSES (uid) = insn_current_address;
---
> INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid];
1144,1148c1285
< if (JUMP_TABLES_IN_TEXT_SECTION
< #if !defined(READONLY_DATA_SECTION)
< || 1
< #endif
< )
---
> if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
1349,1353c1486
< if (JUMP_TABLES_IN_TEXT_SECTION
< #if !defined(READONLY_DATA_SECTION)
< || 1
< #endif
< )
---
> if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
1383c1516
< }
---
> }
1540c1673
< reorder_blocks ();
---
> scope_to_insns_finalize ();
1551,1556d1683
< #ifdef VMS_DEBUGGING_INFO
< /* Output label after the prologue of the function. */
< if (write_symbols == VMS_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
< vmsdbgout_after_prologue ();
< #endif
<
1594c1721
< ASM_OUTPUT_INTERNAL_LABEL (file, "LP", current_function_profile_label_no);
---
> ASM_OUTPUT_INTERNAL_LABEL (file, "LP", current_function_funcdef_no);
1624c1751
< FUNCTION_PROFILER (file, current_function_profile_label_no);
---
> FUNCTION_PROFILER (file, current_function_funcdef_no);
1667c1794
< (*debug_hooks->end_epilogue) ();
---
> (*debug_hooks->end_epilogue) (last_linenum, last_filename);
1672c1799
< dwarf2out_end_epilogue ();
---
> dwarf2out_end_epilogue (last_linenum, last_filename);
1766,1771d1892
< #ifdef STACK_REGS
< /* Irritatingly, the reg-stack pass is creating new instructions
< and because of REG_DEAD note abuse it has to run after
< shorten_branches. Fake address of -1 then. */
< insn_current_address = -1;
< #else
1774,1775c1895,1898
< abort ();
< #endif
---
> if (GET_CODE (insn) == NOTE)
> insn_current_address = -1;
> else
> abort ();
1783a1907,1923
> /* Store function names for edge-profiling. */
> /* ??? Probably should re-use the existing struct function. */
>
> if (cfun->arc_profile)
> {
> struct function_list *new_item = xmalloc (sizeof (struct function_list));
>
> *functions_tail = new_item;
> functions_tail = &new_item->next;
>
> new_item->next = 0;
> new_item->name = xstrdup (IDENTIFIER_POINTER
> (DECL_ASSEMBLER_NAME (current_function_decl)));
> new_item->cfg_checksum = profile_info.current_function_cfg_checksum;
> new_item->count_edges = profile_info.count_edges_instrumented_now;
> }
>
1809a1950,1982
> /* Emit the appropriate declaration for an alternate-entry-point
> symbol represented by INSN, to FILE. INSN is a CODE_LABEL with
> LABEL_KIND != LABEL_NORMAL.
>
> The case fall-through in this function is intentional. */
> static void
> output_alternate_entry_point (file, insn)
> FILE *file;
> rtx insn;
> {
> const char *name = LABEL_NAME (insn);
>
> switch (LABEL_KIND (insn))
> {
> case LABEL_WEAK_ENTRY:
> #ifdef ASM_WEAKEN_LABEL
> ASM_WEAKEN_LABEL (file, name);
> #endif
> case LABEL_GLOBAL_ENTRY:
> (*targetm.asm_out.globalize_label) (file, name);
> case LABEL_STATIC_ENTRY:
> #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
> ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
> #endif
> ASM_OUTPUT_LABEL (file, name);
> break;
>
> case LABEL_NORMAL:
> default:
> abort ();
> }
> }
>
1853,1855d2025
< case NOTE_INSN_RANGE_BEG:
< case NOTE_INSN_RANGE_END:
< case NOTE_INSN_LIVE:
1889c2059
< (*debug_hooks->end_prologue) (last_linenum);
---
> (*debug_hooks->end_prologue) (last_linenum, last_filename);
2018a2189,2191
> #ifdef ASM_OUTPUT_ALIGN_WITH_NOP
> ASM_OUTPUT_ALIGN_WITH_NOP (file, align);
> #else
2020a2194
> #endif
2103,2106c2277
< if (LABEL_ALTERNATE_NAME (insn))
< ASM_OUTPUT_ALTERNATE_LABEL_NAME (file, insn);
< else
< ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
---
> ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
2112,2113c2283,2284
< if (LABEL_ALTERNATE_NAME (insn))
< ASM_OUTPUT_ALTERNATE_LABEL_NAME (file, insn);
---
> if (LABEL_ALT_ENTRY_P (insn))
> output_alternate_entry_point (file, insn);
2542,2548c2713,2719
< /* Dump the insn in the assembly for debugging. */
< if (flag_dump_rtl_in_asm)
< {
< print_rtx_head = ASM_COMMENT_START;
< print_rtl_single (asm_out_file, insn);
< print_rtx_head = "";
< }
---
> /* Dump the insn in the assembly for debugging. */
> if (flag_dump_rtl_in_asm)
> {
> print_rtx_head = ASM_COMMENT_START;
> print_rtl_single (asm_out_file, insn);
> print_rtx_head = "";
> }
2758c2929
< x->used = 0;
---
> RTX_FLAG (x, used) = 0;
2973c3144
<
---
>
3771d3941
< #ifdef REAL_ARITHMETIC
3800,3823d3969
< #else
< if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
< || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
< && ! flag_pretend_float)
< abort ();
<
< if (
< #ifdef HOST_WORDS_BIG_ENDIAN
< WORDS_BIG_ENDIAN
< #else
< ! WORDS_BIG_ENDIAN
< #endif
< )
< {
< /* Host and target agree => no need to swap. */
< *first = GEN_INT (CONST_DOUBLE_LOW (value));
< *second = GEN_INT (CONST_DOUBLE_HIGH (value));
< }
< else
< {
< *second = GEN_INT (CONST_DOUBLE_LOW (value));
< *first = GEN_INT (CONST_DOUBLE_HIGH (value));
< }
< #endif /* no REAL_ARITHMETIC */
3868c4014
< /* Return 1 if branch is an forward branch.
---
> /* Return 1 if branch is a forward branch.