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