Commit Graph

983 Commits

Author SHA1 Message Date
Andrea Gussoni 06733a9f3a InlineHelpers: split into link / inline / delete
Split the `InlineHelpers` pass into the three phases:

- `link-helpers-to-inline` links the missing `revng_inline` helper
  bodies from the `libtcg-helpers-to-inline-arch` module.
- `inline-helpers` inlines, in every function except those tagged
  `Root` or `Helper`, the calls to `revng_inline` helpers whose
  critical arguments on the call site are constant.
- `delete-helper-bodies` drops from the module the body of every
  `revng_inline` function, leaving only the declaration.

The three passes live in a dedicated `revngInlineHelpers` library
(`lib/InlineHelpers/` + `include/revng/InlineHelpers/`), so that
libraries which do not depend on `revngFunctionIsolation` can use them
without creating cyclic dependencies.
2026-06-19 15:35:18 +02:00
Pietro Fezzardi aa1ea25ca7 ExitSSA: add unit tests 2026-06-19 11:07:44 +02:00
Alessandro Di Federico 63734b7ca0 Canonicalize: ban pointers
In order to ensure there are no `alloca`s containing pointers, we change
the passes that emit them to emit instead integer scalars of the same
type.
2026-06-19 09:18:16 +02:00
Giacomo Vercesi dfb9a36bb2 pypeline: implement compression
Implement compression of objects before they are saved into the storage
provider. Each container type can specify which algorithm to use
(currently `none` or `zstd`) and the compression level.
2026-06-17 10:06:35 +02:00
Giacomo Vercesi f0144ac0c9 pypeline: make artifact_categories kebab-case 2026-06-17 09:43:07 +02:00
Ivan Krysak 1609bbe745 Restore the separate enum declaration node 2026-06-16 18:43:45 +02:00
Alessandro Di Federico e4ba9ca989 Drop precedence-tests 2026-06-15 17:28:22 +02:00
Ivan Krysak 3aeb6c8b25 enum-field-access test: fix broken locations 2026-06-15 17:28:22 +02:00
Ivan Krysak 9418844aa3 Add a const serialization test 2026-06-15 17:28:22 +02:00
Ivan Krysak f13a63ba97 Comment tests: make robust to new attributes 2026-06-15 17:28:22 +02:00
Ivan Krysak cdf22d56a5 Comment tests: restore the segment test 2026-06-15 17:28:22 +02:00
Alessandro Di Federico 7d03759672 Drop test_pointer_array_emission 2026-06-15 17:28:22 +02:00
Ivan Krysak 57bbb7b962 Do not propagate model unnecessarily 2026-06-15 17:28:22 +02:00
Ivan Krysak 7b86b7e890 import-types: create a new module 2026-06-15 11:47:41 +02:00
Alessandro Di Federico 6a594a9133 MFP: rename namespace MFP into mfp 2026-06-11 17:39:53 +02:00
Alessandro Di Federico 4f52d444c6 tests/unit: add MFP tests 2026-06-11 17:39:53 +02:00
Alessandro Di Federico d03e62c250 MFP: add ExtraState, MFPConfiguration, variant
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).
2026-06-11 17:39:53 +02:00
Pietro Fezzardi 73cbd99f0a Re-enable comment tests that check for no comments 2026-06-03 22:23:42 +02:00
Alessandro Di Federico 03e02771ac Add model drop-types tool 2026-06-03 13:59:53 +02:00
Alessandro Di Federico 5fa47e8d37 Reorganize lit tests under tests/filecheck 2026-06-03 13:59:53 +02:00
Andrea Gussoni 9c8808fd9e InlineHelpers: Use revng.inline.policy metadata
Use the helper's `!revng.inline.policy` and inline at each call site
only when every critical argument is constant.
2026-05-29 17:12:35 +02:00
Andrea Gussoni 8443f06170 DetectUninlinableHelpers: introduce pass
Introduce a pass which statically demotes some helpers from candidates
for inlining:
1) Helpers which are part of SCC on the callgraph.
2) Helpers which contains an `insertvalue`.
3) Helpers which _fail_ the `CriticalArguments` criterion.

A critical argument is defined starting from the critical operand
definition.
A critical operand is either the condition of a `switch` instruction or
the indices of a `getelementptr` instruction.
If the dataflow computing the the operand trace back to a formal
parameter of the function, that parameter will be considered critical
when attempting the inlining of the helper.

In case each condition is satisfied, the `revng.inline.policy` metadata
is attached to the function, so that it can be used at _inline_ time to
take the decision based on the critical arguments constantness.

The metadata is encoded as an `iN` integer with N = `arg_size() + 1`:
the extra most-significant bit is always zero so LLVM's signed-decimal
`iN` printer renders the value positively (avoiding e.g. `!{i2 -2}`).

The (de)serialisation primitives live in `revng/Support/IRHelpers.h`
as `serializeInliningPolicy` / `deserializeInliningPolicy` so the
runtime `revngFunctionIsolation` doesn't need to link the build-time
`revngHelperInliningAnalyses` to read the metadata back.
2026-05-29 17:12:35 +02:00
Andrea Gussoni 8103e2046c MarkInlineHelpersUpTo: introduce pass
Introduce a build-time pass that tags every QEMU helper transitively
reaching a function defined under one of the configured runtime-library
directories (currently `fpu/` only) as `revng_inline`. The intent is to
make the lift pipeline surface "leaf-level" runtime-library calls (e.g.
softfloat ops) directly in the lifted IR by inlining away every wrapper
helper that sits between QEMU's `helper_*` boundary and the leaf.

We also gate the tagging by a per-function body-size budget.

The pass is run in the pipeline building the `libtcg-helpers-full-*.bc`
artifacts.
2026-05-29 17:12:35 +02:00
Lauri Vasama b078f2c809 Fix C label output around hidden statements 2026-05-25 09:00:41 +02:00
Lauri Vasama 5c9a7b4207 Fix C output around hidden casts
```
// before
(var_0.x)[1];

// after
var_0.x[1];
```
2026-05-25 09:00:41 +02:00
Lauri Vasama 039f533a9f Add ternary inversion rewrite pattern
```
// before
!x ? y ? z

// after
x ? z ? y
```
2026-05-25 09:00:41 +02:00
Lauri Vasama e30a09644e Introduce hoist-variable-initializers pass 2026-05-25 09:00:41 +02:00
Lauri Vasama afaff540ed Implement Clift local variable self-assignment
Local variable initializer regions can now have a block argument
representing the local variable being initialized.
2026-05-25 09:00:41 +02:00
Giacomo Vercesi 3a9317d512 pypeline: factor out starlette middleware code
Factor out in a function the generation of the middleware list, to
facilitate reuse. Add the `AuthMiddleware` which allows authenticating
requests.
2026-05-22 09:04:35 +02:00
Giacomo Vercesi 653f92514b pypeline: adopt hypercorn in place of uvicorn
Switch out from using uvicorn to hypercorn for the pypeline daemon, make
the facilities create hypercorn commands in stand-alone functions, as
they will be re-used for other servers later on.
2026-05-22 09:04:35 +02:00
Giacomo Vercesi edab3e26e9 ProjectMetadata: add additional fields
Expand the `ProjectMetadata` dataclass to include additional timestamps
and the hash of the pipeline description. Change all the
`StorageProvider`s so that all the new data is saved and returned.
2026-05-22 09:04:35 +02:00
Giacomo Vercesi a1878f0f05 StorageProvider: collapse object deps and saving
Consolidate the saving of object dependencies and saving the actual
objects' data into a single function called `add_objects`. The previous
methods `add_dependencies`, `add_custom_invalidation_data` and `put`
have been removed.
2026-05-22 09:04:35 +02:00
Giacomo Vercesi bbff447181 pypeline: split ScheduledTask
Due to the drifting differences, split `ScheduledTask` into
`PipeScheduledTask` and `SavepointScheduledTask`, which allows each to
specialize on the task it has to accomplish.
2026-05-22 09:04:35 +02:00
Giacomo Vercesi e6bdae206e pypeline: notifications a duty of StorageProvider
Make the issuing of notification completely out of band with respect to
the `Pipeline`. Now the `StorageProvider` is responsible for providing
notifications to clients. Since some providers are local-only, there is
a `LOCAL_QUEUE` which allows sensing notifications through a local
queue, re-using the local revng daemon.
2026-05-22 09:04:35 +02:00
Giacomo Vercesi b7f914d53f StorageProvider: move invalidate into set_model
Make `set_model` perform both the invalidation and the changing of the
model bytes. This makes persisting the result of an analysis to storage
atomic.
2026-05-22 09:04:35 +02:00
Giacomo Vercesi 2fabd9c400 pypeline: split Pipe.invalidate in two
Split the `invalidate` method in two phases: in `invalidateCheck` it
just checks if the model diff warrants the execution of the actual
`invalidate` method, which requires fetching the custom invalidation
data from storage. The actual `invalidation` method remains the same.
This should make invalidation faster for storage providers that store
the invalidation remotely.
2026-05-22 09:04:35 +02:00
Giacomo Vercesi dbc734f23a CMake: force use of Python3
Switch from using `find_package(Python ...)` to `find_package(Python3
...)` as it excludes that CMake picks a Python 2 version by accident.
2026-05-14 11:26:41 +02:00
Roberto Bertolini 5dcd6334b3 Add Clift local variable scope tightening 2026-05-13 15:32:34 +02:00
Pietro Fezzardi 986ec7a3b8 STS: add unit tests with the store before the call
Add three more unit tests that mirror the previous "with_alloca"
variants but where the store of the extra argument %val into the
pre-existing alloca happens BEFORE the call instead of after it. The
expected number of NEW allocas after the pass is the same as in the
corresponding store-after-call variant: the position of the store
relative to the call does not change the picker's decision.
2026-05-08 17:16:57 +02:00
Pietro Fezzardi 325af4f696 STS: add unit tests with a pre-existing alloca
Add three more unit tests, one for each of the three call patterns
introduced in the previous commit. Each test takes an extra i64
argument %val, has an alloca pre-existing in the entry block, stores
%val into the alloca right after the call, and at least one branch
returns by loading from the alloca.

The pre-existing alloca/store/load pattern does not write to memory
the call could read (the alloca is local and the call's pointer
argument is unrelated) and the call cannot write to the alloca, so
the picker should reach the same conclusion as in the simpler
counterpart tests: the variant of @call_rw_one_use generates no new
alloca, @call_rw_two_uses generates one new alloca alongside the
pre-existing one, and @call_ro_two_uses generates none.
2026-05-08 17:14:10 +02:00
Pietro Fezzardi 133b29a474 STS: add unit tests for calls and serialization
Cover three representative cases for how the picker should treat
function calls in non-legacy mode:

- A call to a read+write function with a single use (an icmp that
  feeds a conditional branch). The call has only one use, so the
  picker does not pick it and no new alloca is created.
- The same shape, but with two uses of the call (the icmp and a
  return). Because the function may read+write memory and the call
  has more than one use, the picker picks the call: a new alloca is
  created at the top of entry, the result of the call is stored into
  it, and every user of the call uses a load from the alloca.
- The same shape as the second case but with a function that only
  reads memory (and is also nounwind willreturn so that
  Instruction::mayHaveSideEffects returns false). The picker does
  not pick the call and no new alloca is created.
2026-05-08 17:11:00 +02:00
Pietro Fezzardi e41e243d68 ArithmeticToGEP: see through Add subtrees
Make cannotBePointer recurse through an Add when both of its
operands cannot be pointers. This lets canDisambiguatePointerOperand
identify the only viable base pointer of an outer Add even when the
offset side is itself an Add (or a deeper tree of Adds) whose leaves
are all clearly-non-pointer values, e.g.

    %offset = add i64 (%a*%b), (%c*%d)
    %result = add i64 %arg, %offset

Two unit tests cover the simple two-mul case and a deeper
four-mul binary-tree variant.
2026-05-08 11:37:11 +02:00
Pietro Fezzardi 9dd0770290 ArithmeticToGEP: add deep ambiguous-add tests
Cover several scenarios where a single base pointer is reachable
only after the discovery walk in ArithmeticToGEPPass propagates
through many layers of Add instructions, each of which has
ambiguous pointer operands and must be disambiguated separately:

- A chain of 8 chained adds with a varied set of clearly-non-pointer
  offset opcodes (mul, ashr, shl, and, or, xor, sdiv, srem), with
  discovery seeded from the !revng.pointers metadata on the return.
- A chain seeded from a pointer argument (forward propagation).
- A chain feeding the integer argument of a call whose argument is
  a pointer (backwards discovery from the call site).
- A chain where the pointer side alternates between operand 0 and
  operand 1 of each add.
- A chain whose offset side is hidden behind freeze instructions,
  so the cannotBePointer recursion through transparent casts is
  exercised.
- A chain where every add reuses the same multiplication as offset,
  exercising independent disambiguation per-add over a shared
  sub-expression.
- A chain interrupted by ptrtoint/inttoptr round-trips between adds.
2026-05-08 11:37:11 +02:00
Pietro Fezzardi a28e6b8b87 CliftTransforms: add BitCastOfBitCastPattern
Add a Clift expression-rewrite pattern that collapses
`(T2)(T1)x` into `(T2)x` when both casts are BitCastOps. A
matching mlir-lit test is added.
2026-05-08 11:37:10 +02:00
Pietro Fezzardi cb5702dc04 Add ArithmeticToGEP pass
Introduce the ArithmeticToGEP canonicalisation pass. It detects
pointers (LLVM-typed pointer values, model pointers flagged by the
"revng.pointers" metadata, and pointer-tagged extract values) and
rewrites integer arithmetic computed on top of them as i8 GEPs,
followed by a ptrtoint when the original use needs an integer.

For each obvious pointer the pass also walks backwards through Add
chains and disambiguates the pointer operand of each Add when the
other operand cannot be a pointer, so the rewrite extends to integer
arithmetic that only later flows into a pointer use.
2026-05-08 11:37:10 +02:00
Pietro Fezzardi 9111f127dd STS: add unit tests
Add an llvm-lit test suite for the new-PassManager
SwitchToStatements pass, exercised via
`revng opt -passes=switch-to-statements-test` (registered by the
pass's registerCallbacks hook). The tests cover load/store
serialisation, side-effecting calls and a few representative
patterns where an instruction must be picked for serialisation
because its memory read is no longer available at one of its uses.
2026-05-08 11:37:10 +02:00
Lauri Vasama c7e3a12657 Add implicit cast elision pass 2026-05-04 10:49:07 +03:00
Lauri Vasama 04fe27b8e9 Migrate Clift users to CDataModel 2026-05-04 10:49:03 +03:00
Lauri Vasama f6d2eaea4b Add Clift DataModelAttr 2026-05-04 10:48:03 +03:00
Lauri Vasama 0ab9f769dd Add CDataModel in ABI definition 2026-05-02 17:21:47 +03:00