This is the mail archive of the gcc-help@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]

Re: Help in GIMPLE to RTL transformation


Hi Ramana,

Thanks for your prompt reply.

Yes, I am looking at the code produced using i386.md file. And yes, there is a "divmod" pattern in i386.md file which, as you said, has led to generation of this single INSN.

But it would be great if you can let me know, which function or file in GCC source code is involved in producing this single INSN. I have been trying to trace out GCC source code for this, but with little success.

Regards,
Amruta


On Sat, 18 Mar 2006, Ramana Radhakrishnan wrote:


Hi Amruta,

I presume you are looking at the i386 backend. It can't be combine.
Combine comes into the picture much much later than the initial
expansion rounds. There are a set of named patterns that need to be
supported in the backend and if the named patterns can be found, gcc
expands using the named patterns.

Look at the expander pattern for divmodsi4 .That creates this particular
pattern and can be used for cases like the x86 where a single
instruction can create both the quotient and the remainder.

From info gccint . (Read M as the machine mode :) )


`divmodM4'
    Signed division that produces both a quotient and a remainder.
    Operand 1 is divided by operand 2 to produce a quotient stored in
    operand 0 and a remainder stored in operand 3.

    For machines with an instruction that produces both a quotient and
    a remainder, provide a pattern for `divmodM4' but do not provide
    patterns for `divM3' and `modM3'.  This allows optimization in the
    relatively common case when both the quotient and remainder are
    computed.

    If an instruction that just produces a quotient or just a remainder
    exists and is more efficient than the instruction that produces
    both, write the output routine of `divmodM4' to call
    `find_reg_note' and look for a `REG_UNUSED' note on the quotient
    or remainder and generate the appropriate instruction.

HTH

cheers
Ramana

On Sat, 2006-03-18 at 12:22 +0530, Amruta G. Gokhale wrote:
Hi,

I am looking at some part of GCC source code which does the translation
from GIMPLE to RTL.
I created an example, having two consecutive instructions, one with "div"
and other with "mod".

Example:
int a, b, c, d;
a = b / c;
d = b % c;

The first-cut RTL code corresponding to these two instructions is a
PARALLEL INSN, with two SET INSNs, one with "div" and other with "mod".
(insn 22 21 23 1 (parallel [
             (set (reg:SI 70)
                 (div:SI (reg:SI 72)
                     (mem/i:SI (plus:SI (reg/f:SI 54 virtual-stack-vars)
                             (const_int -8 [0xfffffff8])) [0 c+0 S4 A32])))
             (set (reg:SI 71)
                 (mod:SI (reg:SI 72)
                     (mem/i:SI (plus:SI (reg/f:SI 54 virtual-stack-vars)
                             (const_int -8 [0xfffffff8])) [0 c+0 S4 A32])))
)

I am unable to understand how a single INSN gets generated for these two
instructions. The GIMPLE code has two different tree nodes for the two
instructions, namely "trunc_div_expr" and "trunc_mod_expr". So there
should be two different INSNs. My guess is, some pass, like "combine",
must be combining two INSNs into one.
I looked at functions in file "combine.c", but no function in that file is
called!

Can anybody suggest something? I am really stuck at this point And can't
proceed any further.

Regards,

Amruta Gokhale
Graduate Student
IIT Bombay,
Mumbai.




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]