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