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)