MCPcopy Create free account
hub / github.com/argotorg/solidity / gatherKnowledge

Method gatherKnowledge

libevmasm/ControlFlowGraph.cpp:217–319  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

215}
216
217void ControlFlowGraph::gatherKnowledge()
218{
219 // @todo actually we know that memory is filled with zeros at the beginning,
220 // we could make use of that.
221 KnownStatePointer emptyState = std::make_shared<KnownState>();
222 bool unknownJumpEncountered = false;
223
224 struct WorkQueueItem {
225 BlockId blockId;
226 KnownStatePointer state;
227 std::set<BlockId> blocksSeen;
228 };
229
230 std::vector<WorkQueueItem> workQueue{WorkQueueItem{BlockId::initial(), emptyState->copy(), std::set<BlockId>()}};
231 auto addWorkQueueItem = [&](WorkQueueItem const& _currentItem, BlockId _to, KnownStatePointer const& _state)
232 {
233 WorkQueueItem item;
234 item.blockId = _to;
235 item.state = _state->copy();
236 item.blocksSeen = _currentItem.blocksSeen;
237 item.blocksSeen.insert(_currentItem.blockId);
238 workQueue.push_back(std::move(item));
239 };
240
241 while (!workQueue.empty())
242 {
243 WorkQueueItem item = std::move(workQueue.back());
244 workQueue.pop_back();
245 //@todo we might have to do something like incrementing the sequence number for each JUMPDEST
246 assertThrow(!!item.blockId, OptimizerException, "");
247 if (!m_blocks.count(item.blockId))
248 continue; // too bad, we do not know the tag, probably an invalid jump
249 BasicBlock& block = m_blocks.at(item.blockId);
250 KnownStatePointer state = item.state;
251 if (block.startState)
252 {
253 // We call reduceToCommonKnowledge even in the non-join setting to get the correct
254 // sequence number
255 if (!m_joinKnowledge)
256 state->reset();
257 state->reduceToCommonKnowledge(*block.startState, !item.blocksSeen.count(item.blockId));
258 if (*state == *block.startState)
259 continue;
260 }
261
262 block.startState = state->copy();
263
264 // Feed all items except for the final jump yet because it will erase the target tag.
265 unsigned pc = block.begin;
266 while (pc < block.end && !SemanticInformation::altersControlFlow(m_items.at(pc)))
267 state->feedItem(m_items.at(pc++));
268
269 if (
270 block.endType == BasicBlock::EndType::JUMP ||
271 block.endType == BasicBlock::EndType::JUMPI
272 )
273 {
274 assertThrow(block.begin <= pc && pc == block.end - 1, OptimizerException, "");

Callers

nothing calls this directly

Calls 15

insertMethod · 0.80
atMethod · 0.80
tagsInExpressionMethod · 0.80
stackElementMethod · 0.80
eraseMethod · 0.80
BlockIdClass · 0.70
copyMethod · 0.45
emptyMethod · 0.45
countMethod · 0.45
resetMethod · 0.45
feedItemMethod · 0.45

Tested by

no test coverage detected