Improve the way in which we connect the non reachable `JumpTargets` when
rebuilding the dispatcher for non `SemanticsPreserving` `CFGForm`s.
When connecting group of jump targets that are not currently reachable
from the entry dispatcher, we elect the jump target with the lowest
program counter value, as the one to be connected to the dispatcher.
We also mark the jump targets now transitively reachables from the
elected one, as reachable, so to avoid adding other unnecessary edges
from the dispatcher.
Replace the stub implementation of invalidation with the proper
implementation. A ReadPathCache is added to each global so that it can
keep tracks of what target are associated to which read paths.
`ValueMaterializer` is a rewrite of what was called `AdvancedValueInfo`
which follows the same principles.
The main benefits over the old version is:
* We materialize the data-flow graph and the CFG of the relevant part of
root. This makes debugging significantly easier.
* We drop the old MonotoneFramework infrastructure in favor of
getMaximalFixedPoint.
* We significantly reduce the amount of queries we make to
AdvancedValueInfo.
This commit adopts `llvm::DenseSet`, `llvm::DenseMap` and
`std::unordered_set` where needed.
It also tweaks some `llvm::SmallVector` sizes.
It brings an additional ~3% improvement during lifting.
This commit disables GVN in order to improve lifting performance.
It also increases `EarlyCSEMssaOptCap` so we keep catching all the jump
target we used to.
Lifting /bin/bash goes from ~29mins to ~5mins
We used to jump to the dispatcher, however we only sink to an
unreachable `anypc`. We were threfore significantly complicating the CFG
in case of indirect function calls.
`getUniqueString` returns a dedup'd char array `GlobalVariable` given a
string. We used to rely on named metadata to dedup them. However, this
lead to issues with `LLVMContainer` cloning and linking.
The new implementation uses the name of the variable as the
de-decuplication key, circumventing the problem entirely and improving
performance.
This commit introduces `BasicBlockID` as the unique identifier for a
`efa::BasicBlock` into the CFG. A `BasicBlockID` is defined by a
`MetaAddress` plus an incremental integer. This enables us to have
multiple instances of the same block in a single function, which is
particularly useful when inlining multiple times the same function.
Apart from this, the commit also does the following:
* It drops representing `MetaAddress`es a `structs` in the IR. This created
several issues related to ABI. We now represent them as strings.
* It defines more functions in `support.h`, instead of defining prototypes
by hand in `CodeGenerator.cpp` and the like. Specifically, `unknownPC`
and `raise_exception_helper`. We also introduce a C "constructor" for
`PlainMetaAddress`.
* It significantly reduces the API of `GeneratedCodeBasicInfo`, which
was supposed to be put on a diet since a long time. Specifically,
many jump target related methods have been moved to free functions in
`IRHelpers.h`. Also `GCBI::getSuccessors` has been pushed into its
only user, `PruneRetSuccessors`, to prevent further usage of a
deprecated API. In the future, it would be nice to drop it entirely.
* It introduces `efa::BasicBlock::InlinedFrom`.
* Introduce an enum to represent named argument indices for `newpc`.
This enables us to more effectively manipulate its argument list.
* It improves the verification and error reporting for
`efa::FunctionMetadata`.
* Update tests.
This commit is preliminary to another piece of work to improve the
generality of inlining beyond the simple "fake function" scenario, for
which the feature was originally conceived.