Skip to content

Commit 259497d

Browse files
committed
vararg
1 parent 687087b commit 259497d

File tree

1 file changed

+38
-28
lines changed

1 file changed

+38
-28
lines changed

src/device/intrinsics/output.jl

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,7 @@ end
4949

5050
# create functions
5151
param_types = LLVMType[convert(LLVMType, typ) for typ in arg_types]
52-
llvm_f, llvm_ft = create_function(T_void, param_types)
53-
push!(function_attributes(llvm_f), EnumAttribute("alwaysinline", 0))
54-
52+
llvm_f, llvm_ft = create_function(T_void, LLVMType[]; vararg=true)
5553
mod = LLVM.parent(llvm_f)
5654

5755
# generate IR
@@ -60,42 +58,54 @@ end
6058
position!(builder, entry)
6159

6260
str = globalstring_ptr!(builder, String(fmt), addrspace=2)
63-
argsize = 0
64-
65-
# construct and fill args buffer
66-
if isempty(argspec)
67-
buffer = LLVM.PointerNull(T_pint8)
68-
else
69-
argtypes = LLVM.StructType("os_log_args")
70-
elements!(argtypes, param_types)
71-
72-
args = alloca!(builder, argtypes)
73-
for (i, param) in enumerate(parameters(llvm_f))
74-
p = struct_gep!(builder, argtypes, args, i-1)
75-
store!(builder, param, p)
76-
end
7761

78-
dl = datalayout(mod)
79-
argsize = sizeof(dl, argtypes)
80-
buffer = bitcast!(builder, args, T_pint8)
81-
end
62+
# compute argsize
63+
argtypes = LLVM.StructType("os_log_args")
64+
elements!(argtypes, param_types)
65+
dl = datalayout(mod)
66+
argsize = sizeof(dl, argtypes)
67+
68+
# argbuffer
69+
alloc = alloca!(builder, T_pint8)
70+
buffer = bitcast!(builder, alloc, T_pint8)
71+
72+
va_start_fty = LLVM.FunctionType(T_void, [T_pint8])
73+
va_start = LLVM.Function(mod, "llvm.va_start", va_start_fty)
74+
call!(builder, va_start_fty, va_start, [buffer])
8275

8376
# invoke @air.os_log and return
8477
subsystem_str = globalstring_ptr!(builder, MTLLOG_SUBSYSTEM, addrspace=2)
85-
# subsystem_str = LLVM.PointerNull(T_pint8a2)
86-
# intptr = LLVM.ConstantInt(T_int64, Int64(-1))
87-
# category_str = const_inttoptr(intptr, T_pint8a2)
8878
category_str = globalstring_ptr!(builder, MTLLOG_CATEGRORY, addrspace=2)
8979
log_type = LLVM.ConstantInt(T_int32, __METAL_OS_LOG_TYPE_DEBUG__)
90-
arg_size = LLVM.ConstantInt(T_int64, Int64(argsize))
91-
9280
os_log_fty = LLVM.FunctionType(T_void, [T_pint8a2, T_pint8a2, T_int32, T_pint8a2, T_pint8, T_int64])
9381
os_log = LLVM.Function(mod, "air.os_log", os_log_fty)
94-
call!(builder, os_log_fty, os_log, [subsystem_str, category_str, log_type, str, buffer, arg_size])
82+
83+
arg_size = LLVM.ConstantInt(T_int64, Int64(argsize))
84+
85+
arg_ptr = load!(builder, T_pint8, alloc)
86+
87+
call!(builder, os_log_fty, os_log, [subsystem_str, category_str, log_type, str, arg_ptr, arg_size])
88+
89+
va_end_fty = LLVM.FunctionType(T_void, [T_pint8])
90+
va_end = LLVM.Function(mod, "llvm.va_end", va_end_fty)
91+
call!(builder, va_end_fty, va_end, [buffer])
92+
93+
ret!(builder)
94+
end
95+
96+
97+
wrapper_f, wrapper_ft = create_function(T_void, param_types)
98+
99+
@dispose builder=IRBuilder() begin
100+
entry = BasicBlock(wrapper_f, "entry")
101+
position!(builder, entry)
102+
103+
call!(builder, llvm_ft, llvm_f, collect(parameters(wrapper_f)))
104+
95105
ret!(builder)
96106
end
97107

98-
call_function(llvm_f, Nothing, Tuple{arg_types...}, arg_exprs...)
108+
call_function(wrapper_f, Nothing, Tuple{arg_types...}, arg_exprs...)
99109
end
100110
end
101111

0 commit comments

Comments
 (0)