ira_assert (hard_regno >= 0);
for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
if (!allocated_hardreg_p[hard_regno + i]
+ && ira_hard_regno_nrefs[hard_regno + i] == 0
&& !crtl->abi->clobbers_full_reg_p (hard_regno + i)
&& !LOCAL_REGNO (hard_regno + i))
nregs++;
/* Flag of that the above array has been initialized. */
bool x_ira_prohibited_mode_move_regs_initialized_p;
+
+ /* Number of real occurences of hard regs before IRA. */
+ size_t x_ira_hard_regno_nrefs[FIRST_PSEUDO_REGISTER];
};
extern class target_ira_int default_target_ira_int;
(this_target_ira_int->x_ira_reg_class_superunion)
#define ira_prohibited_mode_move_regs \
(this_target_ira_int->x_ira_prohibited_mode_move_regs)
+#define ira_hard_regno_nrefs \
+ (this_target_ira_int->x_ira_hard_regno_nrefs)
\f
/* ira.cc: */
\f
-/* Set up the array above. */
+/* Set up array ira_hard_regno_allocno_class. */
static void
setup_hard_regno_aclass (void)
{
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
-#if 1
ira_hard_regno_allocno_class[i]
= (TEST_HARD_REG_BIT (no_unit_alloc_regs, i)
? NO_REGS
: ira_allocno_class_translate[REGNO_REG_CLASS (i)]);
-#else
- int j;
- enum reg_class cl;
- ira_hard_regno_allocno_class[i] = NO_REGS;
- for (j = 0; j < ira_allocno_classes_num; j++)
- {
- cl = ira_allocno_classes[j];
- if (ira_class_hard_reg_index[cl][i] >= 0)
- {
- ira_hard_regno_allocno_class[i] = cl;
- break;
- }
- }
-#endif
}
}
/* Set to true while in IRA. */
bool ira_in_progress = false;
+/* Set up array ira_hard_regno_nrefs. */
+static void
+setup_hard_regno_nrefs (void)
+{
+ int i;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ ira_hard_regno_nrefs[i] = 0;
+ for (df_ref use = DF_REG_USE_CHAIN (i);
+ use != NULL;
+ use = DF_REF_NEXT_REG (use))
+ if (DF_REF_CLASS (use) != DF_REF_ARTIFICIAL
+ && !(DF_REF_INSN_INFO (use) && DEBUG_INSN_P (DF_REF_INSN (use))))
+ ira_hard_regno_nrefs[i]++;
+ for (df_ref def = DF_REG_DEF_CHAIN (i);
+ def != NULL;
+ def = DF_REF_NEXT_REG (def))
+ if (DF_REF_CLASS (def) != DF_REF_ARTIFICIAL
+ && !(DF_REF_INSN_INFO (def) && DEBUG_INSN_P (DF_REF_INSN (def))))
+ ira_hard_regno_nrefs[i]++;
+ }
+}
+
/* This is the main entry of IRA. */
static void
ira (FILE *f)
edge e;
bool output_jump_reload_p = false;
+ setup_hard_regno_nrefs ();
if (ira_use_lra_p)
{
/* First put potential jump output reloads on the output edges
--- /dev/null
+/* { dg-do compile { target { ia32 } } } */
+/* { dg-options "-O2 -fpic" } */
+extern void crosscall2 (void (*fn) (void *, int), void *, int);
+extern void _cgo_panic (void *, int);
+extern void _cgo_allocate (void *, int);
+
+void
+callPanic (void)
+{
+ struct { const char *p; } a;
+ a.p = "panic from C";
+ crosscall2 (_cgo_panic, &a, sizeof a);
+ *(int*) 1 = 1;
+}
+
+/* { dg-final { scan-assembler "__x86.get_pc_thunk.bx" } } */
}
/* Before adjust_insn:
- 26: [--sp:DI]=bx:DI
- 29: bx:DI=[sp:DI++]
+ 26: [--sp:DI]=b[px]:DI
+ 29: b[px]:DI=[sp:DI++]
after adjust_insn:
- 26: {[argp:DI-0x10]=bx:DI;sp:DI=argp:DI-0x10;}
- 29: {bx:DI=[argp:DI-0x10];sp:DI=argp:DI-0x8;} */
+ 26: {[argp:DI-0x10]=b[px]:DI;sp:DI=argp:DI-0x10;}
+ 29: {b[px]:DI=[argp:DI-0x10];sp:DI=argp:DI-0x8;} */
-/* { dg-final { scan-rtl-dump-times {[0-9][0-9]*: \{\[argp:DI-0x10\]=bx:DI;sp:DI=argp:DI-0x10;\}} 1 "vartrack" } } */
+/* { dg-final { scan-rtl-dump-times {[0-9][0-9]*: \{\[argp:DI-0x10\]=b[px]:DI;sp:DI=argp:DI-0x10;\}} 1 "vartrack" } } */
-/* { dg-final { scan-rtl-dump-times {[0-9][0-9]*: \{bx:DI=\[argp:DI-0x10\];sp:DI=argp:DI-0x8;\}} 1 "vartrack" } } */
+/* { dg-final { scan-rtl-dump-times {[0-9][0-9]*: \{b[px]:DI=\[argp:DI-0x10\];sp:DI=argp:DI-0x8;\}} 1 "vartrack" } } */