waj-ruby-llvm 2.9.2
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 +31 -0
- data/ext/ruby-llvm-support/Makefile.am +1 -0
- data/ext/ruby-llvm-support/Makefile.in +612 -0
- data/ext/ruby-llvm-support/config.guess +1500 -0
- data/ext/ruby-llvm-support/config.sub +1616 -0
- data/ext/ruby-llvm-support/configure +17190 -0
- data/ext/ruby-llvm-support/configure.ac +16 -0
- data/ext/ruby-llvm-support/depcomp +584 -0
- data/ext/ruby-llvm-support/install-sh +507 -0
- data/ext/ruby-llvm-support/libtool +9403 -0
- data/ext/ruby-llvm-support/ltmain.sh +8745 -0
- data/ext/ruby-llvm-support/missing +367 -0
- data/ext/ruby-llvm-support/src/Makefile.am +5 -0
- data/ext/ruby-llvm-support/src/Makefile.in +472 -0
- data/ext/ruby-llvm-support/src/support.cpp +12 -0
- data/lib/llvm.rb +12 -0
- data/lib/llvm/analysis.rb +62 -0
- data/lib/llvm/core.rb +598 -0
- data/lib/llvm/core/bitcode.rb +88 -0
- data/lib/llvm/core/builder.rb +851 -0
- data/lib/llvm/core/context.rb +22 -0
- data/lib/llvm/core/module.rb +232 -0
- data/lib/llvm/core/pass_manager.rb +76 -0
- data/lib/llvm/core/type.rb +173 -0
- data/lib/llvm/core/value.rb +782 -0
- data/lib/llvm/execution_engine.rb +169 -0
- data/lib/llvm/support.rb +22 -0
- data/lib/llvm/target.rb +9 -0
- data/lib/llvm/transforms/ipo.rb +23 -0
- data/lib/llvm/transforms/scalar.rb +136 -0
- data/test/array_test.rb +38 -0
- data/test/basic_block_test.rb +88 -0
- data/test/basic_test.rb +11 -0
- data/test/binary_operations_test.rb +58 -0
- data/test/bitcode_test.rb +25 -0
- data/test/branch_test.rb +57 -0
- data/test/call_test.rb +82 -0
- data/test/comparisons_test.rb +66 -0
- data/test/conversions_test.rb +86 -0
- data/test/double_test.rb +33 -0
- data/test/equality_test.rb +91 -0
- data/test/generic_value_test.rb +22 -0
- data/test/instruction_test.rb +32 -0
- data/test/ipo_test.rb +53 -0
- data/test/memory_access_test.rb +38 -0
- data/test/module_test.rb +21 -0
- data/test/parameter_collection_test.rb +28 -0
- data/test/phi_test.rb +33 -0
- data/test/select_test.rb +22 -0
- data/test/struct_test.rb +75 -0
- data/test/test_helper.rb +50 -0
- data/test/type_test.rb +15 -0
- data/test/vector_test.rb +64 -0
- metadata +133 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class GenericValueTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_from_i
|
10
|
+
assert_equal 2, LLVM::GenericValue.from_i(2).to_i
|
11
|
+
assert_equal 2 ,LLVM::GenericValue.from_i(2.2).to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_from_float
|
15
|
+
assert_in_delta 2.2, LLVM::GenericValue.from_f(2.2).to_f, 1e-6
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_from_double
|
19
|
+
assert_in_delta 2.2, LLVM::GenericValue.from_d(2.2).to_f(LLVM::Double), 1e-6
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class InstructionTestCase < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
LLVM.init_x86
|
6
|
+
@module = LLVM::Module.new("InstructionTestCase")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_instruction
|
10
|
+
fn = @module.functions.add("test_instruction", [LLVM::Double], LLVM::Double) do |fn, arg|
|
11
|
+
fn.basic_blocks.append.build do |builder|
|
12
|
+
builder.ret(
|
13
|
+
builder.fadd(arg, LLVM.Double(3.0)))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
entry = fn.basic_blocks.entry
|
18
|
+
|
19
|
+
inst1 = entry.instructions.first
|
20
|
+
inst2 = entry.instructions.last
|
21
|
+
|
22
|
+
assert_kind_of LLVM::Instruction, inst1
|
23
|
+
assert_kind_of LLVM::Instruction, inst2
|
24
|
+
|
25
|
+
assert_equal inst2, inst1.next
|
26
|
+
assert_equal inst1, inst2.previous
|
27
|
+
assert_equal entry, inst1.parent
|
28
|
+
assert_equal entry, inst2.parent
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
data/test/ipo_test.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "llvm/core"
|
3
|
+
require 'llvm/transforms/ipo'
|
4
|
+
require 'llvm/core/pass_manager'
|
5
|
+
|
6
|
+
class IPOTestCase < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
LLVM.init_x86
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_gdce
|
13
|
+
mod = LLVM::Module.new('test')
|
14
|
+
|
15
|
+
fn1 = mod.functions.add("fn1", [], LLVM.Void) do |fn|
|
16
|
+
fn.linkage = :internal
|
17
|
+
fn.basic_blocks.append.build do |builder|
|
18
|
+
builder.ret_void
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
fn2 = mod.functions.add("fn2", [], LLVM.Void) do |fn|
|
23
|
+
fn.linkage = :internal
|
24
|
+
fn.basic_blocks.append.build do |builder|
|
25
|
+
builder.ret_void
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
main = mod.functions.add("main", [], LLVM.Void) do |fn|
|
30
|
+
fn.basic_blocks.append.build do |builder|
|
31
|
+
builder.call(fn1)
|
32
|
+
builder.ret_void
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
fns = mod.functions.to_a
|
37
|
+
assert fns.include?(fn1)
|
38
|
+
assert fns.include?(fn2)
|
39
|
+
assert fns.include?(main)
|
40
|
+
|
41
|
+
# optimize
|
42
|
+
engine = LLVM::JITCompiler.new(mod)
|
43
|
+
passm = LLVM::PassManager.new(engine)
|
44
|
+
|
45
|
+
passm.gdce!
|
46
|
+
passm.run(mod)
|
47
|
+
|
48
|
+
fns = mod.functions.to_a
|
49
|
+
assert fns.include?(fn1)
|
50
|
+
assert !fns.include?(fn2), 'fn2 should be eliminated'
|
51
|
+
assert fns.include?(main)
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class MemoryAccessTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_memory_access
|
10
|
+
assert_equal 1 + 2, simple_memory_access_function(1, 2).to_i
|
11
|
+
assert_equal 3 + 4, array_memory_access_function(3, 4).to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def simple_memory_access_function(value1, value2)
|
15
|
+
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
16
|
+
entry = function.basic_blocks.append
|
17
|
+
builder.position_at_end(entry)
|
18
|
+
pointer1 = builder.alloca(LLVM::Int)
|
19
|
+
pointer2 = builder.alloca(LLVM::Int)
|
20
|
+
builder.store(arguments.first, pointer1)
|
21
|
+
builder.store(arguments.last, pointer2)
|
22
|
+
builder.ret(builder.add(builder.load(pointer1), builder.load(pointer2)))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def array_memory_access_function(value1, value2)
|
27
|
+
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
28
|
+
entry = function.basic_blocks.append
|
29
|
+
builder.position_at_end(entry)
|
30
|
+
pointer = builder.array_alloca(LLVM::Int, LLVM::Int(2))
|
31
|
+
builder.store(arguments.first, builder.gep(pointer, [LLVM::Int(0)]))
|
32
|
+
builder.store(arguments.last, builder.gep(pointer, [LLVM::Int(1)]))
|
33
|
+
builder.ret(builder.add(builder.load(builder.gep(pointer, [LLVM::Int(0)])),
|
34
|
+
builder.load(builder.gep(pointer, [LLVM::Int(1)]))))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/test/module_test.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ModuleTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_simple_module
|
10
|
+
assert_equal 1, simple_function().to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
def simple_function
|
14
|
+
run_function([], [], LLVM::Int) do |builder, function, *arguments|
|
15
|
+
entry = function.basic_blocks.append
|
16
|
+
builder.position_at_end(entry)
|
17
|
+
builder.ret(LLVM::Int(1))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ParameterCollectionTestCase < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@mod = LLVM::Module.new('test')
|
6
|
+
@fun = @mod.functions.add('fun', [LLVM::Int, LLVM::Int], LLVM::Int)
|
7
|
+
@fun.params[0].name = 'foo'
|
8
|
+
@fun.params[1].name = 'bar'
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_positive_index_in_range
|
12
|
+
assert_equal 'foo', @fun.params[0].name
|
13
|
+
assert_equal 'bar', @fun.params[1].name
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_negative_index_in_range
|
17
|
+
assert_equal 'foo', @fun.params[-2].name
|
18
|
+
assert_equal 'bar', @fun.params[-1].name
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_positive_index_out_of_range
|
22
|
+
assert_nil @fun.params[2]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_negative_index_out_of_range
|
26
|
+
assert_nil @fun.params[-3]
|
27
|
+
end
|
28
|
+
end
|
data/test/phi_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class PhiTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
LLVM.init_x86
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_phi
|
9
|
+
assert_equal 1, run_phi_function(0).to_i
|
10
|
+
assert_equal 0, run_phi_function(1).to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
def run_phi_function(argument)
|
14
|
+
run_function([LLVM::Int], argument, LLVM::Int) do |builder, function, *arguments|
|
15
|
+
entry = function.basic_blocks.append
|
16
|
+
block1 = function.basic_blocks.append
|
17
|
+
block2 = function.basic_blocks.append
|
18
|
+
exit = function.basic_blocks.append
|
19
|
+
builder.position_at_end(entry)
|
20
|
+
builder.cond(builder.icmp(:eq, arguments.first, LLVM::Int(0)), block1, block2)
|
21
|
+
builder.position_at_end(block1)
|
22
|
+
result1 = builder.add(arguments.first, LLVM::Int(1))
|
23
|
+
builder.br(exit)
|
24
|
+
builder.position_at_end(block2)
|
25
|
+
result2 = builder.sub(arguments.first, LLVM::Int(1))
|
26
|
+
builder.br(exit)
|
27
|
+
builder.position_at_end(exit)
|
28
|
+
builder.ret(builder.phi(LLVM::Int,
|
29
|
+
block1 => result1,
|
30
|
+
block2 => result2))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/select_test.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class SelectTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_select
|
10
|
+
assert_equal 0, select_function(1).to_i
|
11
|
+
assert_equal 1, select_function(0).to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def select_function(value)
|
15
|
+
run_function([LLVM::Int1], [value], LLVM::Int) do |builder, function, *arguments|
|
16
|
+
entry = function.basic_blocks.append
|
17
|
+
builder.position_at_end(entry)
|
18
|
+
builder.ret(builder.select(arguments.first, LLVM::Int(0), LLVM::Int(1)))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/test/struct_test.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class StructTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
LLVM_UNPACKED = false
|
6
|
+
LLVM_PACKED = true
|
7
|
+
|
8
|
+
def setup
|
9
|
+
LLVM.init_x86
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_simple_struct
|
13
|
+
struct = LLVM::Struct(LLVM::Int, LLVM::Float)
|
14
|
+
assert_instance_of LLVM::Type, struct
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_unpacked_constant_struct_from_size
|
18
|
+
struct = LLVM::ConstantStruct.const(2, LLVM_UNPACKED) { |i| LLVM::Int(i) }
|
19
|
+
assert_instance_of LLVM::ConstantStruct, struct
|
20
|
+
assert_equal 2, struct.operands.size
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_unpacked_constant_struct_from_struct
|
24
|
+
struct = LLVM::ConstantStruct.const([LLVM::Int(0), LLVM::Int(1)], LLVM_UNPACKED)
|
25
|
+
assert_instance_of LLVM::ConstantStruct, struct
|
26
|
+
assert_equal 2, struct.operands.size
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_packed_constant_struct_from_size
|
30
|
+
struct = LLVM::ConstantStruct.const(2, LLVM_PACKED) { |i| LLVM::Int(i) }
|
31
|
+
assert_instance_of LLVM::ConstantStruct, struct
|
32
|
+
assert_equal 2, struct.operands.size
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_packed_constant_struct_from_struct
|
36
|
+
struct = LLVM::ConstantStruct.const([LLVM::Int(0), LLVM::Int(1)], LLVM_PACKED)
|
37
|
+
assert_instance_of LLVM::ConstantStruct, struct
|
38
|
+
assert_equal 2, struct.operands.size
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_struct_values
|
42
|
+
assert_equal 2 + 3, run_struct_values(2, 3).to_i
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_struct_access
|
46
|
+
assert_in_delta 2 + 3.3, run_struct_access(LLVM::Float, 2, 3.3).to_f, 0.001
|
47
|
+
end
|
48
|
+
|
49
|
+
def run_struct_values(value1, value2)
|
50
|
+
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
51
|
+
entry = function.basic_blocks.append
|
52
|
+
builder.position_at_end(entry)
|
53
|
+
pointer = builder.alloca(LLVM::Struct(LLVM::Int, LLVM::Int))
|
54
|
+
struct = builder.load(pointer)
|
55
|
+
struct = builder.insert_value(struct, arguments.first, 0)
|
56
|
+
struct = builder.insert_value(struct, arguments.last, 1)
|
57
|
+
builder.ret(builder.add(builder.extract_value(struct, 0),
|
58
|
+
builder.extract_value(struct, 1)))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def run_struct_access(return_type, value1, value2)
|
63
|
+
run_function([LLVM::Int, LLVM::Float], [value1, value2], return_type) do |builder, function, *arguments|
|
64
|
+
entry = function.basic_blocks.append
|
65
|
+
builder.position_at_end(entry)
|
66
|
+
pointer = builder.alloca(LLVM::Struct(LLVM::Float, LLVM::Struct(LLVM::Int, LLVM::Float), LLVM::Int))
|
67
|
+
builder.store(arguments.first, builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(0)]))
|
68
|
+
builder.store(arguments.last, builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(1)]))
|
69
|
+
address1 = builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(0)])
|
70
|
+
address2 = builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(1)])
|
71
|
+
builder.ret(builder.fadd(builder.ui2fp(builder.load(address1), LLVM::Float), builder.load(address2)))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "ruby-debug"
|
5
|
+
rescue LoadError
|
6
|
+
# Ignore ruby-debug is case it's not installed
|
7
|
+
end
|
8
|
+
|
9
|
+
require "test/unit"
|
10
|
+
|
11
|
+
require "llvm/core"
|
12
|
+
require "llvm/execution_engine"
|
13
|
+
require "llvm/transforms/scalar"
|
14
|
+
|
15
|
+
class Test::Unit::TestCase
|
16
|
+
|
17
|
+
LLVM_SIGNED = true
|
18
|
+
LLVM_UNSIGNED = false
|
19
|
+
|
20
|
+
LLVM_FALSE = 0
|
21
|
+
LLVM_TRUE = 1
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def define_module(module_name)
|
26
|
+
new_module = LLVM::Module.new(module_name)
|
27
|
+
yield new_module
|
28
|
+
new_module.verify
|
29
|
+
new_module
|
30
|
+
end
|
31
|
+
|
32
|
+
def define_function(host_module, function_name, argument_types, return_type)
|
33
|
+
host_module.functions.add(function_name, argument_types, return_type) do |function, *arguments|
|
34
|
+
yield(LLVM::Builder.new, function, *arguments)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def run_function_on_module(host_module, function_name, *argument_values)
|
39
|
+
LLVM::JITCompiler.new(host_module).
|
40
|
+
run_function(host_module.functions[function_name], *argument_values)
|
41
|
+
end
|
42
|
+
|
43
|
+
def run_function(argument_types, argument_values, return_type, &block)
|
44
|
+
test_module = define_module("test_module") do |host_module|
|
45
|
+
define_function(host_module, "test_function", argument_types, return_type, &block)
|
46
|
+
end
|
47
|
+
|
48
|
+
run_function_on_module(test_module, "test_function", *argument_values)
|
49
|
+
end
|
50
|
+
|
data/test/type_test.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TypeTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_element_type
|
6
|
+
pointer = LLVM.Pointer(LLVM::Int32.type)
|
7
|
+
pointee = pointer.element_type
|
8
|
+
|
9
|
+
assert_equal :pointer, pointer.kind
|
10
|
+
assert_equal :integer, pointee.kind
|
11
|
+
|
12
|
+
assert_nil pointee.element_type
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/test/vector_test.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class VectorTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_all_ones_vector
|
10
|
+
assert_raise(NotImplementedError) do
|
11
|
+
LLVM::ConstantVector.all_ones
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_constant_vector_from_size
|
16
|
+
vector = LLVM::ConstantVector.const(2) { |i| LLVM::Int(i) }
|
17
|
+
assert_instance_of LLVM::ConstantVector, vector
|
18
|
+
assert_equal 2, vector.operands.size
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_constant_vector_from_array
|
22
|
+
vector = LLVM::ConstantVector.const([LLVM::Int(0), LLVM::Int(1)])
|
23
|
+
assert_instance_of LLVM::ConstantVector, vector
|
24
|
+
assert_equal 2, vector.operands.size
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_vector_elements
|
28
|
+
assert_equal 2 + 3, run_vector_elements(2, 3).to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_vector_shuffle
|
32
|
+
assert_equal 1 + 4, run_vector_shuffle(1, 2, 3, 4).to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def run_vector_elements(value1, value2)
|
36
|
+
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
37
|
+
entry = function.basic_blocks.append
|
38
|
+
builder.position_at_end(entry)
|
39
|
+
pointer = builder.alloca(LLVM::Vector(LLVM::Int, 2))
|
40
|
+
vector = builder.load(pointer)
|
41
|
+
vector = builder.insert_element(vector, arguments.first, LLVM::Int32.from_i(0))
|
42
|
+
vector = builder.insert_element(vector, arguments.last, LLVM::Int32.from_i(1))
|
43
|
+
builder.ret(builder.add(builder.extract_element(vector, LLVM::Int32.from_i(0)),
|
44
|
+
builder.extract_element(vector, LLVM::Int32.from_i(1))))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def run_vector_shuffle(*values)
|
49
|
+
run_function([LLVM::Int, LLVM::Int, LLVM::Int, LLVM::Int], values, LLVM::Int) do |builder, function, *arguments|
|
50
|
+
entry = function.basic_blocks.append
|
51
|
+
builder.position_at_end(entry)
|
52
|
+
vector1 = builder.load(builder.alloca(LLVM::Vector(LLVM::Int, 2)))
|
53
|
+
vector1 = builder.insert_element(vector1, arguments[0], LLVM::Int32.from_i(0))
|
54
|
+
vector1 = builder.insert_element(vector1, arguments[1], LLVM::Int32.from_i(1))
|
55
|
+
vector2 = builder.load(builder.alloca(LLVM::Vector(LLVM::Int, 2)))
|
56
|
+
vector2 = builder.insert_element(vector2, arguments[2], LLVM::Int32.from_i(0))
|
57
|
+
vector2 = builder.insert_element(vector2, arguments[3], LLVM::Int32.from_i(1))
|
58
|
+
vector3 = builder.shuffle_vector(vector1, vector2, LLVM::ConstantVector.const([LLVM::Int(0), LLVM::Int(3)]))
|
59
|
+
builder.ret(builder.add(builder.extract_element(vector3, LLVM::Int32.from_i(0)),
|
60
|
+
builder.extract_element(vector3, LLVM::Int32.from_i(1))))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|