This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi, Vladimir attachment is the ira dump of the case Shiva 2013/4/17 Vladimir Makarov <vmakarov@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).
Attachment:
test2.c.208r.ira
Description: Binary data
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |