| 35 | } |
| 36 | |
| 37 | Pass::Status LoopFusionPass::ProcessFunction(Function* function) { |
| 38 | LoopDescriptor& ld = *context()->GetLoopDescriptor(function); |
| 39 | |
| 40 | // If a loop doesn't have a preheader needs then it needs to be created. Make |
| 41 | // sure to return Status::SuccessWithChange in that case. |
| 42 | bool modified = false; |
| 43 | auto status = ld.CreatePreHeaderBlocksIfMissing(); |
| 44 | if (status == LoopDescriptor::Status::Failure) return Status::Failure; |
| 45 | modified = status == LoopDescriptor::Status::SuccessWithChange; |
| 46 | |
| 47 | // TODO(tremmelg): Could the only loop that |loop| could possibly be fused be |
| 48 | // picked out so don't have to check every loop |
| 49 | for (auto& loop_0 : ld) { |
| 50 | for (auto& loop_1 : ld) { |
| 51 | LoopFusion fusion(context(), &loop_0, &loop_1); |
| 52 | |
| 53 | if (fusion.AreCompatible() && fusion.IsLegal()) { |
| 54 | RegisterLiveness liveness(context(), function); |
| 55 | RegisterLiveness::RegionRegisterLiveness reg_pressure{}; |
| 56 | liveness.SimulateFusion(loop_0, loop_1, ®_pressure); |
| 57 | |
| 58 | if (reg_pressure.used_registers_ <= max_registers_per_loop_) { |
| 59 | fusion.Fuse(); |
| 60 | // Recurse, as the current iterators will have been invalidated. |
| 61 | ProcessFunction(function); |
| 62 | return Status::SuccessWithChange; |
| 63 | } |
| 64 | } |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; |
| 69 | } |
| 70 | |
| 71 | } // namespace opt |
| 72 | } // namespace spvtools |
nothing calls this directly
no test coverage detected