ruby-llvm 3.4.0 → 11.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +19 -4
  3. data/ext/ruby-llvm-support/Rakefile +20 -8
  4. data/ext/ruby-llvm-support/support.cpp +0 -20
  5. data/lib/llvm.rb +0 -6
  6. data/lib/llvm/analysis_ffi.rb +30 -28
  7. data/lib/llvm/config.rb +4 -4
  8. data/lib/llvm/core.rb +45 -2
  9. data/lib/llvm/core/bitcode.rb +10 -10
  10. data/lib/llvm/core/bitcode_ffi.rb +92 -70
  11. data/lib/llvm/core/builder.rb +2 -3
  12. data/lib/llvm/core/context.rb +1 -1
  13. data/lib/llvm/core/pass_manager.rb +4 -2
  14. data/lib/llvm/core/type.rb +2 -2
  15. data/lib/llvm/core/value.rb +155 -28
  16. data/lib/llvm/core_ffi.rb +4038 -3716
  17. data/lib/llvm/execution_engine.rb +176 -8
  18. data/lib/llvm/execution_engine_ffi.rb +245 -272
  19. data/lib/llvm/linker.rb +2 -19
  20. data/lib/llvm/linker_ffi.rb +24 -25
  21. data/lib/llvm/support.rb +4 -12
  22. data/lib/llvm/target.rb +11 -17
  23. data/lib/llvm/target_ffi.rb +336 -362
  24. data/lib/llvm/transforms/builder.rb +8 -3
  25. data/lib/llvm/transforms/builder_ffi.rb +57 -58
  26. data/lib/llvm/transforms/ipo.rb +1 -1
  27. data/lib/llvm/transforms/ipo_ffi.rb +60 -61
  28. data/lib/llvm/transforms/scalar_ffi.rb +208 -136
  29. data/lib/llvm/transforms/vectorize_ffi.rb +15 -16
  30. data/lib/llvm/version.rb +3 -2
  31. data/test/basic_block_test.rb +0 -1
  32. data/test/bitcode_test.rb +1 -2
  33. data/test/call_test.rb +1 -1
  34. data/test/double_test.rb +8 -7
  35. data/test/equality_test.rb +2 -4
  36. data/test/function_test.rb +27 -0
  37. data/test/generic_value_test.rb +1 -1
  38. data/test/instruction_test.rb +0 -2
  39. data/test/ipo_test.rb +1 -1
  40. data/test/linker_test.rb +0 -9
  41. data/test/mcjit_test.rb +100 -0
  42. data/test/module_test.rb +31 -1
  43. data/test/pass_manager_builder_test.rb +23 -3
  44. data/test/target_test.rb +7 -24
  45. data/test/test_helper.rb +4 -1
  46. metadata +117 -94
@@ -4,36 +4,35 @@ require 'ffi'
4
4
 
5
5
  module LLVM::C
6
6
  extend FFI::Library
7
- ffi_lib 'LLVM-3.4'
8
-
7
+ ffi_lib ["libLLVM-11.so.1", "libLLVM.so.11", "LLVM-11"]
8
+
9
9
  def self.attach_function(name, *_)
10
10
  begin; super; rescue FFI::NotFoundError => e
11
11
  (class << self; self; end).class_eval { define_method(name) { |*_| raise e } }
12
12
  end
13
13
  end
14
-
15
- # (Not documented)
16
- #
14
+
15
+ # DEPRECATED - Use LLVMAddSLPVectorizePass
16
+ #
17
17
  # @method add_bb_vectorize_pass(pm)
18
- # @param [FFI::Pointer(PassManagerRef)] pm
19
- # @return [nil]
18
+ # @param [FFI::Pointer(PassManagerRef)] pm
19
+ # @return [nil]
20
20
  # @scope class
21
21
  attach_function :add_bb_vectorize_pass, :LLVMAddBBVectorizePass, [:pointer], :void
22
-
22
+
23
23
  # See llvm::createLoopVectorizePass function.
24
- #
24
+ #
25
25
  # @method add_loop_vectorize_pass(pm)
26
- # @param [FFI::Pointer(PassManagerRef)] pm
27
- # @return [nil]
26
+ # @param [FFI::Pointer(PassManagerRef)] pm
27
+ # @return [nil]
28
28
  # @scope class
29
29
  attach_function :add_loop_vectorize_pass, :LLVMAddLoopVectorizePass, [:pointer], :void
30
-
30
+
31
31
  # See llvm::createSLPVectorizerPass function.
32
- #
32
+ #
33
33
  # @method add_slp_vectorize_pass(pm)
34
- # @param [FFI::Pointer(PassManagerRef)] pm
35
- # @return [nil]
34
+ # @param [FFI::Pointer(PassManagerRef)] pm
35
+ # @return [nil]
36
36
  # @scope class
37
37
  attach_function :add_slp_vectorize_pass, :LLVMAddSLPVectorizePass, [:pointer], :void
38
-
39
38
  end
@@ -1,4 +1,5 @@
1
1
  module LLVM
2
- LLVM_VERSION = "3.4"
3
- RUBY_LLVM_VERSION = "3.4.0"
2
+ LLVM_VERSION = "11".freeze
3
+ LLVM_REQUIRED_VERSION = "11.0".freeze
4
+ RUBY_LLVM_VERSION = "11.0.1".freeze
4
5
  end
@@ -85,4 +85,3 @@ class BasicBlockTestCase < Minitest::Test
85
85
  end
86
86
 
87
87
  end
88
-
@@ -8,8 +8,7 @@ class BitcodeTestCase < Minitest::Test
8
8
 
9
9
  def test_bitcode
10
10
  test_module = define_module("test_module") do |mod|
11
- define_function(mod, "test_function", [], LLVM::Int) do
12
- |builder, function, *arguments|
11
+ define_function(mod, "test_function", [], LLVM::Int) do |builder, function, *arguments|
13
12
  entry = function.basic_blocks.append
14
13
  builder.position_at_end(entry)
15
14
  builder.ret(LLVM::Int(1))
@@ -60,7 +60,7 @@ class CallTestCase < Minitest::Test
60
60
  builder.ret(builder.call(external, arguments.first))
61
61
  end
62
62
  end
63
- assert_equal -10.abs, run_function_on_module(test_module, "test_function", -10).to_i
63
+ assert_equal(-10.abs, run_function_on_module(test_module, "test_function", -10).to_i)
64
64
  end
65
65
 
66
66
  def test_external_string
@@ -6,7 +6,7 @@ class DoubleTestCase < Minitest::Test
6
6
  end
7
7
 
8
8
  def test_double
9
- mod = LLVM::Module.new("Double Test")
9
+ mod = LLVM::Module.new("Double Test")
10
10
  mod.functions.add(:sin, [LLVM::Double], LLVM::Double)
11
11
 
12
12
  builder = LLVM::Builder.new
@@ -20,14 +20,15 @@ class DoubleTestCase < Minitest::Test
20
20
  builder.ret(builder.fadd(p0, LLVM::Double(1.0)))
21
21
  end
22
22
 
23
- engine = LLVM::JITCompiler.new(mod)
23
+ engine = LLVM::MCJITCompiler.new(mod)
24
24
 
25
- arg = 5.0
25
+ arg = 5.0
26
26
  result = engine.run_function(mod.functions["test"], arg)
27
- assert_equal arg+1, result.to_f(LLVM::Double)
27
+ assert_equal arg + 1, result.to_f(LLVM::Double)
28
28
 
29
- assert_in_delta(Math.sin(1.0),
30
- engine.run_function(mod.functions["sin"], 1.0).to_f(LLVM::Double),
31
- 1e-10)
29
+ # TODO: fix this
30
+ # assert_in_delta(Math.sin(1.0),
31
+ # engine.run_function(mod.functions["sin"], 1.0).to_f(LLVM::Double),
32
+ # 1e-10)
32
33
  end
33
34
  end
@@ -14,9 +14,9 @@ class EqualityTestCase < Minitest::Test
14
14
  def assert_equalities(options)
15
15
  map = {
16
16
  :equal => method(:assert_equal),
17
- :not_equal => lambda {|n, m, name| assert n != m, name },
17
+ :not_equal => lambda {|n, m, name| assert n != m, name },
18
18
  :same => method(:assert_same),
19
- :not_same => lambda {|n, m, name| assert !n.equal?(m), name },
19
+ :not_same => lambda {|n, m, name| assert !n.equal?(m), name },
20
20
  :eql => lambda {|n, m, name| assert n.eql?(m), name },
21
21
  :not_eql => lambda {|n, m, name| assert !n.eql?(m), name },
22
22
  }
@@ -26,7 +26,6 @@ class EqualityTestCase < Minitest::Test
26
26
  callable.call(n, m, name.to_s)
27
27
  end
28
28
  end
29
-
30
29
  end
31
30
 
32
31
  def test_int_value
@@ -88,4 +87,3 @@ class EqualityTestCase < Minitest::Test
88
87
  end
89
88
 
90
89
  end
91
-
@@ -30,6 +30,33 @@ class FunctionTest < Minitest::Test
30
30
  end
31
31
  end
32
32
 
33
+ def helper_test_attribute(name)
34
+ with_function [], LLVM.Void do |fun|
35
+ assert_equal 0, fun.attribute_count
36
+ assert_equal [], fun.attributes
37
+
38
+ fun.add_attribute(name)
39
+ assert_equal 1, fun.attribute_count
40
+ assert_equal [30], fun.attributes
41
+
42
+ assert_equal false, fun.verify
43
+
44
+ fun.remove_attribute(name)
45
+ assert_equal 0, fun.attribute_count
46
+ assert_equal [], fun.attributes
47
+
48
+ assert_equal false, fun.verify
49
+ end
50
+ end
51
+
52
+ def test_add_attribute_old_name
53
+ helper_test_attribute(:no_unwind_attribute)
54
+ end
55
+
56
+ def test_add_attribute_new_name
57
+ helper_test_attribute(:nounwind)
58
+ end
59
+
33
60
  end
34
61
 
35
62
  class FunctionTypeTest < Minitest::Test
@@ -8,7 +8,7 @@ class GenericValueTestCase < Minitest::Test
8
8
 
9
9
  def test_from_i
10
10
  assert_equal 2, LLVM::GenericValue.from_i(2).to_i
11
- assert_equal 2 ,LLVM::GenericValue.from_i(2.2).to_i
11
+ assert_equal 2, LLVM::GenericValue.from_i(2.2).to_i
12
12
  end
13
13
 
14
14
  def test_from_float
@@ -28,5 +28,3 @@ class InstructionTestCase < Minitest::Test
28
28
  assert_equal entry, inst2.parent
29
29
  end
30
30
  end
31
-
32
-
@@ -39,7 +39,7 @@ class IPOTestCase < Minitest::Test
39
39
  assert fns.include?(main)
40
40
 
41
41
  # optimize
42
- engine = LLVM::JITCompiler.new(mod)
42
+ engine = LLVM::MCJITCompiler.new(mod)
43
43
  passm = LLVM::PassManager.new(engine)
44
44
 
45
45
  passm.gdce!
@@ -34,13 +34,4 @@ class LinkerTestCase < Minitest::Test
34
34
 
35
35
  assert_equal 42, run_function_on_module(@mod1, 'main').to_i
36
36
  end
37
-
38
- def test_link_into_and_destroy
39
- create_modules
40
- @mod2.link_into_and_destroy(@mod1)
41
-
42
- assert_nil @mod2.to_ptr
43
-
44
- assert_equal 42, run_function_on_module(@mod1, 'main').to_i
45
- end
46
37
  end
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+
3
+ class MCJITTestCase < Minitest::Test
4
+ def setup
5
+ LLVM.init_jit(true)
6
+ end
7
+
8
+ def create_square_function_module
9
+ LLVM::Module.new('square').tap do |mod|
10
+ mod.functions.add(:square, [LLVM::Int], LLVM::Int) do |fun, x|
11
+ fun.basic_blocks.append.build do |builder|
12
+ n = builder.mul(x, x)
13
+ builder.ret(n)
14
+ end
15
+ end
16
+
17
+ mod.verify!
18
+ end
19
+ end
20
+
21
+ def test_simple_function
22
+ mod = create_square_function_module
23
+
24
+ engine = LLVM::MCJITCompiler.new(mod, :opt_level => 0)
25
+
26
+ result = engine.run_function(mod.functions['square'], 5)
27
+ assert_equal 25, result.to_i
28
+ end
29
+
30
+ def test_functions_named
31
+ mod = LLVM::Module.new('foo').tap do |mod|
32
+ mod.functions.add(:foo, [], LLVM::Int)
33
+ mod.verify!
34
+ end
35
+
36
+ engine = LLVM::MCJITCompiler.new(mod, :opt_level => 0)
37
+
38
+ # TODO: fix or replace find_function
39
+ skip
40
+
41
+ ['foo', :foo].each do |name|
42
+ engine.functions[name].tap do |fun|
43
+ assert fun, "function named #{name.inspect}"
44
+ assert_equal 'foo', fun.name
45
+ end
46
+ end
47
+ end
48
+
49
+ def test_add_module
50
+ main_mod = LLVM::Module.new('main')
51
+
52
+ main_mod.functions.add(:square, [LLVM::Int], LLVM::Int) do |square|
53
+ main_mod.functions.add(:call_square, [], LLVM::Int) do |call_square|
54
+ call_square.basic_blocks.append.build do |builder|
55
+ n = builder.call(square, LLVM::Int(5))
56
+ builder.ret(n)
57
+ end
58
+ end
59
+ end
60
+
61
+ main_mod.verify!
62
+
63
+ engine = LLVM::MCJITCompiler.new(main_mod, :opt_level => 0)
64
+ engine.modules << create_square_function_module
65
+
66
+ result = engine.run_function(main_mod.functions['call_square'])
67
+ assert_equal 25, result.to_i
68
+ end
69
+
70
+ def test_remove_module
71
+ mod1 = LLVM::Module.new('foo')
72
+ mod2 = LLVM::Module.new('bar')
73
+
74
+ foo = mod1.functions.add(:foo, [], LLVM::Int)
75
+ bar = mod2.functions.add(:bar, [], LLVM::Int)
76
+
77
+ engine = LLVM::MCJITCompiler.new(mod1, :opt_level => 0)
78
+
79
+ (engine.modules << mod2).tap do |ret|
80
+ assert_equal engine.modules, ret, '#<< returns self'
81
+ end
82
+
83
+ # TODO: fix or replace find_function
84
+ skip
85
+
86
+ refute_nil engine.functions[:bar]
87
+ engine.modules.delete(mod2).tap do |ret|
88
+ assert_instance_of LLVM::Module, ret, '#delete returns module'
89
+ assert_equal mod2, ret
90
+ end
91
+ assert_nil engine.functions[:bar]
92
+ end
93
+
94
+ def test_accessors
95
+ main_mod = LLVM::Module.new('main')
96
+ engine = LLVM::MCJITCompiler.new(main_mod, :opt_level => 0)
97
+ assert_match(/^e-/, engine.data_layout.to_s)
98
+ assert_match(/gnu/, engine.target_machine.triple)
99
+ end
100
+ end
@@ -28,9 +28,24 @@ class ModuleTestCase < Minitest::Test
28
28
 
29
29
  assert var.kind_of?(LLVM::GlobalVariable)
30
30
 
31
+ # unnamed_addr
31
32
  assert !var.unnamed_addr?
32
33
  var.unnamed_addr = true
33
34
  assert var.unnamed_addr?
35
+
36
+ assert (var.dll_storage_class == :default)
37
+ var.dll_storage_class = :dll_import
38
+ assert (var.dll_storage_class == :dll_import)
39
+
40
+ # global_constant
41
+ assert !var.global_constant?
42
+ var.global_constant = true
43
+ assert var.global_constant?
44
+
45
+ assert_output("", "Warning: Passing Integer value to LLVM::GlobalValue#global_constant=(Boolean) is deprecated.\n") do
46
+ var.global_constant = 0
47
+ end
48
+ assert !var.global_constant?
34
49
  end
35
50
  end
36
51
 
@@ -39,7 +54,8 @@ class ModuleTestCase < Minitest::Test
39
54
 
40
55
  def test_to_s
41
56
  mod = LLVM::Module.new('test_print')
42
- assert_equal mod.to_s, "; ModuleID = 'test_print'\n"
57
+ assert_equal mod.to_s,
58
+ "; ModuleID = 'test_print'\nsource_filename = \"test_print\"\n"
43
59
  end
44
60
 
45
61
  def test_dump
@@ -60,4 +76,18 @@ class ModuleTestCase < Minitest::Test
60
76
  end
61
77
  end
62
78
 
79
+ def test_module_properties
80
+ mod = LLVM::Module.new('mod')
81
+
82
+ assert_equal '', mod.triple
83
+
84
+ mod.triple = 'x86-linux-gnu'
85
+ assert_equal 'x86-linux-gnu', mod.triple
86
+
87
+ assert_equal '', mod.data_layout
88
+
89
+ mod.data_layout = 'e-p:32:32'
90
+ assert_equal 'e-p:32:32', mod.data_layout
91
+ end
92
+
63
93
  end
@@ -1,14 +1,18 @@
1
1
  require 'test_helper'
2
+ require 'llvm/config'
2
3
  require 'llvm/transforms/builder'
3
4
 
4
5
  class PassManagerBuilderTest < Minitest::Test
5
6
  def setup
6
7
  LLVM.init_jit
7
8
  @builder = LLVM::PassManagerBuilder.new
9
+
10
+ @pass_manager = LLVM::PassManager.new
8
11
  end
9
12
 
10
13
  def teardown
11
14
  @builder.dispose
15
+ @pass_manager.dispose
12
16
  end
13
17
 
14
18
  def test_init
@@ -26,8 +30,24 @@ class PassManagerBuilderTest < Minitest::Test
26
30
  end
27
31
 
28
32
  def test_build
29
- machine = LLVM::Target.by_name('x86-64').create_machine('x86-linux-gnu')
30
- pass_manager = LLVM::PassManager.new(machine)
31
- @builder.build(pass_manager)
33
+ @builder.build(@pass_manager)
34
+ end
35
+
36
+ def test_build_with_lto
37
+ assert_output('', '') do
38
+ @builder.build_with_lto(@pass_manager)
39
+ end
40
+ end
41
+
42
+ def test_build_with_lto_deprecated_internalize_param
43
+ assert_output("", "Warning: Passing Integer value to LLVM::PassManagerBuilder#build_with_lto is deprecated.\n") do
44
+ @builder.build_with_lto(@pass_manager, 0)
45
+ end
46
+ end
47
+
48
+ def test_build_with_lto_deprecated_run_inliner_param
49
+ assert_output("", "Warning: Passing Integer value to LLVM::PassManagerBuilder#build_with_lto is deprecated.\n") do
50
+ @builder.build_with_lto(@pass_manager, false, 0)
51
+ end
32
52
  end
33
53
  end
@@ -56,9 +56,6 @@ class TargetTestCase < Minitest::Test
56
56
  assert_equal 'x86-linux-gnu', mach.triple
57
57
  assert_equal 'i686', mach.cpu
58
58
  assert_equal '', mach.features
59
-
60
- layout = mach.data_layout
61
- assert_equal 'e-p:32:32:32-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f16:16:16-f32:32:32-f64:32:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32', layout.to_s
62
59
  end
63
60
 
64
61
  def test_emit
@@ -74,42 +71,28 @@ class TargetTestCase < Minitest::Test
74
71
 
75
72
  Tempfile.open('emit') do |tmp|
76
73
  mach.emit(mod, tmp.path)
77
- assert_match %r{xorl\t%eax, %eax}, tmp.read
74
+ assert_match(/xorl\t%eax, %eax/, tmp.read)
78
75
  end
79
76
 
80
77
  Tempfile.open('emit') do |tmp|
81
78
  mach.emit(mod, tmp.path, :object)
82
- assert_match %r{\x31\xc0\xc3}, File.read(tmp.path, mode: 'rb')
79
+ assert_match(/\x66\x31\xc0/, File.read(tmp.path, mode: 'rb'))
83
80
  end
84
81
  end
85
82
 
86
- def test_module_properties
87
- mod = LLVM::Module.new('mod')
88
-
89
- assert_equal '', mod.triple
90
-
91
- mod.triple = 'x86-linux-gnu'
92
- assert_equal 'x86-linux-gnu', mod.triple
93
-
94
- assert_equal '', mod.data_layout
95
-
96
- mod.data_layout = 'e-p:64:64:64'
97
- assert_equal 'e-p:64:64:64', mod.data_layout
98
- end
99
-
100
83
  def test_data_layout
101
84
  layout_be = LLVM::TargetDataLayout.new('E')
102
85
  assert_equal :big_endian, layout_be.byte_order
103
86
 
104
- desc = "e-p:64:64:64-S0-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64"
87
+ desc = "e-p:32:32:32-S0-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64"
105
88
  layout = LLVM::TargetDataLayout.new(desc)
106
89
 
107
90
  assert_equal desc, layout.to_s
108
91
  assert_equal :little_endian, layout.byte_order
109
- assert_equal 8, layout.pointer_size
110
- assert_equal 8, layout.pointer_size(0)
111
- assert_equal LLVM::Int64.type, layout.int_ptr_type
112
- assert_equal LLVM::Int64.type, layout.int_ptr_type(0)
92
+ assert_equal 4, layout.pointer_size
93
+ assert_equal 4, layout.pointer_size(0)
94
+ assert_equal LLVM::Int32.type, layout.int_ptr_type
95
+ assert_equal LLVM::Int32.type, layout.int_ptr_type(0)
113
96
 
114
97
  assert_equal 19, layout.bit_size_of(LLVM::Int19.type)
115
98
  assert_equal 3, layout.storage_size_of(LLVM::Int19.type)