comparison gen/toir.c @ 54:28e99b04a132 trunk

[svn r58] Fixed cond expression resulting in a non-basic type. Fixed identity expression for dynamic arrays. Revamped the system to keep track of lvalues and rvalues and their relations. Typedef declaration now generate the custom typeinfo. Other bugfixes.
author lindquist
date Wed, 24 Oct 2007 01:37:34 +0200
parents 06ccc817acd4
children 0ccfae271c45
comparison
equal deleted inserted replaced
53:06ccc817acd4 54:28e99b04a132
375 375
376 elem* e = new elem; 376 elem* e = new elem;
377 377
378 if (dtype->ty == Tarray) { 378 if (dtype->ty == Tarray) {
379 llvm::Constant* clen = llvm::ConstantInt::get(LLVM_DtoSize_t(),len,false); 379 llvm::Constant* clen = llvm::ConstantInt::get(LLVM_DtoSize_t(),len,false);
380 if (p->lvals.empty() || !p->toplval()) { 380 if (!p->topexp() || p->topexp()->e2 != this) {
381 llvm::Value* tmpmem = new llvm::AllocaInst(LLVM_DtoType(dtype),"tmp",p->topallocapoint()); 381 llvm::Value* tmpmem = new llvm::AllocaInst(LLVM_DtoType(dtype),"tmp",p->topallocapoint());
382 LLVM_DtoSetArray(tmpmem, clen, arrptr); 382 LLVM_DtoSetArray(tmpmem, clen, arrptr);
383 e->mem = tmpmem; 383 e->mem = tmpmem;
384 } 384 }
385 else if (llvm::Value* arr = p->toplval()) { 385 else if (p->topexp()->e2 == this) {
386 if (llvm::isa<llvm::GlobalVariable>(arr)) { 386 llvm::Value* arr = p->topexp()->v;
387 e->val = LLVM_DtoConstantSlice(clen, arrptr); 387 assert(arr);
388 } 388 LLVM_DtoSetArray(arr, clen, arrptr);
389 else { 389 e->inplace = true;
390 LLVM_DtoSetArray(arr, clen, arrptr);
391 e->inplace = true;
392 }
393 } 390 }
394 else 391 else
395 assert(0); 392 assert(0);
396 } 393 }
397 else if (dtype->ty == Tsarray) { 394 else if (dtype->ty == Tsarray) {
451 elem* AssignExp::toElem(IRState* p) 448 elem* AssignExp::toElem(IRState* p)
452 { 449 {
453 Logger::print("AssignExp::toElem: %s | %s = %s\n", toChars(), e1->type->toChars(), e2->type->toChars()); 450 Logger::print("AssignExp::toElem: %s | %s = %s\n", toChars(), e1->type->toChars(), e2->type->toChars());
454 LOG_SCOPE; 451 LOG_SCOPE;
455 452
456 assert(e1 && e2); 453 p->exps.push_back(IRExp(e1,e2,NULL));
457 p->inLvalue = true; 454
458 elem* l = e1->toElem(p); 455 elem* l = e1->toElem(p);
459 p->inLvalue = false; 456 p->topexp()->v = l->mem;
460 457 elem* r = e2->toElem(p);
461 p->lvals.push_back(l->mem); 458
462 elem* r = e2->toElem(p); 459 p->exps.pop_back();
463 p->lvals.pop_back();
464 460
465 if (l->type == elem::ARRAYLEN) 461 if (l->type == elem::ARRAYLEN)
466 { 462 {
467 LLVM_DtoResizeDynArray(l->mem, r->getValue()); 463 LLVM_DtoResizeDynArray(l->mem, r->getValue());
468 delete r; 464 delete r;
1064 llvm::FunctionType::param_iterator argiter = llfnty->param_begin(); 1060 llvm::FunctionType::param_iterator argiter = llfnty->param_begin();
1065 int j = 0; 1061 int j = 0;
1066 1062
1067 Logger::println("hidden struct return"); 1063 Logger::println("hidden struct return");
1068 1064
1065 IRExp* topexp = p->topexp();
1066
1069 // hidden struct return arguments 1067 // hidden struct return arguments
1070 if (retinptr) { 1068 if (retinptr) {
1071 if (!p->lvals.empty() && p->toplval()) { 1069 if (topexp && topexp->e2 == this) {
1072 assert(llvm::isa<llvm::StructType>(p->toplval()->getType()->getContainedType(0))); 1070 assert(topexp->v);
1073 llargs[j] = p->toplval(); 1071 assert(llvm::isa<llvm::StructType>(topexp->v->getType()->getContainedType(0)));
1072 llargs[j] = topexp->v;
1074 if (LLVM_DtoIsPassedByRef(tf->next)) { 1073 if (LLVM_DtoIsPassedByRef(tf->next)) {
1075 e->inplace = true; 1074 e->inplace = true;
1076 } 1075 }
1077 else 1076 else
1078 assert(0); 1077 assert(0);
1532 elem* e = new elem; 1531 elem* e = new elem;
1533 1532
1534 llvm::Value* sptr = 0; 1533 llvm::Value* sptr = 0;
1535 1534
1536 // if there is no lval, this is probably a temporary struct literal. correct? 1535 // if there is no lval, this is probably a temporary struct literal. correct?
1537 if (p->lvals.empty() || !p->toplval()) 1536 if (!p->topexp() || p->topexp()->e2 != this)
1538 { 1537 {
1539 sptr = new llvm::AllocaInst(LLVM_DtoType(type),"tmpstructliteral",p->topallocapoint()); 1538 sptr = new llvm::AllocaInst(LLVM_DtoType(type),"tmpstructliteral",p->topallocapoint());
1540 e->mem = sptr; 1539 e->mem = sptr;
1541 e->type = elem::VAR; 1540 e->type = elem::VAR;
1542 } 1541 }
1543 // already has memory 1542 // already has memory
1543 else if (p->topexp()->e2 == this)
1544 {
1545 sptr = p->topexp()->v;
1546 }
1544 else 1547 else
1545 { 1548 assert(0);
1546 sptr = p->toplval();
1547 }
1548 1549
1549 assert(sptr); 1550 assert(sptr);
1550 1551
1551 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 1552 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1552 1553
1556 llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false); 1557 llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false);
1557 llvm::Value* arrptr = LLVM_DtoGEP(sptr,zero,offset,"tmp",p->scopebb()); 1558 llvm::Value* arrptr = LLVM_DtoGEP(sptr,zero,offset,"tmp",p->scopebb());
1558 1559
1559 Expression* vx = (Expression*)elements->data[i]; 1560 Expression* vx = (Expression*)elements->data[i];
1560 if (vx != 0) { 1561 if (vx != 0) {
1561 p->lvals.push_back(arrptr); 1562 p->exps.push_back(IRExp(NULL,vx,arrptr));
1562 elem* ve = vx->toElem(p); 1563 elem* ve = vx->toElem(p);
1563 p->lvals.pop_back(); 1564 p->exps.pop_back();
1564 1565
1565 if (!ve->inplace) { 1566 if (!ve->inplace) {
1566 llvm::Value* val = ve->getValue(); 1567 llvm::Value* val = ve->getValue();
1567 Logger::cout() << *val << " | " << *arrptr << '\n'; 1568 Logger::cout() << *val << " | " << *arrptr << '\n';
1568 1569
2040 else if (ntype->ty == Tarray) { 2041 else if (ntype->ty == Tarray) {
2041 assert(arguments); 2042 assert(arguments);
2042 if (arguments->dim == 1) { 2043 if (arguments->dim == 1) {
2043 elem* sz = ((Expression*)arguments->data[0])->toElem(p); 2044 elem* sz = ((Expression*)arguments->data[0])->toElem(p);
2044 llvm::Value* dimval = sz->getValue(); 2045 llvm::Value* dimval = sz->getValue();
2045 LLVM_DtoNewDynArray(p->toplval(), dimval, ntype->next); 2046 assert(p->topexp() && p->topexp()->e2 == this && p->topexp()->v);
2047 LLVM_DtoNewDynArray(p->topexp()->v, dimval, ntype->next);
2046 delete sz; 2048 delete sz;
2047 } 2049 }
2048 else { 2050 else {
2049 assert(0); 2051 assert(0);
2050 } 2052 }
2159 LOG_SCOPE; 2161 LOG_SCOPE;
2160 2162
2161 elem* e = new elem; 2163 elem* e = new elem;
2162 elem* u = e1->toElem(p); 2164 elem* u = e1->toElem(p);
2163 2165
2164 if (p->inLvalue) 2166 if (p->topexp() && p->topexp()->e1 == this)
2165 { 2167 {
2166 e->mem = u->mem; 2168 e->mem = u->mem;
2167 e->type = elem::ARRAYLEN; 2169 e->type = elem::ARRAYLEN;
2168 } 2170 }
2169 else 2171 else
2370 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); 2372 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars());
2371 LOG_SCOPE; 2373 LOG_SCOPE;
2372 2374
2373 elem* e = new elem; 2375 elem* e = new elem;
2374 elem* u = e1->toElem(p); 2376 elem* u = e1->toElem(p);
2375 2377
2376 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 2378 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
2377 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); 2379 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
2378 2380
2379 const llvm::Type* int8ptrty = llvm::PointerType::get(llvm::Type::Int8Ty); 2381 const llvm::Type* int8ptrty = llvm::PointerType::get(llvm::Type::Int8Ty);
2380 2382
2381 llvm::Value* lval = p->toplval(); 2383 assert(p->topexp() && p->topexp()->e2 == this && p->topexp()->v);
2384 llvm::Value* lval = p->topexp()->v;
2382 2385
2383 llvm::Value* context = LLVM_DtoGEP(lval,zero,zero,"tmp",p->scopebb()); 2386 llvm::Value* context = LLVM_DtoGEP(lval,zero,zero,"tmp",p->scopebb());
2384 llvm::Value* castcontext = new llvm::BitCastInst(u->getValue(),int8ptrty,"tmp",p->scopebb()); 2387 llvm::Value* castcontext = new llvm::BitCastInst(u->getValue(),int8ptrty,"tmp",p->scopebb());
2385 new llvm::StoreInst(castcontext, context, p->scopebb()); 2388 new llvm::StoreInst(castcontext, context, p->scopebb());
2386 2389
2387 llvm::Value* fptr = LLVM_DtoGEP(lval,zero,one,"tmp",p->scopebb()); 2390 llvm::Value* fptr = LLVM_DtoGEP(lval,zero,one,"tmp",p->scopebb());
2388 2391
2389 assert(func->llvmValue); 2392 assert(func->llvmValue);
2390 llvm::Value* castfptr = new llvm::BitCastInst(func->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); 2393 llvm::Value* castfptr = new llvm::BitCastInst(func->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
2391 new llvm::StoreInst(castfptr, fptr, p->scopebb()); 2394 new llvm::StoreInst(castfptr, fptr, p->scopebb());
2392 2395
2393 e->inplace = true; 2396 e->inplace = true;
2394 2397
2395 delete u; 2398 delete u;
2396 return e; 2399 return e;
2397 } 2400 }
2398 2401
2399 ////////////////////////////////////////////////////////////////////////////////////////// 2402 //////////////////////////////////////////////////////////////////////////////////////////
2413 if (v->type == elem::NUL) 2416 if (v->type == elem::NUL)
2414 r = llvm::ConstantPointerNull::get(llvm::cast<llvm::PointerType>(l->getType())); 2417 r = llvm::ConstantPointerNull::get(llvm::cast<llvm::PointerType>(l->getType()));
2415 else 2418 else
2416 r = v->getValue(); 2419 r = v->getValue();
2417 2420
2418 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; 2421 Type* t1 = LLVM_DtoDType(e1->type);
2419 e->val = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb()); 2422
2423 if (t1->ty == Tarray) {
2424 assert(l->getType() == r->getType());
2425 e->val = LLVM_DtoDynArrayIs(op,l,r);
2426 }
2427 else {
2428 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
2429 e->val = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb());
2430 }
2420 e->type = elem::VAL; 2431 e->type = elem::VAL;
2421 2432
2422 delete u; 2433 delete u;
2423 delete v; 2434 delete v;
2424 2435
2443 elem* CondExp::toElem(IRState* p) 2454 elem* CondExp::toElem(IRState* p)
2444 { 2455 {
2445 Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars()); 2456 Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars());
2446 LOG_SCOPE; 2457 LOG_SCOPE;
2447 2458
2448 const llvm::Type* resty = LLVM_DtoType(type); 2459 Type* dtype = LLVM_DtoDType(type);
2460 const llvm::Type* resty = LLVM_DtoType(dtype);
2449 2461
2450 // allocate a temporary for the final result. failed to come up with a better way :/ 2462 // allocate a temporary for the final result. failed to come up with a better way :/
2451 llvm::BasicBlock* entryblock = &p->topfunc()->front(); 2463 llvm::BasicBlock* entryblock = &p->topfunc()->front();
2452 llvm::Value* resval = new llvm::AllocaInst(resty,"condtmp",p->topallocapoint()); 2464 llvm::Value* resval = new llvm::AllocaInst(resty,"condtmp",p->topallocapoint());
2453 2465
2461 delete c; 2473 delete c;
2462 new llvm::BranchInst(condtrue,condfalse,cond_val,p->scopebb()); 2474 new llvm::BranchInst(condtrue,condfalse,cond_val,p->scopebb());
2463 2475
2464 p->scope() = IRScope(condtrue, condfalse); 2476 p->scope() = IRScope(condtrue, condfalse);
2465 elem* u = e1->toElem(p); 2477 elem* u = e1->toElem(p);
2466 new llvm::StoreInst(u->getValue(),resval,p->scopebb()); 2478 LLVM_DtoAssign(dtype, resval, u->getValue());
2467 new llvm::BranchInst(condend,p->scopebb()); 2479 new llvm::BranchInst(condend,p->scopebb());
2468 delete u; 2480 delete u;
2469 2481
2470 p->scope() = IRScope(condfalse, condend); 2482 p->scope() = IRScope(condfalse, condend);
2471 elem* v = e2->toElem(p); 2483 elem* v = e2->toElem(p);
2472 new llvm::StoreInst(v->getValue(),resval,p->scopebb()); 2484 LLVM_DtoAssign(dtype, resval, v->getValue());
2473 new llvm::BranchInst(condend,p->scopebb()); 2485 new llvm::BranchInst(condend,p->scopebb());
2474 delete v; 2486 delete v;
2475 2487
2476 p->scope() = IRScope(condend, oldend); 2488 p->scope() = IRScope(condend, oldend);
2477 2489
2478 elem* e = new elem; 2490 elem* e = new elem;
2479 e->val = new llvm::LoadInst(resval,"tmp",p->scopebb()); 2491 e->mem = resval;
2480 e->type = elem::VAL; 2492 e->type = elem::VAR;
2481 return e; 2493 return e;
2482 } 2494 }
2483 2495
2484 ////////////////////////////////////////////////////////////////////////////////////////// 2496 //////////////////////////////////////////////////////////////////////////////////////////
2485 2497
2587 2599
2588 const llvm::Type* t = LLVM_DtoType(type); 2600 const llvm::Type* t = LLVM_DtoType(type);
2589 Logger::cout() << "array literal has llvm type: " << *t << '\n'; 2601 Logger::cout() << "array literal has llvm type: " << *t << '\n';
2590 2602
2591 llvm::Value* mem = 0; 2603 llvm::Value* mem = 0;
2592 if (p->lvals.empty() || !p->toplval()) { 2604 if (!p->topexp() || p->topexp()->e2 != this) {
2593 assert(LLVM_DtoDType(type)->ty == Tsarray); 2605 assert(LLVM_DtoDType(type)->ty == Tsarray);
2594 mem = new llvm::AllocaInst(t,"tmparrayliteral",p->topallocapoint()); 2606 mem = new llvm::AllocaInst(t,"tmparrayliteral",p->topallocapoint());
2595 } 2607 }
2596 else { 2608 else if (p->topexp()->e2 == this) {
2597 mem = p->toplval(); 2609 mem = p->topexp()->v;
2610 assert(mem);
2598 if (!llvm::isa<llvm::PointerType>(mem->getType()) || 2611 if (!llvm::isa<llvm::PointerType>(mem->getType()) ||
2599 !llvm::isa<llvm::ArrayType>(mem->getType()->getContainedType(0))) 2612 !llvm::isa<llvm::ArrayType>(mem->getType()->getContainedType(0)))
2600 { 2613 {
2601 error("TODO array literals can currently only be used to initialise static arrays"); 2614 error("TODO array literals can currently only be used to initialise static arrays");
2602 fatal(); 2615 fatal();
2603 } 2616 }
2604 } 2617 }
2618 else
2619 assert(0);
2605 2620
2606 for (unsigned i=0; i<elements->dim; ++i) 2621 for (unsigned i=0; i<elements->dim; ++i)
2607 { 2622 {
2608 Expression* expr = (Expression*)elements->data[i]; 2623 Expression* expr = (Expression*)elements->data[i];
2609 llvm::Value* elemAddr = LLVM_DtoGEPi(mem,0,i,"tmp",p->scopebb()); 2624 llvm::Value* elemAddr = LLVM_DtoGEPi(mem,0,i,"tmp",p->scopebb());
2655 Logger::println("kind = %s\n", fd->kind()); 2670 Logger::println("kind = %s\n", fd->kind());
2656 2671
2657 fd->toObjFile(); 2672 fd->toObjFile();
2658 2673
2659 llvm::Value* lval = NULL; 2674 llvm::Value* lval = NULL;
2660 if (p->lvals.empty() || p->toplval() == NULL) { 2675 if (!p->topexp() || p->topexp()->e2 != this) {
2661 const llvm::Type* dgty = LLVM_DtoType(type); 2676 const llvm::Type* dgty = LLVM_DtoType(type);
2662 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; 2677 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n';
2663 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); 2678 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint());
2664 } 2679 }
2665 else { 2680 else if (p->topexp()->e2 == this) {
2666 lval = p->toplval(); 2681 lval = p->topexp()->v;
2667 } 2682 assert(lval);
2683 }
2684 else
2685 assert(0);
2668 2686
2669 elem* e = new elem; 2687 elem* e = new elem;
2670 2688
2671 llvm::Value* context = LLVM_DtoGEPi(lval,0,0,"tmp",p->scopebb()); 2689 llvm::Value* context = LLVM_DtoGEPi(lval,0,0,"tmp",p->scopebb());
2672 const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0)); 2690 const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0));