Skip to main content

Crate qcode_passes

Crate qcode_passes 

Source
Expand description

Block-local cleanup passes over the qcode IR.

These are the transforms that a lifter wants while it is still building a function: they are cheap, local, and safe to run on a partially discovered CFG. They deliberately need no alias analysis, no calling convention, and no knowledge of the target architecture — which is what lets them sit below qcode_analysis and be used on their own by qcode_vm and other consumers that only ever want the cleanup, never the decompiler.

§The context view

A pass reads the module through a PassCtx and mutates a single FunctionBody borrowed &mut from the bodies registry. Splitting a Context into those two halves is what with_body_mut does. Because PassCtx holds only shared references it is Copy, so a caller hands the same view to every helper.

PassCtx is the environment-free half of the richer view used by the full analysis pipeline: it carries the module’s shared IR state and published interfaces, but no architecture configuration. Arch-aware passes live in qcode_analysis and take the richer view instead.

§Example

A pure instruction nothing reads is removed; one whose result is used is kept.

use qcode::{context::Context, qcode};
use qcode_passes::remove_dead_insns;

let mut ctx = Context::new();
qcode!(
    ctx,
    "
    fn f:
    <entry>
        %unused = i64 0x2 + 0x3;
        %kept   = i64 0x4 + 0x5;
        goto <exit @r=%kept>;
    <exit @r:i64>
        goto <0x1001>;
    "
);

assert!(remove_dead_insns(&mut ctx, entry));
// Running it again is a no-op: the pass is idempotent.
assert!(!remove_dead_insns(&mut ctx, entry));

Re-exports§

pub use cfg::absorb_straight_line;
pub use dce::dead_insns;
pub use dce::remove_dead_insns;
pub use dce::remove_dead_insns_body;
pub use symbolize::resolve_addresses;
pub use symbolize::resolve_strings;

Modules§

cfg
CFG simplification: merging straight-line blocks, dropping empty forwarding blocks, and folding degenerate branches.
dce
Dead-instruction elimination: removing pure instructions nothing reads.
symbolize
Attaching meaning to bare integer literals.

Structs§

PassCtx
The bodies-free module view a block-local pass reads through: {shared, interfaces}.

Functions§

replace_terminator_with_branch
split
Split a context into its mutable bodies registry and the read-only module view, so a worker can hold one body &mut while reading shared state.
with_body_mut
Run f against function fid’s body borrowed &mut out of ctx, with the matching read-only view.