MCPcopy Create free account
hub / github.com/avast/retdec / splitWhileTrueLoop

Function splitWhileTrueLoop

src/llvmir2hll/utils/loop_optimizer.cpp:114–165  ·  view source on GitHub ↗

* @brief Splits the given "while True" loop @a stmt into three parts. * * @param[in] stmt "while True" loop to be splitted. * @param[in] indVarInfo * * See the description of SplittedWhileTrueLoop for more details. * * Each statement in the loop will be cloned by calling @c clone() on it. * * If the loop either isn't a "while True" loop or it cannot be splitted into * the three parts, the null poi

Source from the content-addressed store, hash-verified

112* the three parts, the null pointer is returned.
113*/
114ShPtr<SplittedWhileTrueLoop> splitWhileTrueLoop(
115 ShPtr<WhileLoopStmt> stmt,
116 ShPtr<IndVarInfo> indVarInfo) {
117 // It has to be a "while True" loop.
118 if (!isWhileTrueLoop(stmt)) {
119 return {};
120 }
121
122 // Split the loop.
123 auto splittedLoop = std::make_shared<SplittedWhileTrueLoop>();
124 ShPtr<Expression> exitCond;
125 auto currStmt = stmt->getBody();
126 while (currStmt) {
127 // When a statement in the loop is a goto target, we cannot split the
128 // loop. Otherwise, after optimizing the loop, we might end up with
129 // incorrect code.
130 if (currStmt->isGotoTarget()) {
131 return {};
132 }
133
134 // If there is more than one loop end, use the first one.
135 if (isLoopEnd(currStmt) && !exitCond) {
136 exitCond = getExitCondition(currStmt);
137 splittedLoop->loopEnd = cast<IfStmt>(currStmt);
138 currStmt = currStmt->getSuccessor();
139 continue;
140 }
141
142 if (exitCond) {
143 // TODO This can be done more efficiently.
144 splittedLoop->afterLoopEndStmts = Statement::mergeStatements(
145 splittedLoop->afterLoopEndStmts, ucast<Statement>(currStmt->clone()));
146 } else {
147 // TODO This can be done more efficiently.
148 if (indVarInfo == nullptr
149 || !indVarInfo->updateBeforeExit
150 || currStmt != indVarInfo->updateStmt) {
151 splittedLoop->beforeLoopEndStmts = Statement::mergeStatements(
152 splittedLoop->beforeLoopEndStmts, ucast<Statement>(currStmt->clone()));
153 }
154 }
155
156 currStmt = currStmt->getSuccessor();
157 }
158
159 // Check that the loop has been successfully splitted.
160 if (!splittedLoop->loopEnd || !exitCond) {
161 return {};
162 }
163
164 return splittedLoop;
165}
166
167/**
168* @brief Returns information about the induction variable in the given "while

Callers 7

tryOptimizationCase1Method · 0.85
tryOptimizationCase2Method · 0.85
tryOptimizationCase4Method · 0.85
tryOptimizationCase5Method · 0.85
visitMethod · 0.85
visitMethod · 0.85

Calls 7

isWhileTrueLoopFunction · 0.85
isLoopEndFunction · 0.85
getExitConditionFunction · 0.85
isGotoTargetMethod · 0.80
getSuccessorMethod · 0.80
getBodyMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected