comparison gen/toobj.c @ 82:d8dd47ef3973 trunk

[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes. Initial support for debug information. Very limited, but MUCH better than nothing :)
author lindquist
date Fri, 02 Nov 2007 01:17:26 +0100
parents 3587401b6eeb
children 169711a7126e
comparison
equal deleted inserted replaced
81:3587401b6eeb 82:d8dd47ef3973
34 #include "gen/irstate.h" 34 #include "gen/irstate.h"
35 #include "gen/elem.h" 35 #include "gen/elem.h"
36 #include "gen/logger.h" 36 #include "gen/logger.h"
37 #include "gen/tollvm.h" 37 #include "gen/tollvm.h"
38 #include "gen/arrays.h" 38 #include "gen/arrays.h"
39 #include "gen/todebug.h"
39 40
40 ////////////////////////////////////////////////////////////////////////////////////////// 41 //////////////////////////////////////////////////////////////////////////////////////////
41 42
42 void 43 void
43 Module::genobjfile() 44 Module::genobjfile()
72 assert(targetEntry && "Failed to find a static target for module"); 73 assert(targetEntry && "Failed to find a static target for module");
73 std::auto_ptr<llvm::TargetMachine> targetPtr(targetEntry->CtorFn(*ir.module, "")); // TODO: replace "" with features 74 std::auto_ptr<llvm::TargetMachine> targetPtr(targetEntry->CtorFn(*ir.module, "")); // TODO: replace "" with features
74 assert(targetPtr.get() && "Could not allocate target machine!"); 75 assert(targetPtr.get() && "Could not allocate target machine!");
75 llvm::TargetMachine &targetMachine = *targetPtr.get(); 76 llvm::TargetMachine &targetMachine = *targetPtr.get();
76 gTargetData = targetMachine.getTargetData(); 77 gTargetData = targetMachine.getTargetData();
78
79 // debug info
80 if (global.params.symdebug) {
81 RegisterDwarfSymbols(ir.module);
82 ir.dwarfCompileUnit = DtoDwarfCompileUnit(this);
83 }
77 84
78 // process module members 85 // process module members
79 for (int k=0; k < members->dim; k++) { 86 for (int k=0; k < members->dim; k++) {
80 Dsymbol* dsym = (Dsymbol*)(members->data[k]); 87 Dsymbol* dsym = (Dsymbol*)(members->data[k]);
81 assert(dsym); 88 assert(dsym);
748 llvmQueued = true; 755 llvmQueued = true;
749 } 756 }
750 return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete 757 return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete
751 } 758 }
752 759
760 // debug info
761 if (global.params.symdebug) {
762 llvmDwarfSubProgram = DtoDwarfSubProgram(this);
763 }
764
753 assert(f->llvmType); 765 assert(f->llvmType);
754 const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0)); 766 const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0));
755 767
756 // only members of the current module maybe be defined 768 // only members of the current module maybe be defined
757 if (getModule() == gIR->dmodule || parent->isTemplateInstance()) 769 if (getModule() == gIR->dmodule || parent->isTemplateInstance())
806 gIR->scopes.push_back(IRScope(beginbb, endbb)); 818 gIR->scopes.push_back(IRScope(beginbb, endbb));
807 819
808 // create alloca point 820 // create alloca point
809 f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb()); 821 f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb());
810 gIR->func().allocapoint = f->llvmAllocaPoint; 822 gIR->func().allocapoint = f->llvmAllocaPoint;
823
824 // give arguments storage
825 size_t n = Argument::dim(f->parameters);
826 for (int i=0; i < n; ++i) {
827 Argument* arg = Argument::getNth(f->parameters, i);
828 if (arg && arg->vardecl) {
829 VarDeclaration* vd = arg->vardecl;
830 if (!vd->llvmNeedsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
831 continue;
832 llvm::Value* a = vd->llvmValue;
833 assert(a);
834 std::string s(a->getName());
835 Logger::println("giving argument '%s' storage", s.c_str());
836 s.append("_storage");
837 llvm::Value* v = new llvm::AllocaInst(a->getType(),s,f->llvmAllocaPoint);
838 gIR->ir->CreateStore(a,v);
839 vd->llvmValue = v;
840 }
841 else assert(0);
842 }
843
844 // debug info
845 if (global.params.symdebug) DtoDwarfFuncStart(this);
811 846
812 llvm::Value* parentNested = NULL; 847 llvm::Value* parentNested = NULL;
813 if (FuncDeclaration* fd = toParent()->isFuncDeclaration()) { 848 if (FuncDeclaration* fd = toParent()->isFuncDeclaration()) {
814 parentNested = fd->llvmNested; 849 parentNested = fd->llvmNested;
815 } 850 }
864 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement 899 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
865 // in automatically, so we do it here. 900 // in automatically, so we do it here.
866 if (!isMain()) { 901 if (!isMain()) {
867 if (!gIR->scopereturned()) { 902 if (!gIR->scopereturned()) {
868 // pass the previous block into this block 903 // pass the previous block into this block
869 //new llvm::BranchInst(irs.end, irs.begin); 904 if (global.params.symdebug) DtoDwarfFuncEnd(this);
870 if (func->getReturnType() == llvm::Type::VoidTy) { 905 if (func->getReturnType() == llvm::Type::VoidTy) {
871 new llvm::ReturnInst(gIR->scopebb()); 906 new llvm::ReturnInst(gIR->scopebb());
872 } 907 }
873 else { 908 else {
874 new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb()); 909 new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb());