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
data/LICENSE
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Copyright (c) 2010-2011 Jeremy Voorhis
|
2
|
+
|
3
|
+
All rights reserved.
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
6
|
+
modification, are permitted provided that the following conditions
|
7
|
+
are met:
|
8
|
+
|
9
|
+
1. Redistributions of source code must retain the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer.
|
11
|
+
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright
|
13
|
+
notice, this list of conditions and the following disclaimer in the
|
14
|
+
documentation and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
3. Neither the name of the author nor the names of his contributors
|
17
|
+
may be used to endorse or promote products derived from this software
|
18
|
+
without specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
|
21
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
22
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
|
24
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
26
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
27
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
28
|
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
29
|
+
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
30
|
+
POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
Ruby-LLVM
|
2
|
+
=========
|
3
|
+
|
4
|
+
Ruby-LLVM is a Ruby language binding to the LLVM compiler infrastructure
|
5
|
+
library. LLVM allows users to create just-in-time (JIT) compilers, ahead-of-time
|
6
|
+
(AOT) compilers for multiple architectures, code analyzers and more. LLVM
|
7
|
+
bindings can also be used to speed up Ruby code by compiling Ruby methods on the
|
8
|
+
fly.
|
9
|
+
|
10
|
+
Requirements
|
11
|
+
------------
|
12
|
+
* LLVM 3.2, including libLLVM-3.2 (compile LLVM with --enable-shared).
|
13
|
+
* In order to ensure the usability of JIT features (i.e. create_jit_compiler), compile LLVM with --enable-jit as well.
|
14
|
+
|
15
|
+
About version numbers
|
16
|
+
---------------------
|
17
|
+
|
18
|
+
The first two digits of ruby-llvm's version number refer to the required
|
19
|
+
major and minor version of LLVM. The third digit refers to the ruby-llvm
|
20
|
+
release itself. Because LLVM's api changes often, this coupling between
|
21
|
+
LLVM and ruby-llvm versions is useful.
|
22
|
+
|
23
|
+
Homebrew
|
24
|
+
--------
|
25
|
+
LLVM can be installed with Homebrew by executing `brew install llvm --shared`
|
26
|
+
|
27
|
+
See Also
|
28
|
+
--------
|
29
|
+
* [The LLVM project](http://llvm.org)
|
30
|
+
* [ffi-gen](https://github.com/neelance/ffi-gen) – Generate
|
31
|
+
[FFI](https://github.com/ffi/ffi) bindings with LLVM and Clang
|
32
|
+
|
33
|
+
License
|
34
|
+
-------
|
35
|
+
Ruby-LLVM is available under the BSD 3-clause (see LICENSE), Copyright (c) 2010-2013 Jeremy Voorhis
|
36
|
+
|
37
|
+
Ruby-LLVM is possible because of its contributors:
|
38
|
+
|
39
|
+
* Evan Phoenix
|
40
|
+
* David Holroyd
|
41
|
+
* Takanori Ishikawa
|
42
|
+
* Ronaldo M. Ferraz
|
43
|
+
* Mac Malone
|
44
|
+
* Chris Wailes
|
45
|
+
* Ary Borenszweig
|
46
|
+
* Richard Musiol
|
47
|
+
* Juan Wajnerman
|
48
|
+
* Steven Farlie
|
49
|
+
* Peter Zotov
|
@@ -2,12 +2,35 @@ require 'rake/clean'
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'ffi'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
# Change this when updating for a newer LLVM.
|
6
|
+
LLVM_VERSION = '3.2'
|
7
|
+
|
8
|
+
def check_llvm_config(name)
|
9
|
+
actual_version = `#{name} --version`
|
10
|
+
actual_version.strip == LLVM_VERSION
|
11
|
+
rescue Errno::ENOENT
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def invoke_llvm_config(options)
|
16
|
+
variants = %W(llvm-config-#{LLVM_VERSION} llvm-config)
|
17
|
+
|
18
|
+
variants.each do |name|
|
19
|
+
if check_llvm_config(name)
|
20
|
+
return `#{name} #{options}`.gsub("\n", " ")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
raise RuntimeError, "No valid llvm-config found. Tried: #{variants}"
|
25
|
+
end
|
26
|
+
|
27
|
+
LLVM_CONFIG = invoke_llvm_config('--cxxflags --ldflags')
|
28
|
+
|
29
|
+
CXX = "g++"
|
30
|
+
SRC = "support.cpp"
|
31
|
+
OUTPUT = FFI.map_library_name("RubyLLVMSupport-#{LLVM_VERSION}")
|
32
|
+
|
33
|
+
CLEAN.include(OUTPUT)
|
11
34
|
|
12
35
|
task :default => [:build]
|
13
36
|
|
@@ -15,5 +38,5 @@ desc "Build the shared library"
|
|
15
38
|
task :build => [OUTPUT]
|
16
39
|
|
17
40
|
file OUTPUT => [SRC] do
|
18
|
-
sh "#{
|
41
|
+
sh "#{CXX} -shared -lLLVM-#{LLVM_VERSION} #{SRC} #{LLVM_CONFIG} -o #{OUTPUT}"
|
19
42
|
end
|
@@ -2,12 +2,59 @@
|
|
2
2
|
* Extended bindings for LLVM.
|
3
3
|
*/
|
4
4
|
|
5
|
-
#include <llvm/
|
5
|
+
#include <llvm-c/Core.h>
|
6
|
+
#include <llvm/Type.h>
|
7
|
+
#include <llvm/GlobalValue.h>
|
6
8
|
#include <llvm/Support/DynamicLibrary.h>
|
9
|
+
#include <llvm/Support/TargetSelect.h>
|
10
|
+
#include <llvm/Support/raw_ostream.h>
|
7
11
|
|
8
12
|
extern "C" {
|
13
|
+
using namespace llvm;
|
14
|
+
|
9
15
|
int LLVMLoadLibraryPermanently(const char* filename) {
|
10
16
|
return llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename);
|
11
17
|
}
|
18
|
+
|
19
|
+
LLVMBool LLVMHasUnnamedAddr(LLVMValueRef global) {
|
20
|
+
return unwrap<GlobalValue>(global)->hasUnnamedAddr();
|
21
|
+
}
|
22
|
+
|
23
|
+
void LLVMSetUnnamedAddr(LLVMValueRef global, LLVMBool val) {
|
24
|
+
unwrap<GlobalValue>(global)->setUnnamedAddr(val != 0);
|
25
|
+
}
|
26
|
+
|
27
|
+
void LLVMDumpType(LLVMTypeRef type) {
|
28
|
+
unwrap<Type>(type)->dump();
|
29
|
+
}
|
30
|
+
|
31
|
+
int LLVMPrintModuleToFD(LLVMModuleRef module, int fd, LLVMBool shouldClose, LLVMBool unbuffered) {
|
32
|
+
raw_fd_ostream os(fd, shouldClose, unbuffered);
|
33
|
+
unwrap(module)->print(os, 0);
|
34
|
+
}
|
35
|
+
|
36
|
+
void LLVMInitializeAllTargetInfos() {
|
37
|
+
llvm::InitializeAllTargetInfos();
|
38
|
+
}
|
39
|
+
|
40
|
+
void LLVMInitializeAllTargets() {
|
41
|
+
llvm::InitializeAllTargets();
|
42
|
+
}
|
43
|
+
|
44
|
+
void LLVMInitializeAllTargetMCs() {
|
45
|
+
llvm::InitializeAllTargetMCs();
|
46
|
+
}
|
47
|
+
|
48
|
+
void LLVMInitializeAllAsmPrinters() {
|
49
|
+
llvm::InitializeAllAsmPrinters();
|
50
|
+
}
|
51
|
+
|
52
|
+
void LLVMInitializeNativeTarget() {
|
53
|
+
llvm::InitializeNativeTarget();
|
54
|
+
}
|
55
|
+
|
56
|
+
void LLVMInitializeNativeTargetAsmPrinter() {
|
57
|
+
llvm::InitializeNativeTargetAsmPrinter();
|
58
|
+
}
|
12
59
|
}
|
13
60
|
|
data/lib/llvm.rb
CHANGED
@@ -1,12 +1,35 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'ffi'
|
3
3
|
|
4
|
-
require 'llvm/support'
|
5
|
-
|
6
4
|
module LLVM
|
5
|
+
require 'llvm/support'
|
6
|
+
|
7
7
|
# @private
|
8
8
|
module C
|
9
9
|
extend ::FFI::Library
|
10
|
-
ffi_lib ['LLVM-3.
|
10
|
+
ffi_lib ['LLVM-3.2']
|
11
|
+
end
|
12
|
+
|
13
|
+
module PointerIdentity
|
14
|
+
# @private
|
15
|
+
def to_ptr
|
16
|
+
@ptr
|
17
|
+
end
|
18
|
+
|
19
|
+
# Checks if the value is equal to other.
|
20
|
+
def ==(other)
|
21
|
+
other.respond_to?(:to_ptr) &&
|
22
|
+
@ptr == other.to_ptr
|
23
|
+
end
|
24
|
+
|
25
|
+
# Computes hash.
|
26
|
+
def hash
|
27
|
+
@ptr.address.hash
|
28
|
+
end
|
29
|
+
|
30
|
+
# Checks if the value is equivalent to other.
|
31
|
+
def eql?(other)
|
32
|
+
self == other
|
33
|
+
end
|
11
34
|
end
|
12
35
|
end
|
data/lib/llvm/analysis.rb
CHANGED
@@ -11,25 +11,22 @@ module LLVM
|
|
11
11
|
def verify
|
12
12
|
do_verification(:return_status)
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
# Verify that a module is valid, and abort the process if not.
|
16
16
|
# @return [nil]
|
17
17
|
def verify!
|
18
18
|
do_verification(:abort_process)
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
private
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
result = str.read_string if status == 1
|
27
|
-
C.dispose_message str.read_pointer
|
28
|
-
end
|
29
|
-
result
|
22
|
+
|
23
|
+
def do_verification(action)
|
24
|
+
LLVM.with_message_output do |str|
|
25
|
+
C.verify_module(self, action, str)
|
30
26
|
end
|
27
|
+
end
|
31
28
|
end
|
32
|
-
|
29
|
+
|
33
30
|
class Function
|
34
31
|
# Verify that a function is valid.
|
35
32
|
# @return [true, false]
|
data/lib/llvm/analysis_ffi.rb
CHANGED
data/lib/llvm/core.rb
CHANGED
@@ -1,12 +1,47 @@
|
|
1
1
|
require 'llvm'
|
2
2
|
require 'llvm/core_ffi'
|
3
|
+
require 'llvm/support'
|
3
4
|
|
4
5
|
module LLVM
|
5
6
|
# @private
|
6
7
|
module C
|
7
8
|
attach_function :dispose_message, :LLVMDisposeMessage, [:pointer], :void
|
8
9
|
end
|
9
|
-
|
10
|
+
|
11
|
+
# Yields a pointer suitable for storing an LLVM output message.
|
12
|
+
# If the message pointer is non-NULL (an error has happened), converts
|
13
|
+
# the result to a string and returns it. Otherwise, returns +nil+.
|
14
|
+
#
|
15
|
+
# @yield [FFI::MemoryPointer]
|
16
|
+
# @return [String, nil]
|
17
|
+
def self.with_message_output
|
18
|
+
result = nil
|
19
|
+
|
20
|
+
FFI::MemoryPointer.new(FFI.type_size(:pointer)) do |str|
|
21
|
+
yield str
|
22
|
+
|
23
|
+
msg_ptr = str.read_pointer
|
24
|
+
|
25
|
+
unless msg_ptr.null?
|
26
|
+
result = msg_ptr.read_string
|
27
|
+
C.dispose_message msg_ptr
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
result
|
32
|
+
end
|
33
|
+
|
34
|
+
# Same as #with_message_output, but raises a RuntimeError with the
|
35
|
+
# resulting message.
|
36
|
+
#
|
37
|
+
# @yield [FFI::MemoryPointer]
|
38
|
+
# @return [nil]
|
39
|
+
def self.with_error_output(&block)
|
40
|
+
error = with_message_output(&block)
|
41
|
+
|
42
|
+
raise RuntimeError, error unless error.nil?
|
43
|
+
end
|
44
|
+
|
10
45
|
require 'llvm/core/context'
|
11
46
|
require 'llvm/core/module'
|
12
47
|
require 'llvm/core/type'
|
data/lib/llvm/core/builder.rb
CHANGED
@@ -4,7 +4,7 @@ module LLVM
|
|
4
4
|
def initialize
|
5
5
|
@ptr = C.create_builder()
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def dispose
|
9
9
|
return if @ptr.nil?
|
10
10
|
C.dispose_builder(@ptr)
|
@@ -17,8 +17,9 @@ module LLVM
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# Position the builder at the given Instruction within the given BasicBlock.
|
20
|
-
#
|
21
|
-
# @param
|
20
|
+
#
|
21
|
+
# @param [LLVM::BasicBlock] block
|
22
|
+
# @param [LLVM::Instruction] instruction
|
22
23
|
# @return [LLVM::Builder]
|
23
24
|
def position(block, instruction)
|
24
25
|
raise "Block must not be nil" if block.nil?
|
@@ -27,7 +28,8 @@ module LLVM
|
|
27
28
|
end
|
28
29
|
|
29
30
|
# Positions the builder before the given Instruction.
|
30
|
-
#
|
31
|
+
#
|
32
|
+
# @param [LLVM::Instruction] instruction
|
31
33
|
# @return [LLVM::Builder]
|
32
34
|
def position_before(instruction)
|
33
35
|
raise "Instruction must not be nil" if instruction.nil?
|
@@ -36,7 +38,8 @@ module LLVM
|
|
36
38
|
end
|
37
39
|
|
38
40
|
# Positions the builder at the end of the given BasicBlock.
|
39
|
-
#
|
41
|
+
#
|
42
|
+
# @param [LLVM::BasicBlock] block
|
40
43
|
# @return [LLVM::Builder]
|
41
44
|
def position_at_end(block)
|
42
45
|
raise "Block must not be nil" if block.nil?
|
@@ -45,6 +48,7 @@ module LLVM
|
|
45
48
|
end
|
46
49
|
|
47
50
|
# The BasicBlock at which the Builder is currently positioned.
|
51
|
+
#
|
48
52
|
# @return [LLVM::BasicBlock]
|
49
53
|
def insert_block
|
50
54
|
BasicBlock.from_ptr(C.get_insert_block(self))
|
@@ -434,7 +438,7 @@ module LLVM
|
|
434
438
|
end
|
435
439
|
|
436
440
|
# Builds a inbounds getelementptr instruction. If the indices are outside
|
437
|
-
# the allocated pointer the value is undefined.
|
441
|
+
# the allocated pointer the value is undefined.
|
438
442
|
# @param [LLVM::Value] ptr A pointer to an aggregate value
|
439
443
|
# @param [Array<LLVM::Value>] indices Ruby array of LLVM::Value representing
|
440
444
|
# indices into the aggregate
|
@@ -452,11 +456,12 @@ module LLVM
|
|
452
456
|
end
|
453
457
|
|
454
458
|
# Builds a struct getelementptr Instruction.
|
455
|
-
#
|
456
|
-
# @param
|
459
|
+
#
|
460
|
+
# @param [LLVM::Value] pointer A pointer to a structure
|
461
|
+
# @param [LLVM::Value] idx Unsigned integer representing the index of a
|
457
462
|
# structure member
|
458
|
-
# @param
|
459
|
-
# @return [LLVM::Instruction]
|
463
|
+
# @param [String] name The name of the result in LLVM IR
|
464
|
+
# @return [LLVM::Instruction] The resulting pointer
|
460
465
|
# @LLVMinst gep
|
461
466
|
# @see http://llvm.org/docs/GetElementPtr.html
|
462
467
|
def struct_gep(pointer, idx, name = "")
|
@@ -484,7 +489,7 @@ module LLVM
|
|
484
489
|
# @param [LLVM::Value] val Integer or vector of integers to be truncated
|
485
490
|
# @param [LLVM::Type, #type] ty Integer or vector of integers of equal size
|
486
491
|
# to val
|
487
|
-
# @param [String] name The name of the result in LLVM IR
|
492
|
+
# @param [String] name The name of the result in LLVM IR
|
488
493
|
# @return [LLVM::Instruction] The truncated value
|
489
494
|
# @LLVMinst trunc
|
490
495
|
def trunc(val, ty, name = "")
|
@@ -496,7 +501,7 @@ module LLVM
|
|
496
501
|
# @param [LLVM::Value] val Integer or vector of integers to be extended
|
497
502
|
# @param [LLVM::Type, #type] ty Integer or vector of integer type of
|
498
503
|
# greater size than val
|
499
|
-
# @param [String] name The name of the result in LLVM IR
|
504
|
+
# @param [String] name The name of the result in LLVM IR
|
500
505
|
# @return [LLVM::Instruction] The extended value
|
501
506
|
# @LLVMinst zext
|
502
507
|
def zext(val, ty, name = "")
|
@@ -508,7 +513,7 @@ module LLVM
|
|
508
513
|
# @param [LLVM::Value] val Integer or vector of integers to be extended
|
509
514
|
# @param [LLVM::Type] ty Integer or vector of integer type of greater size
|
510
515
|
# than the size of val
|
511
|
-
# @param [String] name The name of the result in LLVM IR
|
516
|
+
# @param [String] name The name of the result in LLVM IR
|
512
517
|
# @return [LLVM::Instruction] The extended value
|
513
518
|
# @LLVMinst sext
|
514
519
|
def sext(val, ty, name = "")
|
@@ -741,7 +746,8 @@ module LLVM
|
|
741
746
|
|
742
747
|
# Builds a call Instruction. Calls the given Function with the given
|
743
748
|
# args (Instructions).
|
744
|
-
#
|
749
|
+
#
|
750
|
+
# @param [LLVM::Function] fun
|
745
751
|
# @param [Array<LLVM::Value>] args
|
746
752
|
# @param [LLVM::Instruction]
|
747
753
|
# @LLVMinst call
|
data/lib/llvm/core/module.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
module LLVM
|
1
|
+
module LLVM
|
2
2
|
class Module
|
3
|
+
include PointerIdentity
|
4
|
+
|
3
5
|
# @private
|
4
6
|
def self.from_ptr(ptr)
|
5
7
|
return if ptr.null?
|
@@ -7,111 +9,113 @@ module LLVM
|
|
7
9
|
mod.instance_variable_set(:@ptr, ptr)
|
8
10
|
mod
|
9
11
|
end
|
10
|
-
|
12
|
+
|
11
13
|
# Important: Call #dispose to free backend memory after use, but not when using JITCompiler with this module.
|
12
14
|
def initialize(name)
|
13
15
|
@ptr = C.module_create_with_name(name)
|
14
16
|
end
|
15
|
-
|
17
|
+
|
16
18
|
def dispose
|
17
19
|
return if @ptr.nil?
|
18
20
|
C.dispose_module(@ptr)
|
19
21
|
@ptr = nil
|
20
22
|
end
|
21
|
-
|
22
|
-
#
|
23
|
-
|
24
|
-
|
23
|
+
|
24
|
+
# Get module triple.
|
25
|
+
#
|
26
|
+
# @return [String]
|
27
|
+
def triple
|
28
|
+
C.get_target(self)
|
25
29
|
end
|
26
|
-
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
|
31
|
+
# Set module triple.
|
32
|
+
#
|
33
|
+
# @param [String] triple
|
34
|
+
def triple=(triple)
|
35
|
+
C.set_target(self, triple.to_s)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Get module data layout.
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
def data_layout
|
42
|
+
C.get_data_layout(self)
|
35
43
|
end
|
36
44
|
|
37
|
-
#
|
38
|
-
|
39
|
-
|
45
|
+
# Set module data layout.
|
46
|
+
#
|
47
|
+
# @param [String, TargetDataLayout] data_layout
|
48
|
+
def data_layout=(data_layout)
|
49
|
+
C.set_data_layout(self, data_layout.to_s)
|
40
50
|
end
|
41
51
|
|
42
52
|
# Returns a TypeCollection of all the Types in the module.
|
43
53
|
def types
|
44
54
|
@types ||= TypeCollection.new(self)
|
45
55
|
end
|
46
|
-
|
56
|
+
|
47
57
|
class TypeCollection
|
48
58
|
def initialize(mod)
|
49
59
|
@module = mod
|
50
60
|
end
|
51
|
-
|
61
|
+
|
52
62
|
# Returns the Type with the given name (symbol or string).
|
53
63
|
def named(name)
|
54
64
|
Type.from_ptr(C.get_type_by_name(@module, name.to_s), nil)
|
55
65
|
end
|
56
|
-
|
57
|
-
|
58
|
-
def [](key)
|
59
|
-
named(key)
|
60
|
-
end
|
61
|
-
|
62
|
-
# Adds the given Type to the collection with a name equal to key (symbol or string).
|
63
|
-
def []=(key, type)
|
64
|
-
add(key, type)
|
65
|
-
end
|
66
|
+
|
67
|
+
alias [] named
|
66
68
|
end
|
67
|
-
|
69
|
+
|
68
70
|
# Returns an Enumerable of all the GlobalVariables in the module.
|
69
71
|
def globals
|
70
72
|
@globals ||= GlobalCollection.new(self)
|
71
73
|
end
|
72
|
-
|
74
|
+
|
73
75
|
class GlobalCollection
|
74
76
|
include Enumerable
|
75
|
-
|
77
|
+
|
76
78
|
def initialize(mod)
|
77
79
|
@module = mod
|
78
80
|
end
|
79
|
-
|
81
|
+
|
80
82
|
# Adds a GlobalVariable with the given type and name to the collection (symbol or string).
|
81
83
|
def add(ty, name)
|
82
|
-
GlobalVariable.from_ptr(C.add_global(@module, LLVM::Type(ty), name.to_s))
|
84
|
+
GlobalVariable.from_ptr(C.add_global(@module, LLVM::Type(ty), name.to_s)).tap do |gvar|
|
85
|
+
yield gvar if block_given?
|
86
|
+
end
|
83
87
|
end
|
84
|
-
|
88
|
+
|
85
89
|
# Returns the GlobalVariable with the given name (symbol or string).
|
86
90
|
def named(name)
|
87
91
|
GlobalValue.from_ptr(C.get_named_global(@module, name.to_s))
|
88
92
|
end
|
89
|
-
|
93
|
+
|
90
94
|
# Returns the first GlobalVariable in the collection.
|
91
95
|
def first
|
92
96
|
GlobalValue.from_ptr(C.get_first_global(@module))
|
93
97
|
end
|
94
|
-
|
98
|
+
|
95
99
|
# Returns the last GlobalVariable in the collection.
|
96
100
|
def last
|
97
101
|
GlobalValue.from_ptr(C.get_last_global(@module))
|
98
102
|
end
|
99
|
-
|
103
|
+
|
100
104
|
# Returns the next GlobalVariable in the collection after global.
|
101
105
|
def next(global)
|
102
106
|
GlobalValue.from_ptr(C.get_next_global(global))
|
103
107
|
end
|
104
|
-
|
108
|
+
|
105
109
|
# Returns the previous GlobalVariable in the collection before global.
|
106
110
|
def previous(global)
|
107
111
|
GlobalValue.from_ptr(C.get_previous_global(global))
|
108
112
|
end
|
109
|
-
|
113
|
+
|
110
114
|
# Deletes the GlobalVariable from the collection.
|
111
115
|
def delete(global)
|
112
116
|
C.delete_global(global)
|
113
117
|
end
|
114
|
-
|
118
|
+
|
115
119
|
# Returns the GlobalVariable with a name equal to key (symbol or string) or at key (integer).
|
116
120
|
def [](key)
|
117
121
|
case key
|
@@ -126,7 +130,7 @@ module LLVM
|
|
126
130
|
g
|
127
131
|
end
|
128
132
|
end
|
129
|
-
|
133
|
+
|
130
134
|
# Iterates through each GlobalVariable in the collection.
|
131
135
|
def each
|
132
136
|
g = first
|
@@ -136,19 +140,19 @@ module LLVM
|
|
136
140
|
end
|
137
141
|
end
|
138
142
|
end
|
139
|
-
|
143
|
+
|
140
144
|
# Returns a FunctionCollection of all the Functions in the module.
|
141
145
|
def functions
|
142
146
|
@functions ||= FunctionCollection.new(self)
|
143
147
|
end
|
144
|
-
|
148
|
+
|
145
149
|
class FunctionCollection
|
146
150
|
include Enumerable
|
147
|
-
|
151
|
+
|
148
152
|
def initialize(mod)
|
149
153
|
@module = mod
|
150
154
|
end
|
151
|
-
|
155
|
+
|
152
156
|
# Adds a Function with the given name (symbol or string) and args (Types).
|
153
157
|
def add(name, *args)
|
154
158
|
if args.first.kind_of? FunctionType
|
@@ -157,45 +161,45 @@ module LLVM
|
|
157
161
|
type = Type.function(*args)
|
158
162
|
end
|
159
163
|
function = Function.from_ptr(C.add_function(@module, name.to_s, type))
|
160
|
-
|
164
|
+
|
161
165
|
if block_given?
|
162
166
|
params = (0...function.params.size).map { |i| function.params[i] }
|
163
167
|
yield function, *params
|
164
168
|
end
|
165
|
-
|
166
|
-
function
|
169
|
+
|
170
|
+
function
|
167
171
|
end
|
168
|
-
|
172
|
+
|
169
173
|
# Returns the Function with the given name (symbol or string).
|
170
174
|
def named(name)
|
171
175
|
Function.from_ptr(C.get_named_function(@module, name.to_s))
|
172
176
|
end
|
173
|
-
|
177
|
+
|
174
178
|
# Returns the first Function in the collection.
|
175
179
|
def first
|
176
180
|
Function.from_ptr(C.get_first_function(@module))
|
177
181
|
end
|
178
|
-
|
182
|
+
|
179
183
|
# Returns the last Function in the collection.
|
180
184
|
def last
|
181
185
|
Function.from_ptr(C.get_last_function(@module))
|
182
186
|
end
|
183
|
-
|
187
|
+
|
184
188
|
# Returns the next Function in the collection after function.
|
185
189
|
def next(function)
|
186
190
|
Function.from_ptr(C.get_next_function(function))
|
187
191
|
end
|
188
|
-
|
192
|
+
|
189
193
|
# Returns the previous Function in the collection before function.
|
190
194
|
def previous(function)
|
191
195
|
Function.from_ptr(C.get_previous_function(function))
|
192
196
|
end
|
193
|
-
|
197
|
+
|
194
198
|
# Deletes the Function from the collection.
|
195
199
|
def delete(function)
|
196
200
|
C.delete_function(function)
|
197
201
|
end
|
198
|
-
|
202
|
+
|
199
203
|
# Returns the Function with a name equal to key (symbol or string) or at key (integer).
|
200
204
|
def [](key)
|
201
205
|
case key
|
@@ -210,7 +214,7 @@ module LLVM
|
|
210
214
|
f
|
211
215
|
end
|
212
216
|
end
|
213
|
-
|
217
|
+
|
214
218
|
# Iterates through each Function in the collection.
|
215
219
|
def each
|
216
220
|
f = first
|
@@ -220,10 +224,30 @@ module LLVM
|
|
220
224
|
end
|
221
225
|
end
|
222
226
|
end
|
223
|
-
|
224
|
-
# Print the module's IR to
|
225
|
-
|
226
|
-
|
227
|
+
|
228
|
+
# Print the module's IR to the given IO object or integer file descriptor.
|
229
|
+
#
|
230
|
+
# The IO object#fileno must not be nil. If fd_or_io is nil or omitted,
|
231
|
+
# dump the module to the output stream for debugging (stderr).
|
232
|
+
def dump(fd_or_io=nil)
|
233
|
+
if fd_or_io.nil?
|
234
|
+
C.dump_module(self)
|
235
|
+
else
|
236
|
+
fd = if fd_or_io.kind_of? ::Integer
|
237
|
+
fd_or_io
|
238
|
+
elsif fd_or_io.respond_to? :fileno
|
239
|
+
fd_or_io.fileno
|
240
|
+
end
|
241
|
+
|
242
|
+
raise ArgumentError, 'Expected IO object or Integer file descriptor' if fd.nil?
|
243
|
+
Support::C.print_module(
|
244
|
+
self,
|
245
|
+
fd,
|
246
|
+
0, # should_close=false : not be closed automatically
|
247
|
+
0 # unbuffered=false : buffered internally
|
248
|
+
)
|
249
|
+
end
|
227
250
|
end
|
251
|
+
|
228
252
|
end
|
229
253
|
end
|