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

📄 ccopt.c

📁 KCC , a good c compiler, write by Ken Harrenstien
💻 C
📖 第 1 页 / 共 5 页
字号:
	p->Pop = P_MOVE;		/* into P_MOVE R,x + P_IBP R */
	r = p->Preg;
	foldmove(p);			/* optimize the P_MOVE */

	/* make P_IBP without optimization */
	p = newcode(PTA_REGIS, P_IBP, 0);
	p->Pr2 = r;
	return;
	}
#endif

    foldplus(n);	/* all optimization failed, fix up the # */
    foldmove(p);	/* and try to improve the ADJBP memory reference */
}

/* OPTLSH(p)	- Attempt to optimize LSH usage.
**	We often get combinations of LSH and AND when dealing with
**	PDP10 compability code.  Someday this could be spiffed up to
**	do LDBs or DPBs.
*/
void
optlsh(p)
PCODE *p;
{
    PCODE *q;
    unsigned long mask;

    if (p->Pop == P_LSH		/* Must be a LSH */
      /* && !prevskips(p) */	/* that isn't skipped */
      && p->Ptype == PTA_RCONST	/* and has constant operand */
      && p->Pvalue < 0		/* and is doing right shift */
      && (q = findrset(before(p), p->Preg)) != NULL)	/* Find instr that sets R */
	{
	if (q->Pop == P_AND		/* If it's AND (we know not skipped) */
	  && q->Ptype == PTV_IMMED	/* with immediate const operand */
	  && (mask = ((unsigned INT)q->Pvalue >> (-p->Pvalue))) <= 0777777L)
	    {

	    /* Fold:			into:
	    **		AND R,[const]		LSH R,-n
	    **		...			...
	    **		LSH R,-n		AND R,[const>>n]
	    ** If const>>n will be small enough to fit in the RH, so we can
	    ** generate ANDI instead of AND.
	    */
	    swappseudo(p,q);		/* Swap AND with LSH */
	    p->Pvalue = mask;		/* Make AND's mask be shifted one */
	    }
	}
}

/* FOLDINC(p)	- Push P_AOS up into the loop it comes from.
**
** Often a for() loop will have a AOS/SOS (and possibly a test) at the bottom.
** The variable is likely to be used in the body of the loop, so for simple
** loops we can merge the AOS in with a previous P_MOVE of the same variable
** (sort of like a reverse common subexpression elimination).
**
**	Fold:	MOVE R,<E>	to:	AOS/SOS R,<E>
**		...			...
**		AOS/SOS S,<E>		--
**
** Intervening instructions must be checked to make sure that
** they do not modify the variable at <E> or the register R,
** and if R is used as an index reg, the offsets need to be fixed up.
** Stack level changes must be tracked so we can be sure whether an
** address reference is to <E> or not.
*/

static void
foldinc(p)
PCODE *p;
{
    INT i;
    int usedreg;
    INT stkoff;
    PCODE *q, *b;

    if (prevskips(p))
	return;

    /* <E> must be something plausible.  Initialize the used-reg mask;
    ** bits which are 0 are safe for use as R.
    */
    switch (p->Ptype & PTF_ADRMODE)
	{
#if 0	/* This isn't supported (probably never called with this anyway) */
	case PTA_REGIS:
	    usedreg = rbits[p->Pr2];
	    break;
#endif
	case PTA_MINDEXED:
	    usedreg = rbits[p->Pindex];
	    break;
	default:
	    return;
	}

    switch (p->Pop)
	{
	case P_AOS:
	    i = -1;
	    break;
	case P_SOS:
	    i = 1;
	    break;
	default:
	    return;
	}

    stkoff = 0;
    q = p;
    while ((q = before(q)) != NULL)
	switch (q->Pop)
	    {
	    case P_PUSH:
		if (q->Preg != R_SP)
		    return;
		++stkoff;
		break;
	    case P_ADJSP:		/* Stack adjustment */
		if (p->Preg == R_SP)
		    stkoff += q->Pvalue;
		break;

	    case P_MOVE:
		if (sameaddr(p, q, stkoff))	/* found what we want? */
		    {
		    if (prevskips(q) || (usedreg&(rbits[q->Preg])))
			return;
		    q->Pop = p->Pop;
		    b = q;
		    do
			{
			b = after(b);
			if ((b->Ptype&PTF_ADRMODE) == PTA_MINDEXED
			  && b->Pindex == q->Preg)
			    b->Poffset += i;
			else if (b->Ptype == PTV_IMMED
			      && b->Preg == q->Preg
			      && b->Pop == P_IMUL)
			    i *= b->Pvalue;
			}
		    while (b != p)
			;
		    i = p->Preg;
		    dropinstr(p);		/* drop extra P_AOS and fix up */
		    code00(P_MOVE, (int) i, q->Preg);
		    return;
		    }
		if (q->Preg == p->Pindex)
		    return;
		usedreg |= rbits[q->Preg];
		continue;

	/* Ops that change a register (or two) */
	    case P_DFAD:
	    case P_DFSB:
	    case P_DFMP:
	    case P_DFDV:
	    case P_DMOVE:
	    case P_DMOVN:
	    case P_IDIV:
	    case P_UIDIV:
	    case P_DFIX:
	    case P_SUBBP:
	    case P_MUL:
	    case P_FADR:
	    case P_FSBR:
	    case P_FMPR:
	    case P_FDVR:
	    case P_ADD:
	    case P_IMUL:
	    case P_SUB:
	    case P_AND:
	    case P_IOR:
	    case P_XOR:
	    case P_ADJBP:
	    case P_LSH:
	    case P_SETCM:
	    case P_MOVN:
	    case P_SETO:
	    case P_SETZ:
	    case P_HRRZ:
	    case P_HLRZ:
	    case P_FIX:
	    case P_FLTR:
	    case P_LDB:
		if ((q->Ptype & PTF_ADRMODE) != PTA_MINDEXED)
		    {
		    usedreg |= rbincode(q);
		    continue;
		    }
		if (q->Preg == p->Pindex || sameaddr(p, q, stkoff))
		    return;
		usedreg |= rbinreg(q);
		continue;

	/* Ops that change memory */
	    case P_POP:
		if (q->Preg != R_SP)
		    return;
		--stkoff;
	    /* Fall thru since op changes mem */
	    case P_MOVEM:
	    case P_DPB:
	    case P_ILDB:
	    case P_IDPB:
	    case P_IBP:
	    case P_FADR+POF_BOTH:
	    case P_FSBR+POF_BOTH:
	    case P_FMPR+POF_BOTH:
	    case P_FDVR+POF_BOTH:
	    case P_ADD+POF_BOTH:
	    case P_IMUL+POF_BOTH:
	    case P_AND+POF_BOTH:
	    case P_XOR+POF_BOTH:
	    case P_IOR+POF_BOTH:
	    case P_AOS:
	    case P_SOS:
	    case P_HRRM:
	    case P_HRLM:
	    case P_MOVN+POF_BOTH:
	    case P_MOVE+POF_BOTH:
	    case P_SETZ+POF_BOTH:
	    case P_SETO+POF_BOTH:
	    case P_SETCM+POF_BOTH:
		if ((q->Ptype & PTF_ADRMODE) != PTA_MINDEXED)
		    {
		    usedreg |= rbincode(q);
		    continue;
		    }
		if (q->Preg == p->Pindex
		  || sameaddr(p, q, stkoff) || alias (p, q, stkoff))
		    return;
		usedreg |= rbinreg(q);
		continue;

	/* Some op type we don't know?
	** Jumps, in particular, come here to simply return and give up the
	** optimization attempt.
	*/
	    default:
		return;
	    }
}

/* FOLDPLUS(p) - Improve instruction used to do addition.
**
**    takes an addition operation (P_ADD, P_ADDB, etc) in the peephole buffer
**    and folds it in with previous instructions, as well as just improving
**    it in itself.
*/

void
foldplus(p)
PCODE *p;
{
    PCODE *q, *b;
    int r;

#if SYS_CSI		/*  Reg linkage */
    if (Register_Preserve (p->Pr2))
	return;			/* avoid faulty optimizations */
    if (p->Pop == P_SUB)	/* Reg linkage optimization */
	if (p->Ptype == PTV_IMMED)
	    {
	    p->Pop = P_ADD;		/* make P_SUBI R,i into P_ADDI R,-i */
	    p->Pvalue = - p->Pvalue;	/* so it can be folded later */
	    }				/* in any case treat like P_ADD here*/
#endif

    if (p->Pop == P_ADD && p->Ptype == PTA_REGIS /* !prevskips */ &&
	(q = before(p)) != NULL && q->Preg == p->Pr2 && !prevskips (q))
	switch (q->Pop)
	    {
	    case P_SUB:
		if (q->Ptype == PTV_IMMED)
		    {
		    q->Pop = P_ADD;		/* make P_SUBI R,i into P_ADDI R,-i */
		    q->Pvalue = - q->Pvalue;	/* so it can be folded later */
		    }				/* in any case treat like P_ADD here */
	    case P_ADD:
	/*
	** fold:  P_ADD S,x
	**        P_ADD R,S
	**
	** into:  P_ADD R,S
	**        P_ADD R,x
	*/

		if ((q->Ptype&PTF_ADRMODE) == PTA_MINDEXED
		  && q->Preg == q->Pindex)
		    return;
		q->Preg = p->Preg;		/* fix up operation */
		swappseudo(p,q);		/* swap the two */
		foldplus(q);			/* optimize earlier code some more */
		q = before(p);			/* pick it up again */
		if (q != NULL && q->Pop == P_MOVE && q->Ptype == PTA_REGIS &&
		    q->Preg == p->Preg)
		    {

	    /*
	    ** fold:  P_MOVE R,S
	    **        P_ADD  R,x
	    **
	    ** into:  P_ADD  S,x
	    **        P_MOVE R,S
	    */
		    p->Preg = (char) (q->Pr2);		/* fix up register again */	// FW KCC-NT
		    swappseudo(p,q);		/* switch them around again */
		    p = q;			/* forget the move, hack the add */
		    }
		break;				/* end case P_ADD, P_SUB */

	    case P_AOS:
	    case P_SOS:
	    case P_MOVE:
	    case P_MOVN:
		if (((q->Ptype & PTF_ADRMODE) == PTA_MINDEXED
		  && q->Pindex == p->Preg) ||
		    (q->Ptype & PTF_IND) || (b = before(q)) == NULL ||
		    ((r = rchange (b->Pop)) != PRC_RCHG && r != PRC_RSET) ||
		    b->Preg != p->Preg || !(b->Ptype & PTF_IMM) || prevskips (b) ||
		    ((b->Ptype & PTF_ADRMODE) == PTA_MINDEXED && q->Preg == b->Pindex))
		    break;

	/*
	** fold:  P_ADDI R,x
	**        P_AOS  S,y
	**        P_ADD  R,S
	**
	** into:  P_AOS  S,y
	**        P_ADDI R,x
	**        P_ADD  R,S
	**
	** so the immediate add can propagate to the list start...
	*/

		swappseudo (b, q);		/* thats all folks! */
	    }					/* end switch(q->Pop) */

    r = p->Preg;			/* remember register */
    q = p;				/* start up just before op */
    if (!prevskips (p))
	while ((q = before(q)) != NULL
	    && !prevskips (q)
	    && q->Preg == r
	    && p->Pop == P_ADD)
	    {
	    switch (q->Pop)
		{
		case P_MOVN:
		case P_SUB:
		case P_SETO:
		case P_SETZ:
		    if (!unsetz (q))
			break;	/* turn into P_MOVE or P_ADD */

		case P_MOVE:
		case P_ADD:
		    switch (p->Ptype)
			{
			case PTV_IMMED:
			    switch (q->Ptype)
				{
				case PTV_IINDEXED:
				case PTV_IMMED:

		    /*
		    ** fold:  P_MOVEI R,addr(i)
		    **        P_ADDI  R,c
		    **
		    ** into:  P_MOVEI R,addr+c(i)
		    */

		    /* 8/91  ensure addr+c is a legal offset */
				    if((q->Poffset +  p->Pvalue) < (1 << 18))
					{
					q->Poffset += p->Pvalue;
					dropinstr(p);	/* poof! */
					p = q;
					}
				    continue;

				case PTA_REGIS:
				    if (q->Pop == P_MOVE)
					{
			/*
			** fold:  P_MOVE  R,S
			**        P_ADDI  R,x
			**
			** into:  P_ADDI  S,x
			**        P_MOVE  R,S
			*/
					if ((q->Ptype&PTF_ADRMODE) == PTA_MINDEXED
					  && q->Preg == q->Pindex)
					    return;

					swappseudo(p, q); /* swap the ops */
					r = q->Preg = (char) (p->Pr2); /* fix reg in P_ADDI */ // FW KCC-NT
					p = q;	/* move back over it */
					}
				default:
				    if (q->Pop == P_ADD)
					continue;
				}			/* end switch(q->Ptype) */
			    break;			/* propagate break to escape loop */

			case PTV_IINDEXED:
			    switch (q->Ptype)
				{
				case PTV_IINDEXED:
				    if ((q->Pptr != NULL && p->Pptr != NULL) ||
					(q->Pindex != 0 && p->Pindex != 0))
					continue;
				case PTV_IMMED:

		    /*
		    ** fold:  P_MOVEI R,c
		    **        P_ADDI  R,addr(i)
		    **
		    ** into:  P_MOVEI R,addr+c(i)
		    */

		    /* 8/91  ensure addr+c is a legal offset */
				    if((p->Poffset +  q->Poffset) < (1 << 18))
					{
					p->Pop = q->Pop;
					q->Pop = P_NOP;
					p->Poffset += q->Poffset;
					if (q->Ptype == PTV_IINDEXED)
					    {
					    if (p->Pptr == NULL)
						p->Pptr = q->Pptr;
					    if (p->Pindex == 0)
						p->Pindex = q->Pindex;
					    }
					}
				    continue;

				case PTA_REGIS:
				    if (q->Pop == P_MOVE)
					{
			/*
			** fold:  P_MOVE  R,S
			**        P_ADDI  R,x
			**
			** into:  P_ADDI  S,x
			**        P_MOVE  R,S
			*/
					swappseudo(p, q); /* swap the ops */
					r = q->Preg = (char) (p->Pr2); /* fix reg in P_ADDI */ // FW KCC-NT
					p = q;	/* move back over it */

⌨️ 快捷键说明

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