3 # SPDX-FileCopyrightText: 2023 EfficiOS, Inc.
5 # SPDX-License-Identifier: MIT
7 # Author: Olivier Dion <odion@efficios.com>
9 # Auto-generate lttng-ust wrappers for HSA.
11 # Please refer to gen-hip-wrappers. This is basically the same thing but
14 # Require: python-clang (libclang)
20 from string
import Template
24 def list_function_declarations(root
):
27 for child
in root
.get_children()
28 if child
.kind
== clang
.cindex
.CursorKind
.FUNCTION_DECL
31 def get_system_include_paths():
33 clang_args
= ["clang", "-v", "-c", "-xc", "-o", "/dev/null", "/dev/null"]
36 with subprocess
.Popen(clang_args
, stderr
=subprocess
.PIPE
, text
=True) as proc
:
37 start_sys_search
= False
38 for line
in proc
.stderr
:
40 if line
== "End of search list.\n":
42 paths
.append("-isystem")
43 paths
.append(line
.strip())
44 elif line
== "#include <...> search starts here:\n":
45 start_sys_search
= True
49 def parse_header(header_file
, includes
, defines
):
51 args
= get_system_include_paths()
63 tu
= clang
.cindex
.Index
.create().parse(header_file
, args
=args
)
65 for d
in tu
.diagnostics
:
66 print(f
"WARNING: {d}")
70 def list_functions(root
):
73 for fn
in list_function_declarations(root
)
74 if fn
.spelling
.startswith("hsa") and fn
.spelling
77 def exact_definition(arg
):
79 ct
= arg
.type.get_canonical()
80 if ct
.kind
== clang
.cindex
.TypeKind
.POINTER
:
82 if pt
.kind
== clang
.cindex
.TypeKind
.FUNCTIONPROTO
:
83 ret_type
= pt
.get_result().spelling
84 argument_types
= ", ".join([a
.spelling
for a
in pt
.argument_types()])
85 return f
"{ret_type} (*{arg.spelling})({argument_types})"
86 m
= re
.search(r
'(\[[0-9]*\])+', arg
.type.spelling
)
88 return f
"{arg.type.spelling[:m.start(0)]} {arg.spelling}{m.group(0)}"
90 return f
"{arg.type.spelling} {arg.spelling}"
93 canon
= arg
.type.get_canonical()
94 if canon
.kind
== clang
.cindex
.TypeKind
.POINTER
:
96 return re
.sub(r
'\[[0-9]*\]', '*', canon
.spelling
)
105 forbiden_list
= set()
107 parser
= argparse
.ArgumentParser(prog
="gen-hsa-wrappers")
109 parser
.add_argument("api",
110 help="HSA API header")
112 parser
.add_argument("wrappers",
113 help="Path to HSA wrappers")
115 parser
.add_argument("--ignores",
121 parser
.add_argument("-I",
125 help="Add DIR to list of directories to include")
127 parser
.add_argument("-D",
129 metavar
="DEFINITION",
131 help="Add DEFINITION to list of definitions")
133 args
= parser
.parse_args()
136 with
open(args
.ignores
, "r") as f
:
137 for ignore
in f
.read().splitlines():
138 forbiden_list
.add(ignore
)
140 prologue_tpl
= Template("""/* Auto-generated */
141 #include "lttng-ust-hsa-states.h"
144 ret_fn_tpl
= Template("""
145 static ${ret_type} lttng_${fn_name}(${fn_arguments})
149 lttng_hsa::api_object_${fn_name} lttng_api_object {${fn_rest_argument_names}};
150 ret = next_hsa_core_table.${fn_name}_fn(${fn_pass_argument_names});
151 lttng_api_object.mark_return(ret);
158 void_fn_tpl
= Template("""
159 static void lttng_${fn_name}(${fn_arguments})
162 lttng_hsa::api_object_${fn_name} lttng_api_object {${fn_rest_argument_names}};
163 next_hsa_core_table.${fn_name}_fn(${fn_pass_argument_names});
164 lttng_api_object.mark_return();
170 epilogue_tpl
= Template("""
171 static void lttng_hsa_install_wrappers(void)
177 functions
= list_functions(parse_header(args
.api
,
181 with
open(args
.wrappers
, "w") as output
:
183 output
.write(prologue_tpl
.substitute())
187 if fn
.spelling
in forbiden_list
:
190 args
= list(fn
.get_arguments())
191 fn_pass_argument_names
= ", ".join([
197 fn_rest_argument_names
= ", ".join([
198 "(%s)%s" % (cast(arg
), arg
.spelling
)
202 fn_rest_argument_names
=""
204 if fn
.spelling
in extra_works
:
205 extra_work
= extra_works
[fn
.spelling
]
209 if "void"== fn
.type.get_result().spelling
:
214 output
.write(fn_tpl
.substitute(fn_name
=fn
.spelling
,
215 fn_arguments
=", ".join([
216 exact_definition(arg
)
217 for arg
in fn
.get_arguments()
219 fn_pass_argument_names
=fn_pass_argument_names
,
220 fn_rest_argument_names
=fn_rest_argument_names
,
221 ret_type
=fn
.type.get_result().spelling
,
222 extra_work
=extra_work
))
224 output
.write(epilogue_tpl
.substitute(wrappers
="\n ".join([
225 f
"lttng_hsa_core_table.{fn.spelling}_fn = <tng_{fn.spelling};"
226 for fn
in functions
if fn
.spelling
not in forbiden_list
230 if __name__
== "__main__":
This page took 0.038096 seconds and 4 git commands to generate.