Better late than never...
Ok, I think I nailed this, the simplest test case is:
register unsigned long regval asm("g5");
extern void cond_resched(void);
unsigned int var;
void *expression(unsigned long regval)
{
void *ret;
__asm__("" : "=r" (ret) : "0" (&var));
return ret + regval;
}
void func(void **pp)
{
int i;
for (i = 0; i < 56; i++) {
cond_resched();
*pp = expression(regval);
}
}
If you build that with "gcc-4.2 -m64 -Os -S -o test.s test.c"
the compiler moves expression() outside of the loop because it
things it is invariant.
The dataflow pass doesn't mark global registers correctly, and
the new thing in gcc-4.2.x vs. gcc-4.1.x is that it uses the
dataflow pass for the loop optimizers.
I've bootstrapped and regression tested the following gcc-4.2.x
patch, I'll test some test kernel builds after I get some sleep.
--- ./gcc/df-scan.c.ORIG 2007-10-16 02:07:46.000000000 -0700
+++ ./gcc/df-scan.c 2007-10-16 23:00:32.000000000 -0700
@@ -1584,12 +1584,19 @@ df_insn_refs_record (struct dataflow *df
so they are recorded as used. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (global_regs[i])
- df_uses_record (dflow, ®no_reg_rtx[i],
- DF_REF_REG_USE, bb, insn,
- 0);
+ {
+ df_uses_record (dflow, ®no_reg_rtx[i],
+ DF_REF_REG_USE, bb, insn, 0);
+ df_ref_record (dflow, regno_reg_rtx[i], ®no_reg_rtx[i],
+ bb, insn, DF_REF_REG_DEF, 0, true);
+ }
+
EXECUTE_IF_SET_IN_BITMAP (df_invalidated_by_call, 0, ui, bi)
- df_ref_record (dflow, regno_reg_rtx[ui], ®no_reg_rtx[ui],
bb,
- insn, DF_REF_REG_DEF, DF_REF_MAY_CLOBBER, false);
+ {
+ if (!global_regs[ui])
+ df_ref_record (dflow, regno_reg_rtx[ui],
®no_reg_rtx[ui], bb,
+ insn, DF_REF_REG_DEF, DF_REF_MAY_CLOBBER,
false);
+ }
}
}
-
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html