From 3994e503bb761d0165837a2a36f65ad387c0302d Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 8 Nov 2021 12:40:03 +0800 Subject: [PATCH] llvmlite: update and patch Still needs more difficult modifications elsewhere to support this majority of labs using windoze and/or conda garbage. --- artiq-fast/pkgs/llvmlite-abiname.diff | 62 +++++++++ artiq-fast/pkgs/llvmlite-callsite.diff | 185 +++++++++++++++++++++++++ artiq-fast/pkgs/llvmlite-llvm11.nix | 10 +- 3 files changed, 254 insertions(+), 3 deletions(-) create mode 100644 artiq-fast/pkgs/llvmlite-abiname.diff create mode 100644 artiq-fast/pkgs/llvmlite-callsite.diff diff --git a/artiq-fast/pkgs/llvmlite-abiname.diff b/artiq-fast/pkgs/llvmlite-abiname.diff new file mode 100644 index 0000000..7162ae0 --- /dev/null +++ b/artiq-fast/pkgs/llvmlite-abiname.diff @@ -0,0 +1,62 @@ +diff --git a/ffi/targets.cpp b/ffi/targets.cpp +index 98de259fc..1ce472c20 100644 +--- a/ffi/targets.cpp ++++ b/ffi/targets.cpp +@@ -182,7 +182,8 @@ LLVMPY_CreateTargetMachine(LLVMTargetRef T, + const char *RelocModel, + const char *CodeModel, + int PrintMC, +- int JIT) ++ int JIT, ++ const char *ABIName) + { + using namespace llvm; + CodeGenOpt::Level cgol; +@@ -233,6 +234,7 @@ LLVMPY_CreateTargetMachine(LLVMTargetRef T, + + TargetOptions opt; + opt.PrintMachineCode = PrintMC; ++ opt.MCOptions.ABIName = ABIName; + + bool jit = JIT; + +diff --git a/llvmlite/binding/targets.py b/llvmlite/binding/targets.py +index eb53f09f2..a7e6ffdc3 100644 +--- a/llvmlite/binding/targets.py ++++ b/llvmlite/binding/targets.py +@@ -218,7 +218,7 @@ def __str__(self): + + def create_target_machine(self, cpu='', features='', + opt=2, reloc='default', codemodel='jitdefault', +- printmc=False, jit=False): ++ printmc=False, jit=False, abiname=''): + """ + Create a new TargetMachine for this target and the given options. + +@@ -230,6 +230,9 @@ def create_target_machine(self, cpu='', features='', + + The `jit` option should be set when the target-machine is to be used + in a JIT engine. ++ ++ The `abiname` option specifies the ABI. RISC-V targets with hard-float ++ needs to pass the ABI name to LLVM. + """ + assert 0 <= opt <= 3 + assert reloc in RELOC +@@ -249,6 +252,7 @@ def create_target_machine(self, cpu='', features='', + _encode_string(codemodel), + int(printmc), + int(jit), ++ _encode_string(abiname), + ) + if tm: + return TargetMachine(tm) +@@ -403,6 +407,8 @@ def has_svml(): + c_int, + # JIT + c_int, ++ # ABIName ++ c_char_p, + ] + ffi.lib.LLVMPY_CreateTargetMachine.restype = ffi.LLVMTargetMachineRef + diff --git a/artiq-fast/pkgs/llvmlite-callsite.diff b/artiq-fast/pkgs/llvmlite-callsite.diff new file mode 100644 index 0000000..b18529b --- /dev/null +++ b/artiq-fast/pkgs/llvmlite-callsite.diff @@ -0,0 +1,185 @@ +diff --git a/llvmlite/ir/builder.py b/llvmlite/ir/builder.py +index f18a8d8bd..b4958770e 100644 +--- a/llvmlite/ir/builder.py ++++ b/llvmlite/ir/builder.py +@@ -872,14 +872,14 @@ def resume(self, landingpad): + # Call APIs + + def call(self, fn, args, name='', cconv=None, tail=False, fastmath=(), +- attrs=()): ++ attrs=(), arg_attrs=None): + """ + Call function *fn* with *args*: + name = fn(args...) + """ + inst = instructions.CallInstr(self.block, fn, args, name=name, + cconv=cconv, tail=tail, fastmath=fastmath, +- attrs=attrs) ++ attrs=attrs, arg_attrs=arg_attrs) + self._insert(inst) + return inst + +@@ -908,9 +908,11 @@ def store_reg(self, value, reg_type, reg_name, name=''): + return self.asm(ftype, "", "{%s}" % reg_name, [value], True, name) + + def invoke(self, fn, args, normal_to, unwind_to, +- name='', cconv=None, tail=False): ++ name='', cconv=None, fastmath=(), attrs=(), arg_attrs=None): + inst = instructions.InvokeInstr(self.block, fn, args, normal_to, +- unwind_to, name=name, cconv=cconv) ++ unwind_to, name=name, cconv=cconv, ++ fastmath=fastmath, attrs=attrs, ++ arg_attrs=arg_attrs) + self._set_terminator(inst) + return inst + +diff --git a/llvmlite/ir/instructions.py b/llvmlite/ir/instructions.py +index 7e82ee032..f337c1586 100644 +--- a/llvmlite/ir/instructions.py ++++ b/llvmlite/ir/instructions.py +@@ -5,7 +5,7 @@ + from llvmlite.ir import types + from llvmlite.ir.values import (Block, Function, Value, NamedValue, Constant, + MetaDataArgument, MetaDataString, AttributeSet, +- Undefined) ++ Undefined, ArgumentAttributes) + from llvmlite.ir._utils import _HasMetadata + + +@@ -63,13 +63,20 @@ class FastMathFlags(AttributeSet): + + class CallInstr(Instruction): + def __init__(self, parent, func, args, name='', cconv=None, tail=False, +- fastmath=(), attrs=()): ++ fastmath=(), attrs=(), arg_attrs=None): + self.cconv = (func.calling_convention + if cconv is None and isinstance(func, Function) + else cconv) + self.tail = tail + self.fastmath = FastMathFlags(fastmath) + self.attributes = CallInstrAttributes(attrs) ++ self.arg_attributes = {} ++ if arg_attrs: ++ for idx, attrs in arg_attrs.items(): ++ if not (0 <= idx < len(args)): ++ raise ValueError("Invalid argument index {}" ++ .format(idx)) ++ self.arg_attributes[idx] = ArgumentAttributes(attrs) + + # Fix and validate arguments + args = list(args) +@@ -111,8 +118,13 @@ def called_function(self): + return self.callee + + def _descr(self, buf, add_metadata): +- args = ', '.join(['{0} {1}'.format(a.type, a.get_reference()) +- for a in self.args]) ++ def descr_arg(i, a): ++ if i in self.arg_attributes: ++ attrs = ' '.join(self.arg_attributes[i]._to_list()) + ' ' ++ else: ++ attrs = '' ++ return '{0} {1}{2}'.format(a.type, attrs, a.get_reference()) ++ args = ', '.join([descr_arg(i, a) for i, a in enumerate(self.args)]) + + fnty = self.callee.function_type + # Only print function type if variable-argument +@@ -142,10 +154,12 @@ def descr(self, buf): + + class InvokeInstr(CallInstr): + def __init__(self, parent, func, args, normal_to, unwind_to, name='', +- cconv=None): ++ cconv=None, fastmath=(), attrs=(), arg_attrs=None): + assert isinstance(normal_to, Block) + assert isinstance(unwind_to, Block) +- super(InvokeInstr, self).__init__(parent, func, args, name, cconv) ++ super(InvokeInstr, self).__init__(parent, func, args, name, cconv, ++ tail=False, fastmath=fastmath, ++ attrs=attrs, arg_attrs=arg_attrs) + self.opname = "invoke" + self.normal_to = normal_to + self.unwind_to = unwind_to +diff --git a/llvmlite/tests/test_ir.py b/llvmlite/tests/test_ir.py +index e97e528ac..ab5864719 100644 +--- a/llvmlite/tests/test_ir.py ++++ b/llvmlite/tests/test_ir.py +@@ -1181,6 +1181,39 @@ def test_call_metadata(self): + call void @"llvm.dbg.declare"(metadata i32* %"a", metadata !0, metadata !0) + """) # noqa E501 + ++ def test_call_attributes(self): ++ block = self.block(name='my_block') ++ builder = ir.IRBuilder(block) ++ fun_ty = ir.FunctionType( ++ ir.VoidType(), (int32.as_pointer(), int32, int32.as_pointer())) ++ fun = ir.Function(builder.function.module, fun_ty, 'fun') ++ fun.args[0].add_attribute('sret') ++ retval = builder.alloca(int32, name='retval') ++ other = builder.alloca(int32, name='other') ++ builder.call( ++ fun, ++ (retval, ir.Constant(int32, 42), other), ++ arg_attrs={ ++ 0: ('sret', 'noalias'), ++ 2: 'noalias' ++ } ++ ) ++ self.check_block(block, """\ ++ my_block: ++ %"retval" = alloca i32 ++ %"other" = alloca i32 ++ call void @"fun"(i32* noalias sret %"retval", i32 42, i32* noalias %"other") ++ """) # noqa E501 ++ ++ def test_invalid_call_attributes(self): ++ block = self.block() ++ builder = ir.IRBuilder(block) ++ fun_ty = ir.FunctionType(ir.VoidType(), ()) ++ fun = ir.Function(builder.function.module, fun_ty, 'fun') ++ with self.assertRaises(ValueError): ++ # The function has no arguments, so this should fail. ++ builder.call(fun, (), arg_attrs={0: 'sret'}) ++ + def test_invoke(self): + block = self.block(name='my_block') + builder = ir.IRBuilder(block) +@@ -1196,6 +1229,39 @@ def test_invoke(self): + to label %"normal" unwind label %"unwind" + """) + ++ def test_invoke_attributes(self): ++ block = self.block(name='my_block') ++ builder = ir.IRBuilder(block) ++ fun_ty = ir.FunctionType( ++ ir.VoidType(), (int32.as_pointer(), int32, int32.as_pointer())) ++ fun = ir.Function(builder.function.module, fun_ty, 'fun') ++ fun.calling_convention = "fastcc" ++ fun.args[0].add_attribute('sret') ++ retval = builder.alloca(int32, name='retval') ++ other = builder.alloca(int32, name='other') ++ bb_normal = builder.function.append_basic_block(name='normal') ++ bb_unwind = builder.function.append_basic_block(name='unwind') ++ builder.invoke( ++ fun, ++ (retval, ir.Constant(int32, 42), other), ++ bb_normal, ++ bb_unwind, ++ cconv='fastcc', ++ fastmath='fast', ++ attrs='noinline', ++ arg_attrs={ ++ 0: ('sret', 'noalias'), ++ 2: 'noalias' ++ } ++ ) ++ self.check_block(block, """\ ++ my_block: ++ %"retval" = alloca i32 ++ %"other" = alloca i32 ++ invoke fast fastcc void @"fun"(i32* noalias sret %"retval", i32 42, i32* noalias %"other") noinline ++ to label %"normal" unwind label %"unwind" ++ """) # noqa E501 ++ + def test_landingpad(self): + block = self.block(name='my_block') + builder = ir.IRBuilder(block) diff --git a/artiq-fast/pkgs/llvmlite-llvm11.nix b/artiq-fast/pkgs/llvmlite-llvm11.nix index d121cc1..9bc140a 100644 --- a/artiq-fast/pkgs/llvmlite-llvm11.nix +++ b/artiq-fast/pkgs/llvmlite-llvm11.nix @@ -2,11 +2,15 @@ python3Packages.buildPythonPackage rec { pname = "llvmlite"; - version = "0.37.0rc2"; + version = "0.37.0-artiq"; src = python3Packages.fetchPypi { - inherit pname version; - sha256 = "sha256-F1quz+76JOt1jaQPVzdKe7RfN6gWG2lyE82qTvgyY/c="; + inherit pname; + version = "0.37.0"; + sha256 = "sha256-Y5K4cM0BjsDGRda7uRjWqg7sqMYmdLqu4whi1raGWxU="; }; + # https://github.com/numba/llvmlite/pull/702 + # https://github.com/numba/llvmlite/pull/775 + patches = [ ./llvmlite-callsite.diff ./llvmlite-abiname.diff ]; nativeBuildInputs = [ llvm_11 ]; # Disable static linking # https://github.com/numba/llvmlite/issues/93