Skip to content

Convert

convert

LLVMTarget dataclass

Bases: Target

Source code in xdsl/backend/llvm/convert.py
151
152
153
154
155
156
157
@dataclass(frozen=True)
class LLVMTarget(Target):
    name = "llvm"

    def emit(self, ctx: Context, module: ModuleOp, output: IO[str]) -> None:
        llvm_module = convert_module(module)
        print(llvm_module, file=output)

name = 'llvm' class-attribute instance-attribute

__init__() -> None

emit(ctx: Context, module: ModuleOp, output: IO[str]) -> None

Source code in xdsl/backend/llvm/convert.py
155
156
157
def emit(self, ctx: Context, module: ModuleOp, output: IO[str]) -> None:
    llvm_module = convert_module(module)
    print(llvm_module, file=output)

convert_module(module: ModuleOp, target_triple: str = '', data_layout: str = '') -> ir.Module

Convert an xDSL module to an LLVM module.

Source code in xdsl/backend/llvm/convert.py
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
def convert_module(
    module: ModuleOp,
    target_triple: str = "",
    data_layout: str = "",
) -> ir.Module:
    """
    Convert an xDSL module to an LLVM module.
    """
    llvm_module = ir.Module()
    if target_triple:
        llvm_module.triple = target_triple
    if data_layout:
        llvm_module.data_layout = data_layout

    func_ops: list[llvm.FuncOp] = []
    for op in module.ops:
        if not isinstance(op, llvm.FuncOp):
            raise NotImplementedError(f"Conversion not implemented for op: {op.name}")
        func_ops.append(op)

    # Declare all functions (enables forward references)
    for op in func_ops:
        ret_type = convert_type(op.function_type.output)
        arg_types: list[ir.Type] = []
        for idx, mlir_type in enumerate(op.function_type.inputs):
            if not (
                isinstance(mlir_type, llvm.LLVMPointerType) and op.arg_attrs is not None
            ):
                arg_types.append(convert_type(mlir_type))
                continue
            attrs = op.arg_attrs.data[idx].data
            elem = next((attrs[n] for n in _ARG_ATTR_TYPES if n in attrs), None)
            if elem is None:
                arg_types.append(convert_type(mlir_type))
                continue
            addrspace = (
                mlir_type.addr_space.data
                if isinstance(mlir_type.addr_space, IntAttr)
                else 0
            )
            arg_types.append(ir.PointerType(convert_type(elem), addrspace=addrspace))
        func_type = ir.FunctionType(ret_type, arg_types)
        fn = ir.Function(llvm_module, func_type, name=op.sym_name.data)

        if op.arg_attrs is None:
            continue
        for llvm_arg, attr_dict in zip(fn.args, op.arg_attrs):
            for mlir_name, value in attr_dict.data.items():
                if mlir_name in _ARG_ATTR_FLAGS:
                    llvm_arg.add_attribute(_ARG_ATTR_FLAGS[mlir_name])
                    continue
                if mlir_name in _ARG_ATTR_TYPES:
                    llvm_arg.add_attribute(_ARG_ATTR_TYPES[mlir_name])
                    continue
                if mlir_name not in _ARG_ATTR_INTS:
                    continue
                assert isinstance(value, IntegerAttr)
                setattr(
                    llvm_arg.attributes, _ARG_ATTR_INTS[mlir_name], value.value.data
                )

    # Generate function bodies
    for func_op in func_ops:
        if func_op.body.blocks:
            _convert_func(func_op, llvm_module)

    return llvm_module