ruby-llvm 15.0.3 → 16.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 +4 -4
- data/ext/ruby-llvm-support/Rakefile +5 -1
- data/ext/ruby-llvm-support/support.cpp +7 -0
- data/lib/llvm/analysis.rb +9 -1
- data/lib/llvm/analysis_ffi.rb +1 -1
- data/lib/llvm/config.rb +7 -4
- data/lib/llvm/core/attribute.rb +158 -0
- data/lib/llvm/core/bitcode.rb +22 -0
- data/lib/llvm/core/bitcode_ffi.rb +1 -1
- data/lib/llvm/core/builder.rb +2 -0
- data/lib/llvm/core/module.rb +10 -0
- data/lib/llvm/core/value.rb +99 -13
- data/lib/llvm/core.rb +65 -3
- data/lib/llvm/core_ffi.rb +1 -1
- data/lib/llvm/execution_engine_ffi.rb +1 -1
- data/lib/llvm/linker_ffi.rb +1 -1
- data/lib/llvm/support.rb +2 -0
- data/lib/llvm/target.rb +18 -3
- data/lib/llvm/target_ffi.rb +1 -1
- data/lib/llvm/transforms/builder_ffi.rb +1 -1
- data/lib/llvm/transforms/ipo.rb +1 -1
- data/lib/llvm/transforms/ipo_ffi.rb +1 -1
- data/lib/llvm/transforms/scalar_ffi.rb +1 -1
- data/lib/llvm/transforms/vectorize_ffi.rb +1 -1
- data/lib/llvm/version.rb +3 -3
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eab8e45c12865b1daf5e471e0e01d59a80580a910fffb0b698c53602ce49fd66
|
|
4
|
+
data.tar.gz: e2b3bbf235ab6a378cb322e69e255b17e3f29f38af990e2c2c315b603cd8f534
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6aefeb6655934955bfaa5073541d028488c053094c7e47ea6ef4562833f3c84cd52e100641a921671213d1f8d792cc8b1b839312caf0acf12a449a310cd13292
|
|
7
|
+
data.tar.gz: d8d01c13ec575e0ba7f5f9b2bdd11cb66c10bdfb6e0eb39187f151c81fa810dddfae34763d2e2bdc5cf30bacd71dc9034f1f4dab5c2c8bcfff5072710edc652b
|
|
@@ -76,18 +76,22 @@ CLEAN.include(SUPPORT_LIB, CONFIG_MOD)
|
|
|
76
76
|
desc "Build the shared library and config module"
|
|
77
77
|
task :default => [SUPPORT_LIB, CONFIG_MOD]
|
|
78
78
|
|
|
79
|
+
# -I/usr/lib/llvm-14/include/c++/v1/ is needed for CI
|
|
79
80
|
file SUPPORT_LIB => %w(support.cpp) do |task|
|
|
80
81
|
clang_stdlib = CXX.match?(/^clang++/) ? "-stdlib=libc++" : ""
|
|
81
82
|
sh "#{CXX} -O3 -shared #{task.prerequisites.join(' ')} -l#{llvm_lib_name} " \
|
|
82
|
-
"#{invoke_llvm_config('--cxxflags --ldflags')} -fPIC #{clang_stdlib} -o #{SUPPORT_LIB}"
|
|
83
|
+
"#{invoke_llvm_config('--cxxflags --ldflags')} -I/usr/lib/llvm-14/include/c++/v1/ -fPIC #{clang_stdlib} -o #{SUPPORT_LIB}"
|
|
83
84
|
end
|
|
84
85
|
|
|
85
86
|
LLVM_CONFIG_OPTS = [
|
|
87
|
+
['VERSION', :string, '--version'],
|
|
86
88
|
['COMPONENTS', :array, '--components'],
|
|
87
89
|
['TARGETS_BUILT', :array, '--targets-built'],
|
|
88
90
|
['HOST_TARGET', :string, '--host-target'],
|
|
89
91
|
['BUILD_MODE', :string, '--build-mode'],
|
|
90
92
|
['CFLAGS', :string, '--cflags'],
|
|
93
|
+
['CXXFLAGS', :string, '--cxxflags'],
|
|
94
|
+
['LDFLAGS', :string, '--ldflags'],
|
|
91
95
|
].freeze
|
|
92
96
|
|
|
93
97
|
file CONFIG_MOD do
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
#include <llvm/Support/TargetSelect.h>
|
|
6
|
+
#include <llvm/IR/Attributes.h>
|
|
6
7
|
|
|
7
8
|
extern "C" {
|
|
8
9
|
void LLVMInitializeAllTargetInfos() {
|
|
@@ -28,5 +29,11 @@ extern "C" {
|
|
|
28
29
|
void LLVMInitializeNativeAsmPrinter() {
|
|
29
30
|
llvm::InitializeNativeTargetAsmPrinter();
|
|
30
31
|
}
|
|
32
|
+
|
|
33
|
+
const char* LLVMGetEnumAttributeNameForKind(const unsigned KindID) {
|
|
34
|
+
const auto AttrKind = (llvm::Attribute::AttrKind) KindID;
|
|
35
|
+
const auto S = llvm::Attribute::getNameFromAttrKind(AttrKind);
|
|
36
|
+
return S.data();
|
|
37
|
+
}
|
|
31
38
|
}
|
|
32
39
|
|
data/lib/llvm/analysis.rb
CHANGED
|
@@ -20,6 +20,10 @@ module LLVM
|
|
|
20
20
|
do_verification(:abort_process)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
def valid?
|
|
24
|
+
verify.nil?
|
|
25
|
+
end
|
|
26
|
+
|
|
23
27
|
private
|
|
24
28
|
|
|
25
29
|
def do_verification(action)
|
|
@@ -42,10 +46,14 @@ module LLVM
|
|
|
42
46
|
do_verification(:abort_process)
|
|
43
47
|
end
|
|
44
48
|
|
|
49
|
+
def valid?
|
|
50
|
+
verify
|
|
51
|
+
end
|
|
52
|
+
|
|
45
53
|
private
|
|
46
54
|
|
|
47
55
|
def do_verification(action)
|
|
48
|
-
C.verify_function(self, action)
|
|
56
|
+
C.verify_function(self, action).zero?
|
|
49
57
|
end
|
|
50
58
|
end
|
|
51
59
|
end
|
data/lib/llvm/analysis_ffi.rb
CHANGED
data/lib/llvm/config.rb
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# Generated by ruby-llvm. Please do not change this file by hand.
|
|
2
2
|
module LLVM
|
|
3
3
|
module CONFIG
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
VERSION = "16.0.5"
|
|
5
|
+
COMPONENTS = ["aarch64", "aarch64asmparser", "aarch64codegen", "aarch64desc", "aarch64disassembler", "aarch64info", "aarch64utils", "aggressiveinstcombine", "all", "all-targets", "amdgpu", "amdgpuasmparser", "amdgpucodegen", "amdgpudesc", "amdgpudisassembler", "amdgpuinfo", "amdgputargetmca", "amdgpuutils", "analysis", "arm", "armasmparser", "armcodegen", "armdesc", "armdisassembler", "arminfo", "armutils", "asmparser", "asmprinter", "avr", "avrasmparser", "avrcodegen", "avrdesc", "avrdisassembler", "avrinfo", "binaryformat", "bitreader", "bitstreamreader", "bitwriter", "bpf", "bpfasmparser", "bpfcodegen", "bpfdesc", "bpfdisassembler", "bpfinfo", "cfguard", "codegen", "core", "coroutines", "coverage", "debuginfocodeview", "debuginfodwarf", "debuginfogsym", "debuginfologicalview", "debuginfomsf", "debuginfopdb", "demangle", "dlltooldriver", "dwarflinker", "dwarflinkerparallel", "dwp", "engine", "executionengine", "extensions", "filecheck", "frontendhlsl", "frontendopenacc", "frontendopenmp", "fuzzercli", "fuzzmutate", "globalisel", "hexagon", "hexagonasmparser", "hexagoncodegen", "hexagondesc", "hexagondisassembler", "hexagoninfo", "instcombine", "instrumentation", "interfacestub", "interpreter", "ipo", "irprinter", "irreader", "jitlink", "lanai", "lanaiasmparser", "lanaicodegen", "lanaidesc", "lanaidisassembler", "lanaiinfo", "libdriver", "lineeditor", "linker", "loongarch", "loongarchasmparser", "loongarchcodegen", "loongarchdesc", "loongarchdisassembler", "loongarchinfo", "lto", "m68k", "m68kasmparser", "m68kcodegen", "m68kdesc", "m68kdisassembler", "m68kinfo", "mc", "mca", "mcdisassembler", "mcjit", "mcparser", "mips", "mipsasmparser", "mipscodegen", "mipsdesc", "mipsdisassembler", "mipsinfo", "mirparser", "msp430", "msp430asmparser", "msp430codegen", "msp430desc", "msp430disassembler", "msp430info", "native", "nativecodegen", "nvptx", "nvptxcodegen", "nvptxdesc", "nvptxinfo", "objcarcopts", "objcopy", "object", "objectyaml", "option", "orcjit", "orcshared", "orctargetprocess", "passes", "perfjitevents", "powerpc", "powerpcasmparser", "powerpccodegen", "powerpcdesc", "powerpcdisassembler", "powerpcinfo", "profiledata", "remarks", "riscv", "riscvasmparser", "riscvcodegen", "riscvdesc", "riscvdisassembler", "riscvinfo", "riscvtargetmca", "runtimedyld", "scalaropts", "selectiondag", "sparc", "sparcasmparser", "sparccodegen", "sparcdesc", "sparcdisassembler", "sparcinfo", "support", "symbolize", "systemz", "systemzasmparser", "systemzcodegen", "systemzdesc", "systemzdisassembler", "systemzinfo", "tablegen", "target", "targetparser", "textapi", "transformutils", "ve", "veasmparser", "vecodegen", "vectorize", "vedesc", "vedisassembler", "veinfo", "webassembly", "webassemblyasmparser", "webassemblycodegen", "webassemblydesc", "webassemblydisassembler", "webassemblyinfo", "webassemblyutils", "windowsdriver", "windowsmanifest", "x86", "x86asmparser", "x86codegen", "x86desc", "x86disassembler", "x86info", "x86targetmca", "xcore", "xcorecodegen", "xcoredesc", "xcoredisassembler", "xcoreinfo", "xray"]
|
|
6
|
+
TARGETS_BUILT = ["AArch64", "AMDGPU", "ARM", "AVR", "BPF", "Hexagon", "Lanai", "LoongArch", "Mips", "MSP430", "NVPTX", "PowerPC", "RISCV", "Sparc", "SystemZ", "VE", "WebAssembly", "X86", "XCore", "M68k"]
|
|
6
7
|
HOST_TARGET = "x86_64-pc-linux-gnu"
|
|
7
|
-
BUILD_MODE = "
|
|
8
|
-
CFLAGS = "-I/usr/lib/llvm-
|
|
8
|
+
BUILD_MODE = "RelWithDebInfo"
|
|
9
|
+
CFLAGS = "-I/usr/lib/llvm-16/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
|
|
10
|
+
CXXFLAGS = "-I/usr/lib/llvm-16/include -std=c++17 -fno-exceptions -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
|
|
11
|
+
LDFLAGS = "-L/usr/lib/llvm-16/lib"
|
|
9
12
|
end
|
|
10
13
|
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LLVM
|
|
4
|
+
class Attribute
|
|
5
|
+
|
|
6
|
+
include PointerIdentity
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
|
|
10
|
+
def new(from)
|
|
11
|
+
case from
|
|
12
|
+
when String, Symbol
|
|
13
|
+
enum(from)
|
|
14
|
+
else
|
|
15
|
+
raise "Not implemented to create Attribute from #{from.class}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# create a memory attribute from a hash where the keys are:
|
|
20
|
+
# argmem, inaccessiblemem, memory
|
|
21
|
+
# and the valid values are:
|
|
22
|
+
# read, write, readwrite
|
|
23
|
+
def memory(opts = {})
|
|
24
|
+
opts = opts.transform_keys(&:to_sym)
|
|
25
|
+
val = bit_value(opts[:argmem]) | (bit_value(opts[:inaccessiblemem]) << 2) | (bit_value(opts[:memory]) << 4)
|
|
26
|
+
enum(:memory, val)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# create enum attribute with optional value and context
|
|
30
|
+
def enum(kind, value = 0, context = Context.global)
|
|
31
|
+
attr_id = attribute_id(kind)
|
|
32
|
+
ptr = C.create_enum_attribute(context, attr_id, value)
|
|
33
|
+
from_ptr(ptr)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# create string attribute with key and value
|
|
37
|
+
def string(key, value, context = Context.global)
|
|
38
|
+
key = key.to_s
|
|
39
|
+
value = value.to_s
|
|
40
|
+
ptr = C.create_string_attribute(context, key, key.size, value, value.size)
|
|
41
|
+
from_ptr(ptr)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def last_enum
|
|
45
|
+
C.get_last_enum_attribute_kind
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def from_ptr(ptr)
|
|
51
|
+
return if ptr.null?
|
|
52
|
+
val = allocate
|
|
53
|
+
val.instance_variable_set(:@ptr, ptr)
|
|
54
|
+
val
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def attribute_name(attr_name)
|
|
58
|
+
attr_name = attr_name.to_s
|
|
59
|
+
if /_attribute$/.match?(attr_name)
|
|
60
|
+
attr_name.chomp('_attribute').tr('_', '')
|
|
61
|
+
else
|
|
62
|
+
attr_name
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def attribute_id(attr_name)
|
|
67
|
+
attr_mem = FFI::MemoryPointer.from_string(attribute_name(attr_name))
|
|
68
|
+
attr_kind_id = C.get_enum_attribute_kind_for_name(attr_mem, attr_mem.size - 1)
|
|
69
|
+
|
|
70
|
+
raise "No attribute named: #{attr_name}" if attr_kind_id.zero?
|
|
71
|
+
attr_kind_id
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# returns correct 2 bits of memory value:
|
|
75
|
+
# 0 = none
|
|
76
|
+
# 1 = read
|
|
77
|
+
# 2 = write
|
|
78
|
+
# 3 = readwrite
|
|
79
|
+
def bit_value(maybe_value)
|
|
80
|
+
case maybe_value.to_s
|
|
81
|
+
when 'read'
|
|
82
|
+
1
|
|
83
|
+
when 'write'
|
|
84
|
+
2
|
|
85
|
+
when 'readwrite'
|
|
86
|
+
3
|
|
87
|
+
else
|
|
88
|
+
0
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def kind
|
|
95
|
+
return enum_kind if enum?
|
|
96
|
+
return string_kind if string?
|
|
97
|
+
raise
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def value
|
|
101
|
+
return C.get_enum_attribute_value(self) if enum?
|
|
102
|
+
return string_value if string?
|
|
103
|
+
raise
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def enum?
|
|
107
|
+
C.is_enum_attribute(self)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def string?
|
|
111
|
+
C.is_string_attribute(self)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def type?
|
|
115
|
+
C.is_type_attribute(self)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def inspect
|
|
119
|
+
return "\"#{kind}\" = \"#{value}\"" if string?
|
|
120
|
+
return "#{kind}(#{value})" if enum?
|
|
121
|
+
super
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def to_s
|
|
125
|
+
return kind if enum?
|
|
126
|
+
super
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def kind_id
|
|
130
|
+
enum_kind_id
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
def enum_kind_id
|
|
136
|
+
C.get_enum_attribute_kind(self)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def enum_kind
|
|
140
|
+
Support::C.get_enum_attribute_name_for_kind(enum_kind_id)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# wraps get_string_attribute_kind
|
|
144
|
+
def string_kind
|
|
145
|
+
FFI::MemoryPointer.new(:uint64) do |size_ptr|
|
|
146
|
+
return C.get_string_attribute_kind(self, size_ptr)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# wraps get_string_attribute_value
|
|
151
|
+
def string_value
|
|
152
|
+
FFI::MemoryPointer.new(:uint) do |size_ptr|
|
|
153
|
+
return C.get_string_attribute_value(self, size_ptr)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
end
|
|
158
|
+
end
|
data/lib/llvm/core/bitcode.rb
CHANGED
|
@@ -36,6 +36,28 @@ module LLVM
|
|
|
36
36
|
end
|
|
37
37
|
status == 0
|
|
38
38
|
end
|
|
39
|
+
|
|
40
|
+
def self.parse_ir(path_or_memory_buffer, context = Context.global)
|
|
41
|
+
memory_buffer = case path_or_memory_buffer
|
|
42
|
+
when MemoryBuffer then path_or_memory_buffer
|
|
43
|
+
else MemoryBuffer.from_file(path_or_memory_buffer)
|
|
44
|
+
end
|
|
45
|
+
FFI::MemoryPointer.new(:pointer) do |mod_ref|
|
|
46
|
+
FFI::MemoryPointer.new(:pointer) do |msg_ref|
|
|
47
|
+
status = C.parse_ir_in_context(context, memory_buffer, mod_ref, msg_ref)
|
|
48
|
+
raise msg_ref.get_pointer(0).get_string(0) if status
|
|
49
|
+
return from_ptr(mod_ref.get_pointer(0))
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def write_ir!(filename)
|
|
55
|
+
FFI::MemoryPointer.new(:pointer) do |msg_ref|
|
|
56
|
+
status = C.print_module_to_file(self, filename, msg_ref)
|
|
57
|
+
raise msg_ref.get_pointer(0).get_string(0) if status != 0
|
|
58
|
+
end
|
|
59
|
+
self
|
|
60
|
+
end
|
|
39
61
|
end
|
|
40
62
|
|
|
41
63
|
# @private
|
data/lib/llvm/core/builder.rb
CHANGED
|
@@ -563,6 +563,7 @@ module LLVM
|
|
|
563
563
|
# @return [LLVM::Instruction] The resulting pointer
|
|
564
564
|
# @LLVMinst gep
|
|
565
565
|
# @see http://llvm.org/docs/GetElementPtr.html
|
|
566
|
+
# may return Instruction or GlobalVariable
|
|
566
567
|
def gep(ptr, indices, name = "")
|
|
567
568
|
gep2(nil, ptr, indices, name)
|
|
568
569
|
end
|
|
@@ -576,6 +577,7 @@ module LLVM
|
|
|
576
577
|
# @return [LLVM::Instruction] The resulting pointer
|
|
577
578
|
# @LLVMinst gep2
|
|
578
579
|
# @see http://llvm.org/docs/GetElementPtr.html
|
|
580
|
+
# may return Instruction or GlobalVariable
|
|
579
581
|
def gep2(type, ptr, indices, name)
|
|
580
582
|
must_be_value!(ptr)
|
|
581
583
|
|
data/lib/llvm/core/module.rb
CHANGED
|
@@ -24,6 +24,16 @@ module LLVM
|
|
|
24
24
|
@ptr = nil
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
def inspect
|
|
28
|
+
{
|
|
29
|
+
triple: triple,
|
|
30
|
+
globals: globals.count,
|
|
31
|
+
functions: functions.count,
|
|
32
|
+
lines: to_s.lines.size,
|
|
33
|
+
valid: valid?,
|
|
34
|
+
}.to_s
|
|
35
|
+
end
|
|
36
|
+
|
|
27
37
|
# Get module triple.
|
|
28
38
|
#
|
|
29
39
|
# @return [String]
|
data/lib/llvm/core/value.rb
CHANGED
|
@@ -12,6 +12,26 @@ module LLVM
|
|
|
12
12
|
val
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
def self.from_ptr_kind(ptr)
|
|
16
|
+
return if ptr.null?
|
|
17
|
+
|
|
18
|
+
kind = C.get_value_kind(ptr)
|
|
19
|
+
case kind
|
|
20
|
+
when :instruction
|
|
21
|
+
Instruction.from_ptr(ptr)
|
|
22
|
+
when :const_int
|
|
23
|
+
Int.from_ptr(ptr)
|
|
24
|
+
when :const_fp
|
|
25
|
+
Float.from_ptr(ptr)
|
|
26
|
+
when :poison
|
|
27
|
+
Poison.from_ptr(ptr)
|
|
28
|
+
when :global_variable
|
|
29
|
+
GlobalValue.from_ptr(ptr)
|
|
30
|
+
else
|
|
31
|
+
raise "from_ptr_kind cannot handle: #{kind}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
15
35
|
# Returns the Value type. This is abstract and is overidden by its subclasses.
|
|
16
36
|
def self.type
|
|
17
37
|
raise NotImplementedError, "#{name}.type() is abstract."
|
|
@@ -26,6 +46,11 @@ module LLVM
|
|
|
26
46
|
Type.from_ptr(C.type_of(self), nil)
|
|
27
47
|
end
|
|
28
48
|
|
|
49
|
+
# Returns the value's kind.
|
|
50
|
+
def kind
|
|
51
|
+
C.get_value_kind(self)
|
|
52
|
+
end
|
|
53
|
+
|
|
29
54
|
def allocated_type
|
|
30
55
|
Type.from_ptr(C.get_allocated_type(self), nil)
|
|
31
56
|
end
|
|
@@ -412,22 +437,22 @@ module LLVM
|
|
|
412
437
|
|
|
413
438
|
# Unsigned division.
|
|
414
439
|
def udiv(rhs)
|
|
415
|
-
|
|
440
|
+
raise "constant udiv removed in LLVM 15"
|
|
416
441
|
end
|
|
417
442
|
|
|
418
443
|
# Signed division.
|
|
419
444
|
def /(rhs)
|
|
420
|
-
|
|
445
|
+
raise "constant sdiv removed in LLVM 15"
|
|
421
446
|
end
|
|
422
447
|
|
|
423
448
|
# Unsigned remainder.
|
|
424
449
|
def urem(rhs)
|
|
425
|
-
|
|
450
|
+
raise "constant urem removed in LLVM 15"
|
|
426
451
|
end
|
|
427
452
|
|
|
428
453
|
# Signed remainder.
|
|
429
454
|
def rem(rhs)
|
|
430
|
-
|
|
455
|
+
raise "constant srem removed in LLVM 15"
|
|
431
456
|
end
|
|
432
457
|
|
|
433
458
|
# Boolean negation.
|
|
@@ -507,6 +532,17 @@ module LLVM
|
|
|
507
532
|
def sext(type)
|
|
508
533
|
self.class.from_ptr(C.const_s_ext(self, type))
|
|
509
534
|
end
|
|
535
|
+
alias_method :ext, :sext
|
|
536
|
+
|
|
537
|
+
# constant trunc
|
|
538
|
+
def trunc(type)
|
|
539
|
+
self.class.from_ptr(C.const_trunc(self, type))
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
# LLVMValueRef LLVMConstSIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
|
|
543
|
+
def to_f(type)
|
|
544
|
+
self.class.from_ptr(C.const_si_to_fp(self, type))
|
|
545
|
+
end
|
|
510
546
|
end
|
|
511
547
|
|
|
512
548
|
def self.const_missing(const)
|
|
@@ -559,27 +595,27 @@ module LLVM
|
|
|
559
595
|
|
|
560
596
|
# Negation.
|
|
561
597
|
def -@
|
|
562
|
-
|
|
598
|
+
raise "constant fneg removed in LLVM 16"
|
|
563
599
|
end
|
|
564
600
|
|
|
565
601
|
# Returns the result of adding this ConstantReal to rhs.
|
|
566
602
|
def +(rhs)
|
|
567
|
-
|
|
603
|
+
raise "constant fadd removed in LLVM 15"
|
|
568
604
|
end
|
|
569
605
|
|
|
570
606
|
# Returns the result of multiplying this ConstantReal by rhs.
|
|
571
607
|
def *(rhs)
|
|
572
|
-
|
|
608
|
+
raise "constant fmul removed in LLVM 15"
|
|
573
609
|
end
|
|
574
610
|
|
|
575
611
|
# Returns the result of dividing this ConstantReal by rhs.
|
|
576
612
|
def /(rhs)
|
|
577
|
-
|
|
613
|
+
raise "constant fdiv removed in LLVM 15"
|
|
578
614
|
end
|
|
579
615
|
|
|
580
616
|
# Remainder.
|
|
581
617
|
def rem(rhs)
|
|
582
|
-
|
|
618
|
+
raise "constant frem removed in LLVM 15"
|
|
583
619
|
end
|
|
584
620
|
|
|
585
621
|
# Floating point comparison using the predicate specified via the first
|
|
@@ -603,6 +639,24 @@ module LLVM
|
|
|
603
639
|
def fcmp(pred, rhs)
|
|
604
640
|
self.class.from_ptr(C.llmv_const_f_cmp(pred, self, rhs))
|
|
605
641
|
end
|
|
642
|
+
|
|
643
|
+
# constant FPToSI
|
|
644
|
+
# LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
|
|
645
|
+
def to_i(type)
|
|
646
|
+
self.class.from_ptr(C.const_fp_to_si(self, type))
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
# Constant FPExt
|
|
650
|
+
# this is a signed extension
|
|
651
|
+
def ext(type)
|
|
652
|
+
self.class.from_ptr(C.const_fp_ext(self, type))
|
|
653
|
+
end
|
|
654
|
+
alias_method :sext, :ext
|
|
655
|
+
|
|
656
|
+
def trunc(type)
|
|
657
|
+
self.class.from_ptr(C.const_fp_trunc(self, type))
|
|
658
|
+
end
|
|
659
|
+
|
|
606
660
|
end
|
|
607
661
|
|
|
608
662
|
class Float < ConstantReal
|
|
@@ -802,9 +856,16 @@ module LLVM
|
|
|
802
856
|
end
|
|
803
857
|
|
|
804
858
|
def add(attr)
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
859
|
+
attr_ref = case attr
|
|
860
|
+
when Attribute
|
|
861
|
+
attr
|
|
862
|
+
when Symbol
|
|
863
|
+
attr_kind_id = attribute_id(attr)
|
|
864
|
+
ctx = Context.global
|
|
865
|
+
C.create_enum_attribute(ctx, attr_kind_id, 0)
|
|
866
|
+
else
|
|
867
|
+
raise "Adding unknown attribute type"
|
|
868
|
+
end
|
|
808
869
|
C.add_attribute_at_index(@fun, @index, attr_ref)
|
|
809
870
|
end
|
|
810
871
|
|
|
@@ -825,7 +886,7 @@ module LLVM
|
|
|
825
886
|
attr_refs = p.read_array_of_type(:pointer, :read_pointer, n)
|
|
826
887
|
end
|
|
827
888
|
|
|
828
|
-
attr_refs.map { |e|
|
|
889
|
+
attr_refs.map { |e| Attribute.send(:from_ptr, e) }
|
|
829
890
|
end
|
|
830
891
|
|
|
831
892
|
private
|
|
@@ -939,6 +1000,17 @@ module LLVM
|
|
|
939
1000
|
def gc
|
|
940
1001
|
C.get_gc(self)
|
|
941
1002
|
end
|
|
1003
|
+
|
|
1004
|
+
def inspect
|
|
1005
|
+
{
|
|
1006
|
+
signature: to_s.lines[attribute_count == 0 ? 0 : 1],
|
|
1007
|
+
type: type.to_s,
|
|
1008
|
+
attributes: attribute_count,
|
|
1009
|
+
valid: valid?,
|
|
1010
|
+
blocks: basic_blocks.size,
|
|
1011
|
+
lines: to_s.lines.size,
|
|
1012
|
+
}.to_s
|
|
1013
|
+
end
|
|
942
1014
|
end
|
|
943
1015
|
|
|
944
1016
|
class GlobalAlias < GlobalValue
|
|
@@ -966,6 +1038,12 @@ module LLVM
|
|
|
966
1038
|
end
|
|
967
1039
|
|
|
968
1040
|
class Instruction < User
|
|
1041
|
+
|
|
1042
|
+
def self.from_ptr(ptr)
|
|
1043
|
+
kind = C.get_value_kind(ptr)
|
|
1044
|
+
kind == :instruction ? super : LLVM::Value.from_ptr_kind(ptr)
|
|
1045
|
+
end
|
|
1046
|
+
|
|
969
1047
|
# Returns the parent of the instruction (a BasicBlock).
|
|
970
1048
|
def parent
|
|
971
1049
|
ptr = C.get_instruction_parent(self)
|
|
@@ -987,6 +1065,14 @@ module LLVM
|
|
|
987
1065
|
def opcode
|
|
988
1066
|
C.get_instruction_opcode(self)
|
|
989
1067
|
end
|
|
1068
|
+
|
|
1069
|
+
def inspect
|
|
1070
|
+
{ self.class.name => { opcode: opcode, ptr: @ptr } }.to_s
|
|
1071
|
+
end
|
|
1072
|
+
end
|
|
1073
|
+
|
|
1074
|
+
class Poison < Value
|
|
1075
|
+
|
|
990
1076
|
end
|
|
991
1077
|
|
|
992
1078
|
class CallInst < Instruction
|
data/lib/llvm/core.rb
CHANGED
|
@@ -24,10 +24,17 @@ module LLVM
|
|
|
24
24
|
# (LLVMContextRef C, unsigned KindID, uint64_t Val);
|
|
25
25
|
attach_function :create_enum_attribute, :LLVMCreateEnumAttribute, [:pointer, :uint, :uint64], :pointer
|
|
26
26
|
|
|
27
|
+
# LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
|
|
28
|
+
# const char *K, unsigned KLength,
|
|
29
|
+
# const char *V, unsigned VLength);
|
|
30
|
+
attach_function :create_string_attribute, :LLVMCreateStringAttribute, [:pointer, :string, :uint, :string, :uint], :pointer
|
|
31
|
+
|
|
27
32
|
# unsigned LLVMGetEnumAttributeKindForName
|
|
28
33
|
# (const char *Name, size_t SLen);
|
|
29
34
|
attach_function :get_enum_attribute_kind_for_name, :LLVMGetEnumAttributeKindForName, [:pointer, :size_t], :uint
|
|
30
35
|
|
|
36
|
+
attach_function :get_last_enum_attribute_kind, :LLVMGetLastEnumAttributeKind, [], :uint
|
|
37
|
+
|
|
31
38
|
# unsigned LLVMGetAttributeCountAtIndex
|
|
32
39
|
# (LLVMValueRef F, LLVMAttributeIndex Idx);
|
|
33
40
|
attach_function :get_attribute_count_at_index, :LLVMGetAttributeCountAtIndex, [:pointer, :llvmattributeindex], :uint
|
|
@@ -42,15 +49,19 @@ module LLVM
|
|
|
42
49
|
|
|
43
50
|
# uint64_t LLVMGetEnumAttributeValue
|
|
44
51
|
# (LLVMAttributeRef A);
|
|
45
|
-
attach_function :get_enum_attribute_value, :
|
|
52
|
+
attach_function :get_enum_attribute_value, :LLVMGetEnumAttributeValue, [:pointer], :uint64
|
|
46
53
|
|
|
47
54
|
# const char *LLVMGetStringAttributeKind
|
|
48
55
|
# (LLVMAttributeRef A, unsigned *Length);
|
|
49
|
-
attach_function :get_string_attribute_kind, :LLVMGetStringAttributeKind, [:pointer, :pointer], :
|
|
56
|
+
attach_function :get_string_attribute_kind, :LLVMGetStringAttributeKind, [:pointer, :pointer], :string
|
|
50
57
|
|
|
51
58
|
# const char *LLVMGetStringAttributeValue
|
|
52
59
|
# (LLVMAttributeRef A, unsigned *Length);
|
|
53
|
-
attach_function :get_string_attribute_value, :LLVMGetStringAttributeValue, [:pointer, :pointer], :
|
|
60
|
+
attach_function :get_string_attribute_value, :LLVMGetStringAttributeValue, [:pointer, :pointer], :string
|
|
61
|
+
|
|
62
|
+
attach_function :is_enum_attribute, :LLVMIsEnumAttribute, [:pointer], :bool
|
|
63
|
+
attach_function :is_string_attribute, :LLVMIsStringAttribute, [:pointer], :bool
|
|
64
|
+
attach_function :is_type_attribute, :LLVMIsTypeAttribute, [:pointer], :bool
|
|
54
65
|
|
|
55
66
|
# LLVMValueRef LLVMBuildLoad2(LLVMBuilderRef, LLVMTypeRef Ty, LLVMValueRef PointerVal, const char *Name);
|
|
56
67
|
attach_function :build_load2, :LLVMBuildLoad2, [:pointer, :pointer, :pointer, :string], :pointer
|
|
@@ -134,6 +145,56 @@ module LLVM
|
|
|
134
145
|
# @return [Bool]
|
|
135
146
|
# @scope class
|
|
136
147
|
attach_function :is_literal_struct, :LLVMIsLiteralStruct, [:pointer], :bool
|
|
148
|
+
|
|
149
|
+
# /**
|
|
150
|
+
# * Read LLVM IR from a memory buffer and convert it into an in-memory Module
|
|
151
|
+
# * object. Returns 0 on success.
|
|
152
|
+
# * Optionally returns a human-readable description of any errors that
|
|
153
|
+
# * occurred during parsing IR. OutMessage must be disposed with
|
|
154
|
+
# * LLVMDisposeMessage.
|
|
155
|
+
# *
|
|
156
|
+
# * @see llvm::ParseIR()
|
|
157
|
+
# */
|
|
158
|
+
# LLVMBool LLVMParseIRInContext(LLVMContextRef ContextRef,
|
|
159
|
+
# LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
|
|
160
|
+
# char **OutMessage);
|
|
161
|
+
attach_function :parse_ir_in_context, :LLVMParseIRInContext, [:pointer, :pointer, :pointer, :pointer], :bool
|
|
162
|
+
|
|
163
|
+
enum :value_kind, [
|
|
164
|
+
:argument, 0,
|
|
165
|
+
:basic_block, 1,
|
|
166
|
+
:memory_use, 2,
|
|
167
|
+
:memory_def, 3,
|
|
168
|
+
:memory_phi, 4,
|
|
169
|
+
:function, 5,
|
|
170
|
+
:global_alias, 6,
|
|
171
|
+
:global_ifunc, 7,
|
|
172
|
+
:global_variable, 8,
|
|
173
|
+
:block_address, 9,
|
|
174
|
+
:const_expr, 10,
|
|
175
|
+
:const_array, 11,
|
|
176
|
+
:const_struct, 12,
|
|
177
|
+
:const_vector, 13,
|
|
178
|
+
:undef, 14,
|
|
179
|
+
:const_aggregregate_zero, 15,
|
|
180
|
+
:const_data_array, 16,
|
|
181
|
+
:const_data_vector, 17,
|
|
182
|
+
:const_int, 18,
|
|
183
|
+
:const_fp, 19,
|
|
184
|
+
:const_null, 20,
|
|
185
|
+
:const_none, 21,
|
|
186
|
+
:metadata, 22,
|
|
187
|
+
:inline_asm, 23,
|
|
188
|
+
:instruction, 24,
|
|
189
|
+
:poison, 25,
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
# /**
|
|
193
|
+
# * Obtain the enumerated type of a Value instance.
|
|
194
|
+
# *
|
|
195
|
+
# * @see llvm::Value::getValueID()
|
|
196
|
+
# */
|
|
197
|
+
attach_function :get_value_kind, :LLVMGetValueKind, [:pointer], :value_kind
|
|
137
198
|
end
|
|
138
199
|
|
|
139
200
|
# Yields a pointer suitable for storing an LLVM output message.
|
|
@@ -179,4 +240,5 @@ module LLVM
|
|
|
179
240
|
require 'llvm/core/builder'
|
|
180
241
|
require 'llvm/core/pass_manager'
|
|
181
242
|
require 'llvm/core/bitcode'
|
|
243
|
+
require 'llvm/core/attribute'
|
|
182
244
|
end
|
data/lib/llvm/core_ffi.rb
CHANGED
data/lib/llvm/linker_ffi.rb
CHANGED
data/lib/llvm/support.rb
CHANGED
|
@@ -27,6 +27,8 @@ module LLVM
|
|
|
27
27
|
:LLVMInitializeNativeTarget, [], :void
|
|
28
28
|
attach_function :initialize_native_asm_printer,
|
|
29
29
|
:LLVMInitializeNativeAsmPrinter, [], :void
|
|
30
|
+
|
|
31
|
+
attach_function :get_enum_attribute_name_for_kind, :LLVMGetEnumAttributeNameForKind, [:uint], :string
|
|
30
32
|
end
|
|
31
33
|
end
|
|
32
34
|
|
data/lib/llvm/target.rb
CHANGED
|
@@ -22,8 +22,21 @@ module LLVM
|
|
|
22
22
|
#
|
|
23
23
|
# @param [String] target Target name in LLVM format, e.g. "X86", "ARM" or "PowerPC".
|
|
24
24
|
# @param [true, false] asm_printer Initialize corresponding AsmPrinter.
|
|
25
|
+
|
|
26
|
+
module TargetModule
|
|
27
|
+
extend FFI::Library
|
|
28
|
+
ffi_lib ["libLLVM-16.so.1", "libLLVM.so.16", "LLVM-16"]
|
|
29
|
+
|
|
30
|
+
def self.safe_attach_function(*args)
|
|
31
|
+
attach_function(*args)
|
|
32
|
+
rescue FFI::NotFoundError => e
|
|
33
|
+
warn(e)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
25
37
|
def self.init(target, asm_printer = false)
|
|
26
|
-
|
|
38
|
+
target_module = TargetModule.dup
|
|
39
|
+
target_module.module_eval do
|
|
27
40
|
attach_function :"initialize_target_info_#{target}",
|
|
28
41
|
:"LLVMInitialize#{target}TargetInfo", [], :void
|
|
29
42
|
attach_function :"initialize_target_#{target}",
|
|
@@ -33,12 +46,14 @@ module LLVM
|
|
|
33
46
|
|
|
34
47
|
attach_function :"initialize_#{target}_asm_printer",
|
|
35
48
|
:"LLVMInitialize#{target}AsmPrinter", [], :void
|
|
36
|
-
|
|
49
|
+
safe_attach_function :"initialize_#{target}_asm_parser",
|
|
37
50
|
:"LLVMInitialize#{target}AsmParser", [], :void
|
|
38
|
-
|
|
51
|
+
safe_attach_function :"initialize_#{target}_disassembler",
|
|
39
52
|
:"LLVMInitialize#{target}Disassembler", [], :void
|
|
40
53
|
end
|
|
41
54
|
|
|
55
|
+
C.extend(target_module)
|
|
56
|
+
|
|
42
57
|
begin
|
|
43
58
|
%W(initialize_target_info_#{target}
|
|
44
59
|
initialize_target_#{target}
|
data/lib/llvm/target_ffi.rb
CHANGED
data/lib/llvm/transforms/ipo.rb
CHANGED
data/lib/llvm/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-llvm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 16.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jesse Johnson
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2023-
|
|
12
|
+
date: 2023-06-01 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: ffi
|
|
@@ -192,6 +192,7 @@ files:
|
|
|
192
192
|
- lib/llvm/analysis_ffi.rb
|
|
193
193
|
- lib/llvm/config.rb
|
|
194
194
|
- lib/llvm/core.rb
|
|
195
|
+
- lib/llvm/core/attribute.rb
|
|
195
196
|
- lib/llvm/core/bitcode.rb
|
|
196
197
|
- lib/llvm/core/bitcode_ffi.rb
|
|
197
198
|
- lib/llvm/core/builder.rb
|