diff options
author | Jing Yu <jingyu@google.com> | 2011-01-30 22:18:29 -0800 |
---|---|---|
committer | Jing Yu <jingyu@google.com> | 2011-01-30 22:18:29 -0800 |
commit | 4a66e756636cb8364582ea503abd10d76f5b4aa3 (patch) | |
tree | 9660204ec085888a0601a6460c967b204a63d5f3 /gcc-4.4.3/gcc/final.c | |
parent | b6be42e837844cce5283f42fcfac31e6d66a277d (diff) | |
download | toolchain_gcc-4a66e756636cb8364582ea503abd10d76f5b4aa3.tar.gz toolchain_gcc-4a66e756636cb8364582ea503abd10d76f5b4aa3.tar.bz2 toolchain_gcc-4a66e756636cb8364582ea503abd10d76f5b4aa3.zip |
Upgrade gcc-4.4.3 for Android toolchain.
- Backport upstream patches to support arm hardfp.
- Backport gcc-4.5 patches to support -march=atom. Now it is
able to build atom toolchain with glibc from this branch
- Develop a bunch of optimizations
- Fix a few arm dejagnu failures
To-do list:
- Support Android/atom
- Fix ia32 bootstrap failure
Change-Id: I5e10dcd21620d4d8ca984d1d1707a76067e61691
Diffstat (limited to 'gcc-4.4.3/gcc/final.c')
-rw-r--r-- | gcc-4.4.3/gcc/final.c | 122 |
1 files changed, 117 insertions, 5 deletions
diff --git a/gcc-4.4.3/gcc/final.c b/gcc-4.4.3/gcc/final.c index dc9a6d818..2c0be960d 100644 --- a/gcc-4.4.3/gcc/final.c +++ b/gcc-4.4.3/gcc/final.c @@ -1649,6 +1649,58 @@ final_end_function (void) #endif } + +static basic_block *start_to_bb = NULL; +static basic_block *end_to_bb = NULL; +static int bb_map_size = 0; +static int bb_seq = 0; + +/* Dumper helper for basic block information. FILE is the assembly + output file, and INSN is the instruction being emitted. */ + +static void +dump_basic_block_info (FILE *file, rtx insn) +{ + basic_block bb; + + if (!flag_debug_asm) + return; + + if (INSN_UID (insn) < bb_map_size + && (bb = start_to_bb[INSN_UID (insn)]) != NULL) + { + edge e; + edge_iterator ei; + + fprintf (file, "# BLOCK %d", bb->index); + if (bb->frequency) + fprintf (file, " freq:%d", bb->frequency); + if (bb->count) + fprintf (file, " count:" HOST_WIDEST_INT_PRINT_DEC, + bb->count); + fprintf (file, " seq:%d", bb_seq++); + fprintf (file, "\n# PRED:"); + FOR_EACH_EDGE (e, ei, bb->preds) + { + dump_edge_info (file, e, 0); + } + fprintf (file, "\n"); + } + if (INSN_UID (insn) < bb_map_size + && (bb = end_to_bb[INSN_UID (insn)]) != NULL) + { + edge e; + edge_iterator ei; + + fprintf (asm_out_file, "# SUCC:"); + FOR_EACH_EDGE (e, ei, bb->succs) + { + dump_edge_info (asm_out_file, e, 1); + } + fprintf (file, "\n"); + } +} + /* Output assembler code for some insns: all or part of a function. For description of args, see `final_start_function', above. */ @@ -1683,6 +1735,21 @@ final (rtx first, FILE *file, int optimize) CC_STATUS_INIT; + if (flag_debug_asm) + { + basic_block bb; + + bb_map_size = get_max_uid () + 1; + start_to_bb = XCNEWVEC (basic_block, bb_map_size); + end_to_bb = XCNEWVEC (basic_block, bb_map_size); + + FOR_EACH_BB_REVERSE (bb) + { + start_to_bb[INSN_UID (BB_HEAD (bb))] = bb; + end_to_bb[INSN_UID (BB_END (bb))] = bb; + } + } + /* Output the insns. */ for (insn = first; insn;) { @@ -1698,8 +1765,19 @@ final (rtx first, FILE *file, int optimize) insn_current_address = INSN_ADDRESSES (INSN_UID (insn)); #endif /* HAVE_ATTR_length */ + dump_basic_block_info (file, insn); insn = final_scan_insn (insn, file, optimize, 0, &seen); } + + if (flag_debug_asm) + { + free (start_to_bb); + free (end_to_bb); + start_to_bb = NULL; + end_to_bb = NULL; + bb_map_size = 0; + bb_seq = 0; + } } const char * @@ -1834,10 +1912,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, targetm.asm_out.unwind_emit (asm_out_file, insn); #endif - if (flag_debug_asm) - fprintf (asm_out_file, "\t%s basic block %d\n", - ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index); - if ((*seen & (SEEN_EMITTED | SEEN_BB)) == SEEN_BB) { *seen |= SEEN_EMITTED; @@ -4203,13 +4277,35 @@ debug_free_queue (void) symbol_queue_size = 0; } } - + +/* List the call graph profiled edges in the ".note.callgraph.text" section. */ +static void +cgraph_get_profiles (void) +{ + struct cgraph_node *node = cgraph_node (current_function_decl); + struct cgraph_edge *e; + struct cgraph_node *callee; + + for (e = node->callees; e != NULL; e = e->next_callee) + { + if (e->count <= PARAM_VALUE (PARAM_NOTE_CGRAPH_SECTION_EDGE_THRESHOLD)) + continue; + callee = e->callee; + fprintf (asm_out_file, "\t.string \"%s\"\n", + IDENTIFIER_POINTER (decl_assembler_name (callee->decl))); + fprintf (asm_out_file, "\t.string \"" HOST_WIDEST_INT_PRINT_DEC "\"\n", + e->count); + } +} + /* Turn the RTL into assembly. */ static unsigned int rest_of_handle_final (void) { rtx x; const char *fnname; + char *profile_fnname; + unsigned int flags; /* Get the function's name, as described by its RTL. This may be different from the DECL_NAME name used in the source file. */ @@ -4274,6 +4370,22 @@ rest_of_handle_final (void) targetm.asm_out.destructor (XEXP (DECL_RTL (current_function_decl), 0), decl_fini_priority_lookup (current_function_decl)); + + /* With -fcgraph-section, add ".note.callgraph.text" section for storing + profiling information. */ + if (flag_cgraph_section + && flag_profile_use + && cgraph_node (current_function_decl) != NULL) + { + flags = SECTION_NOTYPE; + profile_fnname = (char *)xmalloc(strlen(".note.callgraph.text.") + + strlen(fnname) + 1); + sprintf(profile_fnname, ".note.callgraph.text.%s", fnname); + switch_to_section(get_section(profile_fnname, flags, NULL)); + fprintf (asm_out_file, "\t.string \"Function %s\"\n", fnname); + cgraph_get_profiles (); + free (profile_fnname); + } return 0; } |