comparison gen/statements.c @ 40:8b0e809563df trunk

[svn r44] Lots of bug fixes. New array literal support New array ~= operator support (for single element) New with statement support More...
author lindquist
date Fri, 19 Oct 2007 07:43:21 +0200
parents 77cdca8c210f
children ff359b65fa62
comparison
equal deleted inserted replaced
39:fd5e8bbfcb25 40:8b0e809563df
4 #include <math.h> 4 #include <math.h>
5 #include <sstream> 5 #include <sstream>
6 #include <fstream> 6 #include <fstream>
7 #include <iostream> 7 #include <iostream>
8 8
9 #include "llvm/Type.h" 9 #include "gen/llvm.h"
10 #include "llvm/DerivedTypes.h"
11 #include "llvm/Constants.h"
12 #include "llvm/Instructions.h"
13 #include "llvm/IntrinsicInst.h"
14 #include "llvm/CallingConv.h"
15 10
16 #include "total.h" 11 #include "total.h"
17 #include "init.h" 12 #include "init.h"
18 #include "symbol.h" 13 #include "symbol.h"
19 #include "mtype.h" 14 #include "mtype.h"
39 { 34 {
40 Statement* s = (Statement*)statements->data[i]; 35 Statement* s = (Statement*)statements->data[i];
41 if (s) 36 if (s)
42 s->toIR(p); 37 s->toIR(p);
43 else { 38 else {
44 Logger::println("NULL statement found in CompoundStatement !! :S"); 39 Logger::println("*** ATTENTION: null statement found in CompoundStatement");
45 assert(0); 40 //assert(0);
46 } 41 }
47 } 42 }
48 43
49 } 44 }
50 45
54 { 49 {
55 static int rsi = 0; 50 static int rsi = 0;
56 Logger::println("ReturnStatement::toIR(%d): %s", rsi++, toChars()); 51 Logger::println("ReturnStatement::toIR(%d): %s", rsi++, toChars());
57 LOG_SCOPE; 52 LOG_SCOPE;
58 53
54 IRFunction::FinallyVec& fin = p->func().finallys;
55
59 if (exp) 56 if (exp)
60 { 57 {
61 TY expty = exp->type->ty; 58 Type* exptype = LLVM_DtoDType(exp->type);
59 TY expty = exptype->ty;
62 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { 60 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
63 assert(expty == Tstruct || expty == Tdelegate || expty == Tarray); 61 assert(LLVM_DtoIsPassedByRef(exptype));
64 62
65 TypeFunction* f = p->topfunctype(); 63 TypeFunction* f = p->topfunctype();
66 assert(f->llvmRetInPtr && f->llvmRetArg); 64 assert(f->llvmRetInPtr && f->llvmRetArg);
67 65
68 p->lvals.push_back(f->llvmRetArg); 66 p->lvals.push_back(f->llvmRetArg);
69 elem* e = exp->toElem(p); 67 elem* e = exp->toElem(p);
70 p->lvals.pop_back(); 68 p->lvals.pop_back();
71 69
72 // structliterals do this themselves
73 // also they dont produce any value
74 if (expty == Tstruct) { 70 if (expty == Tstruct) {
75 if (!e->inplace) { 71 if (!e->inplace) {
76 TypeStruct* ts = (TypeStruct*)exp->type; 72 TypeStruct* ts = (TypeStruct*)exptype;
77 assert(e->mem); 73 assert(e->mem);
78 LLVM_DtoStructCopy(ts,f->llvmRetArg,e->mem); 74 LLVM_DtoStructCopy(ts,f->llvmRetArg,e->mem);
79 } 75 }
80 } 76 }
81 else if (expty == Tdelegate) { 77 else if (expty == Tdelegate) {
82 // do nothing, handled by the DelegateExp
83 LLVM_DtoDelegateCopy(f->llvmRetArg,e->mem); 78 LLVM_DtoDelegateCopy(f->llvmRetArg,e->mem);
84 } 79 }
85 else if (expty == Tarray) { 80 else if (expty == Tarray) {
86 if (e->type == elem::SLICE) { 81 if (e->type == elem::SLICE) {
87 LLVM_DtoSetArray(f->llvmRetArg,e->arg,e->mem); 82 LLVM_DtoSetArray(f->llvmRetArg,e->arg,e->mem);
89 // else the return value is a variable and should already have been assigned by now 84 // else the return value is a variable and should already have been assigned by now
90 } 85 }
91 else 86 else
92 assert(0); 87 assert(0);
93 88
94 new llvm::ReturnInst(p->scopebb()); 89 if (fin.empty())
90 new llvm::ReturnInst(p->scopebb());
91 else {
92 new llvm::BranchInst(fin.back().bb);
93 fin.back().ret = true;
94 }
95 delete e; 95 delete e;
96 } 96 }
97 else { 97 else {
98 elem* e = exp->toElem(p); 98 elem* e = exp->toElem(p);
99 llvm::Value* v = e->getValue(); 99 llvm::Value* v = e->getValue();
100 Logger::cout() << *v << '\n';
101 new llvm::ReturnInst(v, p->scopebb());
102 delete e; 100 delete e;
101 Logger::cout() << "return value is '" <<*v << "'\n";
102 if (fin.empty()) {
103 new llvm::ReturnInst(v, p->scopebb());
104 }
105 else {
106 llvm::Value* rettmp = new llvm::AllocaInst(v->getType(),"tmpreturn",p->topallocapoint());
107 new llvm::StoreInst(v,rettmp,p->scopebb());
108 new llvm::BranchInst(fin.back().bb, p->scopebb());
109 fin.back().ret = true;
110 fin.back().retval = rettmp;
111 }
103 } 112 }
104 } 113 }
105 else 114 else
106 { 115 {
107 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) 116 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
108 new llvm::ReturnInst(p->scopebb()); 117 if (fin.empty()) {
109 else 118 new llvm::ReturnInst(p->scopebb());
119 }
120 else {
121 new llvm::BranchInst(fin.back().bb);
122 fin.back().ret = true;
123 }
124 }
125 else {
126 assert(0); // why should this ever happen?
110 new llvm::UnreachableInst(p->scopebb()); 127 new llvm::UnreachableInst(p->scopebb());
111 } 128 }
112 129 }
113 p->scope().returned = true;
114 } 130 }
115 131
116 ////////////////////////////////////////////////////////////////////////////// 132 //////////////////////////////////////////////////////////////////////////////
117 133
118 void ExpStatement::toIR(IRState* p) 134 void ExpStatement::toIR(IRState* p)
194 Logger::println("ScopeStatement::toIR(): %s", toChars()); 210 Logger::println("ScopeStatement::toIR(): %s", toChars());
195 LOG_SCOPE; 211 LOG_SCOPE;
196 212
197 llvm::BasicBlock* oldend = p->scopeend(); 213 llvm::BasicBlock* oldend = p->scopeend();
198 214
199 IRScope irs; 215 llvm::BasicBlock* beginbb = 0;
216
200 // remove useless branches by clearing and reusing the current basicblock 217 // remove useless branches by clearing and reusing the current basicblock
201 llvm::BasicBlock* bb = p->scopebegin(); 218 llvm::BasicBlock* bb = p->scopebegin();
202 if (bb->empty()) { 219 if (bb->empty()) {
203 irs.begin = bb; 220 beginbb = bb;
204 } 221 }
205 else { 222 else {
206 irs.begin = new llvm::BasicBlock("scope", p->topfunc(), oldend); 223 assert(!p->scopereturned());
207 new llvm::BranchInst(irs.begin, p->scopebegin()); 224 beginbb = new llvm::BasicBlock("scope", p->topfunc(), oldend);
208 } 225 new llvm::BranchInst(beginbb, p->scopebegin());
209 irs.end = new llvm::BasicBlock("endscope", p->topfunc(), oldend); 226 }
210 227 llvm::BasicBlock* endbb = new llvm::BasicBlock("endscope", p->topfunc(), oldend);
211 gIR->scope() = irs; 228
229 gIR->scope() = IRScope(beginbb, endbb);
212 230
213 statement->toIR(p); 231 statement->toIR(p);
214 232
215 p->scope() = IRScope(p->scopebb(),oldend); 233 p->scope() = IRScope(p->scopebb(),oldend);
216 irs.end->eraseFromParent(); 234 endbb->eraseFromParent();
217
218 /*
219 if (!gIR->scopereturned()) {
220 new llvm::BranchInst(irs.end, gIR->scopebegin());
221 }
222
223 // rewrite the scope
224 gIR->scope() = IRScope(irs.end,oldend);
225 */
226 } 235 }
227 236
228 ////////////////////////////////////////////////////////////////////////////// 237 //////////////////////////////////////////////////////////////////////////////
229 238
230 void WhileStatement::toIR(IRState* p) 239 void WhileStatement::toIR(IRState* p)
237 llvm::BasicBlock* oldend = gIR->scopeend(); 246 llvm::BasicBlock* oldend = gIR->scopeend();
238 llvm::BasicBlock* whilebb = new llvm::BasicBlock("whilecond", gIR->topfunc(), oldend); 247 llvm::BasicBlock* whilebb = new llvm::BasicBlock("whilecond", gIR->topfunc(), oldend);
239 llvm::BasicBlock* endbb = new llvm::BasicBlock("endwhile", gIR->topfunc(), oldend); 248 llvm::BasicBlock* endbb = new llvm::BasicBlock("endwhile", gIR->topfunc(), oldend);
240 249
241 // move into the while block 250 // move into the while block
242 new llvm::BranchInst(whilebb, gIR->scopebegin()); 251 p->ir->CreateBr(whilebb);
252 //new llvm::BranchInst(whilebb, gIR->scopebegin());
243 253
244 // replace current scope 254 // replace current scope
245 gIR->scope() = IRScope(whilebb,endbb); 255 gIR->scope() = IRScope(whilebb,endbb);
246 256
247 // create the condition 257 // create the condition
322 init->toIR(p); 332 init->toIR(p);
323 333
324 // move into the for condition block, ie. start the loop 334 // move into the for condition block, ie. start the loop
325 new llvm::BranchInst(forbb, gIR->scopebegin()); 335 new llvm::BranchInst(forbb, gIR->scopebegin());
326 336
327 IRScope loop; 337 p->loopbbs.push_back(IRScope(forincbb,endbb));
328 loop.begin = forincbb;
329 loop.end = endbb;
330 p->loopbbs.push_back(loop);
331 338
332 // replace current scope 339 // replace current scope
333 gIR->scope() = IRScope(forbb,forbodybb); 340 gIR->scope() = IRScope(forbb,forbodybb);
334 341
335 // create the condition 342 // create the condition
417 { 424 {
418 static int wsi = 0; 425 static int wsi = 0;
419 Logger::println("TryFinallyStatement::toIR(%d): %s", wsi++, toChars()); 426 Logger::println("TryFinallyStatement::toIR(%d): %s", wsi++, toChars());
420 LOG_SCOPE; 427 LOG_SCOPE;
421 428
422 llvm::BasicBlock* oldend = gIR->scopeend(); 429 llvm::BasicBlock* oldend = p->scopeend();
423 430
424 llvm::BasicBlock* trybb = new llvm::BasicBlock("try", gIR->topfunc(), oldend); 431 llvm::BasicBlock* trybb = new llvm::BasicBlock("try", p->topfunc(), oldend);
425 llvm::BasicBlock* finallybb = new llvm::BasicBlock("finally", gIR->topfunc(), oldend); 432 llvm::BasicBlock* finallybb = new llvm::BasicBlock("finally", p->topfunc(), oldend);
426 llvm::BasicBlock* endbb = new llvm::BasicBlock("endtryfinally", gIR->topfunc(), oldend); 433 llvm::BasicBlock* endbb = new llvm::BasicBlock("endtryfinally", p->topfunc(), oldend);
427 434
428 // pass the previous BB into this 435 // pass the previous BB into this
429 new llvm::BranchInst(trybb, gIR->scopebegin()); 436 new llvm::BranchInst(trybb, p->scopebb());
430 437
431 gIR->scope() = IRScope(trybb,finallybb); 438 p->scope() = IRScope(trybb,finallybb);
432 439
433 assert(body); 440 assert(body);
441 gIR->func().finallys.push_back(IRFinally(finallybb));
434 body->toIR(p); 442 body->toIR(p);
435 new llvm::BranchInst(finallybb, gIR->scopebegin()); 443 if (!gIR->scopereturned())
444 new llvm::BranchInst(finallybb, p->scopebb());
436 445
437 // rewrite the scope 446 // rewrite the scope
438 gIR->scope() = IRScope(finallybb,endbb); 447 p->scope() = IRScope(finallybb,endbb);
439 448
440 assert(finalbody); 449 assert(finalbody);
441 finalbody->toIR(p); 450 finalbody->toIR(p);
442 new llvm::BranchInst(endbb, gIR->scopebegin()); 451 if (gIR->func().finallys.back().ret) {
452 llvm::Value* retval = p->func().finallys.back().retval;
453 if (retval) {
454 retval = new llvm::LoadInst(retval,"tmp",p->scopebb());
455 new llvm::ReturnInst(retval, p->scopebb());
456 }
457 else {
458 new llvm::ReturnInst(p->scopebb());
459 }
460 }
461 else if (!gIR->scopereturned()) {
462 new llvm::BranchInst(endbb, p->scopebb());
463 }
464
465 p->func().finallys.pop_back();
443 466
444 // rewrite the scope 467 // rewrite the scope
445 gIR->scope() = IRScope(endbb,oldend); 468 p->scope() = IRScope(endbb,oldend);
446 } 469 }
447 470
448 ////////////////////////////////////////////////////////////////////////////// 471 //////////////////////////////////////////////////////////////////////////////
449 472
450 void TryCatchStatement::toIR(IRState* p) 473 void TryCatchStatement::toIR(IRState* p)
626 if (key) key->llvmValue = keyvar; 649 if (key) key->llvmValue = keyvar;
627 650
628 const llvm::Type* valtype = LLVM_DtoType(value->type); 651 const llvm::Type* valtype = LLVM_DtoType(value->type);
629 llvm::Value* valvar = new llvm::AllocaInst(keytype, "foreachval", p->topallocapoint()); 652 llvm::Value* valvar = new llvm::AllocaInst(keytype, "foreachval", p->topallocapoint());
630 653
631 if (aggr->type->ty == Tsarray) 654 if (LLVM_DtoDType(aggr->type)->ty == Tsarray)
632 { 655 {
633 assert(llvm::isa<llvm::PointerType>(val->getType())); 656 assert(llvm::isa<llvm::PointerType>(val->getType()));
634 assert(llvm::isa<llvm::ArrayType>(val->getType()->getContainedType(0))); 657 assert(llvm::isa<llvm::ArrayType>(val->getType()->getContainedType(0)));
635 size_t n = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements(); 658 size_t n = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements();
636 assert(n > 0); 659 assert(n > 0);
684 p->scope() = IRScope(p->scopebb(),endbb); 707 p->scope() = IRScope(p->scopebb(),endbb);
685 p->loopbbs.push_back(IRScope(nexbb,endbb)); 708 p->loopbbs.push_back(IRScope(nexbb,endbb));
686 body->toIR(p); 709 body->toIR(p);
687 p->loopbbs.pop_back(); 710 p->loopbbs.pop_back();
688 711
689 if (!p->scope().returned) 712 if (!p->scopereturned())
690 new llvm::BranchInst(nexbb, p->scopebb()); 713 new llvm::BranchInst(nexbb, p->scopebb());
691 714
692 // end 715 // end
693 p->scope() = IRScope(endbb,oldend); 716 p->scope() = IRScope(endbb,oldend);
694 } 717 }
732 p->scope() = IRScope(bb,oldend); 755 p->scope() = IRScope(bb,oldend);
733 } 756 }
734 757
735 ////////////////////////////////////////////////////////////////////////////// 758 //////////////////////////////////////////////////////////////////////////////
736 759
760 void WithStatement::toIR(IRState* p)
761 {
762 Logger::println("WithStatement::toIR(): %s", toChars());
763 LOG_SCOPE;
764
765 assert(exp);
766 assert(body);
767
768 elem* e = exp->toElem(p);
769 wthis->llvmValue = e->getValue();
770 delete e;
771
772 body->toIR(p);
773 }
774
775 //////////////////////////////////////////////////////////////////////////////
776
737 ////////////////////////////////////////////////////////////////////////////// 777 //////////////////////////////////////////////////////////////////////////////
738 778
739 #define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();} 779 #define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
740 //STUBST(BreakStatement); 780 //STUBST(BreakStatement);
741 //STUBST(ForStatement); 781 //STUBST(ForStatement);
742 STUBST(WithStatement); 782 //STUBST(WithStatement);
743 STUBST(SynchronizedStatement); 783 STUBST(SynchronizedStatement);
744 //STUBST(ReturnStatement); 784 //STUBST(ReturnStatement);
745 //STUBST(ContinueStatement); 785 //STUBST(ContinueStatement);
746 STUBST(DefaultStatement); 786 STUBST(DefaultStatement);
747 STUBST(CaseStatement); 787 STUBST(CaseStatement);