Move all per-function state and logic into a new SegregateFunctionStack
worker, so the pass class itself only holds module-wide state and the
runOnFunction body is just upgrade() + segregate(). The discovery loop
now uses the MFP ExtraState surface to capture the analysis value
before each interesting program point, replacing the splitBasicBlock
trick that introduced fake nodes only to read the lattice value at
them.
Other changes that ride along:
- StackOffsetCache memoizes getStackOffset per function.
- findAllWriters does a single sorted sweep instead of a quadratic
scan over Ranges.
- The pipeline gains a stack-accesses-segregated artifact entry.
- Test fixtures (filecheck.ll, override.yml, segregate-stack-accesses
configuration) are updated to match the new IR shape.
Three closely-coupled changes that have to land together to keep
every caller compiling:
- Introduce a per-instance ExtraState recording surface (with a
NoExtraState default) and thread it through applyTransferFunction.
- Replace getMaximalFixedPoint's positional arg list with a single
MFPConfiguration struct, so callers spell out only the fields they
need.
- Replace the EntryLabels pointer with an Entry/All/vector* variant
so callers can ask for the graph entry, every node, or a custom
list without juggling extra arguments.
Update every existing caller for the new signatures and switch
Liveness::GraphType to a plain Function* (with the inverse
GraphTraits selected at call sites).
Reorganise LocalVariableBuilder so that the legacy and non-legacy
code paths are separated into two specialisations, and so that the
non-legacy specialisation does not need a model::Binary to operate.
This is a prerequisite for using LocalVariableBuilder from passes
that do not know about the model, e.g. unit tests for the new-PM
SwitchToStatements and the upcoming non-legacy decompilation
pipeline.
Extend SegregateStackAccessesPass to attach the "revng.pointers"
metadata on every llvm::Function it rewrites, and on every CallInst
it produces.
The metadata represents, in a model-agnostic way, which arguments
and return values of a call or function (both formal and actual)
are pointer-typed in the model. Later passes consume this so that
they can stay model-agnostic.
Move member declaration to the top of the class definition of
`GeneratedCodeBasicInfo` and initialize primitive members.
Merge the `run` method into the constructor since all uses have them
happening close to each other.
`revng_undefined_local_sp` was previously initially marked as using
inaccessible memory and, later on, marked as reading only memory.
Doing the latter right away is fine.
This commit also does not assume that function is always available.
* Make the following private headers public:
* Lift/CPUStateAccessAnalysisPass.h
* Lift/CSVOffsets.h
* Lift/PTCDump.h
* Lift/VariableManager.h
* Move from revngSupport to revngLift:
* IRAnnotators.{h,cpp}
* SelfReferencingDbgAnnotationWriter.{h,cpp}
* Move from revngSupport to revngModel:
* FunctionTags.{h,cpp}
* ProgramCounterHandler.{h,cpp}
* Move from revngSupport to revngRecompile:
* OriginalAssemblyAnnotationWriter.{h,cpp}
This reworks NameBuilder to ease the transition to the system where
the model will be guaranteed to never contain any name collisions, both
between user-specified names and the automatic ones.
This commit further centralizes the creation of allocas + ptrtoint. The
creation of these pair of instructions is problematic when the size of a
pointer in the input and target architecture differ.
In fact, in such cases, LLVM turns trunc into masking the integer to
suppresse the high bits. This results in problematic code.
This commit introduces an assumption that ensures LLVM does not do that.
This commit adopts `PatternMatch.h` and adds support discarding
alignment operations even if they are performed after manipulating the
stack pointer.
For instance, glibc's `_start` does the following:
xor ebp,ebp
mov r9,rdx
pop rsi
mov rdx,rsp
and rsp,0xfffffffffffffff0