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
@@ -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.
|