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 }