ruby-llvm 3.4.1 → 3.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7fbf551060132cd96ad86b5c4954c20a77071b0e
4
- data.tar.gz: e37b6914665099358af491974f0fab85581d4438
3
+ metadata.gz: b4c3ca01e2020b5ce26bdf7db68f78f33d4fefbe
4
+ data.tar.gz: 4580027aed01abdc1c9055dfd4d3736f1fae4606
5
5
  SHA512:
6
- metadata.gz: ecbe7f6377c0cf7373ae91b32c6fb5210d19a503d1d3379b8212bd09262a3e4cfc0e2d74bbb73b27d35b084ae02ad240ca19b153700f2a1219e762605b1d6593
7
- data.tar.gz: 2a3918df0a19ebc8cb7f72914d752941f459efb0cc8cef89b4ace55f09276ab30c832c3f93026ff40dfb10a9a1818828d02dd0f776f25fc28447eb8fde3481eb
6
+ metadata.gz: b111187af62e59fd09acd472f241f0e64913832f956f99cf2fb3faf16806f7b61957840f4fe0246181a41521c9180d0b18420356915077635fa5a9690853b81e
7
+ data.tar.gz: 108a673c529d5b7621c7206f169b8704473cc518fafed2e10880f2f96fbe58537e8b2f47cab56b5ac0dabf3c2ef7affa9a0166c0e2cf1511a1ba98b5f6ed824e
@@ -32,8 +32,11 @@ def find_llvm_config
32
32
 
33
33
  begin
34
34
  actual_version = `#{llvm_config} --version`.strip
35
+ actual_maj, actual_min, _ = actual_version.split('.')
35
36
 
36
- actual_version == LLVM_VERSION
37
+ required_maj, required_min = LLVM_VERSION.split('.')
38
+
39
+ actual_maj == required_maj && actual_min == required_min
37
40
  rescue Errno::ENOENT
38
41
  false
39
42
  end
@@ -41,8 +44,8 @@ def find_llvm_config
41
44
  end
42
45
 
43
46
  def find_cxx
44
- check_for('C++ compiler', %W(clang++ g++), 'CXX') do |cxx|
45
- system(cxx, "--version")
47
+ check_for('C++ compiler', %W(g++ clang++), 'CXX') do |cxx|
48
+ system(cxx, "--version", out: File::NULL, err: File::NULL)
46
49
  $?.success?
47
50
  end
48
51
  end
@@ -63,7 +66,7 @@ desc "Build the shared library and config module"
63
66
  task :default => [SUPPORT_LIB, CONFIG_MOD]
64
67
 
65
68
  file SUPPORT_LIB => %w(support.cpp) do |task|
66
- sh "#{CXX} -shared -lLLVM-#{LLVM_VERSION} #{task.prerequisites.join(' ')} " \
69
+ sh "#{CXX} -shared #{task.prerequisites.join(' ')} -lLLVM-#{LLVM_VERSION} " \
67
70
  "#{invoke_llvm_config('--cxxflags --ldflags')} -o #{SUPPORT_LIB}"
68
71
  end
69
72
 
@@ -3,20 +3,12 @@
3
3
  */
4
4
 
5
5
  #include <llvm-c/Core.h>
6
- #include <llvm/IR/Type.h>
7
- #include <llvm/IR/Module.h>
8
6
  #include <llvm/IR/GlobalValue.h>
9
- #include <llvm/Support/DynamicLibrary.h>
10
7
  #include <llvm/Support/TargetSelect.h>
11
- #include <llvm/Support/raw_ostream.h>
12
8
 
13
9
  extern "C" {
14
10
  using namespace llvm;
15
11
 
16
- int LLVMLoadLibraryPermanently(const char* filename) {
17
- return llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename);
18
- }
19
-
20
12
  LLVMBool LLVMHasUnnamedAddr(LLVMValueRef global) {
21
13
  return unwrap<GlobalValue>(global)->hasUnnamedAddr();
22
14
  }
@@ -5,12 +5,19 @@ require 'llvm/analysis'
5
5
  require 'llvm/execution_engine_ffi'
6
6
 
7
7
  module LLVM
8
- class JITCompiler
9
- # Important: Call #dispose to free backend memory after use. Do not call #dispose on mod any more.
10
- def initialize(mod, opt_level = 3)
8
+ # @abstract Subclass and override {#create_execution_engine_for_module}.
9
+ class ExecutionEngine
10
+ # Create a JIT execution engine for module with the given options.
11
+ #
12
+ # @note Important: Call #dispose to free backend memory after use. Do not call #dispose on mod any more.
13
+ #
14
+ # @param [LLVM::Module] mod module
15
+ # @param [Hash{Symbol => Object}] options options
16
+ # @return [ExecutionEngine] JIT execution engine
17
+ def initialize(mod, options)
11
18
  FFI::MemoryPointer.new(FFI.type_size(:pointer)) do |ptr|
12
19
  error = FFI::MemoryPointer.new(FFI.type_size(:pointer))
13
- status = C.create_jit_compiler_for_module(ptr, mod, opt_level, error)
20
+ status = create_execution_engine_for_module(ptr, mod, error, options)
14
21
  errorp = error.read_pointer
15
22
  message = errorp.read_string unless errorp.null?
16
23
 
@@ -69,6 +76,158 @@ module LLVM
69
76
  def pointer_to_global(global)
70
77
  C.get_pointer_to_global(self, global)
71
78
  end
79
+
80
+ # Returns a ModuleCollection of all the Modules in the engine.
81
+ # @return [ModuleCollection]
82
+ def modules
83
+ @modules ||= ModuleCollection.new(self)
84
+ end
85
+
86
+ # Returns a FunctionCollection of all the Functions in the engine.
87
+ # @return [FunctionCollection]
88
+ def functions
89
+ @functions ||= FunctionCollection.new(self)
90
+ end
91
+
92
+ class ModuleCollection
93
+ # @param [ExecutionEngine] engine
94
+ def initialize(engine)
95
+ @engine = engine
96
+ end
97
+
98
+ # @param [LLVM::Module] mod
99
+ # @return [ModuleCollection]
100
+ def add(mod)
101
+ tap { C.add_module(@engine, mod) }
102
+ end
103
+
104
+ # @param [LLVM::Module] mod
105
+ # @return [LLVM::Module] deleted module
106
+ def delete(mod)
107
+ error = FFI::MemoryPointer.new(:pointer)
108
+ out_mod = FFI::MemoryPointer.new(:pointer)
109
+
110
+ status = C.remove_module(@engine, mod, out_mod, error)
111
+
112
+ if status.zero?
113
+ LLVM::Module.from_ptr(out_mod.read_pointer)
114
+ else
115
+ errorp = error.read_pointer
116
+ message = errorp.read_string unless errorp.null?
117
+
118
+ C.dispose_message(error)
119
+ error.autorelease=false
120
+
121
+ raise "Error removing module: #{message}"
122
+ end
123
+ end
124
+
125
+ alias_method :<<, :add
126
+ end
127
+
128
+ class FunctionCollection
129
+ # @param [ExecutionEngine] engine
130
+ def initialize(engine)
131
+ @engine = engine
132
+ end
133
+
134
+ # @param [String, Symbol] name function name
135
+ # @return [Function]
136
+ def named(name)
137
+ out_fun = FFI::MemoryPointer.new(:pointer)
138
+
139
+ status = C.find_function(@engine, name.to_s, out_fun)
140
+ return unless status.zero?
141
+
142
+ Function.from_ptr(out_fun.read_pointer)
143
+ end
144
+
145
+ alias_method :[], :named
146
+ end
147
+
148
+ protected
149
+
150
+ # Create a JIT execution engine for module with the given options.
151
+ #
152
+ # @param [FFI::Pointer(*ExecutionEngineRef)] out_ee execution engine
153
+ # @param [LLVM::Module] mod module
154
+ # @param [FFI::Pointer(**CharS)] out_error error message
155
+ # @param [Hash{Symbol => Object}] options options. `:opt_level => 3` for example.
156
+ # @return [Integer] 0 for success, non- zero to indicate an error
157
+ def create_execution_engine_for_module(out_ee, mod, out_error, options)
158
+ raise NotImplementedError, "override in subclass"
159
+ end
160
+ end
161
+
162
+ class JITCompiler < ExecutionEngine
163
+ # Create a JIT execution engine.
164
+ #
165
+ # @note You should call `LLVM.init_jit` before creating an execution engine.
166
+ #
167
+ # @param [LLVM::Module] mod module
168
+ # @param [Hash{Symbol => Object}] options options
169
+ # @option options [Integer] :opt_level (3) Optimization level
170
+ # @return [ExecutionEngine] Execution engine
171
+ def initialize(mod, options = {})
172
+ # Prior to ruby-llvm 3.4.0, signature is initialize(mod, opt_level = 3)
173
+ if options.kind_of?(Integer)
174
+ options = { :opt_level => options }
175
+ end
176
+
177
+ options = {
178
+ :opt_level => 3,
179
+ }.merge(options)
180
+
181
+ super
182
+ end
183
+
184
+ protected
185
+
186
+ def create_execution_engine_for_module(out_ee, mod, out_error, options)
187
+ C.create_jit_compiler_for_module(out_ee, mod, options[:opt_level], out_error)
188
+ end
189
+ end
190
+
191
+ class MCJITCompiler < ExecutionEngine
192
+ # Create a MCJIT execution engine.
193
+ #
194
+ # @note You should call `LLVM.init_jit(true)` before creating an execution engine.
195
+ # @todo Add :mcjmm option (MCJIT memory manager)
196
+ #
197
+ # @param [LLVM::Module] mod module
198
+ # @param [Hash{Symbol => Object}] options options
199
+ # @option options [Integer] :opt_level (2) Optimization level
200
+ # @option options [Integer] :code_model (0) Code model types
201
+ # @option options [Boolean] :no_frame_pointer_elim (false) Disable frame pointer elimination optimization
202
+ # @option options [Boolean] :enable_fast_i_sel (false) Enables fast-path instruction selection
203
+ # @return [ExecutionEngine] Execution engine
204
+ def initialize(mod, options = {})
205
+ options = {
206
+ :opt_level => 2, # LLVMCodeGenLevelDefault
207
+ :code_model => 0, # LLVMCodeModelDefault
208
+ :no_frame_pointer_elim => false,
209
+ :enable_fast_i_sel => false,
210
+ # TODO
211
+ #:mcjmm => nil,
212
+ }.merge(options)
213
+
214
+ super
215
+ end
216
+
217
+ protected
218
+
219
+ def create_execution_engine_for_module(out_ee, mod, out_error, options)
220
+ mcopts = LLVM::C::MCJITCompilerOptions.new
221
+
222
+ LLVM::C.initialize_mcjit_compiler_options(mcopts, mcopts.size)
223
+
224
+ mcopts[:opt_level] = options[:opt_level]
225
+ mcopts[:code_model] = options[:code_model]
226
+ mcopts[:no_frame_pointer_elim] = options[:no_frame_pointer_elim] ? 1 : 0
227
+ mcopts[:enable_fast_i_sel] = options[:enable_fast_i_sel] ? 1 : 0
228
+
229
+ C.create_mcjit_compiler_for_module(out_ee, mod, mcopts, mcopts.size, out_error)
230
+ end
72
231
  end
73
232
 
74
233
  class GenericValue
data/lib/llvm/support.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'llvm/core_ffi'
2
+ require 'llvm/support_ffi'
2
3
 
3
4
  module LLVM
4
5
 
@@ -16,7 +17,6 @@ module LLVM
16
17
  lib_path = File.expand_path("../../ext/ruby-llvm-support/#{lib_name}", File.dirname(__FILE__))
17
18
  ffi_lib [lib_path]
18
19
 
19
- attach_function :load_library_permanently, :LLVMLoadLibraryPermanently, [:string], :int
20
20
  attach_function :has_unnamed_addr, :LLVMHasUnnamedAddr, [OpaqueValue], :int
21
21
  attach_function :set_unnamed_addr, :LLVMSetUnnamedAddr, [OpaqueValue, :int], :void
22
22
 
@@ -36,11 +36,11 @@ module LLVM
36
36
  end
37
37
  end
38
38
 
39
- def load_library(libname)
40
- Support::C.load_library_permanently(libname)
39
+ def self.load_library(libname)
40
+ if C.load_library_permanently(libname) != 0
41
+ raise "LLVM::Support.load_library failed"
42
+ end
41
43
 
42
44
  nil
43
45
  end
44
-
45
- module_function :load_library
46
46
  end
@@ -0,0 +1,23 @@
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.4'
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 load_library_permanently(filename)
18
+ # @param [String] filename
19
+ # @return [Integer]
20
+ # @scope class
21
+ attach_function :load_library_permanently, :LLVMLoadLibraryPermanently, [:string], :int
22
+
23
+ end
data/lib/llvm/target.rb CHANGED
@@ -4,8 +4,8 @@ require 'llvm/target_ffi'
4
4
 
5
5
  module LLVM
6
6
  # A shorthand for {LLVM::Target.init_native}
7
- def self.init_jit
8
- LLVM::Target.init_native
7
+ def self.init_jit(*args)
8
+ LLVM::Target.init_native(*args)
9
9
  end
10
10
 
11
11
  # @deprecated Use LLVM.init_jit or LLVM::Target.init('X86').
data/lib/llvm/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module LLVM
2
2
  LLVM_VERSION = "3.4"
3
- RUBY_LLVM_VERSION = "3.4.1"
3
+ RUBY_LLVM_VERSION = "3.4.2"
4
4
  end
@@ -0,0 +1,87 @@
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
+ ['foo', :foo].each do |name|
39
+ engine.functions[name].tap do |fun|
40
+ assert fun, "function named #{name.inspect}"
41
+ assert_equal 'foo', fun.name
42
+ end
43
+ end
44
+ end
45
+
46
+ def test_add_module
47
+ main_mod = LLVM::Module.new('main')
48
+
49
+ main_mod.functions.add(:square, [LLVM::Int], LLVM::Int) do |square|
50
+ main_mod.functions.add(:call_square, [], LLVM::Int) do |call_square|
51
+ call_square.basic_blocks.append.build do |builder|
52
+ n = builder.call(square, LLVM::Int(5))
53
+ builder.ret(n)
54
+ end
55
+ end
56
+ end
57
+
58
+ main_mod.verify!
59
+
60
+ engine = LLVM::MCJITCompiler.new(main_mod, :opt_level => 0)
61
+ engine.modules << create_square_function_module
62
+
63
+ result = engine.run_function(main_mod.functions['call_square'])
64
+ assert_equal 25, result.to_i
65
+ end
66
+
67
+ def test_remove_module
68
+ mod1 = LLVM::Module.new('foo')
69
+ mod2 = LLVM::Module.new('bar')
70
+
71
+ foo = mod1.functions.add(:foo, [], LLVM::Int)
72
+ bar = mod2.functions.add(:bar, [], LLVM::Int)
73
+
74
+ engine = LLVM::MCJITCompiler.new(mod1, :opt_level => 0)
75
+
76
+ (engine.modules << mod2).tap do |ret|
77
+ assert_equal engine.modules, ret, '#<< returns self'
78
+ end
79
+
80
+ assert engine.functions[:bar]
81
+ engine.modules.delete(mod2).tap do |ret|
82
+ assert_instance_of LLVM::Module, ret, '#delete returns module'
83
+ assert_equal mod2, ret
84
+ end
85
+ assert_nil engine.functions[:bar]
86
+ end
87
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-llvm
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.1
4
+ version: 3.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Voorhis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-04 00:00:00.000000000 Z
11
+ date: 2015-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -127,6 +127,7 @@ files:
127
127
  - lib/llvm/linker.rb
128
128
  - lib/llvm/linker_ffi.rb
129
129
  - lib/llvm/support.rb
130
+ - lib/llvm/support_ffi.rb
130
131
  - lib/llvm/target.rb
131
132
  - lib/llvm/target_ffi.rb
132
133
  - lib/llvm/transforms/builder.rb
@@ -153,6 +154,7 @@ files:
153
154
  - test/instruction_test.rb
154
155
  - test/ipo_test.rb
155
156
  - test/linker_test.rb
157
+ - test/mcjit_test.rb
156
158
  - test/memory_access_test.rb
157
159
  - test/module_test.rb
158
160
  - test/parameter_collection_test.rb
@@ -183,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
185
  version: '0'
184
186
  requirements: []
185
187
  rubyforge_project:
186
- rubygems_version: 2.2.2
188
+ rubygems_version: 2.4.1
187
189
  signing_key:
188
190
  specification_version: 4
189
191
  summary: LLVM bindings for Ruby
@@ -209,6 +211,7 @@ test_files:
209
211
  - test/struct_test.rb
210
212
  - test/parameter_collection_test.rb
211
213
  - test/call_test.rb
214
+ - test/mcjit_test.rb
212
215
  - test/vector_test.rb
213
216
  - test/target_test.rb
214
217
  - test/array_test.rb