ruby-llvm 2.7.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.
@@ -0,0 +1,30 @@
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
+ # Currently, only scalar transformation passes are supported.
5
+ class PassManager
6
+ def initialize(execution_engine)
7
+ ptr = C.LLVMCreatePassManager()
8
+ C.LLVMAddTargetData(
9
+ C.LLVMGetExecutionEngineTargetData(execution_engine), ptr)
10
+ @ptr = ptr
11
+ end
12
+
13
+ def to_ptr # :nodoc:
14
+ @ptr
15
+ end
16
+
17
+ def <<(name)
18
+ send(:"#{name}!")
19
+ self
20
+ end
21
+
22
+ def run(mod)
23
+ C.LLVMRunPassManager(self, mod)
24
+ end
25
+
26
+ def dispose
27
+ C.LLVMDisposePassManager(self)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,113 @@
1
+ module LLVM
2
+ class Type
3
+ class << self
4
+ private :new
5
+ end
6
+
7
+ def initialize(ptr) # :nodoc:
8
+ @ptr = ptr
9
+ end
10
+
11
+ def to_ptr # :nodoc:
12
+ @ptr
13
+ end
14
+
15
+ # LLVM's represents types uniquely, and supports pointer equality.
16
+ def ==(type)
17
+ case type
18
+ when LLVM::Type
19
+ @ptr == type.to_ptr
20
+ else
21
+ false
22
+ end
23
+ end
24
+
25
+ def size
26
+ Int64.from_ptr(C.LLVMSizeOf(self))
27
+ end
28
+
29
+ def align
30
+ Int64.from_ptr(C.LLVMAlignOf(self))
31
+ end
32
+
33
+ def self.from_ptr(ptr)
34
+ ptr.null? ? nil : new(ptr)
35
+ end
36
+
37
+ def self.array(ty, sz = 0)
38
+ from_ptr(C.LLVMArrayType(LLVM::Type(ty), sz))
39
+ end
40
+
41
+ def self.pointer(ty, address_space = 0)
42
+ from_ptr(C.LLVMPointerType(LLVM::Type(ty), address_space))
43
+ end
44
+
45
+ def self.vector(ty, element_count)
46
+ from_ptr(C.LLVMVectorType(LLVM::Type(ty), element_count))
47
+ end
48
+
49
+ def self.function(arg_types, result_type)
50
+ arg_types.map! { |ty| LLVM::Type(ty) }
51
+ arg_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * arg_types.size)
52
+ 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))
54
+ end
55
+
56
+ def self.struct(elt_types, is_packed)
57
+ elt_types.map! { |ty| LLVM::Type(ty) }
58
+ elt_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * elt_types.size)
59
+ elt_types_ptr.write_array_of_pointer(elt_types)
60
+ from_ptr(C.LLVMStructType(elt_types_ptr, elt_types.size, is_packed ? 1 : 0))
61
+ end
62
+
63
+ def self.void
64
+ from_ptr(C.LLVMVoidType)
65
+ end
66
+
67
+ def self.opaque
68
+ from_ptr(C.LLVMOpaqueType)
69
+ end
70
+
71
+ def self.rec
72
+ h = opaque
73
+ ty = yield h
74
+ h.refine(ty)
75
+ ty
76
+ end
77
+
78
+ def refine(ty)
79
+ C.LLVMRefineType(self, ty)
80
+ end
81
+ end
82
+
83
+ def LLVM.Type(ty)
84
+ case ty
85
+ when LLVM::Type then ty
86
+ else ty.type
87
+ end
88
+ end
89
+
90
+ def LLVM.Array(ty, sz = 0)
91
+ LLVM::Type.array(ty, sz)
92
+ end
93
+
94
+ def LLVM.Pointer(ty)
95
+ LLVM::Type.pointer(ty)
96
+ end
97
+
98
+ def LLVM.Vector(ty, sz)
99
+ LLVM::Type.vector(ty, sz)
100
+ end
101
+
102
+ def LLVM.Function(argtypes, rettype)
103
+ LLVM::Type.function(argtypes, rettype)
104
+ end
105
+
106
+ def LLVM.Struct(*elt_types)
107
+ LLVM::Type.struct(elt_types, false)
108
+ end
109
+
110
+ def LLVM.Void
111
+ LLVM::Type.void
112
+ end
113
+ end
@@ -0,0 +1,469 @@
1
+ module LLVM
2
+ class Value
3
+ def self.from_ptr(ptr)
4
+ new(ptr) unless ptr.null?
5
+ end
6
+
7
+ class << self
8
+ private :new
9
+ end
10
+
11
+ def initialize(ptr)
12
+ @ptr = ptr
13
+ end
14
+
15
+ def to_ptr # :nodoc:
16
+ @ptr
17
+ end
18
+
19
+ def self.type
20
+ raise NotImplementedError, "Value.type is abstract"
21
+ end
22
+
23
+ def self.to_ptr
24
+ type.to_ptr
25
+ end
26
+
27
+ def type
28
+ Type.from_ptr(C.LLVMTypeOf(self))
29
+ end
30
+
31
+ def name
32
+ C.LLVMGetValueName(self)
33
+ end
34
+
35
+ def name=(str)
36
+ C.LLVMSetValueName(self, str)
37
+ str
38
+ end
39
+
40
+ def dump
41
+ C.LLVMDumpValue(self)
42
+ end
43
+
44
+ def constant?
45
+ case C.LLVMIsConstant(self)
46
+ when 0 then false
47
+ when 1 then true
48
+ end
49
+ end
50
+
51
+ def null?
52
+ case C.LLVMIsNull(self)
53
+ when 0 then false
54
+ when 1 then true
55
+ end
56
+ end
57
+
58
+ def undefined?
59
+ case C.LLVMIsUndef(self)
60
+ when 0 then false
61
+ when 1 then true
62
+ end
63
+ end
64
+
65
+ def add_attribute(attr)
66
+ C.LLVMAddAttribute(self, attr)
67
+ end
68
+ end
69
+
70
+ class Argument < Value
71
+ end
72
+
73
+ class BasicBlock < Value
74
+ def build(builder = nil)
75
+ if builder.nil?
76
+ builder = Builder.create
77
+ islocal = true
78
+ else
79
+ islocal = false
80
+ end
81
+ builder.position_at_end(self)
82
+ yield builder
83
+ ensure
84
+ builder.dispose
85
+ end
86
+ end
87
+
88
+ class Constant < Value
89
+ def self.type
90
+ raise NotImplementedError, "Constant.type() is abstract."
91
+ end
92
+
93
+ def self.null
94
+ from_ptr(C.LLVMConstNull(type))
95
+ end
96
+
97
+ def self.undef
98
+ from_ptr(C.LLVMGetUndef(type))
99
+ end
100
+
101
+ def self.null_ptr
102
+ from_ptr(C.LLVMConstPointerNull(type))
103
+ end
104
+ end
105
+
106
+ class ConstantArray < Constant
107
+ def self.string(str, null_terminate = true)
108
+ from_ptr(C.LLVMConstString(str, null_terminate ? 0 : 1))
109
+ end
110
+
111
+ def self.const(type, size)
112
+ vals = (0...size).map { |i| yield i }
113
+ from_ptr C.LLVMConstArray(type, vals, size)
114
+ end
115
+ end
116
+
117
+ class ConstantExpr < Constant
118
+ end
119
+
120
+ class ConstantInt < Constant
121
+ def self.all_ones
122
+ from_ptr(C.LLVMConstAllOnes(type))
123
+ end
124
+
125
+ def self.from_i(n, signed = true)
126
+ from_ptr(C.LLVMConstInt(type, n, signed ? 1 : 0))
127
+ end
128
+
129
+ def self.parse(str, radix = 10)
130
+ from_ptr(C.LLVMConstIntOfString(type, str, radix))
131
+ end
132
+
133
+ def -@
134
+ self.class.from_ptr(C.LLVMConstNeg(self))
135
+ end
136
+
137
+ def not
138
+ self.class.from_ptr(C.LLVMConstNot(self))
139
+ end
140
+
141
+ def +(rhs)
142
+ self.class.from_ptr(C.LLVMConstAdd(self, rhs))
143
+ end
144
+
145
+ def nsw_add(rhs)
146
+ self.class.from_ptr(C.LLVMConstNSWAdd(self, rhs))
147
+ end
148
+
149
+ def *(rhs)
150
+ self.class.from_ptr(C.LLVMConstMul(self, rhs))
151
+ end
152
+
153
+ def udiv(rhs)
154
+ self.class.from_ptr(C.LLVMConstUDiv(self, rhs))
155
+ end
156
+
157
+ def /(rhs)
158
+ self.class.from_ptr(C.LLVMConstSDiv(self, rhs))
159
+ end
160
+
161
+ def urem(rhs)
162
+ self.class.from_ptr(C.LLVMConstURem(self, rhs))
163
+ end
164
+
165
+ def rem(rhs)
166
+ self.class.from_ptr(C.LLVMConstSRem(self, rhs))
167
+ end
168
+
169
+ def and(rhs) # Ruby's && cannot be overloaded
170
+ self.class.from_ptr(C.LLVMConstAnd(self, rhs))
171
+ end
172
+
173
+ def or(rhs) # Nor is ||.
174
+ self.class.from_ptr(C.LLVMConstOr(self, rhs))
175
+ end
176
+
177
+ def xor(rhs) # Nor is ||.
178
+ self.class.from_ptr(C.LLVMConstXor(self, rhs))
179
+ end
180
+
181
+ def icmp(pred, rhs)
182
+ self.class.from_ptr(C.LLVMConstICmp(pred, self, rhs))
183
+ end
184
+
185
+ def <<(bits)
186
+ self.class.from_ptr(C.LLVMConstShl(self, rhs))
187
+ end
188
+
189
+ def >>(bits)
190
+ self.class.from_ptr(C.LLVMConstLShr(self, rhs))
191
+ end
192
+
193
+ def ashr(bits)
194
+ self.class.from_ptr(C.LLVMConstAShr(self, rhs))
195
+ end
196
+ end
197
+
198
+ def LLVM.const_missing(const) # :nodoc:
199
+ case const.to_s
200
+ when /Int(\d+)/
201
+ width = $1.to_i
202
+ name = "Int#{width}"
203
+ eval <<-KLASS
204
+ class #{name} < ConstantInt
205
+ def self.type
206
+ Type.from_ptr(C.LLVMIntType(#{width}))
207
+ end
208
+ end
209
+ KLASS
210
+ const_get(name)
211
+ else
212
+ super
213
+ end
214
+ end
215
+
216
+ # Native integer type
217
+ ::LLVM::Int = const_get("Int#{NATIVE_INT_SIZE}")
218
+
219
+ def LLVM.Int(val)
220
+ case val
221
+ when LLVM::ConstantInt then val
222
+ when Integer then Int.from_i(val)
223
+ end
224
+ end
225
+
226
+ class ConstantReal < Constant
227
+ def self.from_f(n)
228
+ from_ptr(C.LLVMConstReal(type, n))
229
+ end
230
+
231
+ def self.parse(str)
232
+ from_ptr(C.LLVMConstRealOfString(type, str))
233
+ end
234
+
235
+ def -@
236
+ self.class.from_ptr(C.LLVMConstFNeg(self))
237
+ end
238
+
239
+ def +(rhs)
240
+ self.class.from_ptr(C.LLVMConstFAdd(self, rhs))
241
+ end
242
+
243
+ def *(rhs)
244
+ self.class.from_ptr(C.LLVMConstFMul(self, rhs))
245
+ end
246
+
247
+ def /(rhs)
248
+ self.class.from_ptr(C.LLVMConstFDiv(self, rhs))
249
+ end
250
+
251
+ def rem(rhs)
252
+ self.class.from_ptr(C.LLVMConstFRem(self, rhs))
253
+ end
254
+
255
+ def fcmp(pred, rhs)
256
+ self.class.from_ptr(C.LLMVConstFCmp(pred, self, rhs))
257
+ end
258
+ end
259
+
260
+ class Float < ConstantReal
261
+ def self.type
262
+ Type.from_ptr(C.LLVMFloatType)
263
+ end
264
+ end
265
+
266
+ def LLVM.Float(val)
267
+ Float.from_f(val)
268
+ end
269
+
270
+ class Double < ConstantReal
271
+ def self.type
272
+ Type.from_ptr(C.LLVMDoubleType)
273
+ end
274
+ end
275
+
276
+ def LLVM.Double(val)
277
+ Double.from_f(val)
278
+ end
279
+
280
+ class ConstantStruct < Constant
281
+ def self.const(size, packed = false)
282
+ vals = (0..size).map { |i| yield i }
283
+ from_ptr(C.LLVMConstStruct(vals, size, packed ? 1 : 0))
284
+ end
285
+ end
286
+
287
+ class ConstantVector < Constant
288
+ def self.all_ones
289
+ from_ptr(C.LLVMConstAllOnes(type))
290
+ end
291
+
292
+ def self.const(size)
293
+ vals = (0..size).map { |i| yield i }
294
+ from_ptr(C.LLVMConstVector(vals, size))
295
+ end
296
+ end
297
+
298
+ class GlobalValue < Constant
299
+ def declaration?
300
+ C.LLVMIsDeclaration(self)
301
+ end
302
+
303
+ def linkage
304
+ C.LLVMGetLinkage(self)
305
+ end
306
+
307
+ def linkage=(linkage)
308
+ C.LLVMSetLinkage(self, linkage)
309
+ end
310
+
311
+ def section
312
+ C.LLVMGetSection(self)
313
+ end
314
+
315
+ def section=(section)
316
+ C.LLVMSetSection(self, section)
317
+ end
318
+
319
+ def visibility
320
+ C.LLVMGetVisibility(self)
321
+ end
322
+
323
+ def visibility=(viz)
324
+ C.LLVMSetVisibility(self, viz)
325
+ end
326
+
327
+ def alignment
328
+ C.LLVMGetAlignment(self)
329
+ end
330
+
331
+ def alignment=(bytes)
332
+ C.LLVMSetAlignment(self, bytes)
333
+ end
334
+ end
335
+
336
+ class Function < GlobalValue
337
+ def call_conv=(conv)
338
+ C.LLVMSetFunctionCallConv(self, conv)
339
+ conv
340
+ end
341
+
342
+ def add_attribute(attr)
343
+ C.LLVMAddFunctionAttr(self, attr)
344
+ end
345
+
346
+ def remove_attribute(attr)
347
+ C.LLVMRemoveFunctionAttr(self, attr)
348
+ end
349
+
350
+ def basic_blocks
351
+ @basic_block_collection ||= BasicBlockCollection.new(self)
352
+ end
353
+
354
+ class BasicBlockCollection
355
+ def initialize(fun)
356
+ @fun = fun
357
+ end
358
+
359
+ def size
360
+ C.LLVMCountBasicBlocks(@fun)
361
+ end
362
+
363
+ def append(name = "")
364
+ BasicBlock.from_ptr(C.LLVMAppendBasicBlock(@fun, name))
365
+ end
366
+
367
+ def entry
368
+ BasicBlock.from_ptr(C.LLVMGetEntryBasicBlock(@fun))
369
+ end
370
+ end
371
+
372
+ def params
373
+ @parameter_collection ||= ParameterCollection.new(self)
374
+ end
375
+
376
+ class ParameterCollection
377
+ def initialize(fun)
378
+ @fun = fun
379
+ end
380
+
381
+ def [](i)
382
+ Value.from_ptr(C.LLVMGetParam(@fun, i))
383
+ end
384
+
385
+ def size
386
+ C.LLVMCountParams(@fun)
387
+ end
388
+
389
+ include Enumerable
390
+
391
+ def each
392
+ 0.upto(size-1) { |i| yield self[i] }
393
+ end
394
+ end
395
+ end
396
+
397
+ class GlobalAlias < GlobalValue
398
+ end
399
+
400
+ class GlobalVariable < GlobalValue
401
+ def initializer
402
+ Value.from_ptr(C.LLVMGetInitializer(self))
403
+ end
404
+
405
+ def initializer=(val)
406
+ C.LLVMSetInitializer(self, val)
407
+ end
408
+
409
+ def thread_local?
410
+ case C.LLVMIsThreadLocal(self)
411
+ when 0 then false
412
+ else true
413
+ end
414
+ end
415
+
416
+ def thread_local=(local)
417
+ C.LLVMSetThreadLocal(self, local ? 1 : 0)
418
+ end
419
+ end
420
+
421
+ class Instruction < Value
422
+ end
423
+
424
+ class CallInst < Instruction
425
+ def call_conv=(conv)
426
+ C.LLVMSetInstructionCallConv(self, conv)
427
+ conv
428
+ end
429
+
430
+ def call_conv
431
+ C.LLVMGetInstructionCallConv(self)
432
+ end
433
+ end
434
+
435
+ class Phi < Instruction
436
+ # Add incoming branches to a phi node by passing an alternating list
437
+ # of resulting values and basic blocks. e.g.
438
+ # phi.add_incoming(val1, block1, val2, block2, ...)
439
+ def add_incoming(*incoming)
440
+ vals, blocks = [], []
441
+ incoming.each_with_index do |node, i|
442
+ (i % 2 == 0 ? vals : blocks) << node
443
+ end
444
+
445
+ unless vals.size == blocks.size
446
+ raise ArgumentError, "Expected vals.size and blocks.size to match"
447
+ end
448
+
449
+ size = vals.size
450
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |vals_ptr|
451
+ vals_ptr.write_array_of_pointer(vals)
452
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |blocks_ptr|
453
+ blocks_ptr.write_array_of_pointer(blocks)
454
+ C.LLVMAddIncoming(self, vals_ptr, blocks_ptr, vals.size)
455
+ end
456
+ end
457
+
458
+ nil
459
+ end
460
+ end
461
+
462
+ class SwitchInst < Instruction
463
+ # Adds a case to a switch instruction. First the value to match on,
464
+ # then the basic block.
465
+ def add_case(val, block)
466
+ C.LLVMAddCase(self, val, block)
467
+ end
468
+ end
469
+ end