waj-ruby-llvm 2.9.2
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/README.rdoc +31 -0
- data/ext/ruby-llvm-support/Makefile.am +1 -0
- data/ext/ruby-llvm-support/Makefile.in +612 -0
- data/ext/ruby-llvm-support/config.guess +1500 -0
- data/ext/ruby-llvm-support/config.sub +1616 -0
- data/ext/ruby-llvm-support/configure +17190 -0
- data/ext/ruby-llvm-support/configure.ac +16 -0
- data/ext/ruby-llvm-support/depcomp +584 -0
- data/ext/ruby-llvm-support/install-sh +507 -0
- data/ext/ruby-llvm-support/libtool +9403 -0
- data/ext/ruby-llvm-support/ltmain.sh +8745 -0
- data/ext/ruby-llvm-support/missing +367 -0
- data/ext/ruby-llvm-support/src/Makefile.am +5 -0
- data/ext/ruby-llvm-support/src/Makefile.in +472 -0
- data/ext/ruby-llvm-support/src/support.cpp +12 -0
- data/lib/llvm.rb +12 -0
- data/lib/llvm/analysis.rb +62 -0
- data/lib/llvm/core.rb +598 -0
- data/lib/llvm/core/bitcode.rb +88 -0
- data/lib/llvm/core/builder.rb +851 -0
- data/lib/llvm/core/context.rb +22 -0
- data/lib/llvm/core/module.rb +232 -0
- data/lib/llvm/core/pass_manager.rb +76 -0
- data/lib/llvm/core/type.rb +173 -0
- data/lib/llvm/core/value.rb +782 -0
- data/lib/llvm/execution_engine.rb +169 -0
- data/lib/llvm/support.rb +22 -0
- data/lib/llvm/target.rb +9 -0
- data/lib/llvm/transforms/ipo.rb +23 -0
- data/lib/llvm/transforms/scalar.rb +136 -0
- data/test/array_test.rb +38 -0
- data/test/basic_block_test.rb +88 -0
- data/test/basic_test.rb +11 -0
- data/test/binary_operations_test.rb +58 -0
- data/test/bitcode_test.rb +25 -0
- data/test/branch_test.rb +57 -0
- data/test/call_test.rb +82 -0
- data/test/comparisons_test.rb +66 -0
- data/test/conversions_test.rb +86 -0
- data/test/double_test.rb +33 -0
- data/test/equality_test.rb +91 -0
- data/test/generic_value_test.rb +22 -0
- data/test/instruction_test.rb +32 -0
- data/test/ipo_test.rb +53 -0
- data/test/memory_access_test.rb +38 -0
- data/test/module_test.rb +21 -0
- data/test/parameter_collection_test.rb +28 -0
- data/test/phi_test.rb +33 -0
- data/test/select_test.rb +22 -0
- data/test/struct_test.rb +75 -0
- data/test/test_helper.rb +50 -0
- data/test/type_test.rb +15 -0
- data/test/vector_test.rb +64 -0
- metadata +133 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
module LLVM
|
2
|
+
class Context
|
3
|
+
def initialize
|
4
|
+
@ptr = C.LLVMContextCreate()
|
5
|
+
end
|
6
|
+
|
7
|
+
# @private
|
8
|
+
def to_ptr
|
9
|
+
@ptr
|
10
|
+
end
|
11
|
+
|
12
|
+
# Obtains a reference to the global Context.
|
13
|
+
def self.global
|
14
|
+
new(C.LLVMGetGlobalContext())
|
15
|
+
end
|
16
|
+
|
17
|
+
# Diposes the Context.
|
18
|
+
def dispose
|
19
|
+
C.LLVMContextDispose(@ptr)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
module LLVM
|
2
|
+
class Module
|
3
|
+
# @private
|
4
|
+
def self.from_ptr(ptr)
|
5
|
+
return if ptr.null?
|
6
|
+
mod = allocate
|
7
|
+
mod.instance_variable_set(:@ptr, ptr)
|
8
|
+
mod
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(name)
|
12
|
+
@ptr = C.LLVMModuleCreateWithName(name)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @private
|
16
|
+
def to_ptr
|
17
|
+
@ptr
|
18
|
+
end
|
19
|
+
|
20
|
+
# Checks if the module is equal to other.
|
21
|
+
def ==(other)
|
22
|
+
case other
|
23
|
+
when LLVM::Module
|
24
|
+
@ptr == other.to_ptr
|
25
|
+
else
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Checks if the module is equal to other.
|
31
|
+
def eql?(other)
|
32
|
+
other.instance_of?(self.class) && self == other
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns a TypeCollection of all the Types in the module.
|
36
|
+
def types
|
37
|
+
@types ||= TypeCollection.new(self)
|
38
|
+
end
|
39
|
+
|
40
|
+
class TypeCollection
|
41
|
+
def initialize(mod)
|
42
|
+
@module = mod
|
43
|
+
end
|
44
|
+
|
45
|
+
# Adds the given Type to the collection with the given name (symbol or string).
|
46
|
+
def add(name, type)
|
47
|
+
C.LLVMAddTypeName(@module, name.to_s, type)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the Type with the given name (symbol or string).
|
51
|
+
def named(name)
|
52
|
+
Type.from_ptr(C.LLVMGetTypeByName(@module, name.to_s))
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the Type with the a name equal to key (symbol or string).
|
56
|
+
def [](key)
|
57
|
+
named(key)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Adds the given Type to the collection with a name equal to key (symbol or string).
|
61
|
+
def []=(key, type)
|
62
|
+
add(key, type)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns an Enumerable of all the GlobalVariables in the module.
|
67
|
+
def globals
|
68
|
+
@globals ||= GlobalCollection.new(self)
|
69
|
+
end
|
70
|
+
|
71
|
+
class GlobalCollection
|
72
|
+
include Enumerable
|
73
|
+
|
74
|
+
def initialize(mod)
|
75
|
+
@module = mod
|
76
|
+
end
|
77
|
+
|
78
|
+
# Adds a GlobalVariable with the given type and name to the collection (symbol or string).
|
79
|
+
def add(ty, name)
|
80
|
+
GlobalVariable.from_ptr(C.LLVMAddGlobal(@module, LLVM::Type(ty), name.to_s))
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the GlobalVariable with the given name (symbol or string).
|
84
|
+
def named(name)
|
85
|
+
GlobalValue.from_ptr(C.LLVMGetNamedGlobal(@module, name.to_s))
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns the first GlobalVariable in the collection.
|
89
|
+
def first
|
90
|
+
GlobalValue.from_ptr(C.LLVMGetFirstGlobal(@module))
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the last GlobalVariable in the collection.
|
94
|
+
def last
|
95
|
+
GlobalValue.from_ptr(C.LLVMGetLastGlobal(@module))
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns the next GlobalVariable in the collection after global.
|
99
|
+
def next(global)
|
100
|
+
GlobalValue.from_ptr(C.LLVMGetNextGlobal(global))
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns the previous GlobalVariable in the collection before global.
|
104
|
+
def previous(global)
|
105
|
+
GlobalValue.from_ptr(C.LLVMGetPreviousGlobal(global))
|
106
|
+
end
|
107
|
+
|
108
|
+
# Deletes the GlobalVariable from the collection.
|
109
|
+
def delete(global)
|
110
|
+
C.LLVMDeleteGlobal(global)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns the GlobalVariable with a name equal to key (symbol or string) or at key (integer).
|
114
|
+
def [](key)
|
115
|
+
case key
|
116
|
+
when String, Symbol then named(key)
|
117
|
+
when Integer then
|
118
|
+
i = 0
|
119
|
+
g = first
|
120
|
+
until i >= key || g.nil?
|
121
|
+
g = self.next(g)
|
122
|
+
i += 1
|
123
|
+
end
|
124
|
+
g
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Iterates through each GlobalVariable in the collection.
|
129
|
+
def each
|
130
|
+
g = first
|
131
|
+
until g.nil?
|
132
|
+
yield g
|
133
|
+
g = self.next(g)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Returns a FunctionCollection of all the Functions in the module.
|
139
|
+
def functions
|
140
|
+
@functions ||= FunctionCollection.new(self)
|
141
|
+
end
|
142
|
+
|
143
|
+
class FunctionCollection
|
144
|
+
include Enumerable
|
145
|
+
|
146
|
+
def initialize(mod)
|
147
|
+
@module = mod
|
148
|
+
end
|
149
|
+
|
150
|
+
# Adds a Function with the given name (symbol or string) and args (Types).
|
151
|
+
def add(name, *args)
|
152
|
+
if args.first.kind_of? Type
|
153
|
+
type = args.first
|
154
|
+
else
|
155
|
+
type = Type.function(*args)
|
156
|
+
end
|
157
|
+
function = Function.from_ptr(C.LLVMAddFunction(@module, name.to_s, type))
|
158
|
+
|
159
|
+
if block_given?
|
160
|
+
params = (0...function.params.size).map { |i| function.params[i] }
|
161
|
+
yield function, *params
|
162
|
+
end
|
163
|
+
|
164
|
+
function
|
165
|
+
end
|
166
|
+
|
167
|
+
# Returns the Function with the given name (symbol or string).
|
168
|
+
def named(name)
|
169
|
+
Function.from_ptr(C.LLVMGetNamedFunction(@module, name.to_s))
|
170
|
+
end
|
171
|
+
|
172
|
+
# Returns the first Function in the collection.
|
173
|
+
def first
|
174
|
+
Function.from_ptr(C.LLVMGetFirstFunction(@module))
|
175
|
+
end
|
176
|
+
|
177
|
+
# Returns the last Function in the collection.
|
178
|
+
def last
|
179
|
+
Function.from_ptr(C.LLVMGetLastFunction(@module))
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns the next Function in the collection after function.
|
183
|
+
def next(function)
|
184
|
+
Function.from_ptr(C.LLVMGetNextFunction(function))
|
185
|
+
end
|
186
|
+
|
187
|
+
# Returns the previous Function in the collection before function.
|
188
|
+
def previous(function)
|
189
|
+
Function.from_ptr(C.LLVMGetPreviousFunction(function))
|
190
|
+
end
|
191
|
+
|
192
|
+
# Deletes the Function from the collection.
|
193
|
+
def delete(function)
|
194
|
+
C.LLVMDeleteFunction(function)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Returns the Function with a name equal to key (symbol or string) or at key (integer).
|
198
|
+
def [](key)
|
199
|
+
case key
|
200
|
+
when String, Symbol then named(key)
|
201
|
+
when Integer
|
202
|
+
i = 0
|
203
|
+
f = first
|
204
|
+
until i >= key || f.nil?
|
205
|
+
f = self.next(f)
|
206
|
+
i += 1
|
207
|
+
end
|
208
|
+
f
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Iterates through each Function in the collection.
|
213
|
+
def each
|
214
|
+
f = first
|
215
|
+
until f.nil?
|
216
|
+
yield f
|
217
|
+
f = self.next(f)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# Print the module's IR to stdout.
|
223
|
+
def dump
|
224
|
+
C.LLVMDumpModule(self)
|
225
|
+
end
|
226
|
+
|
227
|
+
# Dispose the module.
|
228
|
+
def dispose
|
229
|
+
C.LLVMDisposeModule(@ptr)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module LLVM
|
2
|
+
# The PassManager runs a queue of passes on a module. See
|
3
|
+
# http://llvm.org/docs/Passes.html for the list of available passes.
|
4
|
+
class PassManager
|
5
|
+
# Creates a new pass manager on the given ExecutionEngine.
|
6
|
+
def initialize(execution_engine)
|
7
|
+
ptr = C.LLVMCreatePassManager()
|
8
|
+
C.LLVMAddTargetData(
|
9
|
+
C.LLVMGetExecutionEngineTargetData(execution_engine), ptr)
|
10
|
+
@ptr = ptr
|
11
|
+
|
12
|
+
do_initialization
|
13
|
+
end
|
14
|
+
|
15
|
+
# @private
|
16
|
+
def to_ptr
|
17
|
+
@ptr
|
18
|
+
end
|
19
|
+
|
20
|
+
# Append a pass to the pass queue.
|
21
|
+
# @param [Symbol]
|
22
|
+
# @return [LLVM::PassManager]
|
23
|
+
def <<(name)
|
24
|
+
send(:"#{name}!")
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
# Run the pass queue on the given module.
|
29
|
+
# @param [LLVM::Module]
|
30
|
+
# @return [true, false] Indicates whether the module was modified.
|
31
|
+
def run(mod)
|
32
|
+
C.LLVMRunPassManager(self, mod) != 0
|
33
|
+
end
|
34
|
+
|
35
|
+
# Disposes the pass manager.
|
36
|
+
def dispose
|
37
|
+
do_finalization
|
38
|
+
C.LLVMDisposePassManager(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
def do_initialization
|
44
|
+
end
|
45
|
+
|
46
|
+
def do_finalization
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class FunctionPassManager < PassManager
|
51
|
+
# Creates a new pass manager on the given ExecutionEngine and Module.
|
52
|
+
def initialize(execution_engine, mod)
|
53
|
+
ptr = C.LLVMCreateFunctionPassManagerForModule(mod)
|
54
|
+
C.LLVMAddTargetData(
|
55
|
+
C.LLVMGetExecutionEngineTargetData(execution_engine), ptr)
|
56
|
+
@ptr = ptr
|
57
|
+
end
|
58
|
+
|
59
|
+
# Run the pass queue on the given function.
|
60
|
+
# @param [LLVM::Function]
|
61
|
+
# @return [true, false] indicates whether the function was modified.
|
62
|
+
def run(fn)
|
63
|
+
C.LLVMRunFunctionPassManager(self, fn) != 0
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def do_initialization
|
69
|
+
C.LLVMInitializeFunctionPassManager(self) != 0
|
70
|
+
end
|
71
|
+
|
72
|
+
def do_finalization
|
73
|
+
C.LLVMFinalizeFunctionPassManager(self) != 0
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
module LLVM
|
2
|
+
class Type
|
3
|
+
# @private
|
4
|
+
def to_ptr
|
5
|
+
@ptr
|
6
|
+
end
|
7
|
+
|
8
|
+
# LLVM's represents types uniquely, and supports pointer equality.
|
9
|
+
def ==(type)
|
10
|
+
case type
|
11
|
+
when LLVM::Type
|
12
|
+
@ptr == type.to_ptr
|
13
|
+
else
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Checks if the type is equal to other.
|
19
|
+
def eql?(other)
|
20
|
+
other.instance_of?(self.class) && self == other
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns a symbol representation of the types kind (ex. :pointer, :vector, :array.)
|
24
|
+
def kind
|
25
|
+
C.LLVMGetTypeKind(self)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the size of the type.
|
29
|
+
def size
|
30
|
+
LLVM::Int64.from_ptr(C.LLVMSizeOf(self))
|
31
|
+
end
|
32
|
+
|
33
|
+
def align
|
34
|
+
LLVM::Int64.from_ptr(C.LLVMAlignOf(self))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the type of this types elements (works only for Pointer, Vector, and Array types.)
|
38
|
+
def element_type
|
39
|
+
case self.kind
|
40
|
+
when :pointer, :vector, :array
|
41
|
+
Type.from_ptr(C.LLVMGetElementType(self))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns a null pointer ConstantExpr of this type.
|
46
|
+
def null_pointer
|
47
|
+
ConstantExpr.from_ptr(C.LLVMConstPointerNull(self))
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns a null ConstantExpr of this type.
|
51
|
+
def null
|
52
|
+
ConstantExpr.from_ptr(C.LLVMConstNull(self))
|
53
|
+
end
|
54
|
+
|
55
|
+
# Creates a pointer type with this type and the given address space.
|
56
|
+
def pointer(address_space = 0)
|
57
|
+
Type.pointer(self, address_space)
|
58
|
+
end
|
59
|
+
|
60
|
+
# @private
|
61
|
+
def self.from_ptr(ptr)
|
62
|
+
return if ptr.null?
|
63
|
+
ty = allocate
|
64
|
+
ty.instance_variable_set(:@ptr, ptr)
|
65
|
+
ty
|
66
|
+
end
|
67
|
+
|
68
|
+
# Creates an array type of Type with the given size.
|
69
|
+
def self.array(ty, sz = 0)
|
70
|
+
from_ptr(C.LLVMArrayType(LLVM::Type(ty), sz))
|
71
|
+
end
|
72
|
+
|
73
|
+
# Creates the pointer type of Type with the given address space.
|
74
|
+
def self.pointer(ty, address_space = 0)
|
75
|
+
from_ptr(C.LLVMPointerType(LLVM::Type(ty), address_space))
|
76
|
+
end
|
77
|
+
|
78
|
+
# Creates a vector type of Type with the given element count.
|
79
|
+
def self.vector(ty, element_count)
|
80
|
+
from_ptr(C.LLVMVectorType(LLVM::Type(ty), element_count))
|
81
|
+
end
|
82
|
+
|
83
|
+
# Creates a function type. Takes an array of argument Types and the result Type. The only option is <tt>:varargs</tt>,
|
84
|
+
# which when set to true makes the function type take a variable number of args.
|
85
|
+
def self.function(arg_types, result_type, options = {})
|
86
|
+
arg_types.map! { |ty| LLVM::Type(ty) }
|
87
|
+
arg_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * arg_types.size)
|
88
|
+
arg_types_ptr.write_array_of_pointer(arg_types)
|
89
|
+
FunctionType.from_ptr(C.LLVMFunctionType(LLVM::Type(result_type), arg_types_ptr, arg_types.size, options[:varargs] ? 1 : 0))
|
90
|
+
end
|
91
|
+
|
92
|
+
# Creates a struct type with the given array of element types.
|
93
|
+
def self.struct(elt_types, is_packed)
|
94
|
+
elt_types.map! { |ty| LLVM::Type(ty) }
|
95
|
+
elt_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * elt_types.size)
|
96
|
+
elt_types_ptr.write_array_of_pointer(elt_types)
|
97
|
+
from_ptr(C.LLVMStructType(elt_types_ptr, elt_types.size, is_packed ? 1 : 0))
|
98
|
+
end
|
99
|
+
|
100
|
+
# Creates a void type.
|
101
|
+
def self.void
|
102
|
+
from_ptr(C.LLVMVoidType)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Creates an opaque type.
|
106
|
+
def self.opaque
|
107
|
+
from_ptr(C.LLVMOpaqueType)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.rec
|
111
|
+
h = opaque
|
112
|
+
ty = yield h
|
113
|
+
h.refine(ty)
|
114
|
+
ty
|
115
|
+
end
|
116
|
+
|
117
|
+
def refine(ty)
|
118
|
+
C.LLVMRefineType(self, ty)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class IntType < Type
|
123
|
+
def width
|
124
|
+
C.LLVMGetIntTypeWidth(self)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class FunctionType < Type
|
129
|
+
def return_type
|
130
|
+
LLVM::Type.from_ptr(C.LLVMGetReturnType(self))
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
module_function
|
135
|
+
|
136
|
+
# Creates a Type from the given object.
|
137
|
+
def Type(ty)
|
138
|
+
case ty
|
139
|
+
when LLVM::Type then ty
|
140
|
+
else ty.type
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Shortcut to Type.array.
|
145
|
+
def Array(ty, sz = 0)
|
146
|
+
LLVM::Type.array(ty, sz)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Shortcut to Type.pointer.
|
150
|
+
def Pointer(ty)
|
151
|
+
LLVM::Type.pointer(ty)
|
152
|
+
end
|
153
|
+
|
154
|
+
# Shortcut to Type.vector.
|
155
|
+
def Vector(ty, sz)
|
156
|
+
LLVM::Type.vector(ty, sz)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Shortcut to Type.function.
|
160
|
+
def Function(argtypes, rettype, options = {})
|
161
|
+
LLVM::Type.function(argtypes, rettype, options)
|
162
|
+
end
|
163
|
+
|
164
|
+
# Shortcut to Type.struct.
|
165
|
+
def Struct(*elt_types)
|
166
|
+
LLVM::Type.struct(elt_types, false)
|
167
|
+
end
|
168
|
+
|
169
|
+
# Shortcut to Type.void.
|
170
|
+
def Void
|
171
|
+
LLVM::Type.void
|
172
|
+
end
|
173
|
+
end
|