ruby-llvm 2.9.1 → 2.9.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.
@@ -1,27 +1,19 @@
1
1
  module LLVM
2
2
  class Context
3
- private_class_method :new
4
-
5
- # @private
6
- def initialize(ptr)
7
- @ptr = ptr
3
+ def initialize
4
+ @ptr = C.LLVMContextCreate()
8
5
  end
9
-
6
+
10
7
  # @private
11
8
  def to_ptr
12
9
  @ptr
13
10
  end
14
-
15
- # Creates a new Context.
16
- def self.create
17
- new(C.LLVMContextCreate())
18
- end
19
-
11
+
20
12
  # Obtains a reference to the global Context.
21
13
  def self.global
22
14
  new(C.LLVMGetGlobalContext())
23
15
  end
24
-
16
+
25
17
  # Diposes the Context.
26
18
  def dispose
27
19
  C.LLVMContextDispose(@ptr)
@@ -1,15 +1,15 @@
1
1
  module LLVM
2
2
  class Module
3
- private_class_method :new
4
-
5
3
  # @private
6
4
  def self.from_ptr(ptr)
7
- ptr.null? ? nil : new(ptr)
5
+ return if ptr.null?
6
+ mod = allocate
7
+ mod.instance_variable_set(:@ptr, ptr)
8
+ mod
8
9
  end
9
10
 
10
- # @private
11
- def initialize(ptr)
12
- @ptr = ptr
11
+ def initialize(name)
12
+ @ptr = C.LLVMModuleCreateWithName(name)
13
13
  end
14
14
 
15
15
  # @private
@@ -32,11 +32,6 @@ module LLVM
32
32
  other.instance_of?(self.class) && self == other
33
33
  end
34
34
 
35
- # Creates a module with the given name.
36
- def self.create(name)
37
- new(C.LLVMModuleCreateWithName(name))
38
- end
39
-
40
35
  # Returns a TypeCollection of all the Types in the module.
41
36
  def types
42
37
  @types ||= TypeCollection.new(self)
@@ -8,6 +8,8 @@ module LLVM
8
8
  C.LLVMAddTargetData(
9
9
  C.LLVMGetExecutionEngineTargetData(execution_engine), ptr)
10
10
  @ptr = ptr
11
+
12
+ do_initialization
11
13
  end
12
14
 
13
15
  # @private
@@ -15,26 +17,34 @@ module LLVM
15
17
  @ptr
16
18
  end
17
19
 
20
+ # Append a pass to the pass queue.
21
+ # @param [Symbol]
22
+ # @return [LLVM::PassManager]
18
23
  def <<(name)
19
24
  send(:"#{name}!")
20
25
  self
21
26
  end
22
27
 
23
- def do_initialization
24
- end
25
-
26
- def do_finalization
27
- end
28
-
29
- # Runs the passes on the given module.
28
+ # Run the pass queue on the given module.
29
+ # @param [LLVM::Module]
30
+ # @return [true, false] Indicates whether the module was modified.
30
31
  def run(mod)
31
- C.LLVMRunPassManager(self, mod)
32
+ C.LLVMRunPassManager(self, mod) != 0
32
33
  end
33
34
 
34
35
  # Disposes the pass manager.
35
36
  def dispose
37
+ do_finalization
36
38
  C.LLVMDisposePassManager(self)
37
39
  end
40
+
41
+ protected
42
+
43
+ def do_initialization
44
+ end
45
+
46
+ def do_finalization
47
+ end
38
48
  end
39
49
 
40
50
  class FunctionPassManager < PassManager
@@ -46,6 +56,15 @@ module LLVM
46
56
  @ptr = ptr
47
57
  end
48
58
 
59
+ # Run the pass queue on the given function.
60
+ # @param [LLVM::Function]
61
+ # @return [true, false] indicates whether the function was modified.
62
+ def run(fn)
63
+ C.LLVMRunFunctionPassManager(self, fn) != 0
64
+ end
65
+
66
+ protected
67
+
49
68
  def do_initialization
50
69
  C.LLVMInitializeFunctionPassManager(self) != 0
51
70
  end
@@ -53,10 +72,5 @@ module LLVM
53
72
  def do_finalization
54
73
  C.LLVMFinalizeFunctionPassManager(self) != 0
55
74
  end
56
-
57
- # Runs the passes on the given function.
58
- def run(fn)
59
- C.LLVMRunFunctionPassManager(self, fn)
60
- end
61
75
  end
62
76
  end
@@ -1,12 +1,5 @@
1
1
  module LLVM
2
2
  class Type
3
- private_class_method :new
4
-
5
- # @private
6
- def initialize(ptr)
7
- @ptr = ptr
8
- end
9
-
10
3
  # @private
11
4
  def to_ptr
12
5
  @ptr
@@ -34,11 +27,11 @@ module LLVM
34
27
 
35
28
  # Returns the size of the type.
36
29
  def size
37
- Int64.from_ptr(C.LLVMSizeOf(self))
30
+ LLVM::Int64.from_ptr(C.LLVMSizeOf(self))
38
31
  end
39
32
 
40
33
  def align
41
- Int64.from_ptr(C.LLVMAlignOf(self))
34
+ LLVM::Int64.from_ptr(C.LLVMAlignOf(self))
42
35
  end
43
36
 
44
37
  # Returns the type of this types elements (works only for Pointer, Vector, and Array types.)
@@ -64,8 +57,12 @@ module LLVM
64
57
  Type.pointer(self, address_space)
65
58
  end
66
59
 
60
+ # @private
67
61
  def self.from_ptr(ptr)
68
- ptr.null? ? nil : new(ptr)
62
+ return if ptr.null?
63
+ ty = allocate
64
+ ty.instance_variable_set(:@ptr, ptr)
65
+ ty
69
66
  end
70
67
 
71
68
  # Creates an array type of Type with the given size.
@@ -89,7 +86,7 @@ module LLVM
89
86
  arg_types.map! { |ty| LLVM::Type(ty) }
90
87
  arg_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * arg_types.size)
91
88
  arg_types_ptr.write_array_of_pointer(arg_types)
92
- from_ptr(C.LLVMFunctionType(LLVM::Type(result_type), arg_types_ptr, arg_types.size, options[:varargs] ? 1 : 0))
89
+ FunctionType.from_ptr(C.LLVMFunctionType(LLVM::Type(result_type), arg_types_ptr, arg_types.size, options[:varargs] ? 1 : 0))
93
90
  end
94
91
 
95
92
  # Creates a struct type with the given array of element types.
@@ -121,9 +118,23 @@ module LLVM
121
118
  C.LLVMRefineType(self, ty)
122
119
  end
123
120
  end
121
+
122
+ class IntType < Type
123
+ def width
124
+ C.LLVMGetIntTypeWidth(self)
125
+ end
126
+ end
127
+
128
+ class FunctionType < Type
129
+ def return_type
130
+ LLVM::Type.from_ptr(C.LLVMGetReturnType(self))
131
+ end
132
+ end
133
+
134
+ module_function
124
135
 
125
136
  # Creates a Type from the given object.
126
- def LLVM.Type(ty)
137
+ def Type(ty)
127
138
  case ty
128
139
  when LLVM::Type then ty
129
140
  else ty.type
@@ -131,32 +142,32 @@ module LLVM
131
142
  end
132
143
 
133
144
  # Shortcut to Type.array.
134
- def LLVM.Array(ty, sz = 0)
145
+ def Array(ty, sz = 0)
135
146
  LLVM::Type.array(ty, sz)
136
147
  end
137
148
 
138
149
  # Shortcut to Type.pointer.
139
- def LLVM.Pointer(ty)
150
+ def Pointer(ty)
140
151
  LLVM::Type.pointer(ty)
141
152
  end
142
153
 
143
154
  # Shortcut to Type.vector.
144
- def LLVM.Vector(ty, sz)
155
+ def Vector(ty, sz)
145
156
  LLVM::Type.vector(ty, sz)
146
157
  end
147
158
 
148
159
  # Shortcut to Type.function.
149
- def LLVM.Function(argtypes, rettype, options = {})
160
+ def Function(argtypes, rettype, options = {})
150
161
  LLVM::Type.function(argtypes, rettype, options)
151
162
  end
152
163
 
153
164
  # Shortcut to Type.struct.
154
- def LLVM.Struct(*elt_types)
165
+ def Struct(*elt_types)
155
166
  LLVM::Type.struct(elt_types, false)
156
167
  end
157
168
 
158
169
  # Shortcut to Type.void.
159
- def LLVM.Void
170
+ def Void
160
171
  LLVM::Type.void
161
172
  end
162
173
  end
@@ -2,14 +2,10 @@ module LLVM
2
2
  class Value
3
3
  # @private
4
4
  def self.from_ptr(ptr)
5
- new(ptr) unless ptr.null?
6
- end
7
-
8
- private_class_method :new
9
-
10
- # @private
11
- def initialize(ptr)
12
- @ptr = ptr
5
+ return if ptr.null?
6
+ val = allocate
7
+ val.instance_variable_set(:@ptr, ptr)
8
+ val
13
9
  end
14
10
 
15
11
  # @private
@@ -26,6 +22,10 @@ module LLVM
26
22
  false
27
23
  end
28
24
  end
25
+
26
+ def hash
27
+ @ptr.address.hash
28
+ end
29
29
 
30
30
  # Checks if the value is equal to other.
31
31
  def eql?(other)
@@ -104,7 +104,7 @@ module LLVM
104
104
  # Build the basic block with the given builder. Creates a new one if nil. Yields the builder.
105
105
  def build(builder = nil)
106
106
  if builder.nil?
107
- builder = Builder.create
107
+ builder = Builder.new
108
108
  islocal = true
109
109
  else
110
110
  islocal = false
@@ -401,7 +401,7 @@ module LLVM
401
401
  eval <<-KLASS
402
402
  class #{name} < ConstantInt
403
403
  def self.type
404
- Type.from_ptr(C.LLVMIntType(#{width}))
404
+ IntType.from_ptr(C.LLVMIntType(#{width}))
405
405
  end
406
406
  end
407
407
  KLASS
@@ -412,7 +412,8 @@ module LLVM
412
412
  end
413
413
 
414
414
  # Native integer type
415
- ::LLVM::Int = const_get("Int#{NATIVE_INT_SIZE}")
415
+ bits = FFI.type_size(:int) * 8
416
+ ::LLVM::Int = const_get("Int#{bits}")
416
417
 
417
418
  # Creates a LLVM Int (subclass of ConstantInt) at the NATIVE_INT_SIZE from a integer (val).
418
419
  def LLVM.Int(val)
@@ -421,6 +422,10 @@ module LLVM
421
422
  when Integer then Int.from_i(val)
422
423
  end
423
424
  end
425
+
426
+ # Boolean values
427
+ ::LLVM::TRUE = ::LLVM::Int1.from_i(-1)
428
+ ::LLVM::FALSE = ::LLVM::Int1.from_i(0)
424
429
 
425
430
  class ConstantReal < Constant
426
431
  # Creates a ConstantReal from a float of Type.
@@ -598,6 +603,10 @@ module LLVM
598
603
  @basic_block_collection ||= BasicBlockCollection.new(self)
599
604
  end
600
605
 
606
+ def type
607
+ FunctionType.from_ptr(C.LLVMTypeOf(self))
608
+ end
609
+
601
610
  # @private
602
611
  class BasicBlockCollection
603
612
  include Enumerable
@@ -661,6 +670,9 @@ module LLVM
661
670
 
662
671
  # Returns a Value representation of the parameter at the given index.
663
672
  def [](i)
673
+ sz = self.size
674
+ i = sz + i if i < 0
675
+ return unless 0 <= i && i < sz
664
676
  Value.from_ptr(C.LLVMGetParam(@fun, i))
665
677
  end
666
678
 
@@ -737,26 +749,21 @@ module LLVM
737
749
  end
738
750
  end
739
751
 
752
+ # @private
740
753
  class Phi < Instruction
741
754
  # Add incoming branches to a phi node by passing an alternating list of
742
755
  # resulting values and BasicBlocks. e.g.
743
756
  # phi.add_incoming(val1, block1, val2, block2, ...)
744
- def add_incoming(*incoming)
745
- vals, blocks = [], []
746
- incoming.each_with_index do |node, i|
747
- (i % 2 == 0 ? vals : blocks) << node
748
- end
749
-
750
- unless vals.size == blocks.size
751
- raise ArgumentError, "Expected vals.size and blocks.size to match"
752
- end
757
+ def add_incoming(incoming)
758
+ blks = incoming.keys
759
+ vals = incoming.values_at(*blks)
760
+ size = incoming.size
753
761
 
754
- size = vals.size
755
762
  FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |vals_ptr|
756
763
  vals_ptr.write_array_of_pointer(vals)
757
- FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |blocks_ptr|
758
- blocks_ptr.write_array_of_pointer(blocks)
759
- C.LLVMAddIncoming(self, vals_ptr, blocks_ptr, vals.size)
764
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |blks_ptr|
765
+ blks_ptr.write_array_of_pointer(blks)
766
+ C.LLVMAddIncoming(self, vals_ptr, blks_ptr, vals.size)
760
767
  end
761
768
  end
762
769
 
@@ -764,6 +771,7 @@ module LLVM
764
771
  end
765
772
  end
766
773
 
774
+ # @private
767
775
  class SwitchInst < Instruction
768
776
  # Adds a case to a switch instruction. First the value to match on, then
769
777
  # the basic block.
data/lib/llvm/core.rb CHANGED
@@ -594,4 +594,5 @@ module LLVM
594
594
  require 'llvm/core/value'
595
595
  require 'llvm/core/builder'
596
596
  require 'llvm/core/pass_manager'
597
+ require 'llvm/core/bitcode'
597
598
  end
@@ -52,21 +52,8 @@ module LLVM
52
52
  LLVM::C.LLVMInitializeX86TargetInfo
53
53
  end
54
54
 
55
- class ExecutionEngine
56
- private_class_method :new
57
-
58
- # @private
59
- def initialize(ptr)
60
- @ptr = ptr
61
- end
62
-
63
- # @private
64
- def to_ptr
65
- @ptr
66
- end
67
-
68
- # Create a JIT compiler with an LLVM::Module.
69
- def self.create_jit_compiler(mod, opt_level = 3)
55
+ class JITCompiler
56
+ def initialize(mod, opt_level = 3)
70
57
  FFI::MemoryPointer.new(FFI.type_size(:pointer)) do |ptr|
71
58
  error = FFI::MemoryPointer.new(FFI.type_size(:pointer))
72
59
  status = C.LLVMCreateJITCompilerForModule(ptr, mod, opt_level, error)
@@ -74,7 +61,7 @@ module LLVM
74
61
  message = errorp.read_string unless errorp.null?
75
62
 
76
63
  if status.zero?
77
- return new(ptr.read_pointer)
64
+ @ptr = ptr.read_pointer
78
65
  else
79
66
  C.LLVMDisposeMessage(error)
80
67
  error.autorelease=false
@@ -83,11 +70,18 @@ module LLVM
83
70
  end
84
71
  end
85
72
 
73
+ # @private
74
+ def to_ptr
75
+ @ptr
76
+ end
77
+
86
78
  # Execute the given LLVM::Function with the supplied args (as
87
79
  # GenericValues).
88
80
  def run_function(fun, *args)
89
81
  FFI::MemoryPointer.new(FFI.type_size(:pointer) * args.size) do |args_ptr|
90
- args_ptr.write_array_of_pointer(args.map { |arg| LLVM.GenericValue(arg).to_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
+ }
91
85
  return LLVM::GenericValue.from_ptr(
92
86
  C.LLVMRunFunction(self, fun, args.size, args_ptr))
93
87
  end
@@ -100,28 +94,34 @@ module LLVM
100
94
  end
101
95
 
102
96
  class GenericValue
103
- private_class_method :new
104
-
105
- # @private
106
- def initialize(ptr)
107
- @ptr = ptr
108
- end
109
-
110
97
  # @private
111
98
  def to_ptr
112
99
  @ptr
113
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
114
109
 
115
110
  # Creates a Generic Value from an integer. Type is the size of integer to
116
111
  # create (ex. Int32, Int8, etc.)
117
- def self.from_i(i, type = LLVM::Int, signed = true)
118
- new(C.LLVMCreateGenericValueOfInt(type, i, signed ? 1 : 0))
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))
119
116
  end
120
117
 
121
118
  # Creates a Generic Value from a Float.
122
119
  def self.from_f(f)
123
- type = LLVM::Float.type
124
- new(C.LLVMCreateGenericValueOfFloat(type, 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
125
  end
126
126
 
127
127
  # Creates a GenericValue from a Ruby boolean.
@@ -129,9 +129,9 @@ module LLVM
129
129
  from_i(b ? 1 : 0, LLVM::Int1, false)
130
130
  end
131
131
 
132
- # Creates a GenericValue from an FFI::Pointer.
133
- def self.from_ptr(ptr)
134
- new(ptr)
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
135
  end
136
136
 
137
137
  # Converts a GenericValue to a Ruby Integer.
@@ -148,17 +148,22 @@ module LLVM
148
148
  def to_b
149
149
  to_i(false) != 0
150
150
  end
151
+
152
+ def to_value_ptr
153
+ C.LLVMGenericValueToPointer(self)
154
+ end
151
155
  end
152
156
 
153
- # Creates a GenericValue from an object (GenericValue, Integer, Float, true,
154
- # false).
155
- def LLVM.GenericValue(val)
156
- case val
157
- when GenericValue then val
158
- when ::Integer then GenericValue.from_i(val)
159
- when ::Float then GenericValue.from_f(val)
160
- when ::TrueClass then GenericValue.from_b(true)
161
- when ::FalseClass then GenericValue.from_b(false)
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}."
162
166
  end
163
167
  end
168
+ module_function :make_generic_value
164
169
  end
@@ -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
@@ -6,6 +6,7 @@ module LLVM
6
6
  # @private
7
7
  module C
8
8
  attach_function :LLVMAddGlobalDCEPass, [:pointer], :void
9
+ attach_function :LLVMAddFunctionInliningPass, [:pointer], :void
9
10
  end
10
11
 
11
12
  class PassManager
@@ -13,5 +14,10 @@ module LLVM
13
14
  def gdce!
14
15
  C.LLVMAddGlobalDCEPass(self)
15
16
  end
17
+
18
+ # @LLVMpass inline
19
+ def inline!
20
+ C.LLVMAddFunctionInliningPass(self)
21
+ end
16
22
  end
17
23
  end
@@ -0,0 +1,4 @@
1
+ module LLVM
2
+ LLVM_VERSION = "2.9"
3
+ RUBY_LLVM_VERSION = "2.9.3"
4
+ end
data/lib/llvm.rb CHANGED
@@ -1,18 +1,12 @@
1
1
  require 'rubygems'
2
2
  require 'ffi'
3
3
 
4
+ require 'llvm/support'
5
+
4
6
  module LLVM
5
7
  # @private
6
8
  module C
7
9
  extend ::FFI::Library
8
-
9
- # load required libraries
10
- ffi_lib ['LLVM-2.9', 'libLLVM-2.9']
11
- end
12
-
13
- NATIVE_INT_SIZE = case FFI::Platform::ARCH
14
- when "x86_64" then 64
15
- # PPC, other arches?
16
- else 32
10
+ ffi_lib ['LLVM-2.9']
17
11
  end
18
12
  end
@@ -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