Skip to main content

weir/summary/
program.rs

1use std::sync::Arc;
2
3use super::OP_ID;
4use vyre::ir::{BufferAccess, BufferDecl, DataType, Expr, Ident, Node, Program};
5use vyre_primitives::bitset::bitset_words;
6
7/// One summary-update step for a single function.
8///
9/// Bit `i` of `summary_out` is set iff any of: the AST-derived bit
10/// was set, the callgraph-aggregated bit from callee summaries was
11/// set, or the cached summary from the previous scan was set. That
12/// is a three-way OR  -  same kernel shape as `escape`, different
13/// buffer names.
14#[must_use]
15pub fn summarize_function(
16    fn_ast_in: &str,
17    callgraph_in: &str,
18    cached_summary_in: &str,
19    summary_out: &str,
20) -> Program {
21    summarize_function_with_count(fn_ast_in, callgraph_in, cached_summary_in, summary_out, 64)
22}
23
24/// Version that takes the bit-lane count explicitly.
25#[must_use]
26pub fn summarize_function_with_count(
27    fn_ast_in: &str,
28    callgraph_in: &str,
29    cached_summary_in: &str,
30    summary_out: &str,
31    bit_count: u32,
32) -> Program {
33    let words = bitset_words(bit_count).max(1);
34    let w = Expr::InvocationId { axis: 0 };
35
36    let body = vec![
37        Node::let_bind("ast", Expr::load(fn_ast_in, w.clone())),
38        Node::let_bind("cg", Expr::load(callgraph_in, w.clone())),
39        Node::let_bind("cached", Expr::load(cached_summary_in, w.clone())),
40        Node::store(
41            summary_out,
42            w.clone(),
43            Expr::bitor(
44                Expr::bitor(Expr::var("ast"), Expr::var("cg")),
45                Expr::var("cached"),
46            ),
47        ),
48    ];
49
50    let buffers = vec![
51        BufferDecl::storage(fn_ast_in, 0, BufferAccess::ReadOnly, DataType::U32).with_count(words),
52        BufferDecl::storage(callgraph_in, 1, BufferAccess::ReadOnly, DataType::U32)
53            .with_count(words),
54        BufferDecl::storage(cached_summary_in, 2, BufferAccess::ReadOnly, DataType::U32)
55            .with_count(words),
56        BufferDecl::storage(summary_out, 3, BufferAccess::ReadWrite, DataType::U32)
57            .with_count(words),
58    ];
59
60    Program::wrapped(
61        buffers,
62        [256, 1, 1],
63        vec![Node::Region {
64            generator: Ident::from(OP_ID),
65            source_region: None,
66            body: Arc::new(vec![Node::if_then(
67                Expr::lt(w.clone(), Expr::u32(words)),
68                body,
69            )]),
70        }],
71    )
72}