ruby-llvm 3.5.0 → 13.0.1

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.
Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +21 -4
  3. data/ext/ruby-llvm-support/Rakefile +17 -6
  4. data/lib/llvm/analysis.rb +2 -0
  5. data/lib/llvm/analysis_ffi.rb +27 -28
  6. data/lib/llvm/config.rb +4 -4
  7. data/lib/llvm/core/bitcode.rb +12 -10
  8. data/lib/llvm/core/bitcode_ffi.rb +89 -65
  9. data/lib/llvm/core/builder.rb +4 -3
  10. data/lib/llvm/core/context.rb +3 -1
  11. data/lib/llvm/core/module.rb +2 -0
  12. data/lib/llvm/core/pass_manager.rb +6 -2
  13. data/lib/llvm/core/type.rb +9 -2
  14. data/lib/llvm/core/value.rb +154 -24
  15. data/lib/llvm/core.rb +47 -2
  16. data/lib/llvm/core_ffi.rb +3863 -3730
  17. data/lib/llvm/execution_engine.rb +39 -35
  18. data/lib/llvm/execution_engine_ffi.rb +238 -276
  19. data/lib/llvm/linker.rb +3 -14
  20. data/lib/llvm/linker_ffi.rb +22 -26
  21. data/lib/llvm/support.rb +2 -0
  22. data/lib/llvm/target.rb +11 -15
  23. data/lib/llvm/target_ffi.rb +301 -293
  24. data/lib/llvm/transforms/builder.rb +3 -1
  25. data/lib/llvm/transforms/builder_ffi.rb +57 -58
  26. data/lib/llvm/transforms/ipo.rb +3 -1
  27. data/lib/llvm/transforms/ipo_ffi.rb +59 -60
  28. data/lib/llvm/transforms/scalar.rb +12 -0
  29. data/lib/llvm/transforms/scalar_ffi.rb +199 -143
  30. data/lib/llvm/transforms/vectorize.rb +2 -0
  31. data/lib/llvm/transforms/vectorize_ffi.rb +15 -16
  32. data/lib/llvm/version.rb +5 -2
  33. data/lib/llvm.rb +2 -0
  34. data/test/array_test.rb +2 -0
  35. data/test/basic_block_test.rb +2 -1
  36. data/test/binary_operations_test.rb +2 -0
  37. data/test/bitcode_test.rb +3 -2
  38. data/test/branch_test.rb +2 -0
  39. data/test/call_test.rb +3 -1
  40. data/test/comparisons_test.rb +2 -0
  41. data/test/conversions_test.rb +2 -0
  42. data/test/double_test.rb +10 -7
  43. data/test/equality_test.rb +4 -4
  44. data/test/function_test.rb +29 -0
  45. data/test/generic_value_test.rb +3 -1
  46. data/test/instruction_test.rb +2 -2
  47. data/test/integer_test.rb +28 -0
  48. data/test/ipo_test.rb +3 -1
  49. data/test/linker_test.rb +2 -9
  50. data/test/mcjit_test.rb +11 -3
  51. data/test/memory_access_test.rb +2 -0
  52. data/test/module_test.rb +18 -1
  53. data/test/parameter_collection_test.rb +2 -0
  54. data/test/pass_manager_builder_test.rb +22 -2
  55. data/test/phi_test.rb +2 -0
  56. data/test/select_test.rb +2 -0
  57. data/test/struct_test.rb +2 -0
  58. data/test/target_test.rb +16 -20
  59. data/test/test_helper.rb +6 -1
  60. data/test/type_test.rb +47 -0
  61. data/test/vector_test.rb +2 -0
  62. metadata +105 -40
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LLVM
2
4
  class Value
3
5
  include PointerIdentity
@@ -12,7 +14,7 @@ module LLVM
12
14
 
13
15
  # Returns the Value type. This is abstract and is overidden by its subclasses.
14
16
  def self.type
15
- raise NotImplementedError, "#{self.name}.type() is abstract."
17
+ raise NotImplementedError, "#{name}.type() is abstract."
16
18
  end
17
19
 
18
20
  def self.to_ptr
@@ -40,6 +42,10 @@ module LLVM
40
42
  C.dump_value(self)
41
43
  end
42
44
 
45
+ def to_s
46
+ C.print_value_to_string(self)
47
+ end
48
+
43
49
  # Returns whether the value is constant.
44
50
  def constant?
45
51
  case C.is_constant(self)
@@ -66,8 +72,45 @@ module LLVM
66
72
 
67
73
  # Adds attr to this value's attributes.
68
74
  def add_attribute(attr)
69
- C.add_attribute(self, attr)
75
+ fun = param_parent
76
+ return unless fun
77
+
78
+ index = param_index(fun)
79
+ return unless index
80
+
81
+ fun.add_attribute(attr, index)
70
82
  end
83
+
84
+ # Removes the given attribute from the function.
85
+ def remove_attribute(attr)
86
+ fun = param_parent
87
+ return unless fun
88
+
89
+ index = param_index(fun)
90
+ return unless index
91
+
92
+ fun.remove_attribute(attr, index)
93
+ end
94
+
95
+ private
96
+
97
+ # get function this param belongs to
98
+ # return if it is not a param
99
+ def param_parent
100
+ valueref = C.get_param_parent(self)
101
+ return if valueref.null?
102
+ fun = LLVM::Function.from_ptr(valueref)
103
+ return if fun.null?
104
+ fun
105
+ end
106
+
107
+ # get index of this param by llvm count (+1 from parametercollection)
108
+ def param_index(fun)
109
+ index = fun.params.find_index(self)
110
+ return if index.nil?
111
+ index + 1
112
+ end
113
+
71
114
  end
72
115
 
73
116
  class Argument < Value
@@ -76,7 +119,7 @@ module LLVM
76
119
  class BasicBlock < Value
77
120
  # Creates a basic block for the given function with the given name.
78
121
  def self.create(fun = nil, name = "")
79
- self.from_ptr(C.append_basic_block(fun, name))
122
+ from_ptr(C.append_basic_block(fun, name))
80
123
  end
81
124
 
82
125
  # Build the basic block with the given builder. Creates a new one if nil. Yields the builder.
@@ -110,11 +153,13 @@ module LLVM
110
153
  BasicBlock.from_ptr(ptr) unless ptr.null?
111
154
  end
112
155
 
113
- def first_instruction # deprecated
156
+ # deprecated
157
+ def first_instruction
114
158
  instructions.first
115
159
  end
116
160
 
117
- def last_instruction # deprecated
161
+ # deprecated
162
+ def last_instruction
118
163
  instructions.last
119
164
  end
120
165
 
@@ -192,7 +237,7 @@ module LLVM
192
237
  # Iterates through each operand in the collection.
193
238
  def each
194
239
  return to_enum :each unless block_given?
195
- 0.upto(size-1) { |i| yield self[i] }
240
+ 0.upto(size - 1) { |i| yield self[i] }
196
241
  self
197
242
  end
198
243
  end
@@ -444,12 +489,22 @@ module LLVM
444
489
  def int_to_ptr(type)
445
490
  ConstantExpr.from_ptr(C.const_int_to_ptr(self, type))
446
491
  end
492
+
493
+ # constant zext
494
+ def zext(type)
495
+ self.class.from_ptr(C.const_z_ext(self, type))
496
+ end
497
+
498
+ # constant sext
499
+ def sext(type)
500
+ self.class.from_ptr(C.const_s_ext(self, type))
501
+ end
447
502
  end
448
503
 
449
- def LLVM.const_missing(const)
504
+ def self.const_missing(const)
450
505
  case const.to_s
451
506
  when /Int(\d+)/
452
- width = $1.to_i
507
+ width = Regexp.last_match(1).to_i
453
508
  name = "Int#{width}"
454
509
  eval <<-KLASS
455
510
  class #{name} < ConstantInt
@@ -469,7 +524,7 @@ module LLVM
469
524
  ::LLVM::Int = const_get("Int#{bits}")
470
525
 
471
526
  # Creates a LLVM Int (subclass of ConstantInt) at the NATIVE_INT_SIZE from a integer (val).
472
- def LLVM.Int(val)
527
+ def self.Int(val)
473
528
  case val
474
529
  when LLVM::ConstantInt then val
475
530
  when Integer then Int.from_i(val)
@@ -550,7 +605,7 @@ module LLVM
550
605
  end
551
606
 
552
607
  # Create a LLVM::Float from a Ruby Float (val).
553
- def LLVM.Float(val)
608
+ def self.Float(val)
554
609
  Float.from_f(val)
555
610
  end
556
611
 
@@ -560,7 +615,7 @@ module LLVM
560
615
  end
561
616
  end
562
617
 
563
- def LLVM.Double(val)
618
+ def self.Double(val)
564
619
  Double.from_f(val)
565
620
  end
566
621
 
@@ -675,16 +730,6 @@ module LLVM
675
730
  conv
676
731
  end
677
732
 
678
- # Adds the given attribute to the function.
679
- def add_attribute(attr)
680
- C.add_function_attr(self, attr)
681
- end
682
-
683
- # Removes the given attribute from the function.
684
- def remove_attribute(attr)
685
- C.remove_function_attr(self, attr)
686
- end
687
-
688
733
  # Returns an Enumerable of the BasicBlocks in this function.
689
734
  def basic_blocks
690
735
  @basic_block_collection ||= BasicBlockCollection.new(self)
@@ -698,6 +743,90 @@ module LLVM
698
743
  type.element_type
699
744
  end
700
745
 
746
+ # Adds attr to this value's attributes.
747
+ def add_attribute(attr, index = -1)
748
+ AttributeCollection.new(self, index).add(attr)
749
+ end
750
+
751
+ # Removes the given attribute from the function.
752
+ def remove_attribute(attr, index = -1)
753
+ AttributeCollection.new(self, index).remove(attr)
754
+ end
755
+
756
+ def attribute_count
757
+ function_attributes.count
758
+ end
759
+
760
+ def attributes
761
+ function_attributes.to_a
762
+ end
763
+
764
+ def function_attributes
765
+ AttributeCollection.new(self, -1)
766
+ end
767
+
768
+ def return_attributes
769
+ AttributeCollection.new(self, 0)
770
+ end
771
+
772
+ def param_attributes(index)
773
+ AttributeCollection.new(self, index)
774
+ end
775
+
776
+ class AttributeCollection
777
+
778
+ def initialize(fun, index)
779
+ @fun = fun
780
+ @index = index
781
+ end
782
+
783
+ def add(attr)
784
+ attr_kind_id = attribute_id(attr)
785
+ ctx = Context.global
786
+ attr_ref = C.create_enum_attribute(ctx, attr_kind_id, 0)
787
+ C.add_attribute_at_index(@fun, @index, attr_ref)
788
+ end
789
+
790
+ def remove(attr)
791
+ attr_kind_id = attribute_id(attr)
792
+ C.remove_enum_attribute_at_index(@fun, @index, attr_kind_id)
793
+ end
794
+
795
+ def count
796
+ C.get_attribute_count_at_index(@fun, @index)
797
+ end
798
+
799
+ def to_a
800
+ attr_refs = nil
801
+ n = count
802
+ FFI::MemoryPointer.new(:pointer, n) do |p|
803
+ C.get_attributes_at_index(@fun, @index, p)
804
+ attr_refs = p.read_array_of_type(:pointer, :read_pointer, n)
805
+ end
806
+
807
+ attr_refs.map { |e| C.get_enum_attribute_kind(e) }
808
+ end
809
+
810
+ private
811
+
812
+ def attribute_name(attr_name)
813
+ attr_name = attr_name.to_s
814
+ if attr_name =~ /_attribute$/
815
+ attr_name.chomp('_attribute').tr('_', '')
816
+ else
817
+ attr_name
818
+ end
819
+ end
820
+
821
+ def attribute_id(attr_name)
822
+ attr_mem = FFI::MemoryPointer.from_string(attribute_name(attr_name))
823
+ attr_kind_id = C.get_enum_attribute_kind_for_name(attr_mem, attr_mem.size - 1)
824
+
825
+ raise "No attribute named: #{attr_name}" if attr_kind_id.zero?
826
+ attr_kind_id
827
+ end
828
+ end
829
+
701
830
  # @private
702
831
  class BasicBlockCollection
703
832
  include Enumerable
@@ -716,7 +845,7 @@ module LLVM
716
845
  return to_enum :each unless block_given?
717
846
 
718
847
  ptr = C.get_first_basic_block(@fun)
719
- 0.upto(size-1) do |i|
848
+ 0.upto(size - 1) do |i|
720
849
  yield BasicBlock.from_ptr(ptr)
721
850
  ptr = C.get_next_basic_block(ptr)
722
851
  end
@@ -761,7 +890,7 @@ module LLVM
761
890
 
762
891
  # Returns a Value representation of the parameter at the given index.
763
892
  def [](i)
764
- sz = self.size
893
+ sz = size
765
894
  i = sz + i if i < 0
766
895
  return unless 0 <= i && i < sz
767
896
  Value.from_ptr(C.get_param(@fun, i))
@@ -777,7 +906,7 @@ module LLVM
777
906
  # Iteraters through each parameter in the collection.
778
907
  def each
779
908
  return to_enum :each unless block_given?
780
- 0.upto(size-1) { |i| yield self[i] }
909
+ 0.upto(size - 1) { |i| yield self[i] }
781
910
  self
782
911
  end
783
912
  end
@@ -785,6 +914,7 @@ module LLVM
785
914
  def gc=(name)
786
915
  C.set_gc(self, name)
787
916
  end
917
+
788
918
  def gc
789
919
  C.get_gc(self)
790
920
  end
data/lib/llvm/core.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'llvm'
2
4
  require 'llvm/core_ffi'
3
5
  require 'llvm/support'
@@ -6,6 +8,49 @@ module LLVM
6
8
  # @private
7
9
  module C
8
10
  attach_function :dispose_message, :LLVMDisposeMessage, [:pointer], :void
11
+
12
+ # typedef unsigned LLVMAttributeIndex;
13
+ typedef(:uint, :llvmattributeindex)
14
+
15
+ # void LLVMAddAttributeAtIndex
16
+ # (LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef A);
17
+ attach_function :add_attribute_at_index, :LLVMAddAttributeAtIndex, [:pointer, :llvmattributeindex, :pointer], :void
18
+
19
+ # void LLVMRemoveEnumAttributeAtIndex
20
+ # (LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID);
21
+ attach_function :remove_enum_attribute_at_index, :LLVMRemoveEnumAttributeAtIndex, [:pointer, :llvmattributeindex, :uint], :void
22
+
23
+ # LLVMAttributeRef LLVMCreateEnumAttribute
24
+ # (LLVMContextRef C, unsigned KindID, uint64_t Val);
25
+ attach_function :create_enum_attribute, :LLVMCreateEnumAttribute, [:pointer, :uint, :uint64], :pointer
26
+
27
+ # unsigned LLVMGetEnumAttributeKindForName
28
+ # (const char *Name, size_t SLen);
29
+ attach_function :get_enum_attribute_kind_for_name, :LLVMGetEnumAttributeKindForName, [:pointer, :size_t], :uint
30
+
31
+ # unsigned LLVMGetAttributeCountAtIndex
32
+ # (LLVMValueRef F, LLVMAttributeIndex Idx);
33
+ attach_function :get_attribute_count_at_index, :LLVMGetAttributeCountAtIndex, [:pointer, :llvmattributeindex], :uint
34
+
35
+ # void LLVMGetAttributesAtIndex
36
+ # (LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs);
37
+ attach_function :get_attributes_at_index, :LLVMGetAttributesAtIndex, [:pointer, :llvmattributeindex, :pointer], :void
38
+
39
+ # unsigned LLVMGetEnumAttributeKind
40
+ # (LLVMAttributeRef A);
41
+ attach_function :get_enum_attribute_kind, :LLVMGetEnumAttributeKind, [:pointer], :uint
42
+
43
+ # uint64_t LLVMGetEnumAttributeValue
44
+ # (LLVMAttributeRef A);
45
+ attach_function :get_enum_attribute_value, :LLVMGetEnumAttributeKind, [:pointer], :uint64
46
+
47
+ # const char *LLVMGetStringAttributeKind
48
+ # (LLVMAttributeRef A, unsigned *Length);
49
+ attach_function :get_string_attribute_kind, :LLVMGetStringAttributeKind, [:pointer, :pointer], :pointer
50
+
51
+ # const char *LLVMGetStringAttributeValue
52
+ # (LLVMAttributeRef A, unsigned *Length);
53
+ attach_function :get_string_attribute_value, :LLVMGetStringAttributeValue, [:pointer, :pointer], :pointer
9
54
  end
10
55
 
11
56
  # Yields a pointer suitable for storing an LLVM output message.
@@ -23,7 +68,7 @@ module LLVM
23
68
  msg_ptr = str.read_pointer
24
69
 
25
70
  if result != 0
26
- raise RuntimeError, "Error is signalled, but msg_ptr is null" if msg_ptr.null?
71
+ raise "Error is signalled, but msg_ptr is null" if msg_ptr.null?
27
72
 
28
73
  message = msg_ptr.read_string
29
74
  C.dispose_message msg_ptr
@@ -41,7 +86,7 @@ module LLVM
41
86
  def self.with_error_output(&block)
42
87
  error = with_message_output(&block)
43
88
 
44
- raise RuntimeError, error unless error.nil?
89
+ raise error unless error.nil?
45
90
  end
46
91
 
47
92
  require 'llvm/core/context'