comparison gen/toir.cpp @ 94:61615fa85940 trunk

[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca"). Added support for array .sort and .reverse properties. Fixed some bugs with pointer arithmetic. Disabled some DMD AST optimizations that was messing things up, destroying valuable information. Added a KDevelop project file, this is what I use for coding LLVMDC now :) Other minor stuff.
author lindquist
date Mon, 12 Nov 2007 06:32:46 +0100
parents 70d6113eeb8c
children ce7ed8f59b99
comparison
equal deleted inserted replaced
93:08508eebbb3e 94:61615fa85940
64 const llvm::Type* lltype = DtoType(vd->type); 64 const llvm::Type* lltype = DtoType(vd->type);
65 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); 65 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
66 //allocainst->setAlignment(vd->type->alignsize()); // TODO 66 //allocainst->setAlignment(vd->type->alignsize()); // TODO
67 vd->llvmValue = allocainst; 67 vd->llvmValue = allocainst;
68 } 68 }
69 DVarValue* vv = new DVarValue(type, vd->llvmValue, true); 69 DValue* ie = DtoInitializer(vd->init);
70 DValue* ie = DtoInitializer(vd->init, vv);
71 delete ie;
72 } 70 }
73 71
74 return new DVarValue(vd, vd->llvmValue, true); 72 return new DVarValue(vd, vd->llvmValue, true);
75 } 73 }
76 // struct declaration 74 // struct declaration
463 461
464 p->exps.pop_back(); 462 p->exps.pop_back();
465 463
466 DImValue* im = r->isIm(); 464 DImValue* im = r->isIm();
467 if (!im || !im->inPlace()) { 465 if (!im || !im->inPlace()) {
466 Logger::println("assignment not inplace");
468 if (l->isArrayLen()) 467 if (l->isArrayLen())
469 DtoResizeDynArray(l->getLVal(), r->getRVal()); 468 DtoResizeDynArray(l->getLVal(), r->getRVal());
470 else 469 else
471 DtoAssign(l, r); 470 DtoAssign(l, r);
472 } 471 }
657 std::vector<unsigned> offsets; 656 std::vector<unsigned> offsets;
658 llvm::Value* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets); 657 llvm::Value* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets);
659 return new DFieldValue(type, v, true); 658 return new DFieldValue(type, v, true);
660 } 659 }
661 else if (e1type->ty == Tpointer) { 660 else if (e1type->ty == Tpointer) {
662 Logger::println("add to AddrExp of struct"); 661 Logger::println("add to pointer");
662 if (r->isConst()) {
663 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c);
664 if (cofs->isZero()) {
665 Logger::println("is zero");
666 return new DImValue(type, l->getRVal());
667 }
668 }
663 llvm::Value* v = new llvm::GetElementPtrInst(l->getRVal(), r->getRVal(), "tmp", p->scopebb()); 669 llvm::Value* v = new llvm::GetElementPtrInst(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
664 return new DImValue(type, v); 670 return new DImValue(type, v);
665 } 671 }
666 assert(0); 672 assert(0);
667 } 673 }
726 732
727 DValue* l = e1->toElem(p); 733 DValue* l = e1->toElem(p);
728 DValue* r = e2->toElem(p); 734 DValue* r = e2->toElem(p);
729 735
730 if (DtoDType(e1->type)->ty == Tpointer) { 736 if (DtoDType(e1->type)->ty == Tpointer) {
731 llvm::Value* left = p->ir->CreatePtrToInt(l->getRVal(), DtoSize_t(), "tmp"); 737 llvm::Value* lv = l->getRVal();
732 llvm::Value* right = p->ir->CreatePtrToInt(r->getRVal(), DtoSize_t(), "tmp"); 738 llvm::Value* rv = r->getRVal();
733 llvm::Value* diff = p->ir->CreateSub(left,right,"tmp"); 739 Logger::cout() << "lv: " << *lv << " rv: " << *rv << '\n';
740 if (isaPointer(lv))
741 lv = p->ir->CreatePtrToInt(lv, DtoSize_t(), "tmp");
742 if (isaPointer(rv))
743 rv = p->ir->CreatePtrToInt(rv, DtoSize_t(), "tmp");
744 llvm::Value* diff = p->ir->CreateSub(lv,rv,"tmp");
734 if (diff->getType() != DtoType(type)) 745 if (diff->getType() != DtoType(type))
735 diff = p->ir->CreateIntToPtr(diff, DtoType(type)); 746 diff = p->ir->CreateIntToPtr(diff, DtoType(type));
736 return new DImValue(type, diff); 747 return new DImValue(type, diff);
737 } 748 }
738 else { 749 else {
1092 Type* t = DtoDType(type); 1103 Type* t = DtoDType(type);
1093 const llvm::Type* llt = DtoType(type); 1104 const llvm::Type* llt = DtoType(type);
1094 if (DtoIsPassedByRef(t)) 1105 if (DtoIsPassedByRef(t))
1095 llt = llvm::PointerType::get(llt); 1106 llt = llvm::PointerType::get(llt);
1096 return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp")); 1107 return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp"));
1108 }
1109 else if (fndecl->llvmInternal == LLVMalloca) {
1110 //Argument* fnarg = Argument::getNth(tf->parameters, 0);
1111 Expression* exp = (Expression*)arguments->data[0];
1112 DValue* expv = exp->toElem(p);
1113 llvm::Value* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
1114 return new DImValue(type, alloc);
1097 } 1115 }
1098 } 1116 }
1099 1117
1100 // args 1118 // args
1101 size_t n = arguments->dim; 1119 size_t n = arguments->dim;
1543 const llvm::Type* llt = DtoType(t); 1561 const llvm::Type* llt = DtoType(t);
1544 llvm::Value* off = 0; 1562 llvm::Value* off = 0;
1545 if (offset != 0) { 1563 if (offset != 0) {
1546 Logger::println("offset = %d\n", offset); 1564 Logger::println("offset = %d\n", offset);
1547 } 1565 }
1548 if (llvalue->getType() != llt) { 1566 if (offset == 0) {
1549 varmem = p->ir->CreateBitCast(llvalue, llt, "tmp"); 1567 varmem = llvalue;
1550 if (offset != 0)
1551 varmem = DtoGEPi(varmem, offset, "tmp");
1552 } 1568 }
1553 else { 1569 else {
1554 assert(offset == 0); 1570 const llvm::Type* elemtype = llvalue->getType()->getContainedType(0)->getContainedType(0);
1555 varmem = DtoGEPi(llvalue,0,0,"tmp"); 1571 size_t elemsz = gTargetData->getTypeSize(elemtype);
1572 varmem = DtoGEPi(llvalue, 0, offset / elemsz, "tmp");
1556 } 1573 }
1557 } 1574 }
1558 else if (offset == 0) { 1575 else if (offset == 0) {
1559 Logger::println("normal symoff"); 1576 Logger::println("normal symoff");
1560 1577
1569 else { 1586 else {
1570 assert(0); 1587 assert(0);
1571 } 1588 }
1572 return new DFieldValue(type, varmem, true); 1589 return new DFieldValue(type, varmem, true);
1573 } 1590 }
1574 else if (FuncDeclaration* fd = var->isFuncDeclaration()) 1591
1592 assert(0);
1593 return 0;
1594 }
1595
1596 //////////////////////////////////////////////////////////////////////////////////////////
1597
1598 DValue* AddrExp::toElem(IRState* p)
1599 {
1600 Logger::print("AddrExp::toElem: %s | %s\n", toChars(), type->toChars());
1601 LOG_SCOPE;
1602 DValue* v = e1->toElem(p);
1603 if (v->isField())
1604 return v;
1605 if (DFuncValue* fv = v->isFunc())
1575 { 1606 {
1576 Logger::println("FuncDeclaration"); 1607 Logger::println("FuncDeclaration");
1577 1608 FuncDeclaration* fd = fv->func;
1609 assert(fd);
1578 if (fd->llvmValue == 0) 1610 if (fd->llvmValue == 0)
1579 fd->toObjFile(); 1611 fd->toObjFile();
1580 return new DFuncValue(fd, fd->llvmValue); 1612 return new DFuncValue(fd, fd->llvmValue);
1581 } 1613 }
1582 1614 return new DFieldValue(type, v->getLVal(), false);
1583 assert(0);
1584 return 0;
1585 } 1615 }
1586 1616
1587 ////////////////////////////////////////////////////////////////////////////////////////// 1617 //////////////////////////////////////////////////////////////////////////////////////////
1588 1618
1589 DValue* PtrExp::toElem(IRState* p) 1619 DValue* PtrExp::toElem(IRState* p)
1698 return 0; 1728 return 0;
1699 } 1729 }
1700 1730
1701 ////////////////////////////////////////////////////////////////////////////////////////// 1731 //////////////////////////////////////////////////////////////////////////////////////////
1702 1732
1703 DValue* AddrExp::toElem(IRState* p)
1704 {
1705 Logger::print("AddrExp::toElem: %s | %s\n", toChars(), type->toChars());
1706 LOG_SCOPE;
1707 DValue* v = e1->toElem(p);
1708 if (v->isField())
1709 return v;
1710 return new DFieldValue(type, v->getLVal(), false);
1711 }
1712
1713 //////////////////////////////////////////////////////////////////////////////////////////
1714
1715 DValue* IndexExp::toElem(IRState* p) 1733 DValue* IndexExp::toElem(IRState* p)
1716 { 1734 {
1717 Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars()); 1735 Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars());
1718 LOG_SCOPE; 1736 LOG_SCOPE;
1719 1737
1753 1771
1754 Type* t = DtoDType(type); 1772 Type* t = DtoDType(type);
1755 Type* e1type = DtoDType(e1->type); 1773 Type* e1type = DtoDType(e1->type);
1756 1774
1757 DValue* v = e1->toElem(p); 1775 DValue* v = e1->toElem(p);
1758 llvm::Value* vmem = v->isIm() ? v->getRVal() : v->getLVal(); 1776 llvm::Value* vmem = v->getRVal();
1759 assert(vmem); 1777 assert(vmem);
1760 1778
1761 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 1779 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1762 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); 1780 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
1763 1781
2098 Type* ntype = DtoDType(newtype); 2116 Type* ntype = DtoDType(newtype);
2099 2117
2100 const llvm::Type* t = DtoType(ntype); 2118 const llvm::Type* t = DtoType(ntype);
2101 2119
2102 llvm::Value* emem = 0; 2120 llvm::Value* emem = 0;
2103 bool inplace = true; 2121 bool inplace = false;
2104 2122
2105 if (onstack) { 2123 if (onstack) {
2106 assert(ntype->ty == Tclass); 2124 assert(ntype->ty == Tclass);
2107 emem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint()); 2125 emem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint());
2108 } 2126 }
2127 else if (ntype->ty == Tclass) {
2128 emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
2129 }
2130 else if (ntype->ty == Tarray) {
2131 assert(arguments);
2132 if (arguments->dim == 1) {
2133 DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
2134 llvm::Value* dimval = sz->getRVal();
2135 Type* nnt = DtoDType(ntype->next);
2136 if (nnt->ty == Tvoid)
2137 nnt = Type::tint8;
2138 if (!p->topexp() || p->topexp()->e2 != this) {
2139 const llvm::Type* restype = DtoType(type);
2140 Logger::cout() << "restype = " << *restype << '\n';
2141 emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint());
2142 DtoNewDynArray(emem, dimval, nnt);
2143 return new DVarValue(newtype, emem, true);
2144 }
2145 else if (p->topexp() && p->topexp()->e2 == this) {
2146 assert(p->topexp()->v);
2147 emem = p->topexp()->v->getLVal();
2148 DtoNewDynArray(emem, dimval, nnt);
2149 inplace = true;
2150 }
2151 else
2152 assert(0);
2153 }
2154 else {
2155 assert(0);
2156 }
2157 }
2109 else { 2158 else {
2110 if (ntype->ty == Tclass) { 2159 emem = new llvm::MallocInst(t,"tmp",p->scopebb());
2111 emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
2112 }
2113 else if (ntype->ty == Tarray) {
2114 assert(arguments);
2115 if (arguments->dim == 1) {
2116 DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
2117 llvm::Value* dimval = sz->getRVal();
2118 Type* nnt = DtoDType(ntype->next);
2119 if (nnt->ty == Tvoid)
2120 nnt = Type::tint8;
2121 if (!p->topexp() || p->topexp()->e2 != this) {
2122 const llvm::Type* restype = DtoType(type);
2123 Logger::cout() << "restype = " << *restype << '\n';
2124 emem = new llvm::AllocaInst(restype,"tmp",p->topallocapoint());
2125 DtoNewDynArray(emem, dimval, nnt);
2126 inplace = false;
2127 }
2128 else if (p->topexp() || p->topexp()->e2 != this) {
2129 assert(p->topexp()->v);
2130 emem = p->topexp()->v->getLVal();
2131 DtoNewDynArray(emem, dimval, nnt);
2132 }
2133 else
2134 assert(0);
2135 }
2136 else {
2137 assert(0);
2138 }
2139 }
2140 else {
2141 emem = new llvm::MallocInst(t,"tmp",p->scopebb());
2142 }
2143 } 2160 }
2144 2161
2145 if (ntype->ty == Tclass) { 2162 if (ntype->ty == Tclass) {
2146 // first apply the static initializer 2163 // first apply the static initializer
2147 DtoInitClass((TypeClass*)ntype, emem); 2164 DtoInitClass((TypeClass*)ntype, emem);
2173 else { 2190 else {
2174 DtoStructCopy(emem,ts->llvmInit); 2191 DtoStructCopy(emem,ts->llvmInit);
2175 } 2192 }
2176 } 2193 }
2177 2194
2178 if (inplace) 2195 return new DImValue(type, emem, inplace);
2179 return new DImValue(type, emem, true);
2180
2181 return new DVarValue(type, emem, true);
2182 } 2196 }
2183 2197
2184 ////////////////////////////////////////////////////////////////////////////////////////// 2198 //////////////////////////////////////////////////////////////////////////////////////////
2185 2199
2186 DValue* DeleteExp::toElem(IRState* p) 2200 DValue* DeleteExp::toElem(IRState* p)
2262 LOG_SCOPE; 2276 LOG_SCOPE;
2263 2277
2264 DValue* u = e1->toElem(p); 2278 DValue* u = e1->toElem(p);
2265 DValue* m = msg ? msg->toElem(p) : NULL; 2279 DValue* m = msg ? msg->toElem(p) : NULL;
2266 2280
2267 llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); 2281 DtoAssert(u->getRVal(), &loc, m);
2268 DtoAssert(u->getRVal(), loca, m ? m->getRVal() : NULL);
2269 2282
2270 return 0; 2283 return 0;
2271 } 2284 }
2272 2285
2273 ////////////////////////////////////////////////////////////////////////////////////////// 2286 //////////////////////////////////////////////////////////////////////////////////////////
2399 DValue* HaltExp::toElem(IRState* p) 2412 DValue* HaltExp::toElem(IRState* p)
2400 { 2413 {
2401 Logger::print("HaltExp::toElem: %s | %s\n", toChars(), type->toChars()); 2414 Logger::print("HaltExp::toElem: %s | %s\n", toChars(), type->toChars());
2402 LOG_SCOPE; 2415 LOG_SCOPE;
2403 2416
2404 llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); 2417 DtoAssert(DtoConstBool(false), &loc, NULL);
2405 DtoAssert(llvm::ConstantInt::getFalse(), loca, NULL);
2406 2418
2407 new llvm::UnreachableInst(p->scopebb()); 2419 new llvm::UnreachableInst(p->scopebb());
2408 return 0; 2420 return 0;
2409 } 2421 }
2410 2422
2632 if (fd->isNested()) Logger::println("nested"); 2644 if (fd->isNested()) Logger::println("nested");
2633 Logger::println("kind = %s\n", fd->kind()); 2645 Logger::println("kind = %s\n", fd->kind());
2634 2646
2635 fd->toObjFile(); 2647 fd->toObjFile();
2636 2648
2649 bool temp = false;
2637 llvm::Value* lval = NULL; 2650 llvm::Value* lval = NULL;
2638 if (!p->topexp() || p->topexp()->e2 != this) { 2651 if (p->topexp() && p->topexp()->e2 == this) {
2652 assert(p->topexp()->v);
2653 lval = p->topexp()->v->getLVal();
2654 }
2655 else {
2639 const llvm::Type* dgty = DtoType(type); 2656 const llvm::Type* dgty = DtoType(type);
2640 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; 2657 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n';
2641 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); 2658 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint());
2642 } 2659 temp = true;
2643 else if (p->topexp()->e2 == this) { 2660 }
2644 assert(p->topexp()->v);
2645 lval = p->topexp()->v->getLVal();;
2646 }
2647 else
2648 assert(0);
2649 2661
2650 llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); 2662 llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
2651 const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0)); 2663 const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0));
2652 llvm::Value* llvmNested = p->func().decl->llvmNested; 2664 llvm::Value* llvmNested = p->func().decl->llvmNested;
2653 if (llvmNested == NULL) { 2665 if (llvmNested == NULL) {
2663 2675
2664 assert(fd->llvmValue); 2676 assert(fd->llvmValue);
2665 llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); 2677 llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
2666 new llvm::StoreInst(castfptr, fptr, p->scopebb()); 2678 new llvm::StoreInst(castfptr, fptr, p->scopebb());
2667 2679
2668 return new DImValue(type, lval, true); 2680 if (temp)
2681 return new DVarValue(type, lval, true);
2682 else
2683 return new DImValue(type, lval, true);
2669 } 2684 }
2670 2685
2671 ////////////////////////////////////////////////////////////////////////////////////////// 2686 //////////////////////////////////////////////////////////////////////////////////////////
2672 2687
2673 DValue* ArrayLiteralExp::toElem(IRState* p) 2688 DValue* ArrayLiteralExp::toElem(IRState* p)
3091 void obj_includelib(char*){} 3106 void obj_includelib(char*){}
3092 3107
3093 AsmStatement::AsmStatement(Loc loc, Token *tokens) : 3108 AsmStatement::AsmStatement(Loc loc, Token *tokens) :
3094 Statement(loc) 3109 Statement(loc)
3095 { 3110 {
3096 assert(0); 3111 Logger::println("Ignoring AsmStatement");
3097 } 3112 }
3098 Statement *AsmStatement::syntaxCopy() 3113 Statement *AsmStatement::syntaxCopy()
3099 { 3114 {
3100 assert(0); 3115 assert(0);
3101 return 0; 3116 return 0;