This is the mail archive of the gcc-patches@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: PATCH, rs6000 (alpha?) long const --verbose


Richard Henderson wrote:

> On Sat, Dec 29, 2001 at 09:06:39PM -0600, Tom Rix wrote:
> > > What is the number that didn't match?
> >
> > -131072
>
> That's 0xffff_ffff_fffe_0000, which is definitely valid.  So
> why doesn't that insn get recognized?

I believe the rs6000_emit_allocate_stack is called after the usual
recogn/splitting.   From inspection of the funtion :

if (TARGET_UPDATE)
    {
      if (size > 32767)          << --checking for large stack
        {
          /* Need a note here so that try_split doesn't get confused.
*/
          if (get_last_insn() == NULL_RTX)
            emit_note (0, NOTE_INSN_DELETED);
          insn = emit_move_insn (tmp_reg, todec);
          try_split (PATTERN (insn), insn, 0);   << --splitting the r1 =
r1 - bigstack
          todec = tmp_reg;
        }

    }

If this was a normal add (a = a - 131072),  yes the constraint in adddi3
would have worked.    I am guessing the check for the size means this
add happens after normal contraint checking/splitting  and split is
being done here the hard way.

The split that try_split uses is :

;; Split a load of a large constant into the appropriate
five-instruction
;; sequence.  Handle anything in a constant number of insns.
;; When non-easy constants can go in the TOC, this should use
;; easy_fp_constant predicate.
(define_split
  [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (match_operand:DI 1 "const_int_operand" ""))]
  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
  [(set (match_dup 0) (match_dup 2))
   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
  "
{ rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5);

  if (tem == operands[0])
    DONE;
  else
    FAIL;
}")

Here is the rtl dump of the stack allocation from flow2 :


(note 3 2 5 NOTE_INSN_FUNCTION_BEG)

(note 5 3 24 30033180 NOTE_INSN_BLOCK_BEG)

;; Start of basic block 0, registers live: 1 [1] 65 [lr]
(note 24 5 29 [bb 0] NOTE_INSN_BASIC_BLOCK)

(insn 29 24 31 (set (reg:DI 0 r0)
        (reg:DI 65 lr)) -1 (nil)
    (expr_list:REG_DEAD (reg:DI 65 lr)
        (nil)))

(insn/f 31 29 35 (set (mem:DI (plus:DI (reg/f:DI 1 r1)
                (const_int 16 [0x10])) [0 S8 A64])
        (reg:DI 0 r0)) -1 (insn_list 29 (nil))
    (expr_list:REG_DEAD (reg:DI 0 r0)
        (expr_list:REG_FRAME_RELATED_EXPR (set (mem:DI (plus:DI
(reg/f:DI 1 r1)
                        (const_int 16 [0x10])) [0 S8 A64])
                (reg:DI 65 lr))
            (nil))))

-- start of rs6000_emit_set_long_const

<<<         emit_move_insn (dest, GEN_INT (d3));

(insn 35 31 37 (set (reg:DI 0 r0)
        (const_int 0 [0x0])) -1 (nil)
    (nil))

<<<   if (d2 != 0)
        emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT
(d2)));

(insn 37 35 39 (set (reg:DI 0 r0)            <<< this is the problem >>>

        (plus:DI (reg:DI 0 r0)
            (const_int -131072 [0xfffffffffffe0000]))) -1 (insn_list 35
(nil))
    (nil))


<<<      if (d1 != 0)
        emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT
(d1)));

(insn 39 37 40 (set (reg:DI 0 r0)
        (plus:DI (reg:DI 0 r0)
            (const_int -29040 [0xffffffffffff8e90]))) -1 (insn_list 37
(nil))
    (nil))

-- end of rs6000_emit_set_long const

(insn/f 40 39 41 (parallel[
            (set (mem:DI (plus:DI (reg/f:DI 1 r1)
                        (reg:DI 0 r0)) [0 S8 A64])
                (reg/f:DI 1 r1))
            (set (reg/f:DI 1 r1)
                (plus:DI (reg/f:DI 1 r1)
                    (reg:DI 0 r0)))
        ] ) -1 (insn_list 39 (nil))
    (expr_list:REG_DEAD (reg:DI 0 r0)
        (expr_list:REG_FRAME_RELATED_EXPR (set (reg/f:DI 1 r1)
                (plus:DI (reg/f:DI 1 r1)
                    (const_int -160112 [0xfffffffffffd8e90])))
            (nil))))

(note 41 40 9 NOTE_INSN_PROLOGUE_END)

>
>

New add improved spits out

(insn 35 31 37 (set (reg:DI 0 r0)
        (const_int -131072 [0xfffffffffffe0000])) -1 (nil)
    (nil))

(insn 37 35 38 (set (reg:DI 0 r0)
        (plus:DI (reg:DI 0 r0)
            (const_int -29040 [0xffffffffffff8e90]))) -1 (insn_list 35
(nil))
    (nil))

Which is fairly close to the way it used to work before
rs6000_emit_set_long_const.  If you want to see that,  I will have to
set output to --verbose --verbose :)~

If rs6000_emit_set_long_const is called early,  the error of the add
will be hidden by splitting it again as if it were a normal addition of
a large immediate.  If it is called late, the error shows up as a fatal
compiler error.

Tom

--
Tom Rix
GCC Engineer
trix@redhat.com




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