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)