ruby-llvm 3.5.0 → 13.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.
- checksums.yaml +5 -5
- data/README.md +21 -4
- data/ext/ruby-llvm-support/Rakefile +17 -6
- data/lib/llvm/analysis.rb +2 -0
- data/lib/llvm/analysis_ffi.rb +27 -28
- data/lib/llvm/config.rb +4 -4
- data/lib/llvm/core/bitcode.rb +12 -10
- data/lib/llvm/core/bitcode_ffi.rb +89 -65
- data/lib/llvm/core/builder.rb +4 -3
- data/lib/llvm/core/context.rb +3 -1
- data/lib/llvm/core/module.rb +2 -0
- data/lib/llvm/core/pass_manager.rb +6 -2
- data/lib/llvm/core/type.rb +9 -2
- data/lib/llvm/core/value.rb +154 -24
- data/lib/llvm/core.rb +47 -2
- data/lib/llvm/core_ffi.rb +3863 -3730
- data/lib/llvm/execution_engine.rb +39 -35
- data/lib/llvm/execution_engine_ffi.rb +238 -276
- data/lib/llvm/linker.rb +3 -14
- data/lib/llvm/linker_ffi.rb +22 -26
- data/lib/llvm/support.rb +2 -0
- data/lib/llvm/target.rb +11 -15
- data/lib/llvm/target_ffi.rb +301 -293
- data/lib/llvm/transforms/builder.rb +3 -1
- data/lib/llvm/transforms/builder_ffi.rb +57 -58
- data/lib/llvm/transforms/ipo.rb +3 -1
- data/lib/llvm/transforms/ipo_ffi.rb +59 -60
- data/lib/llvm/transforms/scalar.rb +12 -0
- data/lib/llvm/transforms/scalar_ffi.rb +199 -143
- data/lib/llvm/transforms/vectorize.rb +2 -0
- data/lib/llvm/transforms/vectorize_ffi.rb +15 -16
- data/lib/llvm/version.rb +5 -2
- data/lib/llvm.rb +2 -0
- data/test/array_test.rb +2 -0
- data/test/basic_block_test.rb +2 -1
- data/test/binary_operations_test.rb +2 -0
- data/test/bitcode_test.rb +3 -2
- data/test/branch_test.rb +2 -0
- data/test/call_test.rb +3 -1
- data/test/comparisons_test.rb +2 -0
- data/test/conversions_test.rb +2 -0
- data/test/double_test.rb +10 -7
- data/test/equality_test.rb +4 -4
- data/test/function_test.rb +29 -0
- data/test/generic_value_test.rb +3 -1
- data/test/instruction_test.rb +2 -2
- data/test/integer_test.rb +28 -0
- data/test/ipo_test.rb +3 -1
- data/test/linker_test.rb +2 -9
- data/test/mcjit_test.rb +11 -3
- data/test/memory_access_test.rb +2 -0
- data/test/module_test.rb +18 -1
- data/test/parameter_collection_test.rb +2 -0
- data/test/pass_manager_builder_test.rb +22 -2
- data/test/phi_test.rb +2 -0
- data/test/select_test.rb +2 -0
- data/test/struct_test.rb +2 -0
- data/test/target_test.rb +16 -20
- data/test/test_helper.rb +6 -1
- data/test/type_test.rb +47 -0
- data/test/vector_test.rb +2 -0
- metadata +105 -40
data/test/equality_test.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "test_helper"
|
2
4
|
require "llvm/core"
|
3
5
|
|
@@ -14,9 +16,9 @@ class EqualityTestCase < Minitest::Test
|
|
14
16
|
def assert_equalities(options)
|
15
17
|
map = {
|
16
18
|
:equal => method(:assert_equal),
|
17
|
-
:not_equal => lambda {|n, m, name| assert n != m, name
|
19
|
+
:not_equal => lambda {|n, m, name| assert n != m, name },
|
18
20
|
:same => method(:assert_same),
|
19
|
-
:not_same => lambda {|n, m, name| assert !n.equal?(m), name
|
21
|
+
:not_same => lambda {|n, m, name| assert !n.equal?(m), name },
|
20
22
|
:eql => lambda {|n, m, name| assert n.eql?(m), name },
|
21
23
|
:not_eql => lambda {|n, m, name| assert !n.eql?(m), name },
|
22
24
|
}
|
@@ -26,7 +28,6 @@ class EqualityTestCase < Minitest::Test
|
|
26
28
|
callable.call(n, m, name.to_s)
|
27
29
|
end
|
28
30
|
end
|
29
|
-
|
30
31
|
end
|
31
32
|
|
32
33
|
def test_int_value
|
@@ -88,4 +89,3 @@ class EqualityTestCase < Minitest::Test
|
|
88
89
|
end
|
89
90
|
|
90
91
|
end
|
91
|
-
|
data/test/function_test.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "test_helper"
|
2
4
|
require "llvm/core"
|
3
5
|
|
@@ -30,6 +32,33 @@ class FunctionTest < Minitest::Test
|
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
35
|
+
def helper_test_attribute(name)
|
36
|
+
with_function [], LLVM.Void do |fun|
|
37
|
+
assert_equal 0, fun.attribute_count
|
38
|
+
assert_equal [], fun.attributes
|
39
|
+
|
40
|
+
fun.add_attribute(name)
|
41
|
+
assert_equal 1, fun.attribute_count
|
42
|
+
assert_equal [34], fun.attributes
|
43
|
+
|
44
|
+
assert_equal false, fun.verify
|
45
|
+
|
46
|
+
fun.remove_attribute(name)
|
47
|
+
assert_equal 0, fun.attribute_count
|
48
|
+
assert_equal [], fun.attributes
|
49
|
+
|
50
|
+
assert_equal false, fun.verify
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_add_attribute_old_name
|
55
|
+
helper_test_attribute(:no_unwind_attribute)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_add_attribute_new_name
|
59
|
+
helper_test_attribute(:nounwind)
|
60
|
+
end
|
61
|
+
|
33
62
|
end
|
34
63
|
|
35
64
|
class FunctionTypeTest < Minitest::Test
|
data/test/generic_value_test.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "test_helper"
|
2
4
|
|
3
5
|
class GenericValueTestCase < Minitest::Test
|
@@ -8,7 +10,7 @@ class GenericValueTestCase < Minitest::Test
|
|
8
10
|
|
9
11
|
def test_from_i
|
10
12
|
assert_equal 2, LLVM::GenericValue.from_i(2).to_i
|
11
|
-
assert_equal 2
|
13
|
+
assert_equal 2, LLVM::GenericValue.from_i(2.2).to_i
|
12
14
|
end
|
13
15
|
|
14
16
|
def test_from_float
|
data/test/instruction_test.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class IntegerTestCase < Minitest::Test
|
6
|
+
|
7
|
+
def test_const_zext
|
8
|
+
assert i = LLVM::Int8.from_i(-1)
|
9
|
+
assert_equal 'i8 -1', i.to_s
|
10
|
+
assert_equal :integer, i.type.kind
|
11
|
+
assert_equal 8, i.type.width
|
12
|
+
assert zext = i.zext(LLVM::Int64)
|
13
|
+
assert_equal 'i64 255', zext.to_s
|
14
|
+
assert_equal :integer, zext.type.kind
|
15
|
+
assert_equal 64, zext.type.width
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_const_sext
|
19
|
+
assert i = LLVM::Int8.from_i(-1)
|
20
|
+
assert_equal 'i8 -1', i.to_s
|
21
|
+
assert_equal :integer, i.type.kind
|
22
|
+
assert_equal 8, i.type.width
|
23
|
+
assert sext = i.sext(LLVM::Int64)
|
24
|
+
assert_equal 'i64 -1', sext.to_s
|
25
|
+
assert_equal :integer, sext.type.kind
|
26
|
+
assert_equal 64, sext.type.width
|
27
|
+
end
|
28
|
+
end
|
data/test/ipo_test.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "test_helper"
|
2
4
|
require "llvm/core"
|
3
5
|
require 'llvm/transforms/ipo'
|
@@ -39,7 +41,7 @@ class IPOTestCase < Minitest::Test
|
|
39
41
|
assert fns.include?(main)
|
40
42
|
|
41
43
|
# optimize
|
42
|
-
engine = LLVM::
|
44
|
+
engine = LLVM::MCJITCompiler.new(mod)
|
43
45
|
passm = LLVM::PassManager.new(engine)
|
44
46
|
|
45
47
|
passm.gdce!
|
data/test/linker_test.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
require 'llvm/core'
|
3
5
|
require 'llvm/linker'
|
@@ -34,13 +36,4 @@ class LinkerTestCase < Minitest::Test
|
|
34
36
|
|
35
37
|
assert_equal 42, run_function_on_module(@mod1, 'main').to_i
|
36
38
|
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
39
|
end
|
data/test/mcjit_test.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class MCJITTestCase < Minitest::Test
|
@@ -35,6 +37,9 @@ class MCJITTestCase < Minitest::Test
|
|
35
37
|
|
36
38
|
engine = LLVM::MCJITCompiler.new(mod, :opt_level => 0)
|
37
39
|
|
40
|
+
# TODO: fix or replace find_function
|
41
|
+
skip
|
42
|
+
|
38
43
|
['foo', :foo].each do |name|
|
39
44
|
engine.functions[name].tap do |fun|
|
40
45
|
assert fun, "function named #{name.inspect}"
|
@@ -77,7 +82,10 @@ class MCJITTestCase < Minitest::Test
|
|
77
82
|
assert_equal engine.modules, ret, '#<< returns self'
|
78
83
|
end
|
79
84
|
|
80
|
-
|
85
|
+
# TODO: fix or replace find_function
|
86
|
+
skip
|
87
|
+
|
88
|
+
refute_nil engine.functions[:bar]
|
81
89
|
engine.modules.delete(mod2).tap do |ret|
|
82
90
|
assert_instance_of LLVM::Module, ret, '#delete returns module'
|
83
91
|
assert_equal mod2, ret
|
@@ -88,7 +96,7 @@ class MCJITTestCase < Minitest::Test
|
|
88
96
|
def test_accessors
|
89
97
|
main_mod = LLVM::Module.new('main')
|
90
98
|
engine = LLVM::MCJITCompiler.new(main_mod, :opt_level => 0)
|
91
|
-
assert_match
|
92
|
-
assert_match
|
99
|
+
assert_match(/^e-/, engine.data_layout.to_s)
|
100
|
+
assert_match(/gnu/, engine.target_machine.triple)
|
93
101
|
end
|
94
102
|
end
|
data/test/memory_access_test.rb
CHANGED
data/test/module_test.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "test_helper"
|
2
4
|
require "tempfile"
|
3
5
|
|
@@ -54,7 +56,8 @@ class ModuleTestCase < Minitest::Test
|
|
54
56
|
|
55
57
|
def test_to_s
|
56
58
|
mod = LLVM::Module.new('test_print')
|
57
|
-
assert_equal mod.to_s,
|
59
|
+
assert_equal mod.to_s,
|
60
|
+
"; ModuleID = 'test_print'\nsource_filename = \"test_print\"\n"
|
58
61
|
end
|
59
62
|
|
60
63
|
def test_dump
|
@@ -75,4 +78,18 @@ class ModuleTestCase < Minitest::Test
|
|
75
78
|
end
|
76
79
|
end
|
77
80
|
|
81
|
+
def test_module_properties
|
82
|
+
mod = LLVM::Module.new('mod')
|
83
|
+
|
84
|
+
assert_equal '', mod.triple
|
85
|
+
|
86
|
+
mod.triple = 'x86-linux-gnu'
|
87
|
+
assert_equal 'x86-linux-gnu', mod.triple
|
88
|
+
|
89
|
+
assert_equal '', mod.data_layout
|
90
|
+
|
91
|
+
mod.data_layout = 'e-p:32:32'
|
92
|
+
assert_equal 'e-p:32:32', mod.data_layout
|
93
|
+
end
|
94
|
+
|
78
95
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
require 'llvm/config'
|
3
5
|
require 'llvm/transforms/builder'
|
@@ -7,8 +9,7 @@ class PassManagerBuilderTest < Minitest::Test
|
|
7
9
|
LLVM.init_jit
|
8
10
|
@builder = LLVM::PassManagerBuilder.new
|
9
11
|
|
10
|
-
|
11
|
-
@pass_manager = LLVM::PassManager.new(machine)
|
12
|
+
@pass_manager = LLVM::PassManager.new
|
12
13
|
end
|
13
14
|
|
14
15
|
def teardown
|
@@ -51,4 +52,23 @@ class PassManagerBuilderTest < Minitest::Test
|
|
51
52
|
@builder.build_with_lto(@pass_manager, false, 0)
|
52
53
|
end
|
53
54
|
end
|
55
|
+
|
56
|
+
PASSES = [
|
57
|
+
'always_inline!',
|
58
|
+
'adce!',
|
59
|
+
'tailcallelim!',
|
60
|
+
'fun_attrs!',
|
61
|
+
'mergefunc!',
|
62
|
+
].freeze
|
63
|
+
|
64
|
+
describe "PassManager Passes" do
|
65
|
+
before do
|
66
|
+
assert @pass_manager = LLVM::PassManager.new
|
67
|
+
end
|
68
|
+
PASSES.each do |pass|
|
69
|
+
it "should return '#{pass}'" do
|
70
|
+
assert_nil @pass_manager.send(pass)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
54
74
|
end
|
data/test/phi_test.rb
CHANGED
data/test/select_test.rb
CHANGED
data/test/struct_test.rb
CHANGED
data/test/target_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require "test_helper"
|
4
5
|
require 'tempfile'
|
@@ -56,9 +57,6 @@ class TargetTestCase < Minitest::Test
|
|
56
57
|
assert_equal 'x86-linux-gnu', mach.triple
|
57
58
|
assert_equal 'i686', mach.cpu
|
58
59
|
assert_equal '', mach.features
|
59
|
-
|
60
|
-
layout = mach.data_layout
|
61
|
-
assert_equal 'e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128', layout.to_s
|
62
60
|
end
|
63
61
|
|
64
62
|
def test_emit
|
@@ -74,29 +72,27 @@ class TargetTestCase < Minitest::Test
|
|
74
72
|
|
75
73
|
Tempfile.open('emit') do |tmp|
|
76
74
|
mach.emit(mod, tmp.path)
|
77
|
-
|
75
|
+
data = tmp.read
|
76
|
+
assert_match(/xorl\t%eax, %eax/, data)
|
77
|
+
assert_equal 218, data.length
|
78
78
|
end
|
79
79
|
|
80
|
+
# despite the above test, in LLVM <= 11 the objdump output was:
|
81
|
+
# 00000000 <main>:
|
82
|
+
# 0: 66 31 c0 xor %ax,%ax
|
83
|
+
# 3: 66 c3 retw
|
84
|
+
# In LLVM 13, the objdump output is:
|
85
|
+
# 00000000 <main>:
|
86
|
+
# 0: 31 c0 xor %eax,%eax
|
87
|
+
# 2: c3 ret
|
80
88
|
Tempfile.open('emit') do |tmp|
|
81
89
|
mach.emit(mod, tmp.path, :object)
|
82
|
-
|
90
|
+
data = File.read(tmp.path, mode: 'rb')
|
91
|
+
assert_match(/\x31\xc0\xc3/, data)
|
92
|
+
assert_equal 528, data.length
|
83
93
|
end
|
84
94
|
end
|
85
95
|
|
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:32:32'
|
97
|
-
assert_equal 'e-p:32:32', mod.data_layout
|
98
|
-
end
|
99
|
-
|
100
96
|
def test_data_layout
|
101
97
|
layout_be = LLVM::TargetDataLayout.new('E')
|
102
98
|
assert_equal :big_endian, layout_be.byte_order
|
@@ -104,7 +100,7 @@ class TargetTestCase < Minitest::Test
|
|
104
100
|
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
101
|
layout = LLVM::TargetDataLayout.new(desc)
|
106
102
|
|
107
|
-
assert_equal
|
103
|
+
assert_equal desc, layout.to_s
|
108
104
|
assert_equal :little_endian, layout.byte_order
|
109
105
|
assert_equal 4, layout.pointer_size
|
110
106
|
assert_equal 4, layout.pointer_size(0)
|
data/test/test_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
2
4
|
|
3
5
|
begin
|
@@ -17,6 +19,9 @@ rescue LoadError
|
|
17
19
|
end
|
18
20
|
|
19
21
|
require "minitest/autorun"
|
22
|
+
require 'minitest/reporters'
|
23
|
+
|
24
|
+
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
20
25
|
|
21
26
|
require "llvm/core"
|
22
27
|
require "llvm/execution_engine"
|
@@ -46,7 +51,7 @@ def define_function(host_module, function_name, argument_types, return_type)
|
|
46
51
|
end
|
47
52
|
|
48
53
|
def run_function_on_module(host_module, function_name, *argument_values)
|
49
|
-
LLVM::
|
54
|
+
LLVM::MCJITCompiler.new(host_module).
|
50
55
|
run_function(host_module.functions[function_name], *argument_values)
|
51
56
|
end
|
52
57
|
|
data/test/type_test.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "test_helper"
|
2
4
|
|
3
5
|
class TypeTestCase < Minitest::Test
|
4
6
|
|
7
|
+
extend MiniTest::Spec::DSL
|
8
|
+
|
5
9
|
def test_element_type
|
6
10
|
pointer = LLVM.Pointer(LLVM::Int32.type)
|
7
11
|
pointee = pointer.element_type
|
@@ -12,4 +16,47 @@ class TypeTestCase < Minitest::Test
|
|
12
16
|
assert_nil pointee.element_type
|
13
17
|
end
|
14
18
|
|
19
|
+
TO_S_TESTS = [
|
20
|
+
[LLVM.Struct(LLVM::Int32, LLVM::Int32), '{ i32, i32 }'],
|
21
|
+
[LLVM.Struct(LLVM::Int32, LLVM::Int32, "s1"), '%s1 = type { i32, i32 }'],
|
22
|
+
[LLVM::Type.struct([LLVM::Int32, LLVM::Int32], true), '<{ i32, i32 }>'],
|
23
|
+
[LLVM::Type.struct([LLVM::Int32, LLVM::Int32], true, "s2"), '%s2 = type <{ i32, i32 }>'],
|
24
|
+
|
25
|
+
[LLVM.Array(LLVM::Int8), '[0 x i8]'],
|
26
|
+
[LLVM.Array(LLVM::Int8, 42), '[42 x i8]'],
|
27
|
+
[LLVM::Type.array(LLVM::Int1), '[0 x i1]'],
|
28
|
+
[LLVM::Type.array(LLVM::Int1, 42), '[42 x i1]'],
|
29
|
+
|
30
|
+
[LLVM.Vector(LLVM::Int8, 42), '<42 x i8>'],
|
31
|
+
[LLVM::Type.vector(LLVM::Int1, 42), '<42 x i1>'],
|
32
|
+
|
33
|
+
[LLVM.Void, 'void'],
|
34
|
+
[LLVM::Type.void, 'void'],
|
35
|
+
|
36
|
+
[LLVM.Pointer(LLVM::Int8), 'i8*'],
|
37
|
+
[LLVM::Type.pointer(LLVM::Int1), 'i1*'],
|
38
|
+
|
39
|
+
[LLVM.Function([LLVM::Int8], LLVM.Void), 'void (i8)'],
|
40
|
+
[LLVM.Function([LLVM::Int8], LLVM::Int8), 'i8 (i8)'],
|
41
|
+
[LLVM.Function([], LLVM::Int8), 'i8 ()'],
|
42
|
+
[LLVM.Function([], LLVM.Void), 'void ()'],
|
43
|
+
[LLVM::Type.function([LLVM::Int1], LLVM.Void), 'void (i1)'],
|
44
|
+
[LLVM::Type.function([LLVM::Int1], LLVM::Int1), 'i1 (i1)'],
|
45
|
+
[LLVM::Type.function([], LLVM::Int1), 'i1 ()'],
|
46
|
+
[LLVM::Type.function([], LLVM.Void), 'void ()'],
|
47
|
+
].freeze
|
48
|
+
|
49
|
+
describe "LLVM::Type#to_s" do
|
50
|
+
TO_S_TESTS.each do |(type, string)|
|
51
|
+
it "should return '#{string}'" do
|
52
|
+
assert type.is_a?(LLVM::Type)
|
53
|
+
assert_equal string, type.to_s
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should have 22 dynamic tests' do
|
58
|
+
assert_equal 22, TO_S_TESTS.size
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
15
62
|
end
|