LinkageWithCOMDAT DtoLinkage(Dsymbol *sym) { auto linkage = (DtoIsTemplateInstance(sym) ? templateLinkage : LLGlobalValue::ExternalLinkage); // If @(ldc.attributes.weak) is applied, override the linkage to WeakAny if (hasWeakUDA(sym)) { linkage = LLGlobalValue::WeakAnyLinkage; } return {linkage, supportsCOMDAT()}; }
bool defineAsExternallyAvailable(FuncDeclaration &fdecl) { IF_LOG Logger::println("Enter defineAsExternallyAvailable"); LOG_SCOPE #if LDC_LLVM_VER < 307 // Pre-3.7, cross-module inlining is disabled completely. // See the commandline flag definition for more details. IF_LOG Logger::println("LLVM < 3.7: Cross-module inlining disabled."); return false; #endif // Implementation note: try to do cheap checks first. if (fdecl.neverInline || fdecl.inlining == PINLINEnever) { IF_LOG Logger::println("pragma(inline, false) specified"); return false; } // pragma(inline, true) functions will be inlined even at -O0 if (fdecl.inlining == PINLINEalways) { IF_LOG Logger::println( "pragma(inline, true) specified, overrides cmdline flags"); } else if (!willCrossModuleInline()) { IF_LOG Logger::println("Commandline flags indicate no inlining"); return false; } if (fdecl.isUnitTestDeclaration()) { IF_LOG Logger::println("isUnitTestDeclaration() == true"); return false; } if (fdecl.isFuncAliasDeclaration()) { IF_LOG Logger::println("isFuncAliasDeclaration() == true"); return false; } if (!fdecl.fbody) { IF_LOG Logger::println("No function body available for inlining"); return false; } // TODO: Fix inlining functions from object.d. Currently errors because of // TypeInfo type-mismatch issue (TypeInfo classes get special treatment by the // compiler). To start working on it: comment-out this check and druntime will // fail to compile. if (fdecl.getModule()->ident == Id::object) { IF_LOG Logger::println("Inlining of object.d functions is disabled"); return false; } if (fdecl.semanticRun >= PASSsemantic3) { // If semantic analysis has come this far, the function will be defined // elsewhere and should not get the available_externally attribute from // here. // TODO: This check prevents inlining of nested functions. IF_LOG Logger::println("Semantic analysis already completed"); return false; } if (alreadyOrWillBeDefined(fdecl)) { // This check is needed because of ICEs happening because of unclear issues // upon changing the codegen order without this check. IF_LOG Logger::println("Function will be defined later."); return false; } // Weak-linkage functions can not be inlined. if (hasWeakUDA(&fdecl)) { IF_LOG Logger::println("@weak functions cannot be inlined."); return false; } if (fdecl.inlining != PINLINEalways && !isInlineCandidate(fdecl)) return false; IF_LOG Logger::println("Potential inlining candidate"); { IF_LOG Logger::println("Do semantic analysis"); LOG_SCOPE // The inlining is aggressive and may give semantic errors that are // forward referencing errors. Simply avoid those cases for inlining. unsigned errors = global.startGagging(); global.gaggedForInlining = true; bool semantic_error = false; if (fdecl.functionSemantic3()) { Module::runDeferredSemantic3(); } else { IF_LOG Logger::println("Failed functionSemantic3."); semantic_error = true; } global.gaggedForInlining = false; if (global.endGagging(errors) || semantic_error) { IF_LOG Logger::println("Errors occured during semantic analysis."); return false; } assert(fdecl.semanticRun >= PASSsemantic3done); } // FuncDeclaration::naked is set by the AsmParser during semantic3 analysis, // and so this check can only be done at this late point. if (fdecl.naked) { IF_LOG Logger::println("Naked asm functions cannot be inlined."); return false; } IF_LOG Logger::println("defineAsExternallyAvailable? Yes."); return true; }