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

Method CanPerformSplit

source/opt/loop_fission.cpp:269–358  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

267}
268
269bool LoopFissionImpl::CanPerformSplit() {
270 // Return false if any of the condition instructions in the loop depend on a
271 // load.
272 if (load_used_in_condition_) {
273 return false;
274 }
275
276 // Build a list of all parent loops of this loop. Loop dependence analysis
277 // needs this structure.
278 std::vector<const Loop*> loops;
279 Loop* parent_loop = loop_;
280 while (parent_loop) {
281 loops.push_back(parent_loop);
282 parent_loop = parent_loop->GetParent();
283 }
284
285 LoopDependenceAnalysis analysis{context_, loops};
286
287 // A list of all the stores in the cloned loop.
288 std::vector<Instruction*> set_one_stores{};
289
290 // A list of all the loads in the cloned loop.
291 std::vector<Instruction*> set_one_loads{};
292
293 // Populate the above lists.
294 for (Instruction* inst : cloned_loop_instructions_) {
295 if (inst->opcode() == spv::Op::OpStore) {
296 set_one_stores.push_back(inst);
297 } else if (inst->opcode() == spv::Op::OpLoad) {
298 set_one_loads.push_back(inst);
299 }
300
301 // If we find any instruction which we can't move (such as a barrier),
302 // return false.
303 if (!MovableInstruction(*inst)) return false;
304 }
305
306 // We need to calculate the depth of the loop to create the loop dependency
307 // distance vectors.
308 const size_t loop_depth = loop_->GetDepth();
309
310 // Check the dependencies between loads in the cloned loop and stores in the
311 // original and vice versa.
312 for (Instruction* inst : original_loop_instructions_) {
313 // If we find any instruction which we can't move (such as a barrier),
314 // return false.
315 if (!MovableInstruction(*inst)) return false;
316
317 // Look at the dependency between the loads in the original and stores in
318 // the cloned loops.
319 if (inst->opcode() == spv::Op::OpLoad) {
320 for (Instruction* store : set_one_stores) {
321 DistanceVector vec{loop_depth};
322
323 // If the store actually should appear after the load, return false.
324 // This means the store has been placed in the wrong grouping.
325 if (instruction_order_[store] > instruction_order_[inst]) {
326 return false;

Callers 1

ProcessMethod · 0.80

Calls 5

GetDepthMethod · 0.80
GetDependenceMethod · 0.80
push_backMethod · 0.45
GetParentMethod · 0.45
opcodeMethod · 0.45

Tested by

no test coverage detected