Commit 0ecf09f9 by Jan Hubicka Committed by Jan Hubicka

i386.c (ix86_output_main_function_alignment_hack): New function.

	* i386.c (ix86_output_main_function_alignment_hack): New function.
	(TARGET_ASM_FUNCTION_PROLOGUE): Default to it.

	* flow.c (mark_dfs_back_edges): Move from loop_p ; mark back
	edges by EDGE_DFS_BACK flag.
	(dump_edge_info): Add dfs_back flag.
	* basic-block.h (EDGE_DFS_BACK): New constant.
	(mark_dfs_back_edges): Declare.
	* alias.c (loop_p): Remove.
	(mark_constant_function): Use mark_dfs_back_edges.

	* reg-stack.c (block_info_def): Add predecesors counter and stack_out.
	(reg_to_stack): Call mark_dfs_back_edges; count the predecesors.
	(compensate_edge): Break out from ...
	(convert_regs_1): ... here; do smart choosing of stack_out to copy.
	(convert_regs_2): Set block_done once block is really done;
	Do updating of the predecesors counts.

	* toplev.c (rest_of_compilation): Recompute block_for_insn
	before post-reload cfg_cleanup.
	* function.c (thread_prologue_epilogue_insns):
	Call set_block_for_new_insns when emitting prologue directly.

From-SVN: r44486
parent 1490f392
Mon Jul 30 22:16:08 CEST 2001 Jan Hubicka <jh@suse.cz>
* i386.c (ix86_output_main_function_alignment_hack): New function.
(TARGET_ASM_FUNCTION_PROLOGUE): Default to it.
* flow.c (mark_dfs_back_edges): Move from loop_p ; mark back
edges by EDGE_DFS_BACK flag.
(dump_edge_info): Add dfs_back flag.
* basic-block.h (EDGE_DFS_BACK): New constant.
(mark_dfs_back_edges): Declare.
* alias.c (loop_p): Remove.
(mark_constant_function): Use mark_dfs_back_edges.
* reg-stack.c (block_info_def): Add predecesors counter and stack_out.
(reg_to_stack): Call mark_dfs_back_edges; count the predecesors.
(compensate_edge): Break out from ...
(convert_regs_1): ... here; do smart choosing of stack_out to copy.
(convert_regs_2): Set block_done once block is really done;
Do updating of the predecesors counts.
* toplev.c (rest_of_compilation): Recompute block_for_insn
before post-reload cfg_cleanup.
* function.c (thread_prologue_epilogue_insns):
Call set_block_for_new_insns when emitting prologue directly.
2001-07-30 Andreas Jaeger <aj@suse.de>
* jump.c: Add prototype for mark_modified_reg.
......
......@@ -107,8 +107,6 @@ static int aliases_everything_p PARAMS ((rtx));
static int write_dependence_p PARAMS ((rtx, rtx, int));
static int nonlocal_mentioned_p PARAMS ((rtx));
static int loop_p PARAMS ((void));
/* Set up all info needed to perform alias analysis on memory references. */
/* Returns the size in bytes of the mode of X. */
......@@ -2051,96 +2049,6 @@ nonlocal_mentioned_p (x)
return 0;
}
/* Return non-zero if a loop (natural or otherwise) is present.
Inspired by Depth_First_Search_PP described in:
Advanced Compiler Design and Implementation
Steven Muchnick
Morgan Kaufmann, 1997
and heavily borrowed from flow_depth_first_order_compute. */
static int
loop_p ()
{
edge *stack;
int *pre;
int *post;
int sp;
int prenum = 1;
int postnum = 1;
sbitmap visited;
/* Allocate the preorder and postorder number arrays. */
pre = (int *) xcalloc (n_basic_blocks, sizeof (int));
post = (int *) xcalloc (n_basic_blocks, sizeof (int));
/* Allocate stack for back-tracking up CFG. */
stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
visited = sbitmap_alloc (n_basic_blocks);
/* None of the nodes in the CFG have been visited yet. */
sbitmap_zero (visited);
/* Push the first edge on to the stack. */
stack[sp++] = ENTRY_BLOCK_PTR->succ;
while (sp)
{
edge e;
basic_block src;
basic_block dest;
/* Look at the edge on the top of the stack. */
e = stack[sp - 1];
src = e->src;
dest = e->dest;
/* Check if the edge destination has been visited yet. */
if (dest != EXIT_BLOCK_PTR && ! TEST_BIT (visited, dest->index))
{
/* Mark that we have visited the destination. */
SET_BIT (visited, dest->index);
pre[dest->index] = prenum++;
if (dest->succ)
{
/* Since the DEST node has been visited for the first
time, check its successors. */
stack[sp++] = dest->succ;
}
else
post[dest->index] = postnum++;
}
else
{
if (dest != EXIT_BLOCK_PTR && src != ENTRY_BLOCK_PTR
&& pre[src->index] >= pre[dest->index]
&& post[dest->index] == 0)
break;
if (! e->succ_next && src != ENTRY_BLOCK_PTR)
post[src->index] = postnum++;
if (e->succ_next)
stack[sp - 1] = e->succ_next;
else
sp--;
}
}
free (pre);
free (post);
free (stack);
sbitmap_free (visited);
return sp;
}
/* Mark the function if it is constant. */
void
......@@ -2157,7 +2065,7 @@ mark_constant_function ()
return;
/* A loop might not return which counts as a side effect. */
if (loop_p ())
if (mark_dfs_back_edges ())
return;
nonlocal_mentioned = 0;
......
......@@ -145,6 +145,7 @@ typedef struct edge_def {
#define EDGE_ABNORMAL_CALL 8
#define EDGE_EH 16
#define EDGE_FAKE 32
#define EDGE_DFS_BACK 64
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
......@@ -650,6 +651,7 @@ extern void conflict_graph_print PARAMS ((conflict_graph, FILE*));
extern conflict_graph conflict_graph_compute
PARAMS ((regset,
partition));
extern bool mark_dfs_back_edges PARAMS ((void));
/* In dominance.c */
......
......@@ -574,6 +574,7 @@ static HOST_WIDE_INT ix86_GOT_alias_set PARAMS ((void));
static void ix86_adjust_counter PARAMS ((rtx, HOST_WIDE_INT));
static rtx ix86_expand_aligntest PARAMS ((rtx, int));
static void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx));
static void ix86_output_main_function_alignment_hack PARAMS ((FILE *f, int));
struct ix86_address
{
......@@ -634,6 +635,10 @@ static int ix86_comp_type_attributes PARAMS ((tree, tree));
HOST_WIDE_INT));
# undef TARGET_ASM_FUNCTION_PROLOGUE
# define TARGET_ASM_FUNCTION_PROLOGUE ix86_osf_output_function_prologue
#else
# undef TARGET_ASM_FUNCTION_PROLOGUE
# define TARGET_ASM_FUNCTION_PROLOGUE \
ix86_output_main_function_alignment_hack
#endif
#undef TARGET_ASM_OPEN_PAREN
......@@ -10775,3 +10780,45 @@ ix86_memory_move_cost (mode, class, in)
* (int) GET_MODE_SIZE (mode) / 4);
}
}
/* Most of current runtimes (Jul 2001) do not align stack properly when
entering main, so emit an wrapper to align stack before the real main
code is called.
This can eventually go if we manage to fix the runtimes or teach gcc
to dynamically align stack in main automatically.
Adding check to configure is probably not good idea, as binarry can move
from one shared library to older. */
static void
ix86_output_main_function_alignment_hack (file, size)
FILE *file;
int size ATTRIBUTE_UNUSED;
{
rtx label;
char buf[256];
/* Check that we see main function with maximally 8 bytes of arguments.
if so, emit the hack to align stack for runtimes, where this constraint
is broken. */
if (strcmp (cfun->name, "main"))
return;
if (cfun->pops_args || cfun->args_size > 12)
return;
if (PREFERRED_STACK_BOUNDARY <= 2)
return;
label = gen_label_rtx ();
fprintf (file, "\tpushl\t%%ebp\n");
fprintf (file, "\tmovl\t%%esp, %%ebp\n");
fprintf (file, "\tandl\t$0xfffffff0, %%esp\n");
fprintf (file, "\tpushl\t%%ebp\n");
fprintf (file, "\tpushl\t16(%%ebp)\n");
fprintf (file, "\tpushl\t12(%%ebp)\n");
fprintf (file, "\tpushl\t8(%%ebp)\n");
fprintf (file, "\tcall\t");
ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (label));
assemble_name (file, buf);
fprintf (file, "\n\tleave\n");
fprintf (file, "\tret\n");
ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (label));
}
......@@ -1528,6 +1528,99 @@ mark_critical_edges ()
}
}
/* Mark the back edges in DFS traversal.
Return non-zero if a loop (natural or otherwise) is present.
Inspired by Depth_First_Search_PP described in:
Advanced Compiler Design and Implementation
Steven Muchnick
Morgan Kaufmann, 1997
and heavily borrowed from flow_depth_first_order_compute. */
bool
mark_dfs_back_edges ()
{
edge *stack;
int *pre;
int *post;
int sp;
int prenum = 1;
int postnum = 1;
sbitmap visited;
bool found = false;
/* Allocate the preorder and postorder number arrays. */
pre = (int *) xcalloc (n_basic_blocks, sizeof (int));
post = (int *) xcalloc (n_basic_blocks, sizeof (int));
/* Allocate stack for back-tracking up CFG. */
stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
visited = sbitmap_alloc (n_basic_blocks);
/* None of the nodes in the CFG have been visited yet. */
sbitmap_zero (visited);
/* Push the first edge on to the stack. */
stack[sp++] = ENTRY_BLOCK_PTR->succ;
while (sp)
{
edge e;
basic_block src;
basic_block dest;
/* Look at the edge on the top of the stack. */
e = stack[sp - 1];
src = e->src;
dest = e->dest;
e->flags &= ~EDGE_DFS_BACK;
/* Check if the edge destination has been visited yet. */
if (dest != EXIT_BLOCK_PTR && ! TEST_BIT (visited, dest->index))
{
/* Mark that we have visited the destination. */
SET_BIT (visited, dest->index);
pre[dest->index] = prenum++;
if (dest->succ)
{
/* Since the DEST node has been visited for the first
time, check its successors. */
stack[sp++] = dest->succ;
}
else
post[dest->index] = postnum++;
}
else
{
if (dest != EXIT_BLOCK_PTR && src != ENTRY_BLOCK_PTR
&& pre[src->index] >= pre[dest->index]
&& post[dest->index] == 0)
e->flags |= EDGE_DFS_BACK, found = true;
if (! e->succ_next && src != ENTRY_BLOCK_PTR)
post[src->index] = postnum++;
if (e->succ_next)
stack[sp - 1] = e->succ_next;
else
sp--;
}
}
free (pre);
free (post);
free (stack);
sbitmap_free (visited);
return found;
}
/* Split a block BB after insn INSN creating a new fallthru edge.
Return the new edge. Note that to keep other parts of the compiler happy,
this function renumbers all the basic blocks so that the new
......@@ -7779,7 +7872,7 @@ dump_edge_info (file, e, do_succ)
if (e->flags)
{
static const char * const bitnames[] = {
"fallthru", "crit", "ab", "abcall", "eh", "fake"
"fallthru", "crit", "ab", "abcall", "eh", "fake", "dfs_back"
};
int comma = 0;
int i, flags = e->flags;
......
......@@ -7226,7 +7226,8 @@ thread_prologue_and_epilogue_insns (f)
inserted = 1;
}
else
emit_insn_after (seq, f);
set_block_for_new_insns (emit_insn_after (seq, f),
ENTRY_BLOCK_PTR->succ);
}
#endif
......
......@@ -3473,11 +3473,13 @@ rest_of_compilation (decl)
verify_flow_info ();
#endif
compute_bb_for_insn (get_max_uid ());
/* If optimizing, then go ahead and split insns now. */
if (optimize > 0)
split_all_insns (0);
cleanup_cfg (0);
cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
/* On some machines, the prologue and epilogue code, or parts thereof,
can be represented as RTL. Doing so lets us schedule insns between
......@@ -3485,8 +3487,6 @@ rest_of_compilation (decl)
scheduling to operate in the epilogue. */
thread_prologue_and_epilogue_insns (insns);
compute_bb_for_insn (get_max_uid ());
if (optimize)
{
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_CROSSJUMP);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment