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.
Files changed (53) hide show
  1. data/LICENSE +30 -0
  2. data/README.md +49 -0
  3. data/ext/ruby-llvm-support/Rakefile +30 -7
  4. data/ext/ruby-llvm-support/support.cpp +48 -1
  5. data/lib/llvm.rb +26 -3
  6. data/lib/llvm/analysis.rb +8 -11
  7. data/lib/llvm/analysis_ffi.rb +1 -1
  8. data/lib/llvm/core.rb +36 -1
  9. data/lib/llvm/core/bitcode_ffi.rb +1 -1
  10. data/lib/llvm/core/builder.rb +20 -14
  11. data/lib/llvm/core/module.rb +87 -63
  12. data/lib/llvm/core/pass_manager.rb +30 -30
  13. data/lib/llvm/core/type.rb +34 -51
  14. data/lib/llvm/core/value.rb +13 -25
  15. data/lib/llvm/core_ffi.rb +62 -21
  16. data/lib/llvm/execution_engine.rb +13 -19
  17. data/lib/llvm/execution_engine_ffi.rb +1 -1
  18. data/lib/llvm/linker.rb +35 -0
  19. data/lib/llvm/linker_ffi.rb +45 -0
  20. data/lib/llvm/support.rb +32 -6
  21. data/lib/llvm/target.rb +318 -1
  22. data/lib/llvm/target_ffi.rb +302 -14
  23. data/lib/llvm/transforms/ipo_ffi.rb +1 -1
  24. data/lib/llvm/transforms/scalar_ffi.rb +1 -1
  25. data/lib/llvm/transforms/vectorize.rb +17 -0
  26. data/lib/llvm/transforms/vectorize_ffi.rb +31 -0
  27. data/lib/llvm/version.rb +21 -2
  28. data/test/array_test.rb +1 -1
  29. data/test/basic_block_test.rb +1 -1
  30. data/test/basic_test.rb +1 -1
  31. data/test/binary_operations_test.rb +1 -1
  32. data/test/bitcode_test.rb +2 -2
  33. data/test/branch_test.rb +1 -1
  34. data/test/call_test.rb +1 -1
  35. data/test/comparisons_test.rb +1 -1
  36. data/test/conversions_test.rb +1 -1
  37. data/test/double_test.rb +2 -2
  38. data/test/equality_test.rb +5 -5
  39. data/test/generic_value_test.rb +1 -1
  40. data/test/instruction_test.rb +1 -1
  41. data/test/ipo_test.rb +1 -1
  42. data/test/linker_test.rb +46 -0
  43. data/test/memory_access_test.rb +1 -1
  44. data/test/module_test.rb +50 -1
  45. data/test/phi_test.rb +1 -1
  46. data/test/select_test.rb +1 -1
  47. data/test/struct_test.rb +3 -3
  48. data/test/target_test.rb +124 -0
  49. data/test/test_helper.rb +10 -1
  50. data/test/type_test.rb +1 -1
  51. data/test/vector_test.rb +1 -1
  52. metadata +33 -22
  53. 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
@@ -1,4 +1,23 @@
1
+ require 'find'
2
+
1
3
  module LLVM
2
- LLVM_VERSION = "3.1"
3
- RUBY_LLVM_VERSION = "3.1.0.beta.1"
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
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class ArrayTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
8
 
9
9
  def test_constant_array_from_size
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class BasicBlockTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  @module = LLVM::Module.new("BasicBlockTestCase")
8
8
  end
9
9
 
@@ -4,7 +4,7 @@ class BasicTestCase < Test::Unit::TestCase
4
4
 
5
5
  def test_llvm_initialization
6
6
  assert_nothing_raised do
7
- LLVM.init_x86
7
+ LLVM.init_jit
8
8
  end
9
9
  end
10
10
 
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class BasicOperationsTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
8
 
9
9
  def test_integer_binary_operations
@@ -3,9 +3,9 @@ require "tempfile"
3
3
 
4
4
  class BitcodeTestCase < Test::Unit::TestCase
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
-
8
+
9
9
  def test_bitcode
10
10
  test_module = define_module("test_module") do |mod|
11
11
  define_function(mod, "test_function", [], LLVM::Int) do
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class BranchTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
8
 
9
9
  def test_branching
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class CallTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
8
 
9
9
  def test_simple_call
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class ComparisonsTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
8
 
9
9
  def test_integer_comparison
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class ConversionsTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
8
 
9
9
  def test_trunc_to
@@ -2,7 +2,7 @@ require "test_helper"
2
2
 
3
3
  class DoubleTestCase < Test::Unit::TestCase
4
4
  def setup
5
- LLVM.init_x86
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
 
@@ -3,7 +3,7 @@ require "llvm/core"
3
3
 
4
4
  class EqualityTestCase < Test::Unit::TestCase
5
5
  def setup
6
- LLVM.init_x86
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, int4]
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, mod4]
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, type4]
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, fn4]
87
+ :not_eql => [fn1, fn3]
88
88
  end
89
89
 
90
90
  end
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class GenericValueTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
8
 
9
9
  def test_from_i
@@ -2,7 +2,7 @@ require "test_helper"
2
2
 
3
3
  class InstructionTestCase < Test::Unit::TestCase
4
4
  def setup
5
- LLVM.init_x86
5
+ LLVM.init_jit
6
6
  @module = LLVM::Module.new("InstructionTestCase")
7
7
  end
8
8
 
@@ -6,7 +6,7 @@ require 'llvm/core/pass_manager'
6
6
  class IPOTestCase < Test::Unit::TestCase
7
7
 
8
8
  def setup
9
- LLVM.init_x86
9
+ LLVM.init_jit
10
10
  end
11
11
 
12
12
  def test_gdce
@@ -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
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class MemoryAccessTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
8
 
9
9
  def test_memory_access
@@ -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.init_x86
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
@@ -2,7 +2,7 @@ require "test_helper"
2
2
 
3
3
  class PhiTest < Test::Unit::TestCase
4
4
  def setup
5
- LLVM.init_x86
5
+ LLVM.init_jit
6
6
  end
7
7
 
8
8
  def test_phi
@@ -3,7 +3,7 @@ require "test_helper"
3
3
  class SelectTestCase < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- LLVM.init_x86
6
+ LLVM.init_jit
7
7
  end
8
8
 
9
9
  def test_select
@@ -6,7 +6,7 @@ class StructTestCase < Test::Unit::TestCase
6
6
  LLVM_PACKED = true
7
7
 
8
8
  def setup
9
- LLVM.init_x86
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]
@@ -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