comparison dmd2/optimize.c @ 1452:638d16625da2

LDC 2 compiles again.
author Robert Clipsham <robert@octarineparrot.com>
date Sat, 30 May 2009 17:23:32 +0100
parents f04dde6e882c
children 54b3c1394d62
comparison
equal deleted inserted replaced
1423:42bd767ec5a4 1452:638d16625da2
40 * return that initializer. 40 * return that initializer.
41 */ 41 */
42 42
43 Expression *expandVar(int result, VarDeclaration *v) 43 Expression *expandVar(int result, VarDeclaration *v)
44 { 44 {
45 //printf("expandVar(result = %d, v = %s)\n", result, v ? v->toChars() : "null"); 45 //printf("expandVar(result = %d, v = %p, %s)\n", result, v, v ? v->toChars() : "null");
46
46 Expression *e = NULL; 47 Expression *e = NULL;
47 if (v && (v->isConst() || v->isInvariant() || v->storage_class & STCmanifest)) 48 if (!v)
48 { 49 return e;
50
51 if (v->isConst() || v->isInvariant() || v->storage_class & STCmanifest)
52 {
53 if (!v->type)
54 {
55 //error("ICE");
56 return e;
57 }
58
49 Type *tb = v->type->toBasetype(); 59 Type *tb = v->type->toBasetype();
50 if (result & WANTinterpret || 60 if (result & WANTinterpret ||
51 v->storage_class & STCmanifest || 61 v->storage_class & STCmanifest ||
52 (tb->ty != Tsarray && tb->ty != Tstruct) 62 (tb->ty != Tsarray && tb->ty != Tstruct)
53 ) 63 )
54 { 64 {
55 if (v->init) 65 if (v->init)
56 { 66 {
57 if (v->inuse) 67 if (v->inuse)
68 { if (v->storage_class & STCmanifest)
69 v->error("recursive initialization of constant");
58 goto L1; 70 goto L1;
71 }
59 Expression *ei = v->init->toExpression(); 72 Expression *ei = v->init->toExpression();
60 if (!ei) 73 if (!ei)
61 goto L1; 74 goto L1;
62 if (ei->op == TOKconstruct || ei->op == TOKblit) 75 if (ei->op == TOKconstruct || ei->op == TOKblit)
63 { AssignExp *ae = (AssignExp *)ei; 76 { AssignExp *ae = (AssignExp *)ei;
97 } 110 }
98 if (e->type != v->type) 111 if (e->type != v->type)
99 { 112 {
100 e = e->castTo(NULL, v->type); 113 e = e->castTo(NULL, v->type);
101 } 114 }
115 v->inuse++;
102 e = e->optimize(result); 116 e = e->optimize(result);
117 v->inuse--;
103 } 118 }
104 } 119 }
105 L1: 120 L1:
106 //if (e) printf("\te = %s, e->type = %s\n", e->toChars(), e->type->toChars()); 121 //if (e) printf("\te = %s, e->type = %s\n", e->toChars(), e->type->toChars());
107 return e; 122 return e;
314 { // Convert &array[n] to &array+n 329 { // Convert &array[n] to &array+n
315 IndexExp *ae = (IndexExp *)e1; 330 IndexExp *ae = (IndexExp *)e1;
316 331
317 if (ae->e2->op == TOKint64 && ae->e1->op == TOKvar) 332 if (ae->e2->op == TOKint64 && ae->e1->op == TOKvar)
318 { 333 {
319 integer_t index = ae->e2->toInteger(); 334 dinteger_t index = ae->e2->toInteger();
320 VarExp *ve = (VarExp *)ae->e1; 335 VarExp *ve = (VarExp *)ae->e1;
321 if (ve->type->ty == Tsarray 336 if (ve->type->ty == Tsarray
322 && !ve->var->isImportedSymbol()) 337 && !ve->var->isImportedSymbol())
323 { 338 {
324 TypeSArray *ts = (TypeSArray *)ve->type; 339 TypeSArray *ts = (TypeSArray *)ve->type;
325 integer_t dim = ts->dim->toInteger(); 340 dinteger_t dim = ts->dim->toInteger();
326 if (index < 0 || index >= dim) 341 if (index < 0 || index >= dim)
327 error("array index %lld is out of bounds [0..%lld]", index, dim); 342 error("array index %jd is out of bounds [0..%jd]", index, dim);
328 e = new SymOffExp(loc, ve->var, index * ts->nextOf()->size()); 343 e = new SymOffExp(loc, ve->var, index * ts->nextOf()->size());
329 e->type = type; 344 e->type = type;
330 return e; 345 return e;
331 } 346 }
332 } 347 }
368 VarDeclaration *v = se->var->isVarDeclaration(); 383 VarDeclaration *v = se->var->isVarDeclaration();
369 Expression *e = expandVar(result, v); 384 Expression *e = expandVar(result, v);
370 if (e && e->op == TOKstructliteral) 385 if (e && e->op == TOKstructliteral)
371 { StructLiteralExp *sle = (StructLiteralExp *)e; 386 { StructLiteralExp *sle = (StructLiteralExp *)e;
372 e = sle->getField(type, se->offset); 387 e = sle->getField(type, se->offset);
373 if (e != EXP_CANT_INTERPRET) 388 if (e && e != EXP_CANT_INTERPRET)
374 return e; 389 return e;
375 } 390 }
376 } 391 }
377 return this; 392 return this;
378 } 393 }
379 394
380 ///////////////////////////////////////////
381 // LDC
382 Expression *DotVarExp::optimize(int result) 395 Expression *DotVarExp::optimize(int result)
383 { 396 {
384 e1 = e1->optimize(result); 397 //printf("DotVarExp::optimize(result = x%x) %s\n", result, toChars());
385 398 e1 = e1->optimize(result);
386 // Constant fold structliteral.member 399
387 if (e1->op == TOKstructliteral) 400 if (e1->op == TOKvar)
388 { StructLiteralExp *se = (StructLiteralExp *)e1; 401 { VarExp *ve = (VarExp *)e1;
389 402 VarDeclaration *v = ve->var->isVarDeclaration();
390 VarDeclaration* v; 403 Expression *e = expandVar(result, v);
391 if (v = var->isVarDeclaration()) 404 if (e && e->op == TOKstructliteral)
392 { 405 { StructLiteralExp *sle = (StructLiteralExp *)e;
393 Expression *e = se->getField(type, v->offset); 406 VarDeclaration *vf = var->isVarDeclaration();
394 if (!e) 407 if (vf)
395 e = EXP_CANT_INTERPRET; 408 {
396 return e; 409 e = sle->getField(type, vf->offset);
397 } 410 if (e && e != EXP_CANT_INTERPRET)
398 } 411 return e;
399 412 }
400 return this; 413 }
401 } 414 }
402 /////////////////////////////////////////// 415 else if (e1->op == TOKstructliteral)
416 { StructLiteralExp *sle = (StructLiteralExp *)e1;
417 VarDeclaration *vf = var->isVarDeclaration();
418 if (vf)
419 {
420 Expression *e = sle->getField(type, vf->offset);
421 if (e && e != EXP_CANT_INTERPRET)
422 return e;
423 }
424 }
425
426 return this;
427 }
403 428
404 Expression *CallExp::optimize(int result) 429 Expression *CallExp::optimize(int result)
405 { 430 {
406 //printf("CallExp::optimize(result = %d) %s\n", result, toChars()); 431 //printf("CallExp::optimize(result = %d) %s\n", result, toChars());
407 Expression *e = this; 432 Expression *e = this;
442 //printf("type = %p\n", type); 467 //printf("type = %p\n", type);
443 assert(type); 468 assert(type);
444 enum TOK op1 = e1->op; 469 enum TOK op1 = e1->op;
445 #define X 0 470 #define X 0
446 471
472 Expression *e1old = e1;
447 e1 = e1->optimize(result); 473 e1 = e1->optimize(result);
448 e1 = fromConstInitializer(result, e1); 474 e1 = fromConstInitializer(result, e1);
475
476 if (e1 == e1old &&
477 e1->op == TOKarrayliteral &&
478 type->toBasetype()->ty == Tpointer &&
479 e1->type->toBasetype()->ty != Tsarray)
480 {
481 // Casting this will result in the same expression, and
482 // infinite loop because of Expression::implicitCastTo()
483 return this; // no change
484 }
449 485
450 if ((e1->op == TOKstring || e1->op == TOKarrayliteral) && 486 if ((e1->op == TOKstring || e1->op == TOKarrayliteral) &&
451 (type->ty == Tpointer || type->ty == Tarray) && 487 (type->ty == Tpointer || type->ty == Tarray) &&
452 e1->type->nextOf()->size() == type->nextOf()->size() 488 e1->type->nextOf()->size() == type->nextOf()->size()
453 ) 489 )
454 { 490 {
455 e1 = e1->castTo(NULL, type); 491 Expression *e = e1->castTo(NULL, type);
456 if (X) printf(" returning1 %s\n", e1->toChars()); 492 if (X) printf(" returning1 %s\n", e->toChars());
457 return e1; 493 return e;
458 } 494 }
459 495
460 if (e1->op == TOKstructliteral && 496 if (e1->op == TOKstructliteral &&
461 e1->type->implicitConvTo(type) >= MATCHconst) 497 e1->type->implicitConvTo(type) >= MATCHconst)
462 { 498 {
537 e2 = e2->optimize(result); 573 e2 = e2->optimize(result);
538 if (op == TOKshlass || op == TOKshrass || op == TOKushrass) 574 if (op == TOKshlass || op == TOKshrass || op == TOKushrass)
539 { 575 {
540 if (e2->isConst() == 1) 576 if (e2->isConst() == 1)
541 { 577 {
542 integer_t i2 = e2->toInteger(); 578 dinteger_t i2 = e2->toInteger();
543 d_uns64 sz = e1->type->size() * 8; 579 d_uns64 sz = e1->type->size() * 8;
544 if (i2 < 0 || i2 > sz) 580 if (i2 < 0 || i2 > sz)
545 { 581 { error("shift assign by %jd is outside the range 0..%zu", i2, sz);
546 error("shift assign by %lld is outside the range 0..%"PRIuSIZE, i2, sz);
547 e2 = new IntegerExp(0); 582 e2 = new IntegerExp(0);
548 } 583 }
549 } 584 }
550 } 585 }
551 return this; 586 return this;
633 668
634 e->e1 = e->e1->optimize(result); 669 e->e1 = e->e1->optimize(result);
635 e->e2 = e->e2->optimize(result); 670 e->e2 = e->e2->optimize(result);
636 if (e->e2->isConst() == 1) 671 if (e->e2->isConst() == 1)
637 { 672 {
638 integer_t i2 = e->e2->toInteger(); 673 dinteger_t i2 = e->e2->toInteger();
639 d_uns64 sz = e->e1->type->size() * 8; 674 d_uns64 sz = e->e1->type->size() * 8;
640 if (i2 < 0 || i2 > sz) 675 if (i2 < 0 || i2 > sz)
641 { 676 { e->error("shift by %jd is outside the range 0..%zu", i2, sz);
642 error("shift by %lld is outside the range 0..%"PRIuSIZE, i2, sz);
643 e->e2 = new IntegerExp(0); 677 e->e2 = new IntegerExp(0);
644 } 678 }
645 if (e->e1->isConst() == 1) 679 if (e->e1->isConst() == 1)
646 ex = (*shift)(e->type, e->e1, e->e2); 680 ex = (*shift)(e->type, e->e1, e->e2);
647 } 681 }