comparison gen/toobj.cpp @ 88:058d3925950e trunk

[svn r92] Fixed support for statically initialized unions. lots of bugfixes as cleanups too.
author lindquist
date Tue, 06 Nov 2007 10:03:14 +0100
parents fd32135dca3e
children ccca1c13e13a
comparison
equal deleted inserted replaced
87:25d4fcce53f4 88:058d3925950e
34 #include "gen/irstate.h" 34 #include "gen/irstate.h"
35 #include "gen/elem.h" 35 #include "gen/elem.h"
36 #include "gen/logger.h" 36 #include "gen/logger.h"
37 #include "gen/tollvm.h" 37 #include "gen/tollvm.h"
38 #include "gen/arrays.h" 38 #include "gen/arrays.h"
39 #include "gen/structs.h"
39 #include "gen/todebug.h" 40 #include "gen/todebug.h"
40 #include "gen/runtime.h" 41 #include "gen/runtime.h"
41 42
42 ////////////////////////////////////////////////////////////////////////////////////////// 43 //////////////////////////////////////////////////////////////////////////////////////////
43 44
285 286
286 if (parent->isModule()) { 287 if (parent->isModule()) {
287 gIR->module->addTypeName(mangle(),ts->llvmType); 288 gIR->module->addTypeName(mangle(),ts->llvmType);
288 } 289 }
289 290
291 llvmUnion = new DUnion; // uses gIR->topstruct()
292
290 // generate static data 293 // generate static data
291 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; 294 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
292 llvm::Constant* _init = 0; 295 llvm::Constant* _init = 0;
293 296
294 // always generate the constant initalizer 297 // always generate the constant initalizer
570 LOG_SCOPE; 573 LOG_SCOPE;
571 llvm::Module* M = gIR->module; 574 llvm::Module* M = gIR->module;
572 575
573 if (aliassym) 576 if (aliassym)
574 { 577 {
578 Logger::println("alias sym");
575 toAlias()->toObjFile(); 579 toAlias()->toObjFile();
576 return; 580 return;
577 } 581 }
578 582
579 // global variable or magic 583 // global variable or magic
606 bool _signed = !type->isunsigned(); 610 bool _signed = !type->isunsigned();
607 611
608 Logger::println("Creating global variable"); 612 Logger::println("Creating global variable");
609 std::string _name(mangle()); 613 std::string _name(mangle());
610 614
611 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M); 615 bool emitRTstaticInit = false;
612 llvmValue = gvar;
613 616
614 if (!(storage_class & STCextern) && (getModule() == gIR->dmodule || istempl)) 617 if (!(storage_class & STCextern) && (getModule() == gIR->dmodule || istempl))
615 { 618 {
616 if (parent && parent->isFuncDeclaration() && init && init->isExpInitializer()) { 619 if (parent && parent->isFuncDeclaration() && init && init->isExpInitializer()) {
617 _init = DtoConstInitializer(t, NULL); 620 _init = DtoConstInitializer(t, NULL);
618 // create a flag to make sure initialization only happens once 621 emitRTstaticInit = true;
619 llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage;
620 std::string gflagname(_name);
621 gflagname.append("__initflag");
622 llvm::GlobalVariable* gflag = new llvm::GlobalVariable(llvm::Type::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,M);
623
624 // check flag and do init if not already done
625 llvm::BasicBlock* oldend = gIR->scopeend();
626 llvm::BasicBlock* initbb = new llvm::BasicBlock("ifnotinit",gIR->topfunc(),oldend);
627 llvm::BasicBlock* endinitbb = new llvm::BasicBlock("ifnotinitend",gIR->topfunc(),oldend);
628 llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false));
629 gIR->ir->CreateCondBr(cond, initbb, endinitbb);
630 gIR->scope() = IRScope(initbb,endinitbb);
631 elem* ie = DtoInitializer(init);
632 if (!ie->inPlace()) {
633 DValue* dst = new DVarValue(t, gvar, true);
634 DtoAssign(dst, ie);
635 delete dst;
636 }
637 gIR->ir->CreateStore(DtoConstBool(true), gflag);
638 gIR->ir->CreateBr(endinitbb);
639 gIR->scope() = IRScope(endinitbb,oldend);
640 } 622 }
641 else { 623 else {
642 _init = DtoConstInitializer(t, init); 624 _init = DtoConstInitializer(t, init);
643 } 625 }
644 626
666 else { 648 else {
667 Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; 649 Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
668 //assert(0); 650 //assert(0);
669 } 651 }
670 } 652 }
671 653 }
672 Logger::cout() << "final init = " << *_init << '\n'; 654
673 gvar->setInitializer(_init); 655 if (_init && _init->getType() != _type)
674 } 656 _type = _init->getType();
657 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,_init,_name,M);
658 llvmValue = gvar;
659
660 if (emitRTstaticInit)
661 DtoLazyStaticInit(istempl, gvar, init, t);
675 662
676 llvmDModule = gIR->dmodule; 663 llvmDModule = gIR->dmodule;
677 664
678 //if (storage_class & STCprivate) 665 //if (storage_class & STCprivate)
679 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility); 666 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility);