Exemplo n.º 1
0
Arquivo: cgcs.c Projeto: Kozzi11/dmd
STATIC void touchlvalue(elem *e)
{
  if (e->Eoper == OPind)                /* if indirect store            */
  {
        /* NOTE: Some types of array assignments do not need
         * to touch all variables. (Like a[5], where a is an
         * array instead of a pointer.)
         */

        touchfunc(0);
        return;
  }

    for (int i = hcsarray.top; --i >= 0;)
    {   if (hcstab[i].Helem &&
            hcstab[i].Helem->EV.sp.Vsym == e->EV.sp.Vsym)
                hcstab[i].Helem = NULL;
    }

    if (!(e->Eoper == OPvar || e->Eoper == OPrelconst))
        elem_print(e);
    assert(e->Eoper == OPvar || e->Eoper == OPrelconst);
    switch (e->EV.sp.Vsym->Sclass)
    {
        case SCregpar:
        case SCregister:
        case SCpseudo:
            break;
        case SCauto:
        case SCparameter:
        case SCfastpar:
        case SCshadowreg:
        case SCbprel:
            if (e->EV.sp.Vsym->Sflags & SFLunambig)
                break;
            /* FALL-THROUGH */
        case SCstatic:
        case SCextern:
        case SCglobal:
        case SClocstat:
        case SCcomdat:
        case SCinline:
        case SCsinline:
        case SCeinline:
        case SCcomdef:
            touchstar();
            break;
        default:
            elem_print(e);
            symbol_print(e->EV.sp.Vsym);
            assert(0);
    }
}
Exemplo n.º 2
0
void list_print(FILE* fp, const List* list)
{
   ListElem* le;
   
   for(le = list->anchor.next; le != &list->anchor; le = le->next)
   {
      switch(list->type)
      {
      case LIST_ELEM :
         elem_print(fp, le->data.elem, TRUE);
         break;
      case LIST_TUPLE :
         tuple_print(fp, le->data.tuple);
         break;
      case LIST_ENTRY :
         entry_print(fp, le->data.entry);
         break;
      case LIST_LIST :
         list_print(fp, le->data.list);
         break;
      default :
         abort();
      }
      fprintf(fp, "\n");
   }
}
Exemplo n.º 3
0
void dbg_optprint(char *title)
{
    block *b;
    for (b = startblock; b; b = b->Bnext)
        if (b->Belem)
        {
            dbg_printf("%s\n",title);
            elem_print(b->Belem);
        }
}
void dyntab_print(const dyntab* tab, void (*elem_print)(const void* elem))
{
    printf("[ ") ;
    for(size_t i = 0; i < tab->size; ++i)
    {
        elem_print(tab->data + i * tab->bytes) ;
        printf(" ") ;
    }
    printf("]\n") ;
}
Exemplo n.º 5
0
std::ostream& print(std::ostream& os, const ivl::array<T, S>& in)
{
	array_details::print_init<T> init(os);

	os << "[ " ;
	for(typename ivl::array<T, S>::const_iterator it = in.begin();
		it != in.end(); it++) {
			elem_print(os, *it);
		}
	os << "]";

	return os;
}
Exemplo n.º 6
0
bool ofc_parse_list_print(
	ofc_colstr_t* cs,
	unsigned elem_count, const void** elem,
	bool (*elem_print)(ofc_colstr_t*, const void*))
{
	if (!elem || !elem_print)
		return false;

	unsigned i;
	for (i = 0; i < elem_count; i++)
	{
		if ((i > 0) && !ofc_colstr_atomic_writef(cs, ", "))
			return false;

		if (!elem_print(cs, elem[i]))
			return false;
	}

	return true;
}
Exemplo n.º 7
0
Arquivo: type.c Projeto: michelf/dmd
void param_t::print()
{
    dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Psym=%p,Pnext=%p\n",Pident,Ptype,Pelem,Psym,Pnext);
    if (Pident)
        dbg_printf("\tPident = '%s'\n", Pident);
    if (Ptype)
    {   dbg_printf("\tPtype =\n");
        type_print(Ptype);
    }
    if (Pelem)
    {   dbg_printf("\tPelem =\n");
        elem_print(Pelem);
    }
    if (Pdeftype)
    {   dbg_printf("\tPdeftype =\n");
        type_print(Pdeftype);
    }
    if (Psym)
    {   dbg_printf("\tPsym = '%s'\n", Psym->Sident);
    }
    if (Pptpl)
    {   dbg_printf("\tPptpl = %p\n", Pptpl);
    }
}
Exemplo n.º 8
0
Arquivo: cgcs.c Projeto: 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[]
}
int main()
{
    flint_rand_t state;
    long iter;

    printf("poly_divrem_basecase....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 10000; iter++)
    {
        ring_t ZZ, ZZp, ZZpx[3];
        ring_struct * ring;
        elem_ptr p;
        long size[3];
        elem_poly_t A, B, C, Q, Q2, R, R2;

        ring_init_limb(ZZ);
        ELEM_TMP_INIT(p, ZZ);
        elem_set_ui(p, n_randtest_prime(state, 0), ZZ);
        ring_init_mod(ZZp, ZZ, p);
        ring_init_poly(ZZpx[0], ZZp);
        ring_init_poly(ZZpx[1], ZZpx[0]);
        ring_init_poly(ZZpx[2], ZZpx[1]);

        ring = ZZpx[n_randint(state, 2)];

        size[0] = 1 + n_randint(state, 30);
        size[1] = 1 + n_randint(state, 30);
        size[2] = 1 + n_randint(state, 30);

        elem_init(A, ring);
        elem_init(B, ring);
        elem_init(C, ring);
        elem_init(Q, ring);
        elem_init(Q2, ring);
        elem_init(R, ring);
        elem_init(R2, ring);

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_mul(C, A, B, ring);

        elem_poly_divrem_basecase(Q, R, C, B, ring);
        if (!elem_equal(Q, A, ring) || !elem_is_zero(R, ring))
        {
            printf("FAIL: (A * B) / B = A\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            elem_print(R, ring); printf("\n\n");
            abort();
        }

        elem_divrem(Q, R, A, B, ring);
        elem_mul(C, Q, B, ring);
        elem_add(C, C, R, ring);
        if (!elem_equal(C, A, ring))
        {
            printf("FAIL: Q * B + R = A\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            elem_print(R, ring); printf("\n\n");
            abort();
        }

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_poly_divrem_basecase(Q, R, A, B, ring);
        elem_poly_divrem_basecase(A, R2, A, B, ring);
        if (!elem_equal(A, Q, ring) || !elem_equal(R, R2, ring))
        {
            printf("FAIL: aliasing Q, A\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            elem_print(R, ring); printf("\n\n");
            elem_print(R2, ring); printf("\n\n");
            abort();
        }

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_poly_divrem_basecase(Q, R, A, B, ring);
        elem_poly_divrem_basecase(Q2, A, A, B, ring);
        if (!elem_equal(A, R, ring) || !elem_equal(Q, Q2, ring))
        {
            printf("FAIL: aliasing R, A\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            elem_print(Q2, ring); printf("\n\n");
            elem_print(R, ring); printf("\n\n");
            abort();
        }

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_poly_divrem_basecase(Q, R, A, B, ring);
        elem_poly_divrem_basecase(Q2, B, A, B, ring);
        if (!elem_equal(B, R, ring) || !elem_equal(Q, Q2, ring))
        {
            printf("FAIL: aliasing R, B\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            elem_print(Q2, ring); printf("\n\n");
            elem_print(R, ring); printf("\n\n");
            abort();
        }

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_poly_divrem_basecase(Q, R, A, B, ring);
        elem_poly_divrem_basecase(B, R2, A, B, ring);
        if (!elem_equal(B, Q, ring) || !elem_equal(R, R2, ring))
        {
            printf("FAIL: aliasing Q, B\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            elem_print(R, ring); printf("\n\n");
            elem_print(R2, ring); printf("\n\n");
            abort();
        }

        elem_clear(A, ring);
        elem_clear(B, ring);
        elem_clear(C, ring);
        elem_clear(Q, ring);
        elem_clear(Q2, ring);
        elem_clear(R, ring);
        elem_clear(R2, ring);

        ring_clear(ZZpx[2]);
        ring_clear(ZZpx[1]);
        ring_clear(ZZpx[0]);
        ring_clear(ZZp);
        ELEM_TMP_CLEAR(p, ZZ);
        ring_clear(ZZ);
    }

    printf("PASS\n");
    flint_randclear(state);
    return EXIT_SUCCESS;
}
Exemplo n.º 10
0
void optfunc()
{
#if !HTOD
    block *b;
    int iter;           // iteration count
    clock_t starttime;

    cmes ("optfunc()\n");
    dbg_optprint("optfunc\n");
#ifdef DEBUG
    if (debugb)
    {
        dbg_printf("................Before optimization.........\n");
        WRfunc();
    }
#endif
    iter = 0;

    if (localgot)
    {   // Initialize with:
        //      localgot = OPgot;
        elem *e = el_long(TYnptr, 0);
        e->Eoper = OPgot;
        e = el_bin(OPeq, TYnptr, el_var(localgot), e);
        startblock->Belem = el_combine(e, startblock->Belem);
    }

    // Each pass through the loop can reduce only one level of comma expression.
    // The infinite loop check needs to take this into account.
    int iterationLimit = 0;
    for (b = startblock; b; b = b->Bnext)
    {
        if (!b->Belem)
            continue;
        int d = el_countCommas(b->Belem);
        if (d > iterationLimit)
            iterationLimit = d;
    }

    // Some functions can take enormous amounts of time to optimize.
    // We try to put a lid on it.
    starttime = clock();
    do
    {
        //printf("iter = %d\n", iter);
#if TX86
        if (++iter > 200)
        {   assert(iter < iterationLimit);      // infinite loop check
            break;
        }
#else
     L1:
#endif
#if MARS
        util_progress();
#else
        file_progress();
#endif

        //printf("optelem\n");
        /* canonicalize the trees        */
        for (b = startblock; b; b = b->Bnext)
            if (b->Belem)
            {
#if DEBUG
                if(debuge)
                {
                    dbg_printf("before\n");
                    elem_print(b->Belem);
                    //el_check(b->Belem);
                }
#endif
                b->Belem = doptelem(b->Belem,bc_goal[b->BC] | GOALagain);
#if DEBUG
                if(0 && debugf)
                {
                    dbg_printf("after\n");
                    elem_print(b->Belem);
                }
#endif
            }
        //printf("blockopt\n");
#if TX86
        if (mfoptim & MFdc)
            blockopt(0);                // do block optimization
        out_regcand(&globsym);          // recompute register candidates
        changes = 0;                    /* no changes yet                */
        if (mfoptim & MFcnp)
            constprop();                /* make relationals unsigned     */
        if (mfoptim & (MFli | MFliv))
#else
        if (config.optimized && (mfoptim & MFdc))
            blockopt(0);                // do block optimization

        dbg_optprint("blockopt\n");
        out_regcand();                  // recompute register candidates
        changes = 0;                    /* no changes yet                */

        dbg_optprint("constprop\n");
        if (config.optimized && (mfoptim & MFcnp))
            constprop();                /* make relationals unsigned     */

        dbg_optprint("loopopt\n");
        if (config.optimized && (mfoptim & (MFli | MFliv)))
#endif
            loopopt();                  /* remove loop invariants and    */
                                        /* induction vars                */
                                        /* do loop rotation              */
        else
            for (b = startblock; b; b = b->Bnext)
                b->Bweight = 1;
        dbg_optprint("boolopt\n");
#if TX86
        if (mfoptim & MFcnp)
            boolopt();                  // optimize boolean values
        if (changes && mfoptim & MFloop && (clock() - starttime) < 30 * CLOCKS_PER_SEC)
            continue;

        if (mfoptim & MFcnp)
            constprop();                /* constant propagation          */
        if (mfoptim & MFcp)
            copyprop();                 /* do copy propagation           */

        /* Floating point constants and string literals need to be
         * replaced with loads from variables in read-only data.
         * This can result in localgot getting needed.
         */
        symbol *localgotsave = localgot;
        for (b = startblock; b; b = b->Bnext)
        {
            if (b->Belem)
            {
                b->Belem = doptelem(b->Belem,bc_goal[b->BC] | GOALstruct);
                if (b->Belem)
                    b->Belem = el_convert(b->Belem);
            }
        }
        if (localgot != localgotsave)
        {   /* Looks like we did need localgot, initialize with:
             *  localgot = OPgot;
             */
            elem *e = el_long(TYnptr, 0);
            e->Eoper = OPgot;
            e = el_bin(OPeq, TYnptr, el_var(localgot), e);
            startblock->Belem = el_combine(e, startblock->Belem);
        }

        /* localize() is after localgot, otherwise we wind up with
         * more than one OPgot in a function, which mucks up OSX
         * code generation which assumes at most one (localgotoffset).
         */
        if (mfoptim & MFlocal)
            localize();                 // improve expression locality
        if (mfoptim & MFda)
            rmdeadass();                /* remove dead assignments       */

        cmes2 ("changes = %d\n", changes);
        if (!(changes && mfoptim & MFloop && (clock() - starttime) < 30 * CLOCKS_PER_SEC))
            break;
    } while (1);
    cmes2("%d iterations\n",iter);
    if (mfoptim & MFdc)
        blockopt(1);                    // do block optimization
#else
        if (config.optimized && (mfoptim & MFcnp))
            boolopt();                  // optimize boolean values
        util_progress();
        if (changes)
            goto L1;

        dbg_optprint("constprop\n");
        if (config.optimized && (mfoptim & MFcnp))
            constprop();                /* constant propagation          */

        dbg_optprint("copyprop\n");
        if (config.optimized && (mfoptim & MFcp))
            copyprop();                 /* do copy propagation           */

        dbg_optprint("localize\n");
        if (config.optimized && (mfoptim & MFlocal))
            localize();                 // improve expression locality

        dbg_optprint("rmdeadass\n");
        if (config.optimized && (mfoptim & MFda))
            rmdeadass();                /* remove dead assignments       */
        cmes2 ("changes = %d\n", changes);
        iter++;
        assert (iter < 80);             /* infinite loop check           */
    } while (changes && (config.optimized) && (mfoptim & MFloop));
Exemplo n.º 11
0
STATIC void touchlvalue(elem *e)
{ register int i;

  if (e->Eoper == OPind)                /* if indirect store            */
  {
        /* NOTE: Some types of array assignments do not need
         * to touch all variables. (Like a[5], where a is an
         * array instead of a pointer.)
         */

        touchfunc(0);
        return;
  }

  for (i = hcstop; --i >= 0;)
  {     if (hcstab[i].Helem &&
#if TARGET_MAC  // Vsym should be valid before compare
            !EOP(hcstab[i].Helem) &&
            hcstab[i].Helem->Eoper != OPconst &&
#endif
            hcstab[i].Helem->EV.sp.Vsym == e->EV.sp.Vsym)
                hcstab[i].Helem = NULL;
  }

    assert(e->Eoper == OPvar || e->Eoper == OPrelconst);
    switch (e->EV.sp.Vsym->Sclass)
    {
        case SCregpar:
        case SCregister:
        case SCtmp:
        case SCpseudo:
            break;
        case SCauto:
        case SCparameter:
#if TX86
        case SCfastpar:
        case SCbprel:
#endif
            if (e->EV.sp.Vsym->Sflags & SFLunambig)
                break;
            /* FALL-THROUGH */
        case SCstatic:
        case SCextern:
        case SCglobal:
        case SClocstat:
        case SCcomdat:
        case SCinline:
        case SCsinline:
        case SCeinline:
#if TX86
        case SCcomdef:
#endif
            touchstar();
            break;
        default:
#ifdef DEBUG
            elem_print(e);
            symbol_print(e->EV.sp.Vsym);
#endif
            assert(0);
    }
}
Exemplo n.º 12
0
char *template_mangle(symbol *s,param_t *arglist)
{
    /*  mangling ::= '$' template_name { type | expr }
        type ::= "T" mangled type
        expr ::= integer | string | address | float | double | long_double
        integer ::= "I" dimension
        string ::= "S" string
        address ::= "R" zname
        float ::= "F" hex_digits
        double ::= "D" hex_digits
        long_double ::= "L" hex_digits
     */
    param_t *p;

    assert(s);
    symbol_debug(s);
    //assert(s->Sclass == SCtemplate);

    //printf("\ntemplate_mangle(s = '%s', arglist = %p)\n", s->Sident, arglist);
    //arglist->print_list();

    MangleInuse m;
    mangle.znamei = 0;
    mangle.argi = 0;
    mangle.np = mangle.buf;
    mangle.buf[BUFIDMAX + 1] = 0x55;

    if (NEWTEMPMANGLE)
        STR("?$");
    else
        CHAR('$');

    // BUG: this is for templates nested inside class scopes.
    // Need to check if it creates names that are properly unmanglable.
    cpp_zname(s->Sident);
    if (s->Sscope)
        cpp_scope(s->Sscope);

    for (p = arglist; p; p = p->Pnext)
    {
        if (p->Ptype)
        {   /* Argument is a type       */
            if (!NEWTEMPMANGLE)
                CHAR('T');
            cpp_argument_list(p->Ptype, 1);
        }
        else if (p->Psym)
        {
            CHAR('V');  // this is a 'class' name, but it should be a 'template' name
            cpp_ecsu_name(p->Psym);
        }
        else
        {   /* Argument is an expression        */
            elem *e = p->Pelem;
            tym_t ty = tybasic(e->ET->Tty);
            char *p;
            char a[2];
            int ni;
            char c;

        L2:
            switch (e->Eoper)
            {   case OPconst:
                    switch (ty)
                    {   case TYfloat:   ni = FLOATSIZE;  c = 'F'; goto L1;
                        case TYdouble_alias:
                        case TYdouble:  ni = DOUBLESIZE; c = 'D'; goto L1;
                        case TYldouble: ni = LNGDBLSIZE; c = 'L'; goto L1;
                        L1:
                            if (NEWTEMPMANGLE)
                                CHAR('$');
                            CHAR(c);
                            p = (char *)&e->EV.Vdouble;
                            while (ni--)
                            {   char c;
#if __GNUC__
                                static char hex[16] =
                                    {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
#else
                                static char hex[16] = "0123456789ABCDEF";
#endif

                                c = *p++;
                                CHAR(hex[c & 15]);
                                CHAR(hex[(c >> 4) & 15]);
                            }
                            break;
                        default:
#ifdef DEBUG
                            if (!tyintegral(ty) && !tymptr(ty))
                                elem_print(e);
#endif
                            assert(tyintegral(ty) || tymptr(ty));
                            if (NEWTEMPMANGLE)
                                STR("$0");
                            else
                                CHAR('I');
                            cpp_dimension(el_tolongt(e));
                            break;
                    }
                    break;
                case OPstring:
                    if (NEWTEMPMANGLE)
                        STR("$S");
                    else
                        CHAR('S');
                    if (e->EV.ss.Voffset)
                        synerr(EM_const_init);          // constant initializer expected
                    cpp_string(e->EV.ss.Vstring,e->EV.ss.Vstrlen);
                    break;
                case OPrelconst:
                    if (e->EV.sp.Voffset)
                        synerr(EM_const_init);          // constant initializer expected
                    s = e->EV.sp.Vsym;
                    if (NEWTEMPMANGLE)
                    {   STR("$1");
                        cpp_decorated_name(s);
                    }
                    else
                    {   CHAR('R');
                        cpp_zname(s->Sident);
                    }
                    break;
                case OPvar:
                    if (e->EV.sp.Vsym->Sflags & SFLvalue &&
                        tybasic(e->ET->Tty) != TYstruct)
                    {
                        e = e->EV.sp.Vsym->Svalue;
                        goto L2;
                    }
                    else if (e->EV.sp.Vsym->Sclass == SCconst /*&&
                             pstate.STintemplate*/)
                    {
                        CHAR('V');              // pretend to be a class name
                        cpp_zname(e->EV.sp.Vsym->Sident);
                        break;
                    }
                default:
#if SCPP
#ifdef DEBUG
                    if (!errcnt)
                        elem_print(e);
#endif
                    synerr(EM_const_init);              // constant initializer expected
                    assert(errcnt);
#endif
                    break;
            }
        }
    }
    *mangle.np = 0;
    //printf("template_mangle() = '%s'\n", mangle.buf);
    assert(strlen(mangle.buf) <= BUFIDMAX);
    assert(mangle.buf[BUFIDMAX + 1] == 0x55);
    return mangle.buf;
}
Exemplo n.º 13
0
Arquivo: cgxmm.c Projeto: davispuh/dmd
code *cdvector(elem *e, regm_t *pretregs)
{
    /* e should look like one of:
     *    vector
     *      |
     *    param
     *    /   \
     *  param op2
     *  /   \
     * op   op1
     */

    if (!config.fpxmmregs)
    {   printf("SIMD operations not supported on this platform\n");
        exit(1);
    }

    unsigned n = el_nparams(e->E1);
    elem **params = (elem **)malloc(n * sizeof(elem *));
    assert(params);
    elem **tmp = params;
    el_paramArray(&tmp, e->E1);

#if 0
    printf("cdvector()\n");
    for (int i = 0; i < n; i++)
    {
        printf("[%d]: ", i);
        elem_print(params[i]);
    }
#endif

    if (*pretregs == 0)
    {   /* Evaluate for side effects only
         */
        CodeBuilder cdb;
        for (int i = 0; i < n; i++)
        {
            cdb.append(codelem(params[i], pretregs, FALSE));
            *pretregs = 0;      // in case they got set
        }
        return cdb.finish();
    }

    assert(n >= 2 && n <= 4);

    elem *eop = params[0];
    elem *op1 = params[1];
    elem *op2 = NULL;
    tym_t ty2 = 0;
    if (n >= 3)
    {   op2 = params[2];
        ty2 = tybasic(op2->Ety);
    }

    unsigned op = el_tolong(eop);
#ifdef DEBUG
    assert(!isXMMstore(op));
#endif
    tym_t ty1 = tybasic(op1->Ety);
    unsigned sz1 = _tysize[ty1];
//    assert(sz1 == 16);       // float or double

    regm_t retregs;
    CodeBuilder cdb;
    if (n == 3 && ty2 == TYuchar && op2->Eoper == OPconst)
    {   // Handle: op xmm,imm8

        retregs = *pretregs & XMMREGS;
        if (!retregs)
            retregs = XMMREGS;
        cdb.append(codelem(op1,&retregs,FALSE)); // eval left leaf
        unsigned reg = findreg(retregs);
        int r;
        switch (op)
        {
            case PSLLD:  r = 6; op = 0x660F72;  break;
            case PSLLQ:  r = 6; op = 0x660F73;  break;
            case PSLLW:  r = 6; op = 0x660F71;  break;
            case PSRAD:  r = 4; op = 0x660F72;  break;
            case PSRAW:  r = 4; op = 0x660F71;  break;
            case PSRLD:  r = 2; op = 0x660F72;  break;
            case PSRLQ:  r = 2; op = 0x660F73;  break;
            case PSRLW:  r = 2; op = 0x660F71;  break;
            case PSRLDQ: r = 3; op = 0x660F73;  break;
            case PSLLDQ: r = 7; op = 0x660F73;  break;

            default:
                printf("op = x%x\n", op);
                assert(0);
                break;
        }
        cdb.append(getregs(retregs));
        cdb.genc2(op,modregrmx(3,r,reg-XMM0), el_tolong(op2));
    }
    else if (n == 2)
    {   /* Handle: op xmm,mem
         * where xmm is written only, not read
         */
        code cs;

        if ((op1->Eoper == OPind && !op1->Ecount) || op1->Eoper == OPvar)
        {
            cdb.append(getlvalue(&cs, op1, RMload));     // get addressing mode
        }
        else
        {
            regm_t rretregs = XMMREGS;
            cdb.append(codelem(op1, &rretregs, FALSE));
            unsigned rreg = findreg(rretregs) - XMM0;
            cs.Irm = modregrm(3,0,rreg & 7);
            cs.Iflags = 0;
            cs.Irex = 0;
            if (rreg & 8)
                cs.Irex |= REX_B;
        }

        retregs = *pretregs & XMMREGS;
        if (!retregs)
            retregs = XMMREGS;
        unsigned reg;
        cdb.append(allocreg(&retregs, &reg, e->Ety));
        code_newreg(&cs, reg - XMM0);
        cs.Iop = op;
        cdb.gen(&cs);
    }
    else if (n == 3 || n == 4)
    {   /* Handle:
         *      op xmm,mem        // n = 3
         *      op xmm,mem,imm8   // n = 4
         * Both xmm and mem are operands, evaluate xmm first.
         */

        code cs;

        retregs = *pretregs & XMMREGS;
        if (!retregs)
            retregs = XMMREGS;
        cdb.append(codelem(op1,&retregs,FALSE)); // eval left leaf
        unsigned reg = findreg(retregs);

        if ((op2->Eoper == OPind && !op2->Ecount) || op2->Eoper == OPvar)
        {
            cdb.append(getlvalue(&cs, op2, RMload | retregs));     // get addressing mode
        }
        else
        {
            unsigned rretregs = XMMREGS & ~retregs;
            cdb.append(scodelem(op2, &rretregs, retregs, TRUE));
            unsigned rreg = findreg(rretregs) - XMM0;
            cs.Irm = modregrm(3,0,rreg & 7);
            cs.Iflags = 0;
            cs.Irex = 0;
            if (rreg & 8)
                cs.Irex |= REX_B;
        }

        cdb.append(getregs(retregs));
        if (n == 4)
        {
            switch (op)
            {
                case CMPPD:   case CMPSS:   case CMPSD:   case CMPPS:
                case PSHUFD:  case PSHUFHW: case PSHUFLW:
                case BLENDPD: case BLENDPS: case DPPD:    case DPPS:
                case MPSADBW: case PBLENDW:
                case ROUNDPD: case ROUNDPS: case ROUNDSD: case ROUNDSS:
                case SHUFPD:  case SHUFPS:
                    break;
                default:
                    printf("op = x%x\n", op);
                    assert(0);
                    break;
            }
            elem *imm8 = params[3];
            cs.IFL2 = FLconst;
            cs.IEV2.Vsize_t = el_tolong(imm8);
        }
        code_newreg(&cs, reg - XMM0);
        cs.Iop = op;
        cdb.gen(&cs);
    }
    else
        assert(0);
    cdb.append(fixresult(e,retregs,pretregs));
    free(params);
    freenode(e);
    return cdb.finish();
}
Exemplo n.º 14
0
/******************************************
 * Return elem that evaluates to the static frame pointer for function fd.
 * If fd is a member function, the returned expression will compute the value
 * of fd's 'this' variable.
 * This routine is critical for implementing nested functions.
 */
elem *getEthis(Loc loc, IRState *irs, Dsymbol *fd)
{
    elem *ethis;
    FuncDeclaration *thisfd = irs->getFunc();
    Dsymbol *fdparent = fd->toParent2();
    Dsymbol *fdp = fdparent;

    /* These two are compiler generated functions for the in and out contracts,
     * and are called from an overriding function, not just the one they're
     * nested inside, so this hack is so they'll pass
     */
    if (fdparent != thisfd && (fd->ident == Id::require || fd->ident == Id::ensure))
    {
        FuncDeclaration *fdthis = thisfd;
        for (size_t i = 0; ; )
        {
            if (i == fdthis->foverrides.dim)
            {
                if (i == 0)
                    break;
                fdthis = fdthis->foverrides[0];
                i = 0;
                continue;
            }
            if (fdthis->foverrides[i] == fdp)
            {
                fdparent = thisfd;
                break;
            }
            i++;
        }
    }

    //printf("[%s] getEthis(thisfd = '%s', fd = '%s', fdparent = '%s')\n", loc.toChars(), thisfd->toPrettyChars(), fd->toPrettyChars(), fdparent->toPrettyChars());
    if (fdparent == thisfd)
    {
        /* Going down one nesting level, i.e. we're calling
         * a nested function from its enclosing function.
         */
        if (irs->sclosure && !(fd->ident == Id::require || fd->ident == Id::ensure))
        {
            ethis = el_var(irs->sclosure);
        }
        else if (irs->sthis)
        {
            // We have a 'this' pointer for the current function

            /* If no variables in the current function's frame are
             * referenced by nested functions, then we can 'skip'
             * adding this frame into the linked list of stack
             * frames.
             */
            if (thisfd->hasNestedFrameRefs())
            {
                /* Local variables are referenced, can't skip.
                 * Address of 'sthis' gives the 'this' for the nested
                 * function
                 */
                ethis = el_ptr(irs->sthis);
            }
            else
            {
                ethis = el_var(irs->sthis);
            }
        }
        else
        {
            /* No 'this' pointer for current function,
             */
            if (thisfd->hasNestedFrameRefs())
            {
                /* OPframeptr is an operator that gets the frame pointer
                 * for the current function, i.e. for the x86 it gets
                 * the value of EBP
                 */
                ethis = el_long(TYnptr, 0);
                ethis->Eoper = OPframeptr;
            }
            else
            {
                /* Use NULL if no references to the current function's frame
                 */
                ethis = el_long(TYnptr, 0);
            }
        }
    }
    else
    {
        if (!irs->sthis)                // if no frame pointer for this function
        {
            fd->error(loc, "is a nested function and cannot be accessed from %s", irs->getFunc()->toPrettyChars());
            return el_long(TYnptr, 0); // error recovery
        }

        /* Go up a nesting level, i.e. we need to find the 'this'
         * of an enclosing function.
         * Our 'enclosing function' may also be an inner class.
         */
        ethis = el_var(irs->sthis);
        Dsymbol *s = thisfd;
        while (fd != s)
        {
            FuncDeclaration *fdp = s->toParent2()->isFuncDeclaration();

            //printf("\ts = '%s'\n", s->toChars());
            thisfd = s->isFuncDeclaration();
            if (thisfd)
            {
                /* Enclosing function is a function.
                 */
                // Error should have been caught by front end
                assert(thisfd->isNested() || thisfd->vthis);
            }
            else
            {
                /* Enclosed by an aggregate. That means the current
                 * function must be a member function of that aggregate.
                 */
                AggregateDeclaration *ad = s->isAggregateDeclaration();
                if (!ad)
                {
                  Lnoframe:
                    irs->getFunc()->error(loc, "cannot get frame pointer to %s", fd->toPrettyChars());
                    return el_long(TYnptr, 0);      // error recovery
                }
                ClassDeclaration *cd = ad->isClassDeclaration();
                ClassDeclaration *cdx = fd->isClassDeclaration();
                if (cd && cdx && cdx->isBaseOf(cd, NULL))
                    break;
                StructDeclaration *sd = ad->isStructDeclaration();
                if (fd == sd)
                    break;
                if (!ad->isNested() || !ad->vthis)
                    goto Lnoframe;

                ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYsize_t, ad->vthis->offset));
                ethis = el_una(OPind, TYnptr, ethis);
            }
            if (fdparent == s->toParent2())
                break;

            /* Remember that frames for functions that have no
             * nested references are skipped in the linked list
             * of frames.
             */
            if (fdp && fdp->hasNestedFrameRefs())
                ethis = el_una(OPind, TYnptr, ethis);

            s = s->toParent2();
            assert(s);
        }
    }
#if 0
    printf("ethis:\n");
    elem_print(ethis);
    printf("\n");
#endif
    return ethis;
}
Exemplo n.º 15
0
void WRblock(block *b)
{
    if (OPTIMIZER)
    {
        if (b && b->Bweight)
                dbg_printf("B%d: (%p), weight=%d",b->Bdfoidx,b,b->Bweight);
        else
                dbg_printf("block %p",b);
        if (!b)
        {       ferr("\n");
                return;
        }
        dbg_printf(" flags=x%x weight=%d",b->Bflags,b->Bweight);
#if 0
        dbg_printf("\tfile %p, line %d",b->Bfilptr,b->Blinnum);
#endif
        dbg_printf(" ");
        WRBC(b->BC);
        dbg_printf(" Btry=%p Bindex=%d",b->Btry,b->Bindex);
#if SCPP
        if (b->BC == BCtry)
            dbg_printf(" catchvar = %p",b->catchvar);
#endif
        dbg_printf("\n");
        dbg_printf("\tBpred: "); WRblocklist(b->Bpred);
        dbg_printf("\tBsucc: "); WRblocklist(b->Bsucc);
        if (b->Belem)
        {       if (debugf)                     /* if full output       */
                        elem_print(b->Belem);
                else
                {       ferr("\t");
                        WReqn(b->Belem);
                        dbg_printf(";\n");
                }
        }
        if (b->Bcode)
            b->Bcode->print();
        ferr("\n");
    }
    else
    {
        targ_llong *pu;
        int ncases;
        list_t bl;

        assert(b);
        dbg_printf("********* Basic Block %p ************\n",b);
        if (b->Belem) elem_print(b->Belem);
        dbg_printf("block: ");
        WRBC(b->BC);
        dbg_printf(" Btry=%p Bindex=%d",b->Btry,b->Bindex);
        dbg_printf("\n");
        dbg_printf("\tBpred:\n");
        for (bl = b->Bpred; bl; bl = list_next(bl))
            dbg_printf("\t%p\n",list_block(bl));
        bl = b->Bsucc;
        switch (b->BC)
        {
            case BCswitch:
                pu = b->BS.Bswitch;
                assert(pu);
                ncases = *pu;
                dbg_printf("\tncases = %d\n",ncases);
                dbg_printf("\tdefault: %p\n",list_block(bl));
                while (ncases--)
                {   bl = list_next(bl);
                    dbg_printf("\tcase %lld: %p\n",*++pu,list_block(bl));
                }
                break;
            case BCiftrue:
            case BCgoto:
            case BCasm:
#if SCPP
            case BCtry:
            case BCcatch:
#endif
            case BCjcatch:
            case BC_try:
            case BC_filter:
            case BC_finally:
            case BC_ret:
            case BC_except:

            Lsucc:
                dbg_printf("\tBsucc:\n");
                for ( ; bl; bl = list_next(bl))
                    dbg_printf("\t%p\n",list_block(bl));
                break;
            case BCret:
            case BCretexp:
            case BCexit:
                break;
            default:
                assert(0);
        }
    }
}
Exemplo n.º 16
0
void
test_divexact(flint_rand_t state, const ring_t ring, const long * size, long iters)
{
    long iter;

    for (iter = 0; iter < iters; iter++)
    {
        elem_ptr A, B, C, Q;

        A = elem_new(ring);
        B = elem_new(ring);
        C = elem_new(ring);
        Q = elem_new(ring);

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_mul(C, A, B, ring);
        elem_divexact(Q, C, B, ring);
        if (!elem_equal(Q, A, ring))
        {
            printf("FAIL: (A * B) / B = A\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_randtest_not_zero(A, state, size, ring);
        elem_set(B, A, ring);
        elem_divexact(C, A, A, ring);
        elem_divexact(Q, A, B, ring);
        if (!elem_equal(C, Q, ring) || !elem_is_one(Q, ring))
        {
            printf("FAIL: aliasing A, B\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_mul(A, A, B, ring);
        elem_divexact(Q, A, B, ring);
        elem_divexact(A, A, B, ring);
        if (!elem_equal(A, Q, ring))
        {
            printf("FAIL: aliasing Q, A\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_mul(A, A, B, ring);
        elem_divexact(Q, A, B, ring);
        elem_divexact(B, A, B, ring);
        if (!elem_equal(B, Q, ring))
        {
            printf("FAIL: aliasing Q, A\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_randtest_not_zero(B, state, size, ring);
        elem_divexact(Q, B, B, ring);
        elem_divexact(B, B, B, ring);
        if (!elem_equal(B, Q, ring))
        {
            printf("FAIL: aliasing Q, A, B\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_del(A, ring);
        elem_del(B, ring);
        elem_del(C, ring);
        elem_del(Q, ring);
    }
}
Exemplo n.º 17
0
Arquivo: type.c Projeto: michelf/dmd
void type_print(type *t)
{
  type_debug(t);
  dbg_printf("Tty="); WRTYxx(t->Tty);
  dbg_printf(" Tmangle=%d",t->Tmangle);
  dbg_printf(" Tflags=x%x",t->Tflags);
  dbg_printf(" Tcount=%d",t->Tcount);
  if (!(t->Tflags & TFsizeunknown) &&
        tybasic(t->Tty) != TYvoid &&
        tybasic(t->Tty) != TYident &&
        tybasic(t->Tty) != TYmfunc &&
        tybasic(t->Tty) != TYarray &&
        tybasic(t->Tty) != TYtemplate)
      dbg_printf(" Tsize=%ld",type_size(t));
  dbg_printf(" Tnext=%p",t->Tnext);
  switch (tybasic(t->Tty))
  {     case TYstruct:
        case TYmemptr:
            dbg_printf(" Ttag=%p,'%s'",t->Ttag,t->Ttag->Sident);
            //dbg_printf(" Sfldlst=%p",t->Ttag->Sstruct->Sfldlst);
            break;
        case TYarray:
            dbg_printf(" Tdim=%ld",t->Tdim);
            break;
        case TYident:
            dbg_printf(" Tident='%s'",t->Tident);
            break;
        case TYtemplate:
            dbg_printf(" Tsym='%s'",((typetemp_t *)t)->Tsym->Sident);
            {   param_t *p;
                int i;

                i = 1;
                for (p = t->Tparamtypes; p; p = p->Pnext)
                {   dbg_printf("\nTP%d (%p): ",i++,p);
                    fflush(stdout);

dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p->Pident,p->Ptype,p->Pelem,p->Pnext);
                    param_debug(p);
                    if (p->Pident)
                        printf("'%s' ", p->Pident);
                    if (p->Ptype)
                        type_print(p->Ptype);
                    if (p->Pelem)
                        elem_print(p->Pelem);
                }
            }
            break;
        default:
            if (tyfunc(t->Tty))
            {   param_t *p;
                int i;

                i = 1;
                for (p = t->Tparamtypes; p; p = p->Pnext)
                {   dbg_printf("\nP%d (%p): ",i++,p);
                    fflush(stdout);

dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p->Pident,p->Ptype,p->Pelem,p->Pnext);
                    param_debug(p);
                    if (p->Pident)
                        printf("'%s' ", p->Pident);
                    type_print(p->Ptype);
                }
            }
            break;
  }
  dbg_printf("\n");
  if (t->Tnext) type_print(t->Tnext);
}
Exemplo n.º 18
0
int
main(void)
{
    flint_rand_t state;
    long i;

    printf("inv....");
    fflush(stdout);

    flint_randinit(state);

    /* Test aliasing */
    for (i = 0; i < 40 * flint_test_multiplier(); i++)
    {
        elem_mat_t A, Ainv;
        elem_poly_t den1, den2;
        ring_t ZZ, ZZx, MM;
        long n;
        long size[3] = {5, 5, 5};
        int ns1, ns2;
        int result;

        n = n_randint(state, 8);

        ring_init_fmpz(ZZ);
        ring_init_poly(ZZx, ZZ);
        ring_init_mat(MM, ZZx);

        elem_mat_init(A, n, n, MM);
        elem_mat_init(Ainv, n, n, MM);
        elem_init(den1, ZZx);
        elem_init(den2, ZZx);

        elem_mat_randtest(A, state, size, MM);

        ns1 = elem_mat_inv(Ainv, den1, A, MM);
        ns2 = elem_mat_inv(A, den2, A, MM);

        result = ns1 == ns2;

        if (result && ns1 != 0)
        {
            result = elem_equal(den1, den2, ZZx) &&
                elem_mat_equal(A, Ainv, MM);
        }

        if (!result)
        {
            printf("FAIL (aliasing)!\n");
            elem_mat_print(A, MM); printf("\n");
            elem_mat_print(Ainv, MM); printf("\n");
            abort();
        }

        elem_mat_clear(A, MM);
        elem_mat_clear(Ainv, MM);
        elem_clear(den1, ZZx);
        elem_clear(den2, ZZx);
    }

    /* Check A^(-1) = A = 1 */
    for (i = 0; i < 100 * flint_test_multiplier(); i++)
    {
        elem_mat_t A, Ainv, B, Iden;
        elem_poly_t den, det;
        ring_t ZZ, ZZx, MM;
        long n;
        long size[3] = {5, 5, 5};
        int nonsingular;

        n = n_randint(state, 8);

        ring_init_fmpz(ZZ);
        ring_init_poly(ZZx, ZZ);
        ring_init_mat(MM, ZZx);

        elem_mat_init(A, n, n, MM);
        elem_mat_init(Ainv, n, n, MM);
        elem_mat_init(B, n, n, MM);
        elem_mat_init(Iden, n, n, MM);
        elem_init(den, ZZx);
        elem_init(det, ZZx);

        elem_mat_randtest(A, state, size, MM);

        nonsingular = elem_mat_inv(Ainv, den, A, MM);
        elem_mat_det(det, A, MM);

        if (n == 0)
        {
            if (nonsingular == 0 || !elem_is_one(den, ZZx))
            {
                printf("FAIL: expected empty matrix to pass\n");
                abort();
            }
        }
        else
        {
/*
            if (!elem_equal(den, det, ZZx))
            {
                elem_neg(det, det, ZZx);
                printf("FAIL: den != det(A)\n");
                abort();
            }
*/

            if (nonsingular)
            {
                elem_mat_mul(B, Ainv, A, MM);
                elem_mat_one(Iden, MM);
                elem_mat_scalar_mul(Iden, Iden, den, MM);

                if (!elem_mat_equal(B, Iden, MM))
                {
                    printf("FAIL:\n");
                    printf("A:\n");
                    elem_mat_print(A, MM);
                    printf("Ainv:\n");
                    elem_mat_print(Ainv, MM);
                    printf("B:\n");
                    elem_mat_print(B, MM);
                    printf("den:\n");
                    elem_print(den, ZZx);
                    abort();
                }
            }
            else
            {
                if (!elem_is_zero(det, ZZx) || !elem_is_zero(den, ZZx))
                {
                    printf("FAIL (reported invertible):\n");
                    printf("A:\n");
                    elem_mat_print(A, MM);
                    printf("Ainv:\n");
                    elem_mat_print(Ainv, MM);
                    printf("den:\n");
                    elem_print(den, ZZx);
                    abort();
                }
            }
        }

        elem_clear(den, ZZx);
        elem_clear(det, ZZx);
        elem_mat_clear(A, MM);
        elem_mat_clear(Ainv, MM);
        elem_mat_clear(B, MM);
        elem_mat_clear(Iden, MM);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}