AW: AW: setmemsi, movmemsi and post_inc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> Von: Jeff Law <jeffreyalaw@xxxxxxxxx>
> Gesendet: Donnerstag, 25. März 2021 16:04 On 3/25/2021 8:50 AM, Stefan
>
> That's likely going to lead to a variety of problems.   The (documented)
> restriction around auto-inc not being used early in the pipeline has
> been around at least 30 years and passes have been written with that
> assumption.  Fixing all of them may be a substantial effort.

My way to use auto-inc starting from expand seems to work. The torture tests are passed and also the compiled programs are still working. I'm waiting for feedback from the users of my special treated version... 

So I wan't to share my recipe - whilst I'm sure that you won't pick up that idea...

If an auto-inc insn gets emitted a temp register is mandatory, the REG_INC note must be set on the auto-insns and on the temp register. The REG-INC for the temp register is used as a marker to avoid aliasing or reuse since the value of the temp register changes. This is done via some patches, which do not affect the normal behavior.

  /* tmp reg for auto inc. */
  src = gen_reg_rtx (SImode);
  rtx_insn *sinsn = emit_move_insn (src, regsrc);
  add_reg_note (sinsn, REG_INC, src);

  /* create post_inc. */
  src = gen_rtx_MEM (SImode, gen_rtx_POST_INC(SImode, regsrc));

  /* emit an auto inc. */
  rtx_insn *insn = emit_move_insn (dst, src);
  add_reg_note (insn, REG_INC, regsrc);

To get it work you need changes in these sources:

alias.c: init_alias_analysis : 3463
		  if (set != 0
		      && REG_P (SET_DEST (set))
		      && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
		      /* SBF: ignore regs marked as REG_INC. */
		      && !find_reg_note(insn, REG_INC, SET_DEST (set)))

cprop.c: do_local_cprop : 1183
  if (REG_P (x)
      && (cprop_reg_p (x)
          || (GET_CODE (PATTERN (insn)) != USE
	      && asm_noperands (PATTERN (insn)) < 0))
      /* SBF: ignore regs marked as REG_INC. */
      && !find_reg_note (insn, REG_INC, x))

cse.c: cse_insn : 5513
	  /* SBF: ignore regs marked as REG_INC. */
	  if (!find_reg_note(insn, REG_INC, dest))
	    set_unique_reg_note (insn, REG_EQUAL, src_const);

		:5976
	if (REG_P (dest) || GET_CODE (dest) == SUBREG)
	  {
	    /* SBF: ignore regs marked as REG_INC. */
	    if (find_reg_note (insn, REG_INC, dest))
	      continue;
	    /* Registers must also be inserted into chains for quantities.  */
	    if (insert_regs (dest, sets[i].src_elt, 1))
	      {
		/* If `insert_regs' changes something, the hash code must be
		 recalculated.  */
		rehash_using_reg (dest);
		sets[i].dest_hash = HASH(dest, GET_MODE (dest));
	      }
	  }

gcse.c: pre_insert_copy_insn :2295
  /* SBF: move REG_INC note. */
  if (NEXT_INSN(insn) == new_insn && find_reg_note(insn, REG_INC, old_reg))
    {
      remove_note(insn, find_reg_note(insn, REG_INC, old_reg));
      add_reg_note (new_insn, REG_INC, old_reg);
    }

  gcse_create_count++;


web.c: replace_ref : 292
  rtx_insn * insn = DF_REF_INSN (ref);

  /* SBF: ignore regs marked as REG_INC. */
  if (oldreg == reg || find_reg_note(insn, REG_INC, oldreg))
    return;
  if (dump_file)
    fprintf (dump_file, "Updating insn %i (%i->%i)\n",
	     uid, REGNO (oldreg), REGNO (reg));
  *loc = reg;
  df_insn_rescan (insn);


> It's probably a better use of your time to get a deep understanding of
> why you're not getting the code you want in the presence of unrolling
> -- there may be things we can do in the unroller, auto-inc or passes
> in the middle to improve that.

Despite the REG_INC success: I added two functions to auto-inc-dev.c

1.
static bool
convert_to_post_inc (rtx_insn *last_insn, rtx *inc_reg, int size)

used in try_merge to convert an unsuccessful PRE_ADD into a POST_INC.

2.
static void
convert_mem_offset_to_add (rtx_insn *insn, basic_block bb, bool use_src)

This gets invoked early in the loop of merge_in_block to convert mems with offset and a trailing matching add to the address register into an POST_INC ladder.

Since it adds new registers (max_regno increases) some further changes were needed to adjust the structures.

If someone is interested...

Anyway - thank you for listening 😊


Stefan





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux