Ok, I understand now. Thank you very much for your explanations, Jean Christophe Beyler
On Sat, Feb 7, 2009 at 5:13 PM, Michael Meissner <meiss...@linux.vnet.ibm.com> wrote: > On Sat, Feb 07, 2009 at 03:54:51PM -0500, Jean Christophe Beyler wrote: >> Dear all, >> >> I have a question about the way the machine description works and how >> it affects the different passes of the compiler. I was reading the GNU >> Compiler Collection Internals and I found this part (in section >> 14.8.1): >> >> (define_insn "" >> [(set (match_operand:SI 0 "general_operand" "=r") >> (plus:SI (match_dup 0) >> (match_operand:SI 1 "general_operand" "r")))] >> "" >> "...") >> >> which has two operands, one of which must appear in two places, and >> >> (define_insn "" >> [(set (match_operand:SI 0 "general_operand" "=r") >> (plus:SI (match_operand:SI 1 "general_operand" "0") >> (match_operand:SI 2 "general_operand" "r")))] >> "" >> "...") >> >> which has three operands, two of which are required by a constraint to >> be identical. >> >> >> My question is : >> - How do the constraints work for match_dup or for when you put "0" as >> a constraint? Since we want the same register but as input and not >> output, how does the compiler set up its dependencies? Does it just >> forget the "=" or "+" for the match_dup or "0" ? > > Note, the two are not the same thing before register allocation. Before > register allocation, in the first example, the argument to the plus must point > to the exact RTL that the result is. Given that normally a different pseudo > register is used for the output, the first example won't match a lot of insns > that are created. > > The two general_operands are distinct and the normal live/death information > will track the insns. So you are saying that the first general operand is a > write only value, and the second is a read only value. During register > allocation, the register allocator notices the "0" and then reuses the > register. In that example, the value of operand1 dies in that insn, replaced > by the value in operand0. > > For example, consider a 2 address machine like the 386 (and ignoring things > like LEA). If the value of operand1 is live after the insn, and operand0 > wants > to be %eax, operand1 is in %ebx, and operand2 is in %edx, then the register > allocation typically generates code like: > > movl %ebx, %eax > addl %edx, %eax > > If operand1's value was not needed after the insn, then the compiler would > possibly allocate the output to %ebx, and do: > > addl %edx, %ebx > >> >> - I also read that it is possible to assign a letter with a number for >> the constraint. Does this mean I can do "r0" to say, it's going to be >> an input register but it must look like the one you'll find in >> position 0? > > I'm not sure what you are asking here. If you are talking about the > multi-letter constraints in define_register_constraint, that is basically a > way > to extend the machine description for more constraints when you run out of > single letters. > >> - My third question is: why not put "+r" as the constraint instead of >> "=r" since we are going to be reading and writing into r0. > > Because the output value is not an input to the add in the second example. It > is an input to the add in the first, due to the use of match_dup. > >> - Finally, I have a similar instruction definition, if I use the first >> solution (match_dup), the instruction that will calculate the >> input/output operand 0 sometimes gets removed by the web pass. But if >> I use the second solution (put a "0" constraint), then it is no longer >> removed. Any idea why these two definitions would be treated >> differently in the web pass? > > I don't know much about the web pass, however as I said, the two definitions > are fundamentally different. > > -- > Michael Meissner, IBM > 4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA > meiss...@linux.vnet.ibm.com >