ruby-llvm 2.7.0 → 2.9.0
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 +17 -14
- data/lib/llvm.rb +3 -1
- data/lib/llvm/analysis.rb +2 -6
- data/lib/llvm/core.rb +82 -6
- data/lib/llvm/core/builder.rb +106 -94
- data/lib/llvm/core/context.rb +2 -4
- data/lib/llvm/core/module.rb +14 -3
- data/lib/llvm/core/pass_manager.rb +28 -2
- data/lib/llvm/core/type.rb +32 -7
- data/lib/llvm/core/value.rb +306 -115
- data/lib/llvm/execution_engine.rb +45 -37
- data/lib/llvm/transforms/ipo.rb +15 -0
- data/lib/llvm/transforms/scalar.rb +0 -5
- metadata +31 -10
data/lib/llvm/core/context.rb
CHANGED
data/lib/llvm/core/module.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module LLVM
|
2
2
|
class Module
|
3
|
-
|
4
|
-
private :new
|
5
|
-
end
|
3
|
+
private_class_method :new
|
6
4
|
|
7
5
|
def self.from_ptr(ptr)
|
8
6
|
ptr.null? ? nil : new(ptr)
|
@@ -16,6 +14,19 @@ module LLVM
|
|
16
14
|
@ptr
|
17
15
|
end
|
18
16
|
|
17
|
+
def ==(other)
|
18
|
+
case other
|
19
|
+
when LLVM::Module
|
20
|
+
@ptr == other.to_ptr
|
21
|
+
else
|
22
|
+
false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def eql?(other)
|
27
|
+
other.instance_of?(self.class) && self == other
|
28
|
+
end
|
29
|
+
|
19
30
|
def self.create(name)
|
20
31
|
new(C.LLVMModuleCreateWithName(name))
|
21
32
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
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
|
-
# Currently, only scalar transformation passes are supported.
|
5
4
|
class PassManager
|
6
5
|
def initialize(execution_engine)
|
7
6
|
ptr = C.LLVMCreatePassManager()
|
@@ -18,7 +17,13 @@ module LLVM
|
|
18
17
|
send(:"#{name}!")
|
19
18
|
self
|
20
19
|
end
|
21
|
-
|
20
|
+
|
21
|
+
def do_initialization
|
22
|
+
end
|
23
|
+
|
24
|
+
def do_finalization
|
25
|
+
end
|
26
|
+
|
22
27
|
def run(mod)
|
23
28
|
C.LLVMRunPassManager(self, mod)
|
24
29
|
end
|
@@ -27,4 +32,25 @@ module LLVM
|
|
27
32
|
C.LLVMDisposePassManager(self)
|
28
33
|
end
|
29
34
|
end
|
35
|
+
|
36
|
+
class FunctionPassManager < PassManager
|
37
|
+
def initialize(execution_engine, mod)
|
38
|
+
ptr = C.LLVMCreateFunctionPassManagerForModule(mod)
|
39
|
+
C.LLVMAddTargetData(
|
40
|
+
C.LLVMGetExecutionEngineTargetData(execution_engine), ptr)
|
41
|
+
@ptr = ptr
|
42
|
+
end
|
43
|
+
|
44
|
+
def do_initialization
|
45
|
+
C.LLVMInitializeFunctionPassManager(self) != 0
|
46
|
+
end
|
47
|
+
|
48
|
+
def do_finalization
|
49
|
+
C.LLVMFinalizeFunctionPassManager(self) != 0
|
50
|
+
end
|
51
|
+
|
52
|
+
def run(fn)
|
53
|
+
C.LLVMRunFunctionPassManager(self, fn)
|
54
|
+
end
|
55
|
+
end
|
30
56
|
end
|
data/lib/llvm/core/type.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module LLVM
|
2
2
|
class Type
|
3
|
-
|
4
|
-
private :new
|
5
|
-
end
|
3
|
+
private_class_method :new
|
6
4
|
|
7
5
|
def initialize(ptr) # :nodoc:
|
8
6
|
@ptr = ptr
|
@@ -22,6 +20,14 @@ module LLVM
|
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
23
|
+
def eql?(other)
|
24
|
+
other.instance_of?(self.class) && self == other
|
25
|
+
end
|
26
|
+
|
27
|
+
def kind
|
28
|
+
C.LLVMGetTypeKind(self)
|
29
|
+
end
|
30
|
+
|
25
31
|
def size
|
26
32
|
Int64.from_ptr(C.LLVMSizeOf(self))
|
27
33
|
end
|
@@ -29,6 +35,25 @@ module LLVM
|
|
29
35
|
def align
|
30
36
|
Int64.from_ptr(C.LLVMAlignOf(self))
|
31
37
|
end
|
38
|
+
|
39
|
+
def element_type
|
40
|
+
case self.kind
|
41
|
+
when :pointer, :vector, :array
|
42
|
+
Type.from_ptr(C.LLVMGetElementType(self))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def null_pointer
|
47
|
+
ConstantExpr.from_ptr(C.LLVMConstPointerNull(self))
|
48
|
+
end
|
49
|
+
|
50
|
+
def null
|
51
|
+
ConstantExpr.from_ptr(C.LLVMConstNull(self))
|
52
|
+
end
|
53
|
+
|
54
|
+
def pointer(address_space = 0)
|
55
|
+
Type.pointer(self, address_space)
|
56
|
+
end
|
32
57
|
|
33
58
|
def self.from_ptr(ptr)
|
34
59
|
ptr.null? ? nil : new(ptr)
|
@@ -46,11 +71,11 @@ module LLVM
|
|
46
71
|
from_ptr(C.LLVMVectorType(LLVM::Type(ty), element_count))
|
47
72
|
end
|
48
73
|
|
49
|
-
def self.function(arg_types, result_type)
|
74
|
+
def self.function(arg_types, result_type, options = {})
|
50
75
|
arg_types.map! { |ty| LLVM::Type(ty) }
|
51
76
|
arg_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * arg_types.size)
|
52
77
|
arg_types_ptr.write_array_of_pointer(arg_types)
|
53
|
-
from_ptr(C.LLVMFunctionType(LLVM::Type(result_type), arg_types_ptr, arg_types.size, 0))
|
78
|
+
from_ptr(C.LLVMFunctionType(LLVM::Type(result_type), arg_types_ptr, arg_types.size, options[:varargs] ? 1 : 0))
|
54
79
|
end
|
55
80
|
|
56
81
|
def self.struct(elt_types, is_packed)
|
@@ -99,8 +124,8 @@ module LLVM
|
|
99
124
|
LLVM::Type.vector(ty, sz)
|
100
125
|
end
|
101
126
|
|
102
|
-
def LLVM.Function(argtypes, rettype)
|
103
|
-
LLVM::Type.function(argtypes, rettype)
|
127
|
+
def LLVM.Function(argtypes, rettype, options = {})
|
128
|
+
LLVM::Type.function(argtypes, rettype, options)
|
104
129
|
end
|
105
130
|
|
106
131
|
def LLVM.Struct(*elt_types)
|
data/lib/llvm/core/value.rb
CHANGED
@@ -3,74 +3,89 @@ module LLVM
|
|
3
3
|
def self.from_ptr(ptr)
|
4
4
|
new(ptr) unless ptr.null?
|
5
5
|
end
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
6
|
+
|
7
|
+
private_class_method :new
|
8
|
+
|
11
9
|
def initialize(ptr)
|
12
10
|
@ptr = ptr
|
13
11
|
end
|
14
|
-
|
12
|
+
|
15
13
|
def to_ptr # :nodoc:
|
16
14
|
@ptr
|
17
15
|
end
|
18
|
-
|
16
|
+
|
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 eql?(other)
|
27
|
+
other.instance_of?(self.class) && self == other
|
28
|
+
end
|
29
|
+
|
19
30
|
def self.type
|
20
|
-
raise NotImplementedError, "
|
31
|
+
raise NotImplementedError, "#{self.name}.type() is abstract."
|
21
32
|
end
|
22
|
-
|
33
|
+
|
23
34
|
def self.to_ptr
|
24
35
|
type.to_ptr
|
25
36
|
end
|
26
|
-
|
37
|
+
|
27
38
|
def type
|
28
39
|
Type.from_ptr(C.LLVMTypeOf(self))
|
29
40
|
end
|
30
|
-
|
41
|
+
|
31
42
|
def name
|
32
43
|
C.LLVMGetValueName(self)
|
33
44
|
end
|
34
|
-
|
45
|
+
|
35
46
|
def name=(str)
|
36
47
|
C.LLVMSetValueName(self, str)
|
37
48
|
str
|
38
49
|
end
|
39
|
-
|
50
|
+
|
40
51
|
def dump
|
41
52
|
C.LLVMDumpValue(self)
|
42
53
|
end
|
43
|
-
|
54
|
+
|
44
55
|
def constant?
|
45
56
|
case C.LLVMIsConstant(self)
|
46
57
|
when 0 then false
|
47
58
|
when 1 then true
|
48
59
|
end
|
49
60
|
end
|
50
|
-
|
61
|
+
|
51
62
|
def null?
|
52
63
|
case C.LLVMIsNull(self)
|
53
64
|
when 0 then false
|
54
65
|
when 1 then true
|
55
66
|
end
|
56
67
|
end
|
57
|
-
|
68
|
+
|
58
69
|
def undefined?
|
59
70
|
case C.LLVMIsUndef(self)
|
60
71
|
when 0 then false
|
61
72
|
when 1 then true
|
62
73
|
end
|
63
74
|
end
|
64
|
-
|
75
|
+
|
65
76
|
def add_attribute(attr)
|
66
77
|
C.LLVMAddAttribute(self, attr)
|
67
78
|
end
|
68
79
|
end
|
69
|
-
|
80
|
+
|
70
81
|
class Argument < Value
|
71
82
|
end
|
72
|
-
|
83
|
+
|
73
84
|
class BasicBlock < Value
|
85
|
+
def self.create(fun = nil, name = "")
|
86
|
+
self.from_ptr(C.LLVMAppendBasicBlock(fun, name))
|
87
|
+
end
|
88
|
+
|
74
89
|
def build(builder = nil)
|
75
90
|
if builder.nil?
|
76
91
|
builder = Builder.create
|
@@ -81,120 +96,238 @@ module LLVM
|
|
81
96
|
builder.position_at_end(self)
|
82
97
|
yield builder
|
83
98
|
ensure
|
84
|
-
builder.dispose
|
99
|
+
builder.dispose if islocal
|
100
|
+
end
|
101
|
+
|
102
|
+
def parent
|
103
|
+
fp = C.LLVMGetBasicBlockParent(self)
|
104
|
+
LLVM::Function.from_ptr(fp) unless fp.null?
|
105
|
+
end
|
106
|
+
|
107
|
+
def next
|
108
|
+
ptr = C.LLVMGetNextBasicBlock(self)
|
109
|
+
BasicBlock.from_ptr(ptr) unless ptr.null?
|
110
|
+
end
|
111
|
+
|
112
|
+
def previous
|
113
|
+
ptr = C.LLVMGetPreviousBasicBlock(self)
|
114
|
+
BasicBlock.from_ptr(ptr) unless ptr.null?
|
115
|
+
end
|
116
|
+
|
117
|
+
def first_instruction # deprecated
|
118
|
+
instructions.first
|
119
|
+
end
|
120
|
+
|
121
|
+
def last_instruction # deprecated
|
122
|
+
instructions.last
|
123
|
+
end
|
124
|
+
|
125
|
+
def instructions
|
126
|
+
@instructions ||= InstructionCollection.new(self)
|
127
|
+
end
|
128
|
+
|
129
|
+
class InstructionCollection
|
130
|
+
include Enumerable
|
131
|
+
|
132
|
+
def initialize(block)
|
133
|
+
@block = block
|
134
|
+
end
|
135
|
+
|
136
|
+
def each
|
137
|
+
return to_enum :each unless block_given?
|
138
|
+
inst, last = first, last
|
139
|
+
|
140
|
+
while inst
|
141
|
+
yield inst
|
142
|
+
break if inst == last
|
143
|
+
inst = inst.next
|
144
|
+
end
|
145
|
+
|
146
|
+
self
|
147
|
+
end
|
148
|
+
|
149
|
+
def first
|
150
|
+
ptr = C.LLVMGetFirstInstruction(@block)
|
151
|
+
LLVM::Instruction.from_ptr(ptr) unless ptr.null?
|
152
|
+
end
|
153
|
+
|
154
|
+
def last
|
155
|
+
ptr = C.LLVMGetLastInstruction(@block)
|
156
|
+
LLVM::Instruction.from_ptr(ptr) unless ptr.null?
|
157
|
+
end
|
85
158
|
end
|
86
159
|
end
|
87
|
-
|
88
|
-
class
|
89
|
-
def
|
90
|
-
|
160
|
+
|
161
|
+
class User < Value
|
162
|
+
def operands
|
163
|
+
@operand_collection ||= OperandCollection.new(self)
|
164
|
+
end
|
165
|
+
|
166
|
+
class OperandCollection
|
167
|
+
include Enumerable
|
168
|
+
|
169
|
+
def initialize(user)
|
170
|
+
@user = user
|
171
|
+
end
|
172
|
+
|
173
|
+
def [](i)
|
174
|
+
ptr = C.LLVMGetOperand(@user, i)
|
175
|
+
Value.from_ptr(ptr) unless ptr.null?
|
176
|
+
end
|
177
|
+
|
178
|
+
def []=(i, v)
|
179
|
+
C.LLVMSetOperand(@user, i, v)
|
180
|
+
end
|
181
|
+
|
182
|
+
def size
|
183
|
+
C.LLVMGetNumOperands(@user)
|
184
|
+
end
|
185
|
+
|
186
|
+
def each
|
187
|
+
return to_enum :each unless block_given?
|
188
|
+
0.upto(size-1) { |i| yield self[i] }
|
189
|
+
self
|
190
|
+
end
|
91
191
|
end
|
92
|
-
|
192
|
+
end
|
193
|
+
|
194
|
+
class Constant < User
|
93
195
|
def self.null
|
94
196
|
from_ptr(C.LLVMConstNull(type))
|
95
197
|
end
|
96
|
-
|
198
|
+
|
97
199
|
def self.undef
|
98
200
|
from_ptr(C.LLVMGetUndef(type))
|
99
201
|
end
|
100
|
-
|
202
|
+
|
101
203
|
def self.null_ptr
|
102
204
|
from_ptr(C.LLVMConstPointerNull(type))
|
103
205
|
end
|
206
|
+
|
207
|
+
def bitcast_to(type)
|
208
|
+
ConstantExpr.from_ptr(C.LLVMConstBitCast(self, type))
|
209
|
+
end
|
210
|
+
|
211
|
+
def gep(*indices)
|
212
|
+
indices = Array(indices)
|
213
|
+
FFI::MemoryPointer.new(FFI.type_size(:pointer) * indices.size) do |indices_ptr|
|
214
|
+
indices_ptr.write_array_of_pointer(indices)
|
215
|
+
return ConstantExpr.from_ptr(
|
216
|
+
C.LLVMConstGEP(self, indices_ptr, indices.size))
|
217
|
+
end
|
218
|
+
end
|
104
219
|
end
|
105
|
-
|
220
|
+
|
221
|
+
module Support
|
222
|
+
def allocate_pointers(size_or_values, &block)
|
223
|
+
if size_or_values.is_a?(Integer)
|
224
|
+
raise ArgumentError, 'block not given' unless block_given?
|
225
|
+
size = size_or_values
|
226
|
+
values = (0...size).map { |i| yield i }
|
227
|
+
else
|
228
|
+
values = size_or_values
|
229
|
+
size = values.size
|
230
|
+
end
|
231
|
+
FFI::MemoryPointer.new(:pointer, size).write_array_of_pointer(values)
|
232
|
+
end
|
233
|
+
|
234
|
+
module_function :allocate_pointers
|
235
|
+
end
|
236
|
+
|
106
237
|
class ConstantArray < Constant
|
107
238
|
def self.string(str, null_terminate = true)
|
108
|
-
from_ptr(C.LLVMConstString(str, null_terminate ? 0 : 1))
|
239
|
+
from_ptr(C.LLVMConstString(str, str.length, null_terminate ? 0 : 1))
|
109
240
|
end
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
241
|
+
|
242
|
+
# ConstantArray.const(type, 3) {|i| ... } or
|
243
|
+
# ConstantArray.const(type, [...])
|
244
|
+
def self.const(type, size_or_values, &block)
|
245
|
+
vals = LLVM::Support.allocate_pointers(size_or_values, &block)
|
246
|
+
from_ptr C.LLVMConstArray(type, vals, vals.size / vals.type_size)
|
114
247
|
end
|
115
248
|
end
|
116
|
-
|
249
|
+
|
117
250
|
class ConstantExpr < Constant
|
118
251
|
end
|
119
|
-
|
252
|
+
|
120
253
|
class ConstantInt < Constant
|
121
254
|
def self.all_ones
|
122
255
|
from_ptr(C.LLVMConstAllOnes(type))
|
123
256
|
end
|
124
|
-
|
257
|
+
|
125
258
|
def self.from_i(n, signed = true)
|
126
259
|
from_ptr(C.LLVMConstInt(type, n, signed ? 1 : 0))
|
127
260
|
end
|
128
|
-
|
261
|
+
|
129
262
|
def self.parse(str, radix = 10)
|
130
263
|
from_ptr(C.LLVMConstIntOfString(type, str, radix))
|
131
264
|
end
|
132
|
-
|
265
|
+
|
133
266
|
def -@
|
134
267
|
self.class.from_ptr(C.LLVMConstNeg(self))
|
135
268
|
end
|
136
|
-
|
269
|
+
|
137
270
|
def not
|
138
271
|
self.class.from_ptr(C.LLVMConstNot(self))
|
139
272
|
end
|
140
|
-
|
273
|
+
|
141
274
|
def +(rhs)
|
142
275
|
self.class.from_ptr(C.LLVMConstAdd(self, rhs))
|
143
276
|
end
|
144
|
-
|
277
|
+
|
145
278
|
def nsw_add(rhs)
|
146
279
|
self.class.from_ptr(C.LLVMConstNSWAdd(self, rhs))
|
147
280
|
end
|
148
|
-
|
281
|
+
|
149
282
|
def *(rhs)
|
150
283
|
self.class.from_ptr(C.LLVMConstMul(self, rhs))
|
151
284
|
end
|
152
|
-
|
285
|
+
|
153
286
|
def udiv(rhs)
|
154
287
|
self.class.from_ptr(C.LLVMConstUDiv(self, rhs))
|
155
288
|
end
|
156
|
-
|
289
|
+
|
157
290
|
def /(rhs)
|
158
291
|
self.class.from_ptr(C.LLVMConstSDiv(self, rhs))
|
159
292
|
end
|
160
|
-
|
293
|
+
|
161
294
|
def urem(rhs)
|
162
295
|
self.class.from_ptr(C.LLVMConstURem(self, rhs))
|
163
296
|
end
|
164
|
-
|
297
|
+
|
165
298
|
def rem(rhs)
|
166
299
|
self.class.from_ptr(C.LLVMConstSRem(self, rhs))
|
167
300
|
end
|
168
|
-
|
301
|
+
|
169
302
|
def and(rhs) # Ruby's && cannot be overloaded
|
170
303
|
self.class.from_ptr(C.LLVMConstAnd(self, rhs))
|
171
304
|
end
|
172
|
-
|
305
|
+
|
173
306
|
def or(rhs) # Nor is ||.
|
174
307
|
self.class.from_ptr(C.LLVMConstOr(self, rhs))
|
175
308
|
end
|
176
|
-
|
309
|
+
|
177
310
|
def xor(rhs) # Nor is ||.
|
178
311
|
self.class.from_ptr(C.LLVMConstXor(self, rhs))
|
179
312
|
end
|
180
|
-
|
313
|
+
|
181
314
|
def icmp(pred, rhs)
|
182
315
|
self.class.from_ptr(C.LLVMConstICmp(pred, self, rhs))
|
183
316
|
end
|
184
|
-
|
317
|
+
|
185
318
|
def <<(bits)
|
186
319
|
self.class.from_ptr(C.LLVMConstShl(self, rhs))
|
187
320
|
end
|
188
|
-
|
321
|
+
|
189
322
|
def >>(bits)
|
190
323
|
self.class.from_ptr(C.LLVMConstLShr(self, rhs))
|
191
324
|
end
|
192
|
-
|
325
|
+
|
193
326
|
def ashr(bits)
|
194
327
|
self.class.from_ptr(C.LLVMConstAShr(self, rhs))
|
195
328
|
end
|
196
329
|
end
|
197
|
-
|
330
|
+
|
198
331
|
def LLVM.const_missing(const) # :nodoc:
|
199
332
|
case const.to_s
|
200
333
|
when /Int(\d+)/
|
@@ -212,226 +345,284 @@ module LLVM
|
|
212
345
|
super
|
213
346
|
end
|
214
347
|
end
|
215
|
-
|
348
|
+
|
216
349
|
# Native integer type
|
217
350
|
::LLVM::Int = const_get("Int#{NATIVE_INT_SIZE}")
|
218
|
-
|
351
|
+
|
219
352
|
def LLVM.Int(val)
|
220
353
|
case val
|
221
354
|
when LLVM::ConstantInt then val
|
222
355
|
when Integer then Int.from_i(val)
|
223
356
|
end
|
224
357
|
end
|
225
|
-
|
358
|
+
|
226
359
|
class ConstantReal < Constant
|
227
360
|
def self.from_f(n)
|
228
361
|
from_ptr(C.LLVMConstReal(type, n))
|
229
362
|
end
|
230
|
-
|
363
|
+
|
231
364
|
def self.parse(str)
|
232
365
|
from_ptr(C.LLVMConstRealOfString(type, str))
|
233
366
|
end
|
234
|
-
|
367
|
+
|
235
368
|
def -@
|
236
369
|
self.class.from_ptr(C.LLVMConstFNeg(self))
|
237
370
|
end
|
238
|
-
|
371
|
+
|
239
372
|
def +(rhs)
|
240
373
|
self.class.from_ptr(C.LLVMConstFAdd(self, rhs))
|
241
374
|
end
|
242
|
-
|
375
|
+
|
243
376
|
def *(rhs)
|
244
377
|
self.class.from_ptr(C.LLVMConstFMul(self, rhs))
|
245
378
|
end
|
246
|
-
|
379
|
+
|
247
380
|
def /(rhs)
|
248
381
|
self.class.from_ptr(C.LLVMConstFDiv(self, rhs))
|
249
382
|
end
|
250
|
-
|
383
|
+
|
251
384
|
def rem(rhs)
|
252
385
|
self.class.from_ptr(C.LLVMConstFRem(self, rhs))
|
253
386
|
end
|
254
|
-
|
387
|
+
|
255
388
|
def fcmp(pred, rhs)
|
256
389
|
self.class.from_ptr(C.LLMVConstFCmp(pred, self, rhs))
|
257
390
|
end
|
258
391
|
end
|
259
|
-
|
392
|
+
|
260
393
|
class Float < ConstantReal
|
261
394
|
def self.type
|
262
395
|
Type.from_ptr(C.LLVMFloatType)
|
263
396
|
end
|
264
397
|
end
|
265
|
-
|
398
|
+
|
266
399
|
def LLVM.Float(val)
|
267
400
|
Float.from_f(val)
|
268
401
|
end
|
269
|
-
|
402
|
+
|
270
403
|
class Double < ConstantReal
|
271
404
|
def self.type
|
272
405
|
Type.from_ptr(C.LLVMDoubleType)
|
273
406
|
end
|
274
407
|
end
|
275
|
-
|
408
|
+
|
276
409
|
def LLVM.Double(val)
|
277
410
|
Double.from_f(val)
|
278
411
|
end
|
279
|
-
|
412
|
+
|
280
413
|
class ConstantStruct < Constant
|
281
|
-
|
282
|
-
|
283
|
-
|
414
|
+
# ConstantStruct.const(size) {|i| ... } or
|
415
|
+
# ConstantStruct.const([...])
|
416
|
+
def self.const(size_or_values, packed = false, &block)
|
417
|
+
vals = LLVM::Support.allocate_pointers(size_or_values, &block)
|
418
|
+
from_ptr C.LLVMConstStruct(vals, vals.size / vals.type_size, packed ? 1 : 0)
|
284
419
|
end
|
285
420
|
end
|
286
|
-
|
421
|
+
|
287
422
|
class ConstantVector < Constant
|
288
423
|
def self.all_ones
|
289
424
|
from_ptr(C.LLVMConstAllOnes(type))
|
290
425
|
end
|
291
|
-
|
292
|
-
def self.const(
|
293
|
-
vals = (
|
294
|
-
from_ptr(C.LLVMConstVector(vals, size))
|
426
|
+
|
427
|
+
def self.const(size_or_values, &block)
|
428
|
+
vals = LLVM::Support.allocate_pointers(size_or_values, &block)
|
429
|
+
from_ptr(C.LLVMConstVector(vals, vals.size / vals.type_size))
|
295
430
|
end
|
296
431
|
end
|
297
|
-
|
432
|
+
|
298
433
|
class GlobalValue < Constant
|
299
434
|
def declaration?
|
300
435
|
C.LLVMIsDeclaration(self)
|
301
436
|
end
|
302
|
-
|
437
|
+
|
303
438
|
def linkage
|
304
439
|
C.LLVMGetLinkage(self)
|
305
440
|
end
|
306
|
-
|
441
|
+
|
307
442
|
def linkage=(linkage)
|
308
443
|
C.LLVMSetLinkage(self, linkage)
|
309
444
|
end
|
310
|
-
|
445
|
+
|
311
446
|
def section
|
312
447
|
C.LLVMGetSection(self)
|
313
448
|
end
|
314
|
-
|
449
|
+
|
315
450
|
def section=(section)
|
316
451
|
C.LLVMSetSection(self, section)
|
317
452
|
end
|
318
|
-
|
453
|
+
|
319
454
|
def visibility
|
320
455
|
C.LLVMGetVisibility(self)
|
321
456
|
end
|
322
|
-
|
457
|
+
|
323
458
|
def visibility=(viz)
|
324
459
|
C.LLVMSetVisibility(self, viz)
|
325
460
|
end
|
326
|
-
|
461
|
+
|
327
462
|
def alignment
|
328
463
|
C.LLVMGetAlignment(self)
|
329
464
|
end
|
330
|
-
|
465
|
+
|
331
466
|
def alignment=(bytes)
|
332
467
|
C.LLVMSetAlignment(self, bytes)
|
333
468
|
end
|
469
|
+
|
470
|
+
def initializer
|
471
|
+
Value.from_ptr(C.LLVMGetInitializer(self))
|
472
|
+
end
|
473
|
+
|
474
|
+
def initializer=(val)
|
475
|
+
C.LLVMSetInitializer(self, val)
|
476
|
+
end
|
477
|
+
|
478
|
+
def global_constant?
|
479
|
+
C.LLVMIsGlobalConstant(self)
|
480
|
+
end
|
481
|
+
|
482
|
+
def global_constant=(flag)
|
483
|
+
C.LLVMSetGlobalConstant(self, flag)
|
484
|
+
end
|
334
485
|
end
|
335
|
-
|
486
|
+
|
336
487
|
class Function < GlobalValue
|
337
488
|
def call_conv=(conv)
|
338
489
|
C.LLVMSetFunctionCallConv(self, conv)
|
339
490
|
conv
|
340
491
|
end
|
341
|
-
|
492
|
+
|
342
493
|
def add_attribute(attr)
|
343
494
|
C.LLVMAddFunctionAttr(self, attr)
|
344
495
|
end
|
345
|
-
|
496
|
+
|
346
497
|
def remove_attribute(attr)
|
347
498
|
C.LLVMRemoveFunctionAttr(self, attr)
|
348
499
|
end
|
349
|
-
|
500
|
+
|
350
501
|
def basic_blocks
|
351
502
|
@basic_block_collection ||= BasicBlockCollection.new(self)
|
352
503
|
end
|
353
|
-
|
504
|
+
|
354
505
|
class BasicBlockCollection
|
506
|
+
include Enumerable
|
507
|
+
|
355
508
|
def initialize(fun)
|
356
509
|
@fun = fun
|
357
510
|
end
|
358
|
-
|
511
|
+
|
359
512
|
def size
|
360
513
|
C.LLVMCountBasicBlocks(@fun)
|
361
514
|
end
|
362
|
-
|
515
|
+
|
516
|
+
def each
|
517
|
+
return to_enum :each unless block_given?
|
518
|
+
|
519
|
+
ptr = C.LLVMGetFirstBasicBlock(@fun)
|
520
|
+
0.upto(size-1) do |i|
|
521
|
+
yield BasicBlock.from_ptr(ptr)
|
522
|
+
ptr = C.LLVMGetNextBasicBlock(ptr)
|
523
|
+
end
|
524
|
+
|
525
|
+
self
|
526
|
+
end
|
527
|
+
|
363
528
|
def append(name = "")
|
364
|
-
BasicBlock.
|
529
|
+
BasicBlock.create(@fun, name)
|
365
530
|
end
|
366
|
-
|
531
|
+
|
367
532
|
def entry
|
368
533
|
BasicBlock.from_ptr(C.LLVMGetEntryBasicBlock(@fun))
|
369
534
|
end
|
535
|
+
|
536
|
+
def first
|
537
|
+
ptr = C.LLVMGetFirstBasicBlock(@fun)
|
538
|
+
BasicBlock.from_ptr(ptr) unless ptr.null?
|
539
|
+
end
|
540
|
+
|
541
|
+
def last
|
542
|
+
ptr = C.LLVMGetLastBasicBlock(@fun)
|
543
|
+
BasicBlock.from_ptr(ptr) unless ptr.null?
|
544
|
+
end
|
370
545
|
end
|
371
|
-
|
546
|
+
|
372
547
|
def params
|
373
548
|
@parameter_collection ||= ParameterCollection.new(self)
|
374
549
|
end
|
375
|
-
|
550
|
+
|
376
551
|
class ParameterCollection
|
377
552
|
def initialize(fun)
|
378
553
|
@fun = fun
|
379
554
|
end
|
380
|
-
|
555
|
+
|
381
556
|
def [](i)
|
382
557
|
Value.from_ptr(C.LLVMGetParam(@fun, i))
|
383
558
|
end
|
384
|
-
|
559
|
+
|
385
560
|
def size
|
386
561
|
C.LLVMCountParams(@fun)
|
387
562
|
end
|
388
|
-
|
563
|
+
|
389
564
|
include Enumerable
|
390
|
-
|
565
|
+
|
391
566
|
def each
|
567
|
+
return to_enum :each unless block_given?
|
392
568
|
0.upto(size-1) { |i| yield self[i] }
|
569
|
+
self
|
393
570
|
end
|
394
571
|
end
|
395
572
|
end
|
396
|
-
|
573
|
+
|
397
574
|
class GlobalAlias < GlobalValue
|
398
575
|
end
|
399
|
-
|
576
|
+
|
400
577
|
class GlobalVariable < GlobalValue
|
401
578
|
def initializer
|
402
579
|
Value.from_ptr(C.LLVMGetInitializer(self))
|
403
580
|
end
|
404
|
-
|
581
|
+
|
405
582
|
def initializer=(val)
|
406
583
|
C.LLVMSetInitializer(self, val)
|
407
584
|
end
|
408
|
-
|
585
|
+
|
409
586
|
def thread_local?
|
410
587
|
case C.LLVMIsThreadLocal(self)
|
411
588
|
when 0 then false
|
412
589
|
else true
|
413
590
|
end
|
414
591
|
end
|
415
|
-
|
592
|
+
|
416
593
|
def thread_local=(local)
|
417
594
|
C.LLVMSetThreadLocal(self, local ? 1 : 0)
|
418
595
|
end
|
419
596
|
end
|
420
|
-
|
421
|
-
class Instruction <
|
597
|
+
|
598
|
+
class Instruction < User
|
599
|
+
def parent
|
600
|
+
ptr = C.LLVMGetInstructionParent(self)
|
601
|
+
LLVM::BasicBlock.from_ptr(ptr) unless ptr.null?
|
602
|
+
end
|
603
|
+
|
604
|
+
def next
|
605
|
+
ptr = C.LLVMGetNextInstruction(self)
|
606
|
+
LLVM::Instruction.from_ptr(ptr) unless ptr.null?
|
607
|
+
end
|
608
|
+
|
609
|
+
def previous
|
610
|
+
ptr = C.LLVMGetPreviousInstruction(self)
|
611
|
+
LLVM::Instruction.from_ptr(ptr) unless ptr.null?
|
612
|
+
end
|
422
613
|
end
|
423
|
-
|
614
|
+
|
424
615
|
class CallInst < Instruction
|
425
616
|
def call_conv=(conv)
|
426
617
|
C.LLVMSetInstructionCallConv(self, conv)
|
427
618
|
conv
|
428
619
|
end
|
429
|
-
|
620
|
+
|
430
621
|
def call_conv
|
431
622
|
C.LLVMGetInstructionCallConv(self)
|
432
623
|
end
|
433
624
|
end
|
434
|
-
|
625
|
+
|
435
626
|
class Phi < Instruction
|
436
627
|
# Add incoming branches to a phi node by passing an alternating list
|
437
628
|
# of resulting values and basic blocks. e.g.
|
@@ -441,11 +632,11 @@ module LLVM
|
|
441
632
|
incoming.each_with_index do |node, i|
|
442
633
|
(i % 2 == 0 ? vals : blocks) << node
|
443
634
|
end
|
444
|
-
|
635
|
+
|
445
636
|
unless vals.size == blocks.size
|
446
637
|
raise ArgumentError, "Expected vals.size and blocks.size to match"
|
447
638
|
end
|
448
|
-
|
639
|
+
|
449
640
|
size = vals.size
|
450
641
|
FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |vals_ptr|
|
451
642
|
vals_ptr.write_array_of_pointer(vals)
|
@@ -454,11 +645,11 @@ module LLVM
|
|
454
645
|
C.LLVMAddIncoming(self, vals_ptr, blocks_ptr, vals.size)
|
455
646
|
end
|
456
647
|
end
|
457
|
-
|
648
|
+
|
458
649
|
nil
|
459
650
|
end
|
460
651
|
end
|
461
|
-
|
652
|
+
|
462
653
|
class SwitchInst < Instruction
|
463
654
|
# Adds a case to a switch instruction. First the value to match on,
|
464
655
|
# then the basic block.
|