public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Sandiford <rsandifo@nildram.co.uk>
To: David Daney <ddaney@avtrex.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [Patch] 2/3 MIPS support for builtin __builtin_flush_icache().
Date: Thu, 05 Jul 2007 19:05:00 -0000	[thread overview]
Message-ID: <87odiq3cov.fsf@firetop.home> (raw)
In-Reply-To: <468C9FCA.4060406@avtrex.com> (David Daney's message of "Thu, 05 	Jul 2007 00:37:46 -0700")

Thanks for all the updates.

David Daney <ddaney@avtrex.com> writes:
> Richard Sandiford wrote:
>> David Daney <ddaney@avtrex.com> writes:
>>> +    /* Flush both caches.  We need to flush the data cache in case
>>> +       the system has a write-back cache.  */
>>> +    /* ??? Should check the return value for errors.  */
>>> +    if (mips_cache_flush_func && mips_cache_flush_func[0])
>>> +      emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mips_cache_flush_func),
>>> +                         0, VOIDmode, 3, copy_rtx (operands[0]), Pmode,
>>> +                         copy_rtx (operands[1]), TYPE_MODE (integer_type_node),
>>> +                         GEN_INT (3), TYPE_MODE (integer_type_node));
>>> +  DONE;
>>>     
>>
>> Same copy_rtx comment here.  TBH, I'm not sure what the "???" comment
>> refers to.
>>
>>   
> I just pased this part in from its old home in mips.h.  The ??? comment 
> came with it.  It is gone now.

Sorry, I missed that.  And thanks for deleting it.

>> I wonder if would be better
>> to simply expand this as rtl, with special patterns for the "rdhwr",
>> "synci" and "sync" instructions.  This is similar to what we do for
>> other largish patterns.  That's certainly not a requirement though;
>> I'm not even sure it makes sense.  It's just an idea-cum-question.
>>
> That is what I did.

Looks good, thanks.

>> Following on from your comment about delay slots, it also strikes me
>> that the "bal; nop; addiu" sequence is almost always longer than the
>> sequence to load a local address into a register.  I think the only
>> exception is static n64 with -mno-sym32.  I wonder if it would be
>> worth using a sequence like:
>>
>>     rtx label, target, insn;
>>
>>     label = gen_label_rtx ();
>>     target = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, label));
>>     insn = emit_jump_insn (gen_indirect_jump_hb (target));
>>     REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL, label, REG_NOTES (insn));
>>     emit_label (label);
>>
>> where indirect_jump_hb would just be something like:
>>
>> (define_insn "indirect_jump_hb"
>>   [(set (pc) (match_operand "pmode_register_operand" "d"))
>>    (unspec_volatile [(const_int 0)] UNSPEC_JR_HB)]
>>   "ISA_HAS_SYNCI"
>>   "jr.hb\t%0"
>>   [(set_attr "type" "jump")])
>>
>> (all untested).  I think we might then be able to fill the delay slot
>> from the target of the jump, which should be OK in this context.
>> Again, this is just an idea-cum-question.
>>
>>   
> I spent way too much time trying to get that to work.  For now I left it 
> mostly unchanged from the original patch.
>
> The problem is that the CFG things just don't seem to be able to handle:
> 1) Jump insns where the body is a (parallel ...) instead of a (set (pc) 
> ...).
> 2) Unconditional jumps where the target and fall through edges goto the 
> same place.

Thanks for trying.  In that case, I agree your patch is the way to go.

> I kept the call to mips_cache_flush_func pretty much unchanged because I 
> didn't want to break compatibility with the command line options that 
> allow this to be changed.   Also I added CLEAR_INSN_CACHE that expands 
> in libgcc that is used if  __builtin___clear_cache() cannot be expanded 
> in-line.  This is slightly inefficient as it adds an extra function call 
> layer through libgcc and has to do the arithmetic to convert the 
> function parameters, but I am thinking I shouldn't be concerned about a 
> few extra cycles doing this when we are about to do a system call.  The 
> alternative is to have __builtin___clear_cache() directly expand to 
> mips_cache_flush_func and leave libgcc out of the picture for MIPS. 

I'm happy either way.  I suppose the latter is appealing in some ways --
to mirror what you said above, it means that -mflush-func will be
honoured -- but I can see why the consistency of calling a libgcc
function is good too.

Perhaps if we aren't sure, the libgcc-less version is better.
Once we add the function, we'll have to keep it for ABI compatibility.

> Index: config/mips/mips.h
> ===================================================================
> --- config/mips/mips.h	(revision 125997)
> +++ config/mips/mips.h	(working copy)
> @@ -136,6 +136,10 @@ extern const struct mips_cpu_info mips_c
>  extern const struct mips_cpu_info *mips_arch_info;
>  extern const struct mips_cpu_info *mips_tune_info;
>  extern const struct mips_rtx_cost_data *mips_cost;
> +
> +extern bool mips_builtin_clear_cache_inline_p (void);
> +#undef TARGET_BUILTIN_CLEAR_CACHE_INLINE_P
> +#define TARGET_BUILTIN_CLEAR_CACHE_INLINE_P mips_builtin_clear_cache_inline_p

I think the last two lines belong in mips.c, and that
mips_builtin_clear_cache_inline_p can be static.  See how
similar hooks are handled.

(There's a bit of confusing difference in the way target macros
are handled.  Some are intended to be defined by target .h files,
and target-def.h only defines them if the target .h files don't.
Others are defined by target-def.h and then overridden in the
target .c file.  My understanding is that the former are intended
for things like OS-specific and assembler-specific macros,
whereas the latter are intended for _target_-specific macros.
TARGET_BUILTIN_CLEAR_CACHE_INLINE_P is one of the latter for MIPS.)

> +;; Flush the instruction cache starting as operands[0] with length
> +;; operands[1].
> +(define_expand "flush_icache"
> +  [(match_operand:SI 0 "pmode_register_operand")
> +   (match_operand:SI 1 "register_operand")]

I think this should be:

  [(match_operand 0 "pmode_register_operand")
   (match_operand:SI 1 "const_arith_operand")]

There should be no mode on a pmode_register_operand; the predicate
exists to check the run-time Pmode.  And I think the only user --
INITIALIZE_TRAMPOLINE -- does pass a const_int here.  The use of
const_arith_operand (as opposed to const_int_operand) emphasises
that the constant must be a valid operand to an addition isntruction.

> +  if (ISA_HAS_SYNCI)
> +    {
> +      rtx end_addr = gen_reg_rtx (Pmode);
> +      emit_insn (gen_rtx_SET (VOIDmode, end_addr,
> +      			      gen_rtx_PLUS (Pmode, operands[0], operands[1])));

emit_insn (gen_add3_insn (end_addr, operands[0], operands[1]));

> +;; Expand in-line code to clear the instruction cache between operand[0] and
> +;; operand[1].
> +(define_expand "clear_cache"
> +  [(match_operand:SI 0 "general_operand")
> +   (match_operand:SI 1 "general_operand")]

I still think these should be:

  [(match_operand 0 "pmode_register_operand")
   (match_operand 1 "pmode_register_operand")]

> +(define_insn "sync"
> +  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
> +  ""
> +  "sync"
> +  [(set_attr "length" "4")])

Best make this conditional on ISA_HAS_SYNC, just to be on the safe side.
Very minor nit, but please drop the length attribute, since it's just
restating the default.  Likewise for the others.

> +(define_insn "synci"
> +  [(unspec_volatile [(match_operand:SI 0 "general_operand" "d")] UNSPEC_SYNCI)]
> +  ""
> +  "synci\t0(%0)"
> +  [(set_attr "length" "4")])

ISA_HAS_SYNC again.  Please also make the predicate "pmode_register_operand"
(without a mode).

> +(define_insn "rdhwr"
> +  [(set (match_operand:SI 0 "general_operand" "=d")
> +        (unspec_volatile [(match_operand:SI 1 "immediate_operand" "n")]
> +        UNSPEC_RDHWR))]
> +  ""
> +  "rdhwr\t%0,$%1"
> +  [(set_attr "length" "4")])

Getting even more minor here, but const_int_operand is a little
more specific than immediate_operand, and matches "n" better.

> Index: config/mips/mips.c
> ===================================================================
> --- config/mips/mips.c	(revision 125997)
> +++ config/mips/mips.c	(working copy)
> @@ -3759,6 +3759,47 @@ mips_block_move_loop (rtx dest, rtx src,
>      mips_block_move_straight (dest, src, leftover);
>  }
>  \f
> +
> +/* Return true if we will expand __builtin_clear_cache() in-line. */
> +bool

Silly formatting stuff: two spaces after ".".  Usual (and local) style
is to have a blank line between comment and function.

I tend to prefer comments like:

   Implement TARGET_BUILTIN_CLEAR_CACHE_INLINE_P.

instead, so that you know instantly which tm.texi macro you need to
look at in order to get the full interface.

> +/* Expand a loop of synci insns */
> +void
> +mips_expand_synci_loop (rtx begin, rtx end)

Blank line, and ".  */".  Pedantically, you should mention every
argument in the comment, so how about:

/* Expand a loop of synci insns for the address range [BEGIN, END).  */

> +{
> +  rtx end_addr, inc, label, label_ref, cmp, cmp_result;
> +
> +  begin = force_reg(Pmode, begin);
> +  end = force_reg(Pmode, end);

This wouldn't be needed after the pmode_register_operand change,
although I agree it is needed as things stand.

> +  /* Load INC with the cache line size (rdhwr INC,$1). */
> +  inc = gen_reg_rtx (SImode);
> +  emit_insn (gen_rdhwr (inc ,gen_rtx_CONST_INT(SImode, 1)));

CONST_INT objects don't have modes, and formatting.  Should be:

  emit_insn (gen_rdhwr (inc, const1_rtx));

> +  /* Loop back to here. */
> +  label = gen_label_rtx ();
> +  emit_label (label);
> +
> +  emit_insn (gen_synci (begin));
> +
> +  cmp = gen_reg_rtx (SImode);

Pmode rather than SImode.

> +  emit_insn (gen_rtx_SET (VOIDmode, cmp, gen_rtx_GTU (Pmode, begin, end)));

mips_emit_binary (GTU, cmp, begin, end);

> +
> +  emit_insn (gen_rtx_SET (VOIDmode, begin, gen_rtx_PLUS (Pmode, begin, inc)));

Either:

    emit_insn (gen_add3_insn (begin, begin, inc));

or:

    mips_emit_binary (PLUS, begin, begin, inc);

Probably the latter, givne the GTU thing above.

> +
> +  label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
> +  cmp_result = gen_rtx_EQ (VOIDmode, cmp, gen_rtx_CONST_INT(SImode, 0));
> +  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
> +                               gen_rtx_IF_THEN_ELSE (VOIDmode, cmp_result,
> +                                                     label_ref,
> +                                                     pc_rtx)));

cmp_result = gen_rtx_EQ (VOIDmode, cmp, const0_rtx);
emit_jump_insn (gen_condjump (cmp_result, label));

All in all, very minor comments.  Thanks again for your work on this.

Richard

  reply	other threads:[~2007-07-05 18:53 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-01  5:01 [Patch] 1/3 Add new " David Daney
2007-07-01  5:05 ` [Patch] 2/3 MIPS support for " David Daney
2007-07-01 10:56   ` Richard Sandiford
2007-07-05  7:50     ` David Daney
2007-07-05 19:05       ` Richard Sandiford [this message]
2007-07-08 20:00         ` David Daney
2007-07-09 19:07           ` Richard Sandiford
2007-07-11  5:45             ` David Daney
2007-07-01  5:11 ` [Patch] 3/3 FFI: Use __builtin_flush_icache() to flush MIPS i-cache David Daney
2007-07-05  8:34   ` David Daney
2007-07-05 19:08     ` Richard Sandiford
2007-07-11 18:55       ` Tom Tromey
2007-07-01  8:01 ` [Patch] 1/3 Add new builtin __builtin_flush_icache() Paolo Bonzini
2007-07-01 17:51   ` Thiemo Seufer
2007-07-01 18:47   ` David Daney
2007-07-02  5:04     ` Paolo Bonzini
2007-07-03 23:55       ` Mark Mitchell
2007-07-04  7:18         ` Paolo Bonzini
2007-07-04 17:17           ` Mark Mitchell
2007-07-04 17:10         ` David Daney
2007-07-04 17:51           ` Mark Mitchell
2007-07-05  7:36             ` David Daney
2007-07-05 17:59               ` Richard Sandiford
2007-07-05 18:23                 ` David Daney
2007-07-05 19:11                   ` Richard Sandiford
2007-07-06  6:07               ` Mark Mitchell
2007-07-06  6:19                 ` David Daney
2007-07-06 16:39                   ` Mark Mitchell
2007-07-08 19:22                     ` David Daney
2007-07-09 19:04                       ` Richard Sandiford
2007-07-11  2:22                       ` Mark Mitchell
2007-07-11  4:47                         ` David Daney
2007-07-05  9:05 ` [Patch] 4/3 i386 target support for __builtin___clear_cache() David Daney
2007-07-08 20:39   ` David Daney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87odiq3cov.fsf@firetop.home \
    --to=rsandifo@nildram.co.uk \
    --cc=ddaney@avtrex.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).