Mercurial > projects > ldc
comparison gen/tollvm.cpp @ 217:0806379a5eca trunk
[svn r233] Added: -oq command line option for writing fully qualified object names.
Added: started support for x86 80bit floating point.
Changed: aggregates passed by value now use the llvm 'byval' parameter attribute, also lays ground work for
using other attributes.
Changed: eliminated a lot more std::vectorS, these showed up pretty much at the top when profiling!
Changed: performed other misc. cleanups.
Changed: halt expression now call the new llvm trap intrinsic instead of an assert(0).
Changed: dstress suite now passes -O0 by default, this only eliminates unreferenced globals, which speeds up
linking quite a bit.
author | lindquist |
---|---|
date | Thu, 05 Jun 2008 06:38:36 +0200 |
parents | 7816aafeea3c |
children | a168a2c3ea48 |
comparison
equal
deleted
inserted
replaced
216:3d022aa016ae | 217:0806379a5eca |
---|---|
18 #include "gen/classes.h" | 18 #include "gen/classes.h" |
19 #include "gen/typeinf.h" | 19 #include "gen/typeinf.h" |
20 #include "gen/complex.h" | 20 #include "gen/complex.h" |
21 | 21 |
22 bool DtoIsPassedByRef(Type* type) | 22 bool DtoIsPassedByRef(Type* type) |
23 { | |
24 Type* typ = DtoDType(type); | |
25 TY t = typ->ty; | |
26 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); | |
27 } | |
28 | |
29 bool DtoIsReturnedInArg(Type* type) | |
23 { | 30 { |
24 Type* typ = DtoDType(type); | 31 Type* typ = DtoDType(type); |
25 TY t = typ->ty; | 32 TY t = typ->ty; |
26 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); | 33 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); |
27 } | 34 } |
65 case Tfloat32: | 72 case Tfloat32: |
66 case Timaginary32: | 73 case Timaginary32: |
67 return llvm::Type::FloatTy; | 74 return llvm::Type::FloatTy; |
68 case Tfloat64: | 75 case Tfloat64: |
69 case Timaginary64: | 76 case Timaginary64: |
77 return llvm::Type::DoubleTy; | |
70 case Tfloat80: | 78 case Tfloat80: |
71 case Timaginary80: | 79 case Timaginary80: |
72 return llvm::Type::DoubleTy; | 80 return (global.params.useFP80) ? llvm::Type::X86_FP80Ty : llvm::Type::DoubleTy; |
73 | 81 |
74 // complex | 82 // complex |
75 case Tcomplex32: | 83 case Tcomplex32: |
76 case Tcomplex64: | 84 case Tcomplex64: |
77 case Tcomplex80: | 85 case Tcomplex80: |
588 return 0; | 596 return 0; |
589 } | 597 } |
590 | 598 |
591 ////////////////////////////////////////////////////////////////////////////////////////// | 599 ////////////////////////////////////////////////////////////////////////////////////////// |
592 | 600 |
593 LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const std::string& var, llvm::BasicBlock* bb) | 601 LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var, llvm::BasicBlock* bb) |
594 { | 602 { |
595 std::vector<LLValue*> v(2); | 603 LLSmallVector<LLValue*,2> v(2); |
596 v[0] = i0; | 604 v[0] = i0; |
597 v[1] = i1; | 605 v[1] = i1; |
598 Logger::cout() << "DtoGEP: " << *ptr << ", " << *i0 << ", " << *i1 << '\n'; | |
599 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); | 606 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
600 } | 607 } |
601 | 608 |
602 ////////////////////////////////////////////////////////////////////////////////////////// | 609 ////////////////////////////////////////////////////////////////////////////////////////// |
603 | 610 |
604 LLValue* DtoGEP(LLValue* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) | 611 LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var, llvm::BasicBlock* bb) |
605 { | 612 { |
606 size_t n = src.size(); | 613 size_t n = src.size(); |
607 std::vector<LLValue*> dst(n, NULL); | 614 LLSmallVector<LLValue*, 3> dst(n); |
608 //std::ostream& ostr = Logger::cout(); | 615 |
609 //ostr << "indices for '" << *ptr << "':"; | 616 size_t j=0; |
610 for (size_t i=0; i<n; ++i) | 617 for (DStructIndexVector::const_iterator i=src.begin(); i!=src.end(); ++i) |
611 { | 618 dst[j++] = DtoConstUint(*i); |
612 //ostr << ' ' << i; | 619 |
613 dst[i] = llvm::ConstantInt::get(llvm::Type::Int32Ty, src[i], false); | |
614 } | |
615 //ostr << '\n';*/ | |
616 return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb()); | 620 return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb()); |
617 } | 621 } |
618 | 622 |
619 ////////////////////////////////////////////////////////////////////////////////////////// | 623 ////////////////////////////////////////////////////////////////////////////////////////// |
620 | 624 |
621 LLValue* DtoGEPi(LLValue* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb) | 625 LLValue* DtoGEPi(LLValue* ptr, unsigned i, const char* var, llvm::BasicBlock* bb) |
622 { | 626 { |
623 return llvm::GetElementPtrInst::Create(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb()); | 627 return llvm::GetElementPtrInst::Create(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb()); |
624 } | 628 } |
625 | 629 |
626 ////////////////////////////////////////////////////////////////////////////////////////// | 630 ////////////////////////////////////////////////////////////////////////////////////////// |
627 | 631 |
628 LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb) | 632 LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var, llvm::BasicBlock* bb) |
629 { | 633 { |
630 std::vector<LLValue*> v(2); | 634 LLSmallVector<LLValue*,2> v(2); |
631 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false); | 635 v[0] = DtoConstUint(i0); |
632 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false); | 636 v[1] = DtoConstUint(i1); |
633 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); | 637 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
634 } | 638 } |
635 | 639 |
636 ////////////////////////////////////////////////////////////////////////////////////////// | 640 ////////////////////////////////////////////////////////////////////////////////////////// |
637 | 641 |
640 // get runtime function | 644 // get runtime function |
641 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT"); | 645 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT"); |
642 // get type info | 646 // get type info |
643 LLConstant* ti = DtoTypeInfoOf(newtype); | 647 LLConstant* ti = DtoTypeInfoOf(newtype); |
644 assert(isaPointer(ti)); | 648 assert(isaPointer(ti)); |
645 // call runtime | 649 // call runtime allocator |
646 LLSmallVector<LLValue*,1> arg; | 650 LLValue* mem = gIR->ir->CreateCall(fn, ti, ".gc_mem"); |
647 arg.push_back(ti); | |
648 // allocate | |
649 LLValue* mem = gIR->ir->CreateCall(fn, arg.begin(), arg.end(), ".gc_mem"); | |
650 // cast | 651 // cast |
651 return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem"); | 652 return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem"); |
652 } | 653 } |
653 | 654 |
654 void DtoDeleteMemory(LLValue* ptr) | 655 void DtoDeleteMemory(LLValue* ptr) |
704 LLConstant* c; | 705 LLConstant* c; |
705 | 706 |
706 // func | 707 // func |
707 const char* fname = msg ? "_d_assert_msg" : "_d_assert"; | 708 const char* fname = msg ? "_d_assert_msg" : "_d_assert"; |
708 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); | 709 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); |
710 | |
711 // param attrs | |
712 llvm::PAListPtr palist; | |
713 int idx = 1; | |
709 | 714 |
710 c = DtoConstString(loc->filename); | 715 c = DtoConstString(loc->filename); |
711 | 716 |
712 // msg param | 717 // msg param |
713 if (msg) | 718 if (msg) |
725 } | 730 } |
726 else | 731 else |
727 { | 732 { |
728 args.push_back(msg->getRVal()); | 733 args.push_back(msg->getRVal()); |
729 } | 734 } |
735 palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal); | |
730 } | 736 } |
731 | 737 |
732 // file param | 738 // file param |
733 llvm::AllocaInst* alloc = gIR->func()->srcfileArg; | 739 llvm::AllocaInst* alloc = gIR->func()->srcfileArg; |
734 if (!alloc) | 740 if (!alloc) |
738 } | 744 } |
739 LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp"); | 745 LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp"); |
740 DtoStore(c->getOperand(0), ptr); | 746 DtoStore(c->getOperand(0), ptr); |
741 ptr = DtoGEPi(alloc, 0,1, "tmp"); | 747 ptr = DtoGEPi(alloc, 0,1, "tmp"); |
742 DtoStore(c->getOperand(1), ptr); | 748 DtoStore(c->getOperand(1), ptr); |
749 | |
743 args.push_back(alloc); | 750 args.push_back(alloc); |
751 palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal); | |
752 | |
744 | 753 |
745 // line param | 754 // line param |
746 c = DtoConstUint(loc->linnum); | 755 c = DtoConstUint(loc->linnum); |
747 args.push_back(c); | 756 args.push_back(c); |
748 | 757 |
749 // call | 758 // call |
750 llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb()); | 759 llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb()); |
760 call->setParamAttrs(palist); | |
751 } | 761 } |
752 | 762 |
753 ////////////////////////////////////////////////////////////////////////////////////////// | 763 ////////////////////////////////////////////////////////////////////////////////////////// |
754 | 764 |
755 static const LLType* get_next_frame_ptr_type(Dsymbol* sc) | 765 static const LLType* get_next_frame_ptr_type(Dsymbol* sc) |