plessl-llvmruby 0.0.3

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,11 @@
1
+ module LLVM
2
+
3
+ module Version
4
+ MAJOR = 0
5
+ MINOR = 0
6
+ TINY = 1
7
+
8
+ STRING = [ MAJOR, MINOR, TINY ].join( "." )
9
+ end
10
+
11
+ end
Binary file
@@ -0,0 +1,340 @@
1
+ require 'test/unit'
2
+ $:.unshift File.dirname(__FILE__) + "/../ext"
3
+ require 'llvm'
4
+
5
+ include LLVM
6
+
7
+ class BasicTests < Test::Unit::TestCase
8
+ def function_tester(expected)
9
+ m = LLVM::Module.new("test_module")
10
+ type = Type::function(MACHINE_WORD, [])
11
+ f = m.get_or_insert_function("test", type)
12
+ yield(f)
13
+ ExecutionEngine.get(m);
14
+ assert_equal(expected, ExecutionEngine.run_autoconvert(f))
15
+ end
16
+
17
+ def test_module
18
+ function_tester(5) do |f|
19
+ b = f.create_block.builder
20
+ v = b.add(2.llvm, 3.llvm)
21
+ b.return(v)
22
+ end
23
+ end
24
+
25
+ def bin_op(op, v1, v2, expected)
26
+ function_tester(expected) do |f|
27
+ b = f.create_block.builder
28
+ ret = b.bin_op(op, v1.llvm, v2.llvm)
29
+ b.return(ret)
30
+ end
31
+ end
32
+
33
+ def test_bin_ops
34
+ bin_op(Instruction::Add, 2, 3, 5)
35
+ bin_op(Instruction::Sub, 5, 3, 2)
36
+ bin_op(Instruction::Mul, 2, 3, 6)
37
+ bin_op(Instruction::UDiv, 42, 6, 7)
38
+ bin_op(Instruction::SDiv, 42, 6, 7)
39
+ #bin_op(Instruction::FDiv, 23.0, 5, 0.23)
40
+ bin_op(Instruction::URem, 23, 5, 3)
41
+ bin_op(Instruction::SRem, 23, 5, 3)
42
+ #bin_op(Instruction::FRem, 23.0, 5, 0.23)
43
+
44
+ bin_op(Instruction::Shl, 2, 1, 4)
45
+ bin_op(Instruction::LShr, 8, 1, 4)
46
+ #bin_op(Instruction::AShr, 8, 1, 4)
47
+ bin_op(Instruction::And, 8, 15, 8)
48
+ bin_op(Instruction::Or, 8, 15, 15)
49
+ bin_op(Instruction::Xor, 8, 15, 7)
50
+ end
51
+
52
+ def builder_bin_op(op, v1, v2, expected)
53
+ function_tester(expected) do |f|
54
+ b = f.create_block.builder
55
+ ret = b.send(op, v1.llvm, v2.llvm)
56
+ b.return(ret)
57
+ end
58
+ end
59
+
60
+ def test_builder_bin_ops
61
+ builder_bin_op(:add, 23, 42, 65)
62
+ builder_bin_op(:sub, 69, 13, 56)
63
+ builder_bin_op(:mul, 23, 5, 115)
64
+ builder_bin_op(:udiv, 23, 5, 4)
65
+ builder_bin_op(:sdiv, 99, 33, 3)
66
+ #builder_bin_op(:fdiv, 23, 42, 65)
67
+ builder_bin_op(:urem, 23, 42, 23)
68
+ builder_bin_op(:srem, 77, 5, 2)
69
+ #builder_bin_op(:frem, 23, 42, 65)
70
+ builder_bin_op(:shl, 15, 1, 30)
71
+ builder_bin_op(:lshr, 32, 2, 8)
72
+ #builder_bin_op(:ashr, 23, 42, 65)
73
+ builder_bin_op(:and, 32, 37, 32)
74
+ builder_bin_op(:or, 15, 8, 15)
75
+ builder_bin_op(:xor, 33, 15, 46)
76
+ end
77
+
78
+ def test_insert_point
79
+ function_tester(2) do |f|
80
+ b1 = f.create_block
81
+ b2 = f.create_block
82
+ builder = b1.builder
83
+ builder.br(b2)
84
+ builder.set_insert_point(b2)
85
+ builder.return(2.llvm)
86
+ end
87
+ end
88
+
89
+ def test_builder_utils
90
+ function_tester(5) do |f|
91
+ b = f.create_block.builder
92
+ b.write do
93
+ ret = add(2.llvm, 3.llvm)
94
+ self.return(ret)
95
+ end
96
+ end
97
+ end
98
+
99
+ def test_cmps
100
+ m = LLVM::Module.new("test_cmps")
101
+ type = Type.function(MACHINE_WORD, [])
102
+ f = m.get_or_insert_function("sgt", type)
103
+
104
+ entry_block = f.create_block
105
+ exit_block_true = f.create_block
106
+ exit_block_false = f.create_block
107
+
108
+ b = entry_block.builder
109
+ cmp = b.icmp_sgt(-1.llvm, 1.llvm)
110
+ b.cond_br(cmp, exit_block_true, exit_block_false)
111
+
112
+ b = exit_block_true.builder
113
+ b.return(1.llvm)
114
+
115
+ b = exit_block_false.builder
116
+ b.return(0.llvm)
117
+
118
+ ExecutionEngine.get(m)
119
+ result = ExecutionEngine.run_autoconvert(f)
120
+ assert_equal(0, result)
121
+ end
122
+
123
+ def test_fcmps
124
+ m = LLVM::Module.new('test_fcmps')
125
+ type = Type.function(MACHINE_WORD, [])
126
+ f = m.get_or_insert_function('ult', type)
127
+
128
+ entry_block = f.create_block
129
+ exit_block_true = f.create_block
130
+ exit_block_false = f.create_block
131
+
132
+ b = entry_block.builder
133
+ cmp = b.fcmp_ult(1.0.llvm, 2.0.llvm)
134
+ b.cond_br(cmp, exit_block_true, exit_block_false)
135
+
136
+ b = exit_block_true.builder
137
+ b.return(0.llvm)
138
+
139
+ b = exit_block_false.builder
140
+ b.return(1.llvm)
141
+
142
+ ExecutionEngine.get(m)
143
+ result = ExecutionEngine.run_autoconvert(f)
144
+ assert_equal(0, result)
145
+ end
146
+
147
+ def test_function_calls
148
+ m = LLVM::Module.new('test_module')
149
+ type = Type::function(MACHINE_WORD, [])
150
+ f_caller = m.get_or_insert_function("caller", type)
151
+ type = Type::function(MACHINE_WORD, [MACHINE_WORD, MACHINE_WORD])
152
+ f_callee = m.get_or_insert_function("callee", type)
153
+
154
+ b = f_callee.create_block.builder
155
+ x, y = f_callee.arguments
156
+ sum = b.add(x, y)
157
+ b.return(sum)
158
+
159
+ b = f_caller.create_block.builder
160
+ ret = b.call(f_callee, 2.llvm, 3.llvm)
161
+ b.return(ret)
162
+
163
+ ExecutionEngine.get(m)
164
+ result = ExecutionEngine.run_autoconvert(f_caller)
165
+ assert_equal(5, result)
166
+ end
167
+
168
+ def test_phi_node
169
+ m = LLVM::Module.new('test_module')
170
+ type = Type::function(MACHINE_WORD, [])
171
+ f = m.get_or_insert_function('phi_node', type)
172
+
173
+ entry_block = f.create_block
174
+ loop_block = f.create_block
175
+ exit_block = f.create_block
176
+
177
+ b = entry_block.builder
178
+ b.br(loop_block)
179
+
180
+ b = loop_block.builder
181
+ phi = b.phi(MACHINE_WORD)
182
+ phi.add_incoming(0.llvm, entry_block)
183
+ count = b.add(phi, 1.llvm)
184
+ phi.add_incoming(count, loop_block)
185
+ cmp = b.icmp_ult(count, 10.llvm)
186
+ b.cond_br(cmp, loop_block, exit_block)
187
+
188
+ b = exit_block.builder
189
+ b.return(phi)
190
+
191
+ ExecutionEngine.get(m)
192
+ result = ExecutionEngine.run_autoconvert(f)
193
+ assert_equal(9, result)
194
+ end
195
+
196
+ def test_bitcode_writer
197
+ m = LLVM::Module.new('static_module')
198
+ # create main function
199
+ type = Type.function(Type::Int32Ty, [
200
+ Type::Int32Ty,
201
+ Type.pointer(Type.pointer(Type::Int8Ty))
202
+ ])
203
+ f = m.get_or_insert_function('main', type)
204
+ b = f.create_block.builder
205
+ b.return(666.llvm(Type::Int32Ty))
206
+
207
+ m.write_bitcode("test/static.o")
208
+ end
209
+
210
+ def test_type_errors
211
+ m = LLVM::Module.new('type_errors')
212
+ ftype = Type.function(Type::Int32Ty, [])
213
+ assert_raise(TypeError) { f = LLVM::Module.new(5) }
214
+ assert_raise(TypeError) { m.get_or_insert_function(5, ftype) }
215
+ assert_raise(TypeError) { m.get_or_insert_function('bad_arg', 5) }
216
+ assert_raise(TypeError) { ExecutionEngine.get(5) }
217
+ assert_raise(TypeError) { m.external_function(5, ftype) }
218
+ assert_raise(TypeError) { m.external_function('fname', 5) }
219
+ assert_raise(TypeError) { m.write_bitcode(5) }
220
+ assert_raise(ArgumentError) { ExecutionEngine.run_function }
221
+ assert_raise(TypeError) { ExecutionEngine.run_function(5) }
222
+ assert_raise(TypeError) { ExecutionEngine.run_function(5, 5) }
223
+
224
+ f = m.get_or_insert_function('test', ftype)
225
+ block1 = f.create_block
226
+ block2 = f.create_block
227
+ b = block1.builder
228
+ assert_raise(TypeError) { b.set_insert_point(5) }
229
+ assert_raise(TypeError) { b.phi(5) }
230
+ phi = b.phi(Type::Int32Ty)
231
+ assert_raise(TypeError) { phi.add_incoming(5, 5) }
232
+ assert_raise(TypeError) { phi.add_incoming(5.llvm(Type::Int32Ty), 5) }
233
+ assert_raise(TypeError) { b.bin_op([], 2.llvm, 3.llvm) }
234
+ assert_raise(TypeError) { b.bin_op(Instruction::Add, 5, 3.llvm) }
235
+ assert_raise(TypeError) { b.bin_op(Instruction::Add, 3.llvm, 5) }
236
+ end
237
+
238
+ def test_inspectors
239
+ m = LLVM::Module.new('example')
240
+ ftype = Type.function(Type::Int32Ty, [])
241
+ f = m.get_or_insert_function('inspect', ftype)
242
+ b = f.create_block.builder
243
+ b.return(5.llvm(Type::Int32Ty))
244
+
245
+ assert_match(/define i32 @inspect\(\)/, m.inspect)
246
+ assert_match(/define i32 @inspect\(\)/, f.inspect)
247
+ end
248
+
249
+ def test_global_strings
250
+ m = LLVM::Module.new('globalstrings')
251
+ ftype = Type.function(Type::Int32Ty, [])
252
+ f = m.get_or_insert_function('use_global_strings', ftype)
253
+ b = f.create_block.builder
254
+ v = b.create_global_string_ptr("SHAKA KHAN")
255
+ end
256
+
257
+ def test_var_arg_ftypes
258
+ ftype = Type.function(Type::Int32Ty, [], true)
259
+ end
260
+
261
+ def test_struct_constants
262
+ int_t = Type::Int32Ty
263
+ struct_type = Type.struct([int_t, int_t, int_t])
264
+ struct_const = Value.get_struct_constant(struct_type, 2.llvm(int_t), 3.llvm(int_t), 5.llvm(int_t))
265
+ assert_kind_of(Value, struct_const)
266
+
267
+ m = LLVM::Module.new('globals')
268
+ gv = m.global_variable(struct_type, struct_const)
269
+ assert_kind_of(Value, gv)
270
+ end
271
+
272
+ def test_malloc_free
273
+ function_tester(23) do |f|
274
+ b = f.create_block.builder
275
+ new_space = b.malloc(MACHINE_WORD, 1)
276
+ assert_kind_of(AllocationInst, new_space)
277
+ assert(!new_space.array_allocation?)
278
+ assert_kind_of(Value, new_space.array_size)
279
+ assert_kind_of(Type, new_space.allocated_type)
280
+ assert_equal(0, new_space.alignment)
281
+
282
+ store_inst = b.store(23.llvm(MACHINE_WORD), new_space)
283
+ assert(store_inst.may_write_to_memory?)
284
+ v = b.load(new_space)
285
+ free_inst = b.free(new_space)
286
+ assert_kind_of(FreeInst, free_inst)
287
+ b.return(v)
288
+ end
289
+ end
290
+
291
+ def test_cast
292
+ function_tester(5) do |f|
293
+ b = f.create_block.builder
294
+ b.return(b.cast(Instruction::FPToSI, 5.0.llvm, MACHINE_WORD))
295
+ end
296
+ end
297
+
298
+ def test_switch
299
+ function_tester(23) do |f|
300
+ b = f.create_block.builder
301
+ default = f.create_block
302
+ on5 = f.create_block
303
+ switch = b.switch(5.llvm, default)
304
+ switch.add_case(5.llvm, on5)
305
+ assert_instance_of(SwitchInst, switch)
306
+ assert_equal(2, switch.get_num_cases);
307
+
308
+ b = default.builder
309
+ b.return(7.llvm(MACHINE_WORD))
310
+
311
+ b = on5.builder
312
+ b.return(23.llvm)
313
+ end
314
+ end
315
+
316
+ def test_vector
317
+ function_tester(666) do |f|
318
+ b = f.create_block.builder
319
+ vt = Type.vector(MACHINE_WORD, 3)
320
+ vp = b.alloca(vt, 0)
321
+ v = b.load(vp)
322
+ v2 = b.insert_element(v, 666.llvm(MACHINE_WORD), 0.llvm(Type::Int32Ty))
323
+ r = b.extract_element(v2, 0.llvm(Type::Int32Ty))
324
+ b.return(r)
325
+ end
326
+ end
327
+
328
+ def test_pass_manager_run
329
+ m = LLVM::Module.new('test')
330
+ assert PassManager.new.run(m)
331
+ end
332
+
333
+ def test_type_to_s
334
+ assert_equal "i32", 2.llvm.type.to_s
335
+ end
336
+
337
+ def test_type_type_id
338
+ assert_equal IntegerTyID, 2.llvm.type.type_id
339
+ end
340
+ end
@@ -0,0 +1,80 @@
1
+ require 'test/unit'
2
+ require 'llvm'
3
+
4
+ include LLVM
5
+
6
+ class BasicBlockTests < Test::Unit::TestCase
7
+
8
+ def setup
9
+
10
+ @assembly_gcd=<<-EOF
11
+ ; ModuleID = 'gcd.o'
12
+ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
13
+ target triple = "i386-apple-darwin9"
14
+
15
+ define i32 @gcd(i32 %a, i32 %b) nounwind {
16
+ entry:
17
+ %tmp2 = icmp eq i32 %a, 0 ; <i1> [#uses=1]
18
+ br i1 %tmp2, label %bb26, label %bb19
19
+
20
+ bb5: ; preds = %bb19, %bb11
21
+ %indvar48 = phi i32 [ %indvar.next49, %bb11 ], [ 0, %bb19 ] ; <i32> [#uses=2]
22
+ %tmp50 = sub i32 0, %b_addr.0 ; <i32> [#uses=1]
23
+ %tmp51 = mul i32 %indvar48, %tmp50 ; <i32> [#uses=1]
24
+ %a_addr.0.reg2mem.0 = add i32 %tmp51, %a_addr.0 ; <i32> [#uses=3]
25
+ %tmp8 = icmp sgt i32 %a_addr.0.reg2mem.0, %b_addr.0 ; <i1> [#uses=1]
26
+ br i1 %tmp8, label %bb11, label %bb15.split
27
+
28
+ bb11: ; preds = %bb5
29
+ %indvar.next49 = add i32 %indvar48, 1 ; <i32> [#uses=1]
30
+ br label %bb5
31
+
32
+ bb15.split: ; preds = %bb5
33
+ %tmp18 = sub i32 %b_addr.0, %a_addr.0.reg2mem.0 ; <i32> [#uses=1]
34
+ br label %bb19
35
+
36
+ bb19: ; preds = %bb15.split, %entry
37
+ %b_addr.0 = phi i32 [ %tmp18, %bb15.split ], [ %b, %entry ] ; <i32> [#uses=4]
38
+ %a_addr.0 = phi i32 [ %a_addr.0.reg2mem.0, %bb15.split ], [ %a, %entry ] ; <i32> [#uses=2]
39
+ %tmp21 = icmp eq i32 %b_addr.0, 0 ; <i1> [#uses=1]
40
+ br i1 %tmp21, label %bb26, label %bb5
41
+
42
+ bb26: ; preds = %bb19, %entry
43
+ %tmp.0 = phi i32 [ %b, %entry ], [ %a_addr.0, %bb19 ] ; <i32> [#uses=1]
44
+ ret i32 %tmp.0
45
+ }
46
+ EOF
47
+
48
+ end
49
+
50
+
51
+ def test_count_intructions_in_basic_block
52
+ m = LLVM::Module.read_assembly(@assembly_gcd)
53
+ gcd = m.get_function("gcd")
54
+ assert(gcd)
55
+
56
+ bbs = gcd.get_basic_block_list
57
+ expected = { 'entry' => 2, 'bb5' => 6, 'bb11' => 2, 'bb15.split' => 2, 'bb19' => 4, 'bb26' => 2 }
58
+ res = Hash.new
59
+ bbs.each { |b|
60
+ res[b.name] = b.size
61
+ }
62
+ assert_equal(expected,res)
63
+ end
64
+
65
+ def test_manipulate_values
66
+ m = LLVM::Module.read_assembly(@assembly_gcd)
67
+ gcd = m.get_function("gcd")
68
+
69
+ bbs = gcd.get_basic_block_list
70
+ bb = bbs.first
71
+ assert_equal('entry', bb.name)
72
+ bb.name = 'first_block'
73
+ assert_equal('first_block', bb.name)
74
+ assert_equal(3, bb.num_uses)
75
+ bb2 = bbs.find {|x| x.name == 'bb19'}
76
+ assert(bb.used_in_basic_block?(bb2))
77
+ bb3 = bbs.find {|x| x.name = 'bb26'}
78
+ assert(!bb.used_in_basic_block?(bb3))
79
+ end
80
+ end
@@ -0,0 +1,112 @@
1
+ require 'test/unit'
2
+ require 'llvm'
3
+
4
+ include LLVM
5
+
6
+ class InstructionTests < Test::Unit::TestCase
7
+
8
+ def setup
9
+
10
+ @assembly_byteswap=<<-EOF
11
+ ; ModuleID = 'byteswap.bc'
12
+ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
13
+ target triple = "i386-apple-darwin9"
14
+
15
+ define i32 @bswap(i32 %x) nounwind {
16
+ entry:
17
+ %tmp3 = shl i32 %x, 24 ; <i32> [#uses=1]
18
+ %tmp5 = shl i32 %x, 8 ; <i32> [#uses=1]
19
+ %tmp6 = and i32 %tmp5, 16711680 ; <i32> [#uses=1]
20
+ %tmp9 = lshr i32 %x, 8 ; <i32> [#uses=1]
21
+ %tmp1018 = and i32 %tmp9, 65280 ; <i32> [#uses=1]
22
+ %tmp7 = or i32 %tmp1018, %tmp3 ; <i32> [#uses=1]
23
+ %tmp11 = or i32 %tmp7, %tmp6 ; <i32> [#uses=1]
24
+ ret i32 %tmp11
25
+ }
26
+ EOF
27
+
28
+ end
29
+
30
+ def test_count_intructions_in_basic_block
31
+ m = LLVM::Module.read_assembly(@assembly_byteswap)
32
+ bswap = m.get_function("bswap")
33
+ assert(bswap)
34
+
35
+ bbs = bswap.get_basic_block_list
36
+ assert_equal(1,bbs.size)
37
+ b = bbs[0]
38
+ assert_equal(8,b.size)
39
+
40
+ expected_opcodes_in_bswap = ["shl", "shl", "and", "lshr", "and", "or", "or", "ret"]
41
+ ins = b.get_instruction_list
42
+ actual_opcodes_in_bswap = ins.map { |i| i.get_opcode_name}
43
+ assert_equal(expected_opcodes_in_bswap, actual_opcodes_in_bswap)
44
+
45
+ assert_kind_of(BinaryOperator, ins.first)
46
+ assert_kind_of(ReturnInst, ins.last)
47
+
48
+ f1, f2 = ins[0], ins[1]
49
+ assert(!f1.may_read_from_memory?)
50
+ assert(!f1.may_write_to_memory?)
51
+ assert(!f1.identical_to?(f2))
52
+ assert(f1.identical_to?(f1))
53
+ assert(f1.same_operation_as?(f2))
54
+ assert(f1.same_operation_as?(f1))
55
+ assert(!f1.used_outside_of_block?(b))
56
+ end
57
+
58
+ def test_instruction_classes
59
+ #m = LLVM::Module.read_assembly(@assembly_byteswap)
60
+ #bswap = m.get_function('bswap')
61
+ end
62
+
63
+ def test_branch_instructions
64
+ m = LLVM::Module.new('branch_instructions')
65
+ ExecutionEngine.get(m)
66
+ type = Type::function(MACHINE_WORD, [])
67
+
68
+ f = m.get_or_insert_function("test_br", type)
69
+ b1 = f.create_block
70
+ b2 = f.create_block
71
+ b3 = f.create_block
72
+ b4 = f.create_block
73
+ b5 = f.create_block
74
+
75
+ b = b1.builder
76
+ br_inst = b.br(b2)
77
+
78
+ b = b2.builder
79
+ cmp1 = b.icmp_sgt(-1.llvm, 1.llvm)
80
+ cmp2 = b.icmp_slt(-1.llvm, 1.llvm)
81
+ cond_br_inst = b.cond_br(cmp1, b3, b4)
82
+
83
+ b = b3.builder
84
+ b.return(23.llvm)
85
+
86
+ b = b4.builder
87
+ b.return(5.llvm)
88
+
89
+ b = b5.builder
90
+ ret_inst = b.return(1999.llvm)
91
+
92
+ assert_kind_of(BranchInst, br_inst)
93
+ assert(br_inst.unconditional?)
94
+ assert(!br_inst.conditional?)
95
+ assert_equal(1, br_inst.num_successors)
96
+ assert_kind_of(BasicBlock, br_inst.get_successor(0))
97
+
98
+ assert_kind_of(BranchInst, cond_br_inst)
99
+ assert(cond_br_inst.conditional?)
100
+ assert(!cond_br_inst.unconditional?)
101
+ assert_kind_of(Value, cond_br_inst.condition)
102
+ assert_equal(2, cond_br_inst.num_successors)
103
+ assert_kind_of(BasicBlock, cond_br_inst.get_successor(1))
104
+
105
+ assert_kind_of(ReturnInst, ret_inst)
106
+ assert_equal(0, ret_inst.num_successors)
107
+
108
+ cond_br_inst.condition = cmp2
109
+ cond_br_inst.set_successor(0, b5)
110
+ assert_equal(1999, ExecutionEngine.run_autoconvert(f))
111
+ end
112
+ end