Mercurial > projects > ldc
comparison gen/tollvm.c @ 11:d3ee9efe20e2 trunk
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
* Now 50/51 tests compile.
* Added a simple runalltests.d scripts that should be run with 'gdmd -run runalltests.d' - LLVMDC will not compile it yet.
author | lindquist |
---|---|
date | Tue, 02 Oct 2007 05:10:18 +0200 |
parents | dafae18f9c08 |
children | c05ef76f1c20 |
comparison
equal
deleted
inserted
replaced
10:c0f2c47e5034 | 11:d3ee9efe20e2 |
---|---|
157 return 0; | 157 return 0; |
158 } | 158 } |
159 | 159 |
160 ////////////////////////////////////////////////////////////////////////////////////////// | 160 ////////////////////////////////////////////////////////////////////////////////////////// |
161 | 161 |
162 llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam) | 162 const llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam) |
163 { | 163 { |
164 TypeFunction* f = (TypeFunction*)t; | 164 TypeFunction* f = (TypeFunction*)t; |
165 | 165 |
166 // parameter types | 166 // parameter types |
167 const llvm::Type* rettype; | 167 const llvm::Type* rettype; |
201 return functype; | 201 return functype; |
202 } | 202 } |
203 | 203 |
204 ////////////////////////////////////////////////////////////////////////////////////////// | 204 ////////////////////////////////////////////////////////////////////////////////////////// |
205 | 205 |
206 llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl) | 206 const llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl) |
207 { | 207 { |
208 TypeFunction* f = (TypeFunction*)fdecl->type; | 208 TypeFunction* f = (TypeFunction*)fdecl->type; |
209 assert(f != 0); | 209 assert(f != 0); |
210 | 210 |
211 // type has already been resolved | 211 // type has already been resolved |
307 return functype; | 307 return functype; |
308 } | 308 } |
309 | 309 |
310 ////////////////////////////////////////////////////////////////////////////////////////// | 310 ////////////////////////////////////////////////////////////////////////////////////////// |
311 | 311 |
312 llvm::StructType* LLVM_DtoDelegateType(Type* t) | 312 const llvm::StructType* LLVM_DtoDelegateType(Type* t) |
313 { | 313 { |
314 const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty); | 314 const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty); |
315 const llvm::Type* func = LLVM_DtoFunctionType(t->next, i8ptr); | 315 const llvm::Type* func = LLVM_DtoFunctionType(t->next, i8ptr); |
316 const llvm::Type* funcptr = llvm::PointerType::get(func); | 316 const llvm::Type* funcptr = llvm::PointerType::get(func); |
317 | 317 |
321 return llvm::StructType::get(types); | 321 return llvm::StructType::get(types); |
322 } | 322 } |
323 | 323 |
324 ////////////////////////////////////////////////////////////////////////////////////////// | 324 ////////////////////////////////////////////////////////////////////////////////////////// |
325 | 325 |
326 llvm::Type* LLVM_DtoStructType(Type* t) | 326 const llvm::Type* LLVM_DtoStructType(Type* t) |
327 { | 327 { |
328 assert(0); | 328 assert(0); |
329 std::vector<const llvm::Type*> types; | 329 std::vector<const llvm::Type*> types; |
330 return llvm::StructType::get(types); | 330 return llvm::StructType::get(types); |
331 } | 331 } |
761 | 761 |
762 ////////////////////////////////////////////////////////////////////////////////////////// | 762 ////////////////////////////////////////////////////////////////////////////////////////// |
763 | 763 |
764 void LLVM_DtoInitClass(TypeClass* tc, llvm::Value* dst) | 764 void LLVM_DtoInitClass(TypeClass* tc, llvm::Value* dst) |
765 { | 765 { |
766 assert(tc->llvmInit); | |
767 assert(dst->getType() == tc->llvmInit->getType()); | |
768 assert(gIR); | 766 assert(gIR); |
769 | 767 |
770 assert(tc->llvmType); | 768 assert(tc->llvmType); |
771 uint64_t n = gTargetData->getTypeSize(tc->llvmType); | 769 uint64_t size_t_size = gTargetData->getTypeSize(LLVM_DtoSize_t()); |
772 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); | 770 uint64_t n = gTargetData->getTypeSize(tc->llvmType) - size_t_size; |
773 | 771 |
774 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | 772 // set vtable field |
775 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb()); | 773 llvm::Value* vtblvar = LLVM_DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); |
776 | 774 assert(tc->sym->llvmVtbl); |
777 llvm::Function* fn = LLVM_DeclareMemCpy32(); | 775 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb()); |
778 std::vector<llvm::Value*> llargs; | 776 |
779 llargs.resize(4); | 777 // copy the static initializer |
780 llargs[0] = dstarr; | 778 if (n > 0) { |
781 llargs[1] = srcarr; | 779 assert(tc->llvmInit); |
782 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | 780 assert(dst->getType() == tc->llvmInit->getType()); |
783 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 781 |
784 | 782 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
785 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 783 |
784 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | |
785 dstarr = LLVM_DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb()); | |
786 | |
787 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb()); | |
788 srcarr = LLVM_DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb()); | |
789 | |
790 llvm::Function* fn = LLVM_DeclareMemCpy32(); | |
791 std::vector<llvm::Value*> llargs; | |
792 llargs.resize(4); | |
793 llargs[0] = dstarr; | |
794 llargs[1] = srcarr; | |
795 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
796 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
797 | |
798 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
799 } | |
786 } | 800 } |
787 | 801 |
788 ////////////////////////////////////////////////////////////////////////////////////////// | 802 ////////////////////////////////////////////////////////////////////////////////////////// |
789 | 803 |
790 llvm::Constant* LLVM_DtoInitializer(Type* type, Initializer* init) | 804 llvm::Constant* LLVM_DtoInitializer(Type* type, Initializer* init) |
823 Logger::println("unsupported initializer: %s", init->toChars()); | 837 Logger::println("unsupported initializer: %s", init->toChars()); |
824 } | 838 } |
825 return _init; | 839 return _init; |
826 } | 840 } |
827 | 841 |
842 ////////////////////////////////////////////////////////////////////////////////////////// | |
843 | |
828 llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb) | 844 llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb) |
829 { | 845 { |
830 std::vector<llvm::Value*> v(2); | 846 std::vector<llvm::Value*> v(2); |
831 v[0] = i0; | 847 v[0] = i0; |
832 v[1] = i1; | 848 v[1] = i1; |
849 Logger::cout() << "DtoGEP: " << *ptr << '\n'; | |
833 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb); | 850 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb); |
834 } | 851 } |
852 | |
853 ////////////////////////////////////////////////////////////////////////////////////////// | |
835 | 854 |
836 llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) | 855 llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) |
837 { | 856 { |
838 size_t n = src.size(); | 857 size_t n = src.size(); |
839 std::vector<llvm::Value*> dst(n); | 858 std::vector<llvm::Value*> dst(n); |
845 } | 864 } |
846 Logger::cout() << '\n'; | 865 Logger::cout() << '\n'; |
847 return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb); | 866 return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb); |
848 } | 867 } |
849 | 868 |
869 ////////////////////////////////////////////////////////////////////////////////////////// | |
870 | |
871 llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb) | |
872 { | |
873 return new llvm::GetElementPtrInst(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb); | |
874 } | |
875 | |
876 ////////////////////////////////////////////////////////////////////////////////////////// | |
877 | |
878 llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb) | |
879 { | |
880 std::vector<llvm::Value*> v(2); | |
881 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false); | |
882 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false); | |
883 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb); | |
884 } | |
885 | |
886 ////////////////////////////////////////////////////////////////////////////////////////// | |
887 | |
850 llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl) | 888 llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl) |
851 { | 889 { |
890 TypeFunction* f = (TypeFunction*)fdecl->type; | |
891 assert(f != 0); | |
892 | |
852 if (fdecl->llvmValue != 0) { | 893 if (fdecl->llvmValue != 0) { |
894 assert(llvm::isa<llvm::Function>(fdecl->llvmValue)); | |
853 return llvm::cast<llvm::Function>(fdecl->llvmValue); | 895 return llvm::cast<llvm::Function>(fdecl->llvmValue); |
854 } | 896 } |
855 | 897 |
856 static int fdi = 0; | 898 static int fdi = 0; |
857 Logger::print("FuncDeclaration::toObjFile(%d,%s): %s\n", fdi++, fdecl->needThis()?"this":"static",fdecl->toChars()); | 899 Logger::print("FuncDeclaration::toObjFile(%d,%s): %s\n", fdi++, fdecl->needThis()?"this":"static",fdecl->toChars()); |
861 error("intrinsics cannot have function bodies"); | 903 error("intrinsics cannot have function bodies"); |
862 fatal(); | 904 fatal(); |
863 } | 905 } |
864 | 906 |
865 // construct function | 907 // construct function |
866 TypeFunction* f = (TypeFunction*)fdecl->type; | 908 const llvm::FunctionType* functype = (f->llvmType == 0) ? LLVM_DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType); |
867 assert(f != 0); | |
868 llvm::FunctionType* functype = (f->llvmType == 0) ? LLVM_DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType); | |
869 | 909 |
870 // mangled name | 910 // mangled name |
871 char* mangled_name = (fdecl->llvmInternal == LLVMintrinsic) ? fdecl->llvmInternal1 : fdecl->mangle(); | 911 char* mangled_name = (fdecl->llvmInternal == LLVMintrinsic) ? fdecl->llvmInternal1 : fdecl->mangle(); |
872 | 912 |
873 // make the function | 913 // make the function |
879 if (fdecl->llvmInternal != LLVMintrinsic) | 919 if (fdecl->llvmInternal != LLVMintrinsic) |
880 func->setCallingConv(LLVM_DtoCallingConv(f->linkage)); | 920 func->setCallingConv(LLVM_DtoCallingConv(f->linkage)); |
881 | 921 |
882 fdecl->llvmValue = func; | 922 fdecl->llvmValue = func; |
883 f->llvmType = functype; | 923 f->llvmType = functype; |
924 assert(llvm::isa<llvm::FunctionType>(f->llvmType)); | |
884 | 925 |
885 if (fdecl->isMain()) { | 926 if (fdecl->isMain()) { |
886 gIR->mainFunc = func; | 927 gIR->mainFunc = func; |
887 } | 928 } |
888 | 929 |