Mercurial > projects > ldc
comparison gen/tollvm.cpp @ 1482:d9c5f5a43403
Run `semantic3` on imported modules, and emit new symbols with
`available_externally` linkage. This allows the inliner to inline functions from
other modules while telling the code generator to ignore those functions (treat
them as declarations)
Still generates a few extra `TypeInfo`s and strings...
Disabled when generating debug info because I don't really understand it, and it
doesn't like this.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sun, 07 Jun 2009 16:00:13 +0200 |
parents | b3ba2c6ff038 |
children | 8b9f236dd051 |
comparison
equal
deleted
inserted
replaced
1481:e0f03e11cdf8 | 1482:d9c5f5a43403 |
---|---|
239 LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) | 239 LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) |
240 { | 240 { |
241 // global variable | 241 // global variable |
242 if (VarDeclaration* vd = sym->isVarDeclaration()) | 242 if (VarDeclaration* vd = sym->isVarDeclaration()) |
243 { | 243 { |
244 if (mustDefineSymbol(vd)) | |
245 Logger::println("Variable %savailable externally: %s", (vd->availableExternally ? "" : "not "), vd->toChars()); | |
246 #if LLVM_REV >= 68940 | |
247 // generated by inlining semantics run | |
248 if (vd->availableExternally && mustDefineSymbol(sym)) | |
249 return llvm::GlobalValue::AvailableExternallyLinkage; | |
250 #endif | |
244 // template | 251 // template |
245 if (needsTemplateLinkage(sym)) | 252 if (needsTemplateLinkage(sym)) |
246 return TEMPLATE_LINKAGE_TYPE; | 253 return TEMPLATE_LINKAGE_TYPE; |
247 } | 254 } |
248 // function | 255 // function |
249 else if (FuncDeclaration* fdecl = sym->isFuncDeclaration()) | 256 else if (FuncDeclaration* fdecl = sym->isFuncDeclaration()) |
250 { | 257 { |
258 if (mustDefineSymbol(fdecl)) | |
259 Logger::println("Function %savailable externally: %s", (fdecl->availableExternally ? "" : "not "), fdecl->toChars()); | |
251 assert(fdecl->type->ty == Tfunction); | 260 assert(fdecl->type->ty == Tfunction); |
252 TypeFunction* ft = (TypeFunction*)fdecl->type; | 261 TypeFunction* ft = (TypeFunction*)fdecl->type; |
253 | 262 |
263 // intrinsics are always external | |
264 if (fdecl->llvmInternal == LLVMintrinsic) | |
265 return llvm::GlobalValue::ExternalLinkage; | |
266 #if LLVM_REV >= 68940 | |
267 // generated by inlining semantics run | |
268 if (fdecl->availableExternally && mustDefineSymbol(sym)) | |
269 return llvm::GlobalValue::AvailableExternallyLinkage; | |
270 #endif | |
254 // array operations are always template linkage | 271 // array operations are always template linkage |
255 if (fdecl->isArrayOp) | 272 if (fdecl->isArrayOp) |
256 return TEMPLATE_LINKAGE_TYPE; | 273 return TEMPLATE_LINKAGE_TYPE; |
257 // intrinsics are always external | |
258 if (fdecl->llvmInternal == LLVMintrinsic) | |
259 return llvm::GlobalValue::ExternalLinkage; | |
260 // template instances should have weak linkage | 274 // template instances should have weak linkage |
261 // but only if there's a body, and it's not naked | 275 // but only if there's a body, and it's not naked |
262 // otherwise we make it external | 276 // otherwise we make it external |
263 else if (needsTemplateLinkage(fdecl) && fdecl->fbody && !fdecl->naked) | 277 else if (needsTemplateLinkage(fdecl) && fdecl->fbody && !fdecl->naked) |
264 return TEMPLATE_LINKAGE_TYPE; | 278 return TEMPLATE_LINKAGE_TYPE; |
267 return llvm::GlobalValue::ExternalLinkage; | 281 return llvm::GlobalValue::ExternalLinkage; |
268 } | 282 } |
269 // class | 283 // class |
270 else if (ClassDeclaration* cd = sym->isClassDeclaration()) | 284 else if (ClassDeclaration* cd = sym->isClassDeclaration()) |
271 { | 285 { |
286 if (mustDefineSymbol(cd)) | |
287 Logger::println("Class %savailable externally: %s", (cd->availableExternally ? "" : "not "), vd->toChars()); | |
288 #if LLVM_REV >= 68940 | |
289 // generated by inlining semantics run | |
290 if (cd->availableExternally && mustDefineSymbol(sym)) | |
291 return llvm::GlobalValue::AvailableExternallyLinkage; | |
292 #endif | |
272 // template | 293 // template |
273 if (needsTemplateLinkage(cd)) | 294 if (needsTemplateLinkage(cd)) |
274 return TEMPLATE_LINKAGE_TYPE; | 295 return TEMPLATE_LINKAGE_TYPE; |
275 } | 296 } |
276 else | 297 else |
277 { | 298 { |
278 assert(0 && "not global/function"); | 299 assert(0 && "not global/function"); |
279 } | 300 } |
280 | 301 |
281 // The following breaks for nested naked functions, so check for that. | 302 // The following breaks for nested naked functions and other declarations, so check for that. |
282 bool skipNestedCheck = false; | 303 bool skipNestedCheck = !mustDefineSymbol(sym); |
283 if (FuncDeclaration* fd = sym->isFuncDeclaration()) | 304 if (FuncDeclaration* fd = sym->isFuncDeclaration()) |
284 skipNestedCheck = (fd->naked != 0); | 305 skipNestedCheck = (fd->naked != 0); |
285 | 306 |
286 // Any symbol nested in a function can't be referenced directly from | 307 // Any symbol nested in a function can't be referenced directly from |
287 // outside that function, so we can give such symbols internal linkage. | 308 // outside that function, so we can give such symbols internal linkage. |
304 | 325 |
305 // default to external linkage | 326 // default to external linkage |
306 return llvm::GlobalValue::ExternalLinkage; | 327 return llvm::GlobalValue::ExternalLinkage; |
307 } | 328 } |
308 | 329 |
330 static bool isAvailableExternally(Dsymbol* sym) | |
331 { | |
332 if (VarDeclaration* vd = sym->isVarDeclaration()) | |
333 return vd->availableExternally; | |
334 if (FuncDeclaration* fd = sym->isFuncDeclaration()) | |
335 return fd->availableExternally; | |
336 if (AggregateDeclaration* ad = sym->isAggregateDeclaration()) | |
337 return ad->availableExternally; | |
338 return false; | |
339 } | |
340 | |
309 llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym) | 341 llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym) |
310 { | 342 { |
311 if (needsTemplateLinkage(sym)) | 343 if (needsTemplateLinkage(sym)) { |
344 #if LLVM_REV >= 68940 | |
345 if (isAvailableExternally(sym) && mustDefineSymbol(sym)) | |
346 return llvm::GlobalValue::AvailableExternallyLinkage; | |
347 #endif | |
312 return TEMPLATE_LINKAGE_TYPE; | 348 return TEMPLATE_LINKAGE_TYPE; |
349 } | |
313 else | 350 else |
314 return llvm::GlobalValue::InternalLinkage; | 351 return llvm::GlobalValue::InternalLinkage; |
315 } | 352 } |
316 | 353 |
317 llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym) | 354 llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym) |
318 { | 355 { |
356 #if LLVM_REV >= 68940 | |
357 if (isAvailableExternally(sym) && mustDefineSymbol(sym)) | |
358 return llvm::GlobalValue::AvailableExternallyLinkage; | |
359 #endif | |
319 if (needsTemplateLinkage(sym)) | 360 if (needsTemplateLinkage(sym)) |
320 return TEMPLATE_LINKAGE_TYPE; | 361 return TEMPLATE_LINKAGE_TYPE; |
321 else | 362 else |
322 return llvm::GlobalValue::ExternalLinkage; | 363 return llvm::GlobalValue::ExternalLinkage; |
323 } | 364 } |