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,377 @@
1
+ module LLVM
2
+ class Builder
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
+ def self.create
16
+ new(C.LLVMCreateBuilder())
17
+ end
18
+
19
+ def position_at_end(block)
20
+ C.LLVMPositionBuilderAtEnd(self, block)
21
+ self
22
+ end
23
+
24
+ def get_insert_block
25
+ BasicBlock.from_ptr(C.LLVMGetInsertBlock(self))
26
+ end
27
+
28
+ # Terminators
29
+
30
+ def ret_void
31
+ Instruction.from_ptr(C.LLVMBuildRetVoid(self))
32
+ end
33
+
34
+ def ret(val)
35
+ Instruction.from_ptr(C.LLVMBuildRet(self, val))
36
+ end
37
+
38
+ def aggregate_ret(*vals)
39
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * vals.size) do |vals_ptr|
40
+ vals_ptr.write_array_of_pointer(vals)
41
+ Instruction.from_ptr(C.LLVMBuildAggregateRet(self, vals_ptr, vals.size))
42
+ end
43
+ end
44
+
45
+ def br(block)
46
+ Instruction.from_ptr(
47
+ C.LLVMBuildBr(self, block))
48
+ end
49
+
50
+ def cond(cond, iftrue, iffalse)
51
+ Instruction.from_ptr(
52
+ C.LLVMBuildCondBr(self, cond, iftrue, iffalse))
53
+ end
54
+
55
+ def switch(val, block, ncases)
56
+ SwitchInst.from_ptr(C.LLVMBuildSwitch(self, val, block, ncases))
57
+ end
58
+
59
+ def invoke(fun, args, _then, _catch, name = "")
60
+ Instruction.from_ptr(
61
+ C.LLVMBuildInvoke(self,
62
+ fun, args, args.size, _then, _catch, name))
63
+ end
64
+
65
+ def unwind
66
+ Instruction.from_ptr(C.LLVMBuildUnwind(self))
67
+ end
68
+
69
+ def unreachable
70
+ Instruction.from_ptr(C.LLVMBuildUnreachable(self))
71
+ end
72
+
73
+ # Arithmetic
74
+
75
+ def add(lhs, rhs, name = "")
76
+ Instruction.from_ptr(C.LLVMBuildAdd(self, lhs, rhs, name))
77
+ end
78
+
79
+ def nsw_add(lhs, rhs, name = "")
80
+ Instruction.from_ptr(C.LLVMBuildNSWAdd(self, lhs, rhs, name))
81
+ end
82
+
83
+ def fadd(lhs, rhs, name = "")
84
+ Instruction.from_ptr(C.LLVMBuildFAdd(self, lhs, rhs, name))
85
+ end
86
+
87
+ def sub(lhs, rhs, name = "")
88
+ Instruction.from_ptr(C.LLVMBuildSub(self, lhs, rhs, name))
89
+ end
90
+
91
+ def fsub(lhs, rhs, name = "")
92
+ Instruction.from_ptr(C.LLVMBuildFSub(self, lhs, rhs, name))
93
+ end
94
+
95
+ def mul(lhs, rhs, name = "")
96
+ Instruction.from_ptr(C.LLVMBuildMul(self, lhs, rhs, name))
97
+ end
98
+
99
+ def fmul(lhs, rhs, name = "")
100
+ Instruction.from_ptr(C.LLVMBuildFMul(self, lhs, rhs, name))
101
+ end
102
+
103
+ def udiv(lhs, rhs, name = "")
104
+ Instruction.from_ptr(C.LLVMBuildUDiv(self, lhs, rhs, name))
105
+ end
106
+
107
+ def sdiv(lhs, rhs, name = "")
108
+ Instruction.from_ptr(C.LLVMBuildSDiv(self, lhs, rhs, name))
109
+ end
110
+
111
+ def exact_sdiv(lhs, rhs, name = "")
112
+ Instruction.from_ptr(C.LLVMBuildExactSDiv(self, lhs, rhs, name))
113
+ end
114
+
115
+ def fdiv(lhs, rhs, name = "")
116
+ Instruction.from_ptr(C.LLVMBuildFDiv(self, lhs, rhs, name))
117
+ end
118
+
119
+ def urem(lhs, rhs, name = "")
120
+ Instruction.from_ptr(C.LLVMBuildURem(self, lhs, rhs, name))
121
+ end
122
+
123
+ def srem(lhs, rhs, name = "")
124
+ Instruction.from_ptr(C.LLVMBuildSRem(self, lhs, rhs, name))
125
+ end
126
+
127
+ def frem(lhs, rhs, name = "")
128
+ Instruction.from_ptr(C.LLVMBuildFRem(self, lhs, rhs, name))
129
+ end
130
+
131
+ def shl(lhs, rhs, name = "")
132
+ Instruction.from_ptr(C.LLVMBuildShl(self, lhs, rhs, name))
133
+ end
134
+
135
+ def lshr(lhs, rhs, name = "")
136
+ Instruction.from_ptr(C.LLVMBuildLShr(self, lhs, rhs, name))
137
+ end
138
+
139
+ def ashr(lhs, rhs, name = "")
140
+ Instruction.from_ptr(C.LLVMBuildAShr(self, lhs, rhs, name))
141
+ end
142
+
143
+ def and(lhs, rhs, name = "")
144
+ Instruction.from_ptr(C.LLVMBuildAnd(self, lhs, rhs, name))
145
+ end
146
+
147
+ def or(lhs, rhs, name = "")
148
+ Instruction.from_ptr(C.LLVMBuildOr(self, lhs, rhs, name))
149
+ end
150
+
151
+ def xor(lhs, rhs, name = "")
152
+ Instruction.from_ptr(C.LLVMBuildXor(self, lhs, rhs, name))
153
+ end
154
+
155
+ def neg(arg, name = "")
156
+ Instruction.from_ptr(C.LLVMBuildNeg(self, arg, name))
157
+ end
158
+
159
+ def not(arg, name = "")
160
+ Instruction.from_ptr(C.LLVMBuildNot(self, arg, name))
161
+ end
162
+
163
+ # Memory
164
+
165
+ def malloc(ty, name = "")
166
+ Instruction.from_ptr(C.LLVMBuildMalloc(self, LLVM::Type(ty), name))
167
+ end
168
+
169
+ def array_malloc(ty, val, name = "")
170
+ Instruction.from_ptr(C.LLVMBuildArrayMalloc(self, LLVM::Type(ty), val, name))
171
+ end
172
+
173
+ def alloca(ty, name = "")
174
+ Instruction.from_ptr(C.LLVMBuildAlloca(self, LLVM::Type(ty), name))
175
+ end
176
+
177
+ def array_alloca(ty, val, name = "")
178
+ Instruction.from_ptr(C.LLVMBuildArrayAlloca(self, LLVM::Type(ty), val, name))
179
+ end
180
+
181
+ def free(pointer)
182
+ Instruction.from_ptr(C.LLVMBuildFree(self, pointer))
183
+ end
184
+
185
+ def load(pointer, name = "")
186
+ Instruction.from_ptr(C.LLVMBuildLoad(self, pointer, name))
187
+ end
188
+
189
+ def store(val, pointer)
190
+ Instruction.from_ptr(C.LLVMBuildStore(self, val, pointer))
191
+ end
192
+
193
+ def gep(pointer, indices, name = "")
194
+ indices = Array(indices)
195
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * indices.size) do |indices_ptr|
196
+ indices_ptr.write_array_of_pointer(indices)
197
+ return Instruction.from_ptr(
198
+ C.LLVMBuildInBoundsGEP(self, pointer, indices_ptr, indices.size, name))
199
+ end
200
+ end
201
+
202
+ def inbounds_gep(pointer, indices, name = "")
203
+ indices = Array(indices)
204
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * indices.size) do |indices_ptr|
205
+ indices_ptr.write_array_of_pointer(indices)
206
+ return Instruction.from_ptr(
207
+ C.LLVMBuildGEP(self, pointer, indices_ptr, indices.size, name))
208
+ end
209
+ end
210
+
211
+ def struct_gep(pointer, idx, name = "")
212
+ Instruction.from_ptr(C.LLVMBuildStructGEP(self, pointer, idx, name))
213
+ end
214
+
215
+ def global_string(string, name = "")
216
+ Instruction.from_ptr(C.LLVMBuildGlobalString(self, string, name))
217
+ end
218
+
219
+ def global_string_pointer(string, name = "")
220
+ Instruction.from_ptr(C.LLVMBuildGlobalStringPointer(self, string, name))
221
+ end
222
+
223
+ # Casts
224
+
225
+ def trunc(val, ty, name = "")
226
+ Instruction.from_ptr(C.LLVMBuildTrunc(self, val, LLVM::Type(ty), name))
227
+ end
228
+
229
+ def zext(val, ty, name = "")
230
+ Instruction.from_ptr(C.LLVMBuildZExt(self, val, LLVM::Type(ty), name))
231
+ end
232
+
233
+ def sext(val, ty, name = "")
234
+ Instruction.from_ptr(C.LLVMBuildSExt(self, val, LLVM::Type(ty), name))
235
+ end
236
+
237
+ def fp2ui(val, ty, name = "")
238
+ Instruction.from_ptr(C.LLVMBuildFPToUI(self, val, LLVM::Type(ty), name))
239
+ end
240
+
241
+ def fp2si(val, ty, name = "")
242
+ Instruction.from_ptr(C.LLVMBuildFPToSI(self, val, LLVM::Type(ty), name))
243
+ end
244
+
245
+ def ui2fp(val, ty, name = "")
246
+ Instruction.from_ptr(C.LLVMBuildUIToFP(self, val, LLVM::Type(ty), name))
247
+ end
248
+
249
+ def si2fp(val, ty, name = "")
250
+ Instruction.from_ptr(C.LLVMBuildSIToFP(self, val, LLVM::Type(ty), name))
251
+ end
252
+
253
+ def fp_trunc(val, ty, name = "")
254
+ Instruction.from_ptr(C.LLVMBuildFPTrunc(self, val, LLVM::Type(ty), name))
255
+ end
256
+
257
+ def fp_ext(val, ty, name = "")
258
+ Instruction.from_ptr(C.LLVMBuildFPExt(self, val, LLVM::Type(ty), name))
259
+ end
260
+
261
+ def ptr2int(val, ty, name = "")
262
+ Instruction.from_ptr(C.LLVMBuildPtrToInt(self, val, LLVM::Type(ty), name))
263
+ end
264
+
265
+ def int2ptr(val, ty, name = "")
266
+ Instruction.from_ptr(C.LLVMBuildIntToPtr(self, val, LLVM::Type(ty), name))
267
+ end
268
+
269
+ def bit_cast(val, ty, name = "")
270
+ Instruction.from_ptr(C.LLVMBuildBitCast(self, val, LLVM::Type(ty), name))
271
+ end
272
+
273
+ def zext_or_bit_cast(val, ty, name = "")
274
+ Instruction.from_ptr(C.LLVMBuildZExtOrBitCast(self, val, LLVM::Type(ty), name))
275
+ end
276
+
277
+ def sext_or_bit_cast(val, ty, name = "")
278
+ Instruction.from_ptr(C.LLVMBuildSExtOrBitCast(self, val, LLVM::Type(ty), name))
279
+ end
280
+
281
+ def trunc_or_bit_cast(val, ty, name = "")
282
+ Instruction.from_ptr(C.LLVMBuildTruncOrBitCast(self, val, LLVM::Type(ty), name))
283
+ end
284
+
285
+ def pointer_cast(val, ty, name = "")
286
+ Instruction.from_ptr(C.LLVMBuildPointerCast(self, val, LLVM::Type(ty), name))
287
+ end
288
+
289
+ def int_cast(val, ty, name = "")
290
+ Instruction.from_ptr(C.LLVMBuildIntCast(self, val, LLVM::Type(ty), name))
291
+ end
292
+
293
+ def fp_cast(val, ty, name = "")
294
+ Instruction.from_ptr(C.LLVMBuildFPCast(self, val, LLVM::Type(ty), name))
295
+ end
296
+
297
+ # Comparisons
298
+
299
+ def icmp(pred, lhs, rhs, name = "")
300
+ Instruction.from_ptr(C.LLVMBuildICmp(self, pred, lhs, rhs, name))
301
+ end
302
+
303
+ def fcmp(pred, lhs, rhs, name = "")
304
+ Instruction.from_ptr(C.LLVMBuildFCmp(self, pred, lhs, rhs, name))
305
+ end
306
+
307
+ # Misc
308
+
309
+ def phi(ty, *incoming)
310
+ if incoming.last.kind_of? String
311
+ name = incomimg.pop
312
+ else
313
+ name = ""
314
+ end
315
+
316
+ phi = Phi.from_ptr(C.LLVMBuildPhi(self, LLVM::Type(ty), name))
317
+ phi.add_incoming(*incoming) unless incoming.empty?
318
+ phi
319
+ end
320
+
321
+ def call(fun, *args)
322
+ if args.last.kind_of? String
323
+ name = args.pop
324
+ else
325
+ name = ""
326
+ end
327
+
328
+ args_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * args.size)
329
+ args_ptr.write_array_of_pointer(args)
330
+ CallInst.from_ptr(C.LLVMBuildCall(self, fun, args_ptr, args.size, name))
331
+ end
332
+
333
+ def select(_if, _then, _else, name = "")
334
+ Instruction.from_ptr(C.LLVMBuildSelect(self, _if, _then, _else, name))
335
+ end
336
+
337
+ def va_arg(list, ty, name = "")
338
+ Instruction.from_ptr(C.LLVMBuildVAArg(self, list, LLVM::Type(ty), name))
339
+ end
340
+
341
+ def extract_element(vector, index, name = "")
342
+ Instruction.from_ptr(C.LLVMBuildExtractElement(self, vector, index, name))
343
+ end
344
+
345
+ def insert_element(vector, elem, index, name = "")
346
+ Instruction.from_ptr(C.LLVMBuildInsertElement(self, vector, elem, index, name))
347
+ end
348
+
349
+ def shuffle_vector(vec1, vec2, mask, name = "")
350
+ Instruction.from_ptr(C.LLVMBuildShuffleVector(self, vec1, vec2, mask, name))
351
+ end
352
+
353
+ def extract_value(aggregate, index, name = "")
354
+ Instruction.from_ptr(C.LLVMBuildExtractValue(self, aggregate, index, name))
355
+ end
356
+
357
+ def insert_value(aggregate, elem, index, name = "")
358
+ Instruction.from_ptr(C.LLVMBuildInsertValue(self, aggregate, elem, index, name))
359
+ end
360
+
361
+ def is_null(val, name = "")
362
+ Instruction.from_ptr(C.LLVMBuildIsNull(self, val, name))
363
+ end
364
+
365
+ def is_not_null(val, name = "")
366
+ Instruction.from_ptr(C.LLVMBuildIsNotNull(self, val, name))
367
+ end
368
+
369
+ def ptr_diff(lhs, rhs, name = "")
370
+ Instruction.from_ptr(C.LLVMBuildPtrDiff(lhs, rhs, name))
371
+ end
372
+
373
+ def dispose
374
+ C.LLVMDisposeBuilder(@ptr)
375
+ end
376
+ end
377
+ end
@@ -0,0 +1,29 @@
1
+ module LLVM
2
+ class Context
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
+ # Creates a new Context
16
+ def self.create
17
+ new(C.LLVMContextCreate())
18
+ end
19
+
20
+ # Obtains a reference to the global Context
21
+ def self.global
22
+ new(C.LLVMGetGlobalContext())
23
+ end
24
+
25
+ def dispose
26
+ C.LLVMContextDispose(@ptr)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,199 @@
1
+ module LLVM
2
+ class Module
3
+ class << self
4
+ private :new
5
+ end
6
+
7
+ def self.from_ptr(ptr)
8
+ ptr.null? ? nil : new(ptr)
9
+ end
10
+
11
+ def initialize(ptr) # :nodoc:
12
+ @ptr = ptr
13
+ end
14
+
15
+ def to_ptr # :nodoc:
16
+ @ptr
17
+ end
18
+
19
+ def self.create(name)
20
+ new(C.LLVMModuleCreateWithName(name))
21
+ end
22
+
23
+ def types
24
+ @types ||= TypeCollection.new(self)
25
+ end
26
+
27
+ class TypeCollection
28
+ def initialize(mod)
29
+ @module = mod
30
+ end
31
+
32
+ def add(name, type)
33
+ C.LLVMAddTypeName(@module, name.to_s, type)
34
+ end
35
+
36
+ def named(name)
37
+ Type.from_ptr(C.LLVMGetTypeByName(@module, name))
38
+ end
39
+
40
+ def [](key)
41
+ case key
42
+ when String then named(key)
43
+ when Symbol then named(key.to_s)
44
+ end
45
+ end
46
+
47
+ def []=(key, type)
48
+ add(key, type)
49
+ end
50
+ end
51
+
52
+ def globals
53
+ @globals ||= GlobalCollection.new(self)
54
+ end
55
+
56
+ class GlobalCollection
57
+ include Enumerable
58
+
59
+ def initialize(mod)
60
+ @module = mod
61
+ end
62
+
63
+ def add(ty, name)
64
+ GlobalVariable.from_ptr(C.LLVMAddGlobal(@module, LLVM::Type(ty), name))
65
+ end
66
+
67
+ def named(name)
68
+ GlobalValue.from_ptr(C.LLVMGetNamedGlobal(@module, name))
69
+ end
70
+
71
+ def first
72
+ GlobalValue.from_ptr(C.LLVMGetFirstGlobal(@module))
73
+ end
74
+
75
+ def last
76
+ GlobalValue.from_ptr(C.LLVMGetLastGlobal(@module))
77
+ end
78
+
79
+ def next(global)
80
+ GlobalValue.from_ptr(C.LLVMGetNextGlobal(global))
81
+ end
82
+
83
+ def previous(global)
84
+ GlobalValue.from_ptr(C.LLVMGetPreviousGlobal(global))
85
+ end
86
+
87
+ def delete(global)
88
+ C.LLVMDeleteGlobal(global)
89
+ end
90
+
91
+ def [](key)
92
+ case key
93
+ when String then named(key)
94
+ when Symbol then named(key.to_s)
95
+ when Integer then
96
+ i = 0
97
+ g = first
98
+ until i >= key || g.nil?
99
+ g = self.next(g)
100
+ i += 1
101
+ end
102
+ g
103
+ end
104
+ end
105
+
106
+ def each
107
+ g = first
108
+ until g.nil?
109
+ yield g
110
+ g = self.next(g)
111
+ end
112
+ end
113
+ end
114
+
115
+ def functions
116
+ @functions ||= FunctionCollection.new(self)
117
+ end
118
+
119
+ class FunctionCollection
120
+ include Enumerable
121
+
122
+ def initialize(mod)
123
+ @module = mod
124
+ end
125
+
126
+ def add(name, *args)
127
+ if args.first.kind_of? Type
128
+ type = args.first
129
+ else
130
+ type = Type.function(*args)
131
+ end
132
+ function = Function.from_ptr(C.LLVMAddFunction(@module, name.to_s, type))
133
+
134
+ if block_given?
135
+ params = (0...function.params.size).map { |i| function.params[i] }
136
+ yield function, *params
137
+ end
138
+
139
+ function
140
+ end
141
+
142
+ def named(name)
143
+ Function.from_ptr(C.LLVMGetNamedFunction(@module, name))
144
+ end
145
+
146
+ def first
147
+ Function.from_ptr(C.LLVMGetFirstFunction(@module))
148
+ end
149
+
150
+ def last
151
+ Function.from_ptr(C.LLVMGetLastFunction(@module))
152
+ end
153
+
154
+ def next(function)
155
+ Function.from_ptr(C.LLVMGetNextFunction(function))
156
+ end
157
+
158
+ def previous(function)
159
+ Function.from_ptr(C.LLVMGetPreviousFunction(function))
160
+ end
161
+
162
+ def delete(function)
163
+ C.LLVMDeleteFunction(function)
164
+ end
165
+
166
+ def [](key)
167
+ case key
168
+ when String then named(key)
169
+ when Symbol then named(key.to_s)
170
+ when Integer
171
+ i = 0
172
+ f = first
173
+ until i >= key || f.nil?
174
+ f = self.next(f)
175
+ i += 1
176
+ end
177
+ f
178
+ end
179
+ end
180
+
181
+ def each
182
+ f = first
183
+ until f.nil?
184
+ yield f
185
+ f = self.next(f)
186
+ end
187
+ end
188
+ end
189
+
190
+ # Print the module's IR to stdout
191
+ def dump
192
+ C.LLVMDumpModule(self)
193
+ end
194
+
195
+ def dispose
196
+ C.LLVMDisposeModule(@ptr)
197
+ end
198
+ end
199
+ end