| 81 | } |
| 82 | |
| 83 | std::optional<std::vector<Statement>> LoopInvariantCodeMotion::rewriteLoop(ForLoop& _for) |
| 84 | { |
| 85 | assertThrow(_for.pre.statements.empty(), OptimizerException, ""); |
| 86 | |
| 87 | auto forLoopSideEffects = |
| 88 | SideEffectsCollector{m_dialect, _for, &m_functionSideEffects}.sideEffects(); |
| 89 | |
| 90 | std::vector<Statement> replacement; |
| 91 | for (Block* block: {&_for.post, &_for.body}) |
| 92 | { |
| 93 | std::set<YulName> varsDefinedInScope; |
| 94 | util::iterateReplacing( |
| 95 | block->statements, |
| 96 | [&](Statement& _s) -> std::optional<std::vector<Statement>> |
| 97 | { |
| 98 | if (std::holds_alternative<VariableDeclaration>(_s)) |
| 99 | { |
| 100 | VariableDeclaration const& varDecl = std::get<VariableDeclaration>(_s); |
| 101 | if (canBePromoted(varDecl, varsDefinedInScope, forLoopSideEffects)) |
| 102 | { |
| 103 | replacement.emplace_back(std::move(_s)); |
| 104 | // Do not add the variables declared here to varsDefinedInScope because we are moving them. |
| 105 | return std::vector<Statement>{}; |
| 106 | } |
| 107 | for (auto const& var: varDecl.variables) |
| 108 | varsDefinedInScope.insert(var.name); |
| 109 | } |
| 110 | return {}; |
| 111 | } |
| 112 | ); |
| 113 | } |
| 114 | if (replacement.empty()) |
| 115 | return {}; |
| 116 | else |
| 117 | { |
| 118 | replacement.emplace_back(std::move(_for)); |
| 119 | return { std::move(replacement) }; |
| 120 | } |
| 121 | } |
nothing calls this directly
no test coverage detected