コード例 #1
0
ファイル: type.c プロジェクト: marler8997/dmd
void param_hydrate(param_t **pp)
{
    param_t *p;

    assert(pp);
    if (isdehydrated(*pp))
    {   while (*pp)
        {   assert(isdehydrated(*pp));
            p = (param_t *) ph_hydrate(pp);
            param_debug(p);

            type_hydrate(&p->Ptype);
            if (p->Ptype)
                type_debug(p->Ptype);
            ph_hydrate(&p->Pident);
            if (CPP)
            {
                el_hydrate(&p->Pelem);
                if (p->Pelem)
                    elem_debug(p->Pelem);
                type_hydrate(&p->Pdeftype);
                if (p->Pptpl)
                    param_hydrate(&p->Pptpl);
                if (p->Psym)
                    symbol_hydrate(&p->Psym);
                if (p->PelemToken)
                    token_hydrate(&p->PelemToken);
            }

            pp = &p->Pnext;
        }
    }
}
コード例 #2
0
ファイル: s2ir.c プロジェクト: Rayerd/dmd
void el_setVolatile(elem *e)
{
    elem_debug(e);
    while (1)
    {
        e->Ety |= mTYvolatile;
        if (OTunary(e->Eoper))
            e = e->E1;
        else if (OTbinary(e->Eoper))
        {   el_setVolatile(e->E2);
            e = e->E1;
        }
        else
            break;
    }
}
コード例 #3
0
ファイル: msc.c プロジェクト: shoo/dmd
elem *exp2_copytotemp(elem *e)
{
    //printf("exp2_copytotemp()\n");
    elem_debug(e);
    Symbol *stmp = symbol_genauto(e);
    elem *eeq = el_bin(OPeq,e->Ety,el_var(stmp),e);
    elem *er = el_bin(OPcomma,e->Ety,eeq,el_var(stmp));
    if (tybasic(e->Ety) == TYstruct || tybasic(e->Ety) == TYarray)
    {
        eeq->Eoper = OPstreq;
        eeq->ET = e->ET;
        eeq->E1->ET = e->ET;
        er->ET = e->ET;
        er->E2->ET = e->ET;
    }
    return er;
}
コード例 #4
0
ファイル: cgcs.c プロジェクト: Abscissa/dmd
STATIC unsigned cs_comphash(elem *e)
{   register int hash;
    unsigned op;

    elem_debug(e);
    op = e->Eoper;
#if TX86
    hash = (e->Ety & (mTYbasic | mTYconst | mTYvolatile)) + (op << 8);
#else
    hash = e->Ety + op;
#endif
    if (!OTleaf(op))
    {   hash += (size_t) e->E1;
        if (OTbinary(op))
                hash += (size_t) e->E2;
    }
    else
    {   hash += e->EV.Vint;
        if (op == OPvar || op == OPrelconst)
                hash += (size_t) e->EV.sp.Vsym;
    }
    return hash;
}
コード例 #5
0
ファイル: type.c プロジェクト: michelf/dmd
void param_hydrate(param_t **pp)
{
    param_t *p;

    assert(pp);
    if (isdehydrated(*pp))
    {   while (*pp)
        {   assert(isdehydrated(*pp));
            p = (param_t *) ph_hydrate(pp);
#if SOURCE_4PARAMS
            p->Psrcpos.Sfilnum += File_Hydrate_Num;     /* file number relative header build */
#endif
            param_debug(p);

            type_hydrate(&p->Ptype);
            if (p->Ptype)
                type_debug(p->Ptype);
            ph_hydrate(&p->Pident);
            if (CPP)
            {
                el_hydrate(&p->Pelem);
                if (p->Pelem)
                    elem_debug(p->Pelem);
                type_hydrate(&p->Pdeftype);
                if (p->Pptpl)
                    param_hydrate(&p->Pptpl);
                if (p->Psym)
                    symbol_hydrate(&p->Psym);
                if (p->PelemToken)
                    token_hydrate(&p->PelemToken);
            }

            pp = &p->Pnext;
        }
    }
}
コード例 #6
0
ファイル: cgcs.c プロジェクト: Abscissa/dmd
STATIC void ecom(elem **pe)
{ int i,op,hcstopsave;
  unsigned hash;
  elem *e,*ehash;
  tym_t tym;

  e = *pe;
  assert(e);
  elem_debug(e);
#ifdef DEBUG
  assert(e->Ecount == 0);
  //assert(e->Ecomsub == 0);
#endif
  tym = tybasic(e->Ety);
  op = e->Eoper;
  switch (op)
  {
    case OPconst:
    case OPvar:
    case OPrelconst:
        break;
    case OPstreq:
    case OPpostinc:
    case OPpostdec:
    case OPeq:
    case OPaddass:
    case OPminass:
    case OPmulass:
    case OPdivass:
    case OPmodass:
    case OPshrass:
    case OPashrass:
    case OPshlass:
    case OPandass:
    case OPxorass:
    case OPorass:
#if TX86
        /* Reverse order of evaluation for double op=. This is so that  */
        /* the pushing of the address of the second operand is easier.  */
        /* However, with the 8087 we don't need the kludge.             */
        if (op != OPeq && tym == TYdouble && !config.inline8087)
        {       if (EOP(e->E1))
                        ecom(&e->E1->E1);
                ecom(&e->E2);
        }
        else
#endif
        {
            /* Don't mark the increment of an i++ or i-- as a CSE, if it */
            /* can be done with an INC or DEC instruction.               */
            if (!(OTpost(op) && elemisone(e->E2)))
                ecom(&e->E2);           /* evaluate 2nd operand first   */
    case OPnegass:
            if (EOP(e->E1))             /* if lvalue is an operator     */
            {
#ifdef DEBUG
                if (e->E1->Eoper != OPind)
                    elem_print(e);
#endif
                assert(e->E1->Eoper == OPind);
                ecom(&(e->E1->E1));
            }
        }
        touchlvalue(e->E1);
        if (!OTpost(op))                /* lvalue of i++ or i-- is not a cse*/
        {
            hash = cs_comphash(e->E1);
            vec_setbit(hash % CSVECDIM,csvec);
            addhcstab(e->E1,hash);              // add lvalue to hcstab[]
        }
        return;

    case OPbtc:
    case OPbts:
    case OPbtr:
        ecom(&e->E1);
        ecom(&e->E2);
        touchfunc(0);                   // indirect assignment
        return;

    case OPandand:
    case OPoror:
        ecom(&e->E1);
        hcstopsave = hcstop;
        ecom(&e->E2);
        hcstop = hcstopsave;            /* no common subs by E2         */
        return;                         /* if comsub then logexp() will */
                                        /* break                        */
    case OPcond:
        ecom(&e->E1);
        hcstopsave = hcstop;
        ecom(&e->E2->E1);               /* left condition               */
        hcstop = hcstopsave;            /* no common subs by E2         */
        ecom(&e->E2->E2);               /* right condition              */
        hcstop = hcstopsave;            /* no common subs by E2         */
        return;                         /* can't be a common sub        */
    case OPcall:
    case OPcallns:
        ecom(&e->E2);                   /* eval right first             */
        /* FALL-THROUGH */
    case OPucall:
    case OPucallns:
        ecom(&e->E1);
        touchfunc(1);
        return;
    case OPstrpar:                      /* so we don't break logexp()   */
#if TX86
    case OPinp:                 /* never CSE the I/O instruction itself */
#endif
    case OPdctor:
        ecom(&e->E1);
        /* FALL-THROUGH */
    case OPasm:
    case OPstrthis:             // don't CSE these
    case OPframeptr:
    case OPgot:
    case OPctor:
    case OPdtor:
    case OPmark:
        return;

    case OPddtor:
        return;

    case OPparam:
#if TX86
    case OPoutp:
#endif
        ecom(&e->E1);
    case OPinfo:
        ecom(&e->E2);
        return;
    case OPcomma:
    case OPremquo:
        ecom(&e->E1);
        ecom(&e->E2);
        break;
#if TARGET_SEGMENTED
    case OPvp_fp:
    case OPcvp_fp:
        ecom(&e->E1);
        touchaccess(e);
        break;
#endif
    case OPind:
        ecom(&e->E1);
        /* Generally, CSEing a *(double *) results in worse code        */
        if (tyfloating(tym))
            return;
        break;
#if TX86
    case OPstrcpy:
    case OPstrcat:
    case OPmemcpy:
    case OPmemset:
        ecom(&e->E2);
    case OPsetjmp:
        ecom(&e->E1);
        touchfunc(0);
        return;
#endif
    default:                            /* other operators */
#if TX86
#ifdef DEBUG
        if (!EBIN(e)) WROP(e->Eoper);
#endif
        assert(EBIN(e));
    case OPadd:
    case OPmin:
    case OPmul:
    case OPdiv:
    case OPor:
    case OPxor:
    case OPand:
    case OPeqeq:
    case OPne:
    case OPscale:
    case OPyl2x:
    case OPyl2xp1:
        ecom(&e->E1);
        ecom(&e->E2);
        break;
#else
#ifdef DEBUG
        if (!EOP(e)) WROP(e->Eoper);
#endif
        assert(EOP(e));
        ecom(&e->E1);
        if (EBIN(e))
                ecom(&e->E2);           /* eval left first              */
        break;
#endif
    case OPstring:
    case OPaddr:
    case OPbit:
#ifdef DEBUG
        WROP(e->Eoper);
        elem_print(e);
#endif
        assert(0);              /* optelem() should have removed these  */
        /* NOTREACHED */

    // Explicitly list all the unary ops for speed
    case OPnot: case OPcom: case OPneg: case OPuadd:
    case OPabs: case OPsqrt: case OPrndtol: case OPsin: case OPcos: case OPrint:
    case OPpreinc: case OPpredec:
    case OPbool: case OPstrlen: case OPs16_32: case OPu16_32:
    case OPd_s32: case OPd_u32:
    case OPs32_d: case OPu32_d: case OPd_s16: case OPs16_d: case OP32_16:
    case OPd_f: case OPf_d:
    case OPd_ld: case OPld_d:
    case OPc_r: case OPc_i:
    case OPu8_16: case OPs8_16: case OP16_8:
    case OPu32_64: case OPs32_64: case OP64_32: case OPmsw:
    case OPu64_128: case OPs64_128: case OP128_64:
    case OPd_s64: case OPs64_d: case OPd_u64: case OPu64_d:
    case OPstrctor: case OPu16_d: case OPd_u16:
    case OParrow:
    case OPvoid: case OPnullcheck:
    case OPbsf: case OPbsr: case OPbswap:
    case OPld_u64:
#if TARGET_SEGMENTED
    case OPoffset: case OPnp_fp: case OPnp_f16p: case OPf16p_np:
#endif
        ecom(&e->E1);
        break;
    case OPhalt:
        return;
  }

  /* don't CSE structures or unions or volatile stuff   */
  if (tym == TYstruct ||
      tym == TYvoid ||
      e->Ety & mTYvolatile
#if TX86
    // don't CSE doubles if inline 8087 code (code generator can't handle it)
      || (tyfloating(tym) && config.inline8087)
#endif
     )
        return;

  hash = cs_comphash(e);                /* must be AFTER leaves are done */

  /* Search for a match in hcstab[].
   * Search backwards, as most likely matches will be towards the end
   * of the list.
   */

#ifdef DEBUG
  if (debugx) dbg_printf("elem: %p hash: %6d\n",e,hash);
#endif
  int csveci = hash % CSVECDIM;
  if (vec_testbit(csveci,csvec))
  {
    for (i = hcstop; i--;)
    {
#ifdef DEBUG
        if (debugx)
            dbg_printf("i: %2d Hhash: %6d Helem: %p\n",
                i,hcstab[i].Hhash,hcstab[i].Helem);
#endif
        if (hash == hcstab[i].Hhash && (ehash = hcstab[i].Helem) != NULL)
        {
            /* if elems are the same and we still have room for more    */
            if (el_match(e,ehash) && ehash->Ecount < 0xFF)
            {
                /* Make sure leaves are also common subexpressions
                 * to avoid false matches.
                 */
                if (!OTleaf(op))
                {
                    if (!e->E1->Ecount)
                        continue;
                    if (OTbinary(op) && !e->E2->Ecount)
                        continue;
                }
                ehash->Ecount++;
                *pe = ehash;
#ifdef DEBUG
                if (debugx)
                        dbg_printf("**MATCH** %p with %p\n",e,*pe);
#endif
                el_free(e);
                return;
            }
        }
    }
  }
  else
    vec_setbit(csveci,csvec);
  addhcstab(e,hash);                    // add this elem to hcstab[]
}