Changeset 1650:40bd4a0d4870
- Timestamp:
- 05/19/10 06:42:32 (2 years ago)
- Files:
-
- dmd/expression.h (modified) (3 diffs)
- dmd/statement.h (modified) (2 diffs)
- gen/arrays.cpp (modified) (2 diffs)
- gen/asmstmt.cpp (modified) (3 diffs)
- gen/cl_helpers.cpp (modified) (2 diffs)
- gen/cl_helpers.h (modified) (1 diff)
- gen/configfile.cpp (modified) (1 diff)
- gen/functions.cpp (modified) (5 diffs)
- gen/linker.cpp (modified) (3 diffs)
- gen/llvmhelpers.cpp (modified) (7 diffs)
- gen/llvmhelpers.h (modified) (1 diff)
- gen/logger.cpp (modified) (2 diffs)
- gen/logger.h (modified) (1 diff)
- gen/main.cpp (modified) (1 diff)
- gen/optimizer.cpp (modified) (3 diffs)
- gen/passes/SimplifyDRuntimeCalls.cpp (modified) (1 diff)
- gen/statements.cpp (modified) (23 diffs)
- gen/tocall.cpp (modified) (3 diffs)
- gen/todebug.cpp (modified) (2 diffs)
- gen/todebug.h (modified) (2 diffs)
- gen/tollvm.cpp (modified) (1 diff)
- gen/toobj.cpp (modified) (13 diffs)
- ir/irclass.cpp (modified) (1 diff)
- ir/irlandingpad.cpp (modified) (3 diffs)
- ir/irtype.cpp (modified) (2 diffs)
- ir/irvar.cpp (modified) (2 diffs)
- tango-0.99.9.patch (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
dmd/expression.h
Revision 1630:44b145be2ef5 Revision 1650:40bd4a0d4870 39 struct TemplateInstance; 39 struct TemplateInstance; 40 struct TemplateDeclaration; 40 struct TemplateDeclaration; 41 struct ClassDeclaration; 41 struct ClassDeclaration; 42 struct HdrGenState; 42 struct HdrGenState; 43 struct BinExp; 43 struct BinExp; 44 struct AssignExp; 44 struct InterState; 45 struct InterState; 45 struct OverloadSet; 46 struct OverloadSet; 46 47 47 enum TOK; 48 enum TOK; 48 49 … … 175 virtual DValue* toElem(IRState* irs); 176 virtual DValue* toElem(IRState* irs); 176 virtual llvm::Constant *toConstElem(IRState *irs); 177 virtual llvm::Constant *toConstElem(IRState *irs); 177 virtual void cacheLvalue(IRState* irs); 178 virtual void cacheLvalue(IRState* irs); 178 179 179 llvm::Value* cachedLvalue; 180 llvm::Value* cachedLvalue; 181 182 virtual AssignExp* isAssignExp() { return NULL; } 180 #endif 183 #endif 181 }; 184 }; 182 185 183 struct IntegerExp : Expression 186 struct IntegerExp : Expression 184 { 187 { … … 1376 #endif 1379 #endif 1377 1380 1378 #if IN_LLVM 1381 #if IN_LLVM 1379 DValue* toElem(IRState* irs); 1382 DValue* toElem(IRState* irs); 1380 #endif 1383 #endif 1384 1385 AssignExp* isAssignExp() { return this; } 1381 }; 1386 }; 1382 1387 1383 #if IN_DMD 1388 #if IN_DMD 1384 #define ASSIGNEXP_TOELEM elem *toElem(IRState *irs); 1389 #define ASSIGNEXP_TOELEM elem *toElem(IRState *irs); 1385 #elif IN_LLVM 1390 #elif IN_LLVM dmd/statement.h
Revision 1630:44b145be2ef5 Revision 1650:40bd4a0d4870 139 virtual DeclarationStatement *isDeclarationStatement() { return NULL; } 139 virtual DeclarationStatement *isDeclarationStatement() { return NULL; } 140 virtual CompoundStatement *isCompoundStatement() { return NULL; } 140 virtual CompoundStatement *isCompoundStatement() { return NULL; } 141 virtual ReturnStatement *isReturnStatement() { return NULL; } 141 virtual ReturnStatement *isReturnStatement() { return NULL; } 142 virtual IfStatement *isIfStatement() { return NULL; } 142 virtual IfStatement *isIfStatement() { return NULL; } 143 virtual CaseStatement* isCaseStatement() { return NULL; } 143 virtual CaseStatement* isCaseStatement() { return NULL; } 144 virtual LabelStatement* isLabelStatement() { return NULL; } 144 145 145 #if IN_LLVM 146 #if IN_LLVM 146 virtual void toNakedIR(IRState *irs); 147 virtual void toNakedIR(IRState *irs); 147 virtual AsmBlockStatement* endsWithAsm(); 148 virtual AsmBlockStatement* endsWithAsm(); 148 #endif 149 #endif … … 861 void toIR(IRState *irs); 862 void toIR(IRState *irs); 862 863 863 // LDC 864 // LDC 864 bool asmLabel; // for labels inside inline assembler 865 bool asmLabel; // for labels inside inline assembler 865 void toNakedIR(IRState *irs); 866 void toNakedIR(IRState *irs); 867 868 LabelStatement* isLabelStatement() { return this; } 866 }; 869 }; 867 870 868 struct LabelDsymbol : Dsymbol 871 struct LabelDsymbol : Dsymbol 869 { 872 { 870 LabelStatement *statement; 873 LabelStatement *statement; gen/arrays.cpp
Revision 1643:8f121883bce8 Revision 1650:40bd4a0d4870 307 mismatch = true; 307 mismatch = true; 308 } 308 } 309 309 310 LLConstant* constarr; 310 LLConstant* constarr; 311 if (mismatch) 311 if (mismatch) 312 constarr = LLConstantStruct::get(gIR->context(), initvals );312 constarr = LLConstantStruct::get(gIR->context(), initvals, false); // FIXME should this pack? 313 else 313 else 314 constarr = LLConstantArray::get(LLArrayType::get(llelemty, arrlen), initvals); 314 constarr = LLConstantArray::get(LLArrayType::get(llelemty, arrlen), initvals); 315 315 316 // std::cout << "constarr: " << *constarr << std::endl; 316 // std::cout << "constarr: " << *constarr << std::endl; 317 317 … … 392 392 393 ////////////////////////////////////////////////////////////////////////////////////////// 393 ////////////////////////////////////////////////////////////////////////////////////////// 394 LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) 394 LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) 395 { 395 { 396 LLConstant* values[2] = { dim, ptr }; 396 LLConstant* values[2] = { dim, ptr }; 397 return LLConstantStruct::get(gIR->context(), values, 2 );397 return LLConstantStruct::get(gIR->context(), values, 2, false); 398 } 398 } 399 399 400 ////////////////////////////////////////////////////////////////////////////////////////// 400 ////////////////////////////////////////////////////////////////////////////////////////// 401 static bool isInitialized(Type* et) { 401 static bool isInitialized(Type* et) { 402 // Strip static array types from element type 402 // Strip static array types from element type gen/asmstmt.cpp
Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870 194 194 195 // get asm block 195 // get asm block 196 IRAsmBlock* asmblock = irs->asmBlock; 196 IRAsmBlock* asmblock = irs->asmBlock; 197 assert(asmblock); 197 assert(asmblock); 198 198 199 #ifndef DISABLE_DEBUG_INFO 199 // debug info 200 // debug info 200 if (global.params.symdebug) 201 if (global.params.symdebug) 201 DtoDwarfStopPoint(loc.linnum); 202 DtoDwarfStopPoint(loc.linnum); 203 #endif 202 204 203 if (! asmcode) 205 if (! asmcode) 204 return; 206 return; 205 207 206 static std::string i_cns = "i"; 208 static std::string i_cns = "i"; … … 255 default: assert(0); break; 257 default: assert(0); break; 256 } 258 } 257 break; 259 break; 258 case Arg_FrameRelative: 260 case Arg_FrameRelative: 259 // FIXME 261 // FIXME 260 llvm::cout << "asm fixme Arg_FrameRelative" << std::endl; 262 assert(0 && "asm fixme Arg_FrameRelative"); 261 assert(0); 262 /* if (arg->expr->op == TOKvar) 263 /* if (arg->expr->op == TOKvar) 263 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; 264 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; 264 else 265 else 265 assert(0); 266 assert(0); 266 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { 267 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { … … 273 if (arg->mode != Mode_Input) 274 if (arg->mode != Mode_Input) 274 clobbers_mem = true; 275 clobbers_mem = true; 275 break;*/ 276 break;*/ 276 case Arg_LocalSize: 277 case Arg_LocalSize: 277 // FIXME 278 // FIXME 278 llvm::cout << "asm fixme Arg_LocalSize" << std::endl; 279 assert(0 && "asm fixme Arg_LocalSize"); 279 assert(0); 280 /* var_frame_offset = cfun->x_frame_offset; 280 /* var_frame_offset = cfun->x_frame_offset; 281 if (var_frame_offset < 0) 281 if (var_frame_offset < 0) 282 var_frame_offset = - var_frame_offset; 282 var_frame_offset = - var_frame_offset; 283 arg_val = irs->integerConstant( var_frame_offset );*/ 283 arg_val = irs->integerConstant( var_frame_offset );*/ 284 goto do_integer; 284 goto do_integer; gen/cl_helpers.cpp
Revision 1103:b30fe7e1dbb9 Revision 1650:40bd4a0d4870 15 if (isupper(c)) 15 if (isupper(c)) 16 return tolower(c); 16 return tolower(c); 17 return c; 17 return c; 18 } 18 } 19 19 20 bool FlagParser::parse(cl::Option &O, const char *ArgName, const std::string &Arg, bool &Val) {20 bool FlagParser::parse(cl::Option &O, llvm::StringRef ArgName, llvm::StringRef Arg, bool &Val) { 21 // Make a std::string out of it to make comparisons easier 21 // Make a std::string out of it to make comparisons easier 22 // (and avoid repeated conversion) 22 // (and avoid repeated conversion) 23 std::stringargname = ArgName;23 llvm::StringRef argname = ArgName; 24 24 25 typedef std::vector<std::pair<std::string, bool> >::iterator It; 25 typedef std::vector<std::pair<std::string, bool> >::iterator It; 26 for (It I = switches.begin(), E = switches.end(); I != E; ++I) { 26 for (It I = switches.begin(), E = switches.end(); I != E; ++I) { 27 std::stringname = I->first;27 llvm::StringRef name = I->first; 28 if (name == argname 28 if (name == argname 29 || (name. length() < argname.length()29 || (name.size() < argname.size() 30 && argname.substr(0, name. length()) == name30 && argname.substr(0, name.size()) == name 31 && argname[name. length()] == '=')) {31 && argname[name.size()] == '=')) { 32 32 33 if (!cl::parser<bool>::parse(O, ArgName, Arg, Val)) { 33 if (!cl::parser<bool>::parse(O, ArgName, Arg, Val)) { 34 Val = (Val == I->second); 34 Val = (Val == I->second); 35 return false; 35 return false; 36 } 36 } 37 // Invalid option value 37 // Invalid option value … … 39 } 39 } 40 } 40 } 41 return true; 41 return true; 42 } 42 } 43 43 44 void FlagParser::getExtraOptionNames( std::vector<const char*> &Names) {44 void FlagParser::getExtraOptionNames(llvm::SmallVectorImpl<const char*> &Names) { 45 typedef std::vector<std::pair<std::string, bool> >::iterator It; 45 typedef std::vector<std::pair<std::string, bool> >::iterator It; 46 for (It I = switches.begin() + 1, E = switches.end(); I != E; ++I) { 46 for (It I = switches.begin() + 1, E = switches.end(); I != E; ++I) { 47 Names.push_back(I->first. c_str());47 Names.push_back(I->first.data()); 48 } 48 } 49 } 49 } 50 50 51 51 52 MultiSetter::MultiSetter(bool invert, bool* p, ...) { 52 MultiSetter::MultiSetter(bool invert, bool* p, ...) { gen/cl_helpers.h
Revision 1200:3171f67ad006 Revision 1650:40bd4a0d4870 19 void initialize(Opt &O) { 19 void initialize(Opt &O) { 20 std::string Name = O.ArgStr; 20 std::string Name = O.ArgStr; 21 switches.push_back(make_pair("enable-" + Name, true)); 21 switches.push_back(make_pair("enable-" + Name, true)); 22 switches.push_back(make_pair("disable-" + Name, false)); 22 switches.push_back(make_pair("disable-" + Name, false)); 23 // Replace <foo> with -enable-<foo> 23 // Replace <foo> with -enable-<foo> 24 O.ArgStr = switches[0].first. c_str();24 O.ArgStr = switches[0].first.data(); 25 } 25 } 26 26 27 bool parse(cl::Option &O, const char *ArgName, const std::string &ArgValue, bool &Val);27 bool parse(cl::Option &O, llvm::StringRef ArgName, llvm::StringRef ArgValue, bool &Val); 28 28 29 void getExtraOptionNames( std::vector<const char*> &Names);29 void getExtraOptionNames(llvm::SmallVectorImpl<const char*> &Names); 30 }; 30 }; 31 31 32 /// Helper class for options that set multiple flags 32 /// Helper class for options that set multiple flags 33 class MultiSetter { 33 class MultiSetter { 34 std::vector<bool*> locations; 34 std::vector<bool*> locations; gen/configfile.cpp
Revision 1537:ee6b20e7aedb Revision 1650:40bd4a0d4870 107 std::cerr << "Error failed to locate the configuration file: " << filename << std::endl; 107 std::cerr << "Error failed to locate the configuration file: " << filename << std::endl; 108 return false; 108 return false; 109 } 109 } 110 110 111 // save config file path for -v output 111 // save config file path for -v output 112 pathstr = p. toString();112 pathstr = p.str(); 113 113 114 try 114 try 115 { 115 { 116 // read the cfg 116 // read the cfg 117 cfg->readFile(p.c_str()); 117 cfg->readFile(p.c_str()); gen/functions.cpp
Revision 1607:207a8a438dea Revision 1650:40bd4a0d4870 597 { 597 { 598 DtoDefineNakedFunction(fd); 598 DtoDefineNakedFunction(fd); 599 return; 599 return; 600 } 600 } 601 601 602 #ifndef DISABLE_DEBUG_INFO 602 // debug info 603 // debug info 603 if (global.params.symdebug) {604 if (global.params.symdebug) 604 fd->ir.irFunc->diSubprogram = DtoDwarfSubProgram(fd); 605 fd->ir.irFunc->diSubprogram = DtoDwarfSubProgram(fd); 605 }606 #endif 606 607 607 Type* t = fd->type->toBasetype(); 608 Type* t = fd->type->toBasetype(); 608 TypeFunction* f = (TypeFunction*)t; 609 TypeFunction* f = (TypeFunction*)t; 609 assert(f->irtype); 610 assert(f->irtype); 610 611 … … 640 // create alloca point 641 // create alloca point 641 // this gets erased when the function is complete, so alignment etc does not matter at all 642 // this gets erased when the function is complete, so alignment etc does not matter at all 642 llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::getInt32Ty(gIR->context()), "alloca point", beginbb); 643 llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::getInt32Ty(gIR->context()), "alloca point", beginbb); 643 irfunction->allocapoint = allocaPoint; 644 irfunction->allocapoint = allocaPoint; 644 645 646 #ifndef DISABLE_DEBUG_INFO 645 // debug info - after all allocas, but before any llvm.dbg.declare etc 647 // debug info - after all allocas, but before any llvm.dbg.declare etc 646 if (global.params.symdebug) DtoDwarfFuncStart(fd); 648 if (global.params.symdebug) DtoDwarfFuncStart(fd); 649 #endif 647 650 648 // this hack makes sure the frame pointer elimination optimization is disabled. 651 // this hack makes sure the frame pointer elimination optimization is disabled. 649 // this this eliminates a bunch of inline asm related issues. 652 // this this eliminates a bunch of inline asm related issues. 650 if (fd->inlineAsm) 653 if (fd->inlineAsm) 651 { 654 { … … 666 669 667 assert(!fd->vthis->ir.irLocal); 670 assert(!fd->vthis->ir.irLocal); 668 fd->vthis->ir.irLocal = new IrLocal(fd->vthis); 671 fd->vthis->ir.irLocal = new IrLocal(fd->vthis); 669 fd->vthis->ir.irLocal->value = thismem; 672 fd->vthis->ir.irLocal->value = thismem; 670 673 674 #ifndef DISABLE_DEBUG_INFO 671 if (global.params.symdebug) 675 if (global.params.symdebug) 672 DtoDwarfLocalVariable(thismem, fd->vthis); 676 DtoDwarfLocalVariable(thismem, fd->vthis); 677 #endif 673 678 674 #if DMDV1 679 #if DMDV1 675 if (fd->vthis->nestedref) 680 if (fd->vthis->nestedref) 676 { 681 { 677 fd->nestedVars.insert(fd->vthis); 682 fd->nestedVars.insert(fd->vthis); … … 720 725 721 // set the arg var value to the alloca 726 // set the arg var value to the alloca 722 irloc->value = mem; 727 irloc->value = mem; 723 } 728 } 724 729 730 #ifndef DISABLE_DEBUG_INFO 725 if (global.params.symdebug && !(isaArgument(irloc->value) && !isaArgument(irloc->value)->hasByValAttr()) && !refout) 731 if (global.params.symdebug && !(isaArgument(irloc->value) && !isaArgument(irloc->value)->hasByValAttr()) && !refout) 726 DtoDwarfLocalVariable(irloc->value, vd); 732 DtoDwarfLocalVariable(irloc->value, vd); 733 #endif 727 } 734 } 728 } 735 } 729 736 730 // need result variable? (nested) 737 // need result variable? (nested) 731 #if DMDV1 738 #if DMDV1 … … 794 } else if (!gIR->scopereturned()) { 801 } else if (!gIR->scopereturned()) { 795 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement 802 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement 796 // in automatically, so we do it here. 803 // in automatically, so we do it here. 797 804 798 // pass the previous block into this block 805 // pass the previous block into this block 806 #ifndef DISABLE_DEBUG_INFO 799 if (global.params.symdebug) DtoDwarfFuncEnd(fd); 807 if (global.params.symdebug) DtoDwarfFuncEnd(fd); 808 #endif 800 if (func->getReturnType() == LLType::getVoidTy(gIR->context())) { 809 if (func->getReturnType() == LLType::getVoidTy(gIR->context())) { 801 llvm::ReturnInst::Create(gIR->context(), gIR->scopebb()); 810 llvm::ReturnInst::Create(gIR->context(), gIR->scopebb()); 802 } 811 } 803 else if (!fd->isMain()) { 812 else if (!fd->isMain()) { 804 AsmBlockStatement* asmb = fd->fbody->endsWithAsm(); 813 AsmBlockStatement* asmb = fd->fbody->endsWithAsm(); gen/linker.cpp
Revision 1600:a60e7d1ce3ee Revision 1650:40bd4a0d4870 220 std::string errstr; 220 std::string errstr; 221 221 222 // find gcc for linking 222 // find gcc for linking 223 llvm::sys::Path gcc = getGcc(); 223 llvm::sys::Path gcc = getGcc(); 224 // get a string version for argv[0] 224 // get a string version for argv[0] 225 std::string gccStr = gcc.toString();225 const char* gccStr = gcc.c_str(); 226 226 227 // build arguments 227 // build arguments 228 std::vector<const char*> args; 228 std::vector<const char*> args; 229 229 230 // first the program name ?? 230 // first the program name ?? 231 args.push_back(gccStr .c_str());231 args.push_back(gccStr); 232 232 233 // object files 233 // object files 234 for (int i = 0; i < global.params.objfiles->dim; i++) 234 for (int i = 0; i < global.params.objfiles->dim; i++) 235 { 235 { 236 char *p = (char *)global.params.objfiles->data[i]; 236 char *p = (char *)global.params.objfiles->data[i]; … … 333 std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); 333 std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); 334 Stream logstr = Logger::cout(); 334 Stream logstr = Logger::cout(); 335 for (; I != E; ++I) 335 for (; I != E; ++I) 336 if (*I) 336 if (*I) 337 logstr << "'" << *I << "'" << " "; 337 logstr << "'" << *I << "'" << " "; 338 logstr << "\n" << std::flush;338 logstr << "\n"; // FIXME where's flush ? 339 339 340 340 341 // terminate args list 341 // terminate args list 342 args.push_back(NULL); 342 args.push_back(NULL); 343 343 … … 373 assert(gExePath.isValid()); 373 assert(gExePath.isValid()); 374 374 375 // build arguments 375 // build arguments 376 std::vector<const char*> args; 376 std::vector<const char*> args; 377 // args[0] should be the name of the executable 377 // args[0] should be the name of the executable 378 args.push_back(gExePath. toString().c_str());378 args.push_back(gExePath.c_str()); 379 // Skip first argument to -run; it's a D source file. 379 // Skip first argument to -run; it's a D source file. 380 for (size_t i = 1, length = opts::runargs.size(); i < length; i++) 380 for (size_t i = 1, length = opts::runargs.size(); i < length; i++) 381 { 381 { 382 args.push_back(opts::runargs[i].c_str()); 382 args.push_back(opts::runargs[i].c_str()); 383 } 383 } gen/llvmhelpers.cpp
Revision 1643:8f121883bce8 Revision 1650:40bd4a0d4870 158 args.push_back(c); 158 args.push_back(c); 159 159 160 // call 160 // call 161 gIR->CreateCallOrInvoke(fn, args.begin(), args.end()); 161 gIR->CreateCallOrInvoke(fn, args.begin(), args.end()); 162 162 163 #ifndef DISABLE_DEBUG_INFO 163 // end debug info 164 // end debug info 164 if (global.params.symdebug) 165 if (global.params.symdebug) 165 DtoDwarfFuncEnd(gIR->func()->decl); 166 DtoDwarfFuncEnd(gIR->func()->decl); 167 #endif 166 168 167 // after assert is always unreachable 169 // after assert is always unreachable 168 gIR->ir->CreateUnreachable(); 170 gIR->ir->CreateUnreachable(); 169 } 171 } 170 172 … … 266 268 267 void DtoEnclosingHandlers(Loc loc, Statement* target) 269 void DtoEnclosingHandlers(Loc loc, Statement* target) 268 { 270 { 269 // labels are a special case: they are not required to enclose the current scope 271 // labels are a special case: they are not required to enclose the current scope 270 // for them we use the enclosing scope handler as a reference point 272 // for them we use the enclosing scope handler as a reference point 271 LabelStatement* lblstmt = dynamic_cast<LabelStatement*>(target);273 LabelStatement* lblstmt = target ? target->isLabelStatement() : 0; 272 if (lblstmt) 274 if (lblstmt) 273 target = lblstmt->enclosingScopeExit; 275 target = lblstmt->enclosingScopeExit; 274 276 275 // figure out up until what handler we need to emit 277 // figure out up until what handler we need to emit 276 FuncGen::TargetScopeVec::reverse_iterator targetit = gIR->func()->gen->targetScopes.rbegin(); 278 FuncGen::TargetScopeVec::reverse_iterator targetit = gIR->func()->gen->targetScopes.rbegin(); … … 483 { 485 { 484 return new DNullValue(type, LLConstant::getNullValue(lltype)); 486 return new DNullValue(type, LLConstant::getNullValue(lltype)); 485 } 487 } 486 488 487 // unknown 489 // unknown 488 llvm::cout << "unsupported: null value for " << type->toChars() << '\n';490 error("unsupported: null value for %s", type->toChars()); 489 assert(0); 491 assert(0); 490 return 0; 492 return 0; 491 493 492 } 494 } 493 495 … … 852 #endif 854 #endif 853 } 855 } 854 856 855 gvar->setInitializer(initVal); 857 gvar->setInitializer(initVal); 856 858 859 #ifndef DISABLE_DEBUG_INFO 857 // do debug info 860 // do debug info 858 if (global.params.symdebug) 861 if (global.params.symdebug) 859 { 862 { 860 LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd).getGV(); 863 LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd).getGV(); 861 // keep a reference so GDCE doesn't delete it ! 864 // keep a reference so GDCE doesn't delete it ! 862 gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType())); 865 gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType())); 863 } 866 } 867 #endif 864 } 868 } 865 } 869 } 866 870 867 /****************************************************************************************/ 871 /****************************************************************************************/ 868 /*//////////////////////////////////////////////////////////////////////////////////////// 872 /*//////////////////////////////////////////////////////////////////////////////////////// … … 904 vd->ir.irLocal = new IrLocal(vd); 908 vd->ir.irLocal = new IrLocal(vd); 905 909 906 ExpInitializer* ex = vd->init->isExpInitializer(); 910 ExpInitializer* ex = vd->init->isExpInitializer(); 907 assert(ex && "ref vars must have expression initializer"); 911 assert(ex && "ref vars must have expression initializer"); 908 assert(ex->exp); 912 assert(ex->exp); 909 AssignExp* as = dynamic_cast<AssignExp*>(ex->exp);913 AssignExp* as = ex->exp->isAssignExp(); 910 assert(as && "ref vars must be initialized by an assign exp"); 914 assert(as && "ref vars must be initialized by an assign exp"); 911 vd->ir.irLocal->value = as->e2->toElem(gIR)->getLVal(); 915 vd->ir.irLocal->value = as->e2->toElem(gIR)->getLVal(); 912 } 916 } 913 917 914 // referenced by nested delegate? 918 // referenced by nested delegate? … … 935 allocainst = DtoAlloca(vd->type, vd->toChars()); 939 allocainst = DtoAlloca(vd->type, vd->toChars()); 936 940 937 //allocainst->setAlignment(vd->type->alignsize()); // TODO 941 //allocainst->setAlignment(vd->type->alignsize()); // TODO 938 vd->ir.irLocal->value = allocainst; 942 vd->ir.irLocal->value = allocainst; 939 943 944 #ifndef DISABLE_DEBUG_INFO 940 if (global.params.symdebug) 945 if (global.params.symdebug) 941 {942 DtoDwarfLocalVariable(allocainst, vd); 946 DtoDwarfLocalVariable(allocainst, vd); 943 }947 #endif 944 } 948 } 945 else 949 else 946 { 950 { 947 assert(vd->ir.irLocal->value); 951 assert(vd->ir.irLocal->value); 948 } 952 } … … 1050 // alloca if necessary 1054 // alloca if necessary 1051 LLValue* allocaval = NULL; 1055 LLValue* allocaval = NULL; 1052 if (!addr && (!var->ir.irLocal || !var->ir.irLocal->value)) 1056 if (!addr && (!var->ir.irLocal || !var->ir.irLocal->value)) 1053 { 1057 { 1054 addr = DtoAlloca(var->type, var->toChars()); 1058 addr = DtoAlloca(var->type, var->toChars()); 1055 1059 1060 #ifndef DISABLE_DEBUG_INFO 1056 // add debug info 1061 // add debug info 1057 if (global.params.symdebug) 1062 if (global.params.symdebug) 1058 DtoDwarfLocalVariable(addr, var); 1063 DtoDwarfLocalVariable(addr, var); 1059 } 1064 #endif 1060 1065 } 1066 1061 // referenced by nested function? 1067 // referenced by nested function? 1062 #if DMDV2 1068 #if DMDV2 1063 if (var->nestedrefs.dim) 1069 if (var->nestedrefs.dim) 1064 #else 1070 #else 1065 if (var->nestedref) 1071 if (var->nestedref) gen/llvmhelpers.h
Revision 1643:8f121883bce8 Revision 1650:40bd4a0d4870 154 //////////////////////////////////////////// 154 //////////////////////////////////////////// 155 // gen/tocall.cpp stuff below 155 // gen/tocall.cpp stuff below 156 //////////////////////////////////////////// 156 //////////////////////////////////////////// 157 157 158 /// convert DMD calling conv to LLVM 158 /// convert DMD calling conv to LLVM 159 unsignedDtoCallingConv(Loc loc, LINK l);159 llvm::CallingConv::ID DtoCallingConv(Loc loc, LINK l); 160 160 161 /// 161 /// 162 TypeFunction* DtoTypeFunction(DValue* fnval); 162 TypeFunction* DtoTypeFunction(DValue* fnval); 163 163 164 /// 164 /// gen/logger.cpp
Revision 1502:2292878925f4 Revision 1650:40bd4a0d4870 10 10 11 #include "llvm/Support/CommandLine.h" 11 #include "llvm/Support/CommandLine.h" 12 12 13 #include "llvm/GlobalValue.h" 13 #include "llvm/GlobalValue.h" 14 #include "llvm/Support/Casting.h" 14 #include "llvm/Support/Casting.h" 15 #include "llvm/Support/raw_os tream.h"15 #include "llvm/Support/raw_os_ostream.h" 16 #include "llvm/Assembly/Writer.h" 16 #include "llvm/Assembly/Writer.h" 17 17 18 #include "gen/logger.h" 18 #include "gen/logger.h" 19 #include "gen/irstate.h" 19 #include "gen/irstate.h" 20 20 … … 25 25 26 void Stream::writeValue(std::ostream& OS, const llvm::Value& V) { 26 void Stream::writeValue(std::ostream& OS, const llvm::Value& V) { 27 // Constants don't always get their types pretty-printed. 27 // Constants don't always get their types pretty-printed. 28 // (Only treat non-global constants like this, so that e.g. global variables 28 // (Only treat non-global constants like this, so that e.g. global variables 29 // still get their initializers printed) 29 // still get their initializers printed) 30 llvm::raw_os_ostream raw(OS); 30 if (llvm::isa<llvm::Constant>(V) && !llvm::isa<llvm::GlobalValue>(V)) 31 if (llvm::isa<llvm::Constant>(V) && !llvm::isa<llvm::GlobalValue>(V)) 31 llvm::WriteAsOperand( OS, &V, true, gIR->module);32 llvm::WriteAsOperand(raw, &V, true, gIR->module); 32 else 33 else 33 OS << V;34 V.print(raw); 34 } 35 } 35 36 36 namespace Logger 37 namespace Logger 37 { 38 { 38 static std::string indent_str; 39 static std::string indent_str; gen/logger.h
Revision 1502:2292878925f4 Revision 1650:40bd4a0d4870 23 23 24 public: 24 public: 25 Stream() : OS(0) {} 25 Stream() : OS(0) {} 26 Stream(std::ostream* S) : OS(S) {} 26 Stream(std::ostream* S) : OS(S) {} 27 Stream(std::ostream& S) : OS(&S) {} 27 Stream(std::ostream& S) : OS(&S) {} 28 28 29 /* 29 Stream operator << (std::ios_base &(*Func)(std::ios_base&)) { 30 Stream operator << (std::ios_base &(*Func)(std::ios_base&)) { 30 if (OS) *OS << Func; 31 if (OS) *OS << Func; 31 return *this; 32 return *this; 32 } 33 } 33 34 */ 35 34 Stream operator << (std::ostream &(*Func)(std::ostream&)) { 36 Stream operator << (std::ostream &(*Func)(std::ostream&)) { 35 if (OS) *OS << Func;37 if (OS) Func(*OS); 36 return *this; 38 return *this; 37 } 39 } 38 40 39 template<typename Ty> 41 template<typename Ty> 40 Stream& operator << (const Ty& Thing) { 42 Stream& operator << (const Ty& Thing) { gen/main.cpp
Revision 1645:1d2d1aa16841 Revision 1650:40bd4a0d4870 482 for (unsigned i = 0; i != mAttrs.size(); ++i) 482 for (unsigned i = 0; i != mAttrs.size(); ++i) 483 Features.AddFeature(mAttrs[i]); 483 Features.AddFeature(mAttrs[i]); 484 FeaturesStr = Features.getString(); 484 FeaturesStr = Features.getString(); 485 } 485 } 486 486 487 std::auto_ptr<llvm::TargetMachine> target(theTarget->createTargetMachine(triple, FeaturesStr)); 487 // FIXME 488 assert(target.get() && "Could not allocate target machine!"); 488 //std::auto_ptr<llvm::TargetMachine> target(theTarget->createTargetMachine(triple, FeaturesStr)); 489 gTargetMachine = target.get(); 489 //assert(target.get() && "Could not allocate target machine!"); 490 gTargetData = gTargetMachine->getTargetData(); 490 //gTargetMachine = target.get(); 491 492 llvm::TargetMachine* target = theTarget->createTargetMachine(triple, FeaturesStr); 493 gTargetMachine = target; 494 495 gTargetData = target->getTargetData(); 491 496 492 // get final data layout 497 // get final data layout 493 std::string datalayout = gTargetData->getStringRepresentation(); 498 std::string datalayout = gTargetData->getStringRepresentation(); 494 global.params.dataLayout = datalayout.c_str(); 499 global.params.dataLayout = datalayout.c_str(); 495 500 gen/optimizer.cpp
Revision 1576:4551475bc6b6 Revision 1650:40bd4a0d4870 105 // -O1 105 // -O1 106 if (optimizeLevel >= 1) 106 if (optimizeLevel >= 1) 107 { 107 { 108 //addPass(pm, createStripDeadPrototypesPass()); 108 //addPass(pm, createStripDeadPrototypesPass()); 109 addPass(pm, createGlobalDCEPass()); 109 addPass(pm, createGlobalDCEPass()); 110 addPass(pm, create RaiseAllocationsPass());110 addPass(pm, createPromoteMemoryToRegisterPass()); 111 addPass(pm, createCFGSimplificationPass()); 111 addPass(pm, createCFGSimplificationPass()); 112 if (optimizeLevel == 1) 112 if (optimizeLevel == 1) 113 addPass(pm, createPromoteMemoryToRegisterPass()); 113 addPass(pm, createPromoteMemoryToRegisterPass()); 114 else 114 else 115 addPass(pm, createScalarReplAggregatesPass()); 115 addPass(pm, createScalarReplAggregatesPass()); … … 175 addPass(pm, createInstructionCombiningPass()); 175 addPass(pm, createInstructionCombiningPass()); 176 addPass(pm, createJumpThreadingPass()); 176 addPass(pm, createJumpThreadingPass()); 177 addPass(pm, createCFGSimplificationPass()); 177 addPass(pm, createCFGSimplificationPass()); 178 addPass(pm, createScalarReplAggregatesPass()); 178 addPass(pm, createScalarReplAggregatesPass()); 179 addPass(pm, createInstructionCombiningPass()); 179 addPass(pm, createInstructionCombiningPass()); 180 addPass(pm, createCon dPropagationPass());180 addPass(pm, createConstantPropagationPass()); 181 181 182 addPass(pm, createReassociatePass()); 182 addPass(pm, createReassociatePass()); 183 addPass(pm, createLoopRotatePass()); 183 addPass(pm, createLoopRotatePass()); 184 addPass(pm, createLICMPass()); 184 addPass(pm, createLICMPass()); 185 addPass(pm, createLoopUnswitchPass()); 185 addPass(pm, createLoopUnswitchPass()); … … 192 addPass(pm, createGVNPass()); 192 addPass(pm, createGVNPass()); 193 addPass(pm, createMemCpyOptPass()); 193 addPass(pm, createMemCpyOptPass()); 194 addPass(pm, createSCCPPass()); 194 addPass(pm, createSCCPPass()); 195 195 196 addPass(pm, createInstructionCombiningPass()); 196 addPass(pm, createInstructionCombiningPass()); 197 addPass(pm, createCon dPropagationPass());197 addPass(pm, createConstantPropagationPass()); 198 198 199 addPass(pm, createDeadStoreEliminationPass()); 199 addPass(pm, createDeadStoreEliminationPass()); 200 addPass(pm, createAggressiveDCEPass()); 200 addPass(pm, createAggressiveDCEPass()); 201 addPass(pm, createCFGSimplificationPass()); 201 addPass(pm, createCFGSimplificationPass()); 202 addPass(pm, createDeadTypeEliminationPass()); 202 addPass(pm, createDeadTypeEliminationPass()); gen/passes/SimplifyDRuntimeCalls.cpp
Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870 16 16 17 #define DEBUG_TYPE "simplify-drtcalls" 17 #define DEBUG_TYPE "simplify-drtcalls" 18 18 19 #include "Passes.h" 19 #include "Passes.h" 20 20 21 #include "llvm/Function.h" 21 #include "llvm/Pass.h" 22 #include "llvm/Pass.h" 22 #include "llvm/Intrinsics.h" 23 #include "llvm/Intrinsics.h" 23 #include "llvm/Support/IRBuilder.h" 24 #include "llvm/Support/IRBuilder.h" 24 #include "llvm/Analysis/AliasAnalysis.h" 25 #include "llvm/Analysis/AliasAnalysis.h" 25 #include "llvm/Analysis/ValueTracking.h" 26 #include "llvm/Analysis/ValueTracking.h" gen/statements.cpp
Revision 1647:638a823ace45 Revision 1650:40bd4a0d4870 51 void ReturnStatement::toIR(IRState* p) 51 void ReturnStatement::toIR(IRState* p) 52 { 52 { 53 Logger::println("ReturnStatement::toIR(): %s", loc.toChars()); 53 Logger::println("ReturnStatement::toIR(): %s", loc.toChars()); 54 LOG_SCOPE; 54 LOG_SCOPE; 55 55 56 if (global.params.symdebug) 56 #ifndef DISABLE_DEBUG_INFO 57 DtoDwarfStopPoint(loc.linnum); 57 if (global.params.symdebug) 58 58 DtoDwarfStopPoint(loc.linnum); 59 #endif 60 59 // is there a return value expression? 61 // is there a return value expression? 60 if (exp || (!exp && (p->topfunc() == p->mainFunc)) ) 62 if (exp || (!exp && (p->topfunc() == p->mainFunc)) ) 61 { 63 { 62 // if the functions return type is void this means that 64 // if the functions return type is void this means that 63 // we are returning through a pointer argument 65 // we are returning through a pointer argument … … 76 DtoAssign(loc, rvar, e); 78 DtoAssign(loc, rvar, e); 77 79 78 // emit scopes 80 // emit scopes 79 DtoEnclosingHandlers(loc, NULL); 81 DtoEnclosingHandlers(loc, NULL); 80 82 83 #ifndef DISABLE_DEBUG_INFO 81 // emit dbg end function 84 // emit dbg end function 82 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); 85 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); 86 #endif 83 87 84 // emit ret 88 // emit ret 85 llvm::ReturnInst::Create(gIR->context(), p->scopebb()); 89 llvm::ReturnInst::Create(gIR->context(), p->scopebb()); 86 90 87 } 91 } … … 124 Logger::cout() << "return value after cast: " << *v << '\n'; 128 Logger::cout() << "return value after cast: " << *v << '\n'; 125 } 129 } 126 130 127 DtoEnclosingHandlers(loc, NULL); 131 DtoEnclosingHandlers(loc, NULL); 128 132 133 #ifndef DISABLE_DEBUG_INFO 129 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 134 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 135 #endif 130 llvm::ReturnInst::Create(gIR->context(), v, p->scopebb()); 136 llvm::ReturnInst::Create(gIR->context(), v, p->scopebb()); 131 } 137 } 132 } 138 } 133 // no return value expression means it's a void function 139 // no return value expression means it's a void function 134 else 140 else 135 { 141 { 136 assert(p->topfunc()->getReturnType() == LLType::getVoidTy(gIR->context())); 142 assert(p->topfunc()->getReturnType() == LLType::getVoidTy(gIR->context())); 137 DtoEnclosingHandlers(loc, NULL); 143 DtoEnclosingHandlers(loc, NULL); 138 144 145 #ifndef DISABLE_DEBUG_INFO 139 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 146 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 147 #endif 140 llvm::ReturnInst::Create(gIR->context(), p->scopebb()); 148 llvm::ReturnInst::Create(gIR->context(), p->scopebb()); 141 } 149 } 142 150 143 // the return terminated this basicblock, start a new one 151 // the return terminated this basicblock, start a new one 144 llvm::BasicBlock* oldend = gIR->scopeend(); 152 llvm::BasicBlock* oldend = gIR->scopeend(); … … 151 void ExpStatement::toIR(IRState* p) 159 void ExpStatement::toIR(IRState* p) 152 { 160 { 153 Logger::println("ExpStatement::toIR(): %s", loc.toChars()); 161 Logger::println("ExpStatement::toIR(): %s", loc.toChars()); 154 LOG_SCOPE; 162 LOG_SCOPE; 155 163 156 if (global.params.symdebug) 164 #ifndef DISABLE_DEBUG_INFO 157 DtoDwarfStopPoint(loc.linnum); 165 if (global.params.symdebug) 166 DtoDwarfStopPoint(loc.linnum); 167 #endif 158 168 159 if (exp) { 169 if (exp) { 160 if (global.params.llvmAnnotate) 170 if (global.params.llvmAnnotate) 161 DtoAnnotation(exp->toChars()); 171 DtoAnnotation(exp->toChars()); 162 elem* e; 172 elem* e; … … 180 void IfStatement::toIR(IRState* p) 190 void IfStatement::toIR(IRState* p) 181 { 191 { 182 Logger::println("IfStatement::toIR(): %s", loc.toChars()); 192 Logger::println("IfStatement::toIR(): %s", loc.toChars()); 183 LOG_SCOPE; 193 LOG_SCOPE; 184 194 185 if (global.params.symdebug) 195 #ifndef DISABLE_DEBUG_INFO 186 DtoDwarfStopPoint(loc.linnum); 196 if (global.params.symdebug) 197 DtoDwarfStopPoint(loc.linnum); 198 #endif 187 199 188 if (match) 200 if (match) 189 DtoRawVarDeclaration(match); 201 DtoRawVarDeclaration(match); 190 202 191 DValue* cond_e = condition->toElem(p); 203 DValue* cond_e = condition->toElem(p); … … 268 void WhileStatement::toIR(IRState* p) 280 void WhileStatement::toIR(IRState* p) 269 { 281 { 270 Logger::println("WhileStatement::toIR(): %s", loc.toChars()); 282 Logger::println("WhileStatement::toIR(): %s", loc.toChars()); 271 LOG_SCOPE; 283 LOG_SCOPE; 272 284 273 if (global.params.symdebug) 285 #ifndef DISABLE_DEBUG_INFO 274 DtoDwarfStopPoint(loc.linnum); 286 if (global.params.symdebug) 287 DtoDwarfStopPoint(loc.linnum); 288 #endif 275 289 276 // create while blocks 290 // create while blocks 277 llvm::BasicBlock* oldend = gIR->scopeend(); 291 llvm::BasicBlock* oldend = gIR->scopeend(); 278 llvm::BasicBlock* whilebb = llvm::BasicBlock::Create(gIR->context(), "whilecond", gIR->topfunc(), oldend); 292 llvm::BasicBlock* whilebb = llvm::BasicBlock::Create(gIR->context(), "whilecond", gIR->topfunc(), oldend); 279 llvm::BasicBlock* whilebodybb = llvm::BasicBlock::Create(gIR->context(), "whilebody", gIR->topfunc(), oldend); 293 llvm::BasicBlock* whilebodybb = llvm::BasicBlock::Create(gIR->context(), "whilebody", gIR->topfunc(), oldend); … … 316 void DoStatement::toIR(IRState* p) 330 void DoStatement::toIR(IRState* p) 317 { 331 { 318 Logger::println("DoStatement::toIR(): %s", loc.toChars()); 332 Logger::println("DoStatement::toIR(): %s", loc.toChars()); 319 LOG_SCOPE; 333 LOG_SCOPE; 320 334 321 if (global.params.symdebug) 335 #ifndef DISABLE_DEBUG_INFO 322 DtoDwarfStopPoint(loc.linnum); 336 if (global.params.symdebug) 337 DtoDwarfStopPoint(loc.linnum); 338 #endif 323 339 324 // create while blocks 340 // create while blocks 325 llvm::BasicBlock* oldend = gIR->scopeend(); 341 llvm::BasicBlock* oldend = gIR->scopeend(); 326 llvm::BasicBlock* dowhilebb = llvm::BasicBlock::Create(gIR->context(), "dowhile", gIR->topfunc(), oldend); 342 llvm::BasicBlock* dowhilebb = llvm::BasicBlock::Create(gIR->context(), "dowhile", gIR->topfunc(), oldend); 327 llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "dowhilecond", gIR->topfunc(), oldend); 343 llvm::BasicBlock* condbb = llvm::BasicBlock::Create(gIR->context(), "dowhilecond", gIR->topfunc(), oldend); … … 361 void ForStatement::toIR(IRState* p) 377 void ForStatement::toIR(IRState* p) 362 { 378 { 363 Logger::println("ForStatement::toIR(): %s", loc.toChars()); 379 Logger::println("ForStatement::toIR(): %s", loc.toChars()); 364 LOG_SCOPE; 380 LOG_SCOPE; 365 381 366 if (global.params.symdebug) 382 #ifndef DISABLE_DEBUG_INFO 367 DtoDwarfStopPoint(loc.linnum); 383 if (global.params.symdebug) 384 DtoDwarfStopPoint(loc.linnum); 385 #endif 368 386 369 // create for blocks 387 // create for blocks 370 llvm::BasicBlock* oldend = gIR->scopeend(); 388 llvm::BasicBlock* oldend = gIR->scopeend(); 371 llvm::BasicBlock* forbb = llvm::BasicBlock::Create(gIR->context(), "forcond", gIR->topfunc(), oldend); 389 llvm::BasicBlock* forbb = llvm::BasicBlock::Create(gIR->context(), "forcond", gIR->topfunc(), oldend); 372 llvm::BasicBlock* forbodybb = llvm::BasicBlock::Create(gIR->context(), "forbody", gIR->topfunc(), oldend); 390 llvm::BasicBlock* forbodybb = llvm::BasicBlock::Create(gIR->context(), "forbody", gIR->topfunc(), oldend); … … 441 // don't emit two terminators in a row 459 // don't emit two terminators in a row 442 // happens just before DMD generated default statements if the last case terminates 460 // happens just before DMD generated default statements if the last case terminates 443 if (p->scopereturned()) 461 if (p->scopereturned()) 444 return; 462 return; 445 463 446 if (global.params.symdebug) 464 #ifndef DISABLE_DEBUG_INFO 447 DtoDwarfStopPoint(loc.linnum); 465 if (global.params.symdebug) 466 DtoDwarfStopPoint(loc.linnum); 467 #endif 448 468 449 if (ident != 0) { 469 if (ident != 0) { 450 Logger::println("ident = %s", ident->toChars()); 470 Logger::println("ident = %s", ident->toChars()); 451 471 452 DtoEnclosingHandlers(loc, target); 472 DtoEnclosingHandlers(loc, target); … … 496 void ContinueStatement::toIR(IRState* p) 516 void ContinueStatement::toIR(IRState* p) 497 { 517 { 498 Logger::println("ContinueStatement::toIR(): %s", loc.toChars()); 518 Logger::println("ContinueStatement::toIR(): %s", loc.toChars()); 499 LOG_SCOPE; 519 LOG_SCOPE; 500 520 501 if (global.params.symdebug) 521 #ifndef DISABLE_DEBUG_INFO 502 DtoDwarfStopPoint(loc.linnum); 522 if (global.params.symdebug) 523 DtoDwarfStopPoint(loc.linnum); 524 #endif 503 525 504 if (ident != 0) { 526 if (ident != 0) { 505 Logger::println("ident = %s", ident->toChars()); 527 Logger::println("ident = %s", ident->toChars()); 506 528 507 DtoEnclosingHandlers(loc, target); 529 DtoEnclosingHandlers(loc, target); … … 562 void TryFinallyStatement::toIR(IRState* p) 584 void TryFinallyStatement::toIR(IRState* p) 563 { 585 { 564 Logger::println("TryFinallyStatement::toIR(): %s", loc.toChars()); 586 Logger::println("TryFinallyStatement::toIR(): %s", loc.toChars()); 565 LOG_SCOPE; 587 LOG_SCOPE; 566 588 567 if (global.params.symdebug) 589 #ifndef DISABLE_DEBUG_INFO 568 DtoDwarfStopPoint(loc.linnum); 590 if (global.params.symdebug) 591 DtoDwarfStopPoint(loc.linnum); 592 #endif 569 593 570 // if there's no finalbody or no body, things are simple 594 // if there's no finalbody or no body, things are simple 571 if (!finalbody) { 595 if (!finalbody) { 572 if (body) 596 if (body) 573 body->toIR(p); 597 body->toIR(p); … … 640 void TryCatchStatement::toIR(IRState* p) 664 void TryCatchStatement::toIR(IRState* p) 641 { 665 { 642 Logger::println("TryCatchStatement::toIR(): %s", loc.toChars()); 666 Logger::println("TryCatchStatement::toIR(): %s", loc.toChars()); 643 LOG_SCOPE; 667 LOG_SCOPE; 644 668 645 if (global.params.symdebug) 669 #ifndef DISABLE_DEBUG_INFO 646 DtoDwarfStopPoint(loc.linnum); 670 if (global.params.symdebug) 671 DtoDwarfStopPoint(loc.linnum); 672 #endif 647 673 648 // create basic blocks 674 // create basic blocks 649 llvm::BasicBlock* oldend = p->scopeend(); 675 llvm::BasicBlock* oldend = p->scopeend(); 650 676 651 llvm::BasicBlock* trybb = llvm::BasicBlock::Create(gIR->context(), "try", p->topfunc(), oldend); 677 llvm::BasicBlock* trybb = llvm::BasicBlock::Create(gIR->context(), "try", p->topfunc(), oldend); … … 696 void ThrowStatement::toIR(IRState* p) 722 void ThrowStatement::toIR(IRState* p) 697 { 723 { 698 Logger::println("ThrowStatement::toIR(): %s", loc.toChars()); 724 Logger::println("ThrowStatement::toIR(): %s", loc.toChars()); 699 LOG_SCOPE; 725 LOG_SCOPE; 700 726 701 if (global.params.symdebug) 727 #ifndef DISABLE_DEBUG_INFO 702 DtoDwarfStopPoint(loc.linnum); 728 if (global.params.symdebug) 729 DtoDwarfStopPoint(loc.linnum); 730 #endif 703 731 704 assert(exp); 732 assert(exp); 705 DValue* e = exp->toElem(p); 733 DValue* e = exp->toElem(p); 706 734 735 #ifndef DISABLE_DEBUG_INFO 707 if (global.params.symdebug) DtoDwarfFuncEnd(gIR->func()->decl); 736 if (global.params.symdebug) DtoDwarfFuncEnd(gIR->func()->decl); 737 #endif 708 738 709 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_throw_exception"); 739 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_throw_exception"); 710 //Logger::cout() << "calling: " << *fn << '\n'; 740 //Logger::cout() << "calling: " << *fn << '\n'; 711 LLValue* arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0)); 741 LLValue* arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0)); 712 //Logger::cout() << "arg: " << *arg << '\n'; 742 //Logger::cout() << "arg: " << *arg << '\n'; … … 778 void SwitchStatement::toIR(IRState* p) 808 void SwitchStatement::toIR(IRState* p) 779 { 809 { 780 Logger::println("SwitchStatement::toIR(): %s", loc.toChars()); 810 Logger::println("SwitchStatement::toIR(): %s", loc.toChars()); 781 LOG_SCOPE; 811 LOG_SCOPE; 782 812 783 if (global.params.symdebug) 813 #ifndef DISABLE_DEBUG_INFO 784 DtoDwarfStopPoint(loc.linnum); 814 if (global.params.symdebug) 815 DtoDwarfStopPoint(loc.linnum); 816 #endif 785 817 786 llvm::BasicBlock* oldend = gIR->scopeend(); 818 llvm::BasicBlock* oldend = gIR->scopeend(); 787 819 788 // clear data from previous passes... :/ 820 // clear data from previous passes... :/ 789 for (int i=0; i<cases->dim; ++i) 821 for (int i=0; i<cases->dim; ++i) … … 949 981 950 // if no statements, there's nothing to do 982 // if no statements, there's nothing to do 951 if (!statements || !statements->dim) 983 if (!statements || !statements->dim) 952 return; 984 return; 953 985 954 if (global.params.symdebug) 986 #ifndef DISABLE_DEBUG_INFO 955 DtoDwarfStopPoint(loc.linnum); 987 if (global.params.symdebug) 988 DtoDwarfStopPoint(loc.linnum); 989 #endif 956 990 957 // DMD doesn't fold stuff like continue/break, and since this isn't really a loop 991 // DMD doesn't fold stuff like continue/break, and since this isn't really a loop 958 // we have to keep track of each statement and jump to the next/end on continue/break 992 // we have to keep track of each statement and jump to the next/end on continue/break 959 993 960 llvm::BasicBlock* oldend = gIR->scopeend(); 994 llvm::BasicBlock* oldend = gIR->scopeend(); … … 1015 void ForeachStatement::toIR(IRState* p) 1049 void ForeachStatement::toIR(IRState* p) 1016 { 1050 { 1017 Logger::println("ForeachStatement::toIR(): %s", loc.toChars()); 1051 Logger::println("ForeachStatement::toIR(): %s", loc.toChars()); 1018 LOG_SCOPE; 1052 LOG_SCOPE; 1019 1053 1020 if (global.params.symdebug) 1054 #ifndef DISABLE_DEBUG_INFO 1021 DtoDwarfStopPoint(loc.linnum); 1055 if (global.params.symdebug) 1056 DtoDwarfStopPoint(loc.linnum); 1057 #endif 1022 1058 1023 //assert(arguments->dim == 1); 1059 //assert(arguments->dim == 1); 1024 assert(value != 0); 1060 assert(value != 0); 1025 assert(aggr != 0); 1061 assert(aggr != 0); 1026 assert(func != 0); 1062 assert(func != 0); … … 1147 void ForeachRangeStatement::toIR(IRState* p) 1183 void ForeachRangeStatement::toIR(IRState* p) 1148 { 1184 { 1149 Logger::println("ForeachRangeStatement::toIR(): %s", loc.toChars()); 1185 Logger::println("ForeachRangeStatement::toIR(): %s", loc.toChars()); 1150 LOG_SCOPE; 1186 LOG_SCOPE; 1151 1187 1152 if (global.params.symdebug) 1188 #ifndef DISABLE_DEBUG_INFO 1153 DtoDwarfStopPoint(loc.linnum); 1189 if (global.params.symdebug) 1190 DtoDwarfStopPoint(loc.linnum); 1191 #endif 1154 1192 1155 // evaluate lwr/upr 1193 // evaluate lwr/upr 1156 assert(lwr->type->isintegral()); 1194 assert(lwr->type->isintegral()); 1157 LLValue* lower = lwr->toElem(p)->getRVal(); 1195 LLValue* lower = lwr->toElem(p)->getRVal(); 1158 assert(upr->type->isintegral()); 1196 assert(upr->type->isintegral()); … … 1296 void GotoStatement::toIR(IRState* p) 1334 void GotoStatement::toIR(IRState* p) 1297 { 1335 { 1298 Logger::println("GotoStatement::toIR(): %s", loc.toChars()); 1336 Logger::println("GotoStatement::toIR(): %s", loc.toChars()); 1299 LOG_SCOPE; 1337 LOG_SCOPE; 1300 1338 1301 if (global.params.symdebug) 1339 #ifndef DISABLE_DEBUG_INFO 1302 DtoDwarfStopPoint(loc.linnum); 1340 if (global.params.symdebug) 1341 DtoDwarfStopPoint(loc.linnum); 1342 #endif 1303 1343 1304 llvm::BasicBlock* oldend = gIR->scopeend(); 1344 llvm::BasicBlock* oldend = gIR->scopeend(); 1305 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergoto", p->topfunc(), oldend); 1345 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergoto", p->topfunc(), oldend); 1306 1346 1307 DtoGoto(loc, label->ident, enclosingFinally); 1347 DtoGoto(loc, label->ident, enclosingFinally); … … 1314 void GotoDefaultStatement::toIR(IRState* p) 1354 void GotoDefaultStatement::toIR(IRState* p) 1315 { 1355 { 1316 Logger::println("GotoDefaultStatement::toIR(): %s", loc.toChars()); 1356 Logger::println("GotoDefaultStatement::toIR(): %s", loc.toChars()); 1317 LOG_SCOPE; 1357 LOG_SCOPE; 1318 1358 1319 if (global.params.symdebug) 1359 #ifndef DISABLE_DEBUG_INFO 1320 DtoDwarfStopPoint(loc.linnum); 1360 if (global.params.symdebug) 1361 DtoDwarfStopPoint(loc.linnum); 1362 #endif 1321 1363 1322 llvm::BasicBlock* oldend = gIR->scopeend(); 1364 llvm::BasicBlock* oldend = gIR->scopeend(); 1323 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotodefault", p->topfunc(), oldend); 1365 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotodefault", p->topfunc(), oldend); 1324 1366 1325 assert(!p->scopereturned()); 1367 assert(!p->scopereturned()); … … 1336 void GotoCaseStatement::toIR(IRState* p) 1378 void GotoCaseStatement::toIR(IRState* p) 1337 { 1379 { 1338 Logger::println("GotoCaseStatement::toIR(): %s", loc.toChars()); 1380 Logger::println("GotoCaseStatement::toIR(): %s", loc.toChars()); 1339 LOG_SCOPE; 1381 LOG_SCOPE; 1340 1382 1341 if (global.params.symdebug) 1383 #ifndef DISABLE_DEBUG_INFO 1342 DtoDwarfStopPoint(loc.linnum); 1384 if (global.params.symdebug) 1385 DtoDwarfStopPoint(loc.linnum); 1386 #endif 1343 1387 1344 llvm::BasicBlock* oldend = gIR->scopeend(); 1388 llvm::BasicBlock* oldend = gIR->scopeend(); 1345 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotocase", p->topfunc(), oldend); 1389 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergotocase", p->topfunc(), oldend); 1346 1390 1347 assert(!p->scopereturned()); 1391 assert(!p->scopereturned()); … … 1361 void WithStatement::toIR(IRState* p) 1405 void WithStatement::toIR(IRState* p) 1362 { 1406 { 1363 Logger::println("WithStatement::toIR(): %s", loc.toChars()); 1407 Logger::println("WithStatement::toIR(): %s", loc.toChars()); 1364 LOG_SCOPE; 1408 LOG_SCOPE; 1365 1409 1366 if (global.params.symdebug) 1410 #ifndef DISABLE_DEBUG_INFO 1367 DtoDwarfStopPoint(loc.linnum); 1411 if (global.params.symdebug) 1412 DtoDwarfStopPoint(loc.linnum); 1413 #endif 1368 1414 1369 assert(exp); 1415 assert(exp); 1370 assert(body); 1416 assert(body); 1371 1417 1372 // with(..) can either be used with expressions or with symbols 1418 // with(..) can either be used with expressions or with symbols … … 1391 void SynchronizedStatement::toIR(IRState* p) 1437 void SynchronizedStatement::toIR(IRState* p) 1392 { 1438 { 1393 Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars()); 1439 Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars()); 1394 LOG_SCOPE; 1440 LOG_SCOPE; 1395 1441 1396 if (global.params.symdebug) 1442 #ifndef DISABLE_DEBUG_INFO 1397 DtoDwarfStopPoint(loc.linnum); 1443 if (global.params.symdebug) 1444 DtoDwarfStopPoint(loc.linnum); 1445 #endif 1398 1446 1399 // enter lock 1447 // enter lock 1400 if (exp) 1448 if (exp) 1401 { 1449 { 1402 llsync = exp->toElem(p)->getRVal(); 1450 llsync = exp->toElem(p)->getRVal(); … … 1428 void VolatileStatement::toIR(IRState* p) 1476 void VolatileStatement::toIR(IRState* p) 1429 { 1477 { 1430 Logger::println("VolatileStatement::toIR(): %s", loc.toChars()); 1478 Logger::println("VolatileStatement::toIR(): %s", loc.toChars()); 1431 LOG_SCOPE; 1479 LOG_SCOPE; 1432 1480 1433 if (global.params.symdebug) 1481 #ifndef DISABLE_DEBUG_INFO 1434 DtoDwarfStopPoint(loc.linnum); 1482 if (global.params.symdebug) 1483 DtoDwarfStopPoint(loc.linnum); 1484 #endif 1435 1485 1436 // mark in-volatile 1486 // mark in-volatile 1437 // FIXME 1487 // FIXME 1438 1488 1439 // has statement 1489 // has statement gen/tocall.cpp
Revision 1607:207a8a438dea Revision 1650:40bd4a0d4870 33 return 0; 33 return 0; 34 } 34 } 35 35 36 ////////////////////////////////////////////////////////////////////////////////////////// 36 ////////////////////////////////////////////////////////////////////////////////////////// 37 37 38 unsignedDtoCallingConv(Loc loc, LINK l)38 llvm::CallingConv::ID DtoCallingConv(Loc loc, LINK l) 39 { 39 { 40 if (l == LINKc || l == LINKcpp || l == LINKintrinsic) 40 if (l == LINKc || l == LINKcpp || l == LINKintrinsic) 41 return llvm::CallingConv::C; 41 return llvm::CallingConv::C; 42 else if (l == LINKd || l == LINKdefault) 42 else if (l == LINKd || l == LINKdefault) 43 { 43 { … … 205 // put data in d-array 205 // put data in d-array 206 std::vector<LLConstant*> pinits; 206 std::vector<LLConstant*> pinits; 207 pinits.push_back(DtoConstSize_t(vtype->getNumElements())); 207 pinits.push_back(DtoConstSize_t(vtype->getNumElements())); 208 pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype))); 208 pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype))); 209 const LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf()); 209 const LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf()); 210 tiinits = LLConstantStruct::get(gIR->context(), pinits );210 tiinits = LLConstantStruct::get(gIR->context(), pinits, false); 211 LLValue* typeinfoarrayparam = new llvm::GlobalVariable(*gIR->module, tiarrty, 211 LLValue* typeinfoarrayparam = new llvm::GlobalVariable(*gIR->module, tiarrty, 212 true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array"); 212 true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array"); 213 213 214 llvm::AttributeWithIndex Attr; 214 llvm::AttributeWithIndex Attr; 215 // specify arguments 215 // specify arguments … … 277 bool thiscall = tf->fty.arg_this; 277 bool thiscall = tf->fty.arg_this; 278 bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate); 278 bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate); 279 bool nestedcall = tf->fty.arg_nest; 279 bool nestedcall = tf->fty.arg_nest; 280 bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1); 280 bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1); 281 281 282 unsignedcallconv = DtoCallingConv(loc, tf->linkage);282 llvm::CallingConv::ID callconv = DtoCallingConv(loc, tf->linkage); 283 283 284 // get callee llvm value 284 // get callee llvm value 285 LLValue* callable = DtoCallableValue(fnval); 285 LLValue* callable = DtoCallableValue(fnval); 286 const LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType()); 286 const LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType()); 287 assert(callableTy); 287 assert(callableTy); gen/todebug.cpp
Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870 16 #include "gen/utils.h" 16 #include "gen/utils.h" 17 17 18 #include "ir/irmodule.h" 18 #include "ir/irmodule.h" 19 19 20 using namespace llvm::dwarf; 20 using namespace llvm::dwarf; 21 22 #ifndef DISABLE_DEBUG_INFO 21 23 22 #define DBG_NULL ( LLConstant::getNullValue(DBG_TYPE) ) 24 #define DBG_NULL ( LLConstant::getNullValue(DBG_TYPE) ) 23 #define DBG_TYPE ( getPtrToType(llvm::StructType::get(gIR->context(),NULL,NULL)) ) 25 #define DBG_TYPE ( getPtrToType(llvm::StructType::get(gIR->context(),NULL,NULL)) ) 24 #define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) ) 26 #define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) ) 25 27 … … 634 ln, // line no 636 ln, // line no 635 0, // col no 637 0, // col no 636 gIR->scopebb() 638 gIR->scopebb() 637 ); 639 ); 638 } 640 } 641 642 #endif gen/todebug.h
Revision 946:1714836f2c0b Revision 1650:40bd4a0d4870 1 #ifndef LDC_GEN_TODEBUG_H 1 #ifndef LDC_GEN_TODEBUG_H 2 #define LDC_GEN_TODEBUG_H 2 #define LDC_GEN_TODEBUG_H 3 4 #ifndef DISABLE_DEBUG_INFO 3 5 4 void RegisterDwarfSymbols(llvm::Module* mod); 6 void RegisterDwarfSymbols(llvm::Module* mod); 5 7 6 /** 8 /** 7 * Emit the Dwarf compile_unit global for a Module m. 9 * Emit the Dwarf compile_unit global for a Module m. … … 43 * @param vd 45 * @param vd 44 * @return 46 * @return 45 */ 47 */ 46 llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd); 48 llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd); 47 49 50 #endif // DISABLE_DEBUG_INFO 51 48 #endif // LDC_GEN_TODEBUG_H 52 #endif // LDC_GEN_TODEBUG_H 49 53 50 54 gen/tollvm.cpp
Revision 1644:9176437d98be Revision 1650:40bd4a0d4870 360 if (ptrTy == valTy) 360 if (ptrTy == valTy) 361 { 361 { 362 return val; 362 return val; 363 } 363 } 364 // ptr is integer pointer 364 // ptr is integer pointer 365 else if (ptrTy->isInteger ())365 else if (ptrTy->isIntegerTy()) 366 { 366 { 367 // val is integer 367 // val is integer 368 assert(valTy->isInteger()); 368 assert(valTy->isInteger()); 369 const LLIntegerType* pt = llvm::cast<const LLIntegerType>(ptrTy); 369 const LLIntegerType* pt = llvm::cast<const LLIntegerType>(ptrTy); 370 const LLIntegerType* vt = llvm::cast<const LLIntegerType>(valTy); 370 const LLIntegerType* vt = llvm::cast<const LLIntegerType>(valTy); gen/toobj.cpp
Revision 1575:299a6b634178 Revision 1650:40bd4a0d4870 12 12 13 #include "gen/llvm.h" 13 #include "gen/llvm.h" 14 #include "llvm/Analysis/Verifier.h" 14 #include "llvm/Analysis/Verifier.h" 15 #include "llvm/Bitcode/ReaderWriter.h" 15 #include "llvm/Bitcode/ReaderWriter.h" 16 #include "llvm/Module.h" 16 #include "llvm/Module.h" 17 #include "llvm/ModuleProvider.h"18 #include "llvm/PassManager.h" 17 #include "llvm/PassManager.h" 19 #include "llvm/LinkAllPasses.h" 18 #include "llvm/LinkAllPasses.h" 20 #include "llvm/System/Program.h" 19 #include "llvm/System/Program.h" 21 #include "llvm/Support/raw_ostream.h" 20 #include "llvm/Support/raw_ostream.h" 22 #include "llvm/Support/CommandLine.h" 21 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Support/FormattedStream.h" 22 #include "llvm/Support/FormattedStream.h" 24 #include "llvm/Target/TargetMachine.h" 23 #include "llvm/Target/TargetMachine.h" 24 #include "llvm/CodeGen/MachineCodeEmitter.h" 25 25 26 #include "mars.h" 26 #include "mars.h" 27 #include "module.h" 27 #include "module.h" 28 #include "mtype.h" 28 #include "mtype.h" 29 #include "declaration.h" 29 #include "declaration.h" … … 112 Logger::cout() << "Final data layout: " << global.params.dataLayout << '\n'; 112 Logger::cout() << "Final data layout: " << global.params.dataLayout << '\n'; 113 113 114 // allocate the target abi 114 // allocate the target abi 115 gABI = TargetABI::getTarget(); 115 gABI = TargetABI::getTarget(); 116 116 117 #ifndef DISABLE_DEBUG_INFO 117 // debug info 118 // debug info 118 if (global.params.symdebug) { 119 if (global.params.symdebug) { 119 RegisterDwarfSymbols(ir.module); 120 RegisterDwarfSymbols(ir.module); 120 DtoDwarfCompileUnit(this); 121 DtoDwarfCompileUnit(this); 121 } 122 } 123 #endif 122 124 123 // handle invalid 'objectÞ module 125 // handle invalid 'objectÞ module 124 if (!ClassDeclaration::object) { 126 if (!ClassDeclaration::object) { 125 error("is missing 'class Object'"); 127 error("is missing 'class Object'"); 126 fatal(); 128 fatal(); … … 223 if (global.params.output_bc) { 225 if (global.params.output_bc) { 224 LLPath bcpath = LLPath(filename); 226 LLPath bcpath = LLPath(filename); 225 bcpath.eraseSuffix(); 227 bcpath.eraseSuffix(); 226 bcpath.appendSuffix(std::string(global.bc_ext)); 228 bcpath.appendSuffix(std::string(global.bc_ext)); 227 Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str()); 229 Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str()); 228 std::ofstream bos(bcpath.c_str(), std::ios::binary); 230 std::string errinfo; 229 if (bos.fail()) 231 llvm::raw_fd_ostream bos(bcpath.c_str(), errinfo, llvm::raw_fd_ostream::F_Binary); 232 if (bos.has_error()) 230 { 233 { 231 error("cannot write LLVM bitcode , failed to open file '%s'", bcpath.c_str());234 error("cannot write LLVM bitcode file '%s': %s", bcpath.c_str(), errinfo.c_str()); 232 fatal(); 235 fatal(); 233 } 236 } 234 llvm::WriteBitcodeToFile(m, bos); 237 llvm::WriteBitcodeToFile(m, bos); 235 } 238 } 236 239 … … 238 if (global.params.output_ll) { 241 if (global.params.output_ll) { 239 LLPath llpath = LLPath(filename); 242 LLPath llpath = LLPath(filename); 240 llpath.eraseSuffix(); 243 llpath.eraseSuffix(); 241 llpath.appendSuffix(std::string(global.ll_ext)); 244 llpath.appendSuffix(std::string(global.ll_ext)); 242 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); 245 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); 243 std::ofstream aos(llpath.c_str()); 246 std::string errinfo; 244 if (aos.fail()) 247 llvm::raw_fd_ostream aos(llpath.c_str(), errinfo); 248 if (aos.has_error()) 245 { 249 { 246 error("cannot write LLVM asm , failed to open file '%s'", llpath.c_str());250 error("cannot write LLVM asm file '%s': %s", llpath.c_str(), errinfo.c_str()); 247 fatal(); 251 fatal(); 248 } 252 } 249 m->print(aos, NULL); 253 m->print(aos, NULL); 250 } 254 } 251 255 … … 258 spath.createTemporaryFileOnDisk(); 262 spath.createTemporaryFileOnDisk(); 259 } 263 } 260 Logger::println("Writing native asm to: %s\n", spath.c_str()); 264 Logger::println("Writing native asm to: %s\n", spath.c_str()); 261 std::string err; 265 std::string err; 262 { 266 { 263 llvm::raw_fd_ostream out(spath.c_str(), false, true,err);267 llvm::raw_fd_ostream out(spath.c_str(), err); 264 if (err.empty()) 268 if (err.empty()) 265 { 269 { 266 write_asm_to_file(*gTargetMachine, *m, out); 270 write_asm_to_file(*gTargetMachine, *m, out); 267 } 271 } 268 else 272 else … … 290 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out) 294 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out) 291 { 295 { 292 using namespace llvm; 296 using namespace llvm; 293 297 294 // Build up all of the passes that we want to do to the module. 298 // Build up all of the passes that we want to do to the module. 295 ExistingModuleProvider Provider(&m); 299 FunctionPassManager Passes(&m); 296 FunctionPassManager Passes(&Provider); 297 300 298 if (const TargetData *TD = Target.getTargetData()) 301 if (const TargetData *TD = Target.getTargetData()) 299 Passes.add(new TargetData(*TD)); 302 Passes.add(new TargetData(*TD)); 300 else 303 else 301 Passes.add(new TargetData(&m)); 304 Passes.add(new TargetData(&m)); 302 303 // Ask the target to add backend passes as necessary.304 MachineCodeEmitter *MCE = 0;305 305 306 // Last argument is enum CodeGenOpt::Level OptLevel 306 // Last argument is enum CodeGenOpt::Level OptLevel 307 // debug info doesn't work properly with OptLevel != None! 307 // debug info doesn't work properly with OptLevel != None! 308 CodeGenOpt::Level LastArg = CodeGenOpt::Default; 308 CodeGenOpt::Level LastArg = CodeGenOpt::Default; 309 if (global.params.symdebug || !optimize()) 309 if (global.params.symdebug || !optimize()) 310 LastArg = CodeGenOpt::None; 310 LastArg = CodeGenOpt::None; 311 else if (optLevel() >= 3) 311 else if (optLevel() >= 3) 312 LastArg = CodeGenOpt::Aggressive; 312 LastArg = CodeGenOpt::Aggressive; 313 313 314 llvm::formatted_raw_ostream fout(out); 314 llvm::formatted_raw_ostream fout(out); 315 FileModel::Model mod = Target.addPassesToEmitFile(Passes, fout, TargetMachine::AssemblyFile, LastArg); 315 if (Target.addPassesToEmitFile(Passes, fout, TargetMachine::CGFT_AssemblyFile, LastArg)) 316 assert(mod == FileModel::AsmFile); 316 assert(0 && "no support for asm output"); 317 318 bool err = Target.addPassesToEmitFileFinish(Passes, MCE, LastArg); 319 assert(!err); 320 317 321 Passes.doInitialization(); 318 Passes.doInitialization(); 322 319 323 // Run our queue of passes all at once now, efficiently. 320 // Run our queue of passes all at once now, efficiently. 324 for (llvm::Module::iterator I = m.begin(), E = m.end(); I != E; ++I) 321 for (llvm::Module::iterator I = m.begin(), E = m.end(); I != E; ++I) … … 326 Passes.run(*I); 323 Passes.run(*I); 327 324 328 Passes.doFinalization(); 325 Passes.doFinalization(); 329 326 330 // release module from module provider so we can delete it ourselves 327 // release module from module provider so we can delete it ourselves 331 std::string Err;328 //std::string Err; 332 llvm::Module* rmod = Provider.releaseModule(&Err);329 //llvm::Module* rmod = Provider.releaseModule(&Err); 333 assert(rmod);330 //assert(rmod); 334 } 331 } 335 332 336 /* ================================================================== */ 333 /* ================================================================== */ 337 334 338 // uses gcc to make an obj out of an assembly file 335 // uses gcc to make an obj out of an assembly file … … 348 // Note: 345 // Note: 349 // We can't just assemble and link the file with the system assembler 346 // We can't just assemble and link the file with the system assembler 350 // and linker because we don't know where to put the _start symbol. 347 // and linker because we don't know where to put the _start symbol. 351 // GCC mysteriously knows how to do it. 348 // GCC mysteriously knows how to do it. 352 std::vector<std::string> args; 349 std::vector<std::string> args; 353 args.push_back(gcc. toString());350 args.push_back(gcc.str()); 354 args.push_back("-fno-strict-aliasing"); 351 args.push_back("-fno-strict-aliasing"); 355 args.push_back("-O3"); 352 args.push_back("-O3"); 356 args.push_back("-c"); 353 args.push_back("-c"); 357 args.push_back("-xassembler"); 354 args.push_back("-xassembler"); 358 args.push_back(asmpath. toString());355 args.push_back(asmpath.str()); 359 args.push_back("-o"); 356 args.push_back("-o"); 360 args.push_back(objpath. toString());357 args.push_back(objpath.str()); 361 358 362 //FIXME: only use this if needed? 359 //FIXME: only use this if needed? 363 args.push_back("-fpic"); 360 args.push_back("-fpic"); 364 361 365 //FIXME: enforce 64 bit 362 //FIXME: enforce 64 bit … … 429 426 430 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 427 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 431 IRBuilder<> builder(bb); 428 IRBuilder<> builder(bb); 432 429 433 // debug info 430 // debug info 431 #ifndef DISABLE_DEBUG_INFO 434 LLGlobalVariable* subprog; 432 LLGlobalVariable* subprog; 435 if(global.params.symdebug) { 433 if(global.params.symdebug) { 436 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 434 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 437 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 435 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 438 } 436 } 437 #endif 439 438 440 for (size_t i=0; i<n; i++) { 439 for (size_t i=0; i<n; i++) { 441 llvm::Function* f = gIR->ctors[i]->ir.irFunc->func; 440 llvm::Function* f = gIR->ctors[i]->ir.irFunc->func; 442 llvm::CallInst* call = builder.CreateCall(f,""); 441 llvm::CallInst* call = builder.CreateCall(f,""); 443 call->setCallingConv(DtoCallingConv(0, LINKd)); 442 call->setCallingConv(DtoCallingConv(0, LINKd)); 444 } 443 } 445 444 446 // debug info end 445 // debug info end 446 #ifndef DISABLE_DEBUG_INFO 447 if(global.params.symdebug) 447 if(global.params.symdebug) 448 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 448 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 449 #endif 449 450 450 builder.CreateRetVoid(); 451 builder.CreateRetVoid(); 451 return fn; 452 return fn; 452 } 453 } 453 454 … … 473 fn->setCallingConv(DtoCallingConv(0, LINKd)); 474 fn->setCallingConv(DtoCallingConv(0, LINKd)); 474 475 475 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 476 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 476 IRBuilder<> builder(bb); 477 IRBuilder<> builder(bb); 477 478 479 #ifndef DISABLE_DEBUG_INFO 478 // debug info 480 // debug info 479 LLGlobalVariable* subprog; 481 LLGlobalVariable* subprog; 480 if(global.params.symdebug) { 482 if(global.params.symdebug) { 481 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 483 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 482 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 484 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 483 } 485 } 486 #endif 484 487 485 for (size_t i=0; i<n; i++) { 488 for (size_t i=0; i<n; i++) { 486 llvm::Function* f = gIR->dtors[i]->ir.irFunc->func; 489 llvm::Function* f = gIR->dtors[i]->ir.irFunc->func; 487 llvm::CallInst* call = builder.CreateCall(f,""); 490 llvm::CallInst* call = builder.CreateCall(f,""); 488 call->setCallingConv(DtoCallingConv(0, LINKd)); 491 call->setCallingConv(DtoCallingConv(0, LINKd)); 489 } 492 } 490 493 494 #ifndef DISABLE_DEBUG_INFO 491 // debug info end 495 // debug info end 492 if(global.params.symdebug) 496 if(global.params.symdebug) 493 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 497 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 498 #endif 494 499 495 builder.CreateRetVoid(); 500 builder.CreateRetVoid(); 496 return fn; 501 return fn; 497 } 502 } 498 503 … … 518 fn->setCallingConv(DtoCallingConv(0, LINKd)); 523 fn->setCallingConv(DtoCallingConv(0, LINKd)); 519 524 520 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 525 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "entry", fn); 521 IRBuilder<> builder(bb); 526 IRBuilder<> builder(bb); 522 527 528 #ifndef DISABLE_DEBUG_INFO 523 // debug info 529 // debug info 524 LLGlobalVariable* subprog; 530 LLGlobalVariable* subprog; 525 if(global.params.symdebug) { 531 if(global.params.symdebug) { 526 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 532 subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str()).getGV(); 527 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 533 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 528 } 534 } 535 #endif 529 536 530 for (size_t i=0; i<n; i++) { 537 for (size_t i=0; i<n; i++) { 531 llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func; 538 llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func; 532 llvm::CallInst* call = builder.CreateCall(f,""); 539 llvm::CallInst* call = builder.CreateCall(f,""); 533 call->setCallingConv(DtoCallingConv(0, LINKd)); 540 call->setCallingConv(DtoCallingConv(0, LINKd)); 534 } 541 } 535 542 543 #ifndef DISABLE_DEBUG_INFO 536 // debug info end 544 // debug info end 537 if(global.params.symdebug) 545 if(global.params.symdebug) 538 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 546 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 547 #endif 539 548 540 builder.CreateRetVoid(); 549 builder.CreateRetVoid(); 541 return fn; 550 return fn; 542 } 551 } 543 552 … … 576 // make the function insert this moduleinfo as the beginning of the _Dmodule_ref linked list 585 // make the function insert this moduleinfo as the beginning of the _Dmodule_ref linked list 577 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "moduleinfoCtorEntry", ctor); 586 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "moduleinfoCtorEntry", ctor); 578 IRBuilder<> builder(bb); 587 IRBuilder<> builder(bb); 579 588 580 // debug info 589 // debug info 590 #ifndef DISABLE_DEBUG_INFO 581 LLGlobalVariable* subprog; 591 LLGlobalVariable* subprog; 582 if(global.params.symdebug) { 592 if(global.params.symdebug) { 583 subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str()).getGV(); 593 subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str()).getGV(); 584 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 594 builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog)); 585 } 595 } 596 #endif 586 597 587 // get current beginning 598 // get current beginning 588 LLValue* curbeg = builder.CreateLoad(mref, "current"); 599 LLValue* curbeg = builder.CreateLoad(mref, "current"); 589 600 590 // put current beginning as the next of this one 601 // put current beginning as the next of this one … … 592 builder.CreateStore(curbeg, gep); 603 builder.CreateStore(curbeg, gep); 593 604 594 // replace beginning 605 // replace beginning 595 builder.CreateStore(thismref, mref); 606 builder.CreateStore(thismref, mref); 596 607 608 #ifndef DISABLE_DEBUG_INFO 597 // debug info end 609 // debug info end 598 if(global.params.symdebug) 610 if(global.params.symdebug) 599 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 611 builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog)); 612 #endif 600 613 601 // return 614 // return 602 builder.CreateRetVoid(); 615 builder.CreateRetVoid(); 603 616 604 return ctor; 617 return ctor; ir/irclass.cpp
Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870 481 // offset 481 // offset 482 LLConstant* off = DtoConstSize_t(it->offset); 482 LLConstant* off = DtoConstSize_t(it->offset); 483 483 484 // create Interface struct 484 // create Interface struct 485 LLConstant* inits[3] = { ci, vtb, off }; 485 LLConstant* inits[3] = { ci, vtb, off }; 486 LLConstant* entry = LLConstantStruct::get(gIR->context(), inits, 3 );486 LLConstant* entry = LLConstantStruct::get(gIR->context(), inits, 3, false); 487 constants.push_back(entry); 487 constants.push_back(entry); 488 } 488 } 489 489 490 // create Interface[N] 490 // create Interface[N] 491 const llvm::ArrayType* array_type = llvm::ArrayType::get( 491 const llvm::ArrayType* array_type = llvm::ArrayType::get( ir/irlandingpad.cpp
Revision 1584:f4c56ed32238 Revision 1650:40bd4a0d4870 131 selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->getClassInfoSymbol()); 131 selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->getClassInfoSymbol()); 132 } 132 } 133 } 133 } 134 // if there's a finally, the eh table has to have a 0 action 134 // if there's a finally, the eh table has to have a 0 action 135 if(hasFinally) 135 if(hasFinally) 136 selectorargs.push_back(DtoConst Size_t(0));//LLConstantInt::get(LLType::getInt32Ty(gIR->context()),0));136 selectorargs.push_back(DtoConstUint(0)); 137 137 138 // personality fn 138 // personality fn 139 llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality"); 139 llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality"); 140 LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::getInt8Ty(gIR->context()))); 140 LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::getInt8Ty(gIR->context()))); 141 selectorargs.insert(selectorargs.begin(), personality_fn_arg); 141 selectorargs.insert(selectorargs.begin(), personality_fn_arg); … … 149 const LLType* objectTy = DtoType(ClassDeclaration::object->type); 149 const LLType* objectTy = DtoType(ClassDeclaration::object->type); 150 gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var); 150 gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var); 151 } 151 } 152 152 153 // eh_sel = llvm.eh.selector(eh_ptr, cast(byte*)&_d_eh_personality, <selectorargs>); 153 // eh_sel = llvm.eh.selector(eh_ptr, cast(byte*)&_d_eh_personality, <selectorargs>); 154 llvm::Function* eh_selector_fn; 154 llvm::Function* eh_selector_fn = GET_INTRINSIC_DECL(eh_selector); 155 if (global.params.is64bit) 156 eh_selector_fn = GET_INTRINSIC_DECL(eh_selector_i64); 157 else 158 eh_selector_fn = GET_INTRINSIC_DECL(eh_selector_i32); 159 LLValue* eh_sel = gIR->ir->CreateCall(eh_selector_fn, selectorargs.begin(), selectorargs.end()); 155 LLValue* eh_sel = gIR->ir->CreateCall(eh_selector_fn, selectorargs.begin(), selectorargs.end()); 160 156 161 // emit finallys and switches that branch to catches until there are no more catches 157 // emit finallys and switches that branch to catches until there are no more catches 162 // then simply branch to the finally chain 158 // then simply branch to the finally chain 163 llvm::SwitchInst* switchinst = NULL; 159 llvm::SwitchInst* switchinst = NULL; … … 184 switchinst = gIR->ir->CreateSwitch(eh_sel, llvm::BasicBlock::Create(gIR->context(), "switchdefault", gIR->topfunc(), gIR->scopeend()), infos.size()); 180 switchinst = gIR->ir->CreateSwitch(eh_sel, llvm::BasicBlock::Create(gIR->context(), "switchdefault", gIR->topfunc(), gIR->scopeend()), infos.size()); 185 gIR->scope() = IRScope(switchinst->getDefaultDest(), gIR->scopeend()); 181 gIR->scope() = IRScope(switchinst->getDefaultDest(), gIR->scopeend()); 186 } 182 } 187 // dubious comment 183 // dubious comment 188 // catches matched first get the largest switchval, so do size - unique int 184 // catches matched first get the largest switchval, so do size - unique int 189 llvm::ConstantInt* switchval = LLConstantInt::get(DtoSize_t(),catchToInt[rit->catchType]);185 llvm::ConstantInt* switchval = DtoConstUint(catchToInt[rit->catchType]); 190 // and make sure we don't add the same switchval twice, may happen with nested trys 186 // and make sure we don't add the same switchval twice, may happen with nested trys 191 if(!switchinst->findCaseValue(switchval)) 187 if(!switchinst->findCaseValue(switchval)) 192 switchinst->addCase(switchval, rit->target); 188 switchinst->addCase(switchval, rit->target); 193 } 189 } 194 } 190 } ir/irtype.cpp
Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870 1 #include "llvm/DerivedTypes.h" 1 #include "llvm/DerivedTypes.h" 2 #include "llvm/LLVMContext.h" 2 #include "mars.h" 3 #include "mars.h" 3 #include "mtype.h" 4 #include "mtype.h" 4 #include "gen/irstate.h" 5 #include "gen/irstate.h" 5 #include "gen/logger.h" 6 #include "gen/logger.h" 6 #include "ir/irtype.h" 7 #include "ir/irtype.h" 7 8 9 // This code uses llvm::getGlobalContext() as these functions are invoked before gIR is set. 10 // ... thus it segfaults on gIR==NULL 11 8 ////////////////////////////////////////////////////////////////////////////// 12 ////////////////////////////////////////////////////////////////////////////// 9 13 10 extern const llvm::Type* DtoType(Type* dt); 14 extern const llvm::Type* DtoType(Type* dt); 11 extern const llvm::Type* DtoSize_t(); 15 extern const llvm::Type* DtoSize_t(); 12 16 … … 41 45 42 const llvm::Type * IrTypeBasic::basic2llvm(Type* t) 46 const llvm::Type * IrTypeBasic::basic2llvm(Type* t) 43 { 47 { 44 const llvm::Type* t2; 48 const llvm::Type* t2; 45 49 46 // FIXME: don't use getGlobalContext 50 llvm::LLVMContext& ctx = llvm::getGlobalContext(); 51 47 switch(t->ty) 52 switch(t->ty) 48 { 53 { 49 case Tvoid: 54 case Tvoid: 50 return llvm::Type::getVoidTy( llvm::getGlobalContext());55 return llvm::Type::getVoidTy(ctx); 51 56 52 case Tint8: 57 case Tint8: 53 case Tuns8: 58 case Tuns8: 54 case Tchar: 59 case Tchar: 55 return llvm::Type::getInt8Ty( llvm::getGlobalContext());60 return llvm::Type::getInt8Ty(ctx); 56 61 57 case Tint16: 62 case Tint16: 58 case Tuns16: 63 case Tuns16: 59 case Twchar: 64 case Twchar: 60 return llvm::Type::getInt16Ty( llvm::getGlobalContext());65 return llvm::Type::getInt16Ty(ctx); 61 66 62 case Tint32: 67 case Tint32: 63 case Tuns32: 68 case Tuns32: 64 case Tdchar: 69 case Tdchar: 65 return llvm::Type::getInt32Ty( llvm::getGlobalContext());70 return llvm::Type::getInt32Ty(ctx); 66 71 67 case Tint64: 72 case Tint64: 68 case Tuns64: 73 case Tuns64: 69 return llvm::Type::getInt64Ty( llvm::getGlobalContext());74 return llvm::Type::getInt64Ty(ctx); 70 75 71 /* 76 /* 72 case Tint128: 77 case Tint128: 73 case Tuns128: 78 case Tuns128: 74 return llvm::IntegerType::get(llvm::getGlobalContext(), 128); 79 return llvm::IntegerType::get(llvm::getGlobalContext(), 128); 75 */ 80 */ 76 81 77 case Tfloat32: 82 case Tfloat32: 78 case Timaginary32: 83 case Timaginary32: 79 return llvm::Type::getFloatTy( llvm::getGlobalContext());84 return llvm::Type::getFloatTy(ctx); 80 85 81 case Tfloat64: 86 case Tfloat64: 82 case Timaginary64: 87 case Timaginary64: 83 return llvm::Type::getDoubleTy( llvm::getGlobalContext());88 return llvm::Type::getDoubleTy(ctx); 84 89 85 case Tfloat80: 90 case Tfloat80: 86 case Timaginary80: 91 case Timaginary80: 87 // only x86 has 80bit float 92 // only x86 has 80bit float 88 if (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) 93 if (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) 89 return llvm::Type::getX86_FP80Ty( llvm::getGlobalContext());94 return llvm::Type::getX86_FP80Ty(ctx); 90 // other platforms use 64bit reals 95 // other platforms use 64bit reals 91 else 96 else 92 return llvm::Type::getDoubleTy( llvm::getGlobalContext());97 return llvm::Type::getDoubleTy(ctx); 93 98 94 case Tcomplex32: 99 case Tcomplex32: 95 t2 = llvm::Type::getFloatTy( llvm::getGlobalContext());100 t2 = llvm::Type::getFloatTy(ctx); 96 return llvm::StructType::get( llvm::getGlobalContext(), t2, t2, NULL);101 return llvm::StructType::get(ctx, t2, t2, NULL); 97 102 98 case Tcomplex64: 103 case Tcomplex64: 99 t2 = llvm::Type::getDoubleTy( llvm::getGlobalContext());104 t2 = llvm::Type::getDoubleTy(ctx); 100 return llvm::StructType::get( llvm::getGlobalContext(), t2, t2, NULL);105 return llvm::StructType::get(ctx, t2, t2, NULL); 101 106 102 case Tcomplex80: 107 case Tcomplex80: 103 t2 = (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) 108 t2 = (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64) 104 ? llvm::Type::getX86_FP80Ty( llvm::getGlobalContext())109 ? llvm::Type::getX86_FP80Ty(ctx) 105 : llvm::Type::getDoubleTy( llvm::getGlobalContext());110 : llvm::Type::getDoubleTy(ctx); 106 return llvm::StructType::get( llvm::getGlobalContext(), t2, t2, NULL);111 return llvm::StructType::get(ctx, t2, t2, NULL); 107 112 108 case Tbool: 113 case Tbool: 109 return llvm::Type::getInt1Ty( llvm::getGlobalContext());114 return llvm::Type::getInt1Ty(ctx); 110 } 115 } 111 116 112 assert(0 && "not basic type"); 117 assert(0 && "not basic type"); 113 return NULL; 118 return NULL; 114 } 119 } ir/irvar.cpp
Revision 1571:8d086d552909 Revision 1650:40bd4a0d4870 1 #include "gen/llvm.h" 1 #include "gen/llvm.h" 2 #include "declaration.h" 2 #include "declaration.h" 3 #include "gen/irstate.h" 3 #include "ir/irvar.h" 4 #include "ir/irvar.h" 4 5 5 6 6 ////////////////////////////////////////////////////////////////////////////// 7 ////////////////////////////////////////////////////////////////////////////// 7 ////////////////////////////////////////////////////////////////////////////// 8 ////////////////////////////////////////////////////////////////////////////// … … 16 ////////////////////////////////////////////////////////////////////////////// 17 ////////////////////////////////////////////////////////////////////////////// 17 ////////////////////////////////////////////////////////////////////////////// 18 ////////////////////////////////////////////////////////////////////////////// 18 ////////////////////////////////////////////////////////////////////////////// 19 ////////////////////////////////////////////////////////////////////////////// 19 20 20 IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v), 21 IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v), 21 type(llvm::OpaqueType::get( llvm::getGlobalContext()))22 type(llvm::OpaqueType::get(gIR->context())) 22 { 23 { 23 constInit = NULL; 24 constInit = NULL; 24 } 25 } 25 26 26 ////////////////////////////////////////////////////////////////////////////// 27 ////////////////////////////////////////////////////////////////////////////// tango-0.99.9.patch
Revision 1633:5c0cebff9be8 Revision 1650:40bd4a0d4870 1 Index: tango/core/rt/compiler/ldc/rt/lifetime.d 1 Index: tango/core/rt/compiler/ldc/rt/lifetime.d 2 =================================================================== 2 =================================================================== 3 --- tango/core/rt/compiler/ldc/rt/lifetime.d (revision 5 368)3 --- tango/core/rt/compiler/ldc/rt/lifetime.d (revision 5462) 4 +++ tango/core/rt/compiler/ldc/rt/lifetime.d (working copy) 4 +++ tango/core/rt/compiler/ldc/rt/lifetime.d (working copy) 5 @@ -786,6 +786,7 @@ 5 @@ -786,6 +786,7 @@ 6 return *cast(long*)px; 6 return *cast(long*)px; 7 } 7 } 8 8 … … 51 51 52 +/+ 52 +/+ 53 53 54 /** 54 /** 55 * 55 * 56 Index: tango/core/rt/compiler/ldc/rt/eh.d 57 =================================================================== 58 --- tango/core/rt/compiler/ldc/rt/eh.d (revision 5462) 59 +++ tango/core/rt/compiler/ldc/rt/eh.d (working copy) 60 @@ -1,38 +1,34 @@ 61 /** 62 * This module contains functions and structures required for 63 - * exception handling. 64 + * dwarf exception handling with llvm 65 */ 66 module rt.eh; 67 68 -import ldc.cstdarg; 69 -import rt.compiler.util.console; 70 +//debug = EH_personality; 71 72 -// debug = EH_personality; 73 - 74 // current EH implementation works on x86 75 // if it has a working unwind runtime 76 version(X86) { 77 version(linux) version=X86_UNWIND; 78 version(darwin) version=X86_UNWIND; 79 version(solaris) version=X86_UNWIND; 80 - version(freebsd) version=X86_UNWIND; 81 } 82 version(X86_64) { 83 version(linux) version=X86_UNWIND; 84 version(darwin) version=X86_UNWIND; 85 version(solaris) version=X86_UNWIND; 86 - version(freebsd) version=X86_UNWIND; 87 } 88 89 //version = HP_LIBUNWIND; 90 91 private extern(C) void abort(); 92 private extern(C) int printf(char*, ...); 93 -private extern(C) int vprintf(char*, va_list va); 94 +//private extern(C) int vprintf(char*, va_list va); 95 96 // D runtime functions 97 extern(C) { 98 - int _d_isbaseof(ClassInfo oc, ClassInfo c); 99 +// int _d_isbaseof(ClassInfo oc, ClassInfo c); 100 + Object _d_dynamic_cast(Object o, ClassInfo c); 101 } 102 103 // libunwind headers 104 @@ -74,16 +70,19 @@ 105 // interface to HP's libunwind from http://www.nongnu.org/libunwind/ 106 version(HP_LIBUNWIND) 107 { 108 + // Haven't checked whether and how it has _Unwind_Get{Text,Data}RelBase 109 + pragma (msg, "HP_LIBUNWIND interface is out of date and untested"); 110 + 111 void __libunwind_Unwind_Resume(_Unwind_Exception *); 112 _Unwind_Reason_Code __libunwind_Unwind_RaiseException(_Unwind_Exception *); 113 ptrdiff_t __libunwind_Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr 114 context); 115 - ptrdiff_t __libunwind_Unwind_GetIP(_Unwind_Context_Ptr context); 116 + size_t __libunwind_Unwind_GetIP(_Unwind_Context_Ptr context); 117 ptrdiff_t __libunwind_Unwind_SetIP(_Unwind_Context_Ptr context, 118 ptrdiff_t new_value); 119 ptrdiff_t __libunwind_Unwind_SetGR(_Unwind_Context_Ptr context, int index, 120 ptrdiff_t new_value); 121 - ptrdiff_t __libunwind_Unwind_GetRegionStart(_Unwind_Context_Ptr context); 122 + size_t __libunwind_Unwind_GetRegionStart(_Unwind_Context_Ptr context); 123 124 alias __libunwind_Unwind_Resume _Unwind_Resume; 125 alias __libunwind_Unwind_RaiseException _Unwind_RaiseException; 126 @@ -94,27 +93,30 @@ 127 alias __libunwind_Unwind_SetGR _Unwind_SetGR; 128 alias __libunwind_Unwind_GetRegionStart _Unwind_GetRegionStart; 129 } 130 -else version(X86_UNWIND) 131 +else version(X86_UNWIND) 132 { 133 void _Unwind_Resume(_Unwind_Exception*); 134 _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*); 135 ptrdiff_t _Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr context); 136 - ptrdiff_t _Unwind_GetIP(_Unwind_Context_Ptr context); 137 + size_t _Unwind_GetIP(_Unwind_Context_Ptr context); 138 ptrdiff_t _Unwind_SetIP(_Unwind_Context_Ptr context, ptrdiff_t new_value); 139 ptrdiff_t _Unwind_SetGR(_Unwind_Context_Ptr context, int index, 140 ptrdiff_t new_value); 141 - ptrdiff_t _Unwind_GetRegionStart(_Unwind_Context_Ptr context); 142 + size_t _Unwind_GetRegionStart(_Unwind_Context_Ptr context); 143 + 144 + size_t _Unwind_GetTextRelBase(_Unwind_Context_Ptr); 145 + size_t _Unwind_GetDataRelBase(_Unwind_Context_Ptr); 146 } 147 else 148 { 149 // runtime calls these directly 150 void _Unwind_Resume(_Unwind_Exception*) 151 { 152 - console("_Unwind_Resume is not implemented on this platform.\n"); 153 + printf("_Unwind_Resume is not implemented on this platform.\n"); 154 } 155 _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*) 156 { 157 - console("_Unwind_RaiseException is not implemented on this platform.\n"); 158 + printf("_Unwind_RaiseException is not implemented on this platform.\n"); 159 return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; 160 } 161 } 162 @@ -122,14 +124,161 @@ 163 } 164 165 // error and exit 166 -extern(C) private void fatalerror(char[] format) 167 +extern(C) private void fatalerror(char* format, ...) 168 { 169 - printf("Fatal error in EH code: %.*s\n", format.length, format.ptr); 170 +// va_list args; 171 +// va_start(args, format); 172 + printf("Fatal error in EH code: "); 173 +// vprintf(format, args); 174 + printf("\n"); 175 abort(); 176 } 177 178 179 -// helpers for reading certain DWARF data 180 +// DWARF EH encoding enum 181 +// See e.g. http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/dwarfext.html 182 +private enum : ubyte { 183 + DW_EH_PE_omit = 0xff, // value is not present 184 + 185 + // value format 186 + DW_EH_PE_absptr = 0x00, // literal pointer 187 + DW_EH_PE_uleb128 = 0x01, 188 + DW_EH_PE_udata2 = 0x02, // unsigned 2-byte 189 + DW_EH_PE_udata4 = 0x03, 190 + DW_EH_PE_udata8 = 0x04, 191 + DW_EH_PE_sleb128 = 0x09, 192 + DW_EH_PE_sdata2 = 0x0a, 193 + DW_EH_PE_sdata4 = 0x0b, 194 + DW_EH_PE_sdata8 = 0x0c, 195 + 196 + // value meaning 197 + DW_EH_PE_pcrel = 0x10, // relative to program counter 198 + DW_EH_PE_textrel = 0x20, // relative to .text 199 + DW_EH_PE_datarel = 0x30, // relative to .got or .eh_frame_hdr 200 + DW_EH_PE_funcrel = 0x40, // relative to beginning of function 201 + DW_EH_PE_aligned = 0x50, // is an aligned void* 202 + 203 + // value is a pointer to the actual value 204 + // this is a mask on top of one of the above 205 + DW_EH_PE_indirect = 0x80 206 +} 207 + 208 +// Helpers for reading DWARF data 209 + 210 +// Given an encoding and a context, return the base to which the encoding is 211 +// relative 212 +private size_t base_of_encoded(_Unwind_Context_Ptr context, ubyte encoding) 213 +{ 214 + if (encoding == DW_EH_PE_omit) 215 + return 0; 216 + 217 + switch (encoding & 0x70) // ignore DW_EH_PE_indirect 218 + { 219 + case DW_EH_PE_absptr, DW_EH_PE_pcrel, DW_EH_PE_aligned: 220 + return 0; 221 + 222 + case DW_EH_PE_textrel: return _Unwind_GetTextRelBase(context); 223 + case DW_EH_PE_datarel: return _Unwind_GetDataRelBase(context); 224 + case DW_EH_PE_funcrel: return _Unwind_GetRegionStart(context); 225 + 226 + default: fatalerror("Unrecognized base for DWARF value"); 227 + } 228 +} 229 + 230 +// Only defined for fixed-size encodings 231 +private size_t size_of_encoded(ubyte encoding) 232 +{ 233 + if (encoding == DW_EH_PE_omit) 234 + return 0; 235 + 236 + switch (encoding & 0x07) // ignore leb128 237 + { 238 + case DW_EH_PE_absptr: return (void*).sizeof; 239 + case DW_EH_PE_udata2: return 2; 240 + case DW_EH_PE_udata4: return 4; 241 + case DW_EH_PE_udata8: return 8; 242 + 243 + default: fatalerror("Unrecognized fixed-size DWARF value encoding"); 244 + } 245 +} 246 + 247 +// Actual value readers below: read a value from the given ubyte* into the 248 +// output parameter and return the pointer incremented past the value. 249 + 250 +// Like read_encoded_with_base but gets the base from the given context 251 +private ubyte* read_encoded(_Unwind_Context_Ptr context, ubyte encoding, ubyte* p, out size_t val) 252 +{ 253 + return read_encoded_with_base(encoding, base_of_encoded(context, encoding), p, val); 254 +} 255 + 256 +private ubyte* read_encoded_with_base(ubyte encoding, size_t base, ubyte* p, out size_t val) 257 +{ 258 + if (encoding == DW_EH_PE_aligned) 259 + { 260 + auto a = cast(size_t)p; 261 + a = (a + (void*).sizeof - 1) & -(void*).sizeof; 262 + val = *cast(size_t*)a; 263 + return cast(ubyte*)(a + (void*).sizeof); 264 + } 265 + 266 + union U 267 + { 268 + size_t ptr; 269 + ushort udata2; 270 + uint udata4; 271 + ulong udata8; 272 + short sdata2; 273 + int sdata4; 274 + long sdata8; 275 + } 276 + 277 + auto u = cast(U*)p; 278 + 279 + size_t result; 280 + 281 + switch (encoding & 0x0f) 282 + { 283 + case DW_EH_PE_absptr: 284 + result = u.ptr; 285 + p += (void*).sizeof; 286 + break; 287 + 288 + case DW_EH_PE_uleb128: 289 + { 290 + p = get_uleb128(p, result); 291 + break; 292 + } 293 + case DW_EH_PE_sleb128: 294 + { 295 + ptrdiff_t sleb128; 296 + p = get_sleb128(p, sleb128); 297 + result = cast(size_t)sleb128; 298 + break; 299 + } 300 + 301 + case DW_EH_PE_udata2: result = cast(size_t)u.udata2; p += 2; break; 302 + case DW_EH_PE_udata4: result = cast(size_t)u.udata4; p += 4; break; 303 + case DW_EH_PE_udata8: result = cast(size_t)u.udata8; p += 8; break; 304 + case DW_EH_PE_sdata2: result = cast(size_t)u.sdata2; p += 2; break; 305 + case DW_EH_PE_sdata4: result = cast(size_t)u.sdata4; p += 4; break; 306 + case DW_EH_PE_sdata8: result = cast(size_t)u.sdata8; p += 8; break; 307 + 308 + default: fatalerror("Unrecognized DWARF value encoding format"); 309 + } 310 + if (result) 311 + { 312 + if ((encoding & 0x70) == DW_EH_PE_pcrel) 313 + result += cast(size_t)u; 314 + else 315 + result += base; 316 + 317 + if (encoding & DW_EH_PE_indirect) 318 + result = *cast(size_t*)result; 319 + } 320 + val = result; 321 + return p; 322 +} 323 + 324 private ubyte* get_uleb128(ubyte* addr, ref size_t res) 325 { 326 res = 0; 327 @@ -137,7 +286,7 @@ 328 329 // read as long as high bit is set 330 while(*addr & 0x80) { 331 - res |= (*addr & 0x7f) << bitsize; 332 + res |= (*addr & 0x7fU) << bitsize; 333 bitsize += 7; 334 addr += 1; 335 if(bitsize >= size_t.sizeof*8) 336 @@ -153,12 +302,12 @@ 337 338 private ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res) 339 { 340 - res = 0; 341 + size_t tres = 0; 342 size_t bitsize = 0; 343 344 // read as long as high bit is set 345 while(*addr & 0x80) { 346 - res |= (*addr & 0x7f) << bitsize; 347 + tres |= (*addr & 0x7fU) << bitsize; 348 bitsize += 7; 349 addr += 1; 350 if(bitsize >= size_t.sizeof*8) 351 @@ -167,12 +316,14 @@ 352 // read last 353 if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize) 354 fatalerror("tried to read sleb128 that exceeded size of size_t"); 355 - res |= (*addr) << bitsize; 356 + tres |= (*addr) << bitsize; 357 358 // take care of sign 359 - if(bitsize < size_t.sizeof*8 && ((*addr) & 0x40)) 360 - res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1); 361 + if(bitsize < size_t.sizeof*8 && (*addr & 0x40U) != 0) 362 + tres |= cast(size_t)(-1) ^ ((1 << (bitsize+7)) - 1); 363 364 + res = cast(ptrdiff_t)tres; 365 + 366 return addr + 1; 367 } 368 369 @@ -190,8 +341,7 @@ 370 371 // the 8-byte string identifying the type of exception 372 // the first 4 are for vendor, the second 4 for language 373 -//TODO: This may be the wrong way around 374 -const char[8] _d_exception_class = "LLDCD1\0\0"; 375 +const char[8] _d_exception_class = "LDC_D_10"; 376 377 378 // 379 @@ -201,118 +351,174 @@ 380 version(X86_UNWIND) 381 { 382 383 +// Various stuff we need 384 +struct Region 385 +{ 386 + ubyte* callsite_table; 387 + ubyte* action_table; 388 + 389 + // Note: classinfo_table points past the end of the table 390 + ubyte* classinfo_table; 391 + 392 + size_t start; 393 + size_t lpStart_base; // landing pad base 394 + 395 + ubyte ttypeEnc; 396 + size_t ttype_base; // typeinfo base 397 + 398 + ubyte callSiteEnc; 399 +} 400 + 401 // the personality routine gets called by the unwind handler and is responsible for 402 // reading the EH tables and deciding what to do 403 extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions, ulong exception_class, _Unwind_Exception* exception_info, _Unwind_Context_Ptr context) 404 { 405 + debug(EH_personality) printf("Entering personality routine, context=%p\n", context); 406 // check ver: the C++ Itanium ABI only allows ver == 1 407 if(ver != 1) 408 + { 409 + debug(EH_personality) printf("eh version mismatch\n"); 410 return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; 411 + } 412 413 // check exceptionClass 414 //TODO: Treat foreign exceptions with more respect 415 - if((cast(char*)&exception_class)[0..8] != _d_exception_class) 416 + auto wanted_ec = *cast(ulong*)_d_exception_class.ptr; 417 + if(exception_class != wanted_ec) 418 + { 419 + debug(EH_personality) printf("exception class mismatch %p vs %p\n", exception_class, wanted_ec); 420 return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; 421 + } 422 423 // find call site table, action table and classinfo table 424 // Note: callsite and action tables do not contain static-length 425 // data and will be parsed as needed 426 - // Note: classinfo_table points past the end of the table 427 - ubyte* callsite_table; 428 - ubyte* action_table; 429 - ClassInfo* classinfo_table; 430 - _d_getLanguageSpecificTables(context, callsite_table, action_table, classinfo_table); 431 - if (!callsite_table) 432 + 433 + Region region; 434 + 435 + _d_getLanguageSpecificTables(context, region); 436 + 437 + // workaround. this should not happen 438 + if (!region.callsite_table) 439 + { 440 + debug(EH_personality) printf("callsite_table is null\n"); 441 return _Unwind_Reason_Code.CONTINUE_UNWIND; 442 + } 443 444 + debug(EH_personality) printf("yay, checking\n"); 445 + debug(EH_personality) printf("region.start = %p\n", region.start); 446 + 447 /* 448 find landing pad and action table index belonging to ip by walking 449 the callsite_table 450 */ 451 - ubyte* callsite_walker = callsite_table; 452 + ubyte* callsite_walker = region.callsite_table; 453 + debug(EH_personality) printf("callsite table at: %p\n", region.callsite_table); 454 + debug(EH_personality) printf("action table at: %p\n", region.action_table); 455 + debug(EH_personality) printf("rtti table at %p\n", region.classinfo_table); 456 457 // get the instruction pointer 458 // will be used to find the right entry in the callsite_table 459 // -1 because it will point past the last instruction 460 - ptrdiff_t ip = _Unwind_GetIP(context) - 1; 461 + debug(EH_personality) printf("check1\n"); 462 + size_t ip = _Unwind_GetIP(context) - 1; 463 + debug(EH_personality) printf("check2\n"); 464 465 - // address block_start is relative to 466 - ptrdiff_t region_start = _Unwind_GetRegionStart(context); 467 - 468 // table entries 469 - uint block_start_offset, block_size; 470 - ptrdiff_t landing_pad; 471 + size_t landing_pad; 472 size_t action_offset; 473 474 while(true) { 475 // if we've gone through the list and found nothing... 476 - if(callsite_walker >= action_table) 477 + if(callsite_walker >= region.action_table) 478 + { 479 + debug(EH_personality) printf("found nothing\n"); 480 return _Unwind_Reason_Code.CONTINUE_UNWIND; 481 + } 482 483 - block_start_offset = *cast(uint*)callsite_walker; 484 - block_size = *(cast(uint*)callsite_walker + 1); 485 - landing_pad = *(cast(uint*)callsite_walker + 2); 486 - if(landing_pad) 487 - landing_pad += region_start; 488 - callsite_walker = get_uleb128(callsite_walker + 3*uint.sizeof, action_offset); 489 + size_t block_start, block_size; 490 491 - debug(EH_personality_verbose) printf("ip=%llx %d %d %llx\n", ip, block_start_offset, block_size, landing_pad); 492 + callsite_walker = read_encoded(null, region.callSiteEnc, callsite_walker, block_start); 493 + callsite_walker = read_encoded(null, region.callSiteEnc, callsite_walker, block_size); 494 + callsite_walker = read_encoded(null, region.callSiteEnc, callsite_walker, landing_pad); 495 + callsite_walker = get_uleb128(callsite_walker, action_offset); 496 497 + debug(EH_personality) printf("*block start offset = %p\n", block_start); 498 + debug(EH_personality) printf(" block size = %p\n", block_size); 499 + debug(EH_personality) printf(" landing pad = %p\n", landing_pad); 500 + debug(EH_personality) printf(" ip=%p %p %p %p\n", ip, block_start, block_size, landing_pad); 501 + 502 // since the list is sorted, as soon as we're past the ip 503 // there's no handler to be found 504 - if(ip < region_start + block_start_offset) 505 + if(ip < region.start + block_start) 506 + { 507 + debug(EH_personality) printf("found nothing2\n"); 508 return _Unwind_Reason_Code.CONTINUE_UNWIND; 509 + } 510 511 + if(landing_pad) 512 + landing_pad += region.lpStart_base; 513 + 514 // if we've found our block, exit 515 - if(ip < region_start + block_start_offset + block_size) 516 + if(ip < region.start + block_start + block_size) 517 break; 518 } 519 520 - debug(EH_personality) printf("Found correct landing pad and actionOffset %d\n", action_offset); 521 + debug(EH_personality) printf("Found correct landing pad %p and actionOffset %p\n", landing_pad, action_offset); 522 523 // now we need the exception's classinfo to find a handler 524 // the exception_info is actually a member of a larger _d_exception struct 525 // the runtime allocated. get that now 526 - _d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - _d_exception.unwind_info.offsetof); 527 + _d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - size_t.sizeof); //_d_exception.unwind_info.offsetof); 528 529 // if there's no action offset and no landing pad, continue unwinding 530 if(!action_offset && !landing_pad) 531 return _Unwind_Reason_Code.CONTINUE_UNWIND; 532 533 // if there's no action offset but a landing pad, this is a cleanup handler 534 - else if(!action_offset && landing_pad) 535 - return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context); 536 + else if(!action_offset && landing_pad != 0) 537 + { 538 + debug(EH_personality) printf("installing finally context\n"); 539 + return _d_eh_install_finally_context(actions, cast(ptrdiff_t)landing_pad, exception_struct, context); 540 + } 541 542 /* 543 walk action table chain, comparing classinfos using _d_isbaseof 544 */ 545 - ubyte* action_walker = action_table + action_offset - 1; 546 + ubyte* action_walker = region.action_table + action_offset - 1; 547 548 - ptrdiff_t ti_offset, next_action_offset; 549 while(true) { 550 + ptrdiff_t ti_offset, next_action_offset; 551 + 552 action_walker = get_sleb128(action_walker, ti_offset); 553 // it is intentional that we not modify action_walker here 554 // next_action_offset is from current action_walker position 555 get_sleb128(action_walker, next_action_offset); 556 557 // negative are 'filters' which we don't use 558 - if(!(ti_offset >= 0)) 559 + if(ti_offset < 0) 560 fatalerror("Filter actions are unsupported"); 561 562 // zero means cleanup, which we require to be the last action 563 if(ti_offset == 0) { 564 - if(!(next_action_offset == 0)) 565 + if(next_action_offset != 0) 566 fatalerror("Cleanup action must be last in chain"); 567 - return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context); 568 + return _d_eh_install_finally_context(actions, cast(ptrdiff_t)landing_pad, exception_struct, context); 569 } 570 571 // get classinfo for action and check if the one in the 572 // exception structure is a base 573 - ClassInfo catch_ci = *(classinfo_table - ti_offset); 574 - debug(EH_personality) printf("Comparing catch %s to exception %s\n", catch_ci.name.ptr, exception_struct.exception_object.classinfo.name.ptr); 575 - if(_d_isbaseof(exception_struct.exception_object.classinfo, catch_ci)) 576 - return _d_eh_install_catch_context(actions, ti_offset, landing_pad, exception_struct, context); 577 + size_t typeinfo; 578 + auto filter = cast(size_t)ti_offset * size_of_encoded(region.ttypeEnc); 579 + read_encoded_with_base(region.ttypeEnc, region.ttype_base, region.classinfo_table - filter, typeinfo); 580 581 + debug(EH_personality) 582 + printf("classinfo at %zx (enc %zx (size %zx) base %zx ptr %zx)\n", typeinfo, region.ttypeEnc, size_of_encoded(region.ttypeEnc), region.ttype_base, region.classinfo_table - filter); 583 + 584 + auto catch_ci = *cast(ClassInfo*)&typeinfo; 585 + if(_d_dynamic_cast(exception_struct.exception_object, catch_ci) !is null) 586 + return _d_eh_install_catch_context(actions, ti_offset, cast(ptrdiff_t)landing_pad, exception_struct, context); 587 + 588 // we've walked through all actions and found nothing... 589 if(next_action_offset == 0) 590 return _Unwind_Reason_Code.CONTINUE_UNWIND; 591 @@ -356,6 +562,7 @@ 592 } 593 594 fatalerror("reached unreachable"); 595 + 596 return _Unwind_Reason_Code.FATAL_PHASE2_ERROR; 597 } 598 599 @@ -370,56 +577,78 @@ 600 _Unwind_SetGR(context, eh_exception_regno, cast(ptrdiff_t)exception_struct); 601 _Unwind_SetGR(context, eh_selector_regno, 0); 602 _Unwind_SetIP(context, landing_pad); 603 + 604 return _Unwind_Reason_Code.INSTALL_CONTEXT; 605 } 606 607 -private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, ref ubyte* callsite, ref ubyte* action, ref ClassInfo* ci) 608 +private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, out Region region) 609 { 610 - ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context); 611 + auto data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context); 612 + 613 + // workaround. this should not be 0... 614 if (!data) 615 { 616 - callsite = null; 617 - action = null; 618 - ci = null; 619 - return; 620 + //printf("language specific data is null\n"); 621 + return; 622 } 623 624 - //TODO: Do proper DWARF reading here 625 - if(*data++ != 0xff) 626 - fatalerror("DWARF header has unexpected format 1"); 627 + region.start = _Unwind_GetRegionStart(context); 628 629 - if(*data++ != 0x00) 630 - fatalerror("DWARF header has unexpected format 2"); 631 - size_t cioffset; 632 - data = get_uleb128(data, cioffset); 633 - ci = cast(ClassInfo*)(data + cioffset); 634 + // Read the C++-style LSDA: this is implementation-defined by GCC but LLVM 635 + // outputs the same kind of table 636 637 - if(*data++ != 0x03) 638 - fatalerror("DWARF header has unexpected format 3"); 639 - size_t callsitelength; 640 - data = get_uleb128(data, callsitelength); 641 - action = data + callsitelength; 642 + // Get @LPStart: landing pad offsets are relative to it 643 + auto lpStartEnc = *data++; 644 + if (lpStartEnc == DW_EH_PE_omit) 645 + region.lpStart_base = region.start; 646 + else 647 + data = read_encoded(context, lpStartEnc, data, region.lpStart_base); 648 649 - callsite = data; 650 + // Get @TType: the offset to the handler and typeinfo 651 + region.ttypeEnc = *data++; 652 + if (region.ttypeEnc == DW_EH_PE_omit) 653 + // Not sure about this one... 654 + fatalerror("@TType must not be omitted from DWARF header"); 655 + 656 + size_t ciOffset; 657 + data = get_uleb128(data, ciOffset); 658 + region.classinfo_table = data + ciOffset; 659 + 660 + region.ttype_base = base_of_encoded(context, region.ttypeEnc); 661 + 662 + // Get encoding and length of the call site table, which precedes the action 663 + // table. 664 + region.callSiteEnc = *data++; 665 + if (region.callSiteEnc == DW_EH_PE_omit) 666 + fatalerror("Call site table encoding must not be omitted from DWARF header"); 667 + 668 + size_t callSiteLength; 669 + region.callsite_table = get_uleb128(data, callSiteLength); 670 + region.action_table = region.callsite_table + callSiteLength; 671 } 672 673 } // end of x86 Linux specific implementation 674 675 - 676 -extern(C) void _d_throw_exception(Object e) 677 +// called to throw object 678 +extern(C) 679 +void _d_throw_exception(Object e) 680 { 681 + //printf("throwing %p, rtti = %p\n", e, **cast(ClassRTTI***)e); 682 if (e !is null) 683 { 684 _d_exception* exc_struct = new _d_exception; 685 exc_struct.unwind_info.exception_class = *cast(ulong*)_d_exception_class.ptr; 686 exc_struct.exception_object = e; 687 _Unwind_Reason_Code ret = _Unwind_RaiseException(&exc_struct.unwind_info); 688 - console("_Unwind_RaiseException failed with reason code: ")(ret)("\n"); 689 + printf("Error: returned %d from raise exception.\n", ret); 690 + //console("_Unwind_RaiseException failed with reason code: ")(ret)("\n"); 691 } 692 abort(); 693 } 694 695 -extern(C) void _d_eh_resume_unwind(_d_exception* exception_struct) 696 +// called to resume unwinding 697 +extern(C) 698 +void _d_eh_resume_unwind(void* exception_struct) 699 { 700 - _Unwind_Resume(&exception_struct.unwind_info); 701 + _Unwind_Resume(&(cast(_d_exception*)exception_struct).unwind_info); 702 }

