diff --git a/sledge/cli/frontend.ml b/sledge/cli/frontend.ml index eba558915..a8e91fbd8 100644 --- a/sledge/cli/frontend.ml +++ b/sledge/cli/frontend.ml @@ -945,7 +945,25 @@ let norm_callee llfunc = | _ -> todo "callee kind %a" pp_llvalue llfunc () ) | _ -> todo "callee kind %a" pp_llvalue llfunc () -let xlate_intrinsic_inst emit_inst x llname instr loc = +let num_actuals instr lltyp llfunc = + assert (Poly.(Llvm.classify_type lltyp = Pointer)) ; + if not (Llvm.is_var_arg (Llvm.element_type lltyp)) then + Llvm.num_arg_operands instr + else + let fname = Llvm.value_name llfunc in + if StringS.add ignored_callees fname && not (Llvm.is_declaration llfunc) + then + warn "ignoring variable arguments to variadic function: %a" pp_llvalue + llfunc () ; + let llelt = Llvm.element_type lltyp in + ( match Llvm.classify_type llelt with + | Function -> () + | _ -> + fail "called function not of function type: %a" pp_llvalue instr () + ) ; + Array.length (Llvm.param_types llelt) + +let xlate_intrinsic_inst emit_inst x llname instr num_actuals loc = let emit_inst ?prefix inst = Some (emit_inst ?prefix inst) in match String.split_on_char llname ~by:'.' with | ["__llair_choice"] -> @@ -1002,13 +1020,12 @@ let xlate_intrinsic_inst emit_inst x llname instr loc = match Intrinsic.of_name fname with | Some name -> let reg = xlate_name_opt x instr in - let num_args = Llvm.num_operands instr - 2 in let xlate_arg i pre = let pre_i, arg_i = xlate_value x (Llvm.operand instr i) in (arg_i, pre_i @ pre) in let prefix, args = - Iter.fold_map ~f:xlate_arg Iter.(0 -- num_args) [] + Iter.fold_map ~f:xlate_arg Iter.(0 -- (num_actuals - 1)) [] in let args = IArray.of_iter args in emit_inst ~prefix (Inst.intrinsic ~reg ~name ~args ~loc) @@ -1073,8 +1090,8 @@ let xlate_instr : | Call -> ( let llcallee = Llvm.operand instr (Llvm.num_operands instr - 1) in let lltyp = Llvm.type_of llcallee in - assert (Poly.(Llvm.classify_type lltyp = Pointer)) ; let llfunc = norm_callee llcallee in + let num_actuals = num_actuals instr lltyp llfunc in let fname = Llvm.value_name llfunc in let skip msg = if StringS.add ignored_callees fname then @@ -1086,7 +1103,9 @@ let xlate_instr : match xlate_intrinsic_exp fname with | Some intrinsic -> inline_or_move (intrinsic x) | None -> ( - match xlate_intrinsic_inst emit_inst x fname instr loc with + match + xlate_intrinsic_inst emit_inst x fname instr num_actuals loc + with | Some code -> code | None -> ( match String.split_on_char fname ~by:'.' with @@ -1117,27 +1136,6 @@ let xlate_instr : let lbl = name ^ ".ret" in let pre, call = let pre, actuals = - let num_actuals = - if not (Llvm.is_var_arg (Llvm.element_type lltyp)) then - Llvm.num_arg_operands instr - else - let fname = Llvm.value_name llfunc in - if - StringS.add ignored_callees fname - && not (Llvm.is_declaration llfunc) - then - warn - "ignoring variable arguments to variadic \ - function: %a" - Exp.pp callee () ; - let llfty = Llvm.element_type lltyp in - ( match Llvm.classify_type llfty with - | Function -> () - | _ -> - fail "called function not of function type: %a" - pp_llvalue instr () ) ; - Array.length (Llvm.param_types llfty) - in xlate_values x num_actuals (Llvm.operand instr) in let areturn = xlate_name_opt x instr in @@ -1150,25 +1148,13 @@ let xlate_instr : let cmnd = IArray.of_list insts in (pre0 @ pre, call, [Block.mk ~lbl ~cmnd ~term]) ) ) ) ) | Invoke -> ( - let llfunc = Llvm.operand instr (Llvm.num_operands instr - 3) in - let lltyp = Llvm.type_of llfunc in - assert (Poly.(Llvm.classify_type lltyp = Pointer)) ; + let llcallee = Llvm.operand instr (Llvm.num_operands instr - 3) in + let lltyp = Llvm.type_of llcallee in + let llfunc = norm_callee llcallee in + let num_actuals = num_actuals instr lltyp llfunc in let fname = Llvm.value_name llfunc in let return_blk = Llvm.get_normal_dest instr in let unwind_blk = Llvm.get_unwind_dest instr in - let num_actuals = - if not (Llvm.is_var_arg (Llvm.element_type lltyp)) then - Llvm.num_arg_operands instr - else ( - if - StringS.add ignored_callees fname - && not (Llvm.is_declaration llfunc) - then - warn "ignoring variable arguments to variadic function: %a" - Global.pp (xlate_global x llfunc).name () ; - assert (Poly.(Llvm.classify_type lltyp = Pointer)) ; - Array.length (Llvm.param_types (Llvm.element_type lltyp)) ) - in (* intrinsics *) match String.split_on_char fname ~by:'.' with | _ when Option.is_some (xlate_intrinsic_exp fname) -> @@ -1197,7 +1183,7 @@ let xlate_instr : (* general function call that may throw *) | _ -> let pre_0, callee = xlate_value x llfunc in - let typ = xlate_type x (Llvm.type_of llfunc) in + let typ = xlate_type x lltyp in let pre_1, actuals = xlate_values x num_actuals (Llvm.operand instr) in