ruby-llvm 2.7.0

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