Mercurial > projects > ldc
comparison gen/classes.cpp @ 217:0806379a5eca trunk
[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.
author | lindquist |
---|---|
date | Thu, 05 Jun 2008 06:38:36 +0200 |
parents | 7816aafeea3c |
children | a95056b3c996 |
comparison
equal
deleted
inserted
replaced
216:3d022aa016ae | 217:0806379a5eca |
---|---|
794 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint()); | 794 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint()); |
795 } | 795 } |
796 else | 796 else |
797 { | 797 { |
798 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); | 798 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); |
799 std::vector<LLValue*> args; | 799 mem = gIR->ir->CreateCall(fn, tc->sym->ir.irStruct->classInfo, "newclass_gc_alloc"); |
800 args.push_back(tc->sym->ir.irStruct->classInfo); | |
801 mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc"); | |
802 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); | 800 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); |
803 } | 801 } |
804 | 802 |
805 // init | 803 // init |
806 DtoInitClass(tc, mem); | 804 DtoInitClass(tc, mem); |
896 assert(ctor); | 894 assert(ctor); |
897 DtoForceDeclareDsymbol(ctor); | 895 DtoForceDeclareDsymbol(ctor); |
898 llvm::Function* fn = ctor->ir.irFunc->func; | 896 llvm::Function* fn = ctor->ir.irFunc->func; |
899 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); | 897 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); |
900 | 898 |
899 llvm::PAListPtr palist; | |
900 | |
901 std::vector<LLValue*> ctorargs; | 901 std::vector<LLValue*> ctorargs; |
902 ctorargs.push_back(mem); | 902 ctorargs.push_back(mem); |
903 for (size_t i=0; i<arguments->dim; ++i) | 903 for (size_t i=0; i<arguments->dim; ++i) |
904 { | 904 { |
905 Expression* ex = (Expression*)arguments->data[i]; | 905 Expression* ex = (Expression*)arguments->data[i]; |
908 LLValue* a = argval->getRVal(); | 908 LLValue* a = argval->getRVal(); |
909 const LLType* aty = fn->getFunctionType()->getParamType(i+1); | 909 const LLType* aty = fn->getFunctionType()->getParamType(i+1); |
910 if (a->getType() != aty) | 910 if (a->getType() != aty) |
911 a = DtoBitCast(a, aty); | 911 a = DtoBitCast(a, aty); |
912 ctorargs.push_back(a); | 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 llvm::CallInst* call = llvm::CallInst::Create(fn, ctorargs.begin(), ctorargs.end(), "tmp", gIR->scopebb()); | 916 llvm::CallInst* call = llvm::CallInst::Create(fn, ctorargs.begin(), ctorargs.end(), "tmp", gIR->scopebb()); |
915 call->setCallingConv(DtoCallingConv(LINKd)); | 917 call->setCallingConv(DtoCallingConv(LINKd)); |
918 call->setParamAttrs(palist); | |
916 | 919 |
917 return new DImValue(type, call, false); | 920 return new DImValue(type, call, false); |
918 } | 921 } |
919 | 922 |
920 ////////////////////////////////////////////////////////////////////////////////////////// | 923 ////////////////////////////////////////////////////////////////////////////////////////// |
995 const llvm::FunctionType* funcTy = func->getFunctionType(); | 998 const llvm::FunctionType* funcTy = func->getFunctionType(); |
996 | 999 |
997 std::vector<LLValue*> args; | 1000 std::vector<LLValue*> args; |
998 | 1001 |
999 // Object o | 1002 // Object o |
1000 LLValue* tmp = val->getRVal(); | 1003 LLValue* obj = val->getRVal(); |
1001 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); | 1004 obj = DtoBitCast(obj, funcTy->getParamType(0)); |
1002 args.push_back(tmp); | 1005 assert(funcTy->getParamType(0) == obj->getType()); |
1003 assert(funcTy->getParamType(0) == tmp->getType()); | |
1004 | 1006 |
1005 // ClassInfo c | 1007 // ClassInfo c |
1006 TypeClass* to = (TypeClass*)DtoDType(_to); | 1008 TypeClass* to = (TypeClass*)DtoDType(_to); |
1007 DtoForceDeclareDsymbol(to->sym); | 1009 DtoForceDeclareDsymbol(to->sym); |
1008 assert(to->sym->ir.irStruct->classInfo); | 1010 assert(to->sym->ir.irStruct->classInfo); |
1009 tmp = to->sym->ir.irStruct->classInfo; | 1011 LLValue* cinfo = to->sym->ir.irStruct->classInfo; |
1010 // unfortunately this is needed as the implementation of object differs somehow from the declaration | 1012 // unfortunately this is needed as the implementation of object differs somehow from the declaration |
1011 // this could happen in user code as well :/ | 1013 // this could happen in user code as well :/ |
1012 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); | 1014 cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); |
1013 args.push_back(tmp); | 1015 assert(funcTy->getParamType(1) == cinfo->getType()); |
1014 assert(funcTy->getParamType(1) == tmp->getType()); | |
1015 | 1016 |
1016 // call it | 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 // cast return value | 1020 // cast return value |
1020 ret = DtoBitCast(ret, DtoType(_to)); | 1021 ret = DtoBitCast(ret, DtoType(_to)); |
1021 | 1022 |
1022 return new DImValue(_to, ret); | 1023 return new DImValue(_to, ret); |
1062 const llvm::FunctionType* funcTy = func->getFunctionType(); | 1063 const llvm::FunctionType* funcTy = func->getFunctionType(); |
1063 | 1064 |
1064 std::vector<LLValue*> args; | 1065 std::vector<LLValue*> args; |
1065 | 1066 |
1066 // void* p | 1067 // void* p |
1067 LLValue* tmp = val->getRVal(); | 1068 LLValue* ptr = val->getRVal(); |
1068 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); | 1069 ptr = DtoBitCast(ptr, funcTy->getParamType(0)); |
1069 args.push_back(tmp); | |
1070 | 1070 |
1071 // ClassInfo c | 1071 // ClassInfo c |
1072 TypeClass* to = (TypeClass*)DtoDType(_to); | 1072 TypeClass* to = (TypeClass*)DtoDType(_to); |
1073 DtoForceDeclareDsymbol(to->sym); | 1073 DtoForceDeclareDsymbol(to->sym); |
1074 assert(to->sym->ir.irStruct->classInfo); | 1074 assert(to->sym->ir.irStruct->classInfo); |
1075 tmp = to->sym->ir.irStruct->classInfo; | 1075 LLValue* cinfo = to->sym->ir.irStruct->classInfo; |
1076 // unfortunately this is needed as the implementation of object differs somehow from the declaration | 1076 // unfortunately this is needed as the implementation of object differs somehow from the declaration |
1077 // this could happen in user code as well :/ | 1077 // this could happen in user code as well :/ |
1078 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); | 1078 cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); |
1079 args.push_back(tmp); | |
1080 | 1079 |
1081 // call it | 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 // cast return value | 1083 // cast return value |
1085 ret = DtoBitCast(ret, DtoType(_to)); | 1084 ret = DtoBitCast(ret, DtoType(_to)); |
1086 | 1085 |
1087 return new DImValue(_to, ret); | 1086 return new DImValue(_to, ret); |
1125 result.push_back(r); | 1124 result.push_back(r); |
1126 } | 1125 } |
1127 | 1126 |
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 Logger::println("checking for offset %u type %s:", os, t->toChars()); | 1131 Logger::println("checking for offset %u type %s:", os, t->toChars()); |
1133 LOG_SCOPE; | 1132 LOG_SCOPE; |
1134 | 1133 |
1135 if (idxs.empty()) | 1134 if (idxs.empty()) |
1155 assert(vd->ir.irField->index >= 0); | 1154 assert(vd->ir.irField->index >= 0); |
1156 if (os == vd->offset && vdtype->toBasetype() == t->toBasetype()) { | 1155 if (os == vd->offset && vdtype->toBasetype() == t->toBasetype()) { |
1157 Logger::println("found %s %s", vdtype->toChars(), vd->toChars()); | 1156 Logger::println("found %s %s", vdtype->toChars(), vd->toChars()); |
1158 idxs.push_back(vd->ir.irField->index + dataoffset); | 1157 idxs.push_back(vd->ir.irField->index + dataoffset); |
1159 //Logger::cout() << "indexing: " << *ptr << '\n'; | 1158 //Logger::cout() << "indexing: " << *ptr << '\n'; |
1160 ptr = DtoGEP(ptr, idxs, "tmp"); | 1159 ptr = DtoGEPi(ptr, idxs, "tmp"); |
1161 if (ptr->getType() != llt) | 1160 if (ptr->getType() != llt) |
1162 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); | 1161 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
1163 //Logger::cout() << "indexing: " << *ptr << '\n'; | 1162 //Logger::cout() << "indexing: " << *ptr << '\n'; |
1164 if (vd->ir.irField->indexOffset) | 1163 if (vd->ir.irField->indexOffset) |
1165 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); | 1164 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); |
1170 TypeStruct* ts = (TypeStruct*)vdtype; | 1169 TypeStruct* ts = (TypeStruct*)vdtype; |
1171 StructDeclaration* ssd = ts->sym; | 1170 StructDeclaration* ssd = ts->sym; |
1172 idxs.push_back(vd->ir.irField->index + dataoffset); | 1171 idxs.push_back(vd->ir.irField->index + dataoffset); |
1173 if (vd->ir.irField->indexOffset) { | 1172 if (vd->ir.irField->indexOffset) { |
1174 Logger::println("has union field offset"); | 1173 Logger::println("has union field offset"); |
1175 ptr = DtoGEP(ptr, idxs, "tmp"); | 1174 ptr = DtoGEPi(ptr, idxs, "tmp"); |
1176 if (ptr->getType() != llt) | 1175 if (ptr->getType() != llt) |
1177 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); | 1176 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
1178 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); | 1177 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); |
1179 std::vector<unsigned> tmp; | 1178 DStructIndexVector tmp; |
1180 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | 1179 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
1181 } | 1180 } |
1182 else { | 1181 else { |
1183 const LLType* sty = getPtrToType(DtoType(vd->type)); | 1182 const LLType* sty = getPtrToType(DtoType(vd->type)); |
1184 if (ptr->getType() != sty) { | 1183 if (ptr->getType() != sty) { |
1185 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); | 1184 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); |
1186 std::vector<unsigned> tmp; | 1185 DStructIndexVector tmp; |
1187 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | 1186 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
1188 } | 1187 } |
1189 else { | 1188 else { |
1190 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs); | 1189 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs); |
1191 } | 1190 } |