comparison gen/tollvm.c @ 4:e116aa1488e6 trunk

[svn r8] changed backend includes to always use the gen/<foo>.h prefix fixed passing string literals as array parameters few other fixes moved some array routines into gen/arrays
author lindquist
date Mon, 03 Sep 2007 17:34:30 +0200
parents c53b6e3fe49a
children 35d93ce68cf4
comparison
equal deleted inserted replaced
3:069cf4b0ec67 4:e116aa1488e6
11 #include "dsymbol.h" 11 #include "dsymbol.h"
12 #include "aggregate.h" 12 #include "aggregate.h"
13 #include "declaration.h" 13 #include "declaration.h"
14 #include "init.h" 14 #include "init.h"
15 15
16 #include "tollvm.h" 16 #include "gen/tollvm.h"
17 #include "irstate.h" 17 #include "gen/irstate.h"
18 #include "logger.h" 18 #include "gen/logger.h"
19 #include "runtime.h" 19 #include "gen/runtime.h"
20 #include "elem.h" 20 #include "gen/elem.h"
21 #include "gen/arrays.h"
21 22
22 const llvm::Type* LLVM_DtoType(Type* t) 23 const llvm::Type* LLVM_DtoType(Type* t)
23 { 24 {
24 assert(t); 25 assert(t);
25 switch (t->ty) 26 switch (t->ty)
310 assert(0); 311 assert(0);
311 std::vector<const llvm::Type*> types; 312 std::vector<const llvm::Type*> types;
312 return llvm::StructType::get(types); 313 return llvm::StructType::get(types);
313 } 314 }
314 315
315 //////////////////////////////////////////////////////////////////////////////////////////
316
317 llvm::StructType* LLVM_DtoArrayType(Type* t)
318 {
319 assert(t->next);
320 const llvm::Type* at = LLVM_DtoType(t->next);
321 const llvm::Type* arrty;
322
323 /*if (t->ty == Tsarray) {
324 TypeSArray* tsa = (TypeSArray*)t;
325 assert(tsa->dim->type->isintegral());
326 arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
327 }
328 else {
329 arrty = llvm::ArrayType::get(at,0);
330 }*/
331 if (at == llvm::Type::VoidTy) {
332 at = llvm::Type::Int8Ty;
333 }
334 arrty = llvm::PointerType::get(at);
335
336 std::vector<const llvm::Type*> members;
337 if (global.params.is64bit)
338 members.push_back(llvm::Type::Int64Ty);
339 else
340 members.push_back(llvm::Type::Int32Ty);
341
342 members.push_back(arrty);
343
344 return llvm::StructType::get(members);
345 }
346
347 //////////////////////////////////////////////////////////////////////////////////////////
348
349 llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t)
350 {
351 if (t->llvmType)
352 return llvm::cast<llvm::ArrayType>(t->llvmType);
353
354 assert(t->ty == Tsarray);
355 assert(t->next);
356
357 const llvm::Type* at = LLVM_DtoType(t->next);
358
359 TypeSArray* tsa = (TypeSArray*)t;
360 assert(tsa->dim->type->isintegral());
361 llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
362
363 tsa->llvmType = arrty;
364 return arrty;
365 }
366 316
367 ////////////////////////////////////////////////////////////////////////////////////////// 317 //////////////////////////////////////////////////////////////////////////////////////////
368 318
369 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false) 319 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false)
370 { 320 {
389 } 339 }
390 340
391 ////////////////////////////////////////////////////////////////////////////////////////// 341 //////////////////////////////////////////////////////////////////////////////////////////
392 342
393 // llvm.memset.i32 343 // llvm.memset.i32
394 static llvm::Function* LLVM_DeclareMemSet32() 344 llvm::Function* LLVM_DeclareMemSet32()
395 { 345 {
396 static llvm::Function* _func = 0; 346 static llvm::Function* _func = 0;
397 if (_func == 0) { 347 if (_func == 0) {
398 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i32", 32, true); 348 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i32", 32, true);
399 } 349 }
400 return _func; 350 return _func;
401 } 351 }
402 352
403 ////////////////////////////////////////////////////////////////////////////////////////// 353 //////////////////////////////////////////////////////////////////////////////////////////
404 354
405 static llvm::Function* LLVM_DeclareMemSet64() 355 llvm::Function* LLVM_DeclareMemSet64()
406 { 356 {
407 static llvm::Function* _func = 0; 357 static llvm::Function* _func = 0;
408 if (_func == 0) { 358 if (_func == 0) {
409 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i64", 64, true); 359 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i64", 64, true);
410 } 360 }
412 } 362 }
413 363
414 ////////////////////////////////////////////////////////////////////////////////////////// 364 //////////////////////////////////////////////////////////////////////////////////////////
415 365
416 // llvm.memcpy.i32 366 // llvm.memcpy.i32
417 static llvm::Function* LLVM_DeclareMemCpy32() 367 llvm::Function* LLVM_DeclareMemCpy32()
418 { 368 {
419 static llvm::Function* _func = 0; 369 static llvm::Function* _func = 0;
420 if (_func == 0) { 370 if (_func == 0) {
421 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i32", 32); 371 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i32", 32);
422 } 372 }
424 } 374 }
425 375
426 ////////////////////////////////////////////////////////////////////////////////////////// 376 //////////////////////////////////////////////////////////////////////////////////////////
427 377
428 // llvm.memcpy.i64 378 // llvm.memcpy.i64
429 static llvm::Function* LLVM_DeclareMemCpy64() 379 llvm::Function* LLVM_DeclareMemCpy64()
430 { 380 {
431 static llvm::Function* _func = 0; 381 static llvm::Function* _func = 0;
432 if (_func == 0) { 382 if (_func == 0) {
433 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64); 383 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64);
434 } 384 }
554 } 504 }
555 505
556 return llvm::ConstantStruct::get(structtype, inits); 506 return llvm::ConstantStruct::get(structtype, inits);
557 } 507 }
558 508
559 ////////////////////////////////////////////////////////////////////////////////////////// 509
560 510
561 llvm::Value* LLVM_DtoNullArray(llvm::Value* v) 511 //////////////////////////////////////////////////////////////////////////////////////////
512
513 llvm::Value* LLVM_DtoNullDelegate(llvm::Value* v)
562 { 514 {
563 assert(gIR); 515 assert(gIR);
564 d_uns64 n = (global.params.is64bit) ? 16 : 8; 516 d_uns64 n = (global.params.is64bit) ? 16 : 8;
565 517
566 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty); 518 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty);
573 llargs[0] = arr; 525 llargs[0] = arr;
574 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); 526 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
575 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); 527 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
576 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 528 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
577 529
578 //Logger::cout() << *fn << '|' << *fn->getType() << '\n';
579 //Logger::cout() << "to null array call: " << *llargs[0] << '|' << *llargs[1] << '|' << *llargs[2] << '|' << *llargs[3] << '\n';
580
581 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
582
583 return ret;
584 }
585
586 //////////////////////////////////////////////////////////////////////////////////////////
587
588 llvm::Value* LLVM_DtoNullDelegate(llvm::Value* v)
589 {
590 assert(gIR);
591 d_uns64 n = (global.params.is64bit) ? 16 : 8;
592
593 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty);
594
595 llvm::Value* arr = new llvm::BitCastInst(v,i8p_ty,"tmp",gIR->scopebb());
596
597 llvm::Function* fn = LLVM_DeclareMemSet32();
598 std::vector<llvm::Value*> llargs;
599 llargs.resize(4);
600 llargs[0] = arr;
601 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
602 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
603 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
604
605 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); 530 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
606 531
607 return ret; 532 return ret;
608 } 533 }
609 534
630 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 555 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
631 556
632 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); 557 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
633 } 558 }
634 559
635 ////////////////////////////////////////////////////////////////////////////////////////// 560
636
637 llvm::Value* LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
638 {
639 assert(gIR);
640 if (dst->getType() == src->getType())
641 {
642 d_uns64 n = (global.params.is64bit) ? 16 : 8;
643
644 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
645
646 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
647 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
648
649 llvm::Function* fn = LLVM_DeclareMemCpy32();
650 std::vector<llvm::Value*> llargs;
651 llargs.resize(4);
652 llargs[0] = dstarr;
653 llargs[1] = srcarr;
654 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
655 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
656
657 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
658 }
659 else
660 {
661 if (!llvm::isa<llvm::ArrayType>(src->getType()->getContainedType(0)))
662 {
663 Logger::cout() << "invalid: " << *src << '\n';
664 assert(0);
665 }
666 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(src->getType()->getContainedType(0));
667 llvm::Type* dstty = llvm::PointerType::get(arrty->getElementType());
668
669 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
670 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
671
672 llvm::Value* dstlen = new llvm::GetElementPtrInst(dst,zero,zero,"tmp",gIR->scopebb());
673 llvm::Value* srclen = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
674 new llvm::StoreInst(srclen, dstlen, gIR->scopebb());
675
676 llvm::Value* dstptr = new llvm::GetElementPtrInst(dst,zero,one,"tmp",gIR->scopebb());
677 llvm::Value* srcptr = new llvm::BitCastInst(src,dstty,"tmp",gIR->scopebb());
678 new llvm::StoreInst(srcptr, dstptr, gIR->scopebb());
679 }
680 }
681
682 //////////////////////////////////////////////////////////////////////////////////////////
683
684 void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r)
685 {
686 const llvm::PointerType* ptrty = llvm::cast<llvm::PointerType>(l->getType());
687 if (llvm::isa<llvm::ArrayType>(ptrty->getContainedType(0)))
688 {
689 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(ptrty->getContainedType(0));
690 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
691
692 std::vector<llvm::Value*> args;
693 args.resize(3);
694 args[0] = new llvm::GetElementPtrInst(l,zero,zero,"tmp",gIR->scopebb());
695 args[1] = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
696 args[2] = r;
697
698 const char* funcname = NULL;
699
700 if (llvm::isa<llvm::PointerType>(arrty->getElementType())) {
701 funcname = "_d_array_init_pointer";
702
703 const llvm::Type* dstty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
704 if (args[0]->getType() != dstty)
705 args[0] = new llvm::BitCastInst(args[0],dstty,"tmp",gIR->scopebb());
706
707 const llvm::Type* valty = llvm::PointerType::get(llvm::Type::Int8Ty);
708 if (args[2]->getType() != valty)
709 args[2] = new llvm::BitCastInst(args[2],valty,"tmp",gIR->scopebb());
710 }
711 else if (r->getType() == llvm::Type::Int1Ty) {
712 funcname = "_d_array_init_i1";
713 }
714 else if (r->getType() == llvm::Type::Int8Ty) {
715 funcname = "_d_array_init_i8";
716 }
717 else if (r->getType() == llvm::Type::Int16Ty) {
718 funcname = "_d_array_init_i16";
719 }
720 else if (r->getType() == llvm::Type::Int32Ty) {
721 funcname = "_d_array_init_i32";
722 }
723 else if (r->getType() == llvm::Type::Int64Ty) {
724 funcname = "_d_array_init_i64";
725 }
726 else if (r->getType() == llvm::Type::FloatTy) {
727 funcname = "_d_array_init_float";
728 }
729 else if (r->getType() == llvm::Type::DoubleTy) {
730 funcname = "_d_array_init_double";
731 }
732 else {
733 assert(0);
734 }
735
736 Logger::cout() << *args[0] << '|' << *args[2] << '\n';
737
738 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
739 assert(fn);
740 llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb());
741 call->setCallingConv(llvm::CallingConv::C);
742
743 Logger::println("array init call ok");
744 }
745 else if (llvm::isa<llvm::StructType>(ptrty->getContainedType(0)))
746 {
747 assert(0 && "Only static arrays support initialisers atm");
748 }
749 else
750 assert(0);
751 }
752
753 //////////////////////////////////////////////////////////////////////////////////////////
754
755 void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr)
756 {
757 const llvm::StructType* st = llvm::cast<llvm::StructType>(arr->getType()->getContainedType(0));
758 //const llvm::PointerType* pt = llvm::cast<llvm::PointerType>(r->getType());
759
760 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
761 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
762
763 llvm::Value* arrdim = new llvm::GetElementPtrInst(arr,zero,zero,"tmp",gIR->scopebb());
764 new llvm::StoreInst(dim, arrdim, gIR->scopebb());
765
766 llvm::Value* arrptr = new llvm::GetElementPtrInst(arr,zero,one,"tmp",gIR->scopebb());
767 new llvm::StoreInst(ptr, arrptr, gIR->scopebb());
768 }
769
770 //////////////////////////////////////////////////////////////////////////////////////////
771 llvm::Constant* LLVM_DtoArrayInitializer(ArrayInitializer* arrinit)
772 {
773 Logger::println("arr init begin");
774 assert(arrinit->type->ty == Tsarray);
775 TypeSArray* t = (TypeSArray*)arrinit->type;
776 integer_t tdim = t->dim->toInteger();
777
778 std::vector<llvm::Constant*> inits(tdim, 0);
779
780 const llvm::Type* elemty = LLVM_DtoType(arrinit->type->next);
781
782 assert(arrinit->index.dim == arrinit->value.dim);
783 for (int i=0,j=0; i < tdim; ++i)
784 {
785 Initializer* init = 0;
786 Expression* idx = (Expression*)arrinit->index.data[j];
787
788 if (idx)
789 {
790 integer_t k = idx->toInteger();
791 if (i == k)
792 {
793 init = (Initializer*)arrinit->value.data[j];
794 assert(init);
795 ++j;
796 }
797 }
798 else
799 {
800 init = (Initializer*)arrinit->value.data[j];
801 ++j;
802 }
803
804 llvm::Constant* v = 0;
805
806 if (!init)
807 {
808 elem* e = t->next->defaultInit()->toElem(gIR);
809 v = llvm::cast<llvm::Constant>(e->val);
810 delete e;
811 }
812 else if (ExpInitializer* ex = init->isExpInitializer())
813 {
814 elem* e = ex->exp->toElem(gIR);
815 v = llvm::cast<llvm::Constant>(e->val);
816 delete e;
817 }
818 else if (StructInitializer* si = init->isStructInitializer())
819 {
820 v = LLVM_DtoStructInitializer(si);
821 }
822 else if (ArrayInitializer* ai = init->isArrayInitializer())
823 {
824 v = LLVM_DtoArrayInitializer(ai);
825 }
826 else if (init->isVoidInitializer())
827 {
828 v = llvm::UndefValue::get(elemty);
829 }
830 else
831 assert(v);
832
833 inits[i] = v;
834 }
835
836 llvm::ArrayType* arrty = LLVM_DtoStaticArrayType(t);
837 return llvm::ConstantArray::get(arrty, inits);
838 }
839
840 //////////////////////////////////////////////////////////////////////////////////////////
841 void LLVM_DtoArrayCopy(elem* dst, elem* src)
842 {
843 assert(0);
844 }
845 561
846 ////////////////////////////////////////////////////////////////////////////////////////// 562 //////////////////////////////////////////////////////////////////////////////////////////
847 563
848 llvm::GlobalValue::LinkageTypes LLVM_DtoLinkage(PROT prot, uint stc) 564 llvm::GlobalValue::LinkageTypes LLVM_DtoLinkage(PROT prot, uint stc)
849 { 565 {