Changeset 217:0806379a5eca
- Timestamp:
- 06/05/08 00:38:36
(7 months ago)
- Author:
- lindquist
- branch:
- trunk
- Message:
[svn r233] Added: -oq command line option for writing fully qualified object names.
Added: started support for x86 80bit floating point.
Changed: aggregates passed by value now use the llvm 'byval' parameter attribute, also lays ground work for
using other attributes.
Changed: eliminated a lot more std::vectorS, these showed up pretty much at the top when profiling!
Changed: performed other misc. cleanups.
Changed: halt expression now call the new llvm trap intrinsic instead of an assert(0).
Changed: dstress suite now passes -O0 by default, this only eliminates unreferenced globals, which speeds up
linking quite a bit.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r205 |
r217 |
|
| 203 | 203 | -of<filename> name output file to <filename>\n\ |
|---|
| 204 | 204 | -op do not strip paths from source file\n\ |
|---|
| | 205 | -oq write object files with fully qualified names\n\ |
|---|
| 205 | 206 | -profile profile runtime performance of generated code\n\ |
|---|
| 206 | 207 | -quiet suppress unnecessary messages\n\ |
|---|
| … | … | |
| 215 | 216 | -version=ident compile in version code identified by ident\n\ |
|---|
| 216 | 217 | -w enable warnings\n\ |
|---|
| | 218 | -fp80 enable 80bit reals on x86 32bit (EXPERIMENTAL)\n\ |
|---|
| 217 | 219 | ", |
|---|
| 218 | 220 | #if WIN32 |
|---|
| … | … | |
| 398 | 400 | else if (strcmp(p + 1, "annotate") == 0) |
|---|
| 399 | 401 | global.params.llvmAnnotate = 1; |
|---|
| | 402 | else if (strcmp(p + 1, "fp80") == 0) |
|---|
| | 403 | global.params.useFP80 = 1; |
|---|
| 400 | 404 | else if (p[1] == 'o') |
|---|
| 401 | 405 | { |
|---|
| … | … | |
| 423 | 427 | global.params.preservePaths = 1; |
|---|
| 424 | 428 | break; |
|---|
| | 429 | |
|---|
| | 430 | case 'q': |
|---|
| | 431 | if (p[3]) |
|---|
| | 432 | goto Lerror; |
|---|
| | 433 | global.params.fqnPaths = 1; |
|---|
| | 434 | break; |
|---|
| 425 | 435 | |
|---|
| 426 | 436 | case 0: |
|---|
| … | … | |
| 692 | 702 | } |
|---|
| 693 | 703 | |
|---|
| | 704 | bool is_x86 = false; |
|---|
| 694 | 705 | if (strcmp(global.params.llvmArch,"x86")==0) { |
|---|
| 695 | 706 | VersionCondition::addPredefinedGlobalIdent("X86"); |
|---|
| … | … | |
| 699 | 710 | tt_arch = "i686"; |
|---|
| 700 | 711 | data_layout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:8"; |
|---|
| | 712 | is_x86 = true; |
|---|
| 701 | 713 | } |
|---|
| 702 | 714 | else if (strcmp(global.params.llvmArch,"x86-64")==0) { |
|---|
| … | … | |
| 739 | 751 | if (global.params.is64bit) { |
|---|
| 740 | 752 | VersionCondition::addPredefinedGlobalIdent("LLVM64"); |
|---|
| | 753 | } |
|---|
| | 754 | |
|---|
| | 755 | if (global.params.useFP80) { |
|---|
| | 756 | if (!is_x86) { |
|---|
| | 757 | error("the -fp80 option is only valid for the x86 32bit architecture"); |
|---|
| | 758 | fatal(); |
|---|
| | 759 | } |
|---|
| | 760 | VersionCondition::addPredefinedGlobalIdent("LLVM_X86_FP80"); |
|---|
| 741 | 761 | } |
|---|
| 742 | 762 | |
|---|
| r159 |
r217 |
|
| 134 | 134 | char llvmAnnotate; |
|---|
| 135 | 135 | char *runtimePath; |
|---|
| | 136 | char useFP80; |
|---|
| | 137 | char fqnPaths; // use fully qualified object names |
|---|
| 136 | 138 | }; |
|---|
| 137 | 139 | |
|---|
| r211 |
r217 |
|
| 2539 | 2539 | Type *treturn = next ? next->syntaxCopy() : NULL; |
|---|
| 2540 | 2540 | Arguments *params = Argument::arraySyntaxCopy(parameters); |
|---|
| 2541 | | Type *t = new TypeFunction(params, treturn, varargs, linkage); |
|---|
| | 2541 | TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage); |
|---|
| | 2542 | t->llvmRetInPtr = llvmRetInPtr; |
|---|
| | 2543 | t->llvmUsesThis = llvmUsesThis; |
|---|
| 2542 | 2544 | return t; |
|---|
| 2543 | 2545 | } |
|---|
| … | … | |
| 5063 | 5065 | this->storageClass = storageClass; |
|---|
| 5064 | 5066 | this->defaultArg = defaultArg; |
|---|
| | 5067 | this->llvmByVal = false; |
|---|
| 5065 | 5068 | } |
|---|
| 5066 | 5069 | |
|---|
| … | … | |
| 5071 | 5074 | ident, |
|---|
| 5072 | 5075 | defaultArg ? defaultArg->syntaxCopy() : NULL); |
|---|
| | 5076 | a->llvmByVal = llvmByVal; |
|---|
| 5073 | 5077 | return a; |
|---|
| 5074 | 5078 | } |
|---|
| r211 |
r217 |
|
| 682 | 682 | static size_t dim(Arguments *arguments); |
|---|
| 683 | 683 | static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL); |
|---|
| | 684 | |
|---|
| | 685 | // LLVMDC |
|---|
| | 686 | bool llvmByVal; |
|---|
| 684 | 687 | }; |
|---|
| 685 | 688 | |
|---|
| r213 |
r217 |
|
| 87 | 87 | pkey = DtoBitCast(pkey, funcTy->getParamType(3)); |
|---|
| 88 | 88 | |
|---|
| 89 | | // build arg vector |
|---|
| 90 | | LLSmallVector<LLValue*, 4> args; |
|---|
| 91 | | args.push_back(aaval); |
|---|
| 92 | | args.push_back(keyti); |
|---|
| 93 | | args.push_back(valsize); |
|---|
| 94 | | args.push_back(pkey); |
|---|
| 95 | | |
|---|
| 96 | 89 | // call runtime |
|---|
| 97 | | LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aa.index"); |
|---|
| | 90 | LLValue* ret = gIR->ir->CreateCall4(func, aaval, keyti, valsize, pkey, "aa.index"); |
|---|
| 98 | 91 | |
|---|
| 99 | 92 | // cast return value |
|---|
| … | … | |
| 132 | 125 | pkey = DtoBitCast(pkey, funcTy->getParamType(2)); |
|---|
| 133 | 126 | |
|---|
| 134 | | // build arg vector |
|---|
| 135 | | LLSmallVector<LLValue*, 3> args; |
|---|
| 136 | | args.push_back(aaval); |
|---|
| 137 | | args.push_back(keyti); |
|---|
| 138 | | args.push_back(pkey); |
|---|
| 139 | | |
|---|
| 140 | 127 | // call runtime |
|---|
| 141 | | LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aa.in"); |
|---|
| | 128 | LLValue* ret = gIR->ir->CreateCall3(func, aaval, keyti, pkey, "aa.in"); |
|---|
| 142 | 129 | |
|---|
| 143 | 130 | // cast return value |
|---|
| r213 |
r217 |
|
| 185 | 185 | Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n'; |
|---|
| 186 | 186 | |
|---|
| 187 | | std::vector<LLValue*> args; |
|---|
| | 187 | LLSmallVector<LLValue*, 4> args; |
|---|
| 188 | 188 | args.push_back(ptr); |
|---|
| 189 | 189 | args.push_back(dim); |
|---|
| … | … | |
| 425 | 425 | |
|---|
| 426 | 426 | llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); |
|---|
| 427 | | std::vector<LLValue*> llargs; |
|---|
| 428 | | llargs.resize(4); |
|---|
| | 427 | LLSmallVector<LLValue*, 4> llargs(4); |
|---|
| 429 | 428 | llargs[0] = dstarr; |
|---|
| 430 | 429 | llargs[1] = srcarr; |
|---|
| 431 | 430 | llargs[2] = sz1; |
|---|
| 432 | | llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
|---|
| | 431 | llargs[3] = DtoConstInt(0); |
|---|
| 433 | 432 | |
|---|
| 434 | 433 | llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
|---|
| … | … | |
| 445 | 444 | |
|---|
| 446 | 445 | llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); |
|---|
| 447 | | std::vector<LLValue*> llargs; |
|---|
| 448 | | llargs.resize(4); |
|---|
| | 446 | LLSmallVector<LLValue*, 4> llargs(4); |
|---|
| 449 | 447 | llargs[0] = dstarr; |
|---|
| 450 | 448 | llargs[1] = srcarr; |
|---|
| 451 | 449 | llargs[2] = sz1; |
|---|
| 452 | | llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
|---|
| | 450 | llargs[3] = DtoConstInt(0); |
|---|
| 453 | 451 | |
|---|
| 454 | 452 | llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
|---|
| … | … | |
| 468 | 466 | |
|---|
| 469 | 467 | llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); |
|---|
| 470 | | std::vector<LLValue*> llargs; |
|---|
| 471 | | llargs.resize(4); |
|---|
| | 468 | LLSmallVector<LLValue*,4> llargs(4); |
|---|
| 472 | 469 | llargs[0] = dstarr; |
|---|
| 473 | 470 | llargs[1] = srcarr; |
|---|
| 474 | 471 | llargs[2] = n; |
|---|
| 475 | | llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
|---|
| | 472 | llargs[3] = DtoConstInt(0); |
|---|
| 476 | 473 | |
|---|
| 477 | 474 | llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
|---|
| … | … | |
| 481 | 478 | LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) |
|---|
| 482 | 479 | { |
|---|
| 483 | | std::vector<const LLType*> types; |
|---|
| 484 | | types.push_back(dim->getType()); |
|---|
| 485 | | types.push_back(ptr->getType()); |
|---|
| 486 | | const llvm::StructType* type = llvm::StructType::get(types); |
|---|
| 487 | | std::vector<LLConstant*> values; |
|---|
| 488 | | values.push_back(dim); |
|---|
| 489 | | values.push_back(ptr); |
|---|
| 490 | | return llvm::ConstantStruct::get(type,values); |
|---|
| | 480 | LLConstant* values[2] = { dim, ptr }; |
|---|
| | 481 | return llvm::ConstantStruct::get(values, 2); |
|---|
| 491 | 482 | } |
|---|
| 492 | 483 | |
|---|
| … | … | |
| 497 | 488 | LOG_SCOPE; |
|---|
| 498 | 489 | |
|---|
| | 490 | // typeinfo arg |
|---|
| | 491 | LLValue* arrayTypeInfo = DtoTypeInfoOf(arrayType); |
|---|
| | 492 | |
|---|
| | 493 | // dim arg |
|---|
| | 494 | assert(DtoType(dim->getType()) == DtoSize_t()); |
|---|
| | 495 | LLValue* arrayLen = dim->getRVal(); |
|---|
| | 496 | |
|---|
| | 497 | // get runtime function |
|---|
| 499 | 498 | bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit(); |
|---|
| 500 | 499 | llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" ); |
|---|
| 501 | 500 | |
|---|
| 502 | | LLSmallVector<LLValue*,2> args; |
|---|
| 503 | | args.push_back(DtoTypeInfoOf(arrayType)); |
|---|
| 504 | | assert(DtoType(dim->getType()) == DtoSize_t()); |
|---|
| 505 | | args.push_back(dim->getRVal()); |
|---|
| 506 | | |
|---|
| 507 | | LLValue* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem"); |
|---|
| | 501 | // call allocator |
|---|
| | 502 | LLValue* newptr = gIR->ir->CreateCall2(fn, arrayTypeInfo, arrayLen, ".gc_mem"); |
|---|
| | 503 | |
|---|
| | 504 | // cast to wanted type |
|---|
| 508 | 505 | const LLType* dstType = DtoType(arrayType)->getContainedType(1); |
|---|
| 509 | 506 | if (newptr->getType() != dstType) |
|---|
| … | … | |
| 519 | 516 | #endif |
|---|
| 520 | 517 | |
|---|
| 521 | | return new DSliceValue(arrayType, args[1], newptr); |
|---|
| | 518 | return new DSliceValue(arrayType, arrayLen, newptr); |
|---|
| 522 | 519 | } |
|---|
| 523 | 520 | |
|---|
| … | … | |
| 543 | 540 | args.push_back(newdim->getRVal()); |
|---|
| 544 | 541 | args.push_back(DtoArrayLen(array)); |
|---|
| | 542 | |
|---|
| 545 | 543 | LLValue* arrPtr = DtoArrayPtr(array); |
|---|
| 546 | 544 | Logger::cout() << "arrPtr = " << *arrPtr << '\n'; |
|---|
| … | … | |
| 735 | 733 | assert(l_ty->next == r_ty->next); |
|---|
| 736 | 734 | if ((l_ty->ty == Tsarray) || (r_ty->ty == Tsarray)) { |
|---|
| 737 | | Type* a_ty = new Type(Tarray, l_ty->next); |
|---|
| | 735 | Type* a_ty = l_ty->next->arrayOf(); |
|---|
| 738 | 736 | if (l_ty->ty == Tsarray) |
|---|
| 739 | 737 | l = DtoCastArray(l, a_ty); |
|---|
| … | … | |
| 775 | 773 | const LLType* pt = fn->getFunctionType()->getParamType(0); |
|---|
| 776 | 774 | |
|---|
| 777 | | std::vector<LLValue*> args; |
|---|
| | 775 | LLSmallVector<LLValue*, 3> args; |
|---|
| 778 | 776 | Logger::cout() << "bitcasting to " << *pt << '\n'; |
|---|
| 779 | 777 | Logger::cout() << *lmem << '\n'; |
|---|
| … | … | |
| 800 | 798 | LLValue* DtoArrayEquals(TOK op, DValue* l, DValue* r) |
|---|
| 801 | 799 | { |
|---|
| 802 | | llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_adEq"); |
|---|
| 803 | | assert(fn); |
|---|
| 804 | | |
|---|
| 805 | 800 | LLValue* res = DtoArrayEqCmp_impl("_adEq", l, r, true); |
|---|
| 806 | 801 | if (op == TOKnotequal) |
|---|
| … | … | |
| 884 | 879 | return len; |
|---|
| 885 | 880 | |
|---|
| 886 | | std::vector<LLValue*> args; |
|---|
| | 881 | LLSmallVector<LLValue*, 3> args; |
|---|
| 887 | 882 | args.push_back(len); |
|---|
| 888 | 883 | args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false)); |
|---|
| r213 |
r217 |
|
| 797 | 797 | { |
|---|
| 798 | 798 | llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); |
|---|
| 799 | | std::vector<LLValue*> args; |
|---|
| 800 | | args.push_back(tc->sym->ir.irStruct->classInfo); |
|---|
| 801 | | mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc"); |
|---|
| | 799 | mem = gIR->ir->CreateCall(fn, tc->sym->ir.irStruct->classInfo, "newclass_gc_alloc"); |
|---|
| 802 | 800 | mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); |
|---|
| 803 | 801 | } |
|---|
| … | … | |
| 899 | 897 | TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); |
|---|
| 900 | 898 | |
|---|
| | 899 | llvm::PAListPtr palist; |
|---|
| | 900 | |
|---|
| 901 | 901 | std::vector<LLValue*> ctorargs; |
|---|
| 902 | 902 | ctorargs.push_back(mem); |
|---|
| … | … | |
| 911 | 911 | a = DtoBitCast(a, aty); |
|---|
| 912 | 912 | ctorargs.push_back(a); |
|---|
| | 913 | if (fnarg && fnarg->llvmByVal) |
|---|
| | 914 | palist = palist.addAttr(i+2, llvm::ParamAttr::ByVal); // return,this is 2 |
|---|
| 913 | 915 | } |
|---|
| 914 | 916 | llvm::CallInst* call = llvm::CallInst::Create(fn, ctorargs.begin(), ctorargs.end(), "tmp", gIR->scopebb()); |
|---|
| 915 | 917 | call->setCallingConv(DtoCallingConv(LINKd)); |
|---|
| | 918 | call->setParamAttrs(palist); |
|---|
| 916 | 919 | |
|---|
| 917 | 920 | return new DImValue(type, call, false); |
|---|
| … | … | |
| 998 | 1001 | |
|---|
| 999 | 1002 | // Object o |
|---|
| 1000 | | LLValue* tmp = val->getRVal(); |
|---|
| 1001 | | tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
|---|
| 1002 | | args.push_back(tmp); |
|---|
| 1003 | | assert(funcTy->getParamType(0) == tmp->getType()); |
|---|
| | 1003 | LLValue* obj = val->getRVal(); |
|---|
| | 1004 | obj = DtoBitCast(obj, funcTy->getParamType(0)); |
|---|
| | 1005 | assert(funcTy->getParamType(0) == obj->getType()); |
|---|
| 1004 | 1006 | |
|---|
| 1005 | 1007 | // ClassInfo c |
|---|
| … | … | |
| 1007 | 1009 | DtoForceDeclareDsymbol(to->sym); |
|---|
| 1008 | 1010 | assert(to->sym->ir.irStruct->classInfo); |
|---|
| 1009 | | tmp = to->sym->ir.irStruct->classInfo; |
|---|
| | 1011 | LLValue* cinfo = to->sym->ir.irStruct->classInfo; |
|---|
| 1010 | 1012 | // unfortunately this is needed as the implementation of object differs somehow from the declaration |
|---|
| 1011 | 1013 | // this could happen in user code as well :/ |
|---|
| 1012 | | tmp = DtoBitCast(tmp, funcTy->getParamType(1)); |
|---|
| 1013 | | args.push_back(tmp); |
|---|
| 1014 | | assert(funcTy->getParamType(1) == tmp->getType()); |
|---|
| | 1014 | cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); |
|---|
| | 1015 | assert(funcTy->getParamType(1) == cinfo->getType()); |
|---|
| 1015 | 1016 | |
|---|
| 1016 | 1017 | // call it |
|---|
| 1017 | | LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); |
|---|
| | 1018 | LLValue* ret = gIR->ir->CreateCall2(func, obj, cinfo, "tmp"); |
|---|
| 1018 | 1019 | |
|---|
| 1019 | 1020 | // cast return value |
|---|
| … | … | |
| 1065 | 1066 | |
|---|
| 1066 | 1067 | // void* p |
|---|
| 1067 | | LLValue* tmp = val->getRVal(); |
|---|
| 1068 | | tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
|---|
| 1069 | | args.push_back(tmp); |
|---|
| | 1068 | LLValue* ptr = val->getRVal(); |
|---|
| | 1069 | ptr = DtoBitCast(ptr, funcTy->getParamType(0)); |
|---|
| 1070 | 1070 | |
|---|
| 1071 | 1071 | // ClassInfo c |
|---|
| … | … | |
| 1073 | 1073 | DtoForceDeclareDsymbol(to->sym); |
|---|
| 1074 | 1074 | assert(to->sym->ir.irStruct->classInfo); |
|---|
| 1075 | | tmp = to->sym->ir.irStruct->classInfo; |
|---|
| | 1075 | LLValue* cinfo = to->sym->ir.irStruct->classInfo; |
|---|
| 1076 | 1076 | // unfortunately this is needed as the implementation of object differs somehow from the declaration |
|---|
| 1077 | 1077 | // this could happen in user code as well :/ |
|---|
| 1078 | | tmp = DtoBitCast(tmp, funcTy->getParamType(1)); |
|---|
| 1079 | | args.push_back(tmp); |
|---|
| | 1078 | cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); |
|---|
| 1080 | 1079 | |
|---|
| 1081 | 1080 | // call it |
|---|
| 1082 | | LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); |
|---|
| | 1081 | LLValue* ret = gIR->ir->CreateCall2(func, ptr, cinfo, "tmp"); |
|---|
| 1083 | 1082 | |
|---|
| 1084 | 1083 | // cast return value |
|---|
| … | … | |
| 1128 | 1127 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 1129 | 1128 | |
|---|
| 1130 | | LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, std::vector<unsigned>& idxs) |
|---|
| | 1129 | LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, DStructIndexVector& idxs) |
|---|
| 1131 | 1130 | { |
|---|
| 1132 | 1131 | Logger::println("checking for offset %u type %s:", os, t->toChars()); |
|---|
| … | … | |
| 1158 | 1157 | idxs.push_back(vd->ir.irField->index + dataoffset); |
|---|
| 1159 | 1158 | //Logger::cout() << "indexing: " << *ptr << '\n'; |
|---|
| 1160 | | ptr = DtoGEP(ptr, idxs, "tmp"); |
|---|
| | 1159 | ptr = DtoGEPi(ptr, idxs, "tmp"); |
|---|
| 1161 | 1160 | if (ptr->getType() != llt) |
|---|
| 1162 | 1161 | ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
|---|
| … | … | |
| 1173 | 1172 | if (vd->ir.irField->indexOffset) { |
|---|
| 1174 | 1173 | Logger::println("has union field offset"); |
|---|
| 1175 | | ptr = DtoGEP(ptr, idxs, "tmp"); |
|---|
| | 1174 | ptr = DtoGEPi(ptr, idxs, "tmp"); |
|---|
| 1176 | 1175 | if (ptr->getType() != llt) |
|---|
| 1177 | 1176 | ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
|---|
| 1178 | 1177 | ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); |
|---|
| 1179 | | std::vector<unsigned> tmp; |
|---|
| | 1178 | DStructIndexVector tmp; |
|---|
| 1180 | 1179 | return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
|---|
| 1181 | 1180 | } |
|---|
| … | … | |
| 1184 | 1183 | if (ptr->getType() != sty) { |
|---|
| 1185 | 1184 | ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); |
|---|
| 1186 | | std::vector<unsigned> tmp; |
|---|
| | 1185 | DStructIndexVector tmp; |
|---|
| 1187 | 1186 | return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
|---|
| 1188 | 1187 | } |
|---|
| r213 |
r217 |
|
| 1 | 1 | #ifndef LLVMDC_GEN_CLASSES_H |
|---|
| 2 | 2 | #define LLVMDC_GEN_CLASSES_H |
|---|
| | 3 | |
|---|
| | 4 | #include "gen/structs.h" |
|---|
| 3 | 5 | |
|---|
| 4 | 6 | /** |
|---|
| … | … | |
| 36 | 38 | DValue* DtoDynamicCastInterface(DValue* val, Type* to); |
|---|
| 37 | 39 | |
|---|
| 38 | | LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, std::vector<unsigned>& idxs); |
|---|
| | 40 | LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, DStructIndexVector& idxs); |
|---|
| 39 | 41 | |
|---|
| 40 | 42 | LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl); |
|---|
| r213 |
r217 |
|
| 29 | 29 | const LLType* base; |
|---|
| 30 | 30 | if (ty == Tcomplex32) { |
|---|
| 31 | | return llvm::Type::FloatTy; |
|---|
| 32 | | } |
|---|
| 33 | | else if (ty == Tcomplex64 || ty == Tcomplex80) { |
|---|
| 34 | | return llvm::Type::DoubleTy; |
|---|
| | 31 | return LLType::FloatTy; |
|---|
| | 32 | } |
|---|
| | 33 | else if (ty == Tcomplex64) { |
|---|
| | 34 | return LLType::DoubleTy; |
|---|
| | 35 | } |
|---|
| | 36 | else if (ty == Tcomplex80) { |
|---|
| | 37 | return (global.params.useFP80) ? LLType::X86_FP80Ty : LLType::DoubleTy; |
|---|
| 35 | 38 | } |
|---|
| 36 | 39 | else { |
|---|
| … | … | |
| 61 | 64 | llvm::ConstantFP* fim; |
|---|
| 62 | 65 | |
|---|
| 63 | | const LLType* base; |
|---|
| | 66 | Type* base = 0; |
|---|
| 64 | 67 | |
|---|
| 65 | 68 | if (ty == Tcomplex32) { |
|---|
| 66 | | fre = DtoConstFP(Type::tfloat32, re); |
|---|
| 67 | | fim = DtoConstFP(Type::tfloat32, im); |
|---|
| 68 | | base = llvm::Type::FloatTy; |
|---|
| 69 | | } |
|---|
| 70 | | else if (ty == Tcomplex64 || ty == Tcomplex80) { |
|---|
| 71 | | fre = DtoConstFP(Type::tfloat64, re); |
|---|
| 72 | | fim = DtoConstFP(Type::tfloat64, im); |
|---|
| 73 | | base = llvm::Type::DoubleTy; |
|---|
| 74 | | } |
|---|
| 75 | | else |
|---|
| 76 | | assert(0); |
|---|
| | 69 | base = Type::tfloat32; |
|---|
| | 70 | } |
|---|
| | 71 | else if (ty == Tcomplex64) { |
|---|
| | 72 | base = Type::tfloat64; |
|---|
| | 73 | } |
|---|
| | 74 | else if (ty == Tcomplex80) { |
|---|
| | 75 | base = (global.params.useFP80) ? Type::tfloat80 : Type::tfloat64; |
|---|
| | 76 | } |
|---|
| 77 | 77 | |
|---|
| 78 | 78 | std::vector<LLConstant*> inits; |
|---|
| 79 | | inits.push_back(fre); |
|---|
| 80 | | inits.push_back(fim); |
|---|
| | 79 | inits.push_back(DtoConstFP(base, re)); |
|---|
| | 80 | inits.push_back(DtoConstFP(base, im)); |
|---|
| | 81 | |
|---|
| 81 | 82 | return llvm::ConstantStruct::get(DtoComplexType(_ty), inits); |
|---|
| 82 | | } |
|---|
| 83 | | |
|---|
| 84 | | LLConstant* DtoUndefComplex(Type* _ty) |
|---|
| 85 | | { |
|---|
| 86 | | assert(0); |
|---|
| 87 | | TY ty = DtoDType(_ty)->ty; |
|---|
| 88 | | const LLType* base; |
|---|
| 89 | | if (ty == Tcomplex32) { |
|---|
| 90 | | base = llvm::Type::FloatTy; |
|---|
| 91 | | } |
|---|
| 92 | | else if (ty == Tcomplex64 || ty == Tcomplex80) { |
|---|
| 93 | | base = llvm::Type::DoubleTy; |
|---|
| 94 | | } |
|---|
| 95 | | else |
|---|
| 96 | | assert(0); |
|---|
| 97 | | |
|---|
| 98 | | std::vector<LLConstant*> inits; |
|---|
| 99 | | inits.push_back(llvm::UndefValue::get(base)); |
|---|
| 100 | | inits.push_back(llvm::UndefValue::get(base)); |
|---|
| 101 | | |
|---|
| 102 | | const llvm::VectorType* vt = llvm::VectorType::get(base, 2); |
|---|
| 103 | | return llvm::ConstantVector::get(vt, inits); |
|---|
| 104 | 83 | } |
|---|
| 105 | 84 | |
|---|
| … | … | |
| 136 | 115 | LLConstant* zero; |
|---|
| 137 | 116 | if (ty == Tfloat32 || ty == Timaginary32 || ty == Tcomplex32) |
|---|
| 138 | | zero = llvm::ConstantFP::get(llvm::APFloat(0.0f)); |
|---|
| 139 | | else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tcomplex64 || ty == Tfloat80 || ty == Timaginary80 || ty == Tcomplex80) |
|---|
| 140 | | zero = llvm::ConstantFP::get(llvm::APFloat(0.0)); |
|---|
| | 117 | zero = LLConstant::getNullValue(DtoType(Type::tfloat32)); // llvm::ConstantFP::get(llvm::APFloat(0.0f)); |
|---|
| | 118 | else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tcomplex64) |
|---|
| | 119 | zero = LLConstant::getNullValue(DtoType(Type::tfloat64)); |
|---|
| | 120 | else if (ty == Tfloat80 || ty == Timaginary80 || ty == Tcomplex80) |
|---|
| | 121 | zero = LLConstant::getNullValue(DtoType((global.params.useFP80)?Type::tfloat80:Type::tfloat64)); |
|---|
| 141 | 122 | |
|---|
| 142 | 123 | if (t->isimaginary()) { |
|---|
| r213 |
r217 |
|
| 3 | 3 | |
|---|
| 4 | 4 | const llvm::StructType* DtoComplexType(Type* t); |
|---|
| 5 | | const llvm::Type* DtoComplexBaseType(Type* t); |
|---|
| | 5 | const LLType* DtoComplexBaseType(Type* t); |
|---|
| 6 | 6 | |
|---|
| 7 | 7 | LLConstant* DtoConstComplex(Type* t, LLConstant* re, LLConstant* im); |
|---|
| 8 | 8 | LLConstant* DtoConstComplex(Type* t, long double re, long double im); |
|---|
| 9 | | LLConstant* DtoUndefComplex(Type* _ty); |
|---|
| 10 | 9 | |
|---|
| 11 | 10 | LLConstant* DtoComplexShuffleMask(unsigned a, unsigned b); |
|---|
| r215 |
r217 |
|
| 52 | 52 | assert(rt); |
|---|
| 53 | 53 | Type* rtfin = DtoDType(rt); |
|---|
| 54 | | if (DtoIsPassedByRef(rt)) { |
|---|
| | 54 | if (DtoIsReturnedInArg(rt)) { |
|---|
| 55 | 55 | rettype = getPtrToType(DtoType(rt)); |
|---|
| 56 | 56 | actualRettype = llvm::Type::VoidTy; |
|---|
| … | … | |
| 95 | 95 | size_t n = Argument::dim(f->parameters); |
|---|
| 96 | 96 | |
|---|
| | 97 | int nbyval = 0; |
|---|
| | 98 | |
|---|
| | 99 | llvm::PAListPtr palist; |
|---|
| | 100 | |
|---|
| 97 | 101 | for (int i=0; i < n; ++i) { |
|---|
| 98 | 102 | Argument* arg = Argument::getNth(f->parameters, i); |
|---|
| … | … | |
| 101 | 105 | assert(argT); |
|---|
| 102 | 106 | |
|---|
| | 107 | bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout)); |
|---|
| | 108 | |
|---|
| 103 | 109 | const LLType* at = DtoType(argT); |
|---|
| 104 | 110 | if (isaStruct(at)) { |
|---|
| 105 | 111 | Logger::println("struct param"); |
|---|
| 106 | 112 | paramvec.push_back(getPtrToType(at)); |
|---|
| | 113 | arg->llvmByVal = !refOrOut; |
|---|
| 107 | 114 | } |
|---|
| 108 | 115 | else if (isaArray(at)) { |
|---|
| … | … | |
| 111 | 118 | //paramvec.push_back(getPtrToType(at->getContainedType(0))); |
|---|
| 112 | 119 | paramvec.push_back(getPtrToType(at)); |
|---|
| | 120 | arg->llvmByVal = !refOrOut; |
|---|
| 113 | 121 | } |
|---|
| 114 | 122 | else if (llvm::isa<llvm::OpaqueType>(at)) { |
|---|
| … | … | |
| 118 | 126 | } |
|---|
| 119 | 127 | else { |
|---|
| 120 | | if ((arg->storageClass & STCref) || (arg->storageClass & STCout)) { |
|---|
| | 128 | if (refOrOut) { |
|---|
| 121 | 129 | Logger::println("by ref param"); |
|---|
| 122 | 130 | at = getPtrToType(at); |
|---|
| … | … | |
| 127 | 135 | paramvec.push_back(at); |
|---|
| 128 | 136 | } |
|---|
| 129 | | } |
|---|
| | 137 | |
|---|
| | 138 | if (arg->llvmByVal) |
|---|
| | 139 | nbyval++; |
|---|
| | 140 | } |
|---|
| | 141 | |
|---|
| | 142 | //warning("set %d byval args for type: %s", nbyval, f->toChars()); |
|---|
| 130 | 143 | |
|---|
| 131 | 144 | // construct function type |
|---|
| … | … | |
| 136 | 149 | f->llvmUsesThis = usesthis; |
|---|
| 137 | 150 | |
|---|
| 138 | | //if (!f->ir.type) |
|---|
| 139 | | f->ir.type = new llvm::PATypeHolder(functype); |
|---|
| 140 | | //else |
|---|
| 141 | | //assert(functype == f->ir.type->get()); |
|---|
| | 151 | f->ir.type = new llvm::PATypeHolder(functype); |
|---|
| 142 | 152 | |
|---|
| 143 | 153 | return functype; |
|---|
| … | … | |
| 378 | 388 | fdecl->ir.irFunc->func = func; |
|---|
| 379 | 389 | assert(llvm::isa<llvm::FunctionType>(f->ir.type->get())); |
|---|
| | 390 | |
|---|
| | 391 | // parameter attributes |
|---|
| | 392 | if (f->parameters) |
|---|
| | 393 | { |
|---|
| | 394 | int llidx = 1; |
|---|
| | 395 | if (f->llvmRetInPtr) ++llidx; |
|---|
| | 396 | if (f->llvmUsesThis) ++llidx; |
|---|
| | 397 | if (f->linkage == LINKd && f->varargs == 1) |
|---|
| | 398 | llidx += 2; |
|---|
| | 399 | |
|---|
| | 400 | int funcNumArgs = func->getArgumentList().size(); |
|---|
| | 401 | std::vector<llvm::ParamAttrsWithIndex> attrs; |
|---|
| | 402 | int k = 0; |
|---|
| | 403 | |
|---|
| | 404 | int nbyval = 0; |
|---|
| | 405 | |
|---|
| | 406 | for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k) |
|---|
| | 407 | { |
|---|
| | 408 | Argument* fnarg = (Argument*)f->parameters->data[k]; |
|---|
| | 409 | assert(fnarg); |
|---|
| | 410 | if (fnarg->llvmByVal) |
|---|
| | 411 | { |
|---|
| | 412 | llvm::ParamAttrsWithIndex PAWI; |
|---|
| | 413 | PAWI.Index = llidx; |
|---|
| | 414 | PAWI.Attrs = llvm::ParamAttr::ByVal; |
|---|
| | 415 | attrs.push_back(PAWI); |
|---|
| | 416 | nbyval++; |
|---|
| | 417 | } |
|---|
| | 418 | } |
|---|
| | 419 | |
|---|
| | 420 | //warning("set %d byval args for function: %s", nbyval, func->getName().c_str()); |
|---|
| | 421 | |
|---|
| | 422 | if (nbyval) { |
|---|
| | 423 | llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end()); |
|---|
| | 424 | func->setParamAttrs(palist); |
|---|
| | 425 | } |
|---|
| | 426 | } |
|---|
| 380 | 427 | |
|---|
| 381 | 428 | // main |
|---|
| … | … | |
| 776 | 823 | arg = new DImValue(argexp->type, arg->getRVal(), false); |
|---|
| 777 | 824 | } |
|---|
| 778 | | // aggregate arg |
|---|
| 779 | | else if (DtoIsPassedByRef(argexp->type)) |
|---|
| | 825 | // byval arg, but expr has no storage yet |
|---|
| | 826 | else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isComplex() || arg->isNull())) |
|---|
| 780 | 827 | { |
|---|
| 781 | 828 | LLValue* alloc = new llvm::AllocaInst(DtoType(argexp->type), "tmpparam", gIR->topallocapoint()); |
|---|
| … | … | |
| 783 | 830 | DtoAssign(vv, arg); |
|---|
| 784 | 831 | arg = vv; |
|---|
| 785 | | } |
|---|
| 786 | | // normal arg (basic/value type) |
|---|
| 787 | | else |
|---|
| 788 | | { |
|---|
| 789 | | // nothing to do |
|---|
| 790 | 832 | } |
|---|
| 791 | 833 | |
|---|
| r213 |
r217 |
|
| 93 | 93 | emit_finallyblocks(p, enclosingtryfinally, NULL); |
|---|
| 94 | 94 | |
|---|
| 95 | | if (gIR->func()->inVolatile) { |
|---|
| | 95 | if (f->inVolatile) { |
|---|
| 96 | 96 | // store-load barrier |
|---|
| 97 | 97 | DtoMemoryBarrier(false, false, true, false); |
|---|
| … | … | |
| 129 | 129 | else |
|---|
| 130 | 130 | { |
|---|
| 131 | | if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { |
|---|
| 132 | | emit_finallyblocks(p, enclosingtryfinally, NULL); |
|---|
| 133 | | |
|---|
| 134 | | if (gIR->func()->inVolatile) { |
|---|
| 135 | | // store-load barrier |
|---|
| 136 | | DtoMemoryBarrier(false, false, true, false); |
|---|
| 137 | | } |
|---|
| 138 | | |
|---|
| 139 | | if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); |
|---|
| 140 | | llvm::ReturnInst::Create(p->scopebb()); |
|---|
| 141 | | } |
|---|
| 142 | | else { |
|---|
| 143 | | assert(0); // why should this ever happen? |
|---|
| 144 | | new llvm::UnreachableInst(p->scopebb()); |
|---|
| 145 | | } |
|---|
| | 131 | assert(p->topfunc()->getReturnType() == llvm::Type::VoidTy); |
|---|
| | 132 | emit_finallyblocks(p, enclosingtryfinally, NULL); |
|---|
| | 133 | |
|---|
| | 134 | if (gIR->func()->inVolatile) { |
|---|
| | 135 | // store-load barrier |
|---|
| | 136 | DtoMemoryBarrier(false, false, true, false); |
|---|
| | 137 | } |
|---|
| | 138 | |
|---|
| | 139 | if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); |
|---|
| | 140 | llvm::ReturnInst::Create(p->scopebb()); |
|---|
| 146 | 141 | } |
|---|
| 147 | 142 | } |
|---|
| … | … | |
| 617 | 612 | |
|---|
| 618 | 613 | llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); |
|---|
| 619 | | std::vector<LLValue*> args; |
|---|
| | 614 | |
|---|
| 620 | 615 | Logger::cout() << *table->getType() << '\n'; |
|---|
| 621 | 616 | Logger::cout() << *fn->getFunctionType()->getParamType(0) << '\n'; |
|---|
| 622 | 617 | assert(table->getType() == fn->getFunctionType()->getParamType(0)); |
|---|
| 623 | | args.push_back(table); |
|---|
| 624 | 618 | |
|---|
| 625 | 619 | DValue* val = e->toElem(gIR); |
|---|
| … | … | |
| 637 | 631 | } |
|---|
| 638 | 632 | assert(llval->getType() == fn->getFunctionType()->getParamType(1)); |
|---|
| 639 | | args.push_back(llval); |
|---|
| 640 | | |
|---|
| 641 | | return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp"); |
|---|
| | 633 | |
|---|
| | 634 | return gIR->ir->CreateCall2(fn, table, llval, "tmp"); |
|---|
| 642 | 635 | } |
|---|
| 643 | 636 | |
|---|
| r213 |
r217 |
|
| 106 | 106 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 107 | 107 | |
|---|
| 108 | | LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs) |
|---|
| | 108 | LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, DStructIndexVector& idxs) |
|---|
| 109 | 109 | { |
|---|
| 110 | 110 | Logger::println("checking for offset %u type %s:", os, t->toChars()); |
|---|
| … | … | |
| 128 | 128 | if (os == vd->offset && vdtype == t) { |
|---|
| 129 | 129 | idxs.push_back(vd->ir.irField->index); |
|---|
| 130 | | ptr = DtoGEP(ptr, idxs, "tmp"); |
|---|
| | 130 | ptr = DtoGEPi(ptr, idxs, "tmp"); |
|---|
| 131 | 131 | if (ptr->getType() != llt) |
|---|
| 132 | 132 | ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
|---|
| … | … | |
| 141 | 141 | if (vd->ir.irField->indexOffset) { |
|---|
| 142 | 142 | Logger::println("has union field offset"); |
|---|
| 143 | | ptr = DtoGEP(ptr, idxs, "tmp"); |
|---|
| | 143 | ptr = DtoGEPi(ptr, idxs, "tmp"); |
|---|
| 144 | 144 | if (ptr->getType() != llt) |
|---|
| 145 | 145 | ptr = DtoBitCast(ptr, llt); |
|---|
| 146 | 146 | ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); |
|---|
| 147 | | std::vector<unsigned> tmp; |
|---|
| | 147 | DStructIndexVector tmp; |
|---|
| 148 | 148 | return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
|---|
| 149 | 149 | } |
|---|
| … | … | |
| 152 | 152 | if (ptr->getType() != sty) { |
|---|
| 153 | 153 | ptr = DtoBitCast(ptr, sty); |
|---|
| 154 | | std::vector<unsigned> tmp; |
|---|
| | 154 | DStructIndexVector tmp; |
|---|
| 155 | 155 | return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
|---|
| 156 | 156 | } |
|---|
| r213 |
r217 |
|
| 31 | 31 | void DtoDefineStruct(StructDeclaration* sd); |
|---|
| 32 | 32 | |
|---|
| 33 | | LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs); |
|---|
| | 33 | typedef LLSmallVector<unsigned, 3> DStructIndexVector; |
|---|
| | 34 | LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, DStructIndexVector& idxs); |
|---|
| 34 | 35 | |
|---|
| 35 | 36 | struct DUnionField |
|---|
| r213 |
r217 |
|
| 197 | 197 | void DtoDwarfStopPoint(unsigned ln) |
|---|
| 198 | 198 | { |
|---|
| 199 | | std::vector<LLValue*> args; |
|---|
| | 199 | LLSmallVector<LLValue*,3> args; |
|---|
| 200 | 200 | args.push_back(DtoConstUint(ln)); |
|---|
| 201 | 201 | args.push_back(DtoConstUint(0)); |
|---|
| r215 |
r217 |
|
| 619 | 619 | |
|---|
| 620 | 620 | TypeStruct* ts = (TypeStruct*)e1next; |
|---|
| 621 | | std::vector<unsigned> offsets; |
|---|
| | 621 | DStructIndexVector offsets; |
|---|
| 622 | 622 | LLValue* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets); |
|---|
| 623 | 623 | return new DFieldValue(type, v, true); |
|---|
| … | … | |
| 1019 | 1019 | bool isInPlace = false; |
|---|
| 1020 | 1020 | |
|---|
| | 1021 | // attrs |
|---|
| | 1022 | llvm::PAListPtr palist; |
|---|
| | 1023 | |
|---|
| 1021 | 1024 | // hidden struct return arguments |
|---|
| | 1025 | // TODO: use sret param attr |
|---|
| 1022 | 1026 | if (retinptr) { |
|---|
| 1023 | 1027 | if (topexp && topexp->e2 == this) { |
|---|
| … | … | |
| 1168 | 1172 | DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); |
|---|
| 1169 | 1173 | llargs[j] = argval->getRVal(); |
|---|
| | 1174 | #if USE_BYVAL |
|---|
| | 1175 | if (fnarg->llvmByVal) |
|---|
| | 1176 | palist = palist.addAttr(j, llvm::ParamAttr::ByVal); |
|---|
| | 1177 | #endif |
|---|
| 1170 | 1178 | j++; |
|---|
| 1171 | 1179 | } |
|---|
| … | … | |
| 1188 | 1196 | } |
|---|
| 1189 | 1197 | |
|---|
| | 1198 | #if USE_BYVAL |
|---|
| | 1199 | if (fnarg && fnarg->llvmByVal) |
|---|
| | 1200 | palist = palist.addAttr(j+1, llvm::ParamAttr::ByVal); |
|---|
| | 1201 | #endif |
|---|
| | 1202 | |
|---|
| 1190 | 1203 | // this hack is necessary :/ |
|---|
| 1191 | 1204 | if (dfn && dfn->func && dfn->func->runTimeHack) { |
|---|
| … | … | |
| 1246 | 1259 | } |
|---|
| 1247 | 1260 | |
|---|
| | 1261 | // param attrs |
|---|
| | 1262 | call->setParamAttrs(palist); |
|---|
| | 1263 | |
|---|
| 1248 | 1264 | return new DImValue(type, retllval, isInPlace); |
|---|
| 1249 | 1265 | } |
|---|
| … | … | |
| 1312 | 1328 | } |
|---|
| 1313 | 1329 | else { |
|---|
| 1314 | | std::vector<unsigned> dst; |
|---|
| | 1330 | DStructIndexVector dst; |
|---|
| 1315 | 1331 | varmem = DtoIndexStruct(llvalue,vdt->sym, tnext, offset, dst); |
|---|
| 1316 | 1332 | } |
|---|
| … | … | |
| 1430 | 1446 | LLValue* src = l->getRVal(); |
|---|
| 1431 | 1447 | |
|---|
| 1432 | | std::vector<unsigned> vdoffsets; |
|---|
| | 1448 | DStructIndexVector vdoffsets; |
|---|
| 1433 | 1449 | arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); |
|---|
| 1434 | 1450 | } |
|---|
| … | … | |
| 1439 | 1455 | LLValue* src = l->getRVal(); |
|---|
| 1440 | 1456 | |
|---|
| 1441 | | std::vector<unsigned> vdoffsets; |
|---|
| | 1457 | DStructIndexVector vdoffsets; |
|---|
| 1442 | 1458 | arrptr = DtoIndexClass(src, tc->sym, vd->type, vd->offset, vdoffsets); |
|---|
| 1443 | 1459 | |
|---|
| … | … | |
| 2256 | 2272 | LOG_SCOPE; |
|---|
| 2257 | 2273 | |
|---|
| 2258 | | DtoAssert(&loc, NULL); |
|---|
| | 2274 | // call the new (?) trap intrinsic |
|---|
| | 2275 | p->ir->CreateCall(GET_INTRINSIC_DECL(trap),""); |
|---|
| 2259 | 2276 | |
|---|
| 2260 | 2277 | new llvm::UnreachableInst(p->scopebb()); |
|---|
| r213 |
r217 |
|
| 21 | 21 | |
|---|
| 22 | 22 | bool DtoIsPassedByRef(Type* type) |
|---|
| | 23 | { |
|---|
| | 24 | Type* typ = DtoDType(type); |
|---|
| | 25 | TY t = typ->ty; |
|---|
| | 26 | return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); |
|---|
| | 27 | } |
|---|
| | 28 | |
|---|
| | 29 | bool DtoIsReturnedInArg(Type* type) |
|---|
| 23 | 30 | { |
|---|
| 24 | 31 | Type* typ = DtoDType(type); |
|---|
| … | … | |
| 68 | 75 | case Tfloat64: |
|---|
| 69 | 76 | case Timaginary64: |
|---|
| | 77 | return llvm::Type::DoubleTy; |
|---|
| 70 | 78 | case Tfloat80: |
|---|
| 71 | 79 | case Timaginary80: |
|---|
| 72 | | return llvm::Type::DoubleTy; |
|---|
| | 80 | return (global.params.useFP80) ? llvm::Type::X86_FP80Ty : llvm::Type::DoubleTy; |
|---|
| 73 | 81 | |
|---|
| 74 | 82 | // complex |
|---|
| … | … | |
| 591 | 599 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 592 | 600 | |
|---|
| 593 | | LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const std::string& var, llvm::BasicBlock* bb) |
|---|
| 594 | | { |
|---|
| 595 | | std::vector<LLValue*> v(2); |
|---|
| | 601 | LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var, llvm::BasicBlock* bb) |
|---|
| | 602 | { |
|---|
| | 603 | LLSmallVector<LLValue*,2> v(2); |
|---|
| 596 | 604 | v[0] = i0; |
|---|
| 597 | 605 | v[1] = i1; |
|---|
| 598 | | Logger::cout() << "DtoGEP: " << *ptr << ", " << *i0 << ", " << *i1 << '\n'; |
|---|
| 599 | 606 | return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
|---|
| 600 | 607 | } |
|---|
| … | … | |
| 602 | 609 | ////////////////////////////////////////////////////////////////////////////////////////// |
|---|
| 603 | 610 | |
|---|
| 604 | | LLValue* DtoGEP(LLValue* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) |
|---|
| | 611 | LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var, llvm::BasicBlock* bb) |
|---|
| 605 | 612 | { |
|---|
| 606 | 613 | size_t n = src.size(); |
|---|
| 607 | | std::vector<LLValue*> dst(n, NULL); |
|---|
| 608 | | //std::ostream& ostr = Logger::cout(); |
|---|
| 609 | | //ostr << "indices for '" << *ptr << "':"; |
|---|
| 610 | | for (size_t i=0; i<n; ++i) |
|---|
| 611 | | { |
|---|
| 612 | | //ostr << ' ' << i; |
|---|
| 613 | | dst[i] = llvm::ConstantInt::get(llvm::Type::Int32Ty, src[i], false); |
|---|
| 614 | | } |
|---|
| 615 | | //ostr << '\n';*/ |
|---|
| | 614 | LLSmallVector<LLValue*, 3> dst(n); |
|---|
| | 615 | |
|---|
| | 616 | |
|---|