ruby-llvm 3.1.0.beta.1 → 3.2.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +30 -0
- data/README.md +49 -0
- data/ext/ruby-llvm-support/Rakefile +30 -7
- data/ext/ruby-llvm-support/support.cpp +48 -1
- data/lib/llvm.rb +26 -3
- data/lib/llvm/analysis.rb +8 -11
- data/lib/llvm/analysis_ffi.rb +1 -1
- data/lib/llvm/core.rb +36 -1
- data/lib/llvm/core/bitcode_ffi.rb +1 -1
- data/lib/llvm/core/builder.rb +20 -14
- data/lib/llvm/core/module.rb +87 -63
- data/lib/llvm/core/pass_manager.rb +30 -30
- data/lib/llvm/core/type.rb +34 -51
- data/lib/llvm/core/value.rb +13 -25
- data/lib/llvm/core_ffi.rb +62 -21
- data/lib/llvm/execution_engine.rb +13 -19
- data/lib/llvm/execution_engine_ffi.rb +1 -1
- data/lib/llvm/linker.rb +35 -0
- data/lib/llvm/linker_ffi.rb +45 -0
- data/lib/llvm/support.rb +32 -6
- data/lib/llvm/target.rb +318 -1
- data/lib/llvm/target_ffi.rb +302 -14
- data/lib/llvm/transforms/ipo_ffi.rb +1 -1
- data/lib/llvm/transforms/scalar_ffi.rb +1 -1
- data/lib/llvm/transforms/vectorize.rb +17 -0
- data/lib/llvm/transforms/vectorize_ffi.rb +31 -0
- data/lib/llvm/version.rb +21 -2
- data/test/array_test.rb +1 -1
- data/test/basic_block_test.rb +1 -1
- data/test/basic_test.rb +1 -1
- data/test/binary_operations_test.rb +1 -1
- data/test/bitcode_test.rb +2 -2
- data/test/branch_test.rb +1 -1
- data/test/call_test.rb +1 -1
- data/test/comparisons_test.rb +1 -1
- data/test/conversions_test.rb +1 -1
- data/test/double_test.rb +2 -2
- data/test/equality_test.rb +5 -5
- data/test/generic_value_test.rb +1 -1
- data/test/instruction_test.rb +1 -1
- data/test/ipo_test.rb +1 -1
- data/test/linker_test.rb +46 -0
- data/test/memory_access_test.rb +1 -1
- data/test/module_test.rb +50 -1
- data/test/phi_test.rb +1 -1
- data/test/select_test.rb +1 -1
- data/test/struct_test.rb +3 -3
- data/test/target_test.rb +124 -0
- data/test/test_helper.rb +10 -1
- data/test/type_test.rb +1 -1
- data/test/vector_test.rb +1 -1
- metadata +33 -22
- data/README.rdoc +0 -34
@@ -0,0 +1,31 @@
|
|
1
|
+
# Generated by ffi_gen. Please do not change this file by hand.
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
module LLVM::C
|
6
|
+
extend FFI::Library
|
7
|
+
ffi_lib 'LLVM-3.2'
|
8
|
+
|
9
|
+
def self.attach_function(name, *_)
|
10
|
+
begin; super; rescue FFI::NotFoundError => e
|
11
|
+
(class << self; self; end).class_eval { define_method(name) { |*_| raise e } }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# (Not documented)
|
16
|
+
#
|
17
|
+
# @method add_bb_vectorize_pass(pm)
|
18
|
+
# @param [FFI::Pointer(PassManagerRef)] pm
|
19
|
+
# @return [nil]
|
20
|
+
# @scope class
|
21
|
+
attach_function :add_bb_vectorize_pass, :LLVMAddBBVectorizePass, [:pointer], :void
|
22
|
+
|
23
|
+
# See llvm::createLoopVectorizePass function.
|
24
|
+
#
|
25
|
+
# @method add_loop_vectorize_pass(pm)
|
26
|
+
# @param [FFI::Pointer(PassManagerRef)] pm
|
27
|
+
# @return [nil]
|
28
|
+
# @scope class
|
29
|
+
attach_function :add_loop_vectorize_pass, :LLVMAddLoopVectorizePass, [:pointer], :void
|
30
|
+
|
31
|
+
end
|
data/lib/llvm/version.rb
CHANGED
@@ -1,4 +1,23 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
1
3
|
module LLVM
|
2
|
-
LLVM_VERSION = "3.
|
3
|
-
RUBY_LLVM_VERSION = "3.
|
4
|
+
LLVM_VERSION = "3.2"
|
5
|
+
RUBY_LLVM_VERSION = "3.2.0.beta.1"
|
6
|
+
LLVM_CONFIG = begin
|
7
|
+
variants = %W(llvm-config-#{LLVM_VERSION} llvm-config)
|
8
|
+
llvm_config = nil
|
9
|
+
catch :done do
|
10
|
+
paths = ENV['PATH'].split(File::PATH_SEPARATOR).select(&File.method(:directory?))
|
11
|
+
Find.find(*paths) do |path|
|
12
|
+
if variants.include?(File.basename(path))
|
13
|
+
actual_version = `#{path} --version`.chomp
|
14
|
+
if LLVM_VERSION == actual_version
|
15
|
+
llvm_config = path
|
16
|
+
throw(:done)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
llvm_config
|
22
|
+
end
|
4
23
|
end
|
data/test/array_test.rb
CHANGED
data/test/basic_block_test.rb
CHANGED
data/test/basic_test.rb
CHANGED
data/test/bitcode_test.rb
CHANGED
data/test/branch_test.rb
CHANGED
data/test/call_test.rb
CHANGED
data/test/comparisons_test.rb
CHANGED
data/test/conversions_test.rb
CHANGED
data/test/double_test.rb
CHANGED
@@ -2,7 +2,7 @@ require "test_helper"
|
|
2
2
|
|
3
3
|
class DoubleTestCase < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
LLVM.
|
5
|
+
LLVM.init_jit
|
6
6
|
end
|
7
7
|
|
8
8
|
def test_double
|
@@ -16,7 +16,7 @@ class DoubleTestCase < Test::Unit::TestCase
|
|
16
16
|
|
17
17
|
bb = fun.basic_blocks.append
|
18
18
|
builder.position_at_end(bb)
|
19
|
-
|
19
|
+
|
20
20
|
builder.ret(builder.fadd(p0, LLVM::Double(1.0)))
|
21
21
|
end
|
22
22
|
|
data/test/equality_test.rb
CHANGED
@@ -3,7 +3,7 @@ require "llvm/core"
|
|
3
3
|
|
4
4
|
class EqualityTestCase < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
LLVM.
|
6
|
+
LLVM.init_jit
|
7
7
|
end
|
8
8
|
|
9
9
|
class MyModule < LLVM::Module; end
|
@@ -40,7 +40,7 @@ class EqualityTestCase < Test::Unit::TestCase
|
|
40
40
|
:same => [int1, int1],
|
41
41
|
:not_same => [int1, int2, int3, int4],
|
42
42
|
:eql => [int1, int2],
|
43
|
-
:not_eql => [int1, int3
|
43
|
+
:not_eql => [int1, int3]
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_module
|
@@ -54,7 +54,7 @@ class EqualityTestCase < Test::Unit::TestCase
|
|
54
54
|
:same => [mod1, mod1],
|
55
55
|
:not_same => [mod1, mod2, mod3, mod4],
|
56
56
|
:eql => [mod1, mod2],
|
57
|
-
:not_eql => [mod1, mod3
|
57
|
+
:not_eql => [mod1, mod3]
|
58
58
|
end
|
59
59
|
|
60
60
|
def test_type
|
@@ -68,7 +68,7 @@ class EqualityTestCase < Test::Unit::TestCase
|
|
68
68
|
:same => [type1, type1],
|
69
69
|
:not_same => [type1, type2, type3, type4],
|
70
70
|
:eql => [type1, type2],
|
71
|
-
:not_eql => [type1, type3
|
71
|
+
:not_eql => [type1, type3]
|
72
72
|
end
|
73
73
|
|
74
74
|
def test_function
|
@@ -84,7 +84,7 @@ class EqualityTestCase < Test::Unit::TestCase
|
|
84
84
|
:same => [fn1, fn1],
|
85
85
|
:not_same => [fn1, fn2, fn3, fn4],
|
86
86
|
:eql => [fn1, fn2],
|
87
|
-
:not_eql => [fn1, fn3
|
87
|
+
:not_eql => [fn1, fn3]
|
88
88
|
end
|
89
89
|
|
90
90
|
end
|
data/test/generic_value_test.rb
CHANGED
data/test/instruction_test.rb
CHANGED
data/test/ipo_test.rb
CHANGED
data/test/linker_test.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'llvm/core'
|
3
|
+
require 'llvm/linker'
|
4
|
+
|
5
|
+
class LinkerTestCase < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
LLVM.init_jit
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_modules
|
11
|
+
@mod1 = define_module('mod1') do |mod|
|
12
|
+
mod1calc = mod.functions.add("calc", [], LLVM::Int32)
|
13
|
+
|
14
|
+
mod.functions.add("main", [], LLVM::Int32) do |fn|
|
15
|
+
fn.basic_blocks.append.build do |builder|
|
16
|
+
val = builder.call(mod1calc)
|
17
|
+
builder.ret val
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
@mod2 = define_module('mod2') do |mod|
|
23
|
+
mod.functions.add("calc", [], LLVM::Int32) do |fn|
|
24
|
+
fn.basic_blocks.append.build do |builder|
|
25
|
+
builder.ret LLVM::Int32.from_i(42)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_link_into
|
32
|
+
create_modules
|
33
|
+
@mod2.link_into(@mod1)
|
34
|
+
|
35
|
+
assert_equal 42, run_function_on_module(@mod1, 'main').to_i
|
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
|
+
end
|
data/test/memory_access_test.rb
CHANGED
data/test/module_test.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require "test_helper"
|
2
|
+
require "tempfile"
|
2
3
|
|
3
4
|
class ModuleTestCase < Test::Unit::TestCase
|
4
5
|
|
5
6
|
def setup
|
6
|
-
LLVM.
|
7
|
+
LLVM.init_jit
|
7
8
|
end
|
8
9
|
|
9
10
|
def test_simple_module
|
@@ -18,4 +19,52 @@ class ModuleTestCase < Test::Unit::TestCase
|
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
22
|
+
def test_global_variable
|
23
|
+
yielded = false
|
24
|
+
|
25
|
+
define_module('test_globals_add') do |mod|
|
26
|
+
mod.globals.add(LLVM::Int32, 'i') do |var|
|
27
|
+
yielded = true
|
28
|
+
assert_not_nil var
|
29
|
+
assert var.kind_of?(LLVM::GlobalVariable)
|
30
|
+
|
31
|
+
assert !var.unnamed_addr?
|
32
|
+
var.unnamed_addr = true
|
33
|
+
assert var.unnamed_addr?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
assert yielded, 'LLVM::Module::GlobalCollection#add takes block'
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_dump
|
41
|
+
mod = LLVM::Module.new('test_print')
|
42
|
+
expected_pattern = /^; ModuleID = 'test_print'$/
|
43
|
+
|
44
|
+
Tempfile.open('test_dump.1') do |tmpfile|
|
45
|
+
# debug stream (stderr)
|
46
|
+
stderr_old = $stderr.dup
|
47
|
+
$stderr.reopen(tmpfile.path, 'a')
|
48
|
+
begin
|
49
|
+
mod.dump
|
50
|
+
$stderr.flush
|
51
|
+
assert_match expected_pattern, File.read(tmpfile.path)
|
52
|
+
ensure
|
53
|
+
$stderr.reopen(stderr_old)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
Tempfile.open('test_dump.2') do |tmpfile|
|
58
|
+
# file descriptor
|
59
|
+
mod.dump(tmpfile.fileno)
|
60
|
+
assert_match expected_pattern, File.read(tmpfile.path)
|
61
|
+
end
|
62
|
+
|
63
|
+
Tempfile.open('test_dump.3') do |tmpfile|
|
64
|
+
# io object
|
65
|
+
mod.dump(tmpfile)
|
66
|
+
assert_match expected_pattern, File.read(tmpfile.path)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
21
70
|
end
|
data/test/phi_test.rb
CHANGED
data/test/select_test.rb
CHANGED
data/test/struct_test.rb
CHANGED
@@ -6,7 +6,7 @@ class StructTestCase < Test::Unit::TestCase
|
|
6
6
|
LLVM_PACKED = true
|
7
7
|
|
8
8
|
def setup
|
9
|
-
LLVM.
|
9
|
+
LLVM.init_jit
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_simple_struct
|
@@ -16,13 +16,13 @@ class StructTestCase < Test::Unit::TestCase
|
|
16
16
|
assert_equal LLVM::Int.type, struct.element_types[0]
|
17
17
|
assert_equal LLVM::Float.type, struct.element_types[1]
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def test_named_struct
|
21
21
|
struct = LLVM::Struct(LLVM::Int, LLVM::Float, "struct100")
|
22
22
|
assert_instance_of LLVM::StructType, struct
|
23
23
|
assert_equal "struct100", struct.name
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def test_deferred_element_type_setting
|
27
27
|
struct = LLVM::Struct("struct200")
|
28
28
|
struct.element_types = [LLVM::Int, LLVM::Float]
|
data/test/target_test.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require 'llvm/version'
|
3
|
+
|
4
|
+
class TargetTestCase < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
LLVM::Target.init('X86', true)
|
8
|
+
|
9
|
+
@x86 = LLVM::Target.by_name('x86')
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_init_native
|
13
|
+
assert_nothing_raised { LLVM::Target.init_native }
|
14
|
+
assert_nothing_raised { LLVM::Target.init_native(true) }
|
15
|
+
end
|
16
|
+
|
17
|
+
if `#{LLVM::LLVM_CONFIG} --targets-built` =~ /ARM/
|
18
|
+
def test_init_arm
|
19
|
+
assert_nothing_raised { LLVM::Target.init('ARM') }
|
20
|
+
assert_nothing_raised { LLVM::Target.init('ARM', true) }
|
21
|
+
assert_not_nil LLVM::Target.by_name('arm')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_init_all
|
26
|
+
assert_nothing_raised { LLVM::Target.init_all }
|
27
|
+
assert_nothing_raised { LLVM::Target.init_all(true) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_each
|
31
|
+
targets = LLVM::Target.each
|
32
|
+
|
33
|
+
assert_instance_of Enumerator, targets
|
34
|
+
assert_equal 2, targets.count
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_target
|
38
|
+
assert_equal 'x86', @x86.name
|
39
|
+
assert_equal "32-bit X86: Pentium-Pro and above", @x86.description
|
40
|
+
assert_equal true, @x86.jit?
|
41
|
+
assert_equal true, @x86.target_machine?
|
42
|
+
assert_equal true, @x86.asm_backend?
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_target_machine
|
46
|
+
@x86 = LLVM::Target.by_name('x86')
|
47
|
+
mach = @x86.create_machine('x86-linux-gnu', 'i686')
|
48
|
+
|
49
|
+
assert_equal @x86, mach.target
|
50
|
+
assert_equal 'x86-linux-gnu', mach.triple
|
51
|
+
assert_equal 'i686', mach.cpu
|
52
|
+
assert_equal '', mach.features
|
53
|
+
|
54
|
+
layout = mach.data_layout
|
55
|
+
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
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_emit
|
59
|
+
mach = @x86.create_machine('x86-linux-gnu')
|
60
|
+
|
61
|
+
mod = define_module('test') do |mod|
|
62
|
+
define_function(mod, 'main', [], LLVM::Int) do |builder, fun|
|
63
|
+
entry = fun.basic_blocks.append
|
64
|
+
builder.position_at_end(entry)
|
65
|
+
builder.ret(LLVM::Int(0))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
Tempfile.open('emit') do |tmp|
|
70
|
+
assert_nothing_raised { mach.emit(mod, tmp.path) }
|
71
|
+
assert_match %r{xorl\t%eax, %eax}, tmp.read
|
72
|
+
end
|
73
|
+
|
74
|
+
Tempfile.open('emit') do |tmp|
|
75
|
+
assert_nothing_raised { mach.emit(mod, tmp.path, :object) }
|
76
|
+
assert_match %r{\x31\xc0\xc3}o, File.read(tmp.path, mode: 'rb')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_module_properties
|
81
|
+
mod = LLVM::Module.new('mod')
|
82
|
+
|
83
|
+
assert_equal '', mod.triple
|
84
|
+
|
85
|
+
mod.triple = 'x86-linux-gnu'
|
86
|
+
assert_equal 'x86-linux-gnu', mod.triple
|
87
|
+
|
88
|
+
assert_equal '', mod.data_layout
|
89
|
+
|
90
|
+
mod.data_layout = 'e-p:64:64:64'
|
91
|
+
assert_equal 'e-p:64:64:64', mod.data_layout
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_data_layout
|
95
|
+
layout_be = LLVM::TargetDataLayout.new('E')
|
96
|
+
assert_equal :big_endian, layout_be.byte_order
|
97
|
+
|
98
|
+
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"
|
99
|
+
layout = LLVM::TargetDataLayout.new(desc)
|
100
|
+
|
101
|
+
assert_equal desc, layout.to_s
|
102
|
+
assert_equal :little_endian, layout.byte_order
|
103
|
+
assert_equal 8, layout.pointer_size
|
104
|
+
assert_equal 8, layout.pointer_size(0)
|
105
|
+
assert_equal LLVM::Int64.type, layout.int_ptr_type
|
106
|
+
assert_equal LLVM::Int64.type, layout.int_ptr_type(0)
|
107
|
+
|
108
|
+
assert_equal 19, layout.bit_size_of(LLVM::Int19.type)
|
109
|
+
assert_equal 3, layout.storage_size_of(LLVM::Int19.type)
|
110
|
+
assert_equal 4, layout.abi_size_of(LLVM::Int19.type)
|
111
|
+
assert_equal 4, layout.abi_alignment_of(LLVM::Int19.type)
|
112
|
+
assert_equal 4, layout.call_frame_alignment_of(LLVM::Int19.type)
|
113
|
+
assert_equal 4, layout.preferred_alignment_of(LLVM::Int19.type)
|
114
|
+
|
115
|
+
struct = LLVM.Struct(LLVM::Int8, LLVM::Int32)
|
116
|
+
|
117
|
+
assert_equal 0, layout.offset_of_element(struct, 0)
|
118
|
+
assert_equal 4, layout.offset_of_element(struct, 1)
|
119
|
+
|
120
|
+
assert_equal 0, layout.element_at_offset(struct, 0)
|
121
|
+
assert_equal 0, layout.element_at_offset(struct, 3)
|
122
|
+
assert_equal 1, layout.element_at_offset(struct, 4)
|
123
|
+
end
|
124
|
+
end
|