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
>

Reply via email to