weir/callgraph/
program.rs1use std::sync::Arc;
2
3use super::OP_ID;
4use vyre::ir::{BufferAccess, BufferDecl, DataType, Expr, Ident, Node, Program};
5
6#[must_use]
18pub fn callgraph_build(
19 direct_edges_in: &str,
20 indirect_sites_in: &str,
21 pts_closure_in: &str,
22 callgraph_out: &str,
23) -> Program {
24 callgraph_build_with_count(
25 direct_edges_in,
26 indirect_sites_in,
27 pts_closure_in,
28 callgraph_out,
29 4,
30 )
31}
32
33#[must_use]
35pub fn callgraph_build_with_count(
36 direct_edges_in: &str,
37 indirect_sites_in: &str,
38 pts_closure_in: &str,
39 callgraph_out: &str,
40 node_count: u32,
41) -> Program {
42 let domain = crate::graph_layout::LinearDomain::new(node_count);
43 let words = domain.bitset_words();
44 let w = Expr::InvocationId { axis: 0 };
45
46 let body = vec![
47 Node::let_bind("direct", Expr::load(direct_edges_in, w.clone())),
48 Node::let_bind(
49 "indirect",
50 Expr::bitand(
51 Expr::load(indirect_sites_in, w.clone()),
52 Expr::load(pts_closure_in, w.clone()),
53 ),
54 ),
55 Node::store(
56 callgraph_out,
57 w.clone(),
58 Expr::bitor(Expr::var("direct"), Expr::var("indirect")),
59 ),
60 ];
61
62 let buffers = vec![
63 BufferDecl::storage(direct_edges_in, 0, BufferAccess::ReadOnly, DataType::U32)
64 .with_count(words),
65 BufferDecl::storage(indirect_sites_in, 1, BufferAccess::ReadOnly, DataType::U32)
66 .with_count(words),
67 BufferDecl::storage(pts_closure_in, 2, BufferAccess::ReadOnly, DataType::U32)
68 .with_count(words),
69 BufferDecl::storage(callgraph_out, 3, BufferAccess::ReadWrite, DataType::U32)
70 .with_count(words),
71 ];
72
73 Program::wrapped(
74 buffers,
75 [256, 1, 1],
76 vec![Node::Region {
77 generator: Ident::from(OP_ID),
78 source_region: None,
79 body: Arc::new(vec![Node::if_then(
80 Expr::lt(w.clone(), Expr::u32(words)),
81 body,
82 )]),
83 }],
84 )
85}