comparison gen/llvmhelpers.cpp @ 797:340acf1535d0

Removed KDevelop3 project files, CMake can generate them just fine! Fixed function literals in static initializers. Changed alignment of delegates from 2*PTRSIZE to just PTRSIZE. Changed errors to go to stderr instead of stdout. Fairly major rewriting of struct/union/class handling, STILL A BIT BUGGY !!!
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sat, 29 Nov 2008 21:25:43 +0100
parents 6e7a4c3b64d2
children 92ea3015ace6
comparison
equal deleted inserted replaced
796:6e7a4c3b64d2 797:340acf1535d0
336 LLValue* ctx = 0; 336 LLValue* ctx = 0;
337 if (irfunc->decl->isMember2()) 337 if (irfunc->decl->isMember2())
338 { 338 {
339 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration(); 339 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
340 LLValue* val = DtoLoad(irfunc->thisArg); 340 LLValue* val = DtoLoad(irfunc->thisArg);
341 ctx = DtoLoad(DtoGEPi(val, 0,2+cd->vthis->ir.irField->index, ".vthis")); 341 ctx = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
342 } 342 }
343 else 343 else
344 ctx = irfunc->nestArg; 344 ctx = irfunc->nestArg;
345 assert(ctx); 345 assert(ctx);
346 346
372 { 372 {
373 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration(); 373 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
374 if (!cd || !cd->vthis) 374 if (!cd || !cd->vthis)
375 return getNullPtr(getVoidPtrType()); 375 return getNullPtr(getVoidPtrType());
376 LLValue* val = DtoLoad(irfunc->thisArg); 376 LLValue* val = DtoLoad(irfunc->thisArg);
377 return DtoLoad(DtoGEPi(val, 0,2+cd->vthis->ir.irField->index, ".vthis")); 377 return DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
378 } 378 }
379 else 379 else
380 { 380 {
381 return getNullPtr(getVoidPtrType()); 381 return getNullPtr(getVoidPtrType());
382 } 382 }
962 void DtoConstInitGlobal(VarDeclaration* vd) 962 void DtoConstInitGlobal(VarDeclaration* vd)
963 { 963 {
964 if (vd->ir.initialized) return; 964 if (vd->ir.initialized) return;
965 vd->ir.initialized = gIR->dmodule; 965 vd->ir.initialized = gIR->dmodule;
966 966
967 Logger::println("* DtoConstInitGlobal(%s)", vd->toChars()); 967 Logger::println("DtoConstInitGlobal(%s) @ %s", vd->toChars(), vd->locToChars());
968 LOG_SCOPE; 968 LOG_SCOPE;
969 969
970 bool emitRTstaticInit = false; 970 // if the variable is a function local static variable with a runtime initializer
971 971 // we must do lazy initialization, which involves a boolean flag to make sure it happens only once
972 LLConstant* _init = 0; 972 // FIXME: I don't think it's thread safe ...
973 if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) { 973
974 _init = DtoConstInitializer(vd->loc, vd->type, NULL); 974 bool doLazyInit = false;
975 emitRTstaticInit = true; 975 Dsymbol* par = vd->toParent2();
976 } 976
977 else { 977 if (par && par->isFuncDeclaration() && vd->init)
978 _init = DtoConstInitializer(vd->loc, vd->type, vd->init); 978 {
979 } 979 if (ExpInitializer* einit = vd->init->isExpInitializer())
980 980 {
981 const LLType* _type = DtoType(vd->type); 981 if (!einit->exp->isConst())
982 Type* t = vd->type->toBasetype(); 982 {
983 983 // mark as needing lazy now
984 //Logger::cout() << "initializer: " << *_init << '\n'; 984 doLazyInit = true;
985 if (_type != _init->getType()) { 985 }
986 if (Logger::enabled()) 986 }
987 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; 987 }
988 988
989 // zero initalizer 989 // if we do lazy init, we start out with an undefined initializer
990 if (_init->isNullValue()) 990 LLConstant* initVal;
991 _init = llvm::Constant::getNullValue(_type); 991 if (doLazyInit)
992 // pointer to global constant (struct.init) 992 {
993 else if (llvm::isa<llvm::GlobalVariable>(_init)) 993 initVal = llvm::UndefValue::get(DtoType(vd->type));
994 { 994 }
995 assert(_init->getType()->getContainedType(0) == _type); 995 // otherwise we build it
996 llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init); 996 else
997 assert(t->ty == Tstruct); 997 {
998 TypeStruct* ts = (TypeStruct*)t; 998 initVal = DtoConstInitializer(vd->loc, vd->type, vd->init);
999 assert(ts->sym->ir.irStruct->constInit); 999 }
1000 _init = ts->sym->ir.irStruct->constInit; 1000
1001 } 1001 // set the initializer if appropriate
1002 // array single value init 1002 IrGlobal* glob = vd->ir.irGlobal;
1003 else if (isaArray(_type)) 1003 llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(glob->value);
1004 { 1004
1005 _init = DtoConstStaticArray(_type, _init); 1005 // refine the global's opaque type to the type of the initializer
1006 } 1006 llvm::cast<LLOpaqueType>(glob->type.get())->refineAbstractTypeTo(initVal->getType());
1007 else { 1007
1008 if (Logger::enabled()) 1008 glob->constInit = initVal;
1009 Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
1010 //assert(0);
1011 }
1012 }
1013 1009
1014 bool istempl = false; 1010 bool istempl = false;
1015 if ((vd->storage_class & STCcomdat) || (vd->parent && DtoIsTemplateInstance(vd->parent))) { 1011 if ((vd->storage_class & STCcomdat) || (vd->parent && DtoIsTemplateInstance(vd->parent))) {
1016 istempl = true; 1012 istempl = true;
1017 } 1013 }
1018 1014
1019 if (_init && _init->getType() != _type) 1015 // assign the initializer
1020 _type = _init->getType(); 1016 llvm::GlobalVariable* globalvar = llvm::cast<llvm::GlobalVariable>(glob->value);
1021 llvm::cast<LLOpaqueType>(vd->ir.irGlobal->type.get())->refineAbstractTypeTo(_type); 1017
1022 _type = vd->ir.irGlobal->type.get();
1023
1024 llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->ir.irGlobal->value);
1025 if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl)) 1018 if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
1026 { 1019 {
1027 if (Logger::enabled()) 1020 if (Logger::enabled())
1028 { 1021 {
1029 Logger::println("setting initializer"); 1022 Logger::println("setting initializer");
1030 Logger::cout() << "global: " << *gvar << '\n'; 1023 Logger::cout() << "global: " << *gvar << '\n';
1031 Logger::cout() << "init: " << *_init << '\n'; 1024 Logger::cout() << "init: " << *initVal << '\n';
1032 } 1025 }
1033 gvar->setInitializer(_init); 1026
1027 gvar->setInitializer(initVal);
1028
1034 // do debug info 1029 // do debug info
1035 if (global.params.symdebug) 1030 if (global.params.symdebug)
1036 { 1031 {
1037 LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd); 1032 LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd);
1038 // keep a reference so GDCE doesn't delete it ! 1033 // keep a reference so GDCE doesn't delete it !
1039 gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType())); 1034 gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType()));
1040 } 1035 }
1041 } 1036 }
1042 1037
1043 if (emitRTstaticInit) 1038 if (doLazyInit)
1044 DtoLazyStaticInit(istempl, gvar, vd->init, t); 1039 DtoLazyStaticInit(istempl, gvar, vd->init, vd->type);
1045 } 1040 }
1046 1041
1047 ////////////////////////////////////////////////////////////////////////////////////////// 1042 //////////////////////////////////////////////////////////////////////////////////////////
1048 1043
1049 void DtoEmptyResolveList() 1044 void DtoEmptyResolveList()
1394 /****************************************************************************************/ 1389 /****************************************************************************************/
1395 /*//////////////////////////////////////////////////////////////////////////////////////// 1390 /*////////////////////////////////////////////////////////////////////////////////////////
1396 // INITIALIZER HELPERS 1391 // INITIALIZER HELPERS
1397 ////////////////////////////////////////////////////////////////////////////////////////*/ 1392 ////////////////////////////////////////////////////////////////////////////////////////*/
1398 1393
1399 LLConstant* DtoConstInitializer(Loc& loc, Type* type, Initializer* init) 1394 LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
1400 { 1395 {
1401 LLConstant* _init = 0; // may return zero 1396 LLConstant* _init = 0; // may return zero
1402 if (!init) 1397 if (!init)
1403 { 1398 {
1404 Logger::println("const default initializer for %s", type->toChars()); 1399 Logger::println("const default initializer for %s", type->toChars());
1405 _init = DtoDefaultInit(loc, type); 1400 _init = DtoConstExpInit(loc, type, type->defaultInit());
1406 } 1401 }
1407 else if (ExpInitializer* ex = init->isExpInitializer()) 1402 else if (ExpInitializer* ex = init->isExpInitializer())
1408 { 1403 {
1409 Logger::println("const expression initializer"); 1404 Logger::println("const expression initializer");
1410 _init = ex->exp->toConstElem(gIR); 1405 _init = DtoConstExpInit(loc, type, ex->exp);;
1411 } 1406 }
1412 else if (StructInitializer* si = init->isStructInitializer()) 1407 else if (StructInitializer* si = init->isStructInitializer())
1413 { 1408 {
1414 Logger::println("const struct initializer"); 1409 Logger::println("const struct initializer");
1415 _init = DtoConstStructInitializer(si); 1410 _init = DtoConstStructInitializer(si);
1431 return _init; 1426 return _init;
1432 } 1427 }
1433 1428
1434 ////////////////////////////////////////////////////////////////////////////////////////// 1429 //////////////////////////////////////////////////////////////////////////////////////////
1435 1430
1436 LLConstant* DtoConstFieldInitializer(Loc& loc, Type* t, Initializer* init) 1431 LLConstant* DtoConstFieldInitializer(Loc loc, Type* t, Initializer* init)
1437 { 1432 {
1438 Logger::println("DtoConstFieldInitializer"); 1433 Logger::println("DtoConstFieldInitializer");
1439 LOG_SCOPE; 1434 LOG_SCOPE;
1440 1435
1441 const LLType* _type = DtoType(t); 1436 const LLType* _type = DtoType(t);
1528 1523
1529 ////////////////////////////////////////////////////////////////////////////////////////// 1524 //////////////////////////////////////////////////////////////////////////////////////////
1530 1525
1531 static LLConstant* expand_to_sarray(Type *base, Expression* exp) 1526 static LLConstant* expand_to_sarray(Type *base, Expression* exp)
1532 { 1527 {
1533 Logger::println("building type %s to expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars()); 1528 Logger::println("building type %s from expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars());
1534 const LLType* dstTy = DtoType(base); 1529 const LLType* dstTy = DtoType(base);
1535 if (Logger::enabled()) 1530 if (Logger::enabled())
1536 Logger::cout() << "final llvm type requested: " << *dstTy << '\n'; 1531 Logger::cout() << "final llvm type requested: " << *dstTy << '\n';
1537 1532
1538 LLConstant* val = exp->toConstElem(gIR); 1533 LLConstant* val = exp->toConstElem(gIR);
1539 1534
1540 Type* expbase = exp->type->toBasetype(); 1535 Type* expbase = exp->type->toBasetype();
1541 Type* t = base; 1536 Logger::println("expbase: %s", expbase->toChars());
1542 1537 Type* t = base->toBasetype();
1538
1543 LLSmallVector<size_t, 4> dims; 1539 LLSmallVector<size_t, 4> dims;
1544 1540
1541 // handle zero initializers
1542 if (expbase->isintegral() && exp->isConst())
1543 {
1544 if (!exp->toInteger())
1545 return LLConstant::getNullValue(dstTy);
1546 }
1547 else if (exp->op == TOKnull)
1548 {
1549 return LLConstant::getNullValue(dstTy);
1550 }
1551
1545 while(1) 1552 while(1)
1546 { 1553 {
1554 Logger::println("t: %s", t->toChars());
1547 if (t->equals(expbase)) 1555 if (t->equals(expbase))
1548 break; 1556 break;
1549 assert(t->ty == Tsarray); 1557 assert(t->ty == Tsarray);
1550 TypeSArray* tsa = (TypeSArray*)t; 1558 TypeSArray* tsa = (TypeSArray*)t;
1551 dims.push_back(tsa->dim->toInteger()); 1559 dims.push_back(tsa->dim->toInteger());
1552 assert(t->nextOf()); 1560 assert(t->nextOf());
1553 t = t->nextOf()->toBasetype(); 1561 t = t->nextOf()->toBasetype();
1554 } 1562 }
1555 1563
1556 size_t i = dims.size(); 1564 size_t i = dims.size();
1557 assert(i); 1565 assert(i);
1558 1566
1559 std::vector<LLConstant*> inits; 1567 std::vector<LLConstant*> inits;
1560 while (i--) 1568 while (i--)
1562 const LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]); 1570 const LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]);
1563 inits.clear(); 1571 inits.clear();
1564 inits.insert(inits.end(), dims[i], val); 1572 inits.insert(inits.end(), dims[i], val);
1565 val = LLConstantArray::get(arrty, inits); 1573 val = LLConstantArray::get(arrty, inits);
1566 } 1574 }
1567 1575
1568 return val; 1576 return val;
1569 } 1577 }
1570 1578
1571 LLConstant* DtoDefaultInit(Loc& loc, Type* type) 1579 LLConstant* DtoConstExpInit(Loc loc, Type* type, Expression* exp)
1572 { 1580 {
1573 Expression* exp = type->defaultInit();
1574
1575 Type* expbase = exp->type->toBasetype(); 1581 Type* expbase = exp->type->toBasetype();
1576 Type* base = type->toBasetype(); 1582 Type* base = type->toBasetype();
1577 1583
1578 // if not the same basetypes, we won't get the same llvm types either 1584 // if not the same basetypes, we won't get the same llvm types either
1579 if (!expbase->equals(base)) 1585 if (!expbase->equals(base))
1580 { 1586 {
1581 if (base->ty == Tsarray) 1587 if (base->ty == Tsarray)
1582 { 1588 {
1583 if (base->nextOf()->toBasetype()->ty == Tvoid) { 1589 if (base->nextOf()->toBasetype()->ty == Tvoid) {
1584 error(loc, "static arrays of voids have no default initializer"); 1590 error(loc, "static arrays of voids have no default initializer");
1585 fatal(); 1591 fatal();
1586 } 1592 }
1587
1588 Logger::println("type is a static array, building constant array initializer to single value"); 1593 Logger::println("type is a static array, building constant array initializer to single value");
1589 return expand_to_sarray(base, exp); 1594 return expand_to_sarray(base, exp);
1590 } 1595 }
1591 else 1596 else
1592 { 1597 {
1593 error("cannot yet convert default initializer %s to type %s to %s", exp->toChars(), exp->type->toChars(), type->toChars()); 1598 error("cannot yet convert default initializer %s to type %s to %s", exp->toChars(), exp->type->toChars(), type->toChars());
1594 fatal(); 1599 fatal();
1595 } 1600 }
1596 assert(0); 1601 assert(0);
1597 1602 }
1598 } 1603
1599
1600 return exp->toConstElem(gIR); 1604 return exp->toConstElem(gIR);
1601 } 1605 }
1602 1606
1603 1607
1604 ////////////////////////////////////////////////////////////////////////////////////////// 1608 //////////////////////////////////////////////////////////////////////////////////////////
1613 if (*p == '"') 1617 if (*p == '"')
1614 *p = '\''; 1618 *p = '\'';
1615 ++p; 1619 ++p;
1616 } 1620 }
1617 // create a noop with the code as the result name! 1621 // create a noop with the code as the result name!
1622 // FIXME: this is const folded and eliminated immediately ... :/
1618 gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str()); 1623 gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str());
1619 } 1624 }
1620 1625
1621 ////////////////////////////////////////////////////////////////////////////////////////// 1626 //////////////////////////////////////////////////////////////////////////////////////////
1622 1627