This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[yara-branch] patch for bug fixes, speedup, code improvement
- From: Vladimir Makarov <vmakarov at redhat dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 29 Mar 2006 18:35:18 -0500
- Subject: [yara-branch] patch for bug fixes, speedup, code improvement
This patch
o fixes bugs in YARA when frame pointer is omitted
o fixes bugs in cover class set calculation when tunning other
than for pentium4 is used
o improve generated code for crafty (other changes in SPEC
are insignifciant) by taking allocno sizes into account.
o speeds YARA up for SPECFp lucas (about 20%) by speeding coloring
2006-03-29 Vladimir Makarov <vmakarov@redhat.com>
* yara-int.h (stack_memory_start_frame_offset): Rename to
get_stack_memory_start_frame_offset.
(rounded_slot_memory_size): New prototype.
(set_non_alloc_regs): New prototype.
* yara-color.c (setup_reg_subclasses): Don't take fixed registers
into account.
(min_reg_class_cover_size, min_reg_class_cover): Rename them to
final_reg_class_cover_size, final_reg_class_cover.
(extend_reg_class_cover, set_up_class_translate,
print_class_cover, find_reg_class_closure): Use the new names.
(colorable_can_bucket): New variable.
(add_can_to_bucket, delete_can_from_bucket): Change signature.
(curr_global_can_cover_class): Remove.
(global_can_compare): Don't check cover class. Take allocno sizes
into account.
(push_globals_to_stack): Form and use can arrays according to
their cover classes.
(global_can_alloc): Initialize colorable_can_bucket.
* yara-final.c (final_stack_memory_start_frame_offset,
final_rounded_slot_memory_size): New variables.
(get_allocno_memory_slot_rtx): Fix bug in calculating displacement
relative to stack pointer.
(emit_copy, modify_insn): Don't change offset for elimination to
set pointer.
(align_or_allocate_stack_memory): Rename to
allocate_stack_memory. Setup
final_stack_memory_start_frame_offset and
final_allocate_stack_memory.
(yara_rewrite): Use the renamed function once.
* yara.c (set_non_alloc_regs): Make it external, add
parameter, and call set_up_class_hard_regs and
set_up_available_class_regs.
(yara_init_once): Remove calls of set_up_class_hard_regs and
set_up_available_class_regs.
* yara-trans.c (get_temp_stack_memory_slot_rtx): Add a
parameter. Fix the displacement calculation.
(rounded_slot_memory_size): New function.
(stack_memory_start_frame_offset): Rename to
get_stack_memory_start_frame_offset.
(assign_copy_secondary): Add parameter to
get_temp_stack_memory_slot_rtx call.
* yara-ir.c (modify_offsets_and_frame_pointer_needed): Modify
no_alloc_regs if necessary.
Index: yara-int.h
===================================================================
--- yara-int.h (revision 112301)
+++ yara-int.h (working copy)
@@ -911,7 +911,8 @@ extern void yara_trans_init (void);
extern void yara_trans_finish (void);
/* yara-trans.c: */
-extern HOST_WIDE_INT stack_memory_start_frame_offset (void);
+extern HOST_WIDE_INT rounded_slot_memory_size (void);
+extern HOST_WIDE_INT get_stack_memory_start_frame_offset (void);
extern void print_memory_slot (FILE *, const char *, int,
struct memory_slot *);
extern int get_paradoxical_subreg_memory_offset (int, enum machine_mode);
@@ -998,6 +999,7 @@ extern short class_hard_reg_index [N_REG
extern HARD_REG_SET no_alloc_regs;
extern int available_class_regs [N_REG_CLASSES];
+extern void set_non_alloc_regs (bool);
extern void *yara_allocate (size_t);
extern void yara_free (void *addr);
extern bitmap yara_allocate_bitmap (void);
Index: yara-color.c
===================================================================
--- yara-color.c (revision 112301)
+++ yara-color.c (working copy)
@@ -84,15 +84,12 @@ setup_reg_subclasses (void)
continue;
COPY_HARD_REG_SET (temp_set1, reg_class_contents [i]);
- AND_COMPL_HARD_REG_SET (temp_set1, fixed_reg_set);
-
for (j = 0; j < N_REG_CLASSES; j++)
if (i != j)
{
enum reg_class *p;
COPY_HARD_REG_SET (temp_set2, reg_class_contents [j]);
- AND_COMPL_HARD_REG_SET (temp_set2, fixed_reg_set);
GO_IF_HARD_REG_SUBSET (temp_set1, temp_set2, subclass);
continue;
subclass:
@@ -161,9 +158,9 @@ set_up_closure_classes (void)
}
-static int reg_class_cover_size, min_reg_class_cover_size;
+static int reg_class_cover_size, final_reg_class_cover_size;
static enum reg_class reg_class_cover [N_REG_CLASSES];
-static enum reg_class min_reg_class_cover [N_REG_CLASSES];
+static enum reg_class final_reg_class_cover [N_REG_CLASSES];
static HARD_REG_SET reg_class_cover_set;
static HARD_REG_SET temp_hard_reg_set;
@@ -179,7 +176,7 @@ extend_reg_class_cover (void)
AND_COMPL_HARD_REG_SET (temp_hard_reg_set, reg_class_cover_set);
GO_IF_HARD_REG_EQUAL (temp_hard_reg_set, zero_hard_reg_set,
done);
- if (reg_class_cover_size >= min_reg_class_cover_size)
+ if (reg_class_cover_size >= final_reg_class_cover_size)
return false;
result = false;
for (i = 0; i < closure_classes_size; i++)
@@ -206,10 +203,10 @@ extend_reg_class_cover (void)
gcc_unreachable ();
done:
- if (min_reg_class_cover_size > reg_class_cover_size)
+ if (final_reg_class_cover_size > reg_class_cover_size)
{
- min_reg_class_cover_size = reg_class_cover_size;
- memcpy (min_reg_class_cover, reg_class_cover,
+ final_reg_class_cover_size = reg_class_cover_size;
+ memcpy (final_reg_class_cover, reg_class_cover,
reg_class_cover_size * sizeof (enum reg_class));
}
return true;
@@ -225,9 +222,9 @@ set_up_class_translate (void)
for (cl = 0; cl < N_REG_CLASSES; cl++)
class_translate [cl] = NO_REGS;
- for (i = 0; i < min_reg_class_cover_size; i++)
+ for (i = 0; i < final_reg_class_cover_size; i++)
{
- cl = min_reg_class_cover [i];
+ cl = final_reg_class_cover [i];
for (cl_ptr = &alloc_reg_class_subclasses [cl] [0];
*cl_ptr != LIM_REG_CLASSES;
cl_ptr++)
@@ -259,8 +256,8 @@ print_class_cover (FILE *f)
int i;
fprintf (f, "Class cover:\n");
- for (i = 0; i < min_reg_class_cover_size; i++)
- fprintf (f, " %s", reg_class_names [min_reg_class_cover [i]]);
+ for (i = 0; i < final_reg_class_cover_size; i++)
+ fprintf (f, " %s", reg_class_names [final_reg_class_cover [i]]);
fprintf (f, "\nClass translation:\n");
for (i = 0; i < N_REG_CLASSES; i++)
fprintf (f, " %s -> %s\n", reg_class_names [i],
@@ -280,7 +277,7 @@ find_reg_class_closure (void)
setup_reg_subclasses ();
set_up_closure_classes ();
- min_reg_class_cover_size = N_REG_CLASSES;
+ final_reg_class_cover_size = N_REG_CLASSES;
reg_class_cover_size = 0;
CLEAR_HARD_REG_SET (reg_class_cover_set);
ok_p = extend_reg_class_cover ();
@@ -1337,29 +1334,32 @@ static can_t *sorted_cans;
/* Number of global cans. */
static int global_cans_num;
+/* Bucket of cans can be colored currently without spilling. */
+static can_t colorable_can_bucket;
+
/* Array of all buckets used for colouring. I-th bucket contains cans
conflicting with I other cans uncoloured yet. */
static varray_type bucket_varray;
-/* Add CAN to BUCKET_NUM-th bucket. CAN should be not in a bucket
+/* Add CAN to *BUCKET_PTR bucket. CAN should be not in a bucket
before the call. */
static void
-add_can_to_bucket (can_t can, varray_type *bucket_varray, int bucket_num)
+add_can_to_bucket (can_t can, can_t *bucket_ptr)
{
can_t first_can;
- first_can = VARRAY_GENERIC_PTR (*bucket_varray, bucket_num);
+ first_can = *bucket_ptr;
CAN_NEXT_BUCKET_CAN (can) = first_can;
CAN_PREV_BUCKET_CAN (can) = NULL;
if (first_can != NULL)
CAN_PREV_BUCKET_CAN (first_can) = can;
- VARRAY_GENERIC_PTR (*bucket_varray, bucket_num) = can;
+ *bucket_ptr = can;
}
-/* Delete CAN from BUCKET_NUM-th bucket. It should be there before
+/* Delete CAN from *BUCKET_PTR bucket. It should be there before
the call. */
static void
-delete_can_from_bucket (can_t can, varray_type *bucket_varray, int bucket_num)
+delete_can_from_bucket (can_t can, can_t *bucket_ptr)
{
can_t prev_can, next_can;
@@ -1369,8 +1369,8 @@ delete_can_from_bucket (can_t can, varra
CAN_NEXT_BUCKET_CAN (prev_can) = next_can;
else
{
- gcc_assert (VARRAY_GENERIC_PTR (*bucket_varray, bucket_num) == can);
- VARRAY_GENERIC_PTR (*bucket_varray, bucket_num) = next_can;
+ gcc_assert (*bucket_ptr == can);
+ *bucket_ptr = next_can;
}
if (next_can != NULL)
CAN_PREV_BUCKET_CAN (next_can) = prev_can;
@@ -1380,9 +1380,6 @@ delete_can_from_bucket (can_t can, varra
colouring. */
static varray_type global_stack_varray;
-/* Cover class of the global can in consideration. */
-static enum reg_class curr_global_can_cover_class;
-
/* Function used to sort cans according to their priorities to choose
one for spilling. */
static int
@@ -1390,24 +1387,21 @@ global_can_compare (const void *c1p, con
{
can_t c1 = *(can_t *) c1p;
can_t c2 = *(can_t *) c2p;
- int diff;
+ int diff, size1, size2;
if (CAN_IN_GRAPH_P (c1) && ! CAN_IN_GRAPH_P (c2))
return -1;
else if (! CAN_IN_GRAPH_P (c1) && CAN_IN_GRAPH_P (c2))
return 1;
- else if (CAN_COVER_CLASS (c1) == curr_global_can_cover_class
- && CAN_COVER_CLASS (c2) != curr_global_can_cover_class)
- return -1;
- else if (CAN_COVER_CLASS (c1) != curr_global_can_cover_class
- && CAN_COVER_CLASS (c2) == curr_global_can_cover_class)
- return 1;
else
{
+ gcc_assert (CAN_COVER_CLASS (c1) == CAN_COVER_CLASS (c2));
+ size1 = reg_class_nregs [CAN_COVER_CLASS (c1)] [CAN_MODE (c1)];
+ size2 = reg_class_nregs [CAN_COVER_CLASS (c2)] [CAN_MODE (c2)];
diff = ((CAN_MEMORY_COST (c1) - CAN_COVER_CLASS_COST (c1))
- / (CAN_LEFT_CONFLICTS_NUM (c1) + 1)
+ / (CAN_LEFT_CONFLICTS_NUM (c1) + 1) * size1
- (CAN_MEMORY_COST (c2) - CAN_COVER_CLASS_COST (c2))
- / (CAN_LEFT_CONFLICTS_NUM (c2) + 1));
+ / (CAN_LEFT_CONFLICTS_NUM (c2) + 1) * size2);
if (diff != 0)
return diff;
return CAN_NUM (c1) - CAN_NUM (c2);
@@ -1419,62 +1413,131 @@ global_can_compare (const void *c1p, con
static void
push_globals_to_stack (void)
{
- int i, n, size = 0, cans_num_to_sort;
+ int i, size = 0, conflicts_num, conflict_size;
+ int first_non_empty_bucket_num;
can_t can, conflict_can;
- can_t *sorted_global_cans, *can_vec;
+ can_t *can_vec, *sorted_global_cans, *bucket_ptr;
+ enum reg_class cover_class;
+ int num, cover_class_cans_num [N_REG_CLASSES];
+ can_t *cover_class_cans [N_REG_CLASSES];
- sorted_global_cans = yara_allocate (sizeof (can_t) * global_cans_num);
- for (n = i = 0; i < cans_num; i++)
- if (CAN_GLOBAL_P (cans [i]))
- sorted_global_cans [n++] = cans [i];
- gcc_assert (n == global_cans_num);
- cans_num_to_sort = global_cans_num;
- for (n = 0; n < global_cans_num; n++)
- {
- for (i = 0; i < (int) VARRAY_ACTIVE_SIZE (bucket_varray); i++)
- if (VARRAY_GENERIC_PTR (bucket_varray, i) != NULL)
- break;
- if (i >= (int) VARRAY_ACTIVE_SIZE (bucket_varray))
- break;
- can = VARRAY_GENERIC_PTR (bucket_varray, i);
- gcc_assert (CAN_LEFT_CONFLICTS_NUM (can) == i);
- curr_global_can_cover_class = CAN_COVER_CLASS (can);
- if (curr_global_can_cover_class != NO_REGS)
+ sorted_global_cans = yara_allocate (sizeof (can_t) * cans_num);
+ for (i = 0; i < final_reg_class_cover_size; i++)
+ {
+ cover_class = final_reg_class_cover [i];
+ cover_class_cans_num [cover_class] = 0;
+ cover_class_cans [cover_class] = NULL;
+ }
+ for (i = 0; i < cans_num; i++)
+ if (CAN_GLOBAL_P (cans [i])
+ && (cover_class = CAN_COVER_CLASS (cans [i])) != NO_REGS)
+ cover_class_cans_num [cover_class]++;
+ for (num = i = 0; i < final_reg_class_cover_size; i++)
+ {
+ cover_class = final_reg_class_cover [i];
+ if (cover_class_cans_num [cover_class] != 0)
{
- size
- = reg_class_nregs [curr_global_can_cover_class] [CAN_MODE (can)];
- gcc_assert (size > 0);
- if (i + size > available_class_regs [curr_global_can_cover_class])
- {
- qsort (sorted_global_cans, cans_num_to_sort, sizeof (can_t),
- global_can_compare);
- cans_num_to_sort = global_cans_num - n;
- can = sorted_global_cans [0];
- size = (reg_class_nregs [curr_global_can_cover_class]
- [CAN_MODE (can)]);
- gcc_assert
- (CAN_IN_GRAPH_P (can)
- && CAN_COVER_CLASS (can) == curr_global_can_cover_class);
+ cover_class_cans [cover_class] = sorted_global_cans + num;
+ num += cover_class_cans_num [cover_class];
+ cover_class_cans_num [cover_class] = 0;
+ }
+ }
+ gcc_assert (num <= cans_num);
+ for (i = 0; i < cans_num; i++)
+ if (CAN_GLOBAL_P (cans [i])
+ && (cover_class = CAN_COVER_CLASS (cans [i])) != NO_REGS)
+ cover_class_cans [cover_class] [cover_class_cans_num [cover_class]++]
+ = cans [i];
+ first_non_empty_bucket_num = 0;
+ for (;;)
+ {
+ if (colorable_can_bucket != NULL)
+ {
+ can = colorable_can_bucket;
+ cover_class = CAN_COVER_CLASS (can);
+ if (cover_class != NO_REGS)
+ size = reg_class_nregs [cover_class] [CAN_MODE (can)];
+ gcc_assert (CAN_LEFT_CONFLICTS_NUM (can)
+ + reg_class_nregs [cover_class] [CAN_MODE (can)]
+ <= available_class_regs [cover_class]);
+ bucket_ptr = &colorable_can_bucket;
+ }
+ else
+ {
+ for (i = first_non_empty_bucket_num;
+ i < (int) VARRAY_ACTIVE_SIZE (bucket_varray);
+ i++)
+ if (VARRAY_GENERIC_PTR (bucket_varray, i) != NULL)
+ break;
+ if (i >= (int) VARRAY_ACTIVE_SIZE (bucket_varray))
+ break;
+ first_non_empty_bucket_num = i;
+ bucket_ptr = (can_t *) &VARRAY_GENERIC_PTR (bucket_varray, i);
+ can = *bucket_ptr;
+ gcc_assert (CAN_LEFT_CONFLICTS_NUM (can) == i);
+ cover_class = CAN_COVER_CLASS (can);
+ if (cover_class != NO_REGS)
+ {
+ size = reg_class_nregs [cover_class] [CAN_MODE (can)];
+ gcc_assert (size > 0);
+ if (i + size > available_class_regs [cover_class])
+ {
+ num = cover_class_cans_num [cover_class];
+ gcc_assert (num > 0);
+ can_vec = cover_class_cans [cover_class];
+ qsort (can_vec, num, sizeof (can_t), global_can_compare);
+ for (num--; ! CAN_IN_GRAPH_P (can_vec [num]); num--)
+ ;
+ gcc_assert (num >= 0);
+ cover_class_cans_num [cover_class] = num;
+ can = can_vec [0];
+ cover_class_cans [cover_class]++;
+ size = reg_class_nregs [cover_class] [CAN_MODE (can)];
+ gcc_assert (CAN_IN_GRAPH_P (can)
+ && CAN_COVER_CLASS (can) == cover_class
+ && (CAN_LEFT_CONFLICTS_NUM (can) + size
+ > available_class_regs [cover_class]));
+ bucket_ptr = ((can_t *) &VARRAY_GENERIC_PTR
+ (bucket_varray, CAN_LEFT_CONFLICTS_NUM (can)));
+ }
}
}
- delete_can_from_bucket (can, &bucket_varray,
- CAN_LEFT_CONFLICTS_NUM (can));
+ delete_can_from_bucket (can, bucket_ptr);
CAN_IN_GRAPH_P (can) = false;
VARRAY_PUSH_GENERIC_PTR (global_stack_varray, can);
- if (curr_global_can_cover_class == NO_REGS)
+ if (cover_class == NO_REGS)
continue;
can_vec = CAN_CONFLICT_CAN_VEC (can);
for (i = 0; (conflict_can = can_vec [i]) != NULL; i++)
{
- if (curr_global_can_cover_class != CAN_COVER_CLASS (conflict_can))
+ if (cover_class != CAN_COVER_CLASS (conflict_can))
continue;
if (CAN_IN_GRAPH_P (conflict_can))
{
- delete_can_from_bucket (conflict_can, &bucket_varray,
- CAN_LEFT_CONFLICTS_NUM (conflict_can));
+ conflicts_num = CAN_LEFT_CONFLICTS_NUM (conflict_can);
+ conflict_size
+ = reg_class_nregs [cover_class] [CAN_MODE (conflict_can)];
+ gcc_assert (CAN_LEFT_CONFLICTS_NUM (conflict_can) >= size);
CAN_LEFT_CONFLICTS_NUM (conflict_can) -= size;
- add_can_to_bucket (conflict_can, &bucket_varray,
- CAN_LEFT_CONFLICTS_NUM (conflict_can));
+ if (conflicts_num + conflict_size
+ <= available_class_regs [cover_class])
+ continue;
+ delete_can_from_bucket
+ (conflict_can,
+ (can_t *) &VARRAY_GENERIC_PTR (bucket_varray, conflicts_num));
+ conflicts_num = CAN_LEFT_CONFLICTS_NUM (conflict_can);
+ if (conflicts_num + conflict_size
+ <= available_class_regs [cover_class])
+ add_can_to_bucket (conflict_can, &colorable_can_bucket);
+ else
+ {
+ if (first_non_empty_bucket_num > conflicts_num)
+ first_non_empty_bucket_num = conflicts_num;
+ add_can_to_bucket
+ (conflict_can,
+ (can_t *) &VARRAY_GENERIC_PTR (bucket_varray,
+ conflicts_num));
+ }
}
}
}
@@ -1703,7 +1766,6 @@ pop_globals_from_stack (void)
static void
global_can_alloc (void)
{
- {
int i, j, hard_regno, conflict_cans_size;
can_t can, conflict_can;
can_t *can_vec;
@@ -1712,6 +1774,7 @@ global_can_alloc (void)
global_cans_num = 0;
/* Put the global cans into the corresponding buckets. */
+ colorable_can_bucket = NULL;
VARRAY_GENERIC_PTR_NOGC_INIT (bucket_varray, cans_num,
"buckets of global cans");
for (i = 0; i < cans_num; i++)
@@ -1748,7 +1811,13 @@ global_can_alloc (void)
CAN_LEFT_CONFLICTS_NUM (can) = conflict_cans_size;
while (conflict_cans_size >= (int) VARRAY_ACTIVE_SIZE (bucket_varray))
VARRAY_PUSH_GENERIC_PTR (bucket_varray, NULL);
- add_can_to_bucket (can, &bucket_varray, conflict_cans_size);
+ if (conflict_cans_size + reg_class_nregs [cover_class] [CAN_MODE (can)]
+ <= available_class_regs [cover_class])
+ add_can_to_bucket (can, &colorable_can_bucket);
+ else
+ add_can_to_bucket (can,
+ (can_t *) &VARRAY_GENERIC_PTR (bucket_varray,
+ conflict_cans_size));
}
VARRAY_GENERIC_PTR_NOGC_INIT (global_stack_varray, global_cans_num,
"stack of global cans");
@@ -1756,7 +1825,6 @@ global_can_alloc (void)
pop_globals_from_stack ();
VARRAY_FREE (global_stack_varray);
VARRAY_FREE (bucket_varray);
- }
}
Index: yara-final.c
===================================================================
--- yara-final.c (revision 112301)
+++ yara-final.c (working copy)
@@ -66,7 +66,7 @@ static void add_copy_list (copy_t);
static void modify_insn (rtx, bool);
static void clean_insn (rtx);
-static void align_or_allocate_stack_memory (bool);
+static void allocate_stack_memory (void);
static bitmap insn_to_be_removed_p;
@@ -1631,6 +1631,14 @@ eliminate_regs (rtx x)
return x;
}
+/* Offset between frame and stack memory slot area after the
+ allocation. */
+static HOST_WIDE_INT final_stack_memory_start_frame_offset;
+
+/* Size of stack slots after allocation of all necessary stack
+ memory. */
+static int final_rounded_slot_memory_size;
+
static rtx
get_allocno_memory_slot_rtx (struct memory_slot *memory_slot, int offset,
enum machine_mode mode,
@@ -1652,17 +1660,26 @@ get_allocno_memory_slot_rtx (struct memo
{
HOST_WIDE_INT disp;
+#ifdef FRAME_GROWS_DOWNWARD
if (stack_frame_pointer_can_be_eliminated_p
&& obligatory_stack_frame_pointer_elimination_p)
- disp = (stack_memory_start_frame_offset ()
- + frame_stack_pointer_offset);
+ disp = (frame_stack_pointer_offset
+ + final_stack_memory_start_frame_offset
+ + memory_slot->start - memory_slot->size + 2
+ - final_rounded_slot_memory_size);
else
- disp = (stack_memory_start_frame_offset ()
- + frame_hard_frame_pointer_offset);
-#ifdef FRAME_GROWS_DOWNWARD
- disp -= memory_slot->start;
+ disp = (final_stack_memory_start_frame_offset
+ + frame_hard_frame_pointer_offset - memory_slot->start);
#else
- disp += memory_slot->start;
+ if (stack_frame_pointer_can_be_eliminated_p
+ && obligatory_stack_frame_pointer_elimination_p)
+ disp = (frame_stack_pointer_offset
+ - final_stack_memory_start_frame_offset
+ + memory_slot->start + memory_slot->size
+ - final_rounded_slot_memory_size);
+ else
+ disp = (final_stack_memory_start_frame_offset
+ + frame_hard_frame_pointer_offset + memory_slot->start);
#endif
mem = gen_rtx_MEM (mode,
gen_rtx_PLUS
@@ -1998,8 +2015,6 @@ emit_copy (copy_t cp)
#endif
elimination_subst_reg = gen_allocno_reg_rtx (Pmode, elim->to, dst);
offset = elim->offset;
- if (elim->to == STACK_POINTER_REGNUM)
- offset += slot_memory_size;
interm_elimination_regno
= INSN_ALLOCNO_INTERM_ELIMINATION_REGNO (dst);
regno = ALLOCNO_REGNO (dst);
@@ -2837,8 +2852,6 @@ modify_insn (rtx insn, bool non_operand_
}
interm_regno = INSN_ALLOCNO_INTERM_ELIMINATION_REGNO (a);
offset = elim->offset;
- if (elim->to == STACK_POINTER_REGNUM)
- offset += slot_memory_size;
if (interm_regno < 0)
to = elim->to;
else
@@ -2946,7 +2959,7 @@ clean_insn (rtx insn)
/* Allign stack or allocate memory on the stack for all stack slots
currently existing. */
static void
-align_or_allocate_stack_memory (bool align_p)
+allocate_stack_memory (void)
{
int align;
@@ -2957,10 +2970,13 @@ align_or_allocate_stack_memory (bool ali
boundary. */
if ((unsigned) align * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
align = (int) PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
- (void) assign_stack_local (BLKmode, (align_p ? 0 : slot_memory_size),
+ (void) assign_stack_local (BLKmode, 0, align * BITS_PER_UNIT);
+ final_stack_memory_start_frame_offset
+ = get_stack_memory_start_frame_offset ();
+ (void) assign_stack_local (BLKmode, slot_memory_size,
align * BITS_PER_UNIT);
- if (align_p)
- update_elim_offsets ();
+ final_rounded_slot_memory_size = rounded_slot_memory_size ();
+ update_elim_offsets ();
}
@@ -2982,7 +2998,7 @@ yara_rewrite (void)
finish_locations ();
}
no_new_pseudos = 0;
- align_or_allocate_stack_memory (true);
+ allocate_stack_memory ();
FOR_EACH_BB (bb)
{
bound = NEXT_INSN (BB_END (bb));
@@ -3042,7 +3058,6 @@ yara_rewrite (void)
}
commit_edge_insertions ();
no_new_pseudos = 1;
- align_or_allocate_stack_memory (false);
if ((YARA_PARAMS & YARA_NO_COPY_SYNC) == 0)
yara_free_bitmap (insn_to_be_removed_p);
}
Index: yara.c
===================================================================
--- yara.c (revision 112301)
+++ yara.c (working copy)
@@ -58,9 +58,6 @@ HARD_REG_SET reg_mode_hard_regset [FIRST
int memory_move_cost [MAX_MACHINE_MODE] [N_REG_CLASSES] [2];
int register_move_cost [MAX_MACHINE_MODE] [N_REG_CLASSES] [N_REG_CLASSES];
bool class_subset_p [N_REG_CLASSES] [N_REG_CLASSES];
-short class_hard_regs [N_REG_CLASSES] [FIRST_PSEUDO_REGISTER];
-int class_hard_regs_num [N_REG_CLASSES];
-short class_hard_reg_index [N_REG_CLASSES] [FIRST_PSEUDO_REGISTER];
@@ -140,19 +137,9 @@ set_class_subset_and_move_costs (void)
-HARD_REG_SET no_alloc_regs;
-
-static void
-set_non_alloc_regs (void)
-{
- COPY_HARD_REG_SET (no_alloc_regs, fixed_reg_set);
-
- if (! stack_frame_pointer_can_be_eliminated_p
- || ! obligatory_stack_frame_pointer_elimination_p)
- SET_HARD_REG_BIT (no_alloc_regs, HARD_FRAME_POINTER_REGNUM);
-}
-
-
+short class_hard_regs [N_REG_CLASSES] [FIRST_PSEUDO_REGISTER];
+int class_hard_regs_num [N_REG_CLASSES];
+short class_hard_reg_index [N_REG_CLASSES] [FIRST_PSEUDO_REGISTER];
#ifdef REG_ALLOC_ORDER
static int hard_reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
@@ -211,6 +198,18 @@ set_up_available_class_regs (void)
}
}
+HARD_REG_SET no_alloc_regs;
+
+void
+set_non_alloc_regs (bool use_hard_frame_p)
+{
+ COPY_HARD_REG_SET (no_alloc_regs, fixed_reg_set);
+ if (! use_hard_frame_p)
+ SET_HARD_REG_BIT (no_alloc_regs, HARD_FRAME_POINTER_REGNUM);
+ set_up_class_hard_regs ();
+ set_up_available_class_regs ();
+}
+
static void print_disposition (FILE *);
@@ -393,9 +392,7 @@ yara_init_once (void)
set_inner_mode ();
set_reg_mode_hard_regset ();
set_class_subset_and_move_costs ();
- set_non_alloc_regs ();
- set_up_class_hard_regs ();
- set_up_available_class_regs ();
+ set_non_alloc_regs (flag_omit_frame_pointer);
yara_ir_init_once ();
yara_trans_init_once ();
yara_color_init_once ();
Index: yara-trans.c
===================================================================
--- yara-trans.c (revision 112301)
+++ yara-trans.c (working copy)
@@ -100,7 +100,8 @@ static void finish_memory_slots (void);
static void set_up_temp_mems_and_addresses (void);
static rtx get_temp_const_int (HOST_WIDE_INT);
static rtx get_temp_disp (rtx, HOST_WIDE_INT);
-static rtx get_temp_stack_memory_slot_rtx (enum machine_mode, HOST_WIDE_INT);
+static rtx get_temp_stack_memory_slot_rtx (enum machine_mode, HOST_WIDE_INT,
+ int);
static enum reg_class get_allocno_reg_class (allocno_t);
static int non_pseudo_allocno_copy_cost (allocno_t);
@@ -533,10 +534,25 @@ decrease_align_count (int align)
}
}
+/* Return size of the aligned simulated stack area. */
+HOST_WIDE_INT
+rounded_slot_memory_size (void)
+{
+ int align;
+
+ align = slot_memory_alignment;
+ /* Ignore alignment we can't do with expected alignment of the
+ boundary. */
+ if ((unsigned) align * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
+ align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
+
+ return CEIL_ROUND (slot_memory_size, (unsigned) align);
+}
+
/* Return the displacement of the simulated stack area start relative
to frame pointer. */
HOST_WIDE_INT
-stack_memory_start_frame_offset (void)
+get_stack_memory_start_frame_offset (void)
{
int align, size;
int frame_off, frame_alignment, frame_phase;
@@ -1316,7 +1332,8 @@ get_temp_disp (rtx disp, HOST_WIDE_INT o
}
static rtx
-get_temp_stack_memory_slot_rtx (enum machine_mode mode, HOST_WIDE_INT disp)
+get_temp_stack_memory_slot_rtx (enum machine_mode mode, HOST_WIDE_INT disp,
+ int size)
{
rtx mem;
HOST_WIDE_INT offset;
@@ -1326,20 +1343,25 @@ get_temp_stack_memory_slot_rtx (enum mac
{
/* disp is addressed from the stack bottom in this case. */
mem = temp_stack_disp_mem [mode];
- offset = (stack_memory_start_frame_offset ()
- - frame_stack_pointer_offset);
+ offset = (frame_stack_pointer_offset + disp
+ - rounded_slot_memory_size ());
+#ifdef FRAME_GROWS_DOWNWARD
+ offset += get_stack_memory_start_frame_offset () - size + 2;
+#else
+ offset += size - get_stack_memory_start_frame_offset ();
+#endif
}
else
{
mem = temp_hard_frame_disp_mem [mode];
- offset = (stack_memory_start_frame_offset ()
- - frame_hard_frame_pointer_offset);
- }
+ offset = (get_stack_memory_start_frame_offset ()
+ + frame_hard_frame_pointer_offset);
#ifdef FRAME_GROWS_DOWNWARD
- offset -= disp;
+ offset -= disp;
#else
- offset += disp;
+ offset += disp;
#endif
+ }
XEXP (XEXP (mem, 0), 1) = get_temp_const_int (disp);
return mem;
}
@@ -1769,7 +1791,8 @@ assign_copy_secondary (copy_t cp)
{
x = slot->mem;
if (x == NULL)
- x = get_temp_stack_memory_slot_rtx (mode, slot->start);
+ x = get_temp_stack_memory_slot_rtx (mode, slot->start,
+ slot->size);
}
else
gcc_unreachable ();
Index: yara-ir.c
===================================================================
--- yara-ir.c (revision 112301)
+++ yara-ir.c (working copy)
@@ -647,6 +647,15 @@ modify_offsets_and_frame_pointer_needed
obligatory_stack_frame_pointer_elimination_p = ep->obligatory;
}
}
+ /* Check that NO_ALLOC_REGS should be changed. */
+ if (stack_frame_pointer_can_be_eliminated_p
+ && obligatory_stack_frame_pointer_elimination_p)
+ {
+ if (TEST_HARD_REG_BIT (no_alloc_regs, HARD_FRAME_POINTER_REGNUM))
+ set_non_alloc_regs (true);
+ }
+ else if (! TEST_HARD_REG_BIT (no_alloc_regs, HARD_FRAME_POINTER_REGNUM))
+ set_non_alloc_regs (false);
}
static void