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.
- checksums.yaml +5 -5
- data/README.md +21 -4
- data/ext/ruby-llvm-support/Rakefile +15 -6
- data/ext/ruby-llvm-support/support.cpp +0 -12
- data/lib/llvm/analysis_ffi.rb +30 -28
- data/lib/llvm/config.rb +4 -4
- data/lib/llvm/core/bitcode.rb +10 -10
- data/lib/llvm/core/bitcode_ffi.rb +92 -70
- data/lib/llvm/core/builder.rb +2 -3
- data/lib/llvm/core/context.rb +1 -1
- data/lib/llvm/core/pass_manager.rb +4 -2
- data/lib/llvm/core/type.rb +2 -2
- data/lib/llvm/core/value.rb +148 -26
- data/lib/llvm/core.rb +45 -2
- data/lib/llvm/core_ffi.rb +4038 -3716
- data/lib/llvm/execution_engine.rb +45 -36
- data/lib/llvm/execution_engine_ffi.rb +245 -272
- data/lib/llvm/linker.rb +2 -19
- data/lib/llvm/linker_ffi.rb +24 -25
- data/lib/llvm/support.rb +0 -8
- data/lib/llvm/target.rb +9 -15
- data/lib/llvm/target_ffi.rb +336 -362
- data/lib/llvm/transforms/builder.rb +1 -1
- data/lib/llvm/transforms/builder_ffi.rb +57 -58
- data/lib/llvm/transforms/ipo.rb +1 -1
- data/lib/llvm/transforms/ipo_ffi.rb +60 -61
- data/lib/llvm/transforms/scalar_ffi.rb +208 -136
- data/lib/llvm/transforms/vectorize_ffi.rb +15 -16
- data/lib/llvm/version.rb +3 -2
- data/lib/llvm.rb +0 -6
- data/test/basic_block_test.rb +0 -1
- data/test/bitcode_test.rb +1 -2
- data/test/call_test.rb +1 -1
- data/test/double_test.rb +8 -7
- data/test/equality_test.rb +2 -4
- data/test/function_test.rb +27 -0
- data/test/generic_value_test.rb +1 -1
- data/test/instruction_test.rb +0 -2
- data/test/ipo_test.rb +1 -1
- data/test/linker_test.rb +0 -9
- data/test/mcjit_test.rb +14 -1
- data/test/module_test.rb +20 -1
- data/test/pass_manager_builder_test.rb +1 -2
- data/test/target_test.rb +8 -24
- data/test/test_helper.rb +4 -1
- metadata +103 -41
- data/lib/llvm/support_ffi.rb +0 -23
data/lib/llvm/core/value.rb
CHANGED
@@ -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, "#{
|
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
|
-
|
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
|
-
|
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
|
-
|
150
|
+
# deprecated
|
151
|
+
def first_instruction
|
114
152
|
instructions.first
|
115
153
|
end
|
116
154
|
|
117
|
-
|
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
|
488
|
+
def self.const_missing(const)
|
450
489
|
case const.to_s
|
451
490
|
when /Int(\d+)/
|
452
|
-
width =
|
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
|
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
|
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
|
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
|
-
|
694
|
+
C.has_unnamed_addr(self) != 0
|
656
695
|
end
|
657
696
|
|
658
697
|
def unnamed_addr=(flag)
|
659
|
-
|
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 =
|
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
|
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
|
87
|
+
raise error unless error.nil?
|
45
88
|
end
|
46
89
|
|
47
90
|
require 'llvm/core/context'
|