Files
python-bpf/pythonbpf/globals_pass.py

43 lines
1.3 KiB
Python

from llvmlite import ir
import ast
def emit_globals(module: ir.Module, names: list[str]):
"""
Emit the @llvm.compiler.used global given a list of function/global names.
"""
ptr_ty = ir.PointerType()
used_array_ty = ir.ArrayType(ptr_ty, len(names))
elems = []
for name in names:
# Reuse existing globals (like LICENSE), don't redeclare
if name in module.globals:
g = module.get_global(name)
else:
g = ir.GlobalValue(module, ptr_ty, name)
elems.append(g.bitcast(ptr_ty))
gv = ir.GlobalVariable(module, used_array_ty, "llvm.compiler.used")
gv.linkage = "appending"
gv.initializer = ir.Constant(used_array_ty, elems) # type: ignore
gv.section = "llvm.metadata"
def globals_processing(tree, module: ir.Module):
collected = ["LICENSE"]
for node in tree.body:
if isinstance(node, ast.FunctionDef) and len(node.decorator_list) == 1:
dec = node.decorator_list[0]
if (
isinstance(dec, ast.Call)
and isinstance(dec.func, ast.Name)
and len(dec.args) == 1
and isinstance(dec.args[0], ast.Attribute)
and isinstance(dec.args[0].value, ast.Name)
):
collected.append(node.name)
emit_globals(module, collected)