Loop-unrolling optimization with regex Note: Be cautious, as it does not correctly recognize comments or lexical tokens.
| 11 | // |
| 12 | // Note: Be cautious, as it does not correctly recognize comments or lexical tokens. |
| 13 | std::string loopUnrolling(const std::string& code, int threshold = 32) { |
| 14 | // This regex pattern matches a for loop with the following structure: |
| 15 | // for (var <varName>: u32 = <start>; <varName> < <end>; <varName>++) { <loopBody> } |
| 16 | std::regex forLoopPattern(R"(for\s*\(\s*var\s+(\w+):\s*u32\s*=\s*(\d+)\s*;\s*\1\s*<\s*(\d+)\s*;\s*\1\+\+\s*\)\s*\{\s*([^{}]*)\})"); |
| 17 | // Explanation of the regex: |
| 18 | // for\s*\( : Matches 'for (' with optional whitespace |
| 19 | // \s*var\s+ : Matches 'var ' with optional whitespace |
| 20 | // (\w+) : Captures the variable name (alphanumeric characters and underscores) |
| 21 | // :\s*u32\s*=\s* : Matches ': u32 = ' with optional whitespace |
| 22 | // (\d+) : Captures the start value (one or more digits) |
| 23 | // \s*;\s* : Matches ';' with optional whitespace |
| 24 | // \1\s*<\s* : Matches the captured variable name followed by '<' with optional whitespace |
| 25 | // (\d+) : Captures the end value (one or more digits) |
| 26 | // \s*;\s* : Matches ';' with optional whitespace |
| 27 | // \1\+\+\s* : Matches the captured variable name followed by '++' with optional whitespace |
| 28 | // \)\s*\{\s* : Matches ')' followed by '{' with optional whitespace |
| 29 | // ([^{}]*) : Captures the loop body (anything except '{' or '}') |
| 30 | // \} : Matches the closing '}' |
| 31 | |
| 32 | // Example: |
| 33 | // |
| 34 | // Input code: |
| 35 | // for (var i: u32 = 0; i < 3; i++) { std::cout << i << std::endl; } |
| 36 | // |
| 37 | // Matches: |
| 38 | // varName = "i" |
| 39 | // start = "0" |
| 40 | // end = "3" |
| 41 | // loopBody = "std::cout << i << std::endl;" |
| 42 | // |
| 43 | // Unrolled: |
| 44 | // std::cout << 0 << std::endl; |
| 45 | // std::cout << 1 << std::endl; |
| 46 | // std::cout << 2 << std::endl; |
| 47 | // |
| 48 | std::smatch match; |
| 49 | std::string unrolledCode = code; |
| 50 | while (std::regex_search(unrolledCode, match, forLoopPattern)) { |
| 51 | std::string varName = match[1]; |
| 52 | int start = std::stoi(match[2]); |
| 53 | int end = std::stoi(match[3]); |
| 54 | std::string loopBody = match[4]; |
| 55 | |
| 56 | if (end - start > threshold ) { |
| 57 | std::string skippedLoop = |
| 58 | "for (var " + |
| 59 | std::string(match[1]) + ": u32 = " + std::string(match[2]) + ";"+ |
| 60 | std::string(match[1]) + " < " + std::string(match[3]) + ";"+ |
| 61 | std::string(match[1]) + "++) /* Skipped */ {"+ |
| 62 | std::string(match[4]) + |
| 63 | "}"; |
| 64 | // LOG(kDefLog, kInfo, "Roll loop:%s", skippedLoop.c_str()); |
| 65 | unrolledCode = unrolledCode.substr(0, match.position()) + skippedLoop + unrolledCode.substr(match.position() + match.length()); |
| 66 | } else { |
| 67 | // LOG(kDefLog, kInfo, "Unroll loop(var: %s, start:%d, end:%d, body:%s)", varName.c_str(), start, end, loopBody.c_str()); |
| 68 | std::string unrolledLoop; |
| 69 | for (int i = start; i < end; ++i) { |
| 70 | std::string unrolledIteration = loopBody; |
no outgoing calls
no test coverage detected