ruby-llvm 3.1.0.beta.1 → 3.2.0.beta.1
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.
- 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
|