{"action":"created","comment":{"url":"https://api.github.com/repos/scala-native/scala-native/pulls/comments/84711200","pull_request_review_id":5471409,"id":84711200,"diff_hunk":"@@ -0,0 +1,42 @@\n+package scala.scalanative\n+package compiler\n+package tools\n+\n+import scala.util.parsing.combinator._\n+import scala.util.matching.Regex\n+\n+object DispatchInfoParser extends JavaTokenParsers {","path":"tools/src/main/scala/scala/scalanative/compiler/tools/DispatchInfoParser.scala","position":8,"original_position":8,"commit_id":"71e6375f94ee3e733fdd7128c61f5995fc262080","original_commit_id":"71e6375f94ee3e733fdd7128c61f5995fc262080","user":{"login":"densh","id":320966,"avatar_url":"https://avatars.githubusercontent.com/u/320966?v=3","gravatar_id":"","url":"https://api.github.com/users/densh","html_url":"https://github.com/densh","followers_url":"https://api.github.com/users/densh/followers","following_url":"https://api.github.com/users/densh/following{/other_user}","gists_url":"https://api.github.com/users/densh/gists{/gist_id}","starred_url":"https://api.github.com/users/densh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/densh/subscriptions","organizations_url":"https://api.github.com/users/densh/orgs","repos_url":"https://api.github.com/users/densh/repos","events_url":"https://api.github.com/users/densh/events{/privacy}","received_events_url":"https://api.github.com/users/densh/received_events","type":"User","site_admin":false},"body":"Scala's parser combinators are not being actively maintained. Using `fastparse` for this kind of things is probably a better idea. ","created_at":"2016-10-24T15:17:57Z","updated_at":"2016-10-24T15:17:57Z","html_url":"https://github.com/scala-native/scala-native/pull/352#discussion_r84711200","pull_request_url":"https://api.github.com/repos/scala-native/scala-native/pulls/352","_links":{"self":{"href":"https://api.github.com/repos/scala-native/scala-native/pulls/comments/84711200"},"html":{"href":"https://github.com/scala-native/scala-native/pull/352#discussion_r84711200"},"pull_request":{"href":"https://api.github.com/repos/scala-native/scala-native/pulls/352"}}},"pull_request":{"url":"https://api.github.com/repos/scala-native/scala-native/pulls/352","id":90625782,"html_url":"https://github.com/scala-native/scala-native/pull/352","diff_url":"https://github.com/scala-native/scala-native/pull/352.diff","patch_url":"https://github.com/scala-native/scala-native/pull/352.patch","issue_url":"https://api.github.com/repos/scala-native/scala-native/issues/352","number":352,"state":"open","locked":false,"title":"(WIP) Prototype of offline inline caching","user":{"login":"Duhemm","id":1765926,"avatar_url":"https://avatars.githubusercontent.com/u/1765926?v=3","gravatar_id":"","url":"https://api.github.com/users/Duhemm","html_url":"https://github.com/Duhemm","followers_url":"https://api.github.com/users/Duhemm/followers","following_url":"https://api.github.com/users/Duhemm/following{/other_user}","gists_url":"https://api.github.com/users/Duhemm/gists{/gist_id}","starred_url":"https://api.github.com/users/Duhemm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Duhemm/subscriptions","organizations_url":"https://api.github.com/users/Duhemm/orgs","repos_url":"https://api.github.com/users/Duhemm/repos","events_url":"https://api.github.com/users/Duhemm/events{/privacy}","received_events_url":"https://api.github.com/users/Duhemm/received_events","type":"User","site_admin":false},"body":"This PR adds a prototype of offline inline caching, which works in two steps:\r\n\r\n### 1. The application is compiled in profiling mode\r\nFirst, we collect information about the runtime type of the receivers of virtual method calls at runtime.  This way, we can determine what are the most frequent types that we encounter for each virtual call site.\r\n\r\nTo enable profiling, set `nativeProfileDispatch := true` in sbt, and optionally set `nativeProfileInfo := Some(file(...))` to have the profiling information written on disk.\r\n\r\n### 2. The application is recompiled, leveraging the information we collected\r\nIf the compiler finds the file specified in `nativeProfileInfo`, then it will use the information it contains to rewrite call sites to avoid virtual dispatch.\r\n\r\n#### Example\r\n\r\nGiven this information collected at runtime (the first number is the type id, the second is the number of occurrences):\r\n\r\n```\r\n= src.2:addToGraph_unit:\r\n\t3 (100000)\r\n\t4 (100000)\r\n\t6 (5)\r\n\t7 (100001)\r\n```\r\n\r\nThis definition, which contains a call to `addToGraph_unit`:\r\n\r\n```\r\ndef @Constraint::addConstraint_unit : (class @Constraint) => unit {\r\n  %src.1(%src.0: class @Constraint):\r\n    %src.2 = method[(class @Constraint) => unit] %src.0: class @Constraint, @Constraint::addToGraph_unit\r\n    %src.3 = call[(class @Constraint) => unit] %src.2: ptr(%src.0: class @Constraint)\r\n    ...\r\n}\r\n```\r\n\r\nbecomes\r\n\r\n```\r\ndef @Constraint::addConstraint_unit : (class @Constraint) => unit {\r\n  %src.1(%src.0: class @Constraint):\r\n    %tx.2896 = load[ptr] %src.0: class @Constraint\r\n    %tx.2897 = elem[{i32, ptr, {ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr}}] %tx.2896: ptr, 0i32, 0i32\r\n    %tx.2898 = load[i32] %tx.2897: ptr # %tx.2898 is the type id of the receiver\r\n    jump %tx.2908\r\n  %tx.2908: # first type test, 7 is the id of UnaryConstraint\r\n    %tx.2903 = ieq[i32] 7i32, %tx.2898: i32\r\n    if %tx.2903: bool then %tx.2899 else %tx.2907\r\n  %tx.2907: # second type test, 4 is the id of ScalaConstraint\r\n    %tx.2904 = ieq[i32] 4i32, %tx.2898: i32\r\n    if %tx.2904: bool then %tx.2901 else %tx.2906\r\n  %tx.2906: # fallback\r\n    %tx.2905 = method[(class @Constraint) => unit] %src.0: class @Constraint, @Constraint::addToGraph_unit\r\n    jump %tx.2895(%tx.2905: ptr)\r\n  %tx.2899: # \r\n    %tx.2900 = copy @UnaryConstraint::addToGraph_unit\r\n    jump %tx.2895(%tx.2900: ptr)\r\n  %tx.2901:\r\n    %tx.2902 = copy @ScaleConstraint::addToGraph_unit\r\n    jump %tx.2895(%tx.2902: ptr)\r\n  %tx.2906:\r\n    %tx.2905 = method[(class @Constraint) => unit] %src.0: class @Constraint, @Constraint::addToGraph_unit\r\n    jump %tx.2895(%tx.2905: ptr)\r\n  %tx.2895(%src.2: ptr):\r\n    %src.3 = call[(class @Constraint) => unit] %src.2: ptr(%src.0: class @Constraint)\r\n    ...\r\n}\r\n```\r\n\r\n### 3. Problems\r\n\r\nI'm not seeing any performance improvements. We saw performance improvements thanks to LLVM's optimizer (we compared a non-optimized version without inline caching against an optimized (-O2) version with inline caching). The number of virtual calls is reduced on my benchmark from 20 millions to 800 thousands when inlining the 2 most frequent candidates.\r\n\r\nFrom the NIR, is there any obvious reason why we're not seeing any performance improvement (nor degradation)?","created_at":"2016-10-24T14:40:44Z","updated_at":"2016-10-24T15:17:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ed4a3c6022340351df5a6b612eda588dce6ef443","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/scala-native/scala-native/pulls/352/commits","review_comments_url":"https://api.github.com/repos/scala-native/scala-native/pulls/352/comments","review_comment_url":"https://api.github.com/repos/scala-native/scala-native/pulls/comments{/number}","comments_url":"https://api.github.com/repos/scala-native/scala-native/issues/352/comments","statuses_url":"https://api.github.com/repos/scala-native/scala-native/statuses/71e6375f94ee3e733fdd7128c61f5995fc262080","head":{"label":"Duhemm:inline-caching","ref":"inline-caching","sha":"71e6375f94ee3e733fdd7128c61f5995fc262080","user":{"login":"Duhemm","id":1765926,"avatar_url":"https://avatars.githubusercontent.com/u/1765926?v=3","gravatar_id":"","url":"https://api.github.com/users/Duhemm","html_url":"https://github.com/Duhemm","followers_url":"https://api.github.com/users/Duhemm/followers","following_url":"https://api.github.com/users/Duhemm/following{/other_user}","gists_url":"https://api.github.com/users/Duhemm/gists{/gist_id}","starred_url":"https://api.github.com/users/Duhemm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Duhemm/subscriptions","organizations_url":"https://api.github.com/users/Duhemm/orgs","repos_url":"https://api.github.com/users/Duhemm/repos","events_url":"https://api.github.com/users/Duhemm/events{/privacy}","received_events_url":"https://api.github.com/users/Duhemm/received_events","type":"User","site_admin":false},"repo":{"id":62995739,"name":"scala-native","full_name":"Duhemm/scala-native","owner":{"login":"Duhemm","id":1765926,"avatar_url":"https://avatars.githubusercontent.com/u/1765926?v=3","gravatar_id":"","url":"https://api.github.com/users/Duhemm","html_url":"https://github.com/Duhemm","followers_url":"https://api.github.com/users/Duhemm/followers","following_url":"https://api.github.com/users/Duhemm/following{/other_user}","gists_url":"https://api.github.com/users/Duhemm/gists{/gist_id}","starred_url":"https://api.github.com/users/Duhemm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Duhemm/subscriptions","organizations_url":"https://api.github.com/users/Duhemm/orgs","repos_url":"https://api.github.com/users/Duhemm/repos","events_url":"https://api.github.com/users/Duhemm/events{/privacy}","received_events_url":"https://api.github.com/users/Duhemm/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Duhemm/scala-native","description":"Your favourite language gets closer to bare metal.","fork":true,"url":"https://api.github.com/repos/Duhemm/scala-native","forks_url":"https://api.github.com/repos/Duhemm/scala-native/forks","keys_url":"https://api.github.com/repos/Duhemm/scala-native/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Duhemm/scala-native/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Duhemm/scala-native/teams","hooks_url":"https://api.github.com/repos/Duhemm/scala-native/hooks","issue_events_url":"https://api.github.com/repos/Duhemm/scala-native/issues/events{/number}","events_url":"https://api.github.com/repos/Duhemm/scala-native/events","assignees_url":"https://api.github.com/repos/Duhemm/scala-native/assignees{/user}","branches_url":"https://api.github.com/repos/Duhemm/scala-native/branches{/branch}","tags_url":"https://api.github.com/repos/Duhemm/scala-native/tags","blobs_url":"https://api.github.com/repos/Duhemm/scala-native/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Duhemm/scala-native/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Duhemm/scala-native/git/refs{/sha}","trees_url":"https://api.github.com/repos/Duhemm/scala-native/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Duhemm/scala-native/statuses/{sha}","languages_url":"https://api.github.com/repos/Duhemm/scala-native/languages","stargazers_url":"https://api.github.com/repos/Duhemm/scala-native/stargazers","contributors_url":"https://api.github.com/repos/Duhemm/scala-native/contributors","subscribers_url":"https://api.github.com/repos/Duhemm/scala-native/subscribers","subscription_url":"https://api.github.com/repos/Duhemm/scala-native/subscription","commits_url":"https://api.github.com/repos/Duhemm/scala-native/commits{/sha}","git_commits_url":"https://api.github.com/repos/Duhemm/scala-native/git/commits{/sha}","comments_url":"https://api.github.com/repos/Duhemm/scala-native/comments{/number}","issue_comment_url":"https://api.github.com/repos/Duhemm/scala-native/issues/comments{/number}","contents_url":"https://api.github.com/repos/Duhemm/scala-native/contents/{+path}","compare_url":"https://api.github.com/repos/Duhemm/scala-native/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Duhemm/scala-native/merges","archive_url":"https://api.github.com/repos/Duhemm/scala-native/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Duhemm/scala-native/downloads","issues_url":"https://api.github.com/repos/Duhemm/scala-native/issues{/number}","pulls_url":"https://api.github.com/repos/Duhemm/scala-native/pulls{/number}","milestones_url":"https://api.github.com/repos/Duhemm/scala-native/milestones{/number}","notifications_url":"https://api.github.com/repos/Duhemm/scala-native/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Duhemm/scala-native/labels{/name}","releases_url":"https://api.github.com/repos/Duhemm/scala-native/releases{/id}","deployments_url":"https://api.github.com/repos/Duhemm/scala-native/deployments","created_at":"2016-07-10T11:36:58Z","updated_at":"2016-07-10T11:36:59Z","pushed_at":"2016-10-24T08:30:32Z","git_url":"git://github.com/Duhemm/scala-native.git","ssh_url":"git@github.com:Duhemm/scala-native.git","clone_url":"https://github.com/Duhemm/scala-native.git","svn_url":"https://github.com/Duhemm/scala-native","homepage":"http://scala-native.org","size":2842,"stargazers_count":0,"watchers_count":0,"language":"Scala","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":"scala-native:master","ref":"master","sha":"2c2ed5860cfffc45a179b6d764c1c93b19ad693a","user":{"login":"scala-native","id":17545605,"avatar_url":"https://avatars.githubusercontent.com/u/17545605?v=3","gravatar_id":"","url":"https://api.github.com/users/scala-native","html_url":"https://github.com/scala-native","followers_url":"https://api.github.com/users/scala-native/followers","following_url":"https://api.github.com/users/scala-native/following{/other_user}","gists_url":"https://api.github.com/users/scala-native/gists{/gist_id}","starred_url":"https://api.github.com/users/scala-native/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scala-native/subscriptions","organizations_url":"https://api.github.com/users/scala-native/orgs","repos_url":"https://api.github.com/users/scala-native/repos","events_url":"https://api.github.com/users/scala-native/events{/privacy}","received_events_url":"https://api.github.com/users/scala-native/received_events","type":"Organization","site_admin":false},"repo":{"id":27235687,"name":"scala-native","full_name":"scala-native/scala-native","owner":{"login":"scala-native","id":17545605,"avatar_url":"https://avatars.githubusercontent.com/u/17545605?v=3","gravatar_id":"","url":"https://api.github.com/users/scala-native","html_url":"https://github.com/scala-native","followers_url":"https://api.github.com/users/scala-native/followers","following_url":"https://api.github.com/users/scala-native/following{/other_user}","gists_url":"https://api.github.com/users/scala-native/gists{/gist_id}","starred_url":"https://api.github.com/users/scala-native/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scala-native/subscriptions","organizations_url":"https://api.github.com/users/scala-native/orgs","repos_url":"https://api.github.com/users/scala-native/repos","events_url":"https://api.github.com/users/scala-native/events{/privacy}","received_events_url":"https://api.github.com/users/scala-native/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scala-native/scala-native","description":"Your favourite language gets closer to bare metal.","fork":false,"url":"https://api.github.com/repos/scala-native/scala-native","forks_url":"https://api.github.com/repos/scala-native/scala-native/forks","keys_url":"https://api.github.com/repos/scala-native/scala-native/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scala-native/scala-native/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scala-native/scala-native/teams","hooks_url":"https://api.github.com/repos/scala-native/scala-native/hooks","issue_events_url":"https://api.github.com/repos/scala-native/scala-native/issues/events{/number}","events_url":"https://api.github.com/repos/scala-native/scala-native/events","assignees_url":"https://api.github.com/repos/scala-native/scala-native/assignees{/user}","branches_url":"https://api.github.com/repos/scala-native/scala-native/branches{/branch}","tags_url":"https://api.github.com/repos/scala-native/scala-native/tags","blobs_url":"https://api.github.com/repos/scala-native/scala-native/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scala-native/scala-native/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scala-native/scala-native/git/refs{/sha}","trees_url":"https://api.github.com/repos/scala-native/scala-native/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scala-native/scala-native/statuses/{sha}","languages_url":"https://api.github.com/repos/scala-native/scala-native/languages","stargazers_url":"https://api.github.com/repos/scala-native/scala-native/stargazers","contributors_url":"https://api.github.com/repos/scala-native/scala-native/contributors","subscribers_url":"https://api.github.com/repos/scala-native/scala-native/subscribers","subscription_url":"https://api.github.com/repos/scala-native/scala-native/subscription","commits_url":"https://api.github.com/repos/scala-native/scala-native/commits{/sha}","git_commits_url":"https://api.github.com/repos/scala-native/scala-native/git/commits{/sha}","comments_url":"https://api.github.com/repos/scala-native/scala-native/comments{/number}","issue_comment_url":"https://api.github.com/repos/scala-native/scala-native/issues/comments{/number}","contents_url":"https://api.github.com/repos/scala-native/scala-native/contents/{+path}","compare_url":"https://api.github.com/repos/scala-native/scala-native/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scala-native/scala-native/merges","archive_url":"https://api.github.com/repos/scala-native/scala-native/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scala-native/scala-native/downloads","issues_url":"https://api.github.com/repos/scala-native/scala-native/issues{/number}","pulls_url":"https://api.github.com/repos/scala-native/scala-native/pulls{/number}","milestones_url":"https://api.github.com/repos/scala-native/scala-native/milestones{/number}","notifications_url":"https://api.github.com/repos/scala-native/scala-native/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scala-native/scala-native/labels{/name}","releases_url":"https://api.github.com/repos/scala-native/scala-native/releases{/id}","deployments_url":"https://api.github.com/repos/scala-native/scala-native/deployments","created_at":"2014-11-27T17:38:28Z","updated_at":"2016-10-24T13:30:29Z","pushed_at":"2016-10-24T14:40:44Z","git_url":"git://github.com/scala-native/scala-native.git","ssh_url":"git@github.com:scala-native/scala-native.git","clone_url":"https://github.com/scala-native/scala-native.git","svn_url":"https://github.com/scala-native/scala-native","homepage":"http://scala-native.org","size":3017,"stargazers_count":2106,"watchers_count":2106,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":96,"mirror_url":null,"open_issues_count":96,"forks":96,"open_issues":96,"watchers":2106,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/scala-native/scala-native/pulls/352"},"html":{"href":"https://github.com/scala-native/scala-native/pull/352"},"issue":{"href":"https://api.github.com/repos/scala-native/scala-native/issues/352"},"comments":{"href":"https://api.github.com/repos/scala-native/scala-native/issues/352/comments"},"review_comments":{"href":"https://api.github.com/repos/scala-native/scala-native/pulls/352/comments"},"review_comment":{"href":"https://api.github.com/repos/scala-native/scala-native/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/scala-native/scala-native/pulls/352/commits"},"statuses":{"href":"https://api.github.com/repos/scala-native/scala-native/statuses/71e6375f94ee3e733fdd7128c61f5995fc262080"}}}}
{"actor":{"display_login":"densh"}}