Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 308

Show
Ignore:
Timestamp:
12/24/09 20:15:25 (15 years ago)
Author:
walter
Message:

bugzilla 3633 Optimizer causes access violation

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/backend/cod1.c

    r272 r308  
    13061306    default: 
    13071307#ifdef DEBUG 
    13081308    WRFL((enum FL)fl); 
    13091309    symbol_print(s); 
    13101310#endif 
    13111311    assert(0); 
    13121312  } 
    13131313  return c; 
    13141314} 
    13151315 
    13161316 
    13171317/******************************* 
    13181318 * Same as codelem(), but do not destroy the registers in keepmsk. 
    13191319 * Use scratch registers as much as possible, then use stack. 
    13201320 * Input: 
    13211321 *  constflag   TRUE if user of result will not modify the 
    13221322 *          registers returned in *pretregs. 
    13231323 */ 
    13241324 
    13251325code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) 
    1326 { code *c,*cs1,*cs2
     1326{ code *c,*cs1,*cs2,*cs3
    13271327  unsigned i,j; 
    13281328  regm_t oldmfuncreg,oldregcon,oldregimmed,overlap,tosave,touse; 
    13291329  int adjesp; 
    13301330  unsigned stackpushsave; 
    13311331  char calledafuncsave; 
    13321332 
    13331333#ifdef DEBUG 
    13341334  if (debugw) 
    13351335    printf("+scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 
    13361336        e,*pretregs,keepmsk,constflag); 
    13371337#endif 
    13381338  elem_debug(e); 
    13391339  if (constflag) 
    13401340  { regm_t regm; 
    13411341    unsigned reg; 
    13421342 
    13431343    if (isregvar(e,&regm,&reg) &&       // if e is a register variable 
    13441344        (regm & *pretregs) == regm &&   // in one of the right regs 
    13451345        e->EV.sp.Voffset == 0 
    13461346       ) 
     
    14071407  { 
    14081408    //elem_print(e); 
    14091409    //printf("test1: regcon.mvar x%x tosave x%x\n", regcon.mvar, tosave); 
    14101410    cgreg_unregister(regcon.mvar & tosave); 
    14111411  } 
    14121412 
    14131413  /* which registers can we use to save other registers in? */ 
    14141414  if (config.flags4 & CFG4space ||      // if optimize for space 
    14151415      config.target_cpu >= TARGET_80486)    // PUSH/POP ops are 1 cycle 
    14161416        touse = 0;              // PUSH/POP pairs are always shorter 
    14171417  else 
    14181418  { touse = mfuncreg & allregs & ~(msavereg | oldregcon | regcon.cse.mval); 
    14191419    /* Don't use registers we'll have to save/restore       */ 
    14201420    touse &= ~(fregsaved & oldmfuncreg); 
    14211421    /* Don't use registers that have constant values in them, since 
    14221422       the code generated might have used the value. 
    14231423     */ 
    14241424    touse &= ~oldregimmed; 
    14251425  } 
    14261426 
    1427   cs1 = cs2 = NULL; 
     1427  cs1 = cs2 = cs3 = NULL; 
    14281428  adjesp = 0; 
    14291429 
    14301430  for (i = 0; tosave; i++) 
    14311431  { regm_t mi = mask[i]; 
    14321432 
    14331433    assert(i < REGMAX); 
    14341434    if (mi & tosave)    /* i = register to save         */ 
    14351435    { 
    14361436        if (touse)      /* if any scratch registers     */ 
    14371437        {   for (j = 0; j < 8; j++) 
    14381438        {   regm_t mj = mask[j]; 
    14391439 
    14401440            if (touse & mj) 
    14411441            {   cs1 = genmovreg(cs1,j,i); 
    14421442            cs2 = cat(genmovreg(CNIL,i,j),cs2); 
    14431443            touse &= ~mj; 
    14441444            mfuncreg &= ~mj; 
    14451445            regcon.used |= mj; 
    14461446            break; 
    14471447            } 
    14481448        } 
    14491449        assert(j < 8); 
    14501450            } 
    14511451        else            /* else use stack       */ 
    14521452        {   int push,pop; 
    14531453 
    14541454        stackchanged = 1; 
    14551455        adjesp += REGSIZE; 
    14561456        if (i == ES) 
    14571457        {   push = 0x06; 
    14581458            pop = 0x07; 
    14591459        } 
    14601460        else 
    14611461        {   push = 0x50 + i; 
    14621462            pop = push | 8; 
    14631463        }        
    14641464        cs1 = gen1(cs1,push);           /* PUSH i   */ 
    14651465        cs2 = cat(gen1(CNIL,pop),cs2);      /* POP i    */ 
    14661466        } 
    1467         cs2 = cat(getregs(mi),cs2); 
     1467        cs3 = cat(getregs(mi),cs3); 
    14681468        tosave &= ~mi; 
    14691469    } 
    14701470  } 
    14711471  if (adjesp) 
    14721472  { 
    14731473    // If this is done an odd number of times, it 
    14741474    // will throw off the 8 byte stack alignment. 
    14751475    // We should *only* worry about this if a function 
    14761476    // was called in the code generation by codelem(). 
    14771477    int sz; 
    14781478    if (STACKALIGN == 16) 
    14791479        sz = -(adjesp & (STACKALIGN - 1)) & (STACKALIGN - 1); 
    14801480    else 
    14811481        sz = -(adjesp & 7) & 7; 
    14821482    if (calledafunc && I32 && sz && (STACKALIGN == 16 || config.flags4 & CFG4stackalign)) 
    14831483    {   code *cx; 
    14841484 
    14851485        regm_t mval_save = regcon.immed.mval; 
    14861486        regcon.immed.mval = 0;  // prevent reghasvalue() optimizations 
    14871487                    // because c hasn't been executed yet 
     
    14891489        regcon.immed.mval = mval_save; 
    14901490        cs1 = genadjesp(cs1, sz); 
    14911491 
    14921492        cx = genc2(CNIL,0x81,modregrm(3,0,SP),sz);  // ADD ESP,sz 
    14931493        cx = genadjesp(cx, -sz); 
    14941494        cs2 = cat(cx, cs2); 
    14951495    } 
    14961496 
    14971497    cs1 = genadjesp(cs1,adjesp); 
    14981498    cs2 = genadjesp(cs2,-adjesp); 
    14991499  } 
    15001500 
    15011501  calledafunc |= calledafuncsave; 
    15021502  msavereg &= ~keepmsk | overlap; /* remove from mask of regs to save   */ 
    15031503  mfuncreg &= oldmfuncreg;  /* update original          */ 
    15041504#ifdef DEBUG 
    15051505  if (debugw) 
    15061506    printf("-scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 
    15071507        e,*pretregs,keepmsk,constflag); 
    15081508#endif 
    1509   return cat3(cs1,c,cs2); 
     1509  return cat4(cs1,c,cs3,cs2); 
    15101510} 
    15111511 
    15121512 
    15131513/***************************** 
    15141514 * Given an opcode and EA in cs, generate code 
    15151515 * for each floating register in turn. 
    15161516 * Input: 
    15171517 *  tym either TYdouble or TYfloat 
    15181518 */ 
    15191519 
    15201520code *fltregs(code __ss *pcs,tym_t tym) 
    15211521{   code *c; 
    15221522 
    15231523    tym = tybasic(tym); 
    15241524    if (I32) 
    15251525    { 
    15261526    c = getregs((tym == TYfloat) ? mAX : mAX | mDX); 
    15271527    if (tym != TYfloat) 
    15281528    { 
    15291529        pcs->IEVoffset1 += REGSIZE; 
  • branches/dmd-1.x/src/msc.c

    r189 r308  
    2626static char __file__[] = __FILE__;  /* for tassert.h        */ 
    2727#include    "tassert.h" 
    2828 
    2929extern Global global; 
    3030 
    3131Config config; 
    3232Configv configv; 
    3333 
    3434struct Environment; 
    3535 
    3636/************************************** 
    3737 * Initialize config variables. 
    3838 */ 
    3939 
    4040void out_config_init() 
    4141{ 
    4242    Param *params = &global.params; 
    4343 
    4444    if (!config.target_cpu) 
    4545    {   config.target_cpu = TARGET_PentiumPro; 
    46     config.target_scheduler = config.target_cpu; 
     46    config.target_scheduler = 0; //config.target_cpu; 
    4747    } 
    4848    config.fulltypes = CVNONE; 
    4949    config.inline8087 = 1; 
    5050    config.memmodel = 0; 
    5151    config.flags |= CFGuchar;   // make sure TYchar is unsigned 
    5252#if TARGET_WINDOS 
    5353    if (params->isX86_64) 
    5454    config.exe = EX_WIN64; 
    5555    else 
    5656    config.exe = EX_NT; 
    5757 
    5858    // Win32 eh 
    5959    config.flags2 |= CFG2seh; 
    6060 
    6161    if (params->run) 
    6262    config.wflags |= WFexe;     // EXE file only optimizations 
    6363    else if (params->link && !global.params.deffile) 
    6464    config.wflags |= WFexe;     // EXE file only optimizations 
    6565    else if (params->exefile)       // if writing out EXE file 
    6666    {   size_t len = strlen(params->exefile); 
  • trunk/src/backend/cod1.c

    r272 r308  
    13061306    default: 
    13071307#ifdef DEBUG 
    13081308    WRFL((enum FL)fl); 
    13091309    symbol_print(s); 
    13101310#endif 
    13111311    assert(0); 
    13121312  } 
    13131313  return c; 
    13141314} 
    13151315 
    13161316 
    13171317/******************************* 
    13181318 * Same as codelem(), but do not destroy the registers in keepmsk. 
    13191319 * Use scratch registers as much as possible, then use stack. 
    13201320 * Input: 
    13211321 *  constflag   TRUE if user of result will not modify the 
    13221322 *          registers returned in *pretregs. 
    13231323 */ 
    13241324 
    13251325code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) 
    1326 { code *c,*cs1,*cs2
     1326{ code *c,*cs1,*cs2,*cs3
    13271327  unsigned i,j; 
    13281328  regm_t oldmfuncreg,oldregcon,oldregimmed,overlap,tosave,touse; 
    13291329  int adjesp; 
    13301330  unsigned stackpushsave; 
    13311331  char calledafuncsave; 
    13321332 
    13331333#ifdef DEBUG 
    13341334  if (debugw) 
    13351335    printf("+scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 
    13361336        e,*pretregs,keepmsk,constflag); 
    13371337#endif 
    13381338  elem_debug(e); 
    13391339  if (constflag) 
    13401340  { regm_t regm; 
    13411341    unsigned reg; 
    13421342 
    13431343    if (isregvar(e,&regm,&reg) &&       // if e is a register variable 
    13441344        (regm & *pretregs) == regm &&   // in one of the right regs 
    13451345        e->EV.sp.Voffset == 0 
    13461346       ) 
     
    14071407  { 
    14081408    //elem_print(e); 
    14091409    //printf("test1: regcon.mvar x%x tosave x%x\n", regcon.mvar, tosave); 
    14101410    cgreg_unregister(regcon.mvar & tosave); 
    14111411  } 
    14121412 
    14131413  /* which registers can we use to save other registers in? */ 
    14141414  if (config.flags4 & CFG4space ||      // if optimize for space 
    14151415      config.target_cpu >= TARGET_80486)    // PUSH/POP ops are 1 cycle 
    14161416        touse = 0;              // PUSH/POP pairs are always shorter 
    14171417  else 
    14181418  { touse = mfuncreg & allregs & ~(msavereg | oldregcon | regcon.cse.mval); 
    14191419    /* Don't use registers we'll have to save/restore       */ 
    14201420    touse &= ~(fregsaved & oldmfuncreg); 
    14211421    /* Don't use registers that have constant values in them, since 
    14221422       the code generated might have used the value. 
    14231423     */ 
    14241424    touse &= ~oldregimmed; 
    14251425  } 
    14261426 
    1427   cs1 = cs2 = NULL; 
     1427  cs1 = cs2 = cs3 = NULL; 
    14281428  adjesp = 0; 
    14291429 
    14301430  for (i = 0; tosave; i++) 
    14311431  { regm_t mi = mask[i]; 
    14321432 
    14331433    assert(i < REGMAX); 
    14341434    if (mi & tosave)    /* i = register to save         */ 
    14351435    { 
    14361436        if (touse)      /* if any scratch registers     */ 
    14371437        {   for (j = 0; j < 8; j++) 
    14381438        {   regm_t mj = mask[j]; 
    14391439 
    14401440            if (touse & mj) 
    14411441            {   cs1 = genmovreg(cs1,j,i); 
    14421442            cs2 = cat(genmovreg(CNIL,i,j),cs2); 
    14431443            touse &= ~mj; 
    14441444            mfuncreg &= ~mj; 
    14451445            regcon.used |= mj; 
    14461446            break; 
    14471447            } 
    14481448        } 
    14491449        assert(j < 8); 
    14501450            } 
    14511451        else            /* else use stack       */ 
    14521452        {   int push,pop; 
    14531453 
    14541454        stackchanged = 1; 
    14551455        adjesp += REGSIZE; 
    14561456        if (i == ES) 
    14571457        {   push = 0x06; 
    14581458            pop = 0x07; 
    14591459        } 
    14601460        else 
    14611461        {   push = 0x50 + i; 
    14621462            pop = push | 8; 
    14631463        }        
    14641464        cs1 = gen1(cs1,push);           /* PUSH i   */ 
    14651465        cs2 = cat(gen1(CNIL,pop),cs2);      /* POP i    */ 
    14661466        } 
    1467         cs2 = cat(getregs(mi),cs2); 
     1467        cs3 = cat(getregs(mi),cs3); 
    14681468        tosave &= ~mi; 
    14691469    } 
    14701470  } 
    14711471  if (adjesp) 
    14721472  { 
    14731473    // If this is done an odd number of times, it 
    14741474    // will throw off the 8 byte stack alignment. 
    14751475    // We should *only* worry about this if a function 
    14761476    // was called in the code generation by codelem(). 
    14771477    int sz; 
    14781478    if (STACKALIGN == 16) 
    14791479        sz = -(adjesp & (STACKALIGN - 1)) & (STACKALIGN - 1); 
    14801480    else 
    14811481        sz = -(adjesp & 7) & 7; 
    14821482    if (calledafunc && I32 && sz && (STACKALIGN == 16 || config.flags4 & CFG4stackalign)) 
    14831483    {   code *cx; 
    14841484 
    14851485        regm_t mval_save = regcon.immed.mval; 
    14861486        regcon.immed.mval = 0;  // prevent reghasvalue() optimizations 
    14871487                    // because c hasn't been executed yet 
     
    14891489        regcon.immed.mval = mval_save; 
    14901490        cs1 = genadjesp(cs1, sz); 
    14911491 
    14921492        cx = genc2(CNIL,0x81,modregrm(3,0,SP),sz);  // ADD ESP,sz 
    14931493        cx = genadjesp(cx, -sz); 
    14941494        cs2 = cat(cx, cs2); 
    14951495    } 
    14961496 
    14971497    cs1 = genadjesp(cs1,adjesp); 
    14981498    cs2 = genadjesp(cs2,-adjesp); 
    14991499  } 
    15001500 
    15011501  calledafunc |= calledafuncsave; 
    15021502  msavereg &= ~keepmsk | overlap; /* remove from mask of regs to save   */ 
    15031503  mfuncreg &= oldmfuncreg;  /* update original          */ 
    15041504#ifdef DEBUG 
    15051505  if (debugw) 
    15061506    printf("-scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 
    15071507        e,*pretregs,keepmsk,constflag); 
    15081508#endif 
    1509   return cat3(cs1,c,cs2); 
     1509  return cat4(cs1,c,cs3,cs2); 
    15101510} 
    15111511 
    15121512 
    15131513/***************************** 
    15141514 * Given an opcode and EA in cs, generate code 
    15151515 * for each floating register in turn. 
    15161516 * Input: 
    15171517 *  tym either TYdouble or TYfloat 
    15181518 */ 
    15191519 
    15201520code *fltregs(code __ss *pcs,tym_t tym) 
    15211521{   code *c; 
    15221522 
    15231523    tym = tybasic(tym); 
    15241524    if (I32) 
    15251525    { 
    15261526    c = getregs((tym == TYfloat) ? mAX : mAX | mDX); 
    15271527    if (tym != TYfloat) 
    15281528    { 
    15291529        pcs->IEVoffset1 += REGSIZE;