ruby-llvm 13.0.1 → 13.0.2
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 +4 -4
- data/lib/llvm/core/builder.rb +87 -9
- data/lib/llvm/core/type.rb +4 -0
- data/lib/llvm/version.rb +1 -1
- metadata +13 -68
- data/test/array_test.rb +0 -40
- data/test/basic_block_test.rb +0 -89
- data/test/binary_operations_test.rb +0 -60
- data/test/bitcode_test.rb +0 -26
- data/test/branch_test.rb +0 -59
- data/test/call_test.rb +0 -84
- data/test/comparisons_test.rb +0 -68
- data/test/conversions_test.rb +0 -94
- data/test/double_test.rb +0 -36
- data/test/equality_test.rb +0 -91
- data/test/function_test.rb +0 -102
- data/test/generic_value_test.rb +0 -24
- data/test/instruction_test.rb +0 -32
- data/test/integer_test.rb +0 -28
- data/test/ipo_test.rb +0 -55
- data/test/linker_test.rb +0 -39
- data/test/mcjit_test.rb +0 -102
- data/test/memory_access_test.rb +0 -40
- data/test/module_test.rb +0 -95
- data/test/parameter_collection_test.rb +0 -30
- data/test/pass_manager_builder_test.rb +0 -74
- data/test/phi_test.rb +0 -35
- data/test/select_test.rb +0 -24
- data/test/struct_test.rb +0 -100
- data/test/target_test.rb +0 -126
- data/test/test_helper.rb +0 -64
- data/test/type_test.rb +0 -62
- data/test/vector_test.rb +0 -66
data/test/mcjit_test.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
|
5
|
-
class MCJITTestCase < Minitest::Test
|
6
|
-
def setup
|
7
|
-
LLVM.init_jit(true)
|
8
|
-
end
|
9
|
-
|
10
|
-
def create_square_function_module
|
11
|
-
LLVM::Module.new('square').tap do |mod|
|
12
|
-
mod.functions.add(:square, [LLVM::Int], LLVM::Int) do |fun, x|
|
13
|
-
fun.basic_blocks.append.build do |builder|
|
14
|
-
n = builder.mul(x, x)
|
15
|
-
builder.ret(n)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
mod.verify!
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_simple_function
|
24
|
-
mod = create_square_function_module
|
25
|
-
|
26
|
-
engine = LLVM::MCJITCompiler.new(mod, :opt_level => 0)
|
27
|
-
|
28
|
-
result = engine.run_function(mod.functions['square'], 5)
|
29
|
-
assert_equal 25, result.to_i
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_functions_named
|
33
|
-
mod = LLVM::Module.new('foo').tap do |mod|
|
34
|
-
mod.functions.add(:foo, [], LLVM::Int)
|
35
|
-
mod.verify!
|
36
|
-
end
|
37
|
-
|
38
|
-
engine = LLVM::MCJITCompiler.new(mod, :opt_level => 0)
|
39
|
-
|
40
|
-
# TODO: fix or replace find_function
|
41
|
-
skip
|
42
|
-
|
43
|
-
['foo', :foo].each do |name|
|
44
|
-
engine.functions[name].tap do |fun|
|
45
|
-
assert fun, "function named #{name.inspect}"
|
46
|
-
assert_equal 'foo', fun.name
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_add_module
|
52
|
-
main_mod = LLVM::Module.new('main')
|
53
|
-
|
54
|
-
main_mod.functions.add(:square, [LLVM::Int], LLVM::Int) do |square|
|
55
|
-
main_mod.functions.add(:call_square, [], LLVM::Int) do |call_square|
|
56
|
-
call_square.basic_blocks.append.build do |builder|
|
57
|
-
n = builder.call(square, LLVM::Int(5))
|
58
|
-
builder.ret(n)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
main_mod.verify!
|
64
|
-
|
65
|
-
engine = LLVM::MCJITCompiler.new(main_mod, :opt_level => 0)
|
66
|
-
engine.modules << create_square_function_module
|
67
|
-
|
68
|
-
result = engine.run_function(main_mod.functions['call_square'])
|
69
|
-
assert_equal 25, result.to_i
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_remove_module
|
73
|
-
mod1 = LLVM::Module.new('foo')
|
74
|
-
mod2 = LLVM::Module.new('bar')
|
75
|
-
|
76
|
-
foo = mod1.functions.add(:foo, [], LLVM::Int)
|
77
|
-
bar = mod2.functions.add(:bar, [], LLVM::Int)
|
78
|
-
|
79
|
-
engine = LLVM::MCJITCompiler.new(mod1, :opt_level => 0)
|
80
|
-
|
81
|
-
(engine.modules << mod2).tap do |ret|
|
82
|
-
assert_equal engine.modules, ret, '#<< returns self'
|
83
|
-
end
|
84
|
-
|
85
|
-
# TODO: fix or replace find_function
|
86
|
-
skip
|
87
|
-
|
88
|
-
refute_nil engine.functions[:bar]
|
89
|
-
engine.modules.delete(mod2).tap do |ret|
|
90
|
-
assert_instance_of LLVM::Module, ret, '#delete returns module'
|
91
|
-
assert_equal mod2, ret
|
92
|
-
end
|
93
|
-
assert_nil engine.functions[:bar]
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_accessors
|
97
|
-
main_mod = LLVM::Module.new('main')
|
98
|
-
engine = LLVM::MCJITCompiler.new(main_mod, :opt_level => 0)
|
99
|
-
assert_match(/^e-/, engine.data_layout.to_s)
|
100
|
-
assert_match(/gnu/, engine.target_machine.triple)
|
101
|
-
end
|
102
|
-
end
|
data/test/memory_access_test.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "test_helper"
|
4
|
-
|
5
|
-
class MemoryAccessTestCase < Minitest::Test
|
6
|
-
|
7
|
-
def setup
|
8
|
-
LLVM.init_jit
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_memory_access
|
12
|
-
assert_equal 1 + 2, simple_memory_access_function(1, 2).to_i
|
13
|
-
assert_equal 3 + 4, array_memory_access_function(3, 4).to_i
|
14
|
-
end
|
15
|
-
|
16
|
-
def simple_memory_access_function(value1, value2)
|
17
|
-
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
18
|
-
entry = function.basic_blocks.append
|
19
|
-
builder.position_at_end(entry)
|
20
|
-
pointer1 = builder.alloca(LLVM::Int)
|
21
|
-
pointer2 = builder.alloca(LLVM::Int)
|
22
|
-
builder.store(arguments.first, pointer1)
|
23
|
-
builder.store(arguments.last, pointer2)
|
24
|
-
builder.ret(builder.add(builder.load(pointer1), builder.load(pointer2)))
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def array_memory_access_function(value1, value2)
|
29
|
-
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
30
|
-
entry = function.basic_blocks.append
|
31
|
-
builder.position_at_end(entry)
|
32
|
-
pointer = builder.array_alloca(LLVM::Int, LLVM::Int(2))
|
33
|
-
builder.store(arguments.first, builder.gep(pointer, [LLVM::Int(0)]))
|
34
|
-
builder.store(arguments.last, builder.gep(pointer, [LLVM::Int(1)]))
|
35
|
-
builder.ret(builder.add(builder.load(builder.gep(pointer, [LLVM::Int(0)])),
|
36
|
-
builder.load(builder.gep(pointer, [LLVM::Int(1)]))))
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
data/test/module_test.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "test_helper"
|
4
|
-
require "tempfile"
|
5
|
-
|
6
|
-
class ModuleTestCase < Minitest::Test
|
7
|
-
|
8
|
-
def setup
|
9
|
-
LLVM.init_jit
|
10
|
-
end
|
11
|
-
|
12
|
-
def simple_function
|
13
|
-
run_function([], [], LLVM::Int) do |builder, function, *arguments|
|
14
|
-
entry = function.basic_blocks.append
|
15
|
-
builder.position_at_end(entry)
|
16
|
-
builder.ret(LLVM::Int(1))
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_simple_module
|
21
|
-
assert_equal 1, simple_function().to_i
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_global_variable
|
25
|
-
yielded = false
|
26
|
-
|
27
|
-
define_module('test_globals_add') do |mod|
|
28
|
-
mod.globals.add(LLVM::Int32, 'i') do |var|
|
29
|
-
yielded = true
|
30
|
-
|
31
|
-
assert var.kind_of?(LLVM::GlobalVariable)
|
32
|
-
|
33
|
-
# unnamed_addr
|
34
|
-
assert !var.unnamed_addr?
|
35
|
-
var.unnamed_addr = true
|
36
|
-
assert var.unnamed_addr?
|
37
|
-
|
38
|
-
assert (var.dll_storage_class == :default)
|
39
|
-
var.dll_storage_class = :dll_import
|
40
|
-
assert (var.dll_storage_class == :dll_import)
|
41
|
-
|
42
|
-
# global_constant
|
43
|
-
assert !var.global_constant?
|
44
|
-
var.global_constant = true
|
45
|
-
assert var.global_constant?
|
46
|
-
|
47
|
-
assert_output("", "Warning: Passing Integer value to LLVM::GlobalValue#global_constant=(Boolean) is deprecated.\n") do
|
48
|
-
var.global_constant = 0
|
49
|
-
end
|
50
|
-
assert !var.global_constant?
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
assert yielded, 'LLVM::Module::GlobalCollection#add takes block'
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_to_s
|
58
|
-
mod = LLVM::Module.new('test_print')
|
59
|
-
assert_equal mod.to_s,
|
60
|
-
"; ModuleID = 'test_print'\nsource_filename = \"test_print\"\n"
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_dump
|
64
|
-
mod = LLVM::Module.new('test_print')
|
65
|
-
expected_pattern = /^; ModuleID = 'test_print'$/
|
66
|
-
|
67
|
-
Tempfile.open('test_dump.1') do |tmpfile|
|
68
|
-
# debug stream (stderr)
|
69
|
-
stderr_old = $stderr.dup
|
70
|
-
$stderr.reopen(tmpfile.path, 'a')
|
71
|
-
begin
|
72
|
-
mod.dump
|
73
|
-
$stderr.flush
|
74
|
-
assert_match expected_pattern, File.read(tmpfile.path)
|
75
|
-
ensure
|
76
|
-
$stderr.reopen(stderr_old)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
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
|
-
|
95
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "test_helper"
|
4
|
-
|
5
|
-
class ParameterCollectionTestCase < Minitest::Test
|
6
|
-
def setup
|
7
|
-
@mod = LLVM::Module.new('test')
|
8
|
-
@fun = @mod.functions.add('fun', [LLVM::Int, LLVM::Int], LLVM::Int)
|
9
|
-
@fun.params[0].name = 'foo'
|
10
|
-
@fun.params[1].name = 'bar'
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_positive_index_in_range
|
14
|
-
assert_equal 'foo', @fun.params[0].name
|
15
|
-
assert_equal 'bar', @fun.params[1].name
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_negative_index_in_range
|
19
|
-
assert_equal 'foo', @fun.params[-2].name
|
20
|
-
assert_equal 'bar', @fun.params[-1].name
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_positive_index_out_of_range
|
24
|
-
assert_nil @fun.params[2]
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_negative_index_out_of_range
|
28
|
-
assert_nil @fun.params[-3]
|
29
|
-
end
|
30
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
require 'llvm/config'
|
5
|
-
require 'llvm/transforms/builder'
|
6
|
-
|
7
|
-
class PassManagerBuilderTest < Minitest::Test
|
8
|
-
def setup
|
9
|
-
LLVM.init_jit
|
10
|
-
@builder = LLVM::PassManagerBuilder.new
|
11
|
-
|
12
|
-
@pass_manager = LLVM::PassManager.new
|
13
|
-
end
|
14
|
-
|
15
|
-
def teardown
|
16
|
-
@builder.dispose
|
17
|
-
@pass_manager.dispose
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_init
|
21
|
-
assert_equal 0, @builder.size_level
|
22
|
-
assert_equal 0, @builder.opt_level
|
23
|
-
assert_equal false, @builder.unit_at_a_time
|
24
|
-
assert_equal false, @builder.unroll_loops
|
25
|
-
assert_equal false, @builder.simplify_lib_calls
|
26
|
-
assert_equal 0, @builder.inliner_threshold
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_opt_level
|
30
|
-
@builder.opt_level = 3
|
31
|
-
assert_equal 3, @builder.opt_level
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_build
|
35
|
-
@builder.build(@pass_manager)
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_build_with_lto
|
39
|
-
assert_output('', '') do
|
40
|
-
@builder.build_with_lto(@pass_manager)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_build_with_lto_deprecated_internalize_param
|
45
|
-
assert_output("", "Warning: Passing Integer value to LLVM::PassManagerBuilder#build_with_lto is deprecated.\n") do
|
46
|
-
@builder.build_with_lto(@pass_manager, 0)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_build_with_lto_deprecated_run_inliner_param
|
51
|
-
assert_output("", "Warning: Passing Integer value to LLVM::PassManagerBuilder#build_with_lto is deprecated.\n") do
|
52
|
-
@builder.build_with_lto(@pass_manager, false, 0)
|
53
|
-
end
|
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
|
74
|
-
end
|
data/test/phi_test.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "test_helper"
|
4
|
-
|
5
|
-
class PhiTest < Minitest::Test
|
6
|
-
def setup
|
7
|
-
LLVM.init_jit
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_phi
|
11
|
-
assert_equal 1, run_phi_function(0).to_i
|
12
|
-
assert_equal 0, run_phi_function(1).to_i
|
13
|
-
end
|
14
|
-
|
15
|
-
def run_phi_function(argument)
|
16
|
-
run_function([LLVM::Int], argument, LLVM::Int) do |builder, function, *arguments|
|
17
|
-
entry = function.basic_blocks.append
|
18
|
-
block1 = function.basic_blocks.append
|
19
|
-
block2 = function.basic_blocks.append
|
20
|
-
exit = function.basic_blocks.append
|
21
|
-
builder.position_at_end(entry)
|
22
|
-
builder.cond(builder.icmp(:eq, arguments.first, LLVM::Int(0)), block1, block2)
|
23
|
-
builder.position_at_end(block1)
|
24
|
-
result1 = builder.add(arguments.first, LLVM::Int(1))
|
25
|
-
builder.br(exit)
|
26
|
-
builder.position_at_end(block2)
|
27
|
-
result2 = builder.sub(arguments.first, LLVM::Int(1))
|
28
|
-
builder.br(exit)
|
29
|
-
builder.position_at_end(exit)
|
30
|
-
builder.ret(builder.phi(LLVM::Int,
|
31
|
-
block1 => result1,
|
32
|
-
block2 => result2))
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/test/select_test.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "test_helper"
|
4
|
-
|
5
|
-
class SelectTestCase < Minitest::Test
|
6
|
-
|
7
|
-
def setup
|
8
|
-
LLVM.init_jit
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_select
|
12
|
-
assert_equal 0, select_function(1).to_i
|
13
|
-
assert_equal 1, select_function(0).to_i
|
14
|
-
end
|
15
|
-
|
16
|
-
def select_function(value)
|
17
|
-
run_function([LLVM::Int1], [value], LLVM::Int) do |builder, function, *arguments|
|
18
|
-
entry = function.basic_blocks.append
|
19
|
-
builder.position_at_end(entry)
|
20
|
-
builder.ret(builder.select(arguments.first, LLVM::Int(0), LLVM::Int(1)))
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
data/test/struct_test.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "test_helper"
|
4
|
-
|
5
|
-
class StructTestCase < Minitest::Test
|
6
|
-
|
7
|
-
LLVM_UNPACKED = false
|
8
|
-
LLVM_PACKED = true
|
9
|
-
|
10
|
-
def setup
|
11
|
-
LLVM.init_jit
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_simple_struct
|
15
|
-
struct = LLVM::Struct(LLVM::Int, LLVM::Float)
|
16
|
-
assert_instance_of LLVM::StructType, struct
|
17
|
-
assert_equal 2, struct.element_types.size
|
18
|
-
assert_equal LLVM::Int.type, struct.element_types[0]
|
19
|
-
assert_equal LLVM::Float.type, struct.element_types[1]
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_named_struct
|
23
|
-
struct = LLVM::Struct(LLVM::Int, LLVM::Float, "struct100")
|
24
|
-
assert_instance_of LLVM::StructType, struct
|
25
|
-
assert_equal "struct100", struct.name
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_deferred_element_type_setting
|
29
|
-
struct = LLVM::Struct("struct200")
|
30
|
-
struct.element_types = [LLVM::Int, LLVM::Float]
|
31
|
-
assert_equal 2, struct.element_types.size
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_unpacked_constant_struct_from_size
|
35
|
-
struct = LLVM::ConstantStruct.const(2, LLVM_UNPACKED) { |i| LLVM::Int(i) }
|
36
|
-
assert_instance_of LLVM::ConstantStruct, struct
|
37
|
-
assert_equal 2, struct.operands.size
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_unpacked_constant_struct_from_struct
|
41
|
-
struct = LLVM::ConstantStruct.const([LLVM::Int(0), LLVM::Int(1)], LLVM_UNPACKED)
|
42
|
-
assert_instance_of LLVM::ConstantStruct, struct
|
43
|
-
assert_equal 2, struct.operands.size
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_packed_constant_struct_from_size
|
47
|
-
struct = LLVM::ConstantStruct.const(2, LLVM_PACKED) { |i| LLVM::Int(i) }
|
48
|
-
assert_instance_of LLVM::ConstantStruct, struct
|
49
|
-
assert_equal 2, struct.operands.size
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_packed_constant_struct_from_struct
|
53
|
-
struct = LLVM::ConstantStruct.const([LLVM::Int(0), LLVM::Int(1)], LLVM_PACKED)
|
54
|
-
assert_instance_of LLVM::ConstantStruct, struct
|
55
|
-
assert_equal 2, struct.operands.size
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_constant_named_struct
|
59
|
-
struct_ty = LLVM::Struct(LLVM::Int, "struct300")
|
60
|
-
struct = LLVM::ConstantStruct.named_const(struct_ty, [ LLVM::Int(1) ])
|
61
|
-
assert_instance_of LLVM::ConstantStruct, struct
|
62
|
-
assert_equal 1, struct.operands.size
|
63
|
-
assert_equal struct_ty, struct.type
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_struct_values
|
67
|
-
assert_equal 2 + 3, run_struct_values(2, 3).to_i
|
68
|
-
end
|
69
|
-
|
70
|
-
def test_struct_access
|
71
|
-
assert_in_delta 2 + 3.3, run_struct_access(LLVM::Float, 2, 3.3).to_f, 0.001
|
72
|
-
end
|
73
|
-
|
74
|
-
def run_struct_values(value1, value2)
|
75
|
-
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
76
|
-
entry = function.basic_blocks.append
|
77
|
-
builder.position_at_end(entry)
|
78
|
-
pointer = builder.alloca(LLVM::Struct(LLVM::Int, LLVM::Int))
|
79
|
-
struct = builder.load(pointer)
|
80
|
-
struct = builder.insert_value(struct, arguments.first, 0)
|
81
|
-
struct = builder.insert_value(struct, arguments.last, 1)
|
82
|
-
builder.ret(builder.add(builder.extract_value(struct, 0),
|
83
|
-
builder.extract_value(struct, 1)))
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def run_struct_access(return_type, value1, value2)
|
88
|
-
run_function([LLVM::Int, LLVM::Float], [value1, value2], return_type) do |builder, function, *arguments|
|
89
|
-
entry = function.basic_blocks.append
|
90
|
-
builder.position_at_end(entry)
|
91
|
-
pointer = builder.alloca(LLVM::Struct(LLVM::Float, LLVM::Struct(LLVM::Int, LLVM::Float), LLVM::Int))
|
92
|
-
builder.store(arguments.first, builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(0)]))
|
93
|
-
builder.store(arguments.last, builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(1)]))
|
94
|
-
address1 = builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(0)])
|
95
|
-
address2 = builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(1)])
|
96
|
-
builder.ret(builder.fadd(builder.ui2fp(builder.load(address1), LLVM::Float), builder.load(address2)))
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
data/test/target_test.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "test_helper"
|
5
|
-
require 'tempfile'
|
6
|
-
require 'llvm/version'
|
7
|
-
require 'llvm/config'
|
8
|
-
|
9
|
-
class TargetTestCase < Minitest::Test
|
10
|
-
|
11
|
-
def setup
|
12
|
-
LLVM::Target.init('X86', true)
|
13
|
-
|
14
|
-
@x86 = LLVM::Target.by_name('x86')
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_init_native
|
18
|
-
LLVM::Target.init_native
|
19
|
-
LLVM::Target.init_native(true)
|
20
|
-
end
|
21
|
-
|
22
|
-
if LLVM::CONFIG::TARGETS_BUILT.include?('ARM')
|
23
|
-
def test_init_arm
|
24
|
-
LLVM::Target.init('ARM')
|
25
|
-
LLVM::Target.init('ARM', true)
|
26
|
-
|
27
|
-
arm_target = LLVM::Target.by_name('arm')
|
28
|
-
assert_equal 'arm', arm_target.name
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_init_all
|
33
|
-
LLVM::Target.init_all
|
34
|
-
LLVM::Target.init_all(true)
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_each
|
38
|
-
targets = LLVM::Target.each
|
39
|
-
|
40
|
-
assert_instance_of Enumerator, targets
|
41
|
-
assert targets.count > 0
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_target
|
45
|
-
assert_equal 'x86', @x86.name
|
46
|
-
assert_equal "32-bit X86: Pentium-Pro and above", @x86.description
|
47
|
-
assert_equal true, @x86.jit?
|
48
|
-
assert_equal true, @x86.target_machine?
|
49
|
-
assert_equal true, @x86.asm_backend?
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_target_machine
|
53
|
-
@x86 = LLVM::Target.by_name('x86')
|
54
|
-
mach = @x86.create_machine('x86-linux-gnu', 'i686')
|
55
|
-
|
56
|
-
assert_equal @x86, mach.target
|
57
|
-
assert_equal 'x86-linux-gnu', mach.triple
|
58
|
-
assert_equal 'i686', mach.cpu
|
59
|
-
assert_equal '', mach.features
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_emit
|
63
|
-
mach = @x86.create_machine('x86-linux-gnu')
|
64
|
-
|
65
|
-
mod = define_module('test') do |mod|
|
66
|
-
define_function(mod, 'main', [], LLVM::Int) do |builder, fun|
|
67
|
-
entry = fun.basic_blocks.append
|
68
|
-
builder.position_at_end(entry)
|
69
|
-
builder.ret(LLVM::Int(0))
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
Tempfile.open('emit') do |tmp|
|
74
|
-
mach.emit(mod, tmp.path)
|
75
|
-
data = tmp.read
|
76
|
-
assert_match(/xorl\t%eax, %eax/, data)
|
77
|
-
assert_equal 218, data.length
|
78
|
-
end
|
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
|
88
|
-
Tempfile.open('emit') do |tmp|
|
89
|
-
mach.emit(mod, tmp.path, :object)
|
90
|
-
data = File.read(tmp.path, mode: 'rb')
|
91
|
-
assert_match(/\x31\xc0\xc3/, data)
|
92
|
-
assert_equal 528, data.length
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_data_layout
|
97
|
-
layout_be = LLVM::TargetDataLayout.new('E')
|
98
|
-
assert_equal :big_endian, layout_be.byte_order
|
99
|
-
|
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"
|
101
|
-
layout = LLVM::TargetDataLayout.new(desc)
|
102
|
-
|
103
|
-
assert_equal desc, layout.to_s
|
104
|
-
assert_equal :little_endian, layout.byte_order
|
105
|
-
assert_equal 4, layout.pointer_size
|
106
|
-
assert_equal 4, layout.pointer_size(0)
|
107
|
-
assert_equal LLVM::Int32.type, layout.int_ptr_type
|
108
|
-
assert_equal LLVM::Int32.type, layout.int_ptr_type(0)
|
109
|
-
|
110
|
-
assert_equal 19, layout.bit_size_of(LLVM::Int19.type)
|
111
|
-
assert_equal 3, layout.storage_size_of(LLVM::Int19.type)
|
112
|
-
assert_equal 4, layout.abi_size_of(LLVM::Int19.type)
|
113
|
-
assert_equal 4, layout.abi_alignment_of(LLVM::Int19.type)
|
114
|
-
assert_equal 4, layout.call_frame_alignment_of(LLVM::Int19.type)
|
115
|
-
assert_equal 4, layout.preferred_alignment_of(LLVM::Int19.type)
|
116
|
-
|
117
|
-
struct = LLVM.Struct(LLVM::Int8, LLVM::Int32)
|
118
|
-
|
119
|
-
assert_equal 0, layout.offset_of_element(struct, 0)
|
120
|
-
assert_equal 4, layout.offset_of_element(struct, 1)
|
121
|
-
|
122
|
-
assert_equal 0, layout.element_at_offset(struct, 0)
|
123
|
-
assert_equal 0, layout.element_at_offset(struct, 3)
|
124
|
-
assert_equal 1, layout.element_at_offset(struct, 4)
|
125
|
-
end
|
126
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
4
|
-
|
5
|
-
begin
|
6
|
-
require "ruby-debug"
|
7
|
-
rescue LoadError
|
8
|
-
# Ignore ruby-debug is case it's not installed
|
9
|
-
end
|
10
|
-
|
11
|
-
begin
|
12
|
-
require 'simplecov'
|
13
|
-
|
14
|
-
SimpleCov.start do
|
15
|
-
add_filter "/test/"
|
16
|
-
end
|
17
|
-
rescue LoadError
|
18
|
-
warn "Proceeding without SimpleCov. gem install simplecov on supported platforms."
|
19
|
-
end
|
20
|
-
|
21
|
-
require "minitest/autorun"
|
22
|
-
require 'minitest/reporters'
|
23
|
-
|
24
|
-
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
25
|
-
|
26
|
-
require "llvm/core"
|
27
|
-
require "llvm/execution_engine"
|
28
|
-
require "llvm/transforms/scalar"
|
29
|
-
|
30
|
-
class Minitest::Test
|
31
|
-
|
32
|
-
LLVM_SIGNED = true
|
33
|
-
LLVM_UNSIGNED = false
|
34
|
-
|
35
|
-
LLVM_FALSE = 0
|
36
|
-
LLVM_TRUE = 1
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
def define_module(module_name)
|
41
|
-
new_module = LLVM::Module.new(module_name)
|
42
|
-
yield new_module
|
43
|
-
new_module.verify
|
44
|
-
new_module
|
45
|
-
end
|
46
|
-
|
47
|
-
def define_function(host_module, function_name, argument_types, return_type)
|
48
|
-
host_module.functions.add(function_name, argument_types, return_type) do |function, *arguments|
|
49
|
-
yield(LLVM::Builder.new, function, *arguments)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def run_function_on_module(host_module, function_name, *argument_values)
|
54
|
-
LLVM::MCJITCompiler.new(host_module).
|
55
|
-
run_function(host_module.functions[function_name], *argument_values)
|
56
|
-
end
|
57
|
-
|
58
|
-
def run_function(argument_types, argument_values, return_type, &block)
|
59
|
-
test_module = define_module("test_module") do |host_module|
|
60
|
-
define_function(host_module, "test_function", argument_types, return_type, &block)
|
61
|
-
end
|
62
|
-
|
63
|
-
run_function_on_module(test_module, "test_function", *argument_values)
|
64
|
-
end
|