Mercurial > projects > ldc
comparison gen/toir.cpp @ 334:20446d22f832 trunk
[svn r355] Get rid of IRState::exps and topexp.
author | ChristianK |
---|---|
date | Sat, 12 Jul 2008 15:43:13 +0200 |
parents | 7086a84ab3d6 |
children | 17b844102023 |
comparison
equal
deleted
inserted
replaced
333:f7190d9eb70c | 334:20446d22f832 |
---|---|
468 LLConstant* idxs[2] = { zero, zero }; | 468 LLConstant* idxs[2] = { zero, zero }; |
469 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | 469 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
470 | 470 |
471 if (dtype->ty == Tarray) { | 471 if (dtype->ty == Tarray) { |
472 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); | 472 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); |
473 if (!p->topexp() || p->topexp()->e2 != this) { | 473 LLValue* tmpmem = new llvm::AllocaInst(DtoType(dtype),"tempstring",p->topallocapoint()); |
474 LLValue* tmpmem = new llvm::AllocaInst(DtoType(dtype),"tempstring",p->topallocapoint()); | 474 DtoSetArray(tmpmem, clen, arrptr); |
475 DtoSetArray(tmpmem, clen, arrptr); | 475 return new DVarValue(type, tmpmem, true); |
476 return new DVarValue(type, tmpmem, true); | |
477 } | |
478 else if (p->topexp()->e2 == this) { | |
479 DValue* arr = p->topexp()->v; | |
480 assert(arr); | |
481 if (arr->isSlice()) { | |
482 return new DSliceValue(type, clen, arrptr); | |
483 } | |
484 else { | |
485 DtoSetArray(arr->getRVal(), clen, arrptr); | |
486 return new DImValue(type, arr->getLVal(), true); | |
487 } | |
488 } | |
489 assert(0); | |
490 } | 476 } |
491 else if (dtype->ty == Tsarray) { | 477 else if (dtype->ty == Tsarray) { |
492 const LLType* dstType = getPtrToType(LLArrayType::get(ct, len)); | 478 const LLType* dstType = getPtrToType(LLArrayType::get(ct, len)); |
493 LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); | 479 LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); |
494 return new DVarValue(type, emem, true); | 480 return new DVarValue(type, emem, true); |
575 DValue* AssignExp::toElem(IRState* p) | 561 DValue* AssignExp::toElem(IRState* p) |
576 { | 562 { |
577 Logger::print("AssignExp::toElem: %s | %s = %s\n", toChars(), e1->type->toChars(), e2->type ? e2->type->toChars() : 0); | 563 Logger::print("AssignExp::toElem: %s | %s = %s\n", toChars(), e1->type->toChars(), e2->type ? e2->type->toChars() : 0); |
578 LOG_SCOPE; | 564 LOG_SCOPE; |
579 | 565 |
580 p->exps.push_back(IRExp(e1,e2,NULL)); | |
581 | |
582 DValue* l = e1->toElem(p); | 566 DValue* l = e1->toElem(p); |
583 p->topexp()->v = l; | |
584 DValue* r = e2->toElem(p); | 567 DValue* r = e2->toElem(p); |
585 | |
586 p->exps.pop_back(); | |
587 | 568 |
588 Logger::println("performing assignment"); | 569 Logger::println("performing assignment"); |
589 | 570 |
590 DImValue* im = r->isIm(); | 571 DImValue* im = r->isIm(); |
591 if (!im || !im->inPlace()) { | 572 if (!im || !im->inPlace()) { |
592 Logger::println("assignment not inplace"); | 573 Logger::println("assignment not inplace"); |
593 if (DArrayLenValue* al = l->isArrayLen()) | 574 if (DArrayLenValue* al = l->isArrayLen()) |
594 { | 575 { |
595 DSliceValue* slice = DtoResizeDynArray(l->getType(), l, r); | 576 DLRValue* arrlenval = l->isLRValue(); |
596 DtoAssign(l, slice); | 577 assert(arrlenval); |
578 DVarValue arrval(arrlenval->getLType(), arrlenval->getLVal(), true); | |
579 DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, r); | |
580 DtoAssign(&arrval, slice); | |
597 } | 581 } |
598 else | 582 else |
599 { | 583 { |
600 DtoAssign(l, r); | 584 DtoAssign(l, r); |
601 } | 585 } |
670 DValue* AddAssignExp::toElem(IRState* p) | 654 DValue* AddAssignExp::toElem(IRState* p) |
671 { | 655 { |
672 Logger::print("AddAssignExp::toElem: %s\n", toChars()); | 656 Logger::print("AddAssignExp::toElem: %s\n", toChars()); |
673 LOG_SCOPE; | 657 LOG_SCOPE; |
674 | 658 |
675 p->exps.push_back(IRExp(e1,e2,NULL)); | |
676 DValue* l = e1->toElem(p); | 659 DValue* l = e1->toElem(p); |
677 DValue* r = e2->toElem(p); | 660 DValue* r = e2->toElem(p); |
678 p->exps.pop_back(); | |
679 | 661 |
680 Type* t = DtoDType(type); | 662 Type* t = DtoDType(type); |
681 | 663 |
682 DValue* res; | 664 DValue* res; |
683 if (DtoDType(e1->type)->ty == Tpointer) { | 665 if (DtoDType(e1->type)->ty == Tpointer) { |
690 else { | 672 else { |
691 res = DtoBinAdd(l,r); | 673 res = DtoBinAdd(l,r); |
692 } | 674 } |
693 DtoAssign(l, res); | 675 DtoAssign(l, res); |
694 | 676 |
695 // used as lvalue :/ | 677 // might need to return l here if used as an lvalue |
696 if (p->topexp() && p->topexp()->e1 == this) | 678 // but when can this ever happen? |
697 { | 679 return res; |
698 assert(!l->isLRValue()); | |
699 return l; | |
700 } | |
701 else | |
702 { | |
703 return res; | |
704 } | |
705 } | 680 } |
706 | 681 |
707 ////////////////////////////////////////////////////////////////////////////////////////// | 682 ////////////////////////////////////////////////////////////////////////////////////////// |
708 | 683 |
709 DValue* MinExp::toElem(IRState* p) | 684 DValue* MinExp::toElem(IRState* p) |
1028 | 1003 |
1029 // argument handling | 1004 // argument handling |
1030 LLFunctionType::param_iterator argiter = llfnty->param_begin(); | 1005 LLFunctionType::param_iterator argiter = llfnty->param_begin(); |
1031 int j = 0; | 1006 int j = 0; |
1032 | 1007 |
1033 IRExp* topexp = p->topexp(); | |
1034 | |
1035 bool isInPlace = false; | |
1036 | |
1037 // attrs | 1008 // attrs |
1038 llvm::PAListPtr palist; | 1009 llvm::PAListPtr palist; |
1039 | 1010 |
1040 // hidden struct return arguments | 1011 // hidden struct return arguments |
1041 // TODO: use sret param attr | 1012 // TODO: use sret param attr |
1042 if (retinptr) { | 1013 if (retinptr) { |
1043 if (topexp && topexp->e2 == this) { | 1014 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); |
1044 assert(topexp->v); | |
1045 LLValue* tlv = topexp->v->getLVal(); | |
1046 assert(isaStruct(tlv->getType()->getContainedType(0))); | |
1047 llargs[j] = tlv; | |
1048 isInPlace = true; | |
1049 /*if (DtoIsPassedByRef(tf->next)) { | |
1050 isInPlace = true; | |
1051 } | |
1052 else | |
1053 assert(0);*/ | |
1054 } | |
1055 else { | |
1056 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); | |
1057 } | |
1058 | 1015 |
1059 if (dfn && dfn->func && dfn->func->runTimeHack) { | 1016 if (dfn && dfn->func && dfn->func->runTimeHack) { |
1060 const LLType* rettype = getPtrToType(DtoType(type)); | 1017 const LLType* rettype = getPtrToType(DtoType(type)); |
1061 if (llargs[j]->getType() != llfnty->getParamType(j)) { | 1018 if (llargs[j]->getType() != llfnty->getParamType(j)) { |
1062 Logger::println("llvmRunTimeHack==true - force casting return value param"); | 1019 Logger::println("llvmRunTimeHack==true - force casting return value param"); |
1286 } | 1243 } |
1287 | 1244 |
1288 // param attrs | 1245 // param attrs |
1289 call->setParamAttrs(palist); | 1246 call->setParamAttrs(palist); |
1290 | 1247 |
1291 return new DImValue(type, retllval, isInPlace); | 1248 return new DImValue(type, retllval, false); |
1292 } | 1249 } |
1293 | 1250 |
1294 ////////////////////////////////////////////////////////////////////////////////////////// | 1251 ////////////////////////////////////////////////////////////////////////////////////////// |
1295 | 1252 |
1296 DValue* CastExp::toElem(IRState* p) | 1253 DValue* CastExp::toElem(IRState* p) |
1300 | 1257 |
1301 DValue* u = e1->toElem(p); | 1258 DValue* u = e1->toElem(p); |
1302 DValue* v = DtoCast(u, to); | 1259 DValue* v = DtoCast(u, to); |
1303 | 1260 |
1304 if (v->isSlice()) { | 1261 if (v->isSlice()) { |
1305 assert(!gIR->topexp() || gIR->topexp()->e1 != this); | 1262 // only valid as rvalue! |
1306 return v; | 1263 return v; |
1307 } | 1264 } |
1308 | 1265 |
1309 else if (DLRValue* lr = u->isLRValue()) | 1266 else if(u->isLVal()) |
1310 return new DLRValue(lr->getLType(), lr->getLVal(), to, v->getRVal()); | |
1311 | |
1312 else if (u->isVar() && u->isVar()->lval) | |
1313 return new DLRValue(e1->type, u->getLVal(), to, v->getRVal()); | 1267 return new DLRValue(e1->type, u->getLVal(), to, v->getRVal()); |
1314 | 1268 |
1315 else if (gIR->topexp() && gIR->topexp()->e1 == this) | 1269 else |
1316 return new DLRValue(e1->type, u->getLVal(), to, v->getRVal()); | 1270 return v; |
1317 | |
1318 return v; | |
1319 } | 1271 } |
1320 | 1272 |
1321 ////////////////////////////////////////////////////////////////////////////////////////// | 1273 ////////////////////////////////////////////////////////////////////////////////////////// |
1322 | 1274 |
1323 DValue* SymOffExp::toElem(IRState* p) | 1275 DValue* SymOffExp::toElem(IRState* p) |
1363 Logger::println("PtrExp::toElem: %s | %s", toChars(), type->toChars()); | 1315 Logger::println("PtrExp::toElem: %s | %s", toChars(), type->toChars()); |
1364 LOG_SCOPE; | 1316 LOG_SCOPE; |
1365 | 1317 |
1366 DValue* a = e1->toElem(p); | 1318 DValue* a = e1->toElem(p); |
1367 | 1319 |
1368 if (p->topexp() && p->topexp()->e1 == this) { | |
1369 Logger::println("lval PtrExp"); | |
1370 return new DVarValue(type, a->getRVal(), true); | |
1371 } | |
1372 | |
1373 // this should be deterministic but right now lvalue casts don't propagate lvalueness !?! | 1320 // this should be deterministic but right now lvalue casts don't propagate lvalueness !?! |
1374 LLValue* lv = a->getRVal(); | 1321 LLValue* lv = a->getRVal(); |
1375 LLValue* v = lv; | 1322 LLValue* v = lv; |
1376 if (DtoCanLoad(v)) | 1323 if (DtoCanLoad(v)) |
1377 v = DtoLoad(v); | 1324 v = DtoLoad(v); |
1378 return new DLRValue(e1->type, lv, type, v); | 1325 return new DLRValue(type, lv, type, v); |
1379 } | 1326 } |
1380 | 1327 |
1381 ////////////////////////////////////////////////////////////////////////////////////////// | 1328 ////////////////////////////////////////////////////////////////////////////////////////// |
1382 | 1329 |
1383 DValue* DotVarExp::toElem(IRState* p) | 1330 DValue* DotVarExp::toElem(IRState* p) |
1998 LOG_SCOPE; | 1945 LOG_SCOPE; |
1999 | 1946 |
2000 DValue* u = e1->toElem(p); | 1947 DValue* u = e1->toElem(p); |
2001 Logger::println("e1 = %s", e1->type->toChars()); | 1948 Logger::println("e1 = %s", e1->type->toChars()); |
2002 | 1949 |
2003 if (p->topexp() && p->topexp()->e1 == this) | 1950 return new DArrayLenValue(e1->type, u->getLVal(), type, DtoArrayLen(u)); |
2004 { | |
2005 return new DArrayLenValue(e1->type, u->getLVal()); | |
2006 } | |
2007 else | |
2008 { | |
2009 return new DImValue(type, DtoArrayLen(u)); | |
2010 } | |
2011 } | 1951 } |
2012 | 1952 |
2013 ////////////////////////////////////////////////////////////////////////////////////////// | 1953 ////////////////////////////////////////////////////////////////////////////////////////// |
2014 | 1954 |
2015 DValue* AssertExp::toElem(IRState* p) | 1955 DValue* AssertExp::toElem(IRState* p) |
2150 \ | 2090 \ |
2151 DValue* X##AssignExp::toElem(IRState* p) \ | 2091 DValue* X##AssignExp::toElem(IRState* p) \ |
2152 { \ | 2092 { \ |
2153 Logger::print("%sAssignExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \ | 2093 Logger::print("%sAssignExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \ |
2154 LOG_SCOPE; \ | 2094 LOG_SCOPE; \ |
2155 p->exps.push_back(IRExp(e1,e2,NULL)); \ | |
2156 DValue* u = e1->toElem(p); \ | 2095 DValue* u = e1->toElem(p); \ |
2157 p->topexp()->v = u; \ | |
2158 DValue* v = e2->toElem(p); \ | 2096 DValue* v = e2->toElem(p); \ |
2159 p->exps.pop_back(); \ | |
2160 LLValue* uval = u->getRVal(); \ | 2097 LLValue* uval = u->getRVal(); \ |
2161 LLValue* vval = v->getRVal(); \ | 2098 LLValue* vval = v->getRVal(); \ |
2162 LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \ | 2099 LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \ |
2163 DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal()); \ | 2100 DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal()); \ |
2164 return u; \ | 2101 return u; \ |
2187 | 2124 |
2188 DValue* ShrAssignExp::toElem(IRState* p) | 2125 DValue* ShrAssignExp::toElem(IRState* p) |
2189 { | 2126 { |
2190 Logger::print("ShrAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2127 Logger::print("ShrAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2191 LOG_SCOPE; | 2128 LOG_SCOPE; |
2192 p->exps.push_back(IRExp(e1,e2,NULL)); | |
2193 DValue* u = e1->toElem(p); | 2129 DValue* u = e1->toElem(p); |
2194 p->topexp()->v = u; | |
2195 DValue* v = e2->toElem(p); | 2130 DValue* v = e2->toElem(p); |
2196 p->exps.pop_back(); | |
2197 LLValue* uval = u->getRVal(); | 2131 LLValue* uval = u->getRVal(); |
2198 LLValue* vval = v->getRVal(); | 2132 LLValue* vval = v->getRVal(); |
2199 LLValue* tmp; | 2133 LLValue* tmp; |
2200 if (e1->type->isunsigned()) | 2134 if (e1->type->isunsigned()) |
2201 tmp = p->ir->CreateLShr(uval, vval, "tmp"); | 2135 tmp = p->ir->CreateLShr(uval, vval, "tmp"); |
2237 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2171 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2238 LOG_SCOPE; | 2172 LOG_SCOPE; |
2239 | 2173 |
2240 const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty); | 2174 const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty); |
2241 | 2175 |
2242 LLValue* lval; | 2176 LLValue* lval = new llvm::AllocaInst(DtoType(type), "tmpdelegate", p->topallocapoint()); |
2243 bool inplace = false; | |
2244 if (p->topexp() && p->topexp()->e2 == this) { | |
2245 assert(p->topexp()->v); | |
2246 lval = p->topexp()->v->getLVal(); | |
2247 inplace = true; | |
2248 } | |
2249 else { | |
2250 lval = new llvm::AllocaInst(DtoType(type), "tmpdelegate", p->topallocapoint()); | |
2251 } | |
2252 | 2177 |
2253 DValue* u = e1->toElem(p); | 2178 DValue* u = e1->toElem(p); |
2254 LLValue* uval; | 2179 LLValue* uval; |
2255 if (DFuncValue* f = u->isFunc()) { | 2180 if (DFuncValue* f = u->isFunc()) { |
2256 assert(f->func); | 2181 assert(f->func); |
2298 } | 2223 } |
2299 | 2224 |
2300 castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0)); | 2225 castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0)); |
2301 DtoStore(castfptr, fptr); | 2226 DtoStore(castfptr, fptr); |
2302 | 2227 |
2303 return new DImValue(type, lval, inplace); | 2228 return new DImValue(type, lval); |
2304 } | 2229 } |
2305 | 2230 |
2306 ////////////////////////////////////////////////////////////////////////////////////////// | 2231 ////////////////////////////////////////////////////////////////////////////////////////// |
2307 | 2232 |
2308 DValue* IdentityExp::toElem(IRState* p) | 2233 DValue* IdentityExp::toElem(IRState* p) |
2515 if (fd->isNested()) Logger::println("nested"); | 2440 if (fd->isNested()) Logger::println("nested"); |
2516 Logger::println("kind = %s\n", fd->kind()); | 2441 Logger::println("kind = %s\n", fd->kind()); |
2517 | 2442 |
2518 DtoForceDefineDsymbol(fd); | 2443 DtoForceDefineDsymbol(fd); |
2519 | 2444 |
2520 bool temp = false; | 2445 const LLType* dgty = DtoType(type); |
2521 LLValue* lval = NULL; | 2446 LLValue* lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); |
2522 if (p->topexp() && p->topexp()->e2 == this) { | |
2523 assert(p->topexp()->v); | |
2524 lval = p->topexp()->v->getLVal(); | |
2525 } | |
2526 else { | |
2527 const LLType* dgty = DtoType(type); | |
2528 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; | |
2529 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); | |
2530 temp = true; | |
2531 } | |
2532 | 2447 |
2533 LLValue* context = DtoGEPi(lval,0,0); | 2448 LLValue* context = DtoGEPi(lval,0,0); |
2534 const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0)); | 2449 const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0)); |
2535 LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar; | 2450 LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar; |
2536 if (llvmNested == NULL) { | 2451 if (llvmNested == NULL) { |
2546 | 2461 |
2547 assert(fd->ir.irFunc->func); | 2462 assert(fd->ir.irFunc->func); |
2548 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); | 2463 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); |
2549 DtoStore(castfptr, fptr); | 2464 DtoStore(castfptr, fptr); |
2550 | 2465 |
2551 if (temp) | 2466 return new DVarValue(type, lval, true); |
2552 return new DVarValue(type, lval, true); | |
2553 else | |
2554 return new DImValue(type, lval, true); | |
2555 } | 2467 } |
2556 | 2468 |
2557 ////////////////////////////////////////////////////////////////////////////////////////// | 2469 ////////////////////////////////////////////////////////////////////////////////////////// |
2558 | 2470 |
2559 DValue* ArrayLiteralExp::toElem(IRState* p) | 2471 DValue* ArrayLiteralExp::toElem(IRState* p) |
2580 const LLType* llStoType = LLArrayType::get(DtoType(elemType), len); | 2492 const LLType* llStoType = LLArrayType::get(DtoType(elemType), len); |
2581 Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; | 2493 Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; |
2582 | 2494 |
2583 // dst pointer | 2495 // dst pointer |
2584 LLValue* dstMem = 0; | 2496 LLValue* dstMem = 0; |
2585 | 2497 dstMem = new llvm::AllocaInst(llStoType, "arrayliteral", p->topallocapoint()); |
2586 // rvalue of assignment | |
2587 if (p->topexp() && p->topexp()->e2 == this) | |
2588 { | |
2589 DValue* topval = p->topexp()->v; | |
2590 // slice assignment (copy) | |
2591 if (DSliceValue* s = topval->isSlice()) | |
2592 { | |
2593 assert(s->ptr->getType()->getContainedType(0) == llStoType->getContainedType(0)); | |
2594 dstMem = DtoBitCast(s->ptr, getPtrToType(llStoType)); | |
2595 sliceInPlace = true; | |
2596 // FIXME: insert bounds checks | |
2597 } | |
2598 // static array assignment | |
2599 else if (topval->getType()->toBasetype()->ty == Tsarray) | |
2600 { | |
2601 dstMem = topval->getLVal(); | |
2602 } | |
2603 // otherwise we still need to alloca storage | |
2604 } | |
2605 | |
2606 // alloca storage if not found already | |
2607 if (!dstMem) | |
2608 { | |
2609 dstMem = new llvm::AllocaInst(llStoType, "arrayliteral", p->topallocapoint()); | |
2610 } | |
2611 Logger::cout() << "using dest mem: " << *dstMem << '\n'; | |
2612 | 2498 |
2613 // store elements | 2499 // store elements |
2614 for (size_t i=0; i<len; ++i) | 2500 for (size_t i=0; i<len; ++i) |
2615 { | 2501 { |
2616 Expression* expr = (Expression*)elements->data[i]; | 2502 Expression* expr = (Expression*)elements->data[i]; |
2617 LLValue* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); | 2503 LLValue* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); |
2618 | 2504 |
2619 // emulate assignment | 2505 // emulate assignment |
2620 DVarValue* vv = new DVarValue(expr->type, elemAddr, true); | 2506 DVarValue* vv = new DVarValue(expr->type, elemAddr, true); |
2621 p->exps.push_back(IRExp(NULL, expr, vv)); | |
2622 DValue* e = expr->toElem(p); | 2507 DValue* e = expr->toElem(p); |
2623 p->exps.pop_back(); | |
2624 DImValue* im = e->isIm(); | 2508 DImValue* im = e->isIm(); |
2625 if (!im || !im->inPlace()) { | 2509 if (!im || !im->inPlace()) { |
2626 DtoAssign(vv, e); | 2510 DtoAssign(vv, e); |
2627 } | 2511 } |
2628 } | 2512 } |
2629 | 2513 |
2630 // return storage directly ? | 2514 // return storage directly ? |
2631 if (!dyn || (dyn && sliceInPlace)) | 2515 if (!dyn || (dyn && sliceInPlace)) |
2632 return new DImValue(type, dstMem, true); | 2516 return new DImValue(type, dstMem, false); |
2633 // wrap in a slice | 2517 // wrap in a slice |
2634 return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); | 2518 return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); |
2635 } | 2519 } |
2636 | 2520 |
2637 ////////////////////////////////////////////////////////////////////////////////////////// | 2521 ////////////////////////////////////////////////////////////////////////////////////////// |
2662 DValue* StructLiteralExp::toElem(IRState* p) | 2546 DValue* StructLiteralExp::toElem(IRState* p) |
2663 { | 2547 { |
2664 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2548 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2665 LOG_SCOPE; | 2549 LOG_SCOPE; |
2666 | 2550 |
2667 LLValue* sptr; | |
2668 const LLType* llt = DtoType(type); | 2551 const LLType* llt = DtoType(type); |
2669 | 2552 |
2670 LLValue* mem = 0; | 2553 LLValue* mem = 0; |
2671 bool isinplace = true; | 2554 |
2672 | 2555 LLValue* sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint()); |
2673 // already has memory (r-value of assignment) | |
2674 IRExp* topexp = p->topexp(); | |
2675 if (topexp && topexp->e2 == this && !topexp->v->isSlice()) | |
2676 { | |
2677 assert(topexp->e2 == this); | |
2678 sptr = topexp->v->getLVal(); | |
2679 } | |
2680 // temporary struct literal | |
2681 else | |
2682 { | |
2683 sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint()); | |
2684 isinplace = false; | |
2685 } | |
2686 | 2556 |
2687 | 2557 |
2688 // num elements in literal | 2558 // num elements in literal |
2689 unsigned n = elements->dim; | 2559 unsigned n = elements->dim; |
2690 | 2560 |
2717 | 2587 |
2718 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; | 2588 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; |
2719 LLValue* arrptr = DtoGEPi(sptr,0,j); | 2589 LLValue* arrptr = DtoGEPi(sptr,0,j); |
2720 DValue* darrptr = new DVarValue(vx->type, arrptr, true); | 2590 DValue* darrptr = new DVarValue(vx->type, arrptr, true); |
2721 | 2591 |
2722 p->exps.push_back(IRExp(NULL,vx,darrptr)); | |
2723 DValue* ve = vx->toElem(p); | 2592 DValue* ve = vx->toElem(p); |
2724 p->exps.pop_back(); | |
2725 | 2593 |
2726 if (!ve->inPlace()) | 2594 if (!ve->inPlace()) |
2727 DtoAssign(darrptr, ve); | 2595 DtoAssign(darrptr, ve); |
2728 | 2596 |
2729 j++; | 2597 j++; |
2730 } | 2598 } |
2731 | 2599 |
2732 return new DImValue(type, sptr, isinplace); | 2600 return new DImValue(type, sptr); |
2733 } | 2601 } |
2734 | 2602 |
2735 ////////////////////////////////////////////////////////////////////////////////////////// | 2603 ////////////////////////////////////////////////////////////////////////////////////////// |
2736 | 2604 |
2737 LLConstant* StructLiteralExp::toConstElem(IRState* p) | 2605 LLConstant* StructLiteralExp::toConstElem(IRState* p) |