There seem to be some issues with defining these in headers due to the
storage type being incomplete. The storage type is only defined in the
.cpp file.
`TypeToNumOfRefs` was used only in one method, so it can be computed
directly there on the fly.
`calculateNumOfOccurrences` doesn't need to be a method (it can be a
free function), it doesn't need to run at construction time, and it
doesn't need to return a map. So it's been moved in the `.cpp` file,
renamed to `getCrossReferencedTypes` and changed to return a set. It is
now only called when needed.
Before this commit, the mayReadMemory helper function was broken for
the two custom opcode functions used to model stack variables:
revng_stack_frame and revng_call_stack_arguments.
This means that those two functions were already considered as reading
memory, while the actually do not.
This commit fixes that, so that mayReadMemory now always properly
returns false for them.
Before this commit, it could happen that some duplicated dummy node
(used to mark backedges) could be left lingering in wrong regions when
collapsing a regions, if they were first iteration outlined.
This commit fixes the problem, by collecting them and letting
`updateNodes` take care of them, removing them from the containing
region and all its parents.
Over time, these tags have shifted to basically coincide with the Copy
and Assign tags. There's no need for them anymore they just make the
code more verbose and less straightforward.
Before this commit the `hasSideEffects` helper function was only a stub,
that was never updated to be aware of recent FunctionTags representing
custom opcodes without side-effects.
This commit updates it, so that now it is less aggressive in marking
harmless stuff as side-effectful.
Various improvements to the debug graphs for `restructure-cfg` and
`beautify`:
- Normalize casing and syntax of debug graphs.
- Improve the graph folders name and layout.
- Implement `CFGDumper` and `ASTDumper` for when we need a serialization
with incremental indexes.
- Remove old and stale graph serializations.
Do not re-enqueue conditional nodes a for combing, when duplicating a
conditional.
This can be done in such way, thanks to the property that we process
conditional nodes in postorder. Therefore, if conditional node A causes
the duplication of, say, node B, we have the guarantee that such node B
has already been processed by the combing. Therefore, the clone of node
B, say node B', should not be reprocessed for combing.
Perform a complete rewrite of the `SwitchNode` tiling routine.
The tiling now works in the following way:
- When encountering a node which will produce a `SwitchNode` (either a
standard `switch` or a dispatcher `switch`), we look for the following
situations:
1) We have a node, a successor (case) of the `switch`, which in turn
is the successor of all the other successors (cases) of the
`switch`.
2) We have a node, not a successor (case) of the `switch`, which is
the successor of all the successors (cases) of the `switch`.
- If we find such candidate node, this node will be the fallthrough of
the `switch`. In addition, depending on whether the `switch` dominates
the candidate fallthrough, we can incorporate it as the immediate
successor of the `SwitchNode` we are building.
- There is currently an exception to the above, due to how we currently
handle weaved `switch`es. In such cases, we mandate that the weaved
`switch` is nested inside the main corresponding `switch`. For this
reason, we have a special casing handling the "all inlined but one"
situation in the new code, while this part could in theory be merged
in the common criterion below, at the cost of dropping the invariant
of the nesting of weaved switch`es.