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
@@ -2,64 +2,68 @@ module LLVM
|
|
2
2
|
# The PassManager runs a queue of passes on a module. See
|
3
3
|
# http://llvm.org/docs/Passes.html for the list of available passes.
|
4
4
|
class PassManager
|
5
|
-
# Creates a new pass manager
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@ptr
|
11
|
-
|
12
|
-
do_initialization
|
5
|
+
# Creates a new pass manager.
|
6
|
+
#
|
7
|
+
# @param [LLVM::ExecutionEngine, LLVM::TargetMachine] machine
|
8
|
+
def initialize(machine)
|
9
|
+
@ptr = C.create_pass_manager()
|
10
|
+
C.add_target_data(machine.data_layout, @ptr)
|
13
11
|
end
|
14
|
-
|
12
|
+
|
15
13
|
# @private
|
16
14
|
def to_ptr
|
17
15
|
@ptr
|
18
16
|
end
|
19
|
-
|
17
|
+
|
20
18
|
# Append a pass to the pass queue.
|
21
|
-
#
|
19
|
+
#
|
20
|
+
# @param [Symbol] name
|
22
21
|
# @return [LLVM::PassManager]
|
23
22
|
def <<(name)
|
24
23
|
send(:"#{name}!")
|
24
|
+
|
25
25
|
self
|
26
26
|
end
|
27
27
|
|
28
28
|
# Run the pass queue on the given module.
|
29
|
-
#
|
29
|
+
#
|
30
|
+
# @param [LLVM::Module] mod
|
30
31
|
# @return [true, false] Indicates whether the module was modified.
|
31
32
|
def run(mod)
|
32
33
|
C.run_pass_manager(self, mod) != 0
|
33
34
|
end
|
34
|
-
|
35
|
+
|
35
36
|
# Disposes the pass manager.
|
36
37
|
def dispose
|
37
38
|
return if @ptr.nil?
|
38
|
-
|
39
|
+
|
40
|
+
finalize
|
41
|
+
|
39
42
|
C.dispose_pass_manager(@ptr)
|
40
43
|
@ptr = nil
|
41
44
|
end
|
42
45
|
|
43
46
|
protected
|
44
47
|
|
45
|
-
def
|
46
|
-
end
|
47
|
-
|
48
|
-
def do_finalization
|
48
|
+
def finalize
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
class FunctionPassManager < PassManager
|
53
|
-
# Creates a new pass manager
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
@ptr =
|
53
|
+
# Creates a new function pass manager.
|
54
|
+
#
|
55
|
+
# @param [LLVM::ExecutionEngine, LLVM::TargetMachine] machine
|
56
|
+
# @param [LLVM::Module] mod
|
57
|
+
def initialize(machine, mod)
|
58
|
+
@ptr = C.create_function_pass_manager_for_module(mod)
|
59
|
+
C.add_target_data(machine.data_layout, @ptr)
|
60
|
+
|
61
|
+
C.initialize_function_pass_manager(self) != 0
|
59
62
|
end
|
60
63
|
|
61
64
|
# Run the pass queue on the given function.
|
62
|
-
#
|
65
|
+
#
|
66
|
+
# @param [LLVM::Function] fn
|
63
67
|
# @return [true, false] indicates whether the function was modified.
|
64
68
|
def run(fn)
|
65
69
|
C.run_function_pass_manager(self, fn) != 0
|
@@ -67,11 +71,7 @@ module LLVM
|
|
67
71
|
|
68
72
|
protected
|
69
73
|
|
70
|
-
def
|
71
|
-
C.initialize_function_pass_manager(self) != 0
|
72
|
-
end
|
73
|
-
|
74
|
-
def do_finalization
|
74
|
+
def finalize
|
75
75
|
C.finalize_function_pass_manager(self) != 0
|
76
76
|
end
|
77
77
|
end
|
data/lib/llvm/core/type.rb
CHANGED
@@ -1,27 +1,20 @@
|
|
1
|
-
module LLVM
|
1
|
+
module LLVM
|
2
2
|
class Type
|
3
|
+
include PointerIdentity
|
4
|
+
|
3
5
|
# @private
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@ptr == type.to_ptr
|
13
|
-
else
|
14
|
-
false
|
6
|
+
def self.from_ptr(ptr, kind)
|
7
|
+
return if ptr.null?
|
8
|
+
kind ||= C.get_type_kind(ptr)
|
9
|
+
ty = case kind
|
10
|
+
when :integer then IntType.allocate
|
11
|
+
when :function then FunctionType.allocate
|
12
|
+
when :struct then StructType.allocate
|
13
|
+
else allocate
|
15
14
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
@ptr.address.hash
|
20
|
-
end
|
21
|
-
|
22
|
-
# Checks if the type is equal to other.
|
23
|
-
def eql?(other)
|
24
|
-
other.instance_of?(self.class) && self == other
|
15
|
+
ty.instance_variable_set(:@ptr, ptr)
|
16
|
+
ty.instance_variable_set(:@kind, kind)
|
17
|
+
ty
|
25
18
|
end
|
26
19
|
|
27
20
|
# Returns a symbol representation of the types kind (ex. :pointer, :vector, :array.)
|
@@ -33,7 +26,7 @@ module LLVM
|
|
33
26
|
def size
|
34
27
|
LLVM::Int64.from_ptr(C.size_of(self))
|
35
28
|
end
|
36
|
-
|
29
|
+
|
37
30
|
def align
|
38
31
|
LLVM::Int64.from_ptr(C.align_of(self))
|
39
32
|
end
|
@@ -60,38 +53,28 @@ module LLVM
|
|
60
53
|
def pointer(address_space = 0)
|
61
54
|
Type.pointer(self, address_space)
|
62
55
|
end
|
63
|
-
|
64
|
-
#
|
65
|
-
def
|
66
|
-
|
67
|
-
kind ||= C.get_type_kind(ptr)
|
68
|
-
ty = case kind
|
69
|
-
when :integer then IntType.allocate
|
70
|
-
when :function then FunctionType.allocate
|
71
|
-
when :struct then StructType.allocate
|
72
|
-
else allocate
|
73
|
-
end
|
74
|
-
ty.instance_variable_set(:@ptr, ptr)
|
75
|
-
ty.instance_variable_set(:@kind, kind)
|
76
|
-
ty
|
56
|
+
|
57
|
+
# Print the type's representation to stdout.
|
58
|
+
def dump
|
59
|
+
Support::C.dump_type(self)
|
77
60
|
end
|
78
|
-
|
61
|
+
|
79
62
|
# Creates an array type of Type with the given size.
|
80
63
|
def self.array(ty, sz = 0)
|
81
64
|
from_ptr(C.array_type(LLVM::Type(ty), sz), :array)
|
82
65
|
end
|
83
|
-
|
66
|
+
|
84
67
|
# Creates the pointer type of Type with the given address space.
|
85
68
|
def self.pointer(ty, address_space = 0)
|
86
69
|
from_ptr(C.pointer_type(LLVM::Type(ty), address_space), :pointer)
|
87
70
|
end
|
88
|
-
|
71
|
+
|
89
72
|
# Creates a vector type of Type with the given element count.
|
90
73
|
def self.vector(ty, element_count)
|
91
74
|
from_ptr(C.vector_type(LLVM::Type(ty), element_count), :vector)
|
92
75
|
end
|
93
|
-
|
94
|
-
# Creates a function type. Takes an array of argument Types and the result Type. The only option is <tt>:varargs</tt>,
|
76
|
+
|
77
|
+
# Creates a function type. Takes an array of argument Types and the result Type. The only option is <tt>:varargs</tt>,
|
95
78
|
# which when set to true makes the function type take a variable number of args.
|
96
79
|
def self.function(arg_types, result_type, options = {})
|
97
80
|
arg_types.map! { |ty| LLVM::Type(ty) }
|
@@ -99,7 +82,7 @@ module LLVM
|
|
99
82
|
arg_types_ptr.write_array_of_pointer(arg_types)
|
100
83
|
from_ptr(C.function_type(LLVM::Type(result_type), arg_types_ptr, arg_types.size, options[:varargs] ? 1 : 0), :function)
|
101
84
|
end
|
102
|
-
|
85
|
+
|
103
86
|
# Creates a struct type with the given array of element types.
|
104
87
|
def self.struct(elt_types, is_packed, name = nil)
|
105
88
|
elt_types.map! { |ty| LLVM::Type(ty) }
|
@@ -152,13 +135,13 @@ module LLVM
|
|
152
135
|
C.LLVMIsFunctionVarArg(self)
|
153
136
|
end
|
154
137
|
end
|
155
|
-
|
138
|
+
|
156
139
|
class StructType < Type
|
157
140
|
# Returns the name of the struct.
|
158
141
|
def name
|
159
142
|
C.get_struct_name(self)
|
160
143
|
end
|
161
|
-
|
144
|
+
|
162
145
|
# Returns the element types of the struct.
|
163
146
|
def element_types
|
164
147
|
count = C.count_struct_element_types(self)
|
@@ -169,7 +152,7 @@ module LLVM
|
|
169
152
|
end
|
170
153
|
elt_types
|
171
154
|
end
|
172
|
-
|
155
|
+
|
173
156
|
# Sets the struct body.
|
174
157
|
def element_types=(elt_types)
|
175
158
|
elt_types.map! { |ty| LLVM::Type(ty) }
|
@@ -180,7 +163,7 @@ module LLVM
|
|
180
163
|
end
|
181
164
|
|
182
165
|
module_function
|
183
|
-
|
166
|
+
|
184
167
|
# Creates a Type from the given object.
|
185
168
|
def Type(ty)
|
186
169
|
case ty
|
@@ -188,27 +171,27 @@ module LLVM
|
|
188
171
|
else ty.type
|
189
172
|
end
|
190
173
|
end
|
191
|
-
|
174
|
+
|
192
175
|
# Shortcut to Type.array.
|
193
176
|
def Array(ty, sz = 0)
|
194
177
|
LLVM::Type.array(ty, sz)
|
195
178
|
end
|
196
|
-
|
179
|
+
|
197
180
|
# Shortcut to Type.pointer.
|
198
181
|
def Pointer(ty)
|
199
182
|
LLVM::Type.pointer(ty)
|
200
183
|
end
|
201
|
-
|
184
|
+
|
202
185
|
# Shortcut to Type.vector.
|
203
186
|
def Vector(ty, sz)
|
204
187
|
LLVM::Type.vector(ty, sz)
|
205
188
|
end
|
206
|
-
|
189
|
+
|
207
190
|
# Shortcut to Type.function.
|
208
191
|
def Function(argtypes, rettype, options = {})
|
209
192
|
LLVM::Type.function(argtypes, rettype, options)
|
210
193
|
end
|
211
|
-
|
194
|
+
|
212
195
|
# Shortcut to Type.struct.
|
213
196
|
def Struct(*elt_types)
|
214
197
|
name = if elt_types.last.is_a? String
|
data/lib/llvm/core/value.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module LLVM
|
2
2
|
class Value
|
3
|
+
include PointerIdentity
|
4
|
+
|
3
5
|
# @private
|
4
6
|
def self.from_ptr(ptr)
|
5
7
|
return if ptr.null?
|
@@ -8,30 +10,6 @@ module LLVM
|
|
8
10
|
val
|
9
11
|
end
|
10
12
|
|
11
|
-
# @private
|
12
|
-
def to_ptr
|
13
|
-
@ptr
|
14
|
-
end
|
15
|
-
|
16
|
-
# Checks if the value is equal to other.
|
17
|
-
def ==(other)
|
18
|
-
case other
|
19
|
-
when LLVM::Value
|
20
|
-
@ptr == other.to_ptr
|
21
|
-
else
|
22
|
-
false
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def hash
|
27
|
-
@ptr.address.hash
|
28
|
-
end
|
29
|
-
|
30
|
-
# Checks if the value is equal to other.
|
31
|
-
def eql?(other)
|
32
|
-
other.instance_of?(self.class) && self == other
|
33
|
-
end
|
34
|
-
|
35
13
|
# Returns the Value type. This is abstract and is overidden by its subclasses.
|
36
14
|
def self.type
|
37
15
|
raise NotImplementedError, "#{self.name}.type() is abstract."
|
@@ -313,10 +291,12 @@ module LLVM
|
|
313
291
|
end
|
314
292
|
|
315
293
|
# Boolean negation.
|
316
|
-
def
|
294
|
+
def ~@
|
317
295
|
self.class.from_ptr(C.const_not(self))
|
318
296
|
end
|
319
297
|
|
298
|
+
alias not ~
|
299
|
+
|
320
300
|
# Addition.
|
321
301
|
def +(rhs)
|
322
302
|
self.class.from_ptr(C.const_add(self, rhs))
|
@@ -594,6 +574,14 @@ module LLVM
|
|
594
574
|
def global_constant=(flag)
|
595
575
|
C.set_global_constant(self, flag)
|
596
576
|
end
|
577
|
+
|
578
|
+
def unnamed_addr?
|
579
|
+
Support::C.has_unnamed_addr(self) != 0
|
580
|
+
end
|
581
|
+
|
582
|
+
def unnamed_addr=(flag)
|
583
|
+
Support::C.set_unnamed_addr(self, flag ? 1 : 0)
|
584
|
+
end
|
597
585
|
end
|
598
586
|
|
599
587
|
class Function < GlobalValue
|
data/lib/llvm/core_ffi.rb
CHANGED
@@ -4,7 +4,7 @@ require 'ffi'
|
|
4
4
|
|
5
5
|
module LLVM::C
|
6
6
|
extend FFI::Library
|
7
|
-
ffi_lib 'LLVM-3.
|
7
|
+
ffi_lib 'LLVM-3.2'
|
8
8
|
|
9
9
|
def self.attach_function(name, *_)
|
10
10
|
begin; super; rescue FFI::NotFoundError => e
|
@@ -39,7 +39,7 @@ module LLVM::C
|
|
39
39
|
layout :dummy, :char
|
40
40
|
end
|
41
41
|
|
42
|
-
# Represents a basic block of
|
42
|
+
# Represents a basic block of instructions in LLVM IR.
|
43
43
|
#
|
44
44
|
# This models llvm::BasicBlock.
|
45
45
|
class OpaqueBasicBlock < FFI::Struct
|
@@ -430,9 +430,11 @@ module LLVM::C
|
|
430
430
|
#
|
431
431
|
# :link_once_odr ::
|
432
432
|
# < Keep one copy of function when linking (inline)
|
433
|
-
# :
|
433
|
+
# :link_once_odr_auto_hide ::
|
434
434
|
# < Same, but only replaced by something
|
435
435
|
# equivalent.
|
436
|
+
# :weak_any ::
|
437
|
+
# < Like LinkOnceODR, but possibly hidden.
|
436
438
|
# :weak_odr ::
|
437
439
|
# < Keep one copy of function when linking (weak)
|
438
440
|
# :appending ::
|
@@ -457,8 +459,6 @@ module LLVM::C
|
|
457
459
|
# < Tentative definitions
|
458
460
|
# :linker_private_weak ::
|
459
461
|
# < Like Private, but linker removes.
|
460
|
-
# :linker_private_weak_def_auto ::
|
461
|
-
# < Like LinkerPrivate, but is weak.
|
462
462
|
#
|
463
463
|
# @method _enum_linkage_
|
464
464
|
# @return [Symbol]
|
@@ -468,19 +468,19 @@ module LLVM::C
|
|
468
468
|
:available_externally, 1,
|
469
469
|
:link_once_any, 2,
|
470
470
|
:link_once_odr, 3,
|
471
|
-
:
|
472
|
-
:
|
473
|
-
:
|
474
|
-
:
|
475
|
-
:
|
476
|
-
:
|
477
|
-
:
|
478
|
-
:
|
479
|
-
:
|
480
|
-
:
|
481
|
-
:
|
482
|
-
:
|
483
|
-
:
|
471
|
+
:link_once_odr_auto_hide, 4,
|
472
|
+
:weak_any, 5,
|
473
|
+
:weak_odr, 6,
|
474
|
+
:appending, 7,
|
475
|
+
:internal, 8,
|
476
|
+
:private, 9,
|
477
|
+
:dll_import, 10,
|
478
|
+
:dll_export, 11,
|
479
|
+
:external_weak, 12,
|
480
|
+
:ghost, 13,
|
481
|
+
:common, 14,
|
482
|
+
:linker_private, 15,
|
483
|
+
:linker_private_weak, 16
|
484
484
|
]
|
485
485
|
|
486
486
|
# (Not documented)
|
@@ -803,6 +803,19 @@ module LLVM::C
|
|
803
803
|
# @scope class
|
804
804
|
attach_function :dump_module, :LLVMDumpModule, [OpaqueModule], :void
|
805
805
|
|
806
|
+
# Print a representation of a module to a file. The ErrorMessage needs to be
|
807
|
+
# disposed with LLVMDisposeMessage. Returns 0 on success, 1 otherwise.
|
808
|
+
#
|
809
|
+
# @see Module::print()
|
810
|
+
#
|
811
|
+
# @method print_module_to_file(m, filename, error_message)
|
812
|
+
# @param [OpaqueModule] m
|
813
|
+
# @param [String] filename
|
814
|
+
# @param [FFI::Pointer(**CharS)] error_message
|
815
|
+
# @return [Integer]
|
816
|
+
# @scope class
|
817
|
+
attach_function :print_module_to_file, :LLVMPrintModuleToFile, [OpaqueModule, :string, :pointer], :int
|
818
|
+
|
806
819
|
# Set inline assembly for a module.
|
807
820
|
#
|
808
821
|
# @see Module::setModuleInlineAsm()
|
@@ -2092,7 +2105,7 @@ module LLVM::C
|
|
2092
2105
|
#
|
2093
2106
|
# Uses are obtained in an iterator fashion. First, call this function
|
2094
2107
|
# to obtain a reference to the first use. Then, call LLVMGetNextUse()
|
2095
|
-
# on that instance and all subsequently obtained instances
|
2108
|
+
# on that instance and all subsequently obtained instances until
|
2096
2109
|
# LLVMGetNextUse() returns NULL.
|
2097
2110
|
#
|
2098
2111
|
# @see llvm::Value::use_begin()
|
@@ -3465,7 +3478,7 @@ module LLVM::C
|
|
3465
3478
|
# Set the alignment for a function parameter.
|
3466
3479
|
#
|
3467
3480
|
# @see llvm::Argument::addAttr()
|
3468
|
-
# @see llvm::
|
3481
|
+
# @see llvm::AttrBuilder::addAlignmentAttr()
|
3469
3482
|
#
|
3470
3483
|
# @method set_param_alignment(arg, align)
|
3471
3484
|
# @param [OpaqueValue] arg
|
@@ -3533,6 +3546,34 @@ module LLVM::C
|
|
3533
3546
|
# @scope class
|
3534
3547
|
attach_function :get_md_string, :LLVMGetMDString, [OpaqueValue, :pointer], :string
|
3535
3548
|
|
3549
|
+
# Obtain the number of operands from an MDNode value.
|
3550
|
+
#
|
3551
|
+
# @param V MDNode to get number of operands from.
|
3552
|
+
# @return Number of operands of the MDNode.
|
3553
|
+
#
|
3554
|
+
# @method get_md_node_num_operands(v)
|
3555
|
+
# @param [OpaqueValue] v
|
3556
|
+
# @return [Integer]
|
3557
|
+
# @scope class
|
3558
|
+
attach_function :get_md_node_num_operands, :LLVMGetMDNodeNumOperands, [OpaqueValue], :uint
|
3559
|
+
|
3560
|
+
# Obtain the given MDNode's operands.
|
3561
|
+
#
|
3562
|
+
# The passed LLVMValueRef pointer should point to enough memory to hold all of
|
3563
|
+
# the operands of the given MDNode (see LLVMGetMDNodeNumOperands) as
|
3564
|
+
# LLVMValueRefs. This memory will be populated with the LLVMValueRefs of the
|
3565
|
+
# MDNode's operands.
|
3566
|
+
#
|
3567
|
+
# @param V MDNode to get the operands from.
|
3568
|
+
# @param Dest Destination array for operands.
|
3569
|
+
#
|
3570
|
+
# @method get_md_node_operands(v, dest)
|
3571
|
+
# @param [OpaqueValue] v
|
3572
|
+
# @param [FFI::Pointer(*ValueRef)] dest
|
3573
|
+
# @return [nil]
|
3574
|
+
# @scope class
|
3575
|
+
attach_function :get_md_node_operands, :LLVMGetMDNodeOperands, [OpaqueValue, :pointer], :void
|
3576
|
+
|
3536
3577
|
# Convert a basic block instance to a value type.
|
3537
3578
|
#
|
3538
3579
|
# @method basic_block_as_value(bb)
|
@@ -3825,7 +3866,7 @@ module LLVM::C
|
|
3825
3866
|
# @scope class
|
3826
3867
|
attach_function :get_next_instruction, :LLVMGetNextInstruction, [OpaqueValue], OpaqueValue
|
3827
3868
|
|
3828
|
-
# Obtain the instruction that
|
3869
|
+
# Obtain the instruction that occurred before this one.
|
3829
3870
|
#
|
3830
3871
|
# If the instruction is the first instruction in a basic block, NULL
|
3831
3872
|
# will be returned.
|