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.
- checksums.yaml +5 -5
- data/README.md +19 -4
- data/ext/ruby-llvm-support/Rakefile +20 -8
- data/ext/ruby-llvm-support/support.cpp +0 -20
- data/lib/llvm.rb +0 -6
- data/lib/llvm/analysis_ffi.rb +30 -28
- data/lib/llvm/config.rb +4 -4
- data/lib/llvm/core.rb +45 -2
- data/lib/llvm/core/bitcode.rb +10 -10
- data/lib/llvm/core/bitcode_ffi.rb +92 -70
- data/lib/llvm/core/builder.rb +2 -3
- data/lib/llvm/core/context.rb +1 -1
- data/lib/llvm/core/pass_manager.rb +4 -2
- data/lib/llvm/core/type.rb +2 -2
- data/lib/llvm/core/value.rb +155 -28
- data/lib/llvm/core_ffi.rb +4038 -3716
- data/lib/llvm/execution_engine.rb +176 -8
- data/lib/llvm/execution_engine_ffi.rb +245 -272
- data/lib/llvm/linker.rb +2 -19
- data/lib/llvm/linker_ffi.rb +24 -25
- data/lib/llvm/support.rb +4 -12
- data/lib/llvm/target.rb +11 -17
- data/lib/llvm/target_ffi.rb +336 -362
- data/lib/llvm/transforms/builder.rb +8 -3
- data/lib/llvm/transforms/builder_ffi.rb +57 -58
- data/lib/llvm/transforms/ipo.rb +1 -1
- data/lib/llvm/transforms/ipo_ffi.rb +60 -61
- data/lib/llvm/transforms/scalar_ffi.rb +208 -136
- data/lib/llvm/transforms/vectorize_ffi.rb +15 -16
- data/lib/llvm/version.rb +3 -2
- data/test/basic_block_test.rb +0 -1
- data/test/bitcode_test.rb +1 -2
- data/test/call_test.rb +1 -1
- data/test/double_test.rb +8 -7
- data/test/equality_test.rb +2 -4
- data/test/function_test.rb +27 -0
- data/test/generic_value_test.rb +1 -1
- data/test/instruction_test.rb +0 -2
- data/test/ipo_test.rb +1 -1
- data/test/linker_test.rb +0 -9
- data/test/mcjit_test.rb +100 -0
- data/test/module_test.rb +31 -1
- data/test/pass_manager_builder_test.rb +23 -3
- data/test/target_test.rb +7 -24
- data/test/test_helper.rb +4 -1
- metadata +117 -94
@@ -4,36 +4,35 @@ require 'ffi'
|
|
4
4
|
|
5
5
|
module LLVM::C
|
6
6
|
extend FFI::Library
|
7
|
-
ffi_lib
|
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
|
-
#
|
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
|
data/lib/llvm/version.rb
CHANGED
data/test/basic_block_test.rb
CHANGED
data/test/bitcode_test.rb
CHANGED
@@ -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))
|
data/test/call_test.rb
CHANGED
@@ -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
|
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
|
data/test/double_test.rb
CHANGED
@@ -6,7 +6,7 @@ class DoubleTestCase < Minitest::Test
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def test_double
|
9
|
-
mod
|
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::
|
23
|
+
engine = LLVM::MCJITCompiler.new(mod)
|
24
24
|
|
25
|
-
arg
|
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
|
-
|
30
|
-
|
31
|
-
|
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
|
data/test/equality_test.rb
CHANGED
@@ -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
|
-
|
data/test/function_test.rb
CHANGED
@@ -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
|
data/test/generic_value_test.rb
CHANGED
data/test/instruction_test.rb
CHANGED
data/test/ipo_test.rb
CHANGED
data/test/linker_test.rb
CHANGED
@@ -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
|
data/test/mcjit_test.rb
ADDED
@@ -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
|
data/test/module_test.rb
CHANGED
@@ -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,
|
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
|
-
|
30
|
-
|
31
|
-
|
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
|
data/test/target_test.rb
CHANGED
@@ -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
|
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
|
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:
|
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
|
110
|
-
assert_equal
|
111
|
-
assert_equal LLVM::
|
112
|
-
assert_equal LLVM::
|
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)
|