diff mbox

[AArch64,1/3] Migrate aarch64_add_constant to new interface & kill aarch64_build_constant

Message ID df82b12d-ec52-9c72-0c17-8149a8d8881c@foss.arm.com
State New
Headers show

Commit Message

Jiong Wang July 20, 2016, 1:02 p.m. UTC
Currently aarch64_add_constant is using aarch64_build_constant to move
an immediate into the destination register.

It has considered the following situations:

   * immediate can fit into bitmask pattern that only needs single
     instruction.
   * immediate can fit into single movz/movn.
   * immediate needs single movz/movn, and multiply movk.


Actually we have another constant building helper function
"aarch64_internal_mov_immediate" which cover all these situations and
more.

This patch thus migrate aarch64_add_constant to
aarch64_internal_mov_immediate so that we can kill the old
aarch64_build_constant.

OK for trunk?

gcc/
2016-07-20  Jiong Wang  <jiong.wang@arm.com>

             * config/aarch64/aarch64.c (aarch64_add_constant): New
             parameter "mode".  Use aarch64_internal_mov_immediate
             instead of aarch64_build_constant.
             (aarch64_build_constant): Delete.

Comments

Richard Earnshaw (lists) July 20, 2016, 2:04 p.m. UTC | #1
On 20/07/16 14:02, Jiong Wang wrote:
> Currently aarch64_add_constant is using aarch64_build_constant to move
> an immediate into the destination register.
> 
> It has considered the following situations:
> 
>   * immediate can fit into bitmask pattern that only needs single
>     instruction.
>   * immediate can fit into single movz/movn.
>   * immediate needs single movz/movn, and multiply movk.
> 
> 
> Actually we have another constant building helper function
> "aarch64_internal_mov_immediate" which cover all these situations and
> more.
> 
> This patch thus migrate aarch64_add_constant to
> aarch64_internal_mov_immediate so that we can kill the old
> aarch64_build_constant.
> 
> OK for trunk?
> 
> gcc/
> 2016-07-20  Jiong Wang  <jiong.wang@arm.com>
> 
>             * config/aarch64/aarch64.c (aarch64_add_constant): New
>             parameter "mode".  Use aarch64_internal_mov_immediate
>             instead of aarch64_build_constant.
>             (aarch64_build_constant): Delete.
> 

Really you should also list the callers of aarch64_add_constant that
have been updated as well (there aren't that many).

OK with that change.

R.

> 
> build-const-1.patch
> 
> 
> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
> index 512ef10d158d2eaa1384d28c43b9a8f90387099d..aeea3b3ebc514663043ac8d7cd13361f06f78502 100644
> --- a/gcc/config/aarch64/aarch64.c
> +++ b/gcc/config/aarch64/aarch64.c
> @@ -3337,98 +3337,20 @@ aarch64_final_eh_return_addr (void)
>  				       - 2 * UNITS_PER_WORD));
>  }
>  
> -/* Possibly output code to build up a constant in a register.  For
> -   the benefit of the costs infrastructure, returns the number of
> -   instructions which would be emitted.  GENERATE inhibits or
> -   enables code generation.  */
> -
> -static int
> -aarch64_build_constant (int regnum, HOST_WIDE_INT val, bool generate)
> -{
> -  int insns = 0;
> -
> -  if (aarch64_bitmask_imm (val, DImode))
> -    {
> -      if (generate)
> -	emit_move_insn (gen_rtx_REG (Pmode, regnum), GEN_INT (val));
> -      insns = 1;
> -    }
> -  else
> -    {
> -      int i;
> -      int ncount = 0;
> -      int zcount = 0;
> -      HOST_WIDE_INT valp = val >> 16;
> -      HOST_WIDE_INT valm;
> -      HOST_WIDE_INT tval;
> -
> -      for (i = 16; i < 64; i += 16)
> -	{
> -	  valm = (valp & 0xffff);
> -
> -	  if (valm != 0)
> -	    ++ zcount;
> -
> -	  if (valm != 0xffff)
> -	    ++ ncount;
> -
> -	  valp >>= 16;
> -	}
> -
> -      /* zcount contains the number of additional MOVK instructions
> -	 required if the constant is built up with an initial MOVZ instruction,
> -	 while ncount is the number of MOVK instructions required if starting
> -	 with a MOVN instruction.  Choose the sequence that yields the fewest
> -	 number of instructions, preferring MOVZ instructions when they are both
> -	 the same.  */
> -      if (ncount < zcount)
> -	{
> -	  if (generate)
> -	    emit_move_insn (gen_rtx_REG (Pmode, regnum),
> -			    GEN_INT (val | ~(HOST_WIDE_INT) 0xffff));
> -	  tval = 0xffff;
> -	  insns++;
> -	}
> -      else
> -	{
> -	  if (generate)
> -	    emit_move_insn (gen_rtx_REG (Pmode, regnum),
> -			    GEN_INT (val & 0xffff));
> -	  tval = 0;
> -	  insns++;
> -	}
> -
> -      val >>= 16;
> -
> -      for (i = 16; i < 64; i += 16)
> -	{
> -	  if ((val & 0xffff) != tval)
> -	    {
> -	      if (generate)
> -		emit_insn (gen_insv_immdi (gen_rtx_REG (Pmode, regnum),
> -					   GEN_INT (i),
> -					   GEN_INT (val & 0xffff)));
> -	      insns++;
> -	    }
> -	  val >>= 16;
> -	}
> -    }
> -  return insns;
> -}
> -
>  static void
> -aarch64_add_constant (int regnum, int scratchreg, HOST_WIDE_INT delta)
> +aarch64_add_constant (machine_mode mode, int regnum, int scratchreg,
> +		      HOST_WIDE_INT delta)
>  {
>    HOST_WIDE_INT mdelta = delta;
> -  rtx this_rtx = gen_rtx_REG (Pmode, regnum);
> -  rtx scratch_rtx = gen_rtx_REG (Pmode, scratchreg);
> +  rtx this_rtx = gen_rtx_REG (mode, regnum);
> +  rtx scratch_rtx = gen_rtx_REG (mode, scratchreg);
>  
>    if (mdelta < 0)
>      mdelta = -mdelta;
>  
>    if (mdelta >= 4096 * 4096)
>      {
> -      (void) aarch64_build_constant (scratchreg, delta, true);
> +      aarch64_internal_mov_immediate (scratch_rtx, GEN_INT (delta), true, mode);
>        emit_insn (gen_add3_insn (this_rtx, this_rtx, scratch_rtx));
>      }
>    else if (mdelta > 0)
> @@ -3436,19 +3358,19 @@ aarch64_add_constant (int regnum, int scratchreg, HOST_WIDE_INT delta)
>        if (mdelta >= 4096)
>  	{
>  	  emit_insn (gen_rtx_SET (scratch_rtx, GEN_INT (mdelta / 4096)));
> -	  rtx shift = gen_rtx_ASHIFT (Pmode, scratch_rtx, GEN_INT (12));
> +	  rtx shift = gen_rtx_ASHIFT (mode, scratch_rtx, GEN_INT (12));
>  	  if (delta < 0)
>  	    emit_insn (gen_rtx_SET (this_rtx,
> -				    gen_rtx_MINUS (Pmode, this_rtx, shift)));
> +				    gen_rtx_MINUS (mode, this_rtx, shift)));
>  	  else
>  	    emit_insn (gen_rtx_SET (this_rtx,
> -				    gen_rtx_PLUS (Pmode, this_rtx, shift)));
> +				    gen_rtx_PLUS (mode, this_rtx, shift)));
>  	}
>        if (mdelta % 4096 != 0)
>  	{
>  	  scratch_rtx = GEN_INT ((delta < 0 ? -1 : 1) * (mdelta % 4096));
>  	  emit_insn (gen_rtx_SET (this_rtx,
> -				  gen_rtx_PLUS (Pmode, this_rtx, scratch_rtx)));
> +				  gen_rtx_PLUS (mode, this_rtx, scratch_rtx)));
>  	}
>      }
>  }
> @@ -3473,7 +3395,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
>    emit_note (NOTE_INSN_PROLOGUE_END);
>  
>    if (vcall_offset == 0)
> -    aarch64_add_constant (this_regno, IP1_REGNUM, delta);
> +    aarch64_add_constant (Pmode, this_regno, IP1_REGNUM, delta);
>    else
>      {
>        gcc_assert ((vcall_offset & (POINTER_BYTES - 1)) == 0);
> @@ -3489,7 +3411,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
>  	    addr = gen_rtx_PRE_MODIFY (Pmode, this_rtx,
>  				       plus_constant (Pmode, this_rtx, delta));
>  	  else
> -	    aarch64_add_constant (this_regno, IP1_REGNUM, delta);
> +	    aarch64_add_constant (Pmode, this_regno, IP1_REGNUM, delta);
>  	}
>  
>        if (Pmode == ptr_mode)
> @@ -3503,7 +3425,8 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
>  	  addr = plus_constant (Pmode, temp0, vcall_offset);
>        else
>  	{
> -	  (void) aarch64_build_constant (IP1_REGNUM, vcall_offset, true);
> +	  aarch64_internal_mov_immediate (temp1, GEN_INT (vcall_offset), true,
> +					  Pmode);
>  	  addr = gen_rtx_PLUS (Pmode, temp0, temp1);
>  	}
>  
>
diff mbox

Patch

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 512ef10d158d2eaa1384d28c43b9a8f90387099d..aeea3b3ebc514663043ac8d7cd13361f06f78502 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3337,98 +3337,20 @@  aarch64_final_eh_return_addr (void)
 				       - 2 * UNITS_PER_WORD));
 }
 
-/* Possibly output code to build up a constant in a register.  For
-   the benefit of the costs infrastructure, returns the number of
-   instructions which would be emitted.  GENERATE inhibits or
-   enables code generation.  */
-
-static int
-aarch64_build_constant (int regnum, HOST_WIDE_INT val, bool generate)
-{
-  int insns = 0;
-
-  if (aarch64_bitmask_imm (val, DImode))
-    {
-      if (generate)
-	emit_move_insn (gen_rtx_REG (Pmode, regnum), GEN_INT (val));
-      insns = 1;
-    }
-  else
-    {
-      int i;
-      int ncount = 0;
-      int zcount = 0;
-      HOST_WIDE_INT valp = val >> 16;
-      HOST_WIDE_INT valm;
-      HOST_WIDE_INT tval;
-
-      for (i = 16; i < 64; i += 16)
-	{
-	  valm = (valp & 0xffff);
-
-	  if (valm != 0)
-	    ++ zcount;
-
-	  if (valm != 0xffff)
-	    ++ ncount;
-
-	  valp >>= 16;
-	}
-
-      /* zcount contains the number of additional MOVK instructions
-	 required if the constant is built up with an initial MOVZ instruction,
-	 while ncount is the number of MOVK instructions required if starting
-	 with a MOVN instruction.  Choose the sequence that yields the fewest
-	 number of instructions, preferring MOVZ instructions when they are both
-	 the same.  */
-      if (ncount < zcount)
-	{
-	  if (generate)
-	    emit_move_insn (gen_rtx_REG (Pmode, regnum),
-			    GEN_INT (val | ~(HOST_WIDE_INT) 0xffff));
-	  tval = 0xffff;
-	  insns++;
-	}
-      else
-	{
-	  if (generate)
-	    emit_move_insn (gen_rtx_REG (Pmode, regnum),
-			    GEN_INT (val & 0xffff));
-	  tval = 0;
-	  insns++;
-	}
-
-      val >>= 16;
-
-      for (i = 16; i < 64; i += 16)
-	{
-	  if ((val & 0xffff) != tval)
-	    {
-	      if (generate)
-		emit_insn (gen_insv_immdi (gen_rtx_REG (Pmode, regnum),
-					   GEN_INT (i),
-					   GEN_INT (val & 0xffff)));
-	      insns++;
-	    }
-	  val >>= 16;
-	}
-    }
-  return insns;
-}
-
 static void
-aarch64_add_constant (int regnum, int scratchreg, HOST_WIDE_INT delta)
+aarch64_add_constant (machine_mode mode, int regnum, int scratchreg,
+		      HOST_WIDE_INT delta)
 {
   HOST_WIDE_INT mdelta = delta;
-  rtx this_rtx = gen_rtx_REG (Pmode, regnum);
-  rtx scratch_rtx = gen_rtx_REG (Pmode, scratchreg);
+  rtx this_rtx = gen_rtx_REG (mode, regnum);
+  rtx scratch_rtx = gen_rtx_REG (mode, scratchreg);
 
   if (mdelta < 0)
     mdelta = -mdelta;
 
   if (mdelta >= 4096 * 4096)
     {
-      (void) aarch64_build_constant (scratchreg, delta, true);
+      aarch64_internal_mov_immediate (scratch_rtx, GEN_INT (delta), true, mode);
       emit_insn (gen_add3_insn (this_rtx, this_rtx, scratch_rtx));
     }
   else if (mdelta > 0)
@@ -3436,19 +3358,19 @@  aarch64_add_constant (int regnum, int scratchreg, HOST_WIDE_INT delta)
       if (mdelta >= 4096)
 	{
 	  emit_insn (gen_rtx_SET (scratch_rtx, GEN_INT (mdelta / 4096)));
-	  rtx shift = gen_rtx_ASHIFT (Pmode, scratch_rtx, GEN_INT (12));
+	  rtx shift = gen_rtx_ASHIFT (mode, scratch_rtx, GEN_INT (12));
 	  if (delta < 0)
 	    emit_insn (gen_rtx_SET (this_rtx,
-				    gen_rtx_MINUS (Pmode, this_rtx, shift)));
+				    gen_rtx_MINUS (mode, this_rtx, shift)));
 	  else
 	    emit_insn (gen_rtx_SET (this_rtx,
-				    gen_rtx_PLUS (Pmode, this_rtx, shift)));
+				    gen_rtx_PLUS (mode, this_rtx, shift)));
 	}
       if (mdelta % 4096 != 0)
 	{
 	  scratch_rtx = GEN_INT ((delta < 0 ? -1 : 1) * (mdelta % 4096));
 	  emit_insn (gen_rtx_SET (this_rtx,
-				  gen_rtx_PLUS (Pmode, this_rtx, scratch_rtx)));
+				  gen_rtx_PLUS (mode, this_rtx, scratch_rtx)));
 	}
     }
 }
@@ -3473,7 +3395,7 @@  aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
   emit_note (NOTE_INSN_PROLOGUE_END);
 
   if (vcall_offset == 0)
-    aarch64_add_constant (this_regno, IP1_REGNUM, delta);
+    aarch64_add_constant (Pmode, this_regno, IP1_REGNUM, delta);
   else
     {
       gcc_assert ((vcall_offset & (POINTER_BYTES - 1)) == 0);
@@ -3489,7 +3411,7 @@  aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
 	    addr = gen_rtx_PRE_MODIFY (Pmode, this_rtx,
 				       plus_constant (Pmode, this_rtx, delta));
 	  else
-	    aarch64_add_constant (this_regno, IP1_REGNUM, delta);
+	    aarch64_add_constant (Pmode, this_regno, IP1_REGNUM, delta);
 	}
 
       if (Pmode == ptr_mode)
@@ -3503,7 +3425,8 @@  aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
 	  addr = plus_constant (Pmode, temp0, vcall_offset);
       else
 	{
-	  (void) aarch64_build_constant (IP1_REGNUM, vcall_offset, true);
+	  aarch64_internal_mov_immediate (temp1, GEN_INT (vcall_offset), true,
+					  Pmode);
 	  addr = gen_rtx_PLUS (Pmode, temp0, temp1);
 	}