/* Convert RTL to assembler code and output it, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
#include "df.h"
#include "vecprim.h"
#include "ggc.h"
+#include "cfgloop.h"
+#include "params.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
{
int log, max_skip, max_log;
basic_block bb;
+ int freq_max = 0;
+ int freq_threshold = 0;
if (label_align)
{
if (! optimize || optimize_size)
return 0;
+ if (dump_file)
+ {
+ dump_flow_info (dump_file, TDF_DETAILS);
+ flow_loops_dump (dump_file, NULL, 1);
+ loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+ }
+ FOR_EACH_BB (bb)
+ if (bb->frequency > freq_max)
+ freq_max = bb->frequency;
+ freq_threshold = freq_max / PARAM_VALUE (PARAM_ALIGN_THRESHOLD);
+
+ if (dump_file)
+ fprintf(dump_file, "freq_max: %i\n",freq_max);
FOR_EACH_BB (bb)
{
rtx label = BB_HEAD (bb);
if (!LABEL_P (label)
|| probably_never_executed_bb_p (bb))
- continue;
+ {
+ if (dump_file)
+ fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i skipped.\n",
+ bb->index, bb->frequency, bb->loop_father->num, bb->loop_depth);
+ continue;
+ }
max_log = LABEL_ALIGN (label);
max_skip = LABEL_ALIGN_MAX_SKIP;
else
branch_frequency += EDGE_FREQUENCY (e);
}
+ if (dump_file)
+ {
+ fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i fall %4i branch %4i",
+ bb->index, bb->frequency, bb->loop_father->num,
+ bb->loop_depth,
+ fallthru_frequency, branch_frequency);
+ if (!bb->loop_father->inner && bb->loop_father->num)
+ fprintf (dump_file, " inner_loop");
+ if (bb->loop_father->header == bb)
+ fprintf (dump_file, " loop_header");
+ fprintf (dump_file, "\n");
+ }
/* There are two purposes to align block with no fallthru incoming edge:
1) to avoid fetch stalls when branch destination is near cache boundary
when function is called. */
if (!has_fallthru
- && (branch_frequency > BB_FREQ_MAX / 10
+ && (branch_frequency > freq_threshold
|| (bb->frequency > bb->prev_bb->frequency * 10
&& (bb->prev_bb->frequency
<= ENTRY_BLOCK_PTR->frequency / 2))))
{
log = JUMP_ALIGN (label);
+ if (dump_file)
+ fprintf(dump_file, " jump alignment added.\n");
if (max_log < log)
{
max_log = log;
align it. It is most likely a first block of loop. */
if (has_fallthru
&& maybe_hot_bb_p (bb)
- && branch_frequency + fallthru_frequency > BB_FREQ_MAX / 10
- && branch_frequency > fallthru_frequency * 2)
+ && branch_frequency + fallthru_frequency > freq_threshold
+ && (branch_frequency
+ > fallthru_frequency * PARAM_VALUE (PARAM_ALIGN_LOOP_ITERATIONS)))
{
log = LOOP_ALIGN (label);
+ if (dump_file)
+ fprintf(dump_file, " internal loop alignment added.\n");
if (max_log < log)
{
max_log = log;
LABEL_TO_ALIGNMENT (label) = max_log;
LABEL_TO_MAX_SKIP (label) = max_skip;
}
+
+ if (dump_file)
+ loop_optimizer_finalize ();
return 0;
}
struct tree_opt_pass pass_compute_alignments =
{
- NULL, /* name */
+ "alignments", /* name */
NULL, /* gate */
compute_alignments, /* execute */
NULL, /* sub */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- 0, /* todo_flags_finish */
+ TODO_dump_func | TODO_verify_rtl_sharing
+ | TODO_ggc_collect, /* todo_flags_finish */
0 /* letter */
};
TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
}
+ if (warn_frame_larger_than
+ && get_frame_size () > frame_larger_than_size)
+ {
+ /* Issue a warning */
+ warning (OPT_Wframe_larger_than_,
+ "the frame size of %wd bytes is larger than %wd bytes",
+ get_frame_size (), frame_larger_than_size);
+ }
+
/* First output the function prologue: code to set up the stack frame. */
targetm.asm_out.function_prologue (file, get_frame_size ());
case NOTE_INSN_SWITCH_TEXT_SECTIONS:
in_cold_section_p = !in_cold_section_p;
- (*debug_hooks->switch_text_section) ();
+#ifdef DWARF2_UNWIND_INFO
+ if (dwarf2out_do_frame ())
+ dwarf2out_switch_text_section ();
+ else
+#endif
+ (*debug_hooks->switch_text_section) ();
+
switch_to_section (current_function_section ());
break;
fputs (ASM_APP_ON, file);
app_on = 1;
}
-#ifdef USE_MAPPED_LOCATION
loc = expand_location (ASM_INPUT_SOURCE_LOCATION (body));
-#else
- loc.file = ASM_INPUT_SOURCE_FILE (body);
- loc.line = ASM_INPUT_SOURCE_LINE (body);
-#endif
if (*loc.file && loc.line)
fprintf (asm_out_file, "%s %i \"%s\" 1\n",
ASM_COMMENT_START, loc.line, loc.file);
else if (REG_P (y))
{
/* Simplify_subreg can't handle some REG cases, but we have to. */
- unsigned int regno = subreg_regno (x);
- *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, SUBREG_BYTE (x));
+ unsigned int regno;
+ HOST_WIDE_INT offset;
+
+ regno = subreg_regno (x);
+ if (subreg_lowpart_p (x))
+ offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y));
+ else
+ offset = SUBREG_BYTE (x);
+ *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, offset);
}
}
case ZERO_EXTEND:
case SIGN_EXTEND:
case SUBREG:
+ case TRUNCATE:
output_addr_const (file, XEXP (x, 0));
break;