ruby-llvm 3.4.1 → 3.4.2

Sign up to get free protection for your applications and to get access to all the features.
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