ruby-llvm 3.4.2 → 13.0.0

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 (47) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +21 -4
  3. data/ext/ruby-llvm-support/Rakefile +15 -6
  4. data/ext/ruby-llvm-support/support.cpp +0 -12
  5. data/lib/llvm/analysis_ffi.rb +30 -28
  6. data/lib/llvm/config.rb +4 -4
  7. data/lib/llvm/core/bitcode.rb +10 -10
  8. data/lib/llvm/core/bitcode_ffi.rb +92 -70
  9. data/lib/llvm/core/builder.rb +2 -3
  10. data/lib/llvm/core/context.rb +1 -1
  11. data/lib/llvm/core/pass_manager.rb +4 -2
  12. data/lib/llvm/core/type.rb +2 -2
  13. data/lib/llvm/core/value.rb +148 -26
  14. data/lib/llvm/core.rb +45 -2
  15. data/lib/llvm/core_ffi.rb +4038 -3716
  16. data/lib/llvm/execution_engine.rb +45 -36
  17. data/lib/llvm/execution_engine_ffi.rb +245 -272
  18. data/lib/llvm/linker.rb +2 -19
  19. data/lib/llvm/linker_ffi.rb +24 -25
  20. data/lib/llvm/support.rb +0 -8
  21. data/lib/llvm/target.rb +9 -15
  22. data/lib/llvm/target_ffi.rb +336 -362
  23. data/lib/llvm/transforms/builder.rb +1 -1
  24. data/lib/llvm/transforms/builder_ffi.rb +57 -58
  25. data/lib/llvm/transforms/ipo.rb +1 -1
  26. data/lib/llvm/transforms/ipo_ffi.rb +60 -61
  27. data/lib/llvm/transforms/scalar_ffi.rb +208 -136
  28. data/lib/llvm/transforms/vectorize_ffi.rb +15 -16
  29. data/lib/llvm/version.rb +3 -2
  30. data/lib/llvm.rb +0 -6
  31. data/test/basic_block_test.rb +0 -1
  32. data/test/bitcode_test.rb +1 -2
  33. data/test/call_test.rb +1 -1
  34. data/test/double_test.rb +8 -7
  35. data/test/equality_test.rb +2 -4
  36. data/test/function_test.rb +27 -0
  37. data/test/generic_value_test.rb +1 -1
  38. data/test/instruction_test.rb +0 -2
  39. data/test/ipo_test.rb +1 -1
  40. data/test/linker_test.rb +0 -9
  41. data/test/mcjit_test.rb +14 -1
  42. data/test/module_test.rb +20 -1
  43. data/test/pass_manager_builder_test.rb +1 -2
  44. data/test/target_test.rb +8 -24
  45. data/test/test_helper.rb +4 -1
  46. metadata +103 -41
  47. data/lib/llvm/support_ffi.rb +0 -23
@@ -12,7 +12,7 @@ module LLVM
12
12
 
13
13
  # Returns the Value type. This is abstract and is overidden by its subclasses.
14
14
  def self.type
15
- raise NotImplementedError, "#{self.name}.type() is abstract."
15
+ raise NotImplementedError, "#{name}.type() is abstract."
16
16
  end
17
17
 
18
18
  def self.to_ptr
@@ -66,8 +66,45 @@ module LLVM
66
66
 
67
67
  # Adds attr to this value's attributes.
68
68
  def add_attribute(attr)
69
- C.add_attribute(self, attr)
69
+ fun = param_parent
70
+ return unless fun
71
+
72
+ index = param_index(fun)
73
+ return unless index
74
+
75
+ fun.add_attribute(attr, index)
76
+ end
77
+
78
+ # Removes the given attribute from the function.
79
+ def remove_attribute(attr)
80
+ fun = param_parent
81
+ return unless fun
82
+
83
+ index = param_index(fun)
84
+ return unless index
85
+
86
+ fun.remove_attribute(attr, index)
70
87
  end
88
+
89
+ private
90
+
91
+ # get function this param belongs to
92
+ # return if it is not a param
93
+ def param_parent
94
+ valueref = C.get_param_parent(self)
95
+ return if valueref.null?
96
+ fun = LLVM::Function.from_ptr(valueref)
97
+ return if fun.null?
98
+ fun
99
+ end
100
+
101
+ # get index of this param by llvm count (+1 from parametercollection)
102
+ def param_index(fun)
103
+ index = fun.params.find_index(self)
104
+ return if index.nil?
105
+ index + 1
106
+ end
107
+
71
108
  end
72
109
 
73
110
  class Argument < Value
@@ -76,7 +113,7 @@ module LLVM
76
113
  class BasicBlock < Value
77
114
  # Creates a basic block for the given function with the given name.
78
115
  def self.create(fun = nil, name = "")
79
- self.from_ptr(C.append_basic_block(fun, name))
116
+ from_ptr(C.append_basic_block(fun, name))
80
117
  end
81
118
 
82
119
  # Build the basic block with the given builder. Creates a new one if nil. Yields the builder.
@@ -110,11 +147,13 @@ module LLVM
110
147
  BasicBlock.from_ptr(ptr) unless ptr.null?
111
148
  end
112
149
 
113
- def first_instruction # deprecated
150
+ # deprecated
151
+ def first_instruction
114
152
  instructions.first
115
153
  end
116
154
 
117
- def last_instruction # deprecated
155
+ # deprecated
156
+ def last_instruction
118
157
  instructions.last
119
158
  end
120
159
 
@@ -192,7 +231,7 @@ module LLVM
192
231
  # Iterates through each operand in the collection.
193
232
  def each
194
233
  return to_enum :each unless block_given?
195
- 0.upto(size-1) { |i| yield self[i] }
234
+ 0.upto(size - 1) { |i| yield self[i] }
196
235
  self
197
236
  end
198
237
  end
@@ -446,10 +485,10 @@ module LLVM
446
485
  end
447
486
  end
448
487
 
449
- def LLVM.const_missing(const)
488
+ def self.const_missing(const)
450
489
  case const.to_s
451
490
  when /Int(\d+)/
452
- width = $1.to_i
491
+ width = Regexp.last_match(1).to_i
453
492
  name = "Int#{width}"
454
493
  eval <<-KLASS
455
494
  class #{name} < ConstantInt
@@ -469,7 +508,7 @@ module LLVM
469
508
  ::LLVM::Int = const_get("Int#{bits}")
470
509
 
471
510
  # Creates a LLVM Int (subclass of ConstantInt) at the NATIVE_INT_SIZE from a integer (val).
472
- def LLVM.Int(val)
511
+ def self.Int(val)
473
512
  case val
474
513
  when LLVM::ConstantInt then val
475
514
  when Integer then Int.from_i(val)
@@ -550,7 +589,7 @@ module LLVM
550
589
  end
551
590
 
552
591
  # Create a LLVM::Float from a Ruby Float (val).
553
- def LLVM.Float(val)
592
+ def self.Float(val)
554
593
  Float.from_f(val)
555
594
  end
556
595
 
@@ -560,7 +599,7 @@ module LLVM
560
599
  end
561
600
  end
562
601
 
563
- def LLVM.Double(val)
602
+ def self.Double(val)
564
603
  Double.from_f(val)
565
604
  end
566
605
 
@@ -652,11 +691,19 @@ module LLVM
652
691
  end
653
692
 
654
693
  def unnamed_addr?
655
- Support::C.has_unnamed_addr(self) != 0
694
+ C.has_unnamed_addr(self) != 0
656
695
  end
657
696
 
658
697
  def unnamed_addr=(flag)
659
- Support::C.set_unnamed_addr(self, flag ? 1 : 0)
698
+ C.set_unnamed_addr(self, flag ? 1 : 0)
699
+ end
700
+
701
+ def dll_storage_class
702
+ C.get_dll_storage_class(self)
703
+ end
704
+
705
+ def dll_storage_class=(klass)
706
+ C.set_dll_storage_class(self, klass)
660
707
  end
661
708
  end
662
709
 
@@ -667,16 +714,6 @@ module LLVM
667
714
  conv
668
715
  end
669
716
 
670
- # Adds the given attribute to the function.
671
- def add_attribute(attr)
672
- C.add_function_attr(self, attr)
673
- end
674
-
675
- # Removes the given attribute from the function.
676
- def remove_attribute(attr)
677
- C.remove_function_attr(self, attr)
678
- end
679
-
680
717
  # Returns an Enumerable of the BasicBlocks in this function.
681
718
  def basic_blocks
682
719
  @basic_block_collection ||= BasicBlockCollection.new(self)
@@ -690,6 +727,90 @@ module LLVM
690
727
  type.element_type
691
728
  end
692
729
 
730
+ # Adds attr to this value's attributes.
731
+ def add_attribute(attr, index = -1)
732
+ AttributeCollection.new(self, index).add(attr)
733
+ end
734
+
735
+ # Removes the given attribute from the function.
736
+ def remove_attribute(attr, index = -1)
737
+ AttributeCollection.new(self, index).remove(attr)
738
+ end
739
+
740
+ def attribute_count
741
+ function_attributes.count
742
+ end
743
+
744
+ def attributes
745
+ function_attributes.to_a
746
+ end
747
+
748
+ def function_attributes
749
+ AttributeCollection.new(self, -1)
750
+ end
751
+
752
+ def return_attributes
753
+ AttributeCollection.new(self, 0)
754
+ end
755
+
756
+ def param_attributes(index)
757
+ AttributeCollection.new(self, index)
758
+ end
759
+
760
+ class AttributeCollection
761
+
762
+ def initialize(fun, index)
763
+ @fun = fun
764
+ @index = index
765
+ end
766
+
767
+ def add(attr)
768
+ attr_kind_id = attribute_id(attr)
769
+ ctx = Context.global
770
+ attr_ref = C.create_enum_attribute(ctx, attr_kind_id, 0)
771
+ C.add_attribute_at_index(@fun, @index, attr_ref)
772
+ end
773
+
774
+ def remove(attr)
775
+ attr_kind_id = attribute_id(attr)
776
+ C.remove_enum_attribute_at_index(@fun, @index, attr_kind_id)
777
+ end
778
+
779
+ def count
780
+ C.get_attribute_count_at_index(@fun, @index)
781
+ end
782
+
783
+ def to_a
784
+ attr_refs = nil
785
+ n = count
786
+ FFI::MemoryPointer.new(:pointer, n) do |p|
787
+ C.get_attributes_at_index(@fun, @index, p)
788
+ attr_refs = p.read_array_of_type(:pointer, :read_pointer, n)
789
+ end
790
+
791
+ attr_refs.map { |e| C.get_enum_attribute_kind(e) }
792
+ end
793
+
794
+ private
795
+
796
+ def attribute_name(attr_name)
797
+ attr_name = attr_name.to_s
798
+ if attr_name =~ /_attribute$/
799
+ attr_name.chomp('_attribute').tr('_', '')
800
+ else
801
+ attr_name
802
+ end
803
+ end
804
+
805
+ def attribute_id(attr_name)
806
+ attr_mem = FFI::MemoryPointer.from_string(attribute_name(attr_name))
807
+ attr_kind_id = C.get_enum_attribute_kind_for_name(attr_mem, attr_mem.size - 1)
808
+
809
+ raise "No attribute named: #{attr_name}" if attr_kind_id.zero?
810
+ attr_kind_id
811
+ end
812
+ end
813
+
693
814
  # @private
694
815
  class BasicBlockCollection
695
816
  include Enumerable
@@ -708,7 +829,7 @@ module LLVM
708
829
  return to_enum :each unless block_given?
709
830
 
710
831
  ptr = C.get_first_basic_block(@fun)
711
- 0.upto(size-1) do |i|
832
+ 0.upto(size - 1) do |i|
712
833
  yield BasicBlock.from_ptr(ptr)
713
834
  ptr = C.get_next_basic_block(ptr)
714
835
  end
@@ -753,7 +874,7 @@ module LLVM
753
874
 
754
875
  # Returns a Value representation of the parameter at the given index.
755
876
  def [](i)
756
- sz = self.size
877
+ sz = size
757
878
  i = sz + i if i < 0
758
879
  return unless 0 <= i && i < sz
759
880
  Value.from_ptr(C.get_param(@fun, i))
@@ -769,7 +890,7 @@ module LLVM
769
890
  # Iteraters through each parameter in the collection.
770
891
  def each
771
892
  return to_enum :each unless block_given?
772
- 0.upto(size-1) { |i| yield self[i] }
893
+ 0.upto(size - 1) { |i| yield self[i] }
773
894
  self
774
895
  end
775
896
  end
@@ -777,6 +898,7 @@ module LLVM
777
898
  def gc=(name)
778
899
  C.set_gc(self, name)
779
900
  end
901
+
780
902
  def gc
781
903
  C.get_gc(self)
782
904
  end
data/lib/llvm/core.rb CHANGED
@@ -6,6 +6,49 @@ module LLVM
6
6
  # @private
7
7
  module C
8
8
  attach_function :dispose_message, :LLVMDisposeMessage, [:pointer], :void
9
+
10
+ # typedef unsigned LLVMAttributeIndex;
11
+ typedef(:uint, :llvmattributeindex)
12
+
13
+ # void LLVMAddAttributeAtIndex
14
+ # (LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef A);
15
+ attach_function :add_attribute_at_index, :LLVMAddAttributeAtIndex, [:pointer, :llvmattributeindex, :pointer], :void
16
+
17
+ # void LLVMRemoveEnumAttributeAtIndex
18
+ # (LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID);
19
+ attach_function :remove_enum_attribute_at_index, :LLVMRemoveEnumAttributeAtIndex, [:pointer, :llvmattributeindex, :uint], :void
20
+
21
+ # LLVMAttributeRef LLVMCreateEnumAttribute
22
+ # (LLVMContextRef C, unsigned KindID, uint64_t Val);
23
+ attach_function :create_enum_attribute, :LLVMCreateEnumAttribute, [:pointer, :uint, :uint64], :pointer
24
+
25
+ # unsigned LLVMGetEnumAttributeKindForName
26
+ # (const char *Name, size_t SLen);
27
+ attach_function :get_enum_attribute_kind_for_name, :LLVMGetEnumAttributeKindForName, [:pointer, :size_t], :uint
28
+
29
+ # unsigned LLVMGetAttributeCountAtIndex
30
+ # (LLVMValueRef F, LLVMAttributeIndex Idx);
31
+ attach_function :get_attribute_count_at_index, :LLVMGetAttributeCountAtIndex, [:pointer, :llvmattributeindex], :uint
32
+
33
+ # void LLVMGetAttributesAtIndex
34
+ # (LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs);
35
+ attach_function :get_attributes_at_index, :LLVMGetAttributesAtIndex, [:pointer, :llvmattributeindex, :pointer], :void
36
+
37
+ # unsigned LLVMGetEnumAttributeKind
38
+ # (LLVMAttributeRef A);
39
+ attach_function :get_enum_attribute_kind, :LLVMGetEnumAttributeKind, [:pointer], :uint
40
+
41
+ # uint64_t LLVMGetEnumAttributeValue
42
+ # (LLVMAttributeRef A);
43
+ attach_function :get_enum_attribute_value, :LLVMGetEnumAttributeKind, [:pointer], :uint64
44
+
45
+ # const char *LLVMGetStringAttributeKind
46
+ # (LLVMAttributeRef A, unsigned *Length);
47
+ attach_function :get_string_attribute_kind, :LLVMGetStringAttributeKind, [:pointer, :pointer], :pointer
48
+
49
+ # const char *LLVMGetStringAttributeValue
50
+ # (LLVMAttributeRef A, unsigned *Length);
51
+ attach_function :get_string_attribute_value, :LLVMGetStringAttributeValue, [:pointer, :pointer], :pointer
9
52
  end
10
53
 
11
54
  # Yields a pointer suitable for storing an LLVM output message.
@@ -23,7 +66,7 @@ module LLVM
23
66
  msg_ptr = str.read_pointer
24
67
 
25
68
  if result != 0
26
- raise RuntimeError, "Error is signalled, but msg_ptr is null" if msg_ptr.null?
69
+ raise "Error is signalled, but msg_ptr is null" if msg_ptr.null?
27
70
 
28
71
  message = msg_ptr.read_string
29
72
  C.dispose_message msg_ptr
@@ -41,7 +84,7 @@ module LLVM
41
84
  def self.with_error_output(&block)
42
85
  error = with_message_output(&block)
43
86
 
44
- raise RuntimeError, error unless error.nil?
87
+ raise error unless error.nil?
45
88
  end
46
89
 
47
90
  require 'llvm/core/context'