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]

Re: Compact regsiter allocation


----- Original Message ----

> From: Ian Lance Taylor <iant@google.com>
> To: Jamie Prescott <jpresss@yahoo.com>
> Cc: gcc@gcc.gnu.org
> Sent: Thursday, May 14, 2009 10:09:40 PM
> Subject: Re: Compact regsiter allocation
> 
> Jamie Prescott writes:
> 
> > If not, what is the best spot (in the normal GCC target hooks) to trigger it? 
> Where the
> > full insn tree is passed in such hook (if it's not a global)?
> 
> TARGET_MACHINE_DEPENDENT_REORG.  It will be invoked once for each
> function, and can access and modify the complete RTL insn tree.

It wasn't as easy as I expected. Likely because my knowledge of GCC internals is pretty shallow.
This is what I came up with.
The target reorg is great, but it had two problems for me. One is that it was issued after the
prologue/epilogue, where I had to emit insns based on the already-remapped status, so I
ended up keeping as hash of non-remappable instructions that I fed with the xxx_emit_hashed_insn().
I use the hash to detect which insns do not have to be remapped.
Not only, since REG RTXs can appear multiple times, I need to feed the RTX into the hash, after
having been remapped once.
This seems to be working fine, but my biggest doubt is that way I dig into the single instructions to
find REG RTXs to remap.
I looked around and I ended up with the code below, partially stolen from print_rtx().
Is there a public/non-hackish API to enum all the RTXs contained inside an instruction?
If not, do I handle all the possible cases in xxx_enum_rtx()?
Seem code below, with xxx_reorg() being my reorg function ...



- Jamie



typedef struct s_xxx_reg_remap
{
        int from, to;
} xxx_reg_remap_t;


static void
xxx_remap_reg(rtx insn, xxx_reg_remap_t const *rmap, int n)
{
        int i, regno = REGNO(insn);

        if (xxx_ptrhash_lookup(&insns_hash, (void *) insn, NULL))
                return;

        for (i = 0; i < n; i++)
                if (rmap[i].from == regno) {
                        xxx_ptrhash_add(&insns_hash, (void *) insn);
                        SET_REGNO(insn, rmap[i].to);
                        break;
                }
}

static void
xxx_enum_rtx(rtx insn, xxx_reg_remap_t const *rmap, int n,
             void (*proc)(rtx, xxx_reg_remap_t const *, int))
{
        int i, j, len, vlen;
        char const *fmt;
        rtx x, y;

        if (xxx_ptrhash_lookup(&insns_hash, (void *) insn, NULL))
                return;

        fmt = GET_RTX_FORMAT(GET_CODE(insn));
        len = GET_RTX_LENGTH(GET_CODE(insn));
        for (i = 0; i < len; i++, fmt++) {
                switch (*fmt) {
                case 'e':
                        if ((x = XEXP(insn, i)) == NULL_RTX)
                                continue;
                        if (GET_CODE(x) == REG)
                                (*proc)(x, rmap, n);
                        else
                                xxx_enum_rtx(x, rmap, n, proc);
                        break;

                case 'E':
                case 'V':
                        if (XVEC(insn, i) == NULL)
                                break;
                        vlen = XVECLEN(insn, i);
                        for (j = 0; j < vlen; j++) {
                                if ((y = XVECEXP(insn, i, j)) != NULL_RTX)
                                        xxx_enum_rtx(y, rmap, n, proc);
                        }
                        break;
                }
        }
}

static void
xxx_reorg(void)
{
        rtx insn;

        insn = get_insns();
        gcc_assert(GET_CODE(insn) == NOTE);

        for (insn = next_nonnote_insn(insn); insn != NULL_RTX;
             insn = next_nonnote_insn(insn)) {
                xxx_enum_rtx(insn, func_rmap, func_nrmap, xxx_remap_reg);
        }

        xxx_ptrhash_free(&insns_hash);
}

static rtx
xxx_emit_hashed_insn(rtx insn)
{
        xxx_ptrhash_add(&insns_hash, (void *) insn);

        return emit_insn(insn);
}


      


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