{"action":"created","comment":{"url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/comments/165671915","pull_request_review_id":93623587,"id":165671915,"diff_hunk":"@@ -103,6 +103,197 @@ bool Loop::IsBasicBlockInLoopSlow(const BasicBlock* bb) {\n   return true;\n }\n \n+BasicBlock* Loop::GetOrCreatePreHeaderBlock(ir::IRContext* context) {\n+  if (loop_preheader_) return loop_preheader_;\n+\n+  Function* fn = loop_header_->GetParent();\n+  // Find the insertion point for the preheader.\n+  Function::iterator header_it =\n+      std::find_if(fn->begin(), fn->end(),\n+                   [this](BasicBlock& bb) { return &bb == loop_header_; });\n+  assert(header_it != fn->end());\n+\n+  // Create the preheader basic block.\n+  loop_preheader_ = &*header_it.InsertBefore(std::unique_ptr<ir::BasicBlock>(\n+      new ir::BasicBlock(std::unique_ptr<ir::Instruction>(new ir::Instruction(\n+          context, SpvOpLabel, 0, context->TakeNextId(), {})))));\n+  loop_preheader_->SetParent(fn);\n+  uint32_t loop_preheader_id = loop_preheader_->id();\n+\n+  // Redirect the branches and patch the phi:\n+  //  - For each phi instruction in the header:\n+  //    - If the header has only 1 out-of-loop incoming branch:\n+  //      - Change the incomning branch to be the preheader.\n+  //    - If the header has more than 1 out-of-loop incoming branch:\n+  //      - Create a new phi in the preheader, gathering all out-of-loops\n+  //      incoming values;\n+  //      - Patch the header phi instruction to use the preheader phi\n+  //      instruction;\n+  //  - Redirect all edges coming from outside the loop to the preheader.\n+  opt::InstructionBuilder builder(\n+      context, loop_preheader_,\n+      ir::IRContext::kAnalysisDefUse |\n+          ir::IRContext::kAnalysisInstrToBlockMapping);\n+  // Patch all the phi instructions.\n+  loop_header_->ForEachPhiInst([&builder, context, this](Instruction* phi) {\n+    std::vector<uint32_t> preheader_phi_ops;\n+    std::vector<uint32_t> header_phi_ops;\n+    for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) {\n+      uint32_t def_id = phi->GetSingleWordInOperand(i);\n+      uint32_t branch_id = phi->GetSingleWordInOperand(i + 1);\n+      if (IsInsideLoop(branch_id)) {\n+        header_phi_ops.push_back(def_id);\n+        header_phi_ops.push_back(branch_id);\n+      } else {\n+        preheader_phi_ops.push_back(def_id);\n+        preheader_phi_ops.push_back(branch_id);\n+      }\n+    }\n+\n+    Instruction* preheader_insn_def = nullptr;\n+    // Create a phi instruction if and only if the preheader_phi_ops has more\n+    // than one pair.\n+    if (preheader_phi_ops.size() > 2)\n+      preheader_insn_def = builder.AddPhi(phi->type_id(), preheader_phi_ops);\n+    else\n+      preheader_insn_def =\n+          context->get_def_use_mgr()->GetDef(preheader_phi_ops[0]);\n+    // Build the new incoming edge.\n+    header_phi_ops.push_back(preheader_insn_def->result_id());\n+    header_phi_ops.push_back(loop_preheader_->id());\n+    // Rewrite operands of the header's phi instruction.\n+    uint32_t idx = 0;\n+    for (; idx < header_phi_ops.size(); idx++)\n+      phi->SetInOperand(idx, {header_phi_ops[idx]});\n+    // Remove extra operands, from last to first (more efficient).\n+    for (uint32_t j = phi->NumInOperands() - 1; j >= idx; j--)\n+      phi->RemoveInOperand(j);\n+  });\n+  // Branch from the preheader to the header.\n+  builder.AddBranch(loop_header_->id());\n+\n+  // Redirect all out of loop branches to the header to the preheader.\n+  CFG* cfg = context->cfg();\n+  cfg->RegisterBlock(loop_preheader_);\n+  for (uint32_t pred_id : cfg->preds(loop_header_->id())) {\n+    if (pred_id == loop_preheader_->id()) continue;\n+    if (IsInsideLoop(pred_id)) continue;\n+    BasicBlock* pred = cfg->block(pred_id);\n+    pred->ForEachSuccessorLabel([this, loop_preheader_id](uint32_t* id) {\n+      if (*id == loop_header_->id()) *id = loop_preheader_id;\n+    });\n+    cfg->AddEdge(pred_id, loop_preheader_id);\n+  }\n+  // Delete predecessors that are no longer predecessors of the loop header.\n+  cfg->RemoveNonExistingEdges(loop_header_->id());\n+  // Update the loop descriptors.\n+  if (HasParent()) {\n+    GetParent()->AddBasicBlock(loop_preheader_);\n+    context->GetLoopDescriptor(fn)->SetBasicBlockToLoop(loop_preheader_->id(),\n+                                                        GetParent());\n+  }\n+\n+  context->InvalidateAnalysesExceptFor(\n+      builder.GetPreservedAnalysis() |\n+      ir::IRContext::Analysis::kAnalysisLoopAnalysis |\n+      ir::IRContext::kAnalysisCFG);\n+\n+  return loop_preheader_;\n+}\n+\n+void Loop::SetLatchBlock(BasicBlock* latch) {\n+#ifndef NDEBUG\n+  assert(latch->GetParent() && \"The basic block does not belong to a function\");\n+\n+  latch->ForEachSuccessorLabel([this](uint32_t id) {\n+    assert((!IsInsideLoop(id) || id == GetHeaderBlock()->id()) &&\n+           \"A predecessor of the continue block does not belong to the loop\");\n+  });\n+#endif  // NDEBUG\n+  assert(IsInsideLoop(latch) && \"The continue block is not in the loop\");\n+\n+  SetLatchBlockImpl(latch);\n+}\n+\n+void Loop::SetMergeBlock(BasicBlock* merge) {\n+#ifndef NDEBUG\n+  assert(merge->GetParent() && \"The basic block does not belong to a function\");\n+  CFG& cfg = *merge->GetParent()->GetParent()->context()->cfg();\n+\n+  for (uint32_t pred : cfg.preds(merge->id())) {\n+    assert(IsInsideLoop(pred) &&\n+           \"A predecessor of the merge block does not belong to the loop\");\n+  }\n+#endif  // NDEBUG\n+  assert(!IsInsideLoop(merge) && \"The merge block is in the loop\");","path":"source/opt/loop_descriptor.cpp","position":137,"original_position":137,"commit_id":"cd106077ed508b43257dcb7f23a0b14f3b9aeb14","original_commit_id":"cd106077ed508b43257dcb7f23a0b14f3b9aeb14","user":{"login":"dnovillo","id":7295335,"avatar_url":"https://avatars1.githubusercontent.com/u/7295335?v=4","gravatar_id":"","url":"https://api.github.com/users/dnovillo","html_url":"https://github.com/dnovillo","followers_url":"https://api.github.com/users/dnovillo/followers","following_url":"https://api.github.com/users/dnovillo/following{/other_user}","gists_url":"https://api.github.com/users/dnovillo/gists{/gist_id}","starred_url":"https://api.github.com/users/dnovillo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dnovillo/subscriptions","organizations_url":"https://api.github.com/users/dnovillo/orgs","repos_url":"https://api.github.com/users/dnovillo/repos","events_url":"https://api.github.com/users/dnovillo/events{/privacy}","received_events_url":"https://api.github.com/users/dnovillo/received_events","type":"User","site_admin":false},"body":"Might as well push this assert inside the #ifndef.","created_at":"2018-02-02T15:19:00Z","updated_at":"2018-02-02T15:31:12Z","html_url":"https://github.com/KhronosGroup/SPIRV-Tools/pull/1238#discussion_r165671915","pull_request_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/1238","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/comments/165671915"},"html":{"href":"https://github.com/KhronosGroup/SPIRV-Tools/pull/1238#discussion_r165671915"},"pull_request":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/1238"}}},"pull_request":{"url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/1238","id":165417006,"html_url":"https://github.com/KhronosGroup/SPIRV-Tools/pull/1238","diff_url":"https://github.com/KhronosGroup/SPIRV-Tools/pull/1238.diff","patch_url":"https://github.com/KhronosGroup/SPIRV-Tools/pull/1238.patch","issue_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/1238","number":1238,"state":"closed","locked":false,"title":"Add LoopUtils class to gather some loop transformation support","user":{"login":"Naghasan","id":8445943,"avatar_url":"https://avatars1.githubusercontent.com/u/8445943?v=4","gravatar_id":"","url":"https://api.github.com/users/Naghasan","html_url":"https://github.com/Naghasan","followers_url":"https://api.github.com/users/Naghasan/followers","following_url":"https://api.github.com/users/Naghasan/following{/other_user}","gists_url":"https://api.github.com/users/Naghasan/gists{/gist_id}","starred_url":"https://api.github.com/users/Naghasan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Naghasan/subscriptions","organizations_url":"https://api.github.com/users/Naghasan/orgs","repos_url":"https://api.github.com/users/Naghasan/repos","events_url":"https://api.github.com/users/Naghasan/events{/privacy}","received_events_url":"https://api.github.com/users/Naghasan/received_events","type":"User","site_admin":false},"body":"This patch adds LoopUtils class to handle some loop related transformations. For now it has 2 transformations that will simplifies other transformations such as loop unroll or unswitch:\r\n - Dedicate exit blocks: this ensure that all exit basic block (out-of-loop basic blocks that have a predecessor in the loop) have all their predecessors in the loop;\r\n - Loop Closed SSA (LCSSA): this ensure that all definitions in a loop are used inside the loop or in a phi instruction in an exit basic block.\r\n\r\nIt also adds the following capabilities:\r\n - Loop::IsLCSSA to test if the loop is in a LCSSA form\r\n - Loop::GetOrCreatePreHeaderBlock that can build a loop preheader if required;\r\n - New methods to allow on the fly updates of the loop descriptors.\r\n - New methods to allow on the fly updates of the CFG analysis.\r\n - Instruction::SetOperand to allow expression of the index relative to Instruction::NumOperands (to be compatible with the index returned by DefUseManager::ForEachUse)","created_at":"2018-01-26T17:22:34Z","updated_at":"2018-02-02T15:31:13Z","closed_at":"2018-02-01T20:38:29Z","merged_at":null,"merge_commit_sha":"dc4b3b828bb9943f139b0ccce997d484b2f88778","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"milestone":null,"commits_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/1238/commits","review_comments_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/1238/comments","review_comment_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/comments{/number}","comments_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/1238/comments","statuses_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/statuses/cd106077ed508b43257dcb7f23a0b14f3b9aeb14","head":{"label":"codeplaysoftware:loop-utils","ref":"loop-utils","sha":"cd106077ed508b43257dcb7f23a0b14f3b9aeb14","user":{"login":"codeplaysoftware","id":7440916,"avatar_url":"https://avatars0.githubusercontent.com/u/7440916?v=4","gravatar_id":"","url":"https://api.github.com/users/codeplaysoftware","html_url":"https://github.com/codeplaysoftware","followers_url":"https://api.github.com/users/codeplaysoftware/followers","following_url":"https://api.github.com/users/codeplaysoftware/following{/other_user}","gists_url":"https://api.github.com/users/codeplaysoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/codeplaysoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codeplaysoftware/subscriptions","organizations_url":"https://api.github.com/users/codeplaysoftware/orgs","repos_url":"https://api.github.com/users/codeplaysoftware/repos","events_url":"https://api.github.com/users/codeplaysoftware/events{/privacy}","received_events_url":"https://api.github.com/users/codeplaysoftware/received_events","type":"Organization","site_admin":false},"repo":{"id":110717765,"name":"SPIRV-Tools","full_name":"codeplaysoftware/SPIRV-Tools","owner":{"login":"codeplaysoftware","id":7440916,"avatar_url":"https://avatars0.githubusercontent.com/u/7440916?v=4","gravatar_id":"","url":"https://api.github.com/users/codeplaysoftware","html_url":"https://github.com/codeplaysoftware","followers_url":"https://api.github.com/users/codeplaysoftware/followers","following_url":"https://api.github.com/users/codeplaysoftware/following{/other_user}","gists_url":"https://api.github.com/users/codeplaysoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/codeplaysoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codeplaysoftware/subscriptions","organizations_url":"https://api.github.com/users/codeplaysoftware/orgs","repos_url":"https://api.github.com/users/codeplaysoftware/repos","events_url":"https://api.github.com/users/codeplaysoftware/events{/privacy}","received_events_url":"https://api.github.com/users/codeplaysoftware/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codeplaysoftware/SPIRV-Tools","description":null,"fork":true,"url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools","forks_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/forks","keys_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/teams","hooks_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/hooks","issue_events_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/issues/events{/number}","events_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/events","assignees_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/assignees{/user}","branches_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/branches{/branch}","tags_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/tags","blobs_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/statuses/{sha}","languages_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/languages","stargazers_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/stargazers","contributors_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/contributors","subscribers_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/subscribers","subscription_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/subscription","commits_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/contents/{+path}","compare_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/merges","archive_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/downloads","issues_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/issues{/number}","pulls_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/pulls{/number}","milestones_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/milestones{/number}","notifications_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/labels{/name}","releases_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/releases{/id}","deployments_url":"https://api.github.com/repos/codeplaysoftware/SPIRV-Tools/deployments","created_at":"2017-11-14T16:45:53Z","updated_at":"2017-12-19T20:13:26Z","pushed_at":"2018-02-02T15:06:13Z","git_url":"git://github.com/codeplaysoftware/SPIRV-Tools.git","ssh_url":"git@github.com:codeplaysoftware/SPIRV-Tools.git","clone_url":"https://github.com/codeplaysoftware/SPIRV-Tools.git","svn_url":"https://github.com/codeplaysoftware/SPIRV-Tools","homepage":null,"size":6229,"stargazers_count":2,"watchers_count":2,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":2,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":0,"open_issues":2,"watchers":2,"default_branch":"testing_master"}},"base":{"label":"KhronosGroup:master","ref":"master","sha":"905536c5195bf311a55b8e8d22757cdb31502660","user":{"login":"KhronosGroup","id":1608701,"avatar_url":"https://avatars3.githubusercontent.com/u/1608701?v=4","gravatar_id":"","url":"https://api.github.com/users/KhronosGroup","html_url":"https://github.com/KhronosGroup","followers_url":"https://api.github.com/users/KhronosGroup/followers","following_url":"https://api.github.com/users/KhronosGroup/following{/other_user}","gists_url":"https://api.github.com/users/KhronosGroup/gists{/gist_id}","starred_url":"https://api.github.com/users/KhronosGroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KhronosGroup/subscriptions","organizations_url":"https://api.github.com/users/KhronosGroup/orgs","repos_url":"https://api.github.com/users/KhronosGroup/repos","events_url":"https://api.github.com/users/KhronosGroup/events{/privacy}","received_events_url":"https://api.github.com/users/KhronosGroup/received_events","type":"Organization","site_admin":false},"repo":{"id":45981801,"name":"SPIRV-Tools","full_name":"KhronosGroup/SPIRV-Tools","owner":{"login":"KhronosGroup","id":1608701,"avatar_url":"https://avatars3.githubusercontent.com/u/1608701?v=4","gravatar_id":"","url":"https://api.github.com/users/KhronosGroup","html_url":"https://github.com/KhronosGroup","followers_url":"https://api.github.com/users/KhronosGroup/followers","following_url":"https://api.github.com/users/KhronosGroup/following{/other_user}","gists_url":"https://api.github.com/users/KhronosGroup/gists{/gist_id}","starred_url":"https://api.github.com/users/KhronosGroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KhronosGroup/subscriptions","organizations_url":"https://api.github.com/users/KhronosGroup/orgs","repos_url":"https://api.github.com/users/KhronosGroup/repos","events_url":"https://api.github.com/users/KhronosGroup/events{/privacy}","received_events_url":"https://api.github.com/users/KhronosGroup/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/KhronosGroup/SPIRV-Tools","description":null,"fork":false,"url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools","forks_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/forks","keys_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/teams","hooks_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/hooks","issue_events_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/events{/number}","events_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/events","assignees_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/assignees{/user}","branches_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/branches{/branch}","tags_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/tags","blobs_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/statuses/{sha}","languages_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/languages","stargazers_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/stargazers","contributors_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/contributors","subscribers_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/subscribers","subscription_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/subscription","commits_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/contents/{+path}","compare_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/merges","archive_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/downloads","issues_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues{/number}","pulls_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls{/number}","milestones_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/milestones{/number}","notifications_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/labels{/name}","releases_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/releases{/id}","deployments_url":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/deployments","created_at":"2015-11-11T12:56:25Z","updated_at":"2018-02-01T08:01:33Z","pushed_at":"2018-02-02T15:30:44Z","git_url":"git://github.com/KhronosGroup/SPIRV-Tools.git","ssh_url":"git@github.com:KhronosGroup/SPIRV-Tools.git","clone_url":"https://github.com/KhronosGroup/SPIRV-Tools.git","svn_url":"https://github.com/KhronosGroup/SPIRV-Tools","homepage":null,"size":5657,"stargazers_count":248,"watchers_count":248,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":98,"mirror_url":null,"archived":false,"open_issues_count":164,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":98,"open_issues":164,"watchers":248,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/1238"},"html":{"href":"https://github.com/KhronosGroup/SPIRV-Tools/pull/1238"},"issue":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/1238"},"comments":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/issues/1238/comments"},"review_comments":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/1238/comments"},"review_comment":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/pulls/1238/commits"},"statuses":{"href":"https://api.github.com/repos/KhronosGroup/SPIRV-Tools/statuses/cd106077ed508b43257dcb7f23a0b14f3b9aeb14"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"dnovillo"}}