{"action":"created","comment":{"url":"https://api.github.com/repos/ldc-developers/ldc/pulls/comments/68119323","id":68119323,"diff_hunk":"@@ -42,6 +42,123 @@\n #include \"llvm/IR/CFG.h\"\n #include <iostream>\n \n+////////////////////////////////////////////////////////////////////////////////\n+// Function inlining\n+// TODO: move to its own file?\n+namespace {\n+\n+// Use a heuristic to determine if it could make sense to inline this fdecl.\n+// Note: isInlineCandidate is called _before_ full semantic analysis of fdecl.\n+bool isInlineCandidate(FuncDeclaration &fdecl) {\n+  if (fdecl.inlining == PINLINEalways)\n+    return true;\n+\n+  return true;\n+}\n+\n+/// Check whether the frontend knows that the function is already defined\n+/// in some other module (see DMD's FuncDeclaration::toObjFile).\n+bool alreadyOrWillBeDefined(FuncDeclaration &fdecl) {\n+  for (FuncDeclaration *f = &fdecl; f;) {\n+    if (!f->isInstantiated() && f->inNonRoot()) {\n+      return false;\n+    }\n+    if (f->isNested()) {\n+      f = f->toParent2()->isFuncDeclaration();\n+    } else {\n+      break;\n+    }\n+  }\n+  return true;\n+}\n+\n+/// If true: define this function with externally_available linkage, for\n+/// inlining potential.\n+/// If true: full semantic analysis done on this fdecl, ready for codegen.\n+bool defineAsExternallyAvailable(FuncDeclaration &fdecl) {\n+  IF_LOG Logger::println(\"Enter defineAsExternallyAvailable\");\n+  LOG_SCOPE\n+\n+  // Try to do cheap checks first.\n+\n+  if (fdecl.neverInline || fdecl.inlining == PINLINEnever)\n+    return false;\n+\n+  // pragma(inline, true) functions will be inlined even at -O0\n+  if (!willInline() && (fdecl.inlining != PINLINEalways))\n+    return false;\n+\n+  if (fdecl.isUnitTestDeclaration())\n+    return false;\n+  if (fdecl.isFuncAliasDeclaration())\n+    return false;\n+  if (!fdecl.fbody)\n+    return false;\n+\n+  // Disable inlining functions from object.d because of TypeInfo related issue\n+  if (fdecl.getModule()->ident == Id::object)\n+    return false;\n+\n+  if (alreadyOrWillBeDefined(fdecl))\n+    return false;\n+\n+  // Weak-linkage functions can not be inlined.\n+  if (hasWeakUDA(&fdecl))\n+    return false;\n+\n+  if (!isInlineCandidate(fdecl))\n+    return false;\n+\n+  IF_LOG Logger::println(\"Potential inlining candidate\");\n+\n+  // If semantic analysis is already complete, the function will be codegenned\n+  // elsewhere.\n+  if (fdecl.semanticRun >= PASSsemantic3)\n+    return false;\n+\n+  {\n+    IF_LOG Logger::println(\"Do semantic analysis\");\n+    LOG_SCOPE\n+\n+    // The inlining is aggressive and may give semantic errors that are forward\n+    // referencing errors. Simply avoid those cases for inlining.\n+    uint errors = global.startGagging();\n+    global.gaggedForInlining = true;\n+\n+    bool semantic_error = false;\n+    if (fdecl.functionSemantic3()) {\n+      Module::runDeferredSemantic3();\n+    } else {\n+      IF_LOG Logger::println(\"Failed functionSemantic3.\");\n+      semantic_error = true;\n+    }\n+\n+    global.gaggedForInlining = false;\n+    if (global.endGagging(errors) || semantic_error) {\n+      IF_LOG Logger::println(\"Errors occured during semantic analysis.\");\n+      return false;\n+    }\n+    assert(fdecl.semanticRun >= PASSsemantic3done);\n+  }\n+\n+  // For naked functions (inline assembly), we emit the assembly directly as\n+  // globals in the text section. Emitting them during this inline pass will\n+  // therefore result in multiple definitions. Solution: don't try to inline\n+  // them.\n+  // These naked functions don't appear to be inlined anyway, so it is pointless\n+  // at this moment to try.\n+  // FuncDeclaration::naked is set by the AsmParser during semantic analysis.","path":"gen/functions.cpp","position":null,"original_position":109,"commit_id":"bd85f6bec230a6cc4474e5c38ae77c5e00227676","original_commit_id":"3d0ecdeb9302cb12971b2fd0d1292f3b09fd730c","user":{"login":"klickverbot","id":19335,"avatar_url":"https://avatars.githubusercontent.com/u/19335?v=3","gravatar_id":"","url":"https://api.github.com/users/klickverbot","html_url":"https://github.com/klickverbot","followers_url":"https://api.github.com/users/klickverbot/followers","following_url":"https://api.github.com/users/klickverbot/following{/other_user}","gists_url":"https://api.github.com/users/klickverbot/gists{/gist_id}","starred_url":"https://api.github.com/users/klickverbot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/klickverbot/subscriptions","organizations_url":"https://api.github.com/users/klickverbot/orgs","repos_url":"https://api.github.com/users/klickverbot/repos","events_url":"https://api.github.com/users/klickverbot/events{/privacy}","received_events_url":"https://api.github.com/users/klickverbot/received_events","type":"User","site_admin":false},"body":"That's a bit of an odd comment to find here, given that `naked` is an upstream DMD member – when else would it be set if not during semantic analysis?","created_at":"2016-06-22T19:31:21Z","updated_at":"2016-06-22T19:31:21Z","html_url":"https://github.com/ldc-developers/ldc/pull/1577#discussion_r68119323","pull_request_url":"https://api.github.com/repos/ldc-developers/ldc/pulls/1577","_links":{"self":{"href":"https://api.github.com/repos/ldc-developers/ldc/pulls/comments/68119323"},"html":{"href":"https://github.com/ldc-developers/ldc/pull/1577#discussion_r68119323"},"pull_request":{"href":"https://api.github.com/repos/ldc-developers/ldc/pulls/1577"}}},"pull_request":{"url":"https://api.github.com/repos/ldc-developers/ldc/pulls/1577","id":74824501,"html_url":"https://github.com/ldc-developers/ldc/pull/1577","diff_url":"https://github.com/ldc-developers/ldc/pull/1577.diff","patch_url":"https://github.com/ldc-developers/ldc/pull/1577.patch","issue_url":"https://api.github.com/repos/ldc-developers/ldc/issues/1577","number":1577,"state":"open","locked":false,"title":"[WIP] Implement cross-module inlining","user":{"login":"JohanEngelen","id":10983051,"avatar_url":"https://avatars.githubusercontent.com/u/10983051?v=3","gravatar_id":"","url":"https://api.github.com/users/JohanEngelen","html_url":"https://github.com/JohanEngelen","followers_url":"https://api.github.com/users/JohanEngelen/followers","following_url":"https://api.github.com/users/JohanEngelen/following{/other_user}","gists_url":"https://api.github.com/users/JohanEngelen/gists{/gist_id}","starred_url":"https://api.github.com/users/JohanEngelen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JohanEngelen/subscriptions","organizations_url":"https://api.github.com/users/JohanEngelen/orgs","repos_url":"https://api.github.com/users/JohanEngelen/repos","events_url":"https://api.github.com/users/JohanEngelen/events{/privacy}","received_events_url":"https://api.github.com/users/JohanEngelen/received_events","type":"User","site_admin":false},"body":"An \"inlined\" function will be defined with the LLVM attribute `available_externally`, so that LLVM can decide to actually inline the function or not.\r\n\r\n`pragma(inline, false)` --> the function receives the `noinline` attribute.\r\n`pragma(inline, true)`  --> the function receives the `alwaysinline` attribute and cross-module inlining for this function is performed even at `-O0`.\r\n\r\nThe current heuristic for (defining available_externally functions to enable) inlining functions is: `true`  :-)\r\nVery aggressive indeed; good for testing :). Perhaps a simple statement count heuristic can be used . \r\n\r\nFunctions that have `__FILE__` as default _template_ parameter need to always be inlined `pragma(inline, true)`, otherwise it results in link errors. See the forum discussion:\r\nhttps://forum.dlang.org/thread/induraqegvpyomvzxwmf@forum.dlang.org\r\n\r\nTo inline a function, semantic analysis needs to be completed for that function (DMD does the same). Doing that however, may add new symbols to the module member list for codegenning. This means that the order of how modules are codegenned needs to be reversed (or, members[0] needs to be codegenned last, as that one receives all new symbols). This showed up while testing Weka's codebase and cost me a lot of time. Unfortunately, I have not managed to recreate this problem in a testcase.\r\n\r\nTested succesfully on Weka's codebase.","created_at":"2016-06-22T17:28:11Z","updated_at":"2016-06-22T19:31:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"104454a8289702b3de4bf161e6787ce28702d291","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ldc-developers/ldc/pulls/1577/commits","review_comments_url":"https://api.github.com/repos/ldc-developers/ldc/pulls/1577/comments","review_comment_url":"https://api.github.com/repos/ldc-developers/ldc/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ldc-developers/ldc/issues/1577/comments","statuses_url":"https://api.github.com/repos/ldc-developers/ldc/statuses/bd85f6bec230a6cc4474e5c38ae77c5e00227676","head":{"label":"JohanEngelen:inlining","ref":"inlining","sha":"bd85f6bec230a6cc4474e5c38ae77c5e00227676","user":{"login":"JohanEngelen","id":10983051,"avatar_url":"https://avatars.githubusercontent.com/u/10983051?v=3","gravatar_id":"","url":"https://api.github.com/users/JohanEngelen","html_url":"https://github.com/JohanEngelen","followers_url":"https://api.github.com/users/JohanEngelen/followers","following_url":"https://api.github.com/users/JohanEngelen/following{/other_user}","gists_url":"https://api.github.com/users/JohanEngelen/gists{/gist_id}","starred_url":"https://api.github.com/users/JohanEngelen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JohanEngelen/subscriptions","organizations_url":"https://api.github.com/users/JohanEngelen/orgs","repos_url":"https://api.github.com/users/JohanEngelen/repos","events_url":"https://api.github.com/users/JohanEngelen/events{/privacy}","received_events_url":"https://api.github.com/users/JohanEngelen/received_events","type":"User","site_admin":false},"repo":{"id":31165992,"name":"ldc","full_name":"JohanEngelen/ldc","owner":{"login":"JohanEngelen","id":10983051,"avatar_url":"https://avatars.githubusercontent.com/u/10983051?v=3","gravatar_id":"","url":"https://api.github.com/users/JohanEngelen","html_url":"https://github.com/JohanEngelen","followers_url":"https://api.github.com/users/JohanEngelen/followers","following_url":"https://api.github.com/users/JohanEngelen/following{/other_user}","gists_url":"https://api.github.com/users/JohanEngelen/gists{/gist_id}","starred_url":"https://api.github.com/users/JohanEngelen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JohanEngelen/subscriptions","organizations_url":"https://api.github.com/users/JohanEngelen/orgs","repos_url":"https://api.github.com/users/JohanEngelen/repos","events_url":"https://api.github.com/users/JohanEngelen/events{/privacy}","received_events_url":"https://api.github.com/users/JohanEngelen/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/JohanEngelen/ldc","description":"The LLVM-based D compiler.","fork":true,"url":"https://api.github.com/repos/JohanEngelen/ldc","forks_url":"https://api.github.com/repos/JohanEngelen/ldc/forks","keys_url":"https://api.github.com/repos/JohanEngelen/ldc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JohanEngelen/ldc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JohanEngelen/ldc/teams","hooks_url":"https://api.github.com/repos/JohanEngelen/ldc/hooks","issue_events_url":"https://api.github.com/repos/JohanEngelen/ldc/issues/events{/number}","events_url":"https://api.github.com/repos/JohanEngelen/ldc/events","assignees_url":"https://api.github.com/repos/JohanEngelen/ldc/assignees{/user}","branches_url":"https://api.github.com/repos/JohanEngelen/ldc/branches{/branch}","tags_url":"https://api.github.com/repos/JohanEngelen/ldc/tags","blobs_url":"https://api.github.com/repos/JohanEngelen/ldc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JohanEngelen/ldc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JohanEngelen/ldc/git/refs{/sha}","trees_url":"https://api.github.com/repos/JohanEngelen/ldc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JohanEngelen/ldc/statuses/{sha}","languages_url":"https://api.github.com/repos/JohanEngelen/ldc/languages","stargazers_url":"https://api.github.com/repos/JohanEngelen/ldc/stargazers","contributors_url":"https://api.github.com/repos/JohanEngelen/ldc/contributors","subscribers_url":"https://api.github.com/repos/JohanEngelen/ldc/subscribers","subscription_url":"https://api.github.com/repos/JohanEngelen/ldc/subscription","commits_url":"https://api.github.com/repos/JohanEngelen/ldc/commits{/sha}","git_commits_url":"https://api.github.com/repos/JohanEngelen/ldc/git/commits{/sha}","comments_url":"https://api.github.com/repos/JohanEngelen/ldc/comments{/number}","issue_comment_url":"https://api.github.com/repos/JohanEngelen/ldc/issues/comments{/number}","contents_url":"https://api.github.com/repos/JohanEngelen/ldc/contents/{+path}","compare_url":"https://api.github.com/repos/JohanEngelen/ldc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JohanEngelen/ldc/merges","archive_url":"https://api.github.com/repos/JohanEngelen/ldc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JohanEngelen/ldc/downloads","issues_url":"https://api.github.com/repos/JohanEngelen/ldc/issues{/number}","pulls_url":"https://api.github.com/repos/JohanEngelen/ldc/pulls{/number}","milestones_url":"https://api.github.com/repos/JohanEngelen/ldc/milestones{/number}","notifications_url":"https://api.github.com/repos/JohanEngelen/ldc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JohanEngelen/ldc/labels{/name}","releases_url":"https://api.github.com/repos/JohanEngelen/ldc/releases{/id}","deployments_url":"https://api.github.com/repos/JohanEngelen/ldc/deployments","created_at":"2015-02-22T14:46:29Z","updated_at":"2016-02-23T09:01:52Z","pushed_at":"2016-06-22T15:58:10Z","git_url":"git://github.com/JohanEngelen/ldc.git","ssh_url":"git@github.com:JohanEngelen/ldc.git","clone_url":"https://github.com/JohanEngelen/ldc.git","svn_url":"https://github.com/JohanEngelen/ldc","homepage":"http://wiki.dlang.org/LDC","size":24912,"stargazers_count":0,"watchers_count":0,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"ldc-developers:master","ref":"master","sha":"170502a4ddb36da33ecdb839de2b6c485d55f0f0","user":{"login":"ldc-developers","id":960112,"avatar_url":"https://avatars.githubusercontent.com/u/960112?v=3","gravatar_id":"","url":"https://api.github.com/users/ldc-developers","html_url":"https://github.com/ldc-developers","followers_url":"https://api.github.com/users/ldc-developers/followers","following_url":"https://api.github.com/users/ldc-developers/following{/other_user}","gists_url":"https://api.github.com/users/ldc-developers/gists{/gist_id}","starred_url":"https://api.github.com/users/ldc-developers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ldc-developers/subscriptions","organizations_url":"https://api.github.com/users/ldc-developers/orgs","repos_url":"https://api.github.com/users/ldc-developers/repos","events_url":"https://api.github.com/users/ldc-developers/events{/privacy}","received_events_url":"https://api.github.com/users/ldc-developers/received_events","type":"Organization","site_admin":false},"repo":{"id":2174666,"name":"ldc","full_name":"ldc-developers/ldc","owner":{"login":"ldc-developers","id":960112,"avatar_url":"https://avatars.githubusercontent.com/u/960112?v=3","gravatar_id":"","url":"https://api.github.com/users/ldc-developers","html_url":"https://github.com/ldc-developers","followers_url":"https://api.github.com/users/ldc-developers/followers","following_url":"https://api.github.com/users/ldc-developers/following{/other_user}","gists_url":"https://api.github.com/users/ldc-developers/gists{/gist_id}","starred_url":"https://api.github.com/users/ldc-developers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ldc-developers/subscriptions","organizations_url":"https://api.github.com/users/ldc-developers/orgs","repos_url":"https://api.github.com/users/ldc-developers/repos","events_url":"https://api.github.com/users/ldc-developers/events{/privacy}","received_events_url":"https://api.github.com/users/ldc-developers/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ldc-developers/ldc","description":"The LLVM-based D compiler.","fork":false,"url":"https://api.github.com/repos/ldc-developers/ldc","forks_url":"https://api.github.com/repos/ldc-developers/ldc/forks","keys_url":"https://api.github.com/repos/ldc-developers/ldc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ldc-developers/ldc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ldc-developers/ldc/teams","hooks_url":"https://api.github.com/repos/ldc-developers/ldc/hooks","issue_events_url":"https://api.github.com/repos/ldc-developers/ldc/issues/events{/number}","events_url":"https://api.github.com/repos/ldc-developers/ldc/events","assignees_url":"https://api.github.com/repos/ldc-developers/ldc/assignees{/user}","branches_url":"https://api.github.com/repos/ldc-developers/ldc/branches{/branch}","tags_url":"https://api.github.com/repos/ldc-developers/ldc/tags","blobs_url":"https://api.github.com/repos/ldc-developers/ldc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ldc-developers/ldc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ldc-developers/ldc/git/refs{/sha}","trees_url":"https://api.github.com/repos/ldc-developers/ldc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ldc-developers/ldc/statuses/{sha}","languages_url":"https://api.github.com/repos/ldc-developers/ldc/languages","stargazers_url":"https://api.github.com/repos/ldc-developers/ldc/stargazers","contributors_url":"https://api.github.com/repos/ldc-developers/ldc/contributors","subscribers_url":"https://api.github.com/repos/ldc-developers/ldc/subscribers","subscription_url":"https://api.github.com/repos/ldc-developers/ldc/subscription","commits_url":"https://api.github.com/repos/ldc-developers/ldc/commits{/sha}","git_commits_url":"https://api.github.com/repos/ldc-developers/ldc/git/commits{/sha}","comments_url":"https://api.github.com/repos/ldc-developers/ldc/comments{/number}","issue_comment_url":"https://api.github.com/repos/ldc-developers/ldc/issues/comments{/number}","contents_url":"https://api.github.com/repos/ldc-developers/ldc/contents/{+path}","compare_url":"https://api.github.com/repos/ldc-developers/ldc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ldc-developers/ldc/merges","archive_url":"https://api.github.com/repos/ldc-developers/ldc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ldc-developers/ldc/downloads","issues_url":"https://api.github.com/repos/ldc-developers/ldc/issues{/number}","pulls_url":"https://api.github.com/repos/ldc-developers/ldc/pulls{/number}","milestones_url":"https://api.github.com/repos/ldc-developers/ldc/milestones{/number}","notifications_url":"https://api.github.com/repos/ldc-developers/ldc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ldc-developers/ldc/labels{/name}","releases_url":"https://api.github.com/repos/ldc-developers/ldc/releases{/id}","deployments_url":"https://api.github.com/repos/ldc-developers/ldc/deployments","created_at":"2011-08-08T17:10:27Z","updated_at":"2016-06-22T14:45:30Z","pushed_at":"2016-06-22T17:28:11Z","git_url":"git://github.com/ldc-developers/ldc.git","ssh_url":"git@github.com:ldc-developers/ldc.git","clone_url":"https://github.com/ldc-developers/ldc.git","svn_url":"https://github.com/ldc-developers/ldc","homepage":"http://wiki.dlang.org/LDC","size":28937,"stargazers_count":471,"watchers_count":471,"language":"D","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":101,"mirror_url":null,"open_issues_count":174,"forks":101,"open_issues":174,"watchers":471,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ldc-developers/ldc/pulls/1577"},"html":{"href":"https://github.com/ldc-developers/ldc/pull/1577"},"issue":{"href":"https://api.github.com/repos/ldc-developers/ldc/issues/1577"},"comments":{"href":"https://api.github.com/repos/ldc-developers/ldc/issues/1577/comments"},"review_comments":{"href":"https://api.github.com/repos/ldc-developers/ldc/pulls/1577/comments"},"review_comment":{"href":"https://api.github.com/repos/ldc-developers/ldc/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ldc-developers/ldc/pulls/1577/commits"},"statuses":{"href":"https://api.github.com/repos/ldc-developers/ldc/statuses/bd85f6bec230a6cc4474e5c38ae77c5e00227676"}}}}
{"actor":{"display_login":"klickverbot"}}