MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / MakeSetClosedSSA

Function MakeSetClosedSSA

source/opt/loop_utils.cpp:283–328  ·  view source on GitHub ↗

Make the set |blocks| closed SSA. The set is closed SSA if all the uses outside the set are phi instructions in exiting basic block set (hold by |lcssa_rewriter|).

Source from the content-addressed store, hash-verified

281// outside the set are phi instructions in exiting basic block set (hold by
282// |lcssa_rewriter|).
283inline bool MakeSetClosedSSA(IRContext* context, Function* function,
284 const std::unordered_set<uint32_t>& blocks,
285 const std::unordered_set<BasicBlock*>& exit_bb,
286 LCSSARewriter* lcssa_rewriter) {
287 CFG& cfg = *context->cfg();
288 DominatorTree& dom_tree =
289 context->GetDominatorAnalysis(function)->GetDomTree();
290 analysis::DefUseManager* def_use_manager = context->get_def_use_mgr();
291
292 for (uint32_t bb_id : blocks) {
293 BasicBlock* bb = cfg.block(bb_id);
294 // If bb does not dominate an exit block, then it cannot have escaping defs.
295 if (!DominatesAnExit(bb, exit_bb, dom_tree)) continue;
296 for (Instruction& inst : *bb) {
297 LCSSARewriter::UseRewriter rewriter(lcssa_rewriter, inst);
298 bool success = def_use_manager->WhileEachUse(
299 &inst, [&blocks, &rewriter, &exit_bb, context](
300 Instruction* use, uint32_t operand_index) {
301 BasicBlock* use_parent = context->get_instr_block(use);
302 assert(use_parent);
303 if (blocks.count(use_parent->id())) return true;
304
305 if (use->opcode() == spv::Op::OpPhi) {
306 // If the use is a Phi instruction and the incoming block is
307 // coming from the loop, then that's consistent with LCSSA form.
308 if (exit_bb.count(use_parent)) {
309 return true;
310 } else {
311 // That's not an exit block, but the user is a phi instruction.
312 // Consider the incoming branch only.
313 use_parent = context->get_instr_block(
314 use->GetSingleWordOperand(operand_index + 1));
315 }
316 }
317 // Rewrite the use. Note that this call does not invalidate the
318 // def/use manager. So this operation is safe.
319 return rewriter.RewriteUse(use_parent, use, operand_index);
320 });
321 if (!success) {
322 return false;
323 }
324 rewriter.UpdateManagers();
325 }
326 }
327 return true;
328}
329
330} // namespace
331

Callers 1

MakeLoopClosedSSAMethod · 0.85

Calls 13

DominatesAnExitFunction · 0.85
GetDominatorAnalysisMethod · 0.80
WhileEachUseMethod · 0.80
get_instr_blockMethod · 0.80
GetSingleWordOperandMethod · 0.80
RewriteUseMethod · 0.80
UpdateManagersMethod · 0.80
cfgMethod · 0.45
get_def_use_mgrMethod · 0.45
blockMethod · 0.45
countMethod · 0.45
idMethod · 0.45

Tested by

no test coverage detected