⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flow.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (GET_CODE (SET_SRC (x)) == CALL)	return 0;      while (GET_CODE (r) == SUBREG	     || (strict_low_ok && GET_CODE (r) == STRICT_LOW_PART)	     || GET_CODE (r) == ZERO_EXTRACT	     || GET_CODE (r) == SIGN_EXTRACT)	r = SUBREG_REG (r);      if (GET_CODE (r) == REG)	{	  register int regno = REGNO (r);	  register int offset = regno / REGSET_ELT_BITS;	  register int bit = 1 << (regno % REGSET_ELT_BITS);	  return (! (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])		  && (needed[offset] & bit) == 0);	}    }  /* If performing several activities,     insn is dead if each activity is individually dead.     Also, CLOBBERs and USEs can be ignored; a CLOBBER or USE     that's inside a PARALLEL doesn't make the insn worth keeping.  */  else if (code == PARALLEL)    {      register int i = XVECLEN (x, 0);      for (i--; i >= 0; i--)	{	  rtx elt = XVECEXP (x, 0, i);	  if (!insn_dead_p (elt, needed, strict_low_ok)	      && GET_CODE (elt) != CLOBBER	      && GET_CODE (elt) != USE)	    return 0;	}      return 1;    }  /* We do not check CLOBBER or USE here.     An insn consisting of just a CLOBBER or just a USE     should not be deleted.  */  return 0;}/* If X is the last insn in a libcall, and assuming X is dead,   return 1 if the entire library call is dead.   This is true if the source of X is a dead register   (as well as the destination, which we tested already).   If this insn doesn't just copy a register, then we don't   have an ordinary libcall.  In that case, cse could not have   managed to substitute the source for the dest later on,   so we can assume the libcall is dead.  */static intlibcall_dead_p (x, needed)     rtx x;     regset needed;{  register RTX_CODE code = GET_CODE (x);  if (code == SET)    {      register rtx r = SET_SRC (x);      if (GET_CODE (r) == REG)	{	  register int regno = REGNO (r);	  register int offset = regno / REGSET_ELT_BITS;	  register int bit = 1 << (regno % REGSET_ELT_BITS);	  return (needed[offset] & bit) == 0;	}    }  return 1;}/* Return 1 if register REGNO was used before it was set.   In other words, if it is live at function entry.  */intregno_uninitialized (regno)     int regno;{  if (n_basic_blocks == 0)    return 0;  return (basic_block_live_at_start[0][regno / REGSET_ELT_BITS]	  & (1 << (regno % REGSET_ELT_BITS)));}/* 1 if register REGNO was alive at a place where `setjmp' was called   and was set more than once.  Such regs may be clobbered by `longjmp'.  */intregno_clobbered_at_setjmp (regno)     int regno;{  return (reg_n_sets[regno] > 1	  && (regs_live_at_setjmp[regno / REGSET_ELT_BITS]	      & (1 << (regno % REGSET_ELT_BITS))));}/* Process the registers that are set within X.   Their bits are set to 1 in the regset DEAD,   because they are dead prior to this insn.   If INSN is nonzero, it is the insn being processed   and the fact that it is nonzero implies this is the FINAL pass   in propagate_block.  In this case, various info about register   usage is stored, LOG_LINKS fields of insns are set up.  */static void mark_set_1 ();static voidmark_set_regs (needed, dead, x, insn, significant)     regset needed;     regset dead;     rtx x;     rtx insn;     regset significant;{  register RTX_CODE code = GET_CODE (x);  if (code == SET || code == CLOBBER)    mark_set_1 (needed, dead, x, insn, significant);  else if (code == PARALLEL)    {      register int i;      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)	{	  code = GET_CODE (XVECEXP (x, 0, i));	  if (code == SET || code == CLOBBER)	    mark_set_1 (needed, dead, XVECEXP (x, 0, i), insn, significant);	}    }}/* Process a single SET rtx, X.  */static voidmark_set_1 (needed, dead, x, insn, significant)     regset needed;     regset dead;     rtx x;     rtx insn;     regset significant;{  register int regno;  register rtx reg = SET_DEST (x);  int subreg_p = 0;  if (reg == 0)    return;  /* Modifying just one hardware register of a multi-reg value     or just a byte field of a register     does not mean the value from before this insn is now dead.     But it does mean liveness of that register at the end of the block     is significant.  */  while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT	 || GET_CODE (reg) == SIGN_EXTRACT	 || GET_CODE (reg) == STRICT_LOW_PART)    {      if (GET_CODE (reg) == ZERO_EXTRACT	  || GET_CODE (reg) == SIGN_EXTRACT	  || (GET_CODE (reg) == SUBREG	      && REG_SIZE (SUBREG_REG (reg)) > REG_SIZE (reg)))	subreg_p = 1;      reg = XEXP (reg, 0);    }  if (GET_CODE (reg) == REG      && (regno = REGNO (reg), regno != FRAME_POINTER_REGNUM)      && regno != ARG_POINTER_REGNUM      && ! (regno < FIRST_PSEUDO_REGISTER && global_regs[regno]))    /* && regno != STACK_POINTER_REGNUM) -- let's try without this.  */    {      register int offset = regno / REGSET_ELT_BITS;      register int bit = 1 << (regno % REGSET_ELT_BITS);      int is_needed = 0;      /* Mark it as a significant register for this basic block.  */      if (significant)	significant[offset] |= bit;      /* That's all we do, if we are setting only part of the register.  */      if (subreg_p)	return;      /* If entire register being set, mark it as as dead before this insn.  */      dead[offset] |= bit;      /* A hard reg in a wide mode may really be multiple registers.	 If so, mark all of them just like the first.  */      if (regno < FIRST_PSEUDO_REGISTER)	{	  int n;	  /* Nothing below is needed for the stack pointer; get out asap.	     Eg, log links aren't needed, since combine won't use them.  */	  if (regno == STACK_POINTER_REGNUM)	    return;	  n = HARD_REGNO_NREGS (regno, GET_MODE (reg));	  while (--n > 0)	    {	      dead[(regno + n) / REGSET_ELT_BITS]		|= 1 << ((regno + n) % REGSET_ELT_BITS);	      if (significant)		significant[(regno + n) / REGSET_ELT_BITS]		  |= 1 << ((regno + n) % REGSET_ELT_BITS);	      is_needed |= (needed[(regno + n) / REGSET_ELT_BITS]			    & 1 << ((regno + n) % REGSET_ELT_BITS));	    }	}      /* Additional data to record if this is the final pass.  */      if (insn)	{	  register rtx y = reg_next_use[regno];	  register int blocknum = BLOCK_NUM (insn);	  /* If this is a hard reg, record this function uses the reg.	     `combine.c' will get confused if LOG_LINKs are made	     for hard regs.  */	  if (regno < FIRST_PSEUDO_REGISTER)	    {	      register int i;	      i = HARD_REGNO_NREGS (regno, GET_MODE (reg));	      if (i == 0)		i = 1;	      do		regs_ever_live[regno + --i] = 1;	      while (i > 0);	      if (! ((needed[offset] & bit) || is_needed))		{		  /* Note that dead stores have already been deleted if poss.		     If we get here, we have found a dead store that cannot		     be eliminated (because the insn does something useful).		     Indicate this by marking the reg set as dying here.  */		  REG_NOTES (insn)		    = gen_rtx (EXPR_LIST, REG_DEAD,			       reg, REG_NOTES (insn));		  reg_n_deaths[REGNO (reg)]++;		}	      return;	    }	  /* Keep track of which basic blocks each reg appears in.  */	  if (reg_basic_block[regno] == REG_BLOCK_UNKNOWN)	    reg_basic_block[regno] = blocknum;	  else if (reg_basic_block[regno] != blocknum)	    reg_basic_block[regno] = REG_BLOCK_GLOBAL;	  /* Record first insn to use this reg.  */	  reg_first_use[regno] = insn;	  /* Count (weighted) references, stores, etc.  */	  reg_n_refs[regno] += loop_depth;	  reg_n_sets[regno]++;	  /* The next use is no longer "next", since a store intervenes.  */	  reg_next_use[regno] = 0;	  /* The insns where a reg is live are normally counted elsewhere,	     but we want the count to include the insn where the reg is set,	     and the normal counting mechanism would not count it.  */	  reg_live_length[regno]++;	  if ((needed[offset] & bit) || is_needed)	    {	      /* Make a logical link from the next following insn		 that uses this register, back to this insn.		 The following insns have already been processed.  */	      if (y && (BLOCK_NUM (y) == blocknum))		LOG_LINKS (y)		  = gen_rtx (INSN_LIST, VOIDmode, insn, LOG_LINKS (y));	    }	  else	    {	      /* Note that dead stores have already been deleted when possible		 If we get here, we have found a dead store that cannot		 be eliminated (because the same insn does something useful).		 Indicate this by marking the reg being set as dying here.  */	      REG_NOTES (insn)		= gen_rtx (EXPR_LIST, REG_DEAD,			   reg, REG_NOTES (insn));	      reg_n_deaths[REGNO (reg)]++;	    }	}    }}/* Scan expression X and store a 1-bit in LIVE for each reg it uses.   This is done assuming the registers needed from X   are those that have 1-bits in NEEDED.   On the final pass, FINAL is 1.  This means try for autoincrement   and count the uses and deaths of each pseudo-reg.   INSN is the containing instruction.  */static voidmark_used_regs (needed, live, x, final, insn)     regset needed;     regset live;     rtx x;     rtx insn;     int final;{  register RTX_CODE code;  register int regno; retry:  code = GET_CODE (x);  switch (code)    {    case LABEL_REF:    case SYMBOL_REF:    case CONST_INT:    case CONST:    case CONST_DOUBLE:    case CC0:    case PC:    case CLOBBER:    case ADDR_VEC:    case ADDR_DIFF_VEC:    case ASM_INPUT:      return;#if defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT)    case MEM:      /* Here we detect use of an index register which might	 be good for postincrement or postdecrement.  */      if (final)	{	  rtx addr = XEXP (x, 0);	  register int size = GET_MODE_SIZE (GET_MODE (x));	  if (GET_CODE (addr) == REG)	    {	      register rtx y;	      regno = REGNO (addr);	      /* Is the next use an increment that might make auto-increment? */	      y = reg_next_use[regno];	      if (y && GET_CODE (PATTERN (y)) == SET		  && BLOCK_NUM (y) == BLOCK_NUM (insn)		  /* Can't add side effects to jumps; if reg is spilled and		     reloaded, there's no way to store back the altered value.  */		  && GET_CODE (insn) != JUMP_INSN		  && (y = SET_SRC (PATTERN (y)),		      (0#ifdef HAVE_POST_INCREMENT		       || GET_CODE (y) == PLUS#endif#ifdef HAVE_POST_DECREMENT		       || GET_CODE (y) == MINUS#endif		       )		      && XEXP (y, 0) == addr		      && GET_CODE (XEXP (y, 1)) == CONST_INT		      && INTVAL (XEXP (y, 1)) == size)		  && dead_or_set_p (reg_next_use[regno], addr))		{		  rtx use = find_use_as_address (PATTERN (insn), addr, 0);		  /* Make sure this register appears only once in this insn.  */		  if (use != 0 && use != (rtx) 1)		    {		      /* We have found a suitable auto-increment:			 do POST_INC around the register here,			 and patch out the increment instruction that follows. */		      XEXP (x, 0)			= gen_rtx (GET_CODE (y) == PLUS ? POST_INC : POST_DEC,				   Pmode, addr);		      /* Record that this insn has an implicit side effect.  */		      REG_NOTES (insn)			= gen_rtx (EXPR_LIST, REG_INC, addr, REG_NOTES (insn));		      /* Modify the old increment-insn to simply copy			 the already-incremented value of our register.  */		      y = reg_next_use[regno];		      SET_SRC (PATTERN (y)) = addr;		      /* If that makes it a no-op (copying the register			 into itself) then change it to a simpler no-op			 so it won't appear to be a "use" and a "set"			 of this register.  */		      if (SET_DEST (PATTERN (y)) == addr)			PATTERN (y) = gen_rtx (USE, VOIDmode, const0_rtx);		      /* Count an extra reference to the reg for the increment.			 When a reg is incremented.			 spilling it is worse, so we want to make that			 less likely.  */		      reg_n_refs[regno] += loop_depth;		      /* Count the increment as a setting of the register,			 even though it isn't a SET in rtl.  */		      reg_n_sets[regno]++;		    }		}	    }	}      break;#endif /* HAVE_POST_INCREMENT or HAVE_POST_DECREMENT */    case REG:      /* See a register other than being set	 => mark it as needed.  */      regno = REGNO (x);      if (regno != FRAME_POINTER_REGNUM)	  /* && regno != ARG_POINTER_REGNUM) -- and without this.  */	/* && regno != STACK_POINTER_REGNUM) -- let's try without this.  */	{	  register int offset = regno / REGSET_ELT_BITS;	  register int bit = 1 << (regno % REGSET_ELT_BITS);	  int is_needed = 0;	  live[offset] |= bit;	  /* A hard reg in a wide mode may really be multiple registers.	     If so, mark all of them just like the first.  */	  if (regno < FIRST_PSEUDO_REGISTER)	    {	      int n;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -