ruby-llvm 3.4.0 → 11.0.1

Sign up to get free protection for your applications and to get access to all the features.
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)