Mercurial > projects > ldc
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 } |