Mercurial > projects > ldc
comparison gen/tollvm.cpp @ 129:8096ba7082db trunk
[svn r133] Fixed some problems with inlining not happening :P
Fixed problems with certain cases of deeply nested classes/functions.
author | lindquist |
---|---|
date | Fri, 28 Dec 2007 22:55:24 +0100 |
parents | 9c79b61fb638 |
children | 5825d48b27d1 |
comparison
equal
deleted
inserted
replaced
128:e5fe8521bbfa | 129:8096ba7082db |
---|---|
794 return retval; | 794 return retval; |
795 } | 795 } |
796 | 796 |
797 ////////////////////////////////////////////////////////////////////////////////////////// | 797 ////////////////////////////////////////////////////////////////////////////////////////// |
798 | 798 |
799 static void print_frame_worker(VarDeclaration* var, Dsymbol* par) | |
800 { | |
801 if (var->toParent2() == par) | |
802 { | |
803 Logger::println("parent found: '%s' kind: '%s'", par->toChars(), par->kind()); | |
804 return; | |
805 } | |
806 | |
807 Logger::println("diving into parent: '%s' kind: '%s'", par->toChars(), par->kind()); | |
808 LOG_SCOPE; | |
809 print_frame_worker(var, par->toParent2()); | |
810 } | |
811 | |
812 static void print_nested_frame_list(VarDeclaration* var, Dsymbol* par) | |
813 { | |
814 Logger::println("PRINTING FRAME LIST FOR NESTED VAR: '%s'", var->toChars()); | |
815 { | |
816 LOG_SCOPE; | |
817 print_frame_worker(var, par); | |
818 } | |
819 Logger::println("DONE"); | |
820 } | |
821 | |
822 static const llvm::Type* get_next_frame_ptr_type(Dsymbol* sc) | |
823 { | |
824 assert(sc->isFuncDeclaration() || sc->isClassDeclaration()); | |
825 Dsymbol* p = sc->toParent2(); | |
826 assert(p->isFuncDeclaration() || p->isClassDeclaration()); | |
827 if (FuncDeclaration* fd = p->isFuncDeclaration()) | |
828 { | |
829 llvm::Value* v = fd->llvmNested; | |
830 assert(v); | |
831 return v->getType(); | |
832 } | |
833 else if (ClassDeclaration* cd = p->isClassDeclaration()) | |
834 { | |
835 return DtoType(cd->type); | |
836 } | |
837 else | |
838 { | |
839 Logger::println("symbol: '%s' kind: '%s'", sc->toChars(), sc->kind()); | |
840 assert(0); | |
841 } | |
842 } | |
843 | |
844 static llvm::Value* get_frame_ptr_impl(VarDeclaration* vd, Dsymbol* sc, llvm::Value* v) | |
845 { | |
846 if (vd->toParent2() == sc) | |
847 { | |
848 return v; | |
849 } | |
850 else if (FuncDeclaration* fd = sc->isFuncDeclaration()) | |
851 { | |
852 Logger::println("scope is function"); | |
853 v = DtoBitCast(v, get_next_frame_ptr_type(fd)); | |
854 Logger::cout() << "v = " << *v << '\n'; | |
855 | |
856 if (fd->toParent2() == vd->toParent2()) | |
857 return v; | |
858 | |
859 if (fd->toParent2()->isFuncDeclaration()) | |
860 { | |
861 v = DtoGEPi(v, 0,0, "tmp"); | |
862 v = DtoLoad(v); | |
863 } | |
864 else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration()) | |
865 { | |
866 size_t idx = 2; | |
867 idx += cd->llvmIRStruct->interfaces.size(); | |
868 v = DtoGEPi(v,0,idx,"tmp"); | |
869 v = DtoLoad(v); | |
870 } | |
871 else | |
872 { | |
873 assert(0); | |
874 } | |
875 return get_frame_ptr_impl(vd, fd->toParent2(), v); | |
876 } | |
877 else if (ClassDeclaration* cd = sc->isClassDeclaration()) | |
878 { | |
879 Logger::println("scope is class"); | |
880 /*size_t idx = 2; | |
881 idx += cd->llvmIRStruct->interfaces.size(); | |
882 v = DtoGEPi(v,0,idx,"tmp"); | |
883 Logger::cout() << "gep = " << *v << '\n'; | |
884 v = DtoLoad(v);*/ | |
885 return get_frame_ptr_impl(vd, cd->toParent2(), v); | |
886 } | |
887 else | |
888 { | |
889 Logger::println("symbol: '%s'", sc->toChars()); | |
890 assert(0); | |
891 } | |
892 } | |
893 | |
894 static llvm::Value* get_frame_ptr(VarDeclaration* vd) | |
895 { | |
896 Logger::println("RESOLVING FRAME PTR FOR NESTED VAR: '%s'", vd->toChars()); | |
897 LOG_SCOPE; | |
898 IRFunction* irfunc = gIR->func(); | |
899 | |
900 // in the parent scope already | |
901 if (vd->toParent2() == irfunc->decl) | |
902 return irfunc->decl->llvmNested; | |
903 | |
904 // use the 'this' pointer | |
905 llvm::Value* ptr = irfunc->decl->llvmThisVar; | |
906 assert(ptr); | |
907 | |
908 // return the fully resolved frame pointer | |
909 ptr = get_frame_ptr_impl(vd, irfunc->decl, ptr); | |
910 Logger::cout() << "FOUND: '" << *ptr << "'\n"; | |
911 | |
912 return ptr; | |
913 } | |
914 | |
799 llvm::Value* DtoNestedVariable(VarDeclaration* vd) | 915 llvm::Value* DtoNestedVariable(VarDeclaration* vd) |
800 { | 916 { |
801 FuncDeclaration* fd = vd->toParent()->isFuncDeclaration(); | 917 // log the frame list |
802 assert(fd != NULL); | 918 IRFunction* irfunc = gIR->func(); |
803 | 919 print_nested_frame_list(vd, irfunc->decl); |
804 IRFunction* fcur = gIR->func(); | 920 |
805 FuncDeclaration* f = fcur->decl; | 921 // resolve frame ptr |
806 | 922 llvm::Value* ptr = get_frame_ptr(vd); |
807 // on this stack | 923 Logger::cout() << "nested ptr = " << *ptr << '\n'; |
808 if (fd == f) { | 924 |
809 llvm::Value* vdv = vd->llvmValue; | 925 // we must cast here to be sure. nested classes just have a void* |
810 if (!vdv) | 926 ptr = DtoBitCast(ptr, vd->toParent2()->isFuncDeclaration()->llvmNested->getType()); |
811 { | 927 |
812 Logger::println(":o null vd->llvmValue for: %s", vd->toChars()); | 928 // index nested var and load (if necessary) |
813 vdv = fd->llvmNested; | 929 llvm::Value* v = DtoGEPi(ptr, 0, vd->llvmNestedIndex, "tmp"); |
814 assert(vdv); | 930 // references must be loaded, for normal variables this IS already the variable storage!!! |
815 } | 931 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) |
816 assert(vd->llvmNestedIndex != ~0); | 932 v = DtoLoad(v); |
817 llvm::Value* v = DtoGEPi(vdv,0,unsigned(vd->llvmNestedIndex),"tmp"); | 933 |
818 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) { | 934 Logger::cout() << "FINAL RESULT: " << *v << '\n'; |
819 Logger::cout() << "1267 loading: " << *v << '\n'; | 935 return v; |
820 v = gIR->ir->CreateLoad(v,"tmp"); | |
821 } | |
822 return v; | |
823 } | |
824 | |
825 // on a caller stack | |
826 llvm::Value* ptr = f->llvmThisVar; | |
827 assert(ptr); | |
828 | |
829 f = f->toParent()->isFuncDeclaration(); | |
830 assert(f); | |
831 assert(f->llvmNested); | |
832 const llvm::Type* nesttype = f->llvmNested->getType(); | |
833 assert(nesttype); | |
834 | |
835 ptr = gIR->ir->CreateBitCast(ptr, nesttype, "tmp"); | |
836 | |
837 Logger::cout() << "nested var reference:" << '\n' << *ptr << *nesttype << '\n'; | |
838 | |
839 while (f) { | |
840 if (fd == f) { | |
841 llvm::Value* v = DtoGEPi(ptr,0,vd->llvmNestedIndex,"tmp"); | |
842 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) { | |
843 Logger::cout() << "1291 loading: " << *v << '\n'; | |
844 v = gIR->ir->CreateLoad(v,"tmp"); | |
845 } | |
846 return v; | |
847 } | |
848 else { | |
849 ptr = DtoGEPi(ptr,0,0,"tmp"); | |
850 ptr = gIR->ir->CreateLoad(ptr,"tmp"); | |
851 } | |
852 f = f->toParent()->isFuncDeclaration(); | |
853 } | |
854 | |
855 assert(0 && "nested var not found"); | |
856 return NULL; | |
857 } | 936 } |
858 | 937 |
859 ////////////////////////////////////////////////////////////////////////////////////////// | 938 ////////////////////////////////////////////////////////////////////////////////////////// |
860 | 939 |
861 void DtoAssign(DValue* lhs, DValue* rhs) | 940 void DtoAssign(DValue* lhs, DValue* rhs) |