loop_descriptor.cpp 33 KB

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