Mercurial > projects > ldc
comparison gen/toobj.cpp @ 1147:dbe4af57b240
Changed use of toObjFile to a new codegen method.
More versioning of DMD specific codegen code.
author | Tomas Lindquist Olsen <tomas.l.olsen gmail.com> |
---|---|
date | Fri, 27 Mar 2009 17:54:27 +0100 |
parents | 1860414bf3b7 |
children | 3d1b16dabd25 |
comparison
equal
deleted
inserted
replaced
1146:1860414bf3b7 | 1147:dbe4af57b240 |
---|---|
68 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out); | 68 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out); |
69 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath); | 69 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath); |
70 | 70 |
71 ////////////////////////////////////////////////////////////////////////////////////////// | 71 ////////////////////////////////////////////////////////////////////////////////////////// |
72 | 72 |
73 llvm::Module* Module::genLLVMModule(int multiobj) | 73 llvm::Module* Module::genLLVMModule(Ir* sir) |
74 { | 74 { |
75 bool logenabled = Logger::enabled(); | 75 bool logenabled = Logger::enabled(); |
76 if (llvmForceLogging && !logenabled) | 76 if (llvmForceLogging && !logenabled) |
77 { | 77 { |
78 Logger::enable(); | 78 Logger::enable(); |
98 | 98 |
99 // reset all IR data stored in Dsymbols and Types | 99 // reset all IR data stored in Dsymbols and Types |
100 IrDsymbol::resetAll(); | 100 IrDsymbol::resetAll(); |
101 IrType::resetAll(); | 101 IrType::resetAll(); |
102 | 102 |
103 sir->setState(&ir); | |
104 | |
103 // module ir state | 105 // module ir state |
104 // might already exist via import, just overwrite since | 106 // might already exist via import, just overwrite since |
105 // the global created for the filename must belong to the right llvm module | 107 // the global created for the filename must belong to the right llvm module |
106 // FIXME: but shouldn't this always get reset between modules? like other IrSymbols | 108 // FIXME: but shouldn't this always get reset between modules? like other IrSymbols |
107 this->ir.irModule = new IrModule(this, srcfile->toChars()); | 109 this->ir.irModule = new IrModule(this, srcfile->toChars()); |
135 | 137 |
136 // process module members | 138 // process module members |
137 for (int k=0; k < members->dim; k++) { | 139 for (int k=0; k < members->dim; k++) { |
138 Dsymbol* dsym = (Dsymbol*)(members->data[k]); | 140 Dsymbol* dsym = (Dsymbol*)(members->data[k]); |
139 assert(dsym); | 141 assert(dsym); |
140 dsym->toObjFile(multiobj); | 142 dsym->codegen(sir); |
141 } | 143 } |
142 | 144 |
143 // main driver loop | |
144 DtoEmptyAllLists(); | |
145 // generate ModuleInfo | 145 // generate ModuleInfo |
146 genmoduleinfo(); | 146 genmoduleinfo(); |
147 // do this again as moduleinfo might have pulled something in! | |
148 DtoEmptyAllLists(); | |
149 | 147 |
150 // emit usedArray | 148 // emit usedArray |
151 if (!ir.usedArray.empty()) | 149 if (!ir.usedArray.empty()) |
152 { | 150 { |
153 const LLArrayType* usedTy = LLArrayType::get(getVoidPtrType(), ir.usedArray.size()); | 151 const LLArrayType* usedTy = LLArrayType::get(getVoidPtrType(), ir.usedArray.size()); |
170 Logger::println("Verification passed!"); | 168 Logger::println("Verification passed!"); |
171 } | 169 } |
172 } | 170 } |
173 | 171 |
174 gIR = NULL; | 172 gIR = NULL; |
175 | 173 |
176 if (llvmForceLogging && !logenabled) | 174 if (llvmForceLogging && !logenabled) |
177 { | 175 { |
178 Logger::disable(); | 176 Logger::disable(); |
179 } | 177 } |
180 | 178 |
179 sir->setState(NULL); | |
180 | |
181 return ir.module; | 181 return ir.module; |
182 } | 182 } |
183 | 183 |
184 void writeModule(llvm::Module* m, std::string filename) | 184 void writeModule(llvm::Module* m, std::string filename) |
185 { | 185 { |
678 // fill inits | 678 // fill inits |
679 std::vector<LLConstant*> classInits; | 679 std::vector<LLConstant*> classInits; |
680 for (size_t i = 0; i < aclasses.dim; i++) | 680 for (size_t i = 0; i < aclasses.dim; i++) |
681 { | 681 { |
682 ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i]; | 682 ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i]; |
683 cd->codegen(Type::sir); | |
684 | |
683 if (cd->isInterfaceDeclaration()) | 685 if (cd->isInterfaceDeclaration()) |
684 { | 686 { |
685 Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars()); | 687 Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars()); |
686 continue; | 688 continue; |
687 } | 689 } |
788 std::vector<LLConstant*> appendInits(1, magicinit); | 790 std::vector<LLConstant*> appendInits(1, magicinit); |
789 LLConstant* appendInit = llvm::ConstantArray::get(appendArrTy, appendInits); | 791 LLConstant* appendInit = llvm::ConstantArray::get(appendArrTy, appendInits); |
790 std::string appendName("llvm.global_ctors"); | 792 std::string appendName("llvm.global_ctors"); |
791 llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module); | 793 llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module); |
792 } | 794 } |
793 | |
794 /* ================================================================== */ | |
795 | |
796 void Dsymbol::toObjFile(int multiobj) | |
797 { | |
798 Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars()); | |
799 } | |
800 | |
801 /* ================================================================== */ | |
802 | |
803 void Declaration::toObjFile(int unused) | |
804 { | |
805 Logger::println("Ignoring Declaration::toObjFile for %s", toChars()); | |
806 } | |
807 | |
808 /* ================================================================== */ | |
809 | |
810 void InterfaceDeclaration::toObjFile(int multiobj) | |
811 { | |
812 //Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars()); | |
813 gIR->resolveList.push_back(this); | |
814 } | |
815 | |
816 /* ================================================================== */ | |
817 | |
818 void StructDeclaration::toObjFile(int multiobj) | |
819 { | |
820 gIR->resolveList.push_back(this); | |
821 } | |
822 | |
823 /* ================================================================== */ | |
824 | |
825 void ClassDeclaration::toObjFile(int multiobj) | |
826 { | |
827 gIR->resolveList.push_back(this); | |
828 } | |
829 | |
830 /* ================================================================== */ | |
831 | |
832 void TupleDeclaration::toObjFile(int multiobj) | |
833 { | |
834 Logger::println("TupleDeclaration::toObjFile(): %s", toChars()); | |
835 | |
836 assert(isexp); | |
837 assert(objects); | |
838 | |
839 int n = objects->dim; | |
840 | |
841 for (int i=0; i < n; ++i) | |
842 { | |
843 DsymbolExp* exp = (DsymbolExp*)objects->data[i]; | |
844 assert(exp->op == TOKdsymbol); | |
845 exp->s->toObjFile(multiobj); | |
846 } | |
847 } | |
848 | |
849 /* ================================================================== */ | |
850 | |
851 void VarDeclaration::toObjFile(int multiobj) | |
852 { | |
853 Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars()); | |
854 LOG_SCOPE; | |
855 | |
856 if (aliassym) | |
857 { | |
858 Logger::println("alias sym"); | |
859 toAlias()->toObjFile(multiobj); | |
860 return; | |
861 } | |
862 | |
863 // global variable or magic | |
864 #if DMDV2 | |
865 // taken from dmd2/structs | |
866 if (isDataseg() || (storage_class & (STCconst | STCinvariant) && init)) | |
867 #else | |
868 if (isDataseg()) | |
869 #endif | |
870 { | |
871 Logger::println("data segment"); | |
872 | |
873 #if DMDV2 | |
874 if (storage_class & STCmanifest) | |
875 { | |
876 assert(0 && "manifest constant being codegened!!!"); | |
877 } | |
878 #endif | |
879 | |
880 // don't duplicate work | |
881 if (this->ir.resolved) return; | |
882 this->ir.resolved = true; | |
883 this->ir.declared = true; | |
884 | |
885 this->ir.irGlobal = new IrGlobal(this); | |
886 | |
887 Logger::println("parent: %s (%s)", parent->toChars(), parent->kind()); | |
888 | |
889 #if DMDV2 | |
890 // not sure why this is only needed for d2 | |
891 bool _isconst = isConst() && init; | |
892 #else | |
893 bool _isconst = isConst(); | |
894 #endif | |
895 | |
896 | |
897 Logger::println("Creating global variable"); | |
898 | |
899 const LLType* _type = this->ir.irGlobal->type.get(); | |
900 llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this); | |
901 std::string _name(mangle()); | |
902 | |
903 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module); | |
904 this->ir.irGlobal->value = gvar; | |
905 | |
906 if (Logger::enabled()) | |
907 Logger::cout() << *gvar << '\n'; | |
908 | |
909 // if this global is used from a nested function, this is necessary or | |
910 // optimization could potentially remove the global (if it's the only use) | |
911 if (nakedUse) | |
912 gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType())); | |
913 | |
914 gIR->constInitList.push_back(this); | |
915 } | |
916 else | |
917 { | |
918 // might already have its irField, as classes derive each other without getting copies of the VarDeclaration | |
919 if (!ir.irField) | |
920 { | |
921 assert(!ir.isSet()); | |
922 ir.irField = new IrField(this); | |
923 } | |
924 IrStruct* irstruct = gIR->topstruct(); | |
925 irstruct->addVar(this); | |
926 | |
927 Logger::println("added offset %u", offset); | |
928 } | |
929 } | |
930 | |
931 /* ================================================================== */ | |
932 | |
933 void TypedefDeclaration::toObjFile(int multiobj) | |
934 { | |
935 static int tdi = 0; | |
936 Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars()); | |
937 LOG_SCOPE; | |
938 | |
939 // generate typeinfo | |
940 DtoTypeInfoOf(type, false); | |
941 } | |
942 | |
943 /* ================================================================== */ | |
944 | |
945 void EnumDeclaration::toObjFile(int multiobj) | |
946 { | |
947 Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars()); | |
948 } | |
949 | |
950 /* ================================================================== */ | |
951 | |
952 void FuncDeclaration::toObjFile(int multiobj) | |
953 { | |
954 gIR->resolveList.push_back(this); | |
955 } | |
956 | |
957 /* ================================================================== */ | |
958 | |
959 void AnonDeclaration::toObjFile(int multiobj) | |
960 { | |
961 Array *d = include(NULL, NULL); | |
962 | |
963 if (d) | |
964 { | |
965 // get real aggregate parent | |
966 IrStruct* irstruct = gIR->topstruct(); | |
967 | |
968 // push a block on the stack | |
969 irstruct->pushAnon(isunion); | |
970 | |
971 // go over children | |
972 for (unsigned i = 0; i < d->dim; i++) | |
973 { Dsymbol *s = (Dsymbol *)d->data[i]; | |
974 s->toObjFile(multiobj); | |
975 } | |
976 | |
977 // finish | |
978 irstruct->popAnon(); | |
979 } | |
980 } |