waj-ruby-llvm 2.9.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|