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,169 @@
|
|
1
|
+
require 'llvm'
|
2
|
+
require 'llvm/core'
|
3
|
+
require 'llvm/target'
|
4
|
+
require 'llvm/analysis'
|
5
|
+
|
6
|
+
module LLVM
|
7
|
+
# @private
|
8
|
+
module C
|
9
|
+
# Generic values
|
10
|
+
attach_function :LLVMCreateGenericValueOfInt, [:pointer, :long_long, :int], :pointer
|
11
|
+
attach_function :LLVMCreateGenericValueOfPointer, [:pointer], :pointer
|
12
|
+
attach_function :LLVMCreateGenericValueOfFloat, [:pointer, :double], :pointer
|
13
|
+
|
14
|
+
attach_function :LLVMGenericValueIntWidth, [:pointer], :uint
|
15
|
+
|
16
|
+
attach_function :LLVMGenericValueToInt, [:pointer, :int], :long_long
|
17
|
+
attach_function :LLVMGenericValueToPointer, [:pointer], :pointer
|
18
|
+
attach_function :LLVMGenericValueToFloat, [:pointer, :pointer], :double
|
19
|
+
attach_function :LLVMDisposeGenericValue, [:pointer], :void
|
20
|
+
|
21
|
+
# Execution engines
|
22
|
+
attach_function :LLVMCreateExecutionEngineForModule, [:pointer, :pointer, :pointer], :int
|
23
|
+
attach_function :LLVMCreateInterpreterForModule, [:pointer, :pointer, :pointer], :int
|
24
|
+
attach_function :LLVMCreateJITCompilerForModule, [:pointer, :pointer, :uint, :pointer], :int
|
25
|
+
attach_function :LLVMDisposeExecutionEngine, [:pointer], :void
|
26
|
+
|
27
|
+
attach_function :LLVMRunStaticConstructors, [:pointer], :void
|
28
|
+
attach_function :LLVMRunStaticDestructors, [:pointer], :void
|
29
|
+
|
30
|
+
attach_function :LLVMRunFunctionAsMain, [:pointer, :pointer, :uint, :pointer, :pointer], :int
|
31
|
+
attach_function :LLVMRunFunction, [:pointer, :pointer, :uint, :pointer], :pointer
|
32
|
+
|
33
|
+
attach_function :LLVMFreeMachineCodeForFunction, [:pointer, :pointer], :void
|
34
|
+
attach_function :LLVMAddModuleProvider, [:pointer, :pointer], :void
|
35
|
+
attach_function :LLVMRemoveModuleProvider, [:pointer, :pointer, :pointer, :pointer], :int
|
36
|
+
|
37
|
+
attach_function :LLVMFindFunction, [:pointer, :pointer, :pointer, :pointer], :int
|
38
|
+
|
39
|
+
attach_function :LLVMGetExecutionEngineTargetData, [:pointer], :pointer
|
40
|
+
|
41
|
+
attach_function :LLVMAddGlobalMapping, [:pointer, :pointer, :pointer], :void
|
42
|
+
|
43
|
+
attach_function :LLVMGetPointerToGlobal, [:pointer, :pointer], :pointer
|
44
|
+
|
45
|
+
attach_function :LLVMInitializeX86TargetInfo, [], :void
|
46
|
+
|
47
|
+
attach_function :LLVMInitializeX86Target, [], :void
|
48
|
+
end
|
49
|
+
|
50
|
+
def LLVM.init_x86
|
51
|
+
LLVM::C.LLVMInitializeX86Target
|
52
|
+
LLVM::C.LLVMInitializeX86TargetInfo
|
53
|
+
end
|
54
|
+
|
55
|
+
class JITCompiler
|
56
|
+
def initialize(mod, opt_level = 3)
|
57
|
+
FFI::MemoryPointer.new(FFI.type_size(:pointer)) do |ptr|
|
58
|
+
error = FFI::MemoryPointer.new(FFI.type_size(:pointer))
|
59
|
+
status = C.LLVMCreateJITCompilerForModule(ptr, mod, opt_level, error)
|
60
|
+
errorp = error.read_pointer
|
61
|
+
message = errorp.read_string unless errorp.null?
|
62
|
+
|
63
|
+
if status.zero?
|
64
|
+
@ptr = ptr.read_pointer
|
65
|
+
else
|
66
|
+
C.LLVMDisposeMessage(error)
|
67
|
+
error.autorelease=false
|
68
|
+
raise RuntimeError, "Error creating JIT compiler: #{message}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# @private
|
74
|
+
def to_ptr
|
75
|
+
@ptr
|
76
|
+
end
|
77
|
+
|
78
|
+
# Execute the given LLVM::Function with the supplied args (as
|
79
|
+
# GenericValues).
|
80
|
+
def run_function(fun, *args)
|
81
|
+
FFI::MemoryPointer.new(FFI.type_size(:pointer) * args.size) do |args_ptr|
|
82
|
+
args_ptr.write_array_of_pointer fun.params.zip(args).map { |p, a|
|
83
|
+
a.kind_of?(GenericValue) ? a : LLVM.make_generic_value(p.type, a)
|
84
|
+
}
|
85
|
+
return LLVM::GenericValue.from_ptr(
|
86
|
+
C.LLVMRunFunction(self, fun, args.size, args_ptr))
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Obtain an FFI::Pointer to a global within the current module.
|
91
|
+
def pointer_to_global(global)
|
92
|
+
C.LLVMGetPointerToGlobal(self, global)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
class GenericValue
|
97
|
+
# @private
|
98
|
+
def to_ptr
|
99
|
+
@ptr
|
100
|
+
end
|
101
|
+
|
102
|
+
# Casts an FFI::Pointer pointing to a GenericValue to an instance.
|
103
|
+
def self.from_ptr(ptr)
|
104
|
+
return if ptr.null?
|
105
|
+
val = allocate
|
106
|
+
val.instance_variable_set(:@ptr, ptr)
|
107
|
+
val
|
108
|
+
end
|
109
|
+
|
110
|
+
# Creates a Generic Value from an integer. Type is the size of integer to
|
111
|
+
# create (ex. Int32, Int8, etc.)
|
112
|
+
def self.from_i(i, options = {})
|
113
|
+
type = options.fetch(:type, LLVM::Int)
|
114
|
+
signed = options.fetch(:signed, true)
|
115
|
+
from_ptr(C.LLVMCreateGenericValueOfInt(type, i, signed ? 1 : 0))
|
116
|
+
end
|
117
|
+
|
118
|
+
# Creates a Generic Value from a Float.
|
119
|
+
def self.from_f(f)
|
120
|
+
from_ptr(C.LLVMCreateGenericValueOfFloat(LLVM::Float, f))
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.from_d(val)
|
124
|
+
from_ptr(C.LLVMCreateGenericValueOfFloat(LLVM::Double, val))
|
125
|
+
end
|
126
|
+
|
127
|
+
# Creates a GenericValue from a Ruby boolean.
|
128
|
+
def self.from_b(b)
|
129
|
+
from_i(b ? 1 : 0, LLVM::Int1, false)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Creates a GenericValue from an FFI::Pointer pointing to some arbitrary value.
|
133
|
+
def self.from_value_ptr(ptr)
|
134
|
+
from_ptr(LLVM::C.LLVMCreateGenericValueOfPointer(ptr))
|
135
|
+
end
|
136
|
+
|
137
|
+
# Converts a GenericValue to a Ruby Integer.
|
138
|
+
def to_i(signed = true)
|
139
|
+
C.LLVMGenericValueToInt(self, signed ? 1 : 0)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Converts a GenericValue to a Ruby Float.
|
143
|
+
def to_f(type = LLVM::Float.type)
|
144
|
+
C.LLVMGenericValueToFloat(type, self)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Converts a GenericValue to a Ruby boolean.
|
148
|
+
def to_b
|
149
|
+
to_i(false) != 0
|
150
|
+
end
|
151
|
+
|
152
|
+
def to_value_ptr
|
153
|
+
C.LLVMGenericValueToPointer(self)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# @private
|
158
|
+
def make_generic_value(ty, val)
|
159
|
+
case ty.kind
|
160
|
+
when :double then GenericValue.from_d(val)
|
161
|
+
when :float then GenericValue.from_f(val)
|
162
|
+
when :pointer then GenericValue.from_value_ptr(val)
|
163
|
+
when :integer then GenericValue.from_i(val, :type => ty)
|
164
|
+
else
|
165
|
+
raise "Unsupported type #{ty.kind}."
|
166
|
+
end
|
167
|
+
end
|
168
|
+
module_function :make_generic_value
|
169
|
+
end
|
data/lib/llvm/support.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module LLVM
|
2
|
+
module Support
|
3
|
+
# @private
|
4
|
+
module C
|
5
|
+
extend FFI::Library
|
6
|
+
support_lib = File.expand_path(
|
7
|
+
File.join(
|
8
|
+
File.dirname(__FILE__),
|
9
|
+
'../',
|
10
|
+
FFI.map_library_name('RubyLLVMSupport-2.9.2')))
|
11
|
+
ffi_lib [support_lib]
|
12
|
+
attach_function :LLVMLoadLibraryPermanently, [:string], :int
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def load_library(libname)
|
17
|
+
Support::C.LLVMLoadLibraryPermanently(libname)
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
module_function :load_library
|
22
|
+
end
|
data/lib/llvm/target.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Interprocedural optimization (IPO)
|
2
|
+
require 'llvm'
|
3
|
+
require 'llvm/core'
|
4
|
+
|
5
|
+
module LLVM
|
6
|
+
# @private
|
7
|
+
module C
|
8
|
+
attach_function :LLVMAddGlobalDCEPass, [:pointer], :void
|
9
|
+
attach_function :LLVMAddFunctionInliningPass, [:pointer], :void
|
10
|
+
end
|
11
|
+
|
12
|
+
class PassManager
|
13
|
+
# @LLVMpass gdce
|
14
|
+
def gdce!
|
15
|
+
C.LLVMAddGlobalDCEPass(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @LLVMpass inline
|
19
|
+
def inline!
|
20
|
+
C.LLVMAddFunctionInliningPass(self)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'llvm'
|
2
|
+
require 'llvm/core'
|
3
|
+
|
4
|
+
module LLVM
|
5
|
+
# @private
|
6
|
+
module C
|
7
|
+
attach_function :LLVMAddAggressiveDCEPass, [:pointer], :void
|
8
|
+
attach_function :LLVMAddCFGSimplificationPass, [:pointer], :void
|
9
|
+
attach_function :LLVMAddDeadStoreEliminationPass, [:pointer], :void
|
10
|
+
attach_function :LLVMAddGVNPass, [:pointer], :void
|
11
|
+
attach_function :LLVMAddIndVarSimplifyPass, [:pointer], :void
|
12
|
+
attach_function :LLVMAddInstructionCombiningPass, [:pointer], :void
|
13
|
+
attach_function :LLVMAddJumpThreadingPass, [:pointer], :void
|
14
|
+
attach_function :LLVMAddLICMPass, [:pointer], :void
|
15
|
+
attach_function :LLVMAddLoopDeletionPass, [:pointer], :void
|
16
|
+
attach_function :LLVMAddLoopRotatePass, [:pointer], :void
|
17
|
+
attach_function :LLVMAddLoopUnrollPass, [:pointer], :void
|
18
|
+
attach_function :LLVMAddLoopUnswitchPass, [:pointer], :void
|
19
|
+
attach_function :LLVMAddMemCpyOptPass, [:pointer], :void
|
20
|
+
attach_function :LLVMAddPromoteMemoryToRegisterPass, [:pointer], :void
|
21
|
+
attach_function :LLVMAddReassociatePass, [:pointer], :void
|
22
|
+
attach_function :LLVMAddSCCPPass, [:pointer], :void
|
23
|
+
attach_function :LLVMAddScalarReplAggregatesPass, [:pointer], :void
|
24
|
+
attach_function :LLVMAddSimplifyLibCallsPass, [:pointer], :void
|
25
|
+
attach_function :LLVMAddTailCallEliminationPass, [:pointer], :void
|
26
|
+
attach_function :LLVMAddConstantPropagationPass, [:pointer], :void
|
27
|
+
attach_function :LLVMAddDemoteMemoryToRegisterPass, [:pointer], :void
|
28
|
+
end
|
29
|
+
|
30
|
+
class PassManager
|
31
|
+
# @LLVMpass adce
|
32
|
+
def adce!
|
33
|
+
C.LLVMAddAggressiveDCEPass(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @LLVMpass simplifycfg
|
37
|
+
def simplifycfg!
|
38
|
+
C.LLVMAddCFGSimplificationPass(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @LLVMpass dse
|
42
|
+
def dse!
|
43
|
+
C.LLVMAddDeadStoreEliminationPass(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @LLVMpass gvn
|
47
|
+
def gvn!
|
48
|
+
C.LLVMAddGVNPass(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @LLVMpass indvars
|
52
|
+
def indvars!
|
53
|
+
C.LLVMAddIndVarSimplifyPass(self)
|
54
|
+
end
|
55
|
+
|
56
|
+
# @LLVMpass instcombine
|
57
|
+
def instcombine!
|
58
|
+
C.LLVMAddInstructionCombiningPass(self)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @LLVMpass jump-threading
|
62
|
+
def jump_threading!
|
63
|
+
C.LLVMAddJumpThreadingPass(self)
|
64
|
+
end
|
65
|
+
|
66
|
+
# @LLVMpass licm
|
67
|
+
def licm!
|
68
|
+
C.LLVMAddLICMPass(self)
|
69
|
+
end
|
70
|
+
|
71
|
+
# @LLVMpass loop-deletion
|
72
|
+
def loop_deletion!
|
73
|
+
C.LLVMAddLoopDeletionPass(self)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @LLVMpass loop-rotate
|
77
|
+
def loop_rotate!
|
78
|
+
C.LLVMAddLoopRotatePass(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
# @LLVMpass loop-unroll
|
82
|
+
def loop_unroll!
|
83
|
+
C.LLVMAddLoopUnrollPass(self)
|
84
|
+
end
|
85
|
+
|
86
|
+
# @LLVMpass loop-unswitch
|
87
|
+
def loop_unswitch!
|
88
|
+
C.LLVMAddLoopUnswitchPass(self)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @LLVMpass memcpyopt
|
92
|
+
def memcpyopt!
|
93
|
+
C.LLVMAddMemCpyOptPass(self)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @LLVMpass mem2reg
|
97
|
+
def mem2reg!
|
98
|
+
C.LLVMAddPromoteMemoryToRegisterPass(self)
|
99
|
+
end
|
100
|
+
|
101
|
+
# @LLVMpass reassociate
|
102
|
+
def reassociate!
|
103
|
+
C.LLVMAddReassociatePass(self)
|
104
|
+
end
|
105
|
+
|
106
|
+
# @LLVMpass sccp
|
107
|
+
def sccp!
|
108
|
+
C.LLVMAddSCCPPass(self)
|
109
|
+
end
|
110
|
+
|
111
|
+
# @LLVMpass scalarrepl
|
112
|
+
def scalarrepl!
|
113
|
+
C.LLVMAddScalarReplAggregatesPass(self)
|
114
|
+
end
|
115
|
+
|
116
|
+
# @LLVMpass simplify-libcalls
|
117
|
+
def simplify_libcalls!
|
118
|
+
C.LLVMAddSimplifyLibCallsPass(self)
|
119
|
+
end
|
120
|
+
|
121
|
+
# @LLVMpass tailcallelim
|
122
|
+
def tailcallelim!
|
123
|
+
C.LLVMAddTailCallEliminationPass(self)
|
124
|
+
end
|
125
|
+
|
126
|
+
# @LLVMpass constprop
|
127
|
+
def constprop!
|
128
|
+
C.LLVMAddConstantPropagationPass(self)
|
129
|
+
end
|
130
|
+
|
131
|
+
# @LLVMpass reg2mem
|
132
|
+
def reg2mem!
|
133
|
+
C.LLVMAddDemoteMemoryToRegisterPass(self)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/test/array_test.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ArrayTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_constant_array_from_size
|
10
|
+
array = LLVM::ConstantArray.const(LLVM::Int, 2) { |i| LLVM::Int(i) }
|
11
|
+
assert_instance_of LLVM::ConstantArray, array
|
12
|
+
assert_equal 2, array.operands.size
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_constant_array_from_array
|
16
|
+
array = LLVM::ConstantArray.const(LLVM::Int, [LLVM::Int(0), LLVM::Int(1)])
|
17
|
+
assert_instance_of LLVM::ConstantArray, array
|
18
|
+
assert_equal 2, array.operands.size
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_array_values
|
22
|
+
assert_equal 2 + 3, run_array_values(2, 3).to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
def run_array_values(value1, value2)
|
26
|
+
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
27
|
+
entry = function.basic_blocks.append
|
28
|
+
builder.position_at_end(entry)
|
29
|
+
pointer = builder.alloca(LLVM::Array(LLVM::Int, 2))
|
30
|
+
array = builder.load(pointer)
|
31
|
+
array = builder.insert_value(array, arguments.first, 0)
|
32
|
+
array = builder.insert_value(array, arguments.last, 1)
|
33
|
+
builder.ret(builder.add(builder.extract_value(array, 0),
|
34
|
+
builder.extract_value(array, 1)))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class BasicBlockTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
@module = LLVM::Module.new("BasicBlockTestCase")
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_basic_block_collection
|
11
|
+
@module.functions.add("test_basic_block_collection", [], LLVM.Void) do |fn|
|
12
|
+
coll = fn.basic_blocks
|
13
|
+
|
14
|
+
block1 = coll.append
|
15
|
+
assert_instance_of LLVM::BasicBlock, block1
|
16
|
+
|
17
|
+
assert_equal 1, coll.size
|
18
|
+
assert_equal coll.first, coll.last,
|
19
|
+
'Only one block exists in the function'
|
20
|
+
assert_equal coll.first, coll.entry,
|
21
|
+
'The entry block for the function is always the first block'
|
22
|
+
|
23
|
+
block2 = coll.append
|
24
|
+
assert_equal 2, coll.size
|
25
|
+
assert_equal block1, coll.first
|
26
|
+
assert_equal block2, coll.last
|
27
|
+
|
28
|
+
[ coll.each.to_a, coll.to_a ].each do |blocks|
|
29
|
+
assert_equal 2, blocks.size
|
30
|
+
assert_equal block1, blocks[0]
|
31
|
+
assert_equal block2, blocks[1]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_basic_block
|
37
|
+
@module.functions.add("test_basic_block", [], LLVM.Void) do |fn|
|
38
|
+
coll = fn.basic_blocks
|
39
|
+
|
40
|
+
block1 = coll.append
|
41
|
+
block2 = coll.append
|
42
|
+
|
43
|
+
assert_equal fn, block1.parent
|
44
|
+
assert_equal fn, block2.parent
|
45
|
+
|
46
|
+
assert_equal block2, block1.next
|
47
|
+
assert_equal block1, block2.previous
|
48
|
+
|
49
|
+
block1.build do |builder|
|
50
|
+
builder.br(block2)
|
51
|
+
end
|
52
|
+
|
53
|
+
block2.build do |builder|
|
54
|
+
builder.ret_void
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal block1.first_instruction,
|
58
|
+
block1.last_instruction
|
59
|
+
assert_equal block2.first_instruction,
|
60
|
+
block2.last_instruction
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_basic_block_enumerable
|
65
|
+
@module.functions.add("test_basic_block_enumerable", [LLVM::Double], LLVM::Double) do |fn, arg|
|
66
|
+
block1 = fn.basic_blocks.append
|
67
|
+
|
68
|
+
[ block1.instructions.to_a, block1.instructions.each.to_a ].each do |insts|
|
69
|
+
assert_equal 0, insts.size, 'Empty basic block'
|
70
|
+
end
|
71
|
+
|
72
|
+
block1.build do |builder|
|
73
|
+
builder.ret(builder.fadd(arg, LLVM.Double(1.0)))
|
74
|
+
end
|
75
|
+
|
76
|
+
[ block1.instructions.to_a, block1.instructions.each.to_a ].each do |insts|
|
77
|
+
assert_equal 2, insts.size
|
78
|
+
assert_equal block1.first_instruction, insts[0] # deprecated
|
79
|
+
assert_equal block1.last_instruction, insts[1] # deprecated
|
80
|
+
assert_equal block1.instructions.first, insts[0]
|
81
|
+
assert_equal block1.instructions.last, insts[1]
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|