Full test2.c.209r.reload is about 296kb and i can't send successfully. Is there another way to send the dump file?
Shiva 2013/4/18 Shiva Chen <shiva0...@gmail.com>: > Hi, Vladimir > > attachment is the ira dump of the case > > Shiva > > 2013/4/17 Vladimir Makarov <vmaka...@redhat.com>: >> On 13-04-15 1:20 AM, shiva Chen wrote: >>> >>> HI, >>> >>> I'm trying to port a new 32bit target to GCC 4.8.0 with LRA enabled >>> >>> There is an error case which generates following RTL >>> >>> >>> (insn 536 267 643 3 (set (reg/f:SI 0 $r0 [477]) <== r477 assign to r0 >>> (plus:SI (reg/f:SI 31 $sp) >>> (const_int 112 [0x70]))) test2.c:95 64 {*addsi3} >>> (nil)) >>> (insn 643 536 537 3 (set (reg/f:SI 0 $r0 [565]) <== r565 assign to >>> r0, and corrupt the usage of r477 >>> (reg/f:SI 31 $sp)) test2.c:95 44 {*movsi} >>> (nil)) >>> (insn 537 643 538 3 (set (reg/v:SI 13 $r13 [orig:61 i14 ] [61]) >>> (mem/c:SI (plus:SI (reg/f:SI 0 $r0 [565]) <== use r565 >>> (const_int 136 [0x88])) [5 %sfp+24 S4 A32])) test2.c:95 >>> 39 >>> {*load_si} >>> (expr_list:REG_DEAD (reg/f:SI 0 $r0 [565]) >>> (nil))) >>> ... >>> (insn 539 540 270 3 (set (reg:SI 0 $r0 [479]) >>> (plus:SI (reg/f:SI 0 $r0 [477]) >>> (reg:SI 5 $r5 [480]))) test2.c:95 62 {*add_16bit} >>> (expr_list:REG_DEAD (reg:SI 5 $r5 [480]) >>> (expr_list:REG_DEAD (reg/f:SI 0 $r0 [477]) <== use r477 which >>> should be $sp +112 >>> >>> Note that the live ranges of r477 and r565 are overlapped but assigned >>> same register $r0. (r31 is stack pointer) >>> >>> By tracing LRA process, I noticed that when r477 is created, >>> the lra_reg_info[r477].val = lra_reg_info[r31] due to (set r477 r31). >>> But after lra_eliminate(), the stack offset changes and >>> r477 is equal to r31+112 instead. >>> >>> In next lra-iteration round, r565 is created, and r565 = r31. >>> >>> In that case, register content of r477 should treat as not equal to >>> r565 due to eliminate offset have been changed. >>> >>> Otherwise, r565 and r477 may assign to same hard register. >>> >>> >>> To recognize that, I record the eliminate offset when the pseudo >>> register have been created. >>> >>> Register content are the same only when lra_reg_info[].val and >>> lra_reg_info[].offset are equal. >>> >>> >>> gcc/lra-assigns.c | 6 ++++-- >>> gcc/lra-int.h | 2 ++ >>> gcc/lra.c | 12 +++++++++++- >>> 3 files changed, 17 insertions(+), 3 deletions(-) >>> >>> diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c >>> index b204513..daf0aa9 100644 >>> --- a/gcc/lra-assigns.c >>> +++ b/gcc/lra-assigns.c >>> @@ -448,7 +448,7 @@ find_hard_regno_for (int regno, int *cost, int >>> try_only_hard_regno) >>> int hr, conflict_hr, nregs; >>> enum machine_mode biggest_mode; >>> unsigned int k, conflict_regno; >>> - int val, biggest_nregs, nregs_diff; >>> + int offset, val, biggest_nregs, nregs_diff; >>> enum reg_class rclass; >>> bitmap_iterator bi; >>> bool *rclass_intersect_p; >>> @@ -508,9 +508,11 @@ find_hard_regno_for (int regno, int *cost, int >>> try_only_hard_regno) >>> #endif >>> sparseset_clear_bit (conflict_reload_and_inheritance_pseudos, regno); >>> val = lra_reg_info[regno].val; >>> + offset = lra_reg_info[regno].offset; >>> CLEAR_HARD_REG_SET (impossible_start_hard_regs); >>> EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, >>> conflict_regno) >>> - if (val == lra_reg_info[conflict_regno].val) >>> + if ((val == lra_reg_info[conflict_regno].val) >>> + && (offset == lra_reg_info[conflict_regno].offset)) >>> { >>> conflict_hr = live_pseudos_reg_renumber[conflict_regno]; >>> nregs = (hard_regno_nregs[conflict_hr] >>> diff --git a/gcc/lra-int.h b/gcc/lra-int.h >>> index 98f2ff7..8ae4eb0 100644 >>> --- a/gcc/lra-int.h >>> +++ b/gcc/lra-int.h >>> @@ -116,6 +116,8 @@ struct lra_reg >>> /* Value holding by register. If the pseudos have the same >>> value >>> they do not conflict. */ >>> int val; >>> + /* Eliminate offset of the pseduo have been created. */ >>> + int offset; >>> /* These members are set up in lra-lives.c and updated in >>> lra-coalesce.c. */ >>> /* The biggest size mode in which each pseudo reg is referred in >>> diff --git a/gcc/lra.c b/gcc/lra.c >>> index 9df24b5..69962be 100644 >>> --- a/gcc/lra.c >>> +++ b/gcc/lra.c >>> @@ -194,7 +194,17 @@ lra_create_new_reg (enum machine_mode md_mode, >>> rtx original, >>> new_reg >>> = lra_create_new_reg_with_unique_value (md_mode, original, rclass, >>> title); >>> if (original != NULL_RTX && REG_P (original)) >>> - lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO >>> (original)].val; >>> + { >>> + lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO >>> (original)].val; >>> + >>> + rtx x = lra_eliminate_regs (original, VOIDmode, NULL_RTX); >>> + >>> + if (GET_CODE (x) == PLUS >>> + && GET_CODE (XEXP (x, 1)) == CONST_INT) >>> + lra_reg_info[REGNO (new_reg)].offset = INTVAL (XEXP (x, 1)); >>> + else >>> + lra_reg_info[REGNO (new_reg)].offset = 0; >>> + } >>> return new_reg; >>> } >>> >>> -- >>> 1.7.9.5 >>> >>> >>> Comments? >>> >>> >> Thanks for working on it, Shiva. Could you send me full dump for lra (and >> ira if possible) for better understanding the problem situation. It is hard >> for me to say now that your solution is complete (e.g. offsets can be >> changed again).