#include "debug.h"
#include "expr.h"
#include "profile.h"
+#include "cfglayout.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
#define JUMP_TABLES_IN_TEXT_SECTION 0
#endif
+#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
+
/* Last insn processed by final_scan_insn. */
static rtx debug_insn;
rtx current_output_insn;
end_final (filename)
const char *filename;
{
- if (profile_arc_flag)
+ if (profile_arc_flag && profile_info.count_instrumented_edges)
{
char name[20];
tree string_type, string_cst;
tree structure_decl, structure_value, structure_pointer_type;
tree field_decl, decl_chain, value_chain;
- tree nwords_field_value, domain_type;
+ tree sizeof_field_value, domain_type;
/* Build types. */
string_type = build_pointer_type (char_type_node);
/* Libgcc2 bb structure. */
structure_decl = make_node (RECORD_TYPE);
- TYPE_PACKED (structure_decl) = flag_pack_struct;
structure_pointer_type = build_pointer_type (structure_decl);
/* Output the main header, of 7 words:
decl_chain =
build_decl (FIELD_DECL, get_identifier ("zero_word"),
long_integer_type_node);
- value_chain = build_tree_list (decl_chain, integer_zero_node);
+ value_chain = build_tree_list (decl_chain,
+ convert (long_integer_type_node,
+ integer_zero_node));
/* Address of filename. */
{
- char *cwd = getpwd ();
- int da_filename_len = strlen (filename) + strlen (cwd) + 4 + 1;
- char *da_filename = (char *) alloca (da_filename_len);
+ char *cwd, *da_filename;
+ int da_filename_len;
+
+ field_decl =
+ build_decl (FIELD_DECL, get_identifier ("filename"), string_type);
+ TREE_CHAIN (field_decl) = decl_chain;
+ decl_chain = field_decl;
+ 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);
strip_off_ending (da_filename, da_filename_len - 3);
strcat (da_filename, ".da");
- field_decl =
- build_decl (FIELD_DECL, get_identifier ("filename"), string_type);
- string_cst = build_string (strlen (da_filename) + 1, da_filename);
- domain_type = build_index_type (build_int_2 (strlen (da_filename) + 1,
- 0));
- TREE_TYPE (string_cst) =
- build_array_type (char_type_node, domain_type);
+ 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);
- TREE_CHAIN (field_decl) = decl_chain;
- decl_chain = field_decl;
}
/* 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 gcov_type_array_type, gcov_type_array_pointer_type;
- tree domain_tree = build_index_type (build_int_2
- (profile_info.
- count_instrumented_edges - 1,
- 0));
+ 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;
- gcov_type_array_type = build_array_type (gcov_type_type, domain_tree);
- gcov_type_array_pointer_type =
- build_pointer_type (gcov_type_array_type);
+ field_decl =
+ build_decl (FIELD_DECL, get_identifier ("counts"),
+ gcov_type_pointer_type);
+ TREE_CHAIN (field_decl) = decl_chain;
+ decl_chain = field_decl;
/* No values. */
- counts_table =
- build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
+ 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);
- field_decl =
- build_decl (FIELD_DECL, get_identifier ("counts"),
- gcov_type_pointer_type);
value_chain = tree_cons (field_decl,
build1 (ADDR_EXPR,
gcov_type_array_pointer_type,
counts_table), value_chain);
- TREE_CHAIN (field_decl) = decl_chain;
- decl_chain = field_decl;
}
/* Count of the # of instrumented arcs. */
- field_decl =
- build_decl (FIELD_DECL, get_identifier ("ncounts"),
- long_integer_type_node);
+ field_decl
+ = build_decl (FIELD_DECL, get_identifier ("ncounts"),
+ long_integer_type_node);
+ TREE_CHAIN (field_decl) = decl_chain;
+ decl_chain = field_decl;
+
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;
- /* Pointer to the next bb. */
- field_decl =
- build_decl (FIELD_DECL, get_identifier ("next"),
- structure_pointer_type);
value_chain = tree_cons (field_decl, null_pointer_node, value_chain);
- TREE_CHAIN (field_decl) = decl_chain;
- decl_chain = field_decl;
- /* Number of words. We'll set this after entire structure is laid out. */
- field_decl =
- build_decl (FIELD_DECL, get_identifier ("nwords"),
- long_integer_type_node);
- value_chain = nwords_field_value =
- tree_cons (field_decl, NULL, value_chain);
+ /* 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;
+ sizeof_field_value = tree_cons (field_decl, NULL, value_chain);
+ value_chain = sizeof_field_value;
+
/* struct bb_function []. */
{
struct function_list *item;
tree field_value, field_value_chain;
bb_fn_struct_type = make_node (RECORD_TYPE);
- TYPE_PACKED (bb_fn_struct_type) = flag_pack_struct;
checksum_field = build_decl (FIELD_DECL, get_identifier ("checksum"),
long_integer_type_node);
- arc_count_field =
- build_decl (FIELD_DECL, get_identifier ("arc_count"),
- integer_type_node);
+
+ 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);
+
+ 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;
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);
+ 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);
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);
-
- string_cst = build_string (strlen (item->name) + 1, item->name);
- domain_type = build_index_type (build_int_2 (strlen (item->name) +
- 1, 0));
- TREE_TYPE (string_cst) = build_array_type (char_type_node,
- domain_type);
+ 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);
+ array_value_chain
+ = tree_cons (NULL_TREE, build (CONSTRUCTOR,
+ bb_fn_struct_type, NULL_TREE,
+ nreverse (field_value_chain)),
+ array_value_chain);
}
/* Add terminator. */
/* Create constructor for array. */
-
- field_decl =
- build_decl (FIELD_DECL, get_identifier ("function_infos"),
- bb_fn_struct_pointer_type);
+ 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,
decl_chain = field_decl;
}
-
/* 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));
+ 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);
- /* Set number of words in this structure. */
- TREE_VALUE (nwords_field_value) =
- build_int_2 (TREE_INT_CST_LOW (TYPE_SIZE_UNIT (structure_decl)) /
- (INT_TYPE_SIZE / BITS_PER_UNIT), 0);
+ /* 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);
-
- /* Offset to table of arc counters for thread-safe profiling. */
- {
- tree table_offset_var = make_node (VAR_DECL);
- TREE_TYPE (table_offset_var) = build_pointer_type (integer_type_node);
- DECL_INITIAL (table_offset_var) = integer_zero_node;
- DECL_NAME (table_offset_var) = get_identifier (".LPBF0");
- TREE_STATIC (table_offset_var) = 1;
- assemble_variable (table_offset_var, 0, 0, 0);
- }
}
}
static int *insn_lengths;
-#ifdef HAVE_ATTR_length
varray_type insn_addresses_;
-#endif
/* Max uid for which the above arrays are valid. */
static int insn_lengths_max_uid;
case JUMP_INSN:
body = PATTERN (insn);
- if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
+ if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
{
/* Alignment is machine-dependent and should be handled by
ADDR_VEC_ALIGN. */
void
compute_alignments ()
{
- int i;
int log, max_skip, max_log;
+ basic_block bb;
if (label_align)
{
if (! optimize || optimize_size)
return;
- for (i = 0; i < n_basic_blocks; i++)
+ FOR_EACH_BB (bb)
{
- basic_block bb = BASIC_BLOCK (i);
rtx label = bb->head;
int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0;
edge e;
if (!has_fallthru
&& (branch_frequency > BB_FREQ_MAX / 10
- || (bb->frequency > BASIC_BLOCK (i - 1)->frequency * 10
- && (BASIC_BLOCK (i - 1)->frequency
+ || (bb->frequency > bb->prev_bb->frequency * 10
+ && (bb->prev_bb->frequency
<= ENTRY_BLOCK_PTR->frequency / 2))))
{
log = JUMP_ALIGN (label);
next = NEXT_INSN (insn);
/* ADDR_VECs only take room if read-only data goes into the text
section. */
- if (JUMP_TABLES_IN_TEXT_SECTION
-#if !defined(READONLY_DATA_SECTION)
- || 1
-#endif
- )
+ if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
if (next && GET_CODE (next) == JUMP_INSN)
{
rtx nextbody = PATTERN (next);
{
/* This only takes room if read-only data goes into the text
section. */
- if (JUMP_TABLES_IN_TEXT_SECTION
-#if !defined(READONLY_DATA_SECTION)
- || 1
-#endif
- )
+ if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
insn_lengths[uid] = (XVECLEN (body,
GET_CODE (body) == ADDR_DIFF_VEC)
* GET_MODE_SIZE (GET_MODE (body)));
PUT_MODE (body, CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr,
max_addr - rel_addr,
body));
- if (JUMP_TABLES_IN_TEXT_SECTION
-#if !defined(READONLY_DATA_SECTION)
- || 1
-#endif
- )
+ if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
{
insn_lengths[uid]
= (XVECLEN (body, 1) * GET_MODE_SIZE (GET_MODE (body)));
insn_current_address += insn_lengths[inner_uid];
}
- }
+ }
else
insn_current_address += insn_lengths[uid];
if (write_symbols)
{
remove_unnecessary_notes ();
- reorder_blocks ();
+ scope_to_insns_finalize ();
number_blocks (current_function_decl);
/* We never actually put out begin/end notes for the top-level
block in the function. But, conceptually, that block is
#ifndef NO_PROFILE_COUNTERS
data_section ();
ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
- ASM_OUTPUT_INTERNAL_LABEL (file, "LP", current_function_profile_label_no);
+ ASM_OUTPUT_INTERNAL_LABEL (file, "LP", current_function_funcdef_no);
assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
#endif
#endif
#endif
- FUNCTION_PROFILER (file, current_function_profile_label_no);
+ FUNCTION_PROFILER (file, current_function_funcdef_no);
#if defined(STATIC_CHAIN_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
if (cxt)
#ifdef HAVE_ATTR_length
if ((unsigned) INSN_UID (insn) >= INSN_ADDRESSES_SIZE ())
{
-#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
/* This can be triggered by bugs elsewhere in the compiler if
new insns are created after init_insn_lengths is called. */
- abort ();
-#endif
+ if (GET_CODE (insn) == NOTE)
+ insn_current_address = -1;
+ else
+ abort ();
}
else
insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
}
/* 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 (current_function_name);
+ new_item->cfg_checksum = profile_info.current_function_cfg_checksum;
+ new_item->count_edges = profile_info.count_edges_instrumented_now;
+ }
- if (profile_arc_flag)
- {
- struct function_list *new_item = xmalloc (sizeof (struct function_list));
-
- /* Add function to linked list. */
- new_item->next = 0;
- *functions_tail = new_item;
- functions_tail = &new_item->next;
-
- /* Set values. */
- new_item->cfg_checksum = profile_info.current_function_cfg_checksum;
- new_item->count_edges = profile_info.count_edges_instrumented_now;
- new_item->name = xstrdup (current_function_name);
-
- }
-
free (line_note_exists);
line_note_exists = NULL;
}
case NOTE_INSN_LOOP_VTOP:
case NOTE_INSN_FUNCTION_END:
case NOTE_INSN_REPEATED_LINE_NUMBER:
- case NOTE_INSN_RANGE_BEG:
- case NOTE_INSN_RANGE_END:
- case NOTE_INSN_LIVE:
case NOTE_INSN_EXPECTED_VALUE:
break;
insn_code_number = recog_memoized (insn);
cleanup_subreg_operands (insn);
- /* 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 = "";
+ }
if (! constrain_operands_cached (1))
fatal_insn_not_found (insn);
pfx_str = this_is_asm_operands ? _("invalid `asm': ") : "output_operand: ";
asprintf (&fmt_string, "%s%s", pfx_str, _(msgid));
vasprintf (&new_message, fmt_string, ap);
-
+
if (this_is_asm_operands)
error_for_asm (this_is_asm_operands, "%s", new_message);
else
*paddressp = 0;
+ if (op == NULL)
+ return 0;
+
if (GET_CODE (op) == REG && ORIGINAL_REGNO (op) >= FIRST_PSEUDO_REGISTER)
return REGNO_DECL (ORIGINAL_REGNO (op));
else if (GET_CODE (op) != MEM)