Mercurial > projects > ldc
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 |