Thread-safe profiling

Richard Henderson rth@redhat.com
Tue Mar 20 21:29:00 GMT 2007


On Wed, Mar 14, 2007 at 08:47:09PM +0100, Michael Matz wrote:
> +  gcov_type old_val;
> +  while (1)
> +    {
> +      gcov_type old2;
> +      /* We need the old value, which we need to read atomically, but
> +         the only primitive we have for that is compare_and_swap :-/ */
> +      old_val = __sync_val_compare_and_swap (&counters[1], 0, 0);
> +      if (old_val == (gcov_type)-1)
> +	continue;

A plain read will be fine here, especially since the following
compare_and_swap will validate the value was read properly.

> +;; Theoretically we'd like to use constraint "r" (any reg) for operand
> +;; 3, but that includes ecx.  If operand 3 and 4 are the same (like when
> +;; the input is -1LL) GCC might chose to allocate operand 3 to ecx, like
> +;; operand 4.  This breaks, as the xchg will move the PIC register contents
> +;; to %ecx then --> boom.  Operands 3 and 4 really need to be different
> +;; registers, which in this case means operand 3 must not be ecx.
> +;; Instead of playing tricks with fake early clobbers or the like we
> +;; just enumerate all regs possible here, which (as this is !TARGET_64BIT)
> +;; are just esi and edi.

Well, and ebp too, assuming -fomit-frame-pointer.  In which case your
solution cuts the available registers by 1/3.  I think it might be
better to go ahead and play with clobbers.  Something like

(define_insn "*sync_double_compare_and_swapdi_pic"
  [(set (match_operand:DI 0 "register_operand" "=A,A")
        (match_operand:DI 1 "memory_operand" "+m,m"))
   (set (match_dup 1)
        (unspec_volatile:DI
          [(match_dup 1)
           (match_operand:DI 2 "register_operand" "A,A")
           (match_operand:SI 3 "register_operand" "c,r")
           (match_operand:SI 4 "register_operand" "c,c")]
          UNSPECV_CMPXCHG_1))
   (clobber (match_scratch:SI 5 "=&r,X"))
   (clobber (reg:CC FLAGS_REG))]
  "!TARGET_64BIT && TARGET_CMPXCHG8B && flag_pic"
  "@
   mov{l}\t%%ebx, %5\;mov{l}\t%3, %%ebx\;lock{\;| }cmpxchg8b{\t| }%1\;mov{l}\t%5, %%ebx
   xchg{l}\t%%ebx, %3\;lock{\;| }cmpxchg8b{\t| }%1\;xchg{l}\t%%ebx, %3")


r~



More information about the Gcc-patches mailing list