comparison gen/toir.c @ 14:0e86428ee567 trunk

[svn r18] * Initial support for switch statements - No string switches yet. * Moved Statement::toIR definitions into gen/statements.c - toir.c is still too big. * Removed some BB bloat with ScopeStatements.
author lindquist
date Wed, 03 Oct 2007 02:15:12 +0200
parents d3ee9efe20e2
children 37a4fdab33fc
comparison
equal deleted inserted replaced
13:3d1d98329fa7 14:0e86428ee567
2397 void 2397 void
2398 ClassDeclaration::toDebug() 2398 ClassDeclaration::toDebug()
2399 { 2399 {
2400 } 2400 }
2401 2401
2402 /* --------------------------------------------------------------------------------------- */ 2402 //////////////////////////////////////////////////////////////////////////////
2403
2404 void CompoundStatement::toIR(IRState* p)
2405 {
2406 static int csi = 0;
2407 Logger::println("CompoundStatement::toIR(%d):\n<<<\n%s>>>", csi++, toChars());
2408 LOG_SCOPE;
2409
2410 /*
2411 const char* labelname;
2412 bool insterm = false;
2413
2414 if (!p->scopes()) {
2415 labelname = "bb";
2416 insterm = true;
2417 }
2418 else
2419 labelname = "entry";
2420
2421 //if (!llvm::isa<llvm::TerminatorInst>(p->topfunc()->back().back()))
2422 // insterm = true;
2423
2424 llvm::BasicBlock* bb = new llvm::BasicBlock(labelname, p->topfunc());
2425
2426 if (insterm) {
2427 new llvm::BranchInst(bb,p->topbb());
2428 }
2429
2430 p->bbs.push(bb);
2431 */
2432
2433 size_t n = statements->dim;
2434 for (size_t i=0; i<n; i++)
2435 {
2436 Statement* s = (Statement*)statements->data[i];
2437 if (s)
2438 s->toIR(p);
2439 else
2440 Logger::println("NULL statement found in CompoundStatement !! :S");
2441 }
2442
2443 //p->bbs.pop();
2444 }
2445
2446 void ReturnStatement::toIR(IRState* p)
2447 {
2448 static int rsi = 0;
2449 Logger::println("ReturnStatement::toIR(%d): %s", rsi++, toChars());
2450 LOG_SCOPE;
2451
2452 if (exp)
2453 {
2454 TY expty = exp->type->ty;
2455 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
2456 assert(expty == Tstruct || expty == Tdelegate || expty == Tarray);
2457
2458 TypeFunction* f = p->topfunctype();
2459 assert(f->llvmRetInPtr && f->llvmRetArg);
2460
2461 p->lvals.push_back(f->llvmRetArg);
2462 elem* e = exp->toElem(p);
2463 p->lvals.pop_back();
2464
2465 // structliterals do this themselves
2466 // also they dont produce any value
2467 if (expty == Tstruct) {
2468 if (!e->inplace) {
2469 TypeStruct* ts = (TypeStruct*)exp->type;
2470 assert(e->mem);
2471 LLVM_DtoStructCopy(ts,f->llvmRetArg,e->mem);
2472 }
2473 }
2474 else if (expty == Tdelegate) {
2475 // do nothing, handled by the DelegateExp
2476 LLVM_DtoDelegateCopy(f->llvmRetArg,e->mem);
2477 }
2478 else if (expty == Tarray) {
2479 if (e->type == elem::SLICE) {
2480 LLVM_DtoSetArray(f->llvmRetArg,e->arg,e->mem);
2481 }
2482 // else the return value is a variable and should already have been assigned by now
2483 }
2484 else
2485 assert(0);
2486
2487 new llvm::ReturnInst(p->scopebb());
2488 delete e;
2489 }
2490 else {
2491 elem* e = exp->toElem(p);
2492 llvm::Value* v = e->getValue();
2493 Logger::cout() << *v << '\n';
2494 new llvm::ReturnInst(v, p->scopebb());
2495 delete e;
2496 }
2497 }
2498 else
2499 {
2500 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy)
2501 new llvm::ReturnInst(p->scopebb());
2502 else
2503 new llvm::UnreachableInst(p->scopebb());
2504 }
2505
2506 p->scope().returned = true;
2507 }
2508
2509 void ExpStatement::toIR(IRState* p)
2510 {
2511 static int esi = 0;
2512 Logger::println("ExpStatement::toIR(%d): %s", esi++, toChars());
2513 LOG_SCOPE;
2514
2515 if (exp != 0) {
2516 elem* e = exp->toElem(p);
2517 delete e;
2518 }
2519 /*elem* e = exp->toElem(p);
2520 p->buf.printf("%s", e->toChars());
2521 delete e;
2522 p->buf.writenl();*/
2523 }
2524
2525 void IfStatement::toIR(IRState* p)
2526 {
2527 static int wsi = 0;
2528 Logger::println("IfStatement::toIR(%d): %s", wsi++, toChars());
2529 LOG_SCOPE;
2530
2531 elem* cond_e = condition->toElem(p);
2532 llvm::Value* cond_val = cond_e->getValue();
2533 delete cond_e;
2534
2535 llvm::BasicBlock* oldend = gIR->scopeend();
2536
2537 llvm::BasicBlock* ifbb = new llvm::BasicBlock("if", gIR->topfunc(), oldend);
2538 llvm::BasicBlock* endbb = new llvm::BasicBlock("endif", gIR->topfunc(), oldend);
2539 llvm::BasicBlock* elsebb = 0;
2540 if (elsebody) {
2541 elsebb = new llvm::BasicBlock("else", gIR->topfunc(), endbb);
2542 }
2543 else {
2544 elsebb = endbb;
2545 }
2546
2547 if (cond_val->getType() != llvm::Type::Int1Ty) {
2548 Logger::cout() << "if conditional: " << *cond_val << '\n';
2549 cond_val = LLVM_DtoBoolean(cond_val);
2550 }
2551 llvm::Value* ifgoback = new llvm::BranchInst(ifbb, elsebb, cond_val, gIR->scopebegin());
2552
2553 // replace current scope
2554 gIR->scope() = IRScope(ifbb,elsebb);
2555
2556 bool endifUsed = false;
2557
2558 // do scoped statements
2559 ifbody->toIR(p);
2560 if (!gIR->scopereturned()) {
2561 new llvm::BranchInst(endbb,gIR->scopebegin());
2562 endifUsed = true;
2563 }
2564
2565 if (elsebody) {
2566 //assert(0);
2567 gIR->scope() = IRScope(elsebb,endbb);
2568 elsebody->toIR(p);
2569 if (!gIR->scopereturned()) {
2570 new llvm::BranchInst(endbb,gIR->scopebegin());
2571 endifUsed = true;
2572 }
2573 }
2574
2575 // rewrite the scope
2576 gIR->scope() = IRScope(endbb,oldend);
2577 }
2578
2579 void ScopeStatement::toIR(IRState* p)
2580 {
2581 static int wsi = 0;
2582 Logger::println("ScopeStatement::toIR(%d): %s", wsi++, toChars());
2583 LOG_SCOPE;
2584
2585 llvm::BasicBlock* oldend = gIR->scopeend();
2586
2587 IRScope irs;
2588 // remove useless branches by clearing and reusing the current basicblock
2589 llvm::BasicBlock* bb = gIR->scopebegin();
2590 if (bb->empty()) {
2591 irs.begin = bb;
2592 }
2593 else {
2594 irs.begin = new llvm::BasicBlock("scope", gIR->topfunc(), oldend);
2595 new llvm::BranchInst(irs.begin, gIR->scopebegin());
2596 }
2597 irs.end = new llvm::BasicBlock("endscope", gIR->topfunc(), oldend);
2598
2599 gIR->scope() = irs;
2600
2601 statement->toIR(p);
2602 if (!gIR->scopereturned()) {
2603 new llvm::BranchInst(irs.end, gIR->scopebegin());
2604 }
2605
2606 // rewrite the scope
2607 gIR->scope() = IRScope(irs.end,oldend);
2608 }
2609
2610 void WhileStatement::toIR(IRState* p)
2611 {
2612 static int wsi = 0;
2613 Logger::println("WhileStatement::toIR(%d): %s", wsi++, toChars());
2614 LOG_SCOPE;
2615
2616 // create while blocks
2617 llvm::BasicBlock* oldend = gIR->scopeend();
2618 llvm::BasicBlock* whilebb = new llvm::BasicBlock("whilecond", gIR->topfunc(), oldend);
2619 llvm::BasicBlock* endbb = new llvm::BasicBlock("endwhile", gIR->topfunc(), oldend);
2620
2621 // move into the while block
2622 new llvm::BranchInst(whilebb, gIR->scopebegin());
2623
2624 // replace current scope
2625 gIR->scope() = IRScope(whilebb,endbb);
2626
2627 // create the condition
2628 elem* cond_e = condition->toElem(p);
2629 llvm::Value* cond_val = LLVM_DtoBoolean(cond_e->getValue());
2630 delete cond_e;
2631
2632 // while body block
2633 llvm::BasicBlock* whilebodybb = new llvm::BasicBlock("whilebody", gIR->topfunc(), endbb);
2634
2635 // conditional branch
2636 llvm::Value* ifbreak = new llvm::BranchInst(whilebodybb, endbb, cond_val, whilebb);
2637
2638 // rewrite scope
2639 gIR->scope() = IRScope(whilebodybb,endbb);
2640
2641 // do while body code
2642 body->toIR(p);
2643
2644 // loop
2645 new llvm::BranchInst(whilebb, gIR->scopebegin());
2646
2647 // rewrite the scope
2648 gIR->scope() = IRScope(endbb,oldend);
2649 }
2650
2651 void DoStatement::toIR(IRState* p)
2652 {
2653 static int wsi = 0;
2654 Logger::println("DoStatement::toIR(%d): %s", wsi++, toChars());
2655 LOG_SCOPE;
2656
2657 // create while blocks
2658 llvm::BasicBlock* oldend = gIR->scopeend();
2659 llvm::BasicBlock* dowhilebb = new llvm::BasicBlock("dowhile", gIR->topfunc(), oldend);
2660 llvm::BasicBlock* endbb = new llvm::BasicBlock("enddowhile", gIR->topfunc(), oldend);
2661
2662 // move into the while block
2663 new llvm::BranchInst(dowhilebb, gIR->scopebegin());
2664
2665 // replace current scope
2666 gIR->scope() = IRScope(dowhilebb,endbb);
2667
2668 // do do-while body code
2669 body->toIR(p);
2670
2671 // create the condition
2672 elem* cond_e = condition->toElem(p);
2673 llvm::Value* cond_val = LLVM_DtoBoolean(cond_e->getValue());
2674 delete cond_e;
2675
2676 // conditional branch
2677 llvm::Value* ifbreak = new llvm::BranchInst(dowhilebb, endbb, cond_val, gIR->scopebegin());
2678
2679 // rewrite the scope
2680 gIR->scope() = IRScope(endbb,oldend);
2681 }
2682
2683 void ForStatement::toIR(IRState* p)
2684 {
2685 static int wsi = 0;
2686 Logger::println("ForStatement::toIR(%d): %s", wsi++, toChars());
2687 LOG_SCOPE;
2688
2689 // create for blocks
2690 llvm::BasicBlock* oldend = gIR->scopeend();
2691 llvm::BasicBlock* forbb = new llvm::BasicBlock("forcond", gIR->topfunc(), oldend);
2692 llvm::BasicBlock* forbodybb = new llvm::BasicBlock("forbody", gIR->topfunc(), oldend);
2693 llvm::BasicBlock* forincbb = new llvm::BasicBlock("forinc", gIR->topfunc(), oldend);
2694 llvm::BasicBlock* endbb = new llvm::BasicBlock("endfor", gIR->topfunc(), oldend);
2695
2696 // init
2697 if (init != 0)
2698 init->toIR(p);
2699
2700 // move into the for condition block, ie. start the loop
2701 new llvm::BranchInst(forbb, gIR->scopebegin());
2702
2703 IRScope loop;
2704 loop.begin = forincbb;
2705 loop.end = endbb;
2706 p->loopbbs.push_back(loop);
2707
2708 // replace current scope
2709 gIR->scope() = IRScope(forbb,forbodybb);
2710
2711 // create the condition
2712 elem* cond_e = condition->toElem(p);
2713 llvm::Value* cond_val = LLVM_DtoBoolean(cond_e->getValue());
2714 delete cond_e;
2715
2716 // conditional branch
2717 llvm::Value* ifbreak = new llvm::BranchInst(forbodybb, endbb, cond_val, forbb);
2718
2719 // rewrite scope
2720 gIR->scope() = IRScope(forbodybb,forincbb);
2721
2722 // do for body code
2723 body->toIR(p);
2724
2725 // move into the for increment block
2726 new llvm::BranchInst(forincbb, gIR->scopebegin());
2727 gIR->scope() = IRScope(forincbb, endbb);
2728
2729 // increment
2730 if (increment) {
2731 elem* inc = increment->toElem(p);
2732 delete inc;
2733 }
2734
2735 // loop
2736 new llvm::BranchInst(forbb, gIR->scopebegin());
2737
2738 p->loopbbs.pop_back();
2739
2740 // rewrite the scope
2741 gIR->scope() = IRScope(endbb,oldend);
2742 }
2743
2744 void BreakStatement::toIR(IRState* p)
2745 {
2746 static int wsi = 0;
2747 Logger::println("BreakStatement::toIR(%d): %s", wsi++, toChars());
2748 LOG_SCOPE;
2749
2750 if (ident != 0) {
2751 Logger::println("ident = %s", ident->toChars());
2752 assert(0);
2753 }
2754 else {
2755 new llvm::BranchInst(gIR->loopbbs.back().end, gIR->scopebegin());
2756 }
2757 }
2758
2759 void ContinueStatement::toIR(IRState* p)
2760 {
2761 static int wsi = 0;
2762 Logger::println("ContinueStatement::toIR(%d): %s", wsi++, toChars());
2763 LOG_SCOPE;
2764
2765 if (ident != 0) {
2766 Logger::println("ident = %s", ident->toChars());
2767 assert(0);
2768 }
2769 else {
2770 new llvm::BranchInst(gIR->loopbbs.back().begin, gIR->scopebegin());
2771 }
2772 }
2773
2774 void OnScopeStatement::toIR(IRState* p)
2775 {
2776 static int wsi = 0;
2777 Logger::println("OnScopeStatement::toIR(%d): %s", wsi++, toChars());
2778 LOG_SCOPE;
2779
2780 assert(statement);
2781 //statement->toIR(p); // this seems to be redundant
2782 }
2783
2784 void TryFinallyStatement::toIR(IRState* p)
2785 {
2786 static int wsi = 0;
2787 Logger::println("TryFinallyStatement::toIR(%d): %s", wsi++, toChars());
2788 LOG_SCOPE;
2789
2790 llvm::BasicBlock* oldend = gIR->scopeend();
2791
2792 llvm::BasicBlock* trybb = new llvm::BasicBlock("try", gIR->topfunc(), oldend);
2793 llvm::BasicBlock* finallybb = new llvm::BasicBlock("finally", gIR->topfunc(), oldend);
2794 llvm::BasicBlock* endbb = new llvm::BasicBlock("endtryfinally", gIR->topfunc(), oldend);
2795
2796 // pass the previous BB into this
2797 new llvm::BranchInst(trybb, gIR->scopebegin());
2798
2799 gIR->scope() = IRScope(trybb,finallybb);
2800
2801 assert(body);
2802 body->toIR(p);
2803 new llvm::BranchInst(finallybb, gIR->scopebegin());
2804
2805 // rewrite the scope
2806 gIR->scope() = IRScope(finallybb,endbb);
2807
2808 assert(finalbody);
2809 finalbody->toIR(p);
2810 new llvm::BranchInst(endbb, gIR->scopebegin());
2811
2812 // rewrite the scope
2813 gIR->scope() = IRScope(endbb,oldend);
2814 }
2815
2816 void TryCatchStatement::toIR(IRState* p)
2817 {
2818 static int wsi = 0;
2819 Logger::println("TryCatchStatement::toIR(%d): %s", wsi++, toChars());
2820 LOG_SCOPE;
2821
2822 assert(0 && "try-catch is not properly");
2823
2824 assert(body);
2825 body->toIR(p);
2826
2827 assert(catches);
2828 for(size_t i=0; i<catches->dim; ++i)
2829 {
2830 Catch* c = (Catch*)catches->data[i];
2831 c->handler->toIR(p);
2832 }
2833 }
2834
2835 void ThrowStatement::toIR(IRState* p)
2836 {
2837 static int wsi = 0;
2838 Logger::println("ThrowStatement::toIR(%d): %s", wsi++, toChars());
2839 LOG_SCOPE;
2840
2841 assert(0 && "throw is not implemented");
2842
2843 assert(exp);
2844 elem* e = exp->toElem(p);
2845 delete e;
2846 }
2847
2848 #define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
2849 //STUBST(BreakStatement);
2850 //STUBST(ForStatement);
2851 STUBST(WithStatement);
2852 STUBST(SynchronizedStatement);
2853 //STUBST(ReturnStatement);
2854 //STUBST(ContinueStatement);
2855 STUBST(DefaultStatement);
2856 STUBST(CaseStatement);
2857 STUBST(SwitchStatement);
2858 STUBST(SwitchErrorStatement);
2859 STUBST(Statement);
2860 //STUBST(IfStatement);
2861 STUBST(ForeachStatement);
2862 //STUBST(DoStatement);
2863 //STUBST(WhileStatement);
2864 //STUBST(ExpStatement);
2865 //STUBST(CompoundStatement);
2866 //STUBST(ScopeStatement);
2867 STUBST(AsmStatement);
2868 //STUBST(TryCatchStatement);
2869 //STUBST(TryFinallyStatement);
2870 STUBST(VolatileStatement);
2871 STUBST(LabelStatement);
2872 //STUBST(ThrowStatement);
2873 STUBST(GotoCaseStatement);
2874 STUBST(GotoDefaultStatement);
2875 STUBST(GotoStatement);
2876 STUBST(UnrolledLoopStatement);
2877 //STUBST(OnScopeStatement);
2878
2879 2403
2880 void 2404 void
2881 EnumDeclaration::toDebug() 2405 EnumDeclaration::toDebug()
2882 { 2406 {
2883 2407