Skip to content

Commit d6f9dd1

Browse files
committed
Refactor variable declaration handling in eBPF C code generation. Streamline the collection of declared registers by directly iterating over instruction blocks, improving clarity and efficiency. Enhance function call declaration processing to ensure proper instruction ordering for variable declarations and assignments.
1 parent c6e96f0 commit d6f9dd1

2 files changed

Lines changed: 42 additions & 32 deletions

File tree

src/ebpf_c_codegen.ml

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,35 +2809,8 @@ let generate_c_basic_block ctx ir_block =
28092809
increase_indent ctx
28102810
);
28112811

2812-
(* Emit instructions with special handling for function call + variable declaration sequences *)
2813-
let rec emit_instructions_optimized = function
2814-
| [] -> ()
2815-
| call_instr :: decl_instr :: rest
2816-
when (match call_instr.instr_desc, decl_instr.instr_desc with
2817-
| IRCall (call_target, args, Some result_val), IRDeclareVariable (dest_val, typ, None) ->
2818-
(* Check if the call result register matches the declaration register *)
2819-
(match result_val.value_desc, dest_val.value_desc with
2820-
| IRRegister call_reg, IRRegister decl_reg when call_reg = decl_reg ->
2821-
(* Generate combined declaration with function call initialization *)
2822-
let var_name = get_meaningful_var_name ctx decl_reg typ in
2823-
let args_str = String.concat ", " (List.map (generate_c_value ctx) args) in
2824-
let call_str = match call_target with
2825-
| DirectCall name -> sprintf "%s(%s)" name args_str
2826-
| FunctionPointerCall func_ptr -> sprintf "(*%s)(%s)" (generate_c_value ctx func_ptr) args_str
2827-
in
2828-
let decl_str = generate_ebpf_c_declaration typ var_name in
2829-
emit_line ctx (sprintf "%s = %s;" decl_str call_str);
2830-
true
2831-
| _ -> false)
2832-
| _ -> false) ->
2833-
(* Skip the next instruction since we handled it in the combined declaration *)
2834-
emit_instructions_optimized rest
2835-
| instr :: rest ->
2836-
(* Regular instruction processing *)
2837-
generate_c_instruction ctx instr;
2838-
emit_instructions_optimized rest
2839-
in
2840-
emit_instructions_optimized ir_block.instructions
2812+
(* Generate C code for each IR instruction *)
2813+
List.iter (generate_c_instruction ctx) ir_block.instructions
28412814

28422815
(** Collect mapping from registers to variable names *)
28432816
let collect_register_variable_mapping ir_func =

src/ir_generator.ml

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,10 +1307,47 @@ and lower_statement ctx stmt =
13071307

13081308
| Ast.Declaration (name, typ_opt, expr_opt) ->
13091309
let reg = get_variable_register ctx name in
1310-
let (target_type, init_value_opt) =
1311-
resolve_declaration_type_and_init ctx reg typ_opt expr_opt in
13121310

1313-
declare_variable ctx name reg target_type init_value_opt stmt.stmt_pos
1311+
(* Handle function call declarations elegantly by proper instruction ordering *)
1312+
(match expr_opt with
1313+
| Some expr when (match expr.Ast.expr_desc with Ast.Call _ -> true | _ -> false) ->
1314+
(* For function calls: emit declaration first, then call with assignment *)
1315+
let target_type = match typ_opt with
1316+
| Some ast_type -> resolve_type_alias ctx reg ast_type
1317+
| None ->
1318+
(* Infer type from function call if no explicit type *)
1319+
(match expr.expr_type with
1320+
| Some ast_type -> ast_type_to_ir_type_with_context ctx.symbol_table ast_type
1321+
| None -> IRU32)
1322+
in
1323+
1324+
(* Emit declaration first *)
1325+
declare_variable ctx name reg target_type None stmt.stmt_pos;
1326+
1327+
(* Then emit function call as assignment *)
1328+
(match expr.Ast.expr_desc with
1329+
| Ast.Call (callee_expr, args) ->
1330+
let arg_vals = List.map (lower_expression ctx) args in
1331+
let result_val = make_ir_value (IRRegister reg) target_type expr.Ast.expr_pos in
1332+
let call_target = match callee_expr.Ast.expr_desc with
1333+
| Ast.Identifier name ->
1334+
if Hashtbl.mem ctx.variables name || Hashtbl.mem ctx.function_parameters name then
1335+
let callee_val = lower_expression ctx callee_expr in
1336+
FunctionPointerCall callee_val
1337+
else
1338+
DirectCall name
1339+
| _ ->
1340+
let callee_val = lower_expression ctx callee_expr in
1341+
FunctionPointerCall callee_val
1342+
in
1343+
let instr = make_ir_instruction (IRCall (call_target, arg_vals, Some result_val)) expr.Ast.expr_pos in
1344+
emit_instruction ctx instr
1345+
| _ -> ()) (* Shouldn't happen due to our guard *)
1346+
| _ ->
1347+
(* Non-function call declarations: use existing logic *)
1348+
let (target_type, init_value_opt) =
1349+
resolve_declaration_type_and_init ctx reg typ_opt expr_opt in
1350+
declare_variable ctx name reg target_type init_value_opt stmt.stmt_pos)
13141351

13151352
| Ast.ConstDeclaration (name, typ_opt, expr) ->
13161353
let reg = get_variable_register ctx name in

0 commit comments

Comments
 (0)