loop_descriptor.cpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. // Copyright (c) 2017 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "source/opt/loop_descriptor.h"
  15. #include <algorithm>
  16. #include <iostream>
  17. #include <limits>
  18. #include <stack>
  19. #include <type_traits>
  20. #include <utility>
  21. #include <vector>
  22. #include "source/opt/cfg.h"
  23. #include "source/opt/constants.h"
  24. #include "source/opt/dominator_tree.h"
  25. #include "source/opt/ir_builder.h"
  26. #include "source/opt/ir_context.h"
  27. #include "source/opt/iterator.h"
  28. #include "source/opt/tree_iterator.h"
  29. #include "source/util/make_unique.h"
  30. namespace spvtools {
  31. namespace opt {
  32. // Takes in a phi instruction |induction| and the loop |header| and returns the
  33. // step operation of the loop.
  34. Instruction* Loop::GetInductionStepOperation(
  35. const Instruction* induction) const {
  36. // Induction must be a phi instruction.
  37. assert(induction->opcode() == SpvOpPhi);
  38. Instruction* step = nullptr;
  39. analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr();
  40. // Traverse the incoming operands of the phi instruction.
  41. for (uint32_t operand_id = 1; operand_id < induction->NumInOperands();
  42. operand_id += 2) {
  43. // Incoming edge.
  44. BasicBlock* incoming_block =
  45. context_->cfg()->block(induction->GetSingleWordInOperand(operand_id));
  46. // Check if the block is dominated by header, and thus coming from within
  47. // the loop.
  48. if (IsInsideLoop(incoming_block)) {
  49. step = def_use_manager->GetDef(
  50. induction->GetSingleWordInOperand(operand_id - 1));
  51. break;
  52. }
  53. }
  54. if (!step || !IsSupportedStepOp(step->opcode())) {
  55. return nullptr;
  56. }
  57. // The induction variable which binds the loop must only be modified once.
  58. uint32_t lhs = step->GetSingleWordInOperand(0);
  59. uint32_t rhs = step->GetSingleWordInOperand(1);
  60. // One of the left hand side or right hand side of the step instruction must
  61. // be the induction phi and the other must be an OpConstant.
  62. if (lhs != induction->result_id() && rhs != induction->result_id()) {
  63. return nullptr;
  64. }
  65. if (def_use_manager->GetDef(lhs)->opcode() != SpvOp::SpvOpConstant &&
  66. def_use_manager->GetDef(rhs)->opcode() != SpvOp::SpvOpConstant) {
  67. return nullptr;
  68. }
  69. return step;
  70. }
  71. // Returns true if the |step| operation is an induction variable step operation
  72. // which is currently handled.
  73. bool Loop::IsSupportedStepOp(SpvOp step) const {
  74. switch (step) {
  75. case SpvOp::SpvOpISub:
  76. case SpvOp::SpvOpIAdd:
  77. return true;
  78. default:
  79. return false;
  80. }
  81. }
  82. bool Loop::IsSupportedCondition(SpvOp condition) const {
  83. switch (condition) {
  84. // <
  85. case SpvOp::SpvOpULessThan:
  86. case SpvOp::SpvOpSLessThan:
  87. // >
  88. case SpvOp::SpvOpUGreaterThan:
  89. case SpvOp::SpvOpSGreaterThan:
  90. // >=
  91. case SpvOp::SpvOpSGreaterThanEqual:
  92. case SpvOp::SpvOpUGreaterThanEqual:
  93. // <=
  94. case SpvOp::SpvOpSLessThanEqual:
  95. case SpvOp::SpvOpULessThanEqual:
  96. return true;
  97. default:
  98. return false;
  99. }
  100. }
  101. int64_t Loop::GetResidualConditionValue(SpvOp condition, int64_t initial_value,
  102. int64_t step_value,
  103. size_t number_of_iterations,
  104. size_t factor) {
  105. int64_t remainder =
  106. initial_value + (number_of_iterations % factor) * step_value;
  107. // We subtract or add one as the above formula calculates the remainder if the
  108. // loop where just less than or greater than. Adding or subtracting one should
  109. // give a functionally equivalent value.
  110. switch (condition) {
  111. case SpvOp::SpvOpSGreaterThanEqual:
  112. case SpvOp::SpvOpUGreaterThanEqual: {
  113. remainder -= 1;
  114. break;
  115. }
  116. case SpvOp::SpvOpSLessThanEqual:
  117. case SpvOp::SpvOpULessThanEqual: {
  118. remainder += 1;
  119. break;
  120. }
  121. default:
  122. break;
  123. }
  124. return remainder;
  125. }
  126. Instruction* Loop::GetConditionInst() const {
  127. BasicBlock* condition_block = FindConditionBlock();
  128. if (!condition_block) {
  129. return nullptr;
  130. }
  131. Instruction* branch_conditional = &*condition_block->tail();
  132. if (!branch_conditional ||
  133. branch_conditional->opcode() != SpvOpBranchConditional) {
  134. return nullptr;
  135. }
  136. Instruction* condition_inst = context_->get_def_use_mgr()->GetDef(
  137. branch_conditional->GetSingleWordInOperand(0));
  138. if (IsSupportedCondition(condition_inst->opcode())) {
  139. return condition_inst;
  140. }
  141. return nullptr;
  142. }
  143. // Extract the initial value from the |induction| OpPhi instruction and store it
  144. // in |value|. If the function couldn't find the initial value of |induction|
  145. // return false.
  146. bool Loop::GetInductionInitValue(const Instruction* induction,
  147. int64_t* value) const {
  148. Instruction* constant_instruction = nullptr;
  149. analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr();
  150. for (uint32_t operand_id = 0; operand_id < induction->NumInOperands();
  151. operand_id += 2) {
  152. BasicBlock* bb = context_->cfg()->block(
  153. induction->GetSingleWordInOperand(operand_id + 1));
  154. if (!IsInsideLoop(bb)) {
  155. constant_instruction = def_use_manager->GetDef(
  156. induction->GetSingleWordInOperand(operand_id));
  157. }
  158. }
  159. if (!constant_instruction) return false;
  160. const analysis::Constant* constant =
  161. context_->get_constant_mgr()->FindDeclaredConstant(
  162. constant_instruction->result_id());
  163. if (!constant) return false;
  164. if (value) {
  165. const analysis::Integer* type = constant->type()->AsInteger();
  166. if (!type) {
  167. return false;
  168. }
  169. *value = type->IsSigned() ? constant->GetSignExtendedValue()
  170. : constant->GetZeroExtendedValue();
  171. }
  172. return true;
  173. }
  174. Loop::Loop(IRContext* context, DominatorAnalysis* dom_analysis,
  175. BasicBlock* header, BasicBlock* continue_target,
  176. BasicBlock* merge_target)
  177. : context_(context),
  178. loop_header_(header),
  179. loop_continue_(continue_target),
  180. loop_merge_(merge_target),
  181. loop_preheader_(nullptr),
  182. parent_(nullptr),
  183. loop_is_marked_for_removal_(false) {
  184. assert(context);
  185. assert(dom_analysis);
  186. loop_preheader_ = FindLoopPreheader(dom_analysis);
  187. loop_latch_ = FindLatchBlock();
  188. }
  189. BasicBlock* Loop::FindLoopPreheader(DominatorAnalysis* dom_analysis) {
  190. CFG* cfg = context_->cfg();
  191. DominatorTree& dom_tree = dom_analysis->GetDomTree();
  192. DominatorTreeNode* header_node = dom_tree.GetTreeNode(loop_header_);
  193. // The loop predecessor.
  194. BasicBlock* loop_pred = nullptr;
  195. auto header_pred = cfg->preds(loop_header_->id());
  196. for (uint32_t p_id : header_pred) {
  197. DominatorTreeNode* node = dom_tree.GetTreeNode(p_id);
  198. if (node && !dom_tree.Dominates(header_node, node)) {
  199. // The predecessor is not part of the loop, so potential loop preheader.
  200. if (loop_pred && node->bb_ != loop_pred) {
  201. // If we saw 2 distinct predecessors that are outside the loop, we don't
  202. // have a loop preheader.
  203. return nullptr;
  204. }
  205. loop_pred = node->bb_;
  206. }
  207. }
  208. // Safe guard against invalid code, SPIR-V spec forbids loop with the entry
  209. // node as header.
  210. assert(loop_pred && "The header node is the entry block ?");
  211. // So we have a unique basic block that can enter this loop.
  212. // If this loop is the unique successor of this block, then it is a loop
  213. // preheader.
  214. bool is_preheader = true;
  215. uint32_t loop_header_id = loop_header_->id();
  216. const auto* const_loop_pred = loop_pred;
  217. const_loop_pred->ForEachSuccessorLabel(
  218. [&is_preheader, loop_header_id](const uint32_t id) {
  219. if (id != loop_header_id) is_preheader = false;
  220. });
  221. if (is_preheader) return loop_pred;
  222. return nullptr;
  223. }
  224. bool Loop::IsInsideLoop(Instruction* inst) const {
  225. const BasicBlock* parent_block = context_->get_instr_block(inst);
  226. if (!parent_block) return false;
  227. return IsInsideLoop(parent_block);
  228. }
  229. bool Loop::IsBasicBlockInLoopSlow(const BasicBlock* bb) {
  230. assert(bb->GetParent() && "The basic block does not belong to a function");
  231. DominatorAnalysis* dom_analysis =
  232. context_->GetDominatorAnalysis(bb->GetParent());
  233. if (dom_analysis->IsReachable(bb) &&
  234. !dom_analysis->Dominates(GetHeaderBlock(), bb))
  235. return false;
  236. return true;
  237. }
  238. BasicBlock* Loop::GetOrCreatePreHeaderBlock() {
  239. if (loop_preheader_) return loop_preheader_;
  240. CFG* cfg = context_->cfg();
  241. loop_header_ = cfg->SplitLoopHeader(loop_header_);
  242. return loop_preheader_;
  243. }
  244. void Loop::SetContinueBlock(BasicBlock* continue_block) {
  245. assert(IsInsideLoop(continue_block));
  246. loop_continue_ = continue_block;
  247. }
  248. void Loop::SetLatchBlock(BasicBlock* latch) {
  249. #ifndef NDEBUG
  250. assert(latch->GetParent() && "The basic block does not belong to a function");
  251. const auto* const_latch = latch;
  252. const_latch->ForEachSuccessorLabel([this](uint32_t id) {
  253. assert((!IsInsideLoop(id) || id == GetHeaderBlock()->id()) &&
  254. "A predecessor of the continue block does not belong to the loop");
  255. });
  256. #endif // NDEBUG
  257. assert(IsInsideLoop(latch) && "The continue block is not in the loop");
  258. SetLatchBlockImpl(latch);
  259. }
  260. void Loop::SetMergeBlock(BasicBlock* merge) {
  261. #ifndef NDEBUG
  262. assert(merge->GetParent() && "The basic block does not belong to a function");
  263. #endif // NDEBUG
  264. assert(!IsInsideLoop(merge) && "The merge block is in the loop");
  265. SetMergeBlockImpl(merge);
  266. if (GetHeaderBlock()->GetLoopMergeInst()) {
  267. UpdateLoopMergeInst();
  268. }
  269. }
  270. void Loop::SetPreHeaderBlock(BasicBlock* preheader) {
  271. if (preheader) {
  272. assert(!IsInsideLoop(preheader) && "The preheader block is in the loop");
  273. assert(preheader->tail()->opcode() == SpvOpBranch &&
  274. "The preheader block does not unconditionally branch to the header "
  275. "block");
  276. assert(preheader->tail()->GetSingleWordOperand(0) ==
  277. GetHeaderBlock()->id() &&
  278. "The preheader block does not unconditionally branch to the header "
  279. "block");
  280. }
  281. loop_preheader_ = preheader;
  282. }
  283. BasicBlock* Loop::FindLatchBlock() {
  284. CFG* cfg = context_->cfg();
  285. DominatorAnalysis* dominator_analysis =
  286. context_->GetDominatorAnalysis(loop_header_->GetParent());
  287. // Look at the predecessors of the loop header to find a predecessor block
  288. // which is dominated by the loop continue target. There should only be one
  289. // block which meets this criteria and this is the latch block, as per the
  290. // SPIR-V spec.
  291. for (uint32_t block_id : cfg->preds(loop_header_->id())) {
  292. if (dominator_analysis->Dominates(loop_continue_->id(), block_id)) {
  293. return cfg->block(block_id);
  294. }
  295. }
  296. assert(
  297. false &&
  298. "Every loop should have a latch block dominated by the continue target");
  299. return nullptr;
  300. }
  301. void Loop::GetExitBlocks(std::unordered_set<uint32_t>* exit_blocks) const {
  302. CFG* cfg = context_->cfg();
  303. exit_blocks->clear();
  304. for (uint32_t bb_id : GetBlocks()) {
  305. const BasicBlock* bb = cfg->block(bb_id);
  306. bb->ForEachSuccessorLabel([exit_blocks, this](uint32_t succ) {
  307. if (!IsInsideLoop(succ)) {
  308. exit_blocks->insert(succ);
  309. }
  310. });
  311. }
  312. }
  313. void Loop::GetMergingBlocks(
  314. std::unordered_set<uint32_t>* merging_blocks) const {
  315. assert(GetMergeBlock() && "This loop is not structured");
  316. CFG* cfg = context_->cfg();
  317. merging_blocks->clear();
  318. std::stack<const BasicBlock*> to_visit;
  319. to_visit.push(GetMergeBlock());
  320. while (!to_visit.empty()) {
  321. const BasicBlock* bb = to_visit.top();
  322. to_visit.pop();
  323. merging_blocks->insert(bb->id());
  324. for (uint32_t pred_id : cfg->preds(bb->id())) {
  325. if (!IsInsideLoop(pred_id) && !merging_blocks->count(pred_id)) {
  326. to_visit.push(cfg->block(pred_id));
  327. }
  328. }
  329. }
  330. }
  331. namespace {
  332. static inline bool IsBasicBlockSafeToClone(IRContext* context, BasicBlock* bb) {
  333. for (Instruction& inst : *bb) {
  334. if (!inst.IsBranch() && !context->IsCombinatorInstruction(&inst))
  335. return false;
  336. }
  337. return true;
  338. }
  339. } // namespace
  340. bool Loop::IsSafeToClone() const {
  341. CFG& cfg = *context_->cfg();
  342. for (uint32_t bb_id : GetBlocks()) {
  343. BasicBlock* bb = cfg.block(bb_id);
  344. assert(bb);
  345. if (!IsBasicBlockSafeToClone(context_, bb)) return false;
  346. }
  347. // Look at the merge construct.
  348. if (GetHeaderBlock()->GetLoopMergeInst()) {
  349. std::unordered_set<uint32_t> blocks;
  350. GetMergingBlocks(&blocks);
  351. blocks.erase(GetMergeBlock()->id());
  352. for (uint32_t bb_id : blocks) {
  353. BasicBlock* bb = cfg.block(bb_id);
  354. assert(bb);
  355. if (!IsBasicBlockSafeToClone(context_, bb)) return false;
  356. }
  357. }
  358. return true;
  359. }
  360. bool Loop::IsLCSSA() const {
  361. CFG* cfg = context_->cfg();
  362. analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
  363. std::unordered_set<uint32_t> exit_blocks;
  364. GetExitBlocks(&exit_blocks);
  365. // Declare ir_context so we can capture context_ in the below lambda
  366. IRContext* ir_context = context_;
  367. for (uint32_t bb_id : GetBlocks()) {
  368. for (Instruction& insn : *cfg->block(bb_id)) {
  369. // All uses must be either:
  370. // - In the loop;
  371. // - In an exit block and in a phi instruction.
  372. if (!def_use_mgr->WhileEachUser(
  373. &insn,
  374. [&exit_blocks, ir_context, this](Instruction* use) -> bool {
  375. BasicBlock* parent = ir_context->get_instr_block(use);
  376. assert(parent && "Invalid analysis");
  377. if (IsInsideLoop(parent)) return true;
  378. if (use->opcode() != SpvOpPhi) return false;
  379. return exit_blocks.count(parent->id());
  380. }))
  381. return false;
  382. }
  383. }
  384. return true;
  385. }
  386. bool Loop::ShouldHoistInstruction(IRContext* context, Instruction* inst) {
  387. return AreAllOperandsOutsideLoop(context, inst) &&
  388. inst->IsOpcodeCodeMotionSafe();
  389. }
  390. bool Loop::AreAllOperandsOutsideLoop(IRContext* context, Instruction* inst) {
  391. analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
  392. bool all_outside_loop = true;
  393. const std::function<void(uint32_t*)> operand_outside_loop =
  394. [this, &def_use_mgr, &all_outside_loop](uint32_t* id) {
  395. if (this->IsInsideLoop(def_use_mgr->GetDef(*id))) {
  396. all_outside_loop = false;
  397. return;
  398. }
  399. };
  400. inst->ForEachInId(operand_outside_loop);
  401. return all_outside_loop;
  402. }
  403. void Loop::ComputeLoopStructuredOrder(
  404. std::vector<BasicBlock*>* ordered_loop_blocks, bool include_pre_header,
  405. bool include_merge) const {
  406. CFG& cfg = *context_->cfg();
  407. // Reserve the memory: all blocks in the loop + extra if needed.
  408. ordered_loop_blocks->reserve(GetBlocks().size() + include_pre_header +
  409. include_merge);
  410. if (include_pre_header && GetPreHeaderBlock())
  411. ordered_loop_blocks->push_back(loop_preheader_);
  412. bool is_shader =
  413. context_->get_feature_mgr()->HasCapability(SpvCapabilityShader);
  414. if (!is_shader) {
  415. cfg.ForEachBlockInReversePostOrder(
  416. loop_header_, [ordered_loop_blocks, this](BasicBlock* bb) {
  417. if (IsInsideLoop(bb)) ordered_loop_blocks->push_back(bb);
  418. });
  419. } else {
  420. // If this is a shader, it is possible that there are unreachable merge and
  421. // continue blocks that must be copied to retain the structured order.
  422. // The structured order will include these.
  423. std::list<BasicBlock*> order;
  424. cfg.ComputeStructuredOrder(loop_header_->GetParent(), loop_header_,
  425. loop_merge_, &order);
  426. for (BasicBlock* bb : order) {
  427. if (bb == GetMergeBlock()) {
  428. break;
  429. }
  430. ordered_loop_blocks->push_back(bb);
  431. }
  432. }
  433. if (include_merge && GetMergeBlock())
  434. ordered_loop_blocks->push_back(loop_merge_);
  435. }
  436. LoopDescriptor::LoopDescriptor(IRContext* context, const Function* f)
  437. : loops_(), placeholder_top_loop_(nullptr) {
  438. PopulateList(context, f);
  439. }
  440. LoopDescriptor::~LoopDescriptor() { ClearLoops(); }
  441. void LoopDescriptor::PopulateList(IRContext* context, const Function* f) {
  442. DominatorAnalysis* dom_analysis = context->GetDominatorAnalysis(f);
  443. ClearLoops();
  444. // Post-order traversal of the dominator tree to find all the OpLoopMerge
  445. // instructions.
  446. DominatorTree& dom_tree = dom_analysis->GetDomTree();
  447. for (DominatorTreeNode& node :
  448. make_range(dom_tree.post_begin(), dom_tree.post_end())) {
  449. Instruction* merge_inst = node.bb_->GetLoopMergeInst();
  450. if (merge_inst) {
  451. bool all_backedge_unreachable = true;
  452. for (uint32_t pid : context->cfg()->preds(node.bb_->id())) {
  453. if (dom_analysis->IsReachable(pid) &&
  454. dom_analysis->Dominates(node.bb_->id(), pid)) {
  455. all_backedge_unreachable = false;
  456. break;
  457. }
  458. }
  459. if (all_backedge_unreachable)
  460. continue; // ignore this one, we actually never branch back.
  461. // The id of the merge basic block of this loop.
  462. uint32_t merge_bb_id = merge_inst->GetSingleWordOperand(0);
  463. // The id of the continue basic block of this loop.
  464. uint32_t continue_bb_id = merge_inst->GetSingleWordOperand(1);
  465. // The merge target of this loop.
  466. BasicBlock* merge_bb = context->cfg()->block(merge_bb_id);
  467. // The continue target of this loop.
  468. BasicBlock* continue_bb = context->cfg()->block(continue_bb_id);
  469. // The basic block containing the merge instruction.
  470. BasicBlock* header_bb = context->get_instr_block(merge_inst);
  471. // Add the loop to the list of all the loops in the function.
  472. Loop* current_loop =
  473. new Loop(context, dom_analysis, header_bb, continue_bb, merge_bb);
  474. loops_.push_back(current_loop);
  475. // We have a bottom-up construction, so if this loop has nested-loops,
  476. // they are by construction at the tail of the loop list.
  477. for (auto itr = loops_.rbegin() + 1; itr != loops_.rend(); ++itr) {
  478. Loop* previous_loop = *itr;
  479. // If the loop already has a parent, then it has been processed.
  480. if (previous_loop->HasParent()) continue;
  481. // If the current loop does not dominates the previous loop then it is
  482. // not nested loop.
  483. if (!dom_analysis->Dominates(header_bb,
  484. previous_loop->GetHeaderBlock()))
  485. continue;
  486. // If the current loop merge dominates the previous loop then it is
  487. // not nested loop.
  488. if (dom_analysis->Dominates(merge_bb, previous_loop->GetHeaderBlock()))
  489. continue;
  490. current_loop->AddNestedLoop(previous_loop);
  491. }
  492. DominatorTreeNode* dom_merge_node = dom_tree.GetTreeNode(merge_bb);
  493. for (DominatorTreeNode& loop_node :
  494. make_range(node.df_begin(), node.df_end())) {
  495. // Check if we are in the loop.
  496. if (dom_tree.Dominates(dom_merge_node, &loop_node)) continue;
  497. current_loop->AddBasicBlock(loop_node.bb_);
  498. basic_block_to_loop_.insert(
  499. std::make_pair(loop_node.bb_->id(), current_loop));
  500. }
  501. }
  502. }
  503. for (Loop* loop : loops_) {
  504. if (!loop->HasParent()) placeholder_top_loop_.nested_loops_.push_back(loop);
  505. }
  506. }
  507. std::vector<Loop*> LoopDescriptor::GetLoopsInBinaryLayoutOrder() {
  508. std::vector<uint32_t> ids{};
  509. for (size_t i = 0; i < NumLoops(); ++i) {
  510. ids.push_back(GetLoopByIndex(i).GetHeaderBlock()->id());
  511. }
  512. std::vector<Loop*> loops{};
  513. if (!ids.empty()) {
  514. auto function = GetLoopByIndex(0).GetHeaderBlock()->GetParent();
  515. for (const auto& block : *function) {
  516. auto block_id = block.id();
  517. auto element = std::find(std::begin(ids), std::end(ids), block_id);
  518. if (element != std::end(ids)) {
  519. loops.push_back(&GetLoopByIndex(element - std::begin(ids)));
  520. }
  521. }
  522. }
  523. return loops;
  524. }
  525. BasicBlock* Loop::FindConditionBlock() const {
  526. if (!loop_merge_) {
  527. return nullptr;
  528. }
  529. BasicBlock* condition_block = nullptr;
  530. uint32_t in_loop_pred = 0;
  531. for (uint32_t p : context_->cfg()->preds(loop_merge_->id())) {
  532. if (IsInsideLoop(p)) {
  533. if (in_loop_pred) {
  534. // 2 in-loop predecessors.
  535. return nullptr;
  536. }
  537. in_loop_pred = p;
  538. }
  539. }
  540. if (!in_loop_pred) {
  541. // Merge block is unreachable.
  542. return nullptr;
  543. }
  544. BasicBlock* bb = context_->cfg()->block(in_loop_pred);
  545. if (!bb) return nullptr;
  546. const Instruction& branch = *bb->ctail();
  547. // Make sure the branch is a conditional branch.
  548. if (branch.opcode() != SpvOpBranchConditional) return nullptr;
  549. // Make sure one of the two possible branches is to the merge block.
  550. if (branch.GetSingleWordInOperand(1) == loop_merge_->id() ||
  551. branch.GetSingleWordInOperand(2) == loop_merge_->id()) {
  552. condition_block = bb;
  553. }
  554. return condition_block;
  555. }
  556. bool Loop::FindNumberOfIterations(const Instruction* induction,
  557. const Instruction* branch_inst,
  558. size_t* iterations_out,
  559. int64_t* step_value_out,
  560. int64_t* init_value_out) const {
  561. // From the branch instruction find the branch condition.
  562. analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr();
  563. // Condition instruction from the OpConditionalBranch.
  564. Instruction* condition =
  565. def_use_manager->GetDef(branch_inst->GetSingleWordOperand(0));
  566. assert(IsSupportedCondition(condition->opcode()));
  567. // Get the constant manager from the ir context.
  568. analysis::ConstantManager* const_manager = context_->get_constant_mgr();
  569. // Find the constant value used by the condition variable. Exit out if it
  570. // isn't a constant int.
  571. const analysis::Constant* upper_bound =
  572. const_manager->FindDeclaredConstant(condition->GetSingleWordOperand(3));
  573. if (!upper_bound) return false;
  574. // Must be integer because of the opcode on the condition.
  575. const analysis::Integer* type = upper_bound->type()->AsInteger();
  576. if (!type || type->width() > 64) {
  577. return false;
  578. }
  579. int64_t condition_value = type->IsSigned()
  580. ? upper_bound->GetSignExtendedValue()
  581. : upper_bound->GetZeroExtendedValue();
  582. // Find the instruction which is stepping through the loop.
  583. //
  584. // GetInductionStepOperation returns nullptr if |step_inst| is OpConstantNull.
  585. Instruction* step_inst = GetInductionStepOperation(induction);
  586. if (!step_inst) return false;
  587. // Find the constant value used by the condition variable.
  588. const analysis::Constant* step_constant =
  589. const_manager->FindDeclaredConstant(step_inst->GetSingleWordOperand(3));
  590. if (!step_constant) return false;
  591. // Must be integer because of the opcode on the condition.
  592. int64_t step_value = 0;
  593. const analysis::Integer* step_type =
  594. step_constant->AsIntConstant()->type()->AsInteger();
  595. if (step_type->IsSigned()) {
  596. step_value = step_constant->AsIntConstant()->GetS32BitValue();
  597. } else {
  598. step_value = step_constant->AsIntConstant()->GetU32BitValue();
  599. }
  600. // If this is a subtraction step we should negate the step value.
  601. if (step_inst->opcode() == SpvOp::SpvOpISub) {
  602. step_value = -step_value;
  603. }
  604. // Find the initial value of the loop and make sure it is a constant integer.
  605. int64_t init_value = 0;
  606. if (!GetInductionInitValue(induction, &init_value)) return false;
  607. // If iterations is non null then store the value in that.
  608. int64_t num_itrs = GetIterations(condition->opcode(), condition_value,
  609. init_value, step_value);
  610. // If the loop body will not be reached return false.
  611. if (num_itrs <= 0) {
  612. return false;
  613. }
  614. if (iterations_out) {
  615. assert(static_cast<size_t>(num_itrs) <= std::numeric_limits<size_t>::max());
  616. *iterations_out = static_cast<size_t>(num_itrs);
  617. }
  618. if (step_value_out) {
  619. *step_value_out = step_value;
  620. }
  621. if (init_value_out) {
  622. *init_value_out = init_value;
  623. }
  624. return true;
  625. }
  626. // We retrieve the number of iterations using the following formula, diff /
  627. // |step_value| where diff is calculated differently according to the
  628. // |condition| and uses the |condition_value| and |init_value|. If diff /
  629. // |step_value| is NOT cleanly divisible then we add one to the sum.
  630. int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value,
  631. int64_t init_value, int64_t step_value) const {
  632. if (step_value == 0) {
  633. return 0;
  634. }
  635. int64_t diff = 0;
  636. switch (condition) {
  637. case SpvOp::SpvOpSLessThan:
  638. case SpvOp::SpvOpULessThan: {
  639. // If the condition is not met to begin with the loop will never iterate.
  640. if (!(init_value < condition_value)) return 0;
  641. diff = condition_value - init_value;
  642. // If the operation is a less then operation then the diff and step must
  643. // have the same sign otherwise the induction will never cross the
  644. // condition (either never true or always true).
  645. if ((diff < 0 && step_value > 0) || (diff > 0 && step_value < 0)) {
  646. return 0;
  647. }
  648. break;
  649. }
  650. case SpvOp::SpvOpSGreaterThan:
  651. case SpvOp::SpvOpUGreaterThan: {
  652. // If the condition is not met to begin with the loop will never iterate.
  653. if (!(init_value > condition_value)) return 0;
  654. diff = init_value - condition_value;
  655. // If the operation is a greater than operation then the diff and step
  656. // must have opposite signs. Otherwise the condition will always be true
  657. // or will never be true.
  658. if ((diff < 0 && step_value < 0) || (diff > 0 && step_value > 0)) {
  659. return 0;
  660. }
  661. break;
  662. }
  663. case SpvOp::SpvOpSGreaterThanEqual:
  664. case SpvOp::SpvOpUGreaterThanEqual: {
  665. // If the condition is not met to begin with the loop will never iterate.
  666. if (!(init_value >= condition_value)) return 0;
  667. // We subtract one to make it the same as SpvOpGreaterThan as it is
  668. // functionally equivalent.
  669. diff = init_value - (condition_value - 1);
  670. // If the operation is a greater than operation then the diff and step
  671. // must have opposite signs. Otherwise the condition will always be true
  672. // or will never be true.
  673. if ((diff > 0 && step_value > 0) || (diff < 0 && step_value < 0)) {
  674. return 0;
  675. }
  676. break;
  677. }
  678. case SpvOp::SpvOpSLessThanEqual:
  679. case SpvOp::SpvOpULessThanEqual: {
  680. // If the condition is not met to begin with the loop will never iterate.
  681. if (!(init_value <= condition_value)) return 0;
  682. // We add one to make it the same as SpvOpLessThan as it is functionally
  683. // equivalent.
  684. diff = (condition_value + 1) - init_value;
  685. // If the operation is a less than operation then the diff and step must
  686. // have the same sign otherwise the induction will never cross the
  687. // condition (either never true or always true).
  688. if ((diff < 0 && step_value > 0) || (diff > 0 && step_value < 0)) {
  689. return 0;
  690. }
  691. break;
  692. }
  693. default:
  694. assert(false &&
  695. "Could not retrieve number of iterations from the loop condition. "
  696. "Condition is not supported.");
  697. }
  698. // Take the abs of - step values.
  699. step_value = llabs(step_value);
  700. diff = llabs(diff);
  701. int64_t result = diff / step_value;
  702. if (diff % step_value != 0) {
  703. result += 1;
  704. }
  705. return result;
  706. }
  707. // Returns the list of induction variables within the loop.
  708. void Loop::GetInductionVariables(
  709. std::vector<Instruction*>& induction_variables) const {
  710. for (Instruction& inst : *loop_header_) {
  711. if (inst.opcode() == SpvOp::SpvOpPhi) {
  712. induction_variables.push_back(&inst);
  713. }
  714. }
  715. }
  716. Instruction* Loop::FindConditionVariable(
  717. const BasicBlock* condition_block) const {
  718. // Find the branch instruction.
  719. const Instruction& branch_inst = *condition_block->ctail();
  720. Instruction* induction = nullptr;
  721. // Verify that the branch instruction is a conditional branch.
  722. if (branch_inst.opcode() == SpvOp::SpvOpBranchConditional) {
  723. // From the branch instruction find the branch condition.
  724. analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr();
  725. // Find the instruction representing the condition used in the conditional
  726. // branch.
  727. Instruction* condition =
  728. def_use_manager->GetDef(branch_inst.GetSingleWordOperand(0));
  729. // Ensure that the condition is a less than operation.
  730. if (condition && IsSupportedCondition(condition->opcode())) {
  731. // The left hand side operand of the operation.
  732. Instruction* variable_inst =
  733. def_use_manager->GetDef(condition->GetSingleWordOperand(2));
  734. // Make sure the variable instruction used is a phi.
  735. if (!variable_inst || variable_inst->opcode() != SpvOpPhi) return nullptr;
  736. // Make sure the phi instruction only has two incoming blocks. Each
  737. // incoming block will be represented by two in operands in the phi
  738. // instruction, the value and the block which that value came from. We
  739. // assume the cannocalised phi will have two incoming values, one from the
  740. // preheader and one from the continue block.
  741. size_t max_supported_operands = 4;
  742. if (variable_inst->NumInOperands() == max_supported_operands) {
  743. // The operand index of the first incoming block label.
  744. uint32_t operand_label_1 = 1;
  745. // The operand index of the second incoming block label.
  746. uint32_t operand_label_2 = 3;
  747. // Make sure one of them is the preheader.
  748. if (!IsInsideLoop(
  749. variable_inst->GetSingleWordInOperand(operand_label_1)) &&
  750. !IsInsideLoop(
  751. variable_inst->GetSingleWordInOperand(operand_label_2))) {
  752. return nullptr;
  753. }
  754. // And make sure that the other is the latch block.
  755. if (variable_inst->GetSingleWordInOperand(operand_label_1) !=
  756. loop_latch_->id() &&
  757. variable_inst->GetSingleWordInOperand(operand_label_2) !=
  758. loop_latch_->id()) {
  759. return nullptr;
  760. }
  761. } else {
  762. return nullptr;
  763. }
  764. if (!FindNumberOfIterations(variable_inst, &branch_inst, nullptr))
  765. return nullptr;
  766. induction = variable_inst;
  767. }
  768. }
  769. return induction;
  770. }
  771. bool LoopDescriptor::CreatePreHeaderBlocksIfMissing() {
  772. auto modified = false;
  773. for (auto& loop : *this) {
  774. if (!loop.GetPreHeaderBlock()) {
  775. modified = true;
  776. // TODO(1841): Handle failure to create pre-header.
  777. loop.GetOrCreatePreHeaderBlock();
  778. }
  779. }
  780. return modified;
  781. }
  782. // Add and remove loops which have been marked for addition and removal to
  783. // maintain the state of the loop descriptor class.
  784. void LoopDescriptor::PostModificationCleanup() {
  785. LoopContainerType loops_to_remove_;
  786. for (Loop* loop : loops_) {
  787. if (loop->IsMarkedForRemoval()) {
  788. loops_to_remove_.push_back(loop);
  789. if (loop->HasParent()) {
  790. loop->GetParent()->RemoveChildLoop(loop);
  791. }
  792. }
  793. }
  794. for (Loop* loop : loops_to_remove_) {
  795. loops_.erase(std::find(loops_.begin(), loops_.end(), loop));
  796. delete loop;
  797. }
  798. for (auto& pair : loops_to_add_) {
  799. Loop* parent = pair.first;
  800. std::unique_ptr<Loop> loop = std::move(pair.second);
  801. if (parent) {
  802. loop->SetParent(nullptr);
  803. parent->AddNestedLoop(loop.get());
  804. for (uint32_t block_id : loop->GetBlocks()) {
  805. parent->AddBasicBlock(block_id);
  806. }
  807. }
  808. loops_.emplace_back(loop.release());
  809. }
  810. loops_to_add_.clear();
  811. }
  812. void LoopDescriptor::ClearLoops() {
  813. for (Loop* loop : loops_) {
  814. delete loop;
  815. }
  816. loops_.clear();
  817. }
  818. // Adds a new loop nest to the descriptor set.
  819. Loop* LoopDescriptor::AddLoopNest(std::unique_ptr<Loop> new_loop) {
  820. Loop* loop = new_loop.release();
  821. if (!loop->HasParent()) placeholder_top_loop_.nested_loops_.push_back(loop);
  822. // Iterate from inner to outer most loop, adding basic block to loop mapping
  823. // as we go.
  824. for (Loop& current_loop :
  825. make_range(iterator::begin(loop), iterator::end(nullptr))) {
  826. loops_.push_back(&current_loop);
  827. for (uint32_t bb_id : current_loop.GetBlocks())
  828. basic_block_to_loop_.insert(std::make_pair(bb_id, &current_loop));
  829. }
  830. return loop;
  831. }
  832. void LoopDescriptor::RemoveLoop(Loop* loop) {
  833. Loop* parent = loop->GetParent() ? loop->GetParent() : &placeholder_top_loop_;
  834. parent->nested_loops_.erase(std::find(parent->nested_loops_.begin(),
  835. parent->nested_loops_.end(), loop));
  836. std::for_each(
  837. loop->nested_loops_.begin(), loop->nested_loops_.end(),
  838. [loop](Loop* sub_loop) { sub_loop->SetParent(loop->GetParent()); });
  839. parent->nested_loops_.insert(parent->nested_loops_.end(),
  840. loop->nested_loops_.begin(),
  841. loop->nested_loops_.end());
  842. for (uint32_t bb_id : loop->GetBlocks()) {
  843. Loop* l = FindLoopForBasicBlock(bb_id);
  844. if (l == loop) {
  845. SetBasicBlockToLoop(bb_id, l->GetParent());
  846. } else {
  847. ForgetBasicBlock(bb_id);
  848. }
  849. }
  850. LoopContainerType::iterator it =
  851. std::find(loops_.begin(), loops_.end(), loop);
  852. assert(it != loops_.end());
  853. delete loop;
  854. loops_.erase(it);
  855. }
  856. } // namespace opt
  857. } // namespace spvtools