comparison gen/tollvm.cpp @ 102:027b8d8b71ec trunk

[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up. Basically it tries to do the following in order: Resolve types, Declare symbols, Create constant initializers, Apply initializers, Generate functions bodies. ClassInfo is now has the most useful(biased?) members working. Probably other stuf...
author lindquist
date Sun, 18 Nov 2007 06:52:57 +0100
parents 5071469303d4
children 855adfdb8d38
comparison
equal deleted inserted replaced
101:169fda3a77d4 102:027b8d8b71ec
15 #include "gen/arrays.h" 15 #include "gen/arrays.h"
16 #include "gen/dvalue.h" 16 #include "gen/dvalue.h"
17 #include "gen/functions.h" 17 #include "gen/functions.h"
18 #include "gen/structs.h" 18 #include "gen/structs.h"
19 #include "gen/classes.h" 19 #include "gen/classes.h"
20 #include "gen/typeinf.h"
20 21
21 bool DtoIsPassedByRef(Type* type) 22 bool DtoIsPassedByRef(Type* type)
22 { 23 {
23 TY t = DtoDType(type)->ty; 24 TY t = DtoDType(type)->ty;
24 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray); 25 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray);
112 } 113 }
113 114
114 // forward declaration 115 // forward declaration
115 TypeStruct* ts = (TypeStruct*)t; 116 TypeStruct* ts = (TypeStruct*)t;
116 assert(ts->sym); 117 assert(ts->sym);
117 ts->sym->toObjFile(); 118 DtoResolveDsymbol(ts->sym);
118 } 119 }
119 return t->llvmType->get(); 120 return t->llvmType->get();
120 } 121 }
121 122
122 case Tclass: { 123 case Tclass: {
135 } 136 }
136 137
137 // forward declaration 138 // forward declaration
138 TypeClass* tc = (TypeClass*)t; 139 TypeClass* tc = (TypeClass*)t;
139 assert(tc->sym); 140 assert(tc->sym);
140 tc->sym->toObjFile(); 141 DtoResolveDsymbol(tc->sym);
141 } 142 }
142 return llvm::PointerType::get(t->llvmType->get()); 143 return llvm::PointerType::get(t->llvmType->get());
143 } 144 }
144 145
145 // functions 146 // functions
652 653
653 std::vector<llvm::Value*> llargs; 654 std::vector<llvm::Value*> llargs;
654 llargs.resize(3); 655 llargs.resize(3);
655 llargs[0] = cond ? DtoBoolean(cond) : llvm::ConstantInt::getFalse(); 656 llargs[0] = cond ? DtoBoolean(cond) : llvm::ConstantInt::getFalse();
656 llargs[1] = DtoConstUint(loc->linnum); 657 llargs[1] = DtoConstUint(loc->linnum);
657 llargs[2] = msg ? msg->getRVal() : llvm::Constant::getNullValue(fnt->getParamType(2)); 658 if (msg)
659 llargs[2] = msg->getRVal();
660 else {
661 llvm::Constant* c = DtoConstSlice(DtoConstSize_t(0), DtoConstNullPtr(llvm::Type::Int8Ty));
662 static llvm::AllocaInst* alloc = 0;
663 if (!alloc || alloc->getParent()->getParent() != gIR->func()->func) {
664 alloc = new llvm::AllocaInst(c->getType(), "assertnullparam", gIR->topallocapoint());
665 DtoSetArrayToNull(alloc);
666 }
667 llargs[2] = alloc;
668 }
658 669
659 assert(fn); 670 assert(fn);
660 llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); 671 llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
661 call->setCallingConv(llvm::CallingConv::C); 672 call->setCallingConv(llvm::CallingConv::C);
662 } 673 }
859 else if (DSliceValue* s = rhs->isSlice()) { 870 else if (DSliceValue* s = rhs->isSlice()) {
860 DtoSetArray(lhs->getLVal(),s->len,s->ptr); 871 DtoSetArray(lhs->getLVal(),s->len,s->ptr);
861 } 872 }
862 // null 873 // null
863 else if (rhs->isNull()) { 874 else if (rhs->isNull()) {
864 DtoNullArray(lhs->getLVal()); 875 DtoSetArrayToNull(lhs->getLVal());
865 } 876 }
866 // reference assignment 877 // reference assignment
867 else { 878 else {
868 DtoArrayAssign(lhs->getLVal(), rhs->getRVal()); 879 DtoArrayAssign(lhs->getLVal(), rhs->getRVal());
869 } 880 }
1028 assert(to->ty == Tclass || to->ty == Tpointer); 1039 assert(to->ty == Tclass || to->ty == Tpointer);
1029 llvm::Value* rval = new llvm::BitCastInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); 1040 llvm::Value* rval = new llvm::BitCastInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
1030 return new DImValue(_to, rval); 1041 return new DImValue(_to, rval);
1031 } 1042 }
1032 1043
1033 DValue* DtoCastArray(DValue* u, Type* to)
1034 {
1035 const llvm::Type* tolltype = DtoType(to);
1036
1037 Type* totype = DtoDType(to);
1038 Type* fromtype = DtoDType(u->getType());
1039 assert(fromtype->ty == Tarray || fromtype->ty == Tsarray);
1040
1041 llvm::Value* rval;
1042 llvm::Value* rval2;
1043 bool isslice = false;
1044
1045 Logger::cout() << "from array or sarray" << '\n';
1046 if (totype->ty == Tpointer) {
1047 Logger::cout() << "to pointer" << '\n';
1048 assert(fromtype->next == totype->next || totype->next->ty == Tvoid);
1049 llvm::Value* ptr = DtoGEPi(u->getRVal(),0,1,"tmp",gIR->scopebb());
1050 rval = new llvm::LoadInst(ptr, "tmp", gIR->scopebb());
1051 if (fromtype->next != totype->next)
1052 rval = gIR->ir->CreateBitCast(rval, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp");
1053 }
1054 else if (totype->ty == Tarray) {
1055 Logger::cout() << "to array" << '\n';
1056 const llvm::Type* ptrty = DtoType(totype->next);
1057 if (ptrty == llvm::Type::VoidTy)
1058 ptrty = llvm::Type::Int8Ty;
1059 ptrty = llvm::PointerType::get(ptrty);
1060
1061 const llvm::Type* ety = DtoType(fromtype->next);
1062 if (ety == llvm::Type::VoidTy)
1063 ety = llvm::Type::Int8Ty;
1064
1065 if (DSliceValue* usl = u->isSlice()) {
1066 Logger::println("from slice");
1067 rval = new llvm::BitCastInst(usl->ptr, ptrty, "tmp", gIR->scopebb());
1068 if (fromtype->next->size() == totype->next->size())
1069 rval2 = usl->len;
1070 else
1071 rval2 = DtoArrayCastLength(usl->len, ety, ptrty->getContainedType(0));
1072 }
1073 else {
1074 llvm::Value* uval = u->getRVal();
1075 if (fromtype->ty == Tsarray) {
1076 Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
1077 assert(isaPointer(uval->getType()));
1078 const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
1079 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
1080 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
1081 rval = new llvm::BitCastInst(uval, ptrty, "tmp", gIR->scopebb());
1082 }
1083 else {
1084 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1085 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
1086 rval2 = DtoGEP(uval,zero,zero,"tmp",gIR->scopebb());
1087 rval2 = new llvm::LoadInst(rval2, "tmp", gIR->scopebb());
1088 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
1089
1090 rval = DtoGEP(uval,zero,one,"tmp",gIR->scopebb());
1091 rval = new llvm::LoadInst(rval, "tmp", gIR->scopebb());
1092 //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n';
1093 rval = new llvm::BitCastInst(rval, ptrty, "tmp", gIR->scopebb());
1094 }
1095 }
1096 isslice = true;
1097 }
1098 else if (totype->ty == Tsarray) {
1099 Logger::cout() << "to sarray" << '\n';
1100 assert(0);
1101 }
1102 else {
1103 assert(0);
1104 }
1105
1106 if (isslice) {
1107 Logger::println("isslice");
1108 return new DSliceValue(to, rval2, rval);
1109 }
1110
1111 return new DImValue(to, rval);
1112 }
1113
1114 DValue* DtoCast(DValue* val, Type* to) 1044 DValue* DtoCast(DValue* val, Type* to)
1115 { 1045 {
1116 Type* fromtype = DtoDType(val->getType()); 1046 Type* fromtype = DtoDType(val->getType());
1117 if (fromtype->isintegral()) { 1047 if (fromtype->isintegral()) {
1118 return DtoCastInt(val, to); 1048 return DtoCastInt(val, to);
1174 llvm::GlobalVariable* gvar = new llvm::GlobalVariable( 1104 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(
1175 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module); 1105 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module);
1176 if (section) gvar->setSection(section); 1106 if (section) gvar->setSection(section);
1177 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; 1107 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
1178 return llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); 1108 return llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
1109 }
1110
1111 //////////////////////////////////////////////////////////////////////////////////////////
1112
1113 llvm::Constant* DtoConstNullPtr(const llvm::Type* t)
1114 {
1115 return llvm::ConstantPointerNull::get(
1116 llvm::PointerType::get(t)
1117 );
1179 } 1118 }
1180 1119
1181 ////////////////////////////////////////////////////////////////////////////////////////// 1120 //////////////////////////////////////////////////////////////////////////////////////////
1182 1121
1183 void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes) 1122 void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes)
1319 gIR->scope() = IRScope(endinitbb,oldend); 1258 gIR->scope() = IRScope(endinitbb,oldend);
1320 } 1259 }
1321 1260
1322 ////////////////////////////////////////////////////////////////////////////////////////// 1261 //////////////////////////////////////////////////////////////////////////////////////////
1323 1262
1263 void DtoResolveDsymbol(Dsymbol* dsym)
1264 {
1265 if (StructDeclaration* sd = dsym->isStructDeclaration()) {
1266 DtoResolveStruct(sd);
1267 }
1268 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
1269 DtoResolveClass(cd);
1270 }
1271 else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
1272 DtoResolveFunction(fd);
1273 }
1274 else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
1275 DtoResolveTypeInfo(fd);
1276 }
1277 else {
1278 error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
1279 assert(0 && "unsupported dsymbol for DtoResolveDsymbol");
1280 }
1281 }
1282
1283 //////////////////////////////////////////////////////////////////////////////////////////
1284
1285 void DtoDeclareDsymbol(Dsymbol* dsym)
1286 {
1287 if (StructDeclaration* sd = dsym->isStructDeclaration()) {
1288 DtoDeclareStruct(sd);
1289 }
1290 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
1291 DtoDeclareClass(cd);
1292 }
1293 else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
1294 DtoDeclareFunction(fd);
1295 }
1296 else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
1297 DtoDeclareTypeInfo(fd);
1298 }
1299 else {
1300 error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
1301 assert(0 && "unsupported dsymbol for DtoDeclareDsymbol");
1302 }
1303 }
1304
1305 //////////////////////////////////////////////////////////////////////////////////////////
1306
1307 void DtoConstInitDsymbol(Dsymbol* dsym)
1308 {
1309 if (StructDeclaration* sd = dsym->isStructDeclaration()) {
1310 DtoConstInitStruct(sd);
1311 }
1312 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
1313 DtoConstInitClass(cd);
1314 }
1315 else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
1316 DtoConstInitTypeInfo(fd);
1317 }
1318 else if (VarDeclaration* vd = dsym->isVarDeclaration()) {
1319 DtoConstInitGlobal(vd);
1320 }
1321 else {
1322 error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
1323 assert(0 && "unsupported dsymbol for DtoConstInitDsymbol");
1324 }
1325 }
1326
1327 //////////////////////////////////////////////////////////////////////////////////////////
1328
1324 void DtoDefineDsymbol(Dsymbol* dsym) 1329 void DtoDefineDsymbol(Dsymbol* dsym)
1325 { 1330 {
1326 if (StructDeclaration* sd = dsym->isStructDeclaration()) { 1331 if (StructDeclaration* sd = dsym->isStructDeclaration()) {
1327 DtoDefineStruct(sd); 1332 DtoDefineStruct(sd);
1328 } 1333 }
1329 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { 1334 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
1330 DtoDefineClass(cd); 1335 DtoDefineClass(cd);
1331 } 1336 }
1332 else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { 1337 else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
1333 DtoDefineFunc(fd); 1338 DtoDefineFunc(fd);
1339 }
1340 else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
1341 DtoDefineTypeInfo(fd);
1334 } 1342 }
1335 else { 1343 else {
1336 error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars()); 1344 error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
1337 assert(0 && "unsupported dsymbol for DtoDefineDsymbol"); 1345 assert(0 && "unsupported dsymbol for DtoDefineDsymbol");
1338 } 1346 }
1339 } 1347 }
1340 1348
1341 ////////////////////////////////////////////////////////////////////////////////////////// 1349 //////////////////////////////////////////////////////////////////////////////////////////
1342 1350
1343 void DtoConstInitDsymbol(Dsymbol* dsym)
1344 {
1345 if (StructDeclaration* sd = dsym->isStructDeclaration()) {
1346 DtoConstInitStruct(sd);
1347 }
1348 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
1349 DtoConstInitClass(cd);
1350 }
1351 else if (VarDeclaration* vd = dsym->isVarDeclaration()) {
1352 DtoConstInitGlobal(vd);
1353 }
1354 else {
1355 error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
1356 assert(0 && "unsupported dsymbol for DtoInitDsymbol");
1357 }
1358 }
1359
1360 //////////////////////////////////////////////////////////////////////////////////////////
1361
1362 void DtoConstInitGlobal(VarDeclaration* vd) 1351 void DtoConstInitGlobal(VarDeclaration* vd)
1363 { 1352 {
1364 Logger::println("DtoConstInitGlobal(%s)", vd->toChars()); 1353 if (vd->llvmInitialized) return;
1354 vd->llvmInitialized = gIR->dmodule;
1355
1356 Logger::println("* DtoConstInitGlobal(%s)", vd->toChars());
1365 LOG_SCOPE; 1357 LOG_SCOPE;
1366
1367 if (vd->llvmDModule) return;
1368 vd->llvmDModule = gIR->dmodule;
1369 1358
1370 bool emitRTstaticInit = false; 1359 bool emitRTstaticInit = false;
1371 1360
1372 llvm::Constant* _init = 0; 1361 llvm::Constant* _init = 0;
1373 if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) { 1362 if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) {
1426 } 1415 }
1427 1416
1428 if (emitRTstaticInit) 1417 if (emitRTstaticInit)
1429 DtoLazyStaticInit(istempl, gvar, vd->init, t); 1418 DtoLazyStaticInit(istempl, gvar, vd->init, t);
1430 } 1419 }
1420
1421 //////////////////////////////////////////////////////////////////////////////////////////
1422
1423 void DtoEmptyResolveList()
1424 {
1425 //Logger::println("DtoEmptyResolveList()");
1426 Dsymbol* dsym;
1427 while (!gIR->resolveList.empty()) {
1428 dsym = gIR->resolveList.front();
1429 gIR->resolveList.pop_front();
1430 DtoResolveDsymbol(dsym);
1431 }
1432 }
1433
1434 //////////////////////////////////////////////////////////////////////////////////////////
1435
1436 void DtoEmptyDeclareList()
1437 {
1438 //Logger::println("DtoEmptyDeclareList()");
1439 Dsymbol* dsym;
1440 while (!gIR->declareList.empty()) {
1441 dsym = gIR->declareList.front();
1442 gIR->declareList.pop_front();
1443 DtoDeclareDsymbol(dsym);
1444 }
1445 }
1446
1447 //////////////////////////////////////////////////////////////////////////////////////////
1448
1449 void DtoEmptyConstInitList()
1450 {
1451 //Logger::println("DtoEmptyConstInitList()");
1452 Dsymbol* dsym;
1453 while (!gIR->constInitList.empty()) {
1454 dsym = gIR->constInitList.front();
1455 gIR->constInitList.pop_front();
1456 DtoConstInitDsymbol(dsym);
1457 }
1458 }
1459
1460 //////////////////////////////////////////////////////////////////////////////////////////
1461
1462 void DtoEmptyDefineList()
1463 {
1464 //Logger::println("DtoEmptyDefineList()");
1465 Dsymbol* dsym;
1466 while (!gIR->defineList.empty()) {
1467 dsym = gIR->defineList.front();
1468 gIR->defineList.pop_front();
1469 DtoDefineDsymbol(dsym);
1470 }
1471 }
1472
1473 //////////////////////////////////////////////////////////////////////////////////////////
1474
1475 void DtoForceDeclareDsymbol(Dsymbol* dsym)
1476 {
1477 if (dsym->llvmDeclared) return;
1478 Logger::println("DtoForceDeclareDsymbol(%s)", dsym->toChars());
1479 LOG_SCOPE;
1480 DtoResolveDsymbol(dsym);
1481
1482 DtoEmptyResolveList();
1483
1484 DtoDeclareDsymbol(dsym);
1485 }
1486
1487 //////////////////////////////////////////////////////////////////////////////////////////
1488
1489 void DtoForceConstInitDsymbol(Dsymbol* dsym)
1490 {
1491 if (dsym->llvmInitialized) return;
1492 Logger::println("DtoForceConstInitDsymbol(%s)", dsym->toChars());
1493 LOG_SCOPE;
1494 DtoResolveDsymbol(dsym);
1495
1496 DtoEmptyResolveList();
1497 DtoEmptyDeclareList();
1498
1499 DtoConstInitDsymbol(dsym);
1500 }
1501
1502 //////////////////////////////////////////////////////////////////////////////////////////
1503
1504 void DtoForceDefineDsymbol(Dsymbol* dsym)
1505 {
1506 if (dsym->llvmDefined) return;
1507 Logger::println("DtoForceDefineDsymbol(%s)", dsym->toChars());
1508 LOG_SCOPE;
1509 DtoResolveDsymbol(dsym);
1510
1511 DtoEmptyResolveList();
1512 DtoEmptyDeclareList();
1513 DtoEmptyConstInitList();
1514
1515 DtoDefineDsymbol(dsym);
1516 }