use super::*;
#[must_use]
#[allow(clippy::too_many_arguments)]
pub fn c11_build_call_graph(
calls: &str,
fn_hashes: &str,
tok_starts: &str,
tok_lens: &str,
haystack: &str,
num_calls: Expr,
num_functions: Expr,
num_tokens: Expr,
out_edges: &str,
out_counts: &str,
) -> Program {
let t = Expr::InvocationId { axis: 0 };
let loop_body = vec![
Node::let_bind(
"caller_fn_id",
Expr::load(calls, Expr::mul(t.clone(), Expr::u32(4))),
),
Node::let_bind(
"callee_tok_idx",
Expr::load(
calls,
Expr::add(Expr::mul(t.clone(), Expr::u32(4)), Expr::u32(1)),
),
),
Node::let_bind(
"callee_tok_start",
Expr::load(tok_starts, Expr::var("callee_tok_idx")),
),
Node::let_bind(
"callee_tok_len",
Expr::load(tok_lens, Expr::var("callee_tok_idx")),
),
Node::let_bind("callee_hash", Expr::u32(2166136261)),
Node::loop_for(
"b",
Expr::u32(0),
Expr::var("callee_tok_len"),
vec![
Node::let_bind(
"byte",
Expr::load(
haystack,
Expr::add(Expr::var("callee_tok_start"), Expr::var("b")),
),
),
Node::assign(
"callee_hash",
Expr::bitxor(Expr::var("callee_hash"), Expr::var("byte")),
),
Node::assign(
"callee_hash",
Expr::mul(Expr::var("callee_hash"), Expr::u32(16777619)),
),
],
),
Node::let_bind("matched_fn", Expr::u32(0)),
Node::loop_for(
"f",
Expr::u32(0),
num_functions.clone(),
vec![
Node::let_bind("func_hash", Expr::load(fn_hashes, Expr::var("f"))), Node::if_then(
Expr::and(
Expr::eq(Expr::var("matched_fn"), Expr::u32(0)),
Expr::eq(Expr::var("callee_hash"), Expr::var("func_hash")),
),
vec![
Node::let_bind(
"idx",
Expr::atomic_add(out_counts, Expr::u32(0), Expr::u32(2)),
), Node::store(out_edges, Expr::var("idx"), Expr::var("caller_fn_id")),
Node::store(
out_edges,
Expr::add(Expr::var("idx"), Expr::u32(1)),
Expr::var("f"),
),
Node::assign("matched_fn", Expr::u32(1)),
],
),
],
),
];
let call_count = match &num_calls {
Expr::LitU32(n) => *n,
_ => 1,
};
let fn_count = match &num_functions {
Expr::LitU32(n) => *n,
_ => 1,
};
let token_count = match &num_tokens {
Expr::LitU32(n) => *n,
_ => call_count,
};
Program::wrapped(
vec![
BufferDecl::storage(calls, 0, BufferAccess::ReadOnly, DataType::U32)
.with_count(call_count.saturating_mul(4)),
BufferDecl::storage(fn_hashes, 1, BufferAccess::ReadOnly, DataType::U32)
.with_count(fn_count),
BufferDecl::storage(tok_starts, 2, BufferAccess::ReadOnly, DataType::U32)
.with_count(token_count),
BufferDecl::storage(tok_lens, 3, BufferAccess::ReadOnly, DataType::U32)
.with_count(token_count),
BufferDecl::storage(haystack, 4, BufferAccess::ReadOnly, DataType::U32)
.with_count(call_count.saturating_mul(16)),
BufferDecl::storage(out_edges, 5, BufferAccess::ReadWrite, DataType::U32)
.with_count(call_count.saturating_mul(4)),
BufferDecl::storage(out_counts, 6, BufferAccess::ReadWrite, DataType::U32)
.with_count(1),
],
[256, 1, 1],
vec![wrap_anonymous(
"vyre-libs::parsing::c11_build_call_graph",
vec![Node::if_then(
Expr::lt(t.clone(), num_calls.clone()),
loop_body,
)],
)],
)
.with_entry_op_id("vyre-libs::parsing::c11_build_call_graph")
.with_non_composable_with_self(true)
}