Re: Help-The possible places where insn is splitted in greg pass
2010/1/27 fanqifei fanqi...@gmail.com: 2010/1/25 Ulrich Weigand uweig...@de.ibm.com: Qifei Fan wrote: But insn#479 is not recognized by recog() in insn-recog.c and the compilation failed. (recog only recognizes RTL defined in md, right?) Here the backtrace is reload---cleanup_subreg_operands---extract_insn_cached---extract_insn-= --recog_memoized---recog. There is no machine instruction(r3=3Dr1*4+r2) match the pattern of insn#479. Though there is pattern r3=3Dmem(r1*4+r2). I don=92t quite understand the generation of reload information. There's two issues here. The first issue is that reload makes the fundamental assumption that everything that is a valid address, can be loaded into a register as well, if necessary. On many platforms this is true, either because there is some sort of load address instruction, or because the form of valid addresses matches standard arithmetic instruction patterns. Reload will simply emit a naked set of some register to the address -- if the back-end doesn't support that, you'll get the failure you saw. If this doesn't work on your particular platform, you could either try to set things up so that reload never thinks it needs to reload an address (but this may be difficult to achieve). The safe option would be to tell reload how to achieve computing an address by providing a secondary reload pattern. See e.g. s390_secondary_reload (in config/s390/s390.c) and the associated reloadmode_plus pattern. The second issue is as you notice here: Actually the second reload is not needed if there is already the first relo= ad. If (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]) is replaced by (reg:SI 12 a12), then (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (reg:SI 12 a12) ) is a valid memory address. But in function find_reloads, I can=92t find the related code that deciding whether the second reload should be generated by regarding the previous reload. The function is too complex. :-( The first reload, loading sp + 96 into a register, is generated from within find_reloads_address. After this is done, it is assumed that the address is now valid. However, something else later in find_reloads apparently assumes there is still some problem with the operand, and decides to reload the whole address. It is hard to say exactly what the problem is, without seeing the insn constraints, but the most likely cause seems to be that this instruction pattern does not have a general m constraint, but a more restricted memory constraint. If this is the case, the back-end procedure called to verify the constraint probably rejects it. This runs into another fundamental assumption reload makes: it assumes such procedures take other actions done by reload into account implicitly. This means the constraint checker ought to *accept* addresses of the form reg*const + (sp + const) because it ought to know that reload will already load the (sp + const) into a register anyway. If this is *not* the case, please send me the instruction pattern and constraints for the insn pattern that matched insn 320 before reload so I can investigate in more detail. (Please note that I'm currently travelling with restricted access to email, so it might be a couple of days before I'm able to reply; sorry ...) Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE ulrich.weig...@de.ibm.com For the second issue, there is indeed a strict constraint(back-end procedure) that rejects the pattern. The back-end procedure is composed of macros like EXTRA_MEMORY_CONSTRAINT/EXTRA_CONSTRAINT. These macros are defined in config/cpu.c and used in around Line3376 of reload.c(gcc4.3.2). So it's the constraint checker's job to know whether reload will load the (sp+const) into a register and use such information to decide whether to accept the pattern or not, right? Is there any other architecture which checks address by using previous determined reload info? I think this may be the proper way to resolve this problem. It may be easy to implement too. I will dig into all the issues and possible options, and provide more information later. As I am not familiar with it, it may take some time. Thanks very much!! -Qifei Fan I have modified the constraint checker in which previous generated reloads are considered. Now the error is gone, from the result of reload I can see that the reload is correct. However the instruction is not in the final assembly code. It may be optimized away. So I am not sure this change is really correct. -Qifei Fan
Re: Help-The possible places where insn is splitted in greg pass
2010/1/25 Ulrich Weigand uweig...@de.ibm.com: Qifei Fan wrote: But insn#479 is not recognized by recog() in insn-recog.c and the compilation failed. (recog only recognizes RTL defined in md, right?) Here the backtrace is reload---cleanup_subreg_operands---extract_insn_cached---extract_insn-= --recog_memoized---recog. There is no machine instruction(r3=3Dr1*4+r2) match the pattern of insn#479. Though there is pattern r3=3Dmem(r1*4+r2). I don=92t quite understand the generation of reload information. There's two issues here. The first issue is that reload makes the fundamental assumption that everything that is a valid address, can be loaded into a register as well, if necessary. On many platforms this is true, either because there is some sort of load address instruction, or because the form of valid addresses matches standard arithmetic instruction patterns. Reload will simply emit a naked set of some register to the address -- if the back-end doesn't support that, you'll get the failure you saw. If this doesn't work on your particular platform, you could either try to set things up so that reload never thinks it needs to reload an address (but this may be difficult to achieve). The safe option would be to tell reload how to achieve computing an address by providing a secondary reload pattern. See e.g. s390_secondary_reload (in config/s390/s390.c) and the associated reloadmode_plus pattern. The second issue is as you notice here: Actually the second reload is not needed if there is already the first relo= ad. If (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]) is replaced by (reg:SI 12 a12), then (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (reg:SI 12 a12) ) is a valid memory address. But in function find_reloads, I can=92t find the related code that deciding whether the second reload should be generated by regarding the previous reload. The function is too complex. :-( The first reload, loading sp + 96 into a register, is generated from within find_reloads_address. After this is done, it is assumed that the address is now valid. However, something else later in find_reloads apparently assumes there is still some problem with the operand, and decides to reload the whole address. It is hard to say exactly what the problem is, without seeing the insn constraints, but the most likely cause seems to be that this instruction pattern does not have a general m constraint, but a more restricted memory constraint. If this is the case, the back-end procedure called to verify the constraint probably rejects it. This runs into another fundamental assumption reload makes: it assumes such procedures take other actions done by reload into account implicitly. This means the constraint checker ought to *accept* addresses of the form reg*const + (sp + const) because it ought to know that reload will already load the (sp + const) into a register anyway. If this is *not* the case, please send me the instruction pattern and constraints for the insn pattern that matched insn 320 before reload so I can investigate in more detail. (Please note that I'm currently travelling with restricted access to email, so it might be a couple of days before I'm able to reply; sorry ...) Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE ulrich.weig...@de.ibm.com For the second issue, there is indeed a strict constraint(back-end procedure) that rejects the pattern. The back-end procedure is composed of macros like EXTRA_MEMORY_CONSTRAINT/EXTRA_CONSTRAINT. These macros are defined in config/cpu.c and used in around Line3376 of reload.c(gcc4.3.2). So it's the constraint checker's job to know whether reload will load the (sp+const) into a register and use such information to decide whether to accept the pattern or not, right? Is there any other architecture which checks address by using previous determined reload info? I think this may be the proper way to resolve this problem. It may be easy to implement too. I will dig into all the issues and possible options, and provide more information later. As I am not familiar with it, it may take some time. Thanks very much!! -Qifei Fan
Re: Help-The possible places where insn is splitted in greg pass
Qifei Fan wrote: But insn#479 is not recognized by recog() in insn-recog.c and the compilation failed. (recog only recognizes RTL defined in md, right?) Here the backtrace is reload---cleanup_subreg_operands---extract_insn_cached---extract_insn-= --recog_memoized---recog. There is no machine instruction(r3=3Dr1*4+r2) match the pattern of insn#479. Though there is pattern r3=3Dmem(r1*4+r2). I don=92t quite understand the generation of reload information. There's two issues here. The first issue is that reload makes the fundamental assumption that everything that is a valid address, can be loaded into a register as well, if necessary. On many platforms this is true, either because there is some sort of load address instruction, or because the form of valid addresses matches standard arithmetic instruction patterns. Reload will simply emit a naked set of some register to the address -- if the back-end doesn't support that, you'll get the failure you saw. If this doesn't work on your particular platform, you could either try to set things up so that reload never thinks it needs to reload an address (but this may be difficult to achieve). The safe option would be to tell reload how to achieve computing an address by providing a secondary reload pattern. See e.g. s390_secondary_reload (in config/s390/s390.c) and the associated reloadmode_plus pattern. The second issue is as you notice here: Actually the second reload is not needed if there is already the first relo= ad. If (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]) is replaced by (reg:SI 12 a12), then (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (reg:SI 12 a12) ) is a valid memory address. But in function find_reloads, I can=92t find the related code that deciding whether the second reload should be generated by regarding the previous reload. The function is too complex. :-( The first reload, loading sp + 96 into a register, is generated from within find_reloads_address. After this is done, it is assumed that the address is now valid. However, something else later in find_reloads apparently assumes there is still some problem with the operand, and decides to reload the whole address. It is hard to say exactly what the problem is, without seeing the insn constraints, but the most likely cause seems to be that this instruction pattern does not have a general m constraint, but a more restricted memory constraint. If this is the case, the back-end procedure called to verify the constraint probably rejects it. This runs into another fundamental assumption reload makes: it assumes such procedures take other actions done by reload into account implicitly. This means the constraint checker ought to *accept* addresses of the form reg*const + (sp + const) because it ought to know that reload will already load the (sp + const) into a register anyway. If this is *not* the case, please send me the instruction pattern and constraints for the insn pattern that matched insn 320 before reload so I can investigate in more detail. (Please note that I'm currently travelling with restricted access to email, so it might be a couple of days before I'm able to reply; sorry ...) Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE ulrich.weig...@de.ibm.com
Re: Help-The possible places where insn is splitted in greg pass
2010/1/16 fanqifei fanqi...@gmail.com: 2010/1/15 Ian Lance Taylor i...@google.com: There are many places where that insn could be generated, so it's pretty hard to answer your question as asked. I recommend setting a breakpoint on make_insn_raw if cfun-emit-x_cur_insn_uid == 479. Then a backtrace will show you what is creating the insn. Ian That insn was generated in subst_reloads() called by reload_as_needed in reload1.c. In greg pass, the instruction#320 needs to be splitted. The cpu supports the memory address mode mem(r1*4+r2). (insn 320 308 309 19 a.c:381 (set (reg:SI 207 [ variable.wrData ]) (mem/s:SI (plus:SI (mult:SI (reg:SI 204) (const_int 4 [0x4])) (reg/f:SI 234)) [5 variable.wrData+0 S4 A32])) 3 {movsi} (expr_list:REG_DEAD (reg:SI 204) (nil))) In find_reloads() (called by reload_as_needed()), following reload information was generated. (insn 320 308 309 19 a.c:381 (set (reg:SI 14 a14 [orig:207 variable.wrData ] [207]) (mem/s:SI (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]))) [5 variable.wrData+0 S4 A32])) 3 {movsi} (expr_list:REG_DEAD (reg:SI 9 a9 [204]) (nil))) Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60])) GENERAL_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1) reload_in_reg: (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60])) reload_reg_rtx: (reg:SI 12 a12) Reload 1: reload_in (SI) = (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]))) GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 1), inc by 4 reload_in_reg: (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]))) reload_reg_rtx: (reg:SI 12 a12) After find_reloads() called, emit_reload_insns() generated insns to reload operands. Then subst_reloads() substituted the reload regs using the replacement information. The insn list after subst_reloads(): (insn 475 308 477 19 a.c:381 (set (reg:SI 12 a12) (const_int 96 [0x60])) -1 (nil)) (insn 477 475 478 19 a.c:381 (set (reg:SI 12 a12) (reg/f:SI 16 SP)) -1 (nil)) (insn 478 477 479 19 a.c:381 (set (reg:SI 12 a12) (plus:SI (reg:SI 12 a12) (const_int 96 [0x60]))) -1 (expr_list:REG_EQUIV (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60])) (nil))) (insn 479 478 320 19 a.c:381 (set (reg:SI 12 a12) (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (reg:SI 12 a12))) -1 (nil)) (insn 320 479 481 19 a.c:381 (set (reg:SI 14 a14 [orig:207 variable.wrData ] [207]) (mem/s:SI (reg:SI 12 a12) [5 variable.wrData+0 S4 A32])) 3 {movsi} (expr_list:REG_DEAD (reg:SI 9 a9 [204]) (nil))) But insn#479 is not recognized by recog() in insn-recog.c and the compilation failed. (recog only recognizes RTL defined in md, right?) Here the backtrace is reload---cleanup_subreg_operands---extract_insn_cached---extract_insn---recog_memoized---recog. There is no machine instruction(r3=r1*4+r2) match the pattern of insn#479. Though there is pattern r3=mem(r1*4+r2). I don’t quite understand the generation of reload information. What can I do next? Thanks! Qifei Fan Actually the second reload is not needed if there is already the first reload. If (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]) is replaced by (reg:SI 12 a12), then (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (reg:SI 12 a12) ) is a valid memory address. But in function find_reloads, I can’t find the related code that deciding whether the second reload should be generated by regarding the previous reload. The function is too complex. :-( Qifei Fan
Re: Help-The possible places where insn is splitted in greg pass
2010/1/15 Ian Lance Taylor i...@google.com: There are many places where that insn could be generated, so it's pretty hard to answer your question as asked. I recommend setting a breakpoint on make_insn_raw if cfun-emit-x_cur_insn_uid == 479. Then a backtrace will show you what is creating the insn. Ian That insn was generated in subst_reloads() called by reload_as_needed in reload1.c. In greg pass, the instruction#320 needs to be splitted. The cpu supports the memory address mode mem(r1*4+r2). (insn 320 308 309 19 a.c:381 (set (reg:SI 207 [ variable.wrData ]) (mem/s:SI (plus:SI (mult:SI (reg:SI 204) (const_int 4 [0x4])) (reg/f:SI 234)) [5 variable.wrData+0 S4 A32])) 3 {movsi} (expr_list:REG_DEAD (reg:SI 204) (nil))) In find_reloads() (called by reload_as_needed()), following reload information was generated. (insn 320 308 309 19 a.c:381 (set (reg:SI 14 a14 [orig:207 variable.wrData ] [207]) (mem/s:SI (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]))) [5 variable.wrData+0 S4 A32])) 3 {movsi} (expr_list:REG_DEAD (reg:SI 9 a9 [204]) (nil))) Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60])) GENERAL_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1) reload_in_reg: (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60])) reload_reg_rtx: (reg:SI 12 a12) Reload 1: reload_in (SI) = (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]))) GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 1), inc by 4 reload_in_reg: (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60]))) reload_reg_rtx: (reg:SI 12 a12) After find_reloads() called, emit_reload_insns() generated insns to reload operands. Then subst_reloads() substituted the reload regs using the replacement information. The insn list after subst_reloads(): (insn 475 308 477 19 a.c:381 (set (reg:SI 12 a12) (const_int 96 [0x60])) -1 (nil)) (insn 477 475 478 19 a.c:381 (set (reg:SI 12 a12) (reg/f:SI 16 SP)) -1 (nil)) (insn 478 477 479 19 a.c:381 (set (reg:SI 12 a12) (plus:SI (reg:SI 12 a12) (const_int 96 [0x60]))) -1 (expr_list:REG_EQUIV (plus:SI (reg/f:SI 16 SP) (const_int 96 [0x60])) (nil))) (insn 479 478 320 19 a.c:381 (set (reg:SI 12 a12) (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (reg:SI 12 a12))) -1 (nil)) (insn 320 479 481 19 a.c:381 (set (reg:SI 14 a14 [orig:207 variable.wrData ] [207]) (mem/s:SI (reg:SI 12 a12) [5 variable.wrData+0 S4 A32])) 3 {movsi} (expr_list:REG_DEAD (reg:SI 9 a9 [204]) (nil))) But insn#479 is not recognized by recog() in insn-recog.c and the compilation failed. (recog only recognizes RTL defined in md, right?) Here the backtrace is reload---cleanup_subreg_operands---extract_insn_cached---extract_insn---recog_memoized---recog. There is no machine instruction(r3=r1*4+r2) match the pattern of insn#479. Though there is pattern r3=mem(r1*4+r2). I don’t quite understand the generation of reload information. What can I do next? Thanks! Qifei Fan
Re: Help-The possible places where insn is splitted in greg pass
fanqifei fanqi...@gmail.com writes: 2010/1/13 fanqifei fanqi...@gmail.com: Hi, I am working on a micro controller and trying to port gcc(4.3.2) for it. Not the compiling process runs into the following error: a.c: In function 'task': a.c:150: error: unrecognizable insn: (insn 479 478 320 19 a:381 (set (reg:SI 12 a12) (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (reg:SI 12 a12))) -1 (nil)) a.c:150: internal compiler error: in extract_insn, at recog.c:1990 Please submit a full bug report, ... This insn is generated in greg pass from another insn: (insn 320 308 309 19 a.c:381 (set (reg:SI 207 [ variable.wrData ]) (mem/s:SI (plus:SI (mult:SI (reg:SI 204) (const_int 4 [0x4])) (reg/f:SI 234)) [5 variable.wrData+0 S4 A32])) 3 {movsi} (expr_list:REG_DEAD (reg:SI 204) (nil))) I surfed the web a bit and found similar gcc bug report 37436 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37436. But basically they are not same. Can someone show me the possible places where insn#479 is generated in reload.c or reload1.c? Thanks! Qifei Fan Is there anyone can help? There are many places where that insn could be generated, so it's pretty hard to answer your question as asked. I recommend setting a breakpoint on make_insn_raw if cfun-emit-x_cur_insn_uid == 479. Then a backtrace will show you what is creating the insn. Ian
Help-The possible places where insn is splitted in greg pass
Hi, I am working on a micro controller and trying to port gcc(4.3.2) for it. Not the compiling process runs into the following error: a.c: In function 'task': a.c:150: error: unrecognizable insn: (insn 479 478 320 19 a:381 (set (reg:SI 12 a12) (plus:SI (mult:SI (reg:SI 9 a9 [204]) (const_int 4 [0x4])) (reg:SI 12 a12))) -1 (nil)) a.c:150: internal compiler error: in extract_insn, at recog.c:1990 Please submit a full bug report, ... This insn is generated in greg pass from another insn: (insn 320 308 309 19 a.c:381 (set (reg:SI 207 [ variable.wrData ]) (mem/s:SI (plus:SI (mult:SI (reg:SI 204) (const_int 4 [0x4])) (reg/f:SI 234)) [5 variable.wrData+0 S4 A32])) 3 {movsi} (expr_list:REG_DEAD (reg:SI 204) (nil))) I surfed the web a bit and found similar gcc bug report 37436 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37436. But basically they are not same. Can someone show me the possible places where insn#479 is generated in reload.c or reload1.c? Thanks! Qifei Fan