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]

extract_insn tweek



Hi
Even with caching the extract_insn and asm_noperands are still top CPU eaters
in the non-optimizing compilation.  This patch tweaks them a bit - it just
rewrites body of asm_noperads to case in hope to get better code.  The
extract_insn is rewriten to call asm_noperands only when the asm instruction is
actually detected, so it shots asm_noperads from the top five of most commonly
called functions in gcc.

Wed Sep 20 21:29:41 CEST 2000  Jan Hubicka  <jh@suse.cz>

	* recog.c (asm_noperands): Tweak.
	(extract_insn): Do not call asm_noperads for non-asm instructions.

*** ../../egcs-20000918.orig/gcc/./recog.c	Wed Sep 20 11:18:04 2000
--- ./recog.c	Wed Sep 20 17:30:32 2000
*************** int
*** 1401,1468 ****
  asm_noperands (body)
       rtx body;
  {
!   if (GET_CODE (body) == ASM_OPERANDS)
!     /* No output operands: return number of input operands.  */
!     return ASM_OPERANDS_INPUT_LENGTH (body);
!   if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
!     /* Single output operand: BODY is (set OUTPUT (asm_operands ...)).  */
!     return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body)) + 1;
!   else if (GET_CODE (body) == PARALLEL
! 	   && GET_CODE (XVECEXP (body, 0, 0)) == SET
! 	   && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
      {
!       /* Multiple output operands, or 1 output plus some clobbers:
! 	 body is [(set OUTPUT (asm_operands ...))... (clobber (reg ...))...].  */
!       int i;
!       int n_sets;
! 
!       /* Count backwards through CLOBBERs to determine number of SETs.  */
!       for (i = XVECLEN (body, 0); i > 0; i--)
  	{
! 	  if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
! 	    break;
! 	  if (GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
! 	    return -1;
! 	}
  
!       /* N_SETS is now number of output operands.  */
!       n_sets = i;
  
!       /* Verify that all the SETs we have
! 	 came from a single original asm_operands insn
! 	 (so that invalid combinations are blocked).  */
!       for (i = 0; i < n_sets; i++)
! 	{
! 	  rtx elt = XVECEXP (body, 0, i);
! 	  if (GET_CODE (elt) != SET)
! 	    return -1;
! 	  if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS)
! 	    return -1;
! 	  /* If these ASM_OPERANDS rtx's came from different original insns
! 	     then they aren't allowed together.  */
! 	  if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
! 	      != ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (body, 0, 0))))
! 	    return -1;
  	}
!       return (ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)))
! 	      + n_sets);
!     }
!   else if (GET_CODE (body) == PARALLEL
! 	   && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
!     {
!       /* 0 outputs, but some clobbers:
! 	 body is [(asm_operands ...) (clobber (reg ...))...].  */
!       int i;
! 
!       /* Make sure all the other parallel things really are clobbers.  */
!       for (i = XVECLEN (body, 0) - 1; i > 0; i--)
! 	if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
! 	  return -1;
  
!       return ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
      }
-   else
-     return -1;
  }
  
  /* Assuming BODY is an insn body that uses ASM_OPERANDS,
--- 1401,1475 ----
  asm_noperands (body)
       rtx body;
  {
!   switch (GET_CODE (body))
      {
!     case ASM_OPERANDS:
!       /* No output operands: return number of input operands.  */
!       return ASM_OPERANDS_INPUT_LENGTH (body);
!     case SET:
!       if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
! 	/* Single output operand: BODY is (set OUTPUT (asm_operands ...)).  */
! 	return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body)) + 1;
!       else
! 	return -1;
!     case PARALLEL:
!       if (GET_CODE (XVECEXP (body, 0, 0)) == SET
! 	  && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
  	{
! 	  /* Multiple output operands, or 1 output plus some clobbers:
! 	     body is [(set OUTPUT (asm_operands ...))... (clobber (reg ...))...].  */
! 	  int i;
! 	  int n_sets;
  
! 	  /* Count backwards through CLOBBERs to determine number of SETs.  */
! 	  for (i = XVECLEN (body, 0); i > 0; i--)
! 	    {
! 	      if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
! 		break;
! 	      if (GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
! 		return -1;
! 	    }
  
! 	  /* N_SETS is now number of output operands.  */
! 	  n_sets = i;
! 
! 	  /* Verify that all the SETs we have
! 	     came from a single original asm_operands insn
! 	     (so that invalid combinations are blocked).  */
! 	  for (i = 0; i < n_sets; i++)
! 	    {
! 	      rtx elt = XVECEXP (body, 0, i);
! 	      if (GET_CODE (elt) != SET)
! 		return -1;
! 	      if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS)
! 		return -1;
! 	      /* If these ASM_OPERANDS rtx's came from different original insns
! 	         then they aren't allowed together.  */
! 	      if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
! 		  != ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (body, 0, 0))))
! 		return -1;
! 	    }
! 	  return (ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)))
! 		  + n_sets);
  	}
!       else if (GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
! 	{
! 	  /* 0 outputs, but some clobbers:
! 	     body is [(asm_operands ...) (clobber (reg ...))...].  */
! 	  int i;
! 
! 	  /* Make sure all the other parallel things really are clobbers.  */
! 	  for (i = XVECLEN (body, 0) - 1; i > 0; i--)
! 	    if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
! 	      return -1;
  
! 	  return ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
! 	}
!       else
! 	return -1;
!     default:
!       return -1;
      }
  }
  
  /* Assuming BODY is an insn body that uses ASM_OPERANDS,
*************** extract_insn (insn)
*** 2097,2104 ****
--- 2114,2132 ----
        return;
  
      case SET:
+       if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
+ 	goto asm_insn;
+       else
+ 	goto normal_insn;
      case PARALLEL:
+       if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
+ 	   && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
+ 	  || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
+ 	goto asm_insn;
+       else
+ 	goto normal_insn;
      case ASM_OPERANDS:
+     asm_insn:
        recog_data.n_operands = noperands = asm_noperands (body);
        if (noperands >= 0)
  	{
*************** extract_insn (insn)
*** 2122,2131 ****
  	    }
  	  break;
  	}
! 
!       /* FALLTHROUGH */
  
      default:
        /* Ordinary insn: recognize it, get the operands via insn_extract
  	 and get the constraints.  */
  
--- 2150,2159 ----
  	    }
  	  break;
  	}
!       fatal_insn_not_found (insn);
  
      default:
+     normal_insn:
        /* Ordinary insn: recognize it, get the operands via insn_extract
  	 and get the constraints.  */
  

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