ruby-llvm 16.0.1 → 18.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6e1b8f07e635723694d6a987397f074c5433bcfad6867cb1832e71333c7a13e
4
- data.tar.gz: 730e751e566373dc30950c08b12eafa665403ac635ffa6d33bb5324b56cd906d
3
+ metadata.gz: 67a728c4318fe7c347dfc1d85e626c0c93c29011f329638585b8eac584cf0aff
4
+ data.tar.gz: 62e72a80da04ec235acc44fd6ef7027d3903e1b47ef59edc7e36e63b92a69296
5
5
  SHA512:
6
- metadata.gz: c1bbf9522c2c6a9782d46760138ff35ad5ed41b571bdd93425b3bc4d0d89992ec04cf904ec59fda21793a9edfa14ecb749128ccb4d03fa2a4b0801c5a22a61f9
7
- data.tar.gz: 917666ebfceda78a79299df2849bf653dfdd2d723615ba6e105bf56f54ab95f3580158903a8b9b4702ffd32e0764b79d246bd1aecac35faac12eabd049f2d54d
6
+ metadata.gz: 504c7b62dac6dbd58b072f53fc2a817b33ef6ac43a9234687c7f60ab62d29a1c9f4682cda8e0432aa96809989858c6028e5addb916997244283f249244e8b31c
7
+ data.tar.gz: 03a43636eeea68eb6a279a8f91d794704b8a572bb64b34baed9718778942863e461ae11d44107859264ffd6ede8d593217d3dab2eb8ebafb1bee4e9711122294
data/README.md CHANGED
@@ -14,7 +14,7 @@ computationally intensive algorithms on the fly.
14
14
  Current version
15
15
  ---------------
16
16
 
17
- This library currently binds to LLVM-15 (specifically llvm-c 15).
17
+ This library currently binds to LLVM-17 (specifically llvm-c 17).
18
18
 
19
19
  About version numbers
20
20
  ---------------------
@@ -30,10 +30,20 @@ extern "C" {
30
30
  llvm::InitializeNativeTargetAsmPrinter();
31
31
  }
32
32
 
33
+ // static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
34
+ // https://llvm.org/doxygen/classllvm_1_1Attribute.html
33
35
  const char* LLVMGetEnumAttributeNameForKind(const unsigned KindID) {
34
36
  const auto AttrKind = (llvm::Attribute::AttrKind) KindID;
35
37
  const auto S = llvm::Attribute::getNameFromAttrKind(AttrKind);
36
38
  return S.data();
37
39
  }
40
+
41
+ // std::string Attribute::getAsString(bool InAttrGrp = false) const
42
+ // https://llvm.org/doxygen/classllvm_1_1Attribute.html
43
+ // string must be disposed with LLVMDisposeMessage
44
+ const char* LLVMGetAttributeAsString(LLVMAttributeRef A) {
45
+ auto S = llvm::unwrap(A).getAsString();
46
+ return strdup(S.c_str());
47
+ }
38
48
  }
39
49
 
@@ -4,7 +4,7 @@ require 'ffi'
4
4
 
5
5
  module LLVM::C
6
6
  extend FFI::Library
7
- ffi_lib ["libLLVM-16.so.1", "libLLVM.so.16", "LLVM-16"]
7
+ ffi_lib ["libLLVM-18.so.1", "libLLVM.so.18", "LLVM-18"]
8
8
 
9
9
  def self.attach_function(name, *_)
10
10
  begin; super; rescue FFI::NotFoundError => e
data/lib/llvm/config.rb CHANGED
@@ -1,13 +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
- VERSION = "17.0.6"
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", "codegentypes", "core", "coroutines", "coverage", "debuginfobtf", "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", "xtensa", "xtensaasmparser", "xtensacodegen", "xtensadesc", "xtensadisassembler", "xtensainfo"]
4
+ VERSION = "18.1.0"
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", "codegentypes", "core", "coroutines", "coverage", "debuginfobtf", "debuginfocodeview", "debuginfodwarf", "debuginfogsym", "debuginfologicalview", "debuginfomsf", "debuginfopdb", "demangle", "dlltooldriver", "dwarflinker", "dwarflinkerclassic", "dwarflinkerparallel", "dwp", "engine", "executionengine", "extensions", "filecheck", "frontenddriver", "frontendhlsl", "frontendoffloading", "frontendopenacc", "frontendopenmp", "fuzzercli", "fuzzmutate", "globalisel", "hexagon", "hexagonasmparser", "hexagoncodegen", "hexagondesc", "hexagondisassembler", "hexagoninfo", "hipstdpar", "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", "orcdebugging", "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", "textapibinaryreader", "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", "xtensa", "xtensaasmparser", "xtensacodegen", "xtensadesc", "xtensadisassembler", "xtensainfo"]
6
6
  TARGETS_BUILT = ["AArch64", "AMDGPU", "ARM", "AVR", "BPF", "Hexagon", "Lanai", "LoongArch", "Mips", "MSP430", "NVPTX", "PowerPC", "RISCV", "Sparc", "SystemZ", "VE", "WebAssembly", "X86", "XCore", "M68k", "Xtensa"]
7
7
  HOST_TARGET = "x86_64-pc-linux-gnu"
8
8
  BUILD_MODE = "RelWithDebInfo"
9
- CFLAGS = "-I/usr/lib/llvm-17/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
10
- CXXFLAGS = "-I/usr/lib/llvm-17/include -std=c++17 -fno-exceptions -funwind-tables -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
11
- LDFLAGS = "-L/usr/lib/llvm-17/lib"
9
+ CFLAGS = "-I/usr/lib/llvm-18/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
10
+ CXXFLAGS = "-I/usr/lib/llvm-18/include -std=c++17 -fno-exceptions -funwind-tables -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
11
+ LDFLAGS = "-L/usr/lib/llvm-18/lib"
12
12
  end
13
13
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LLVM
4
+ # wrapper for LLVMAttributeRef
4
5
  class Attribute
5
6
 
6
7
  include PointerIdentity
@@ -98,7 +99,7 @@ module LLVM
98
99
  end
99
100
 
100
101
  def value
101
- return C.get_enum_attribute_value(self) if enum?
102
+ return enum_value if enum?
102
103
  return string_value if string?
103
104
  raise
104
105
  end
@@ -116,22 +117,52 @@ module LLVM
116
117
  end
117
118
 
118
119
  def inspect
119
- return "\"#{kind}\" = \"#{value}\"" if string?
120
- return "#{kind}(#{value})" if enum?
121
- super
120
+ to_s
122
121
  end
123
122
 
124
123
  def to_s
125
- return kind if enum?
126
- super
124
+ Support::C.get_attribute_as_string(self)
127
125
  end
128
126
 
129
127
  def kind_id
130
128
  enum_kind_id
131
129
  end
132
130
 
131
+ def ==(other)
132
+ super if self.class == other.class
133
+
134
+ # strings and symbols
135
+ return true if to_s == other.to_s
136
+
137
+ false
138
+ end
139
+
140
+ def readnone?
141
+ enum_kind == 'readnone' || (enum_kind == 'memory' && enum_value_mem_none?)
142
+ end
143
+
144
+ def readonly?
145
+ enum_kind == 'readonly' || (enum_kind == 'memory' && enum_value_mem_read?)
146
+ end
147
+
148
+ def writeonly?
149
+ enum_kind == 'writeonly' || (enum_kind == 'memory' && enum_value_mem_write?)
150
+ end
151
+
133
152
  private
134
153
 
154
+ def enum_value_mem_none?
155
+ (enum_value & 63).zero?
156
+ end
157
+
158
+ def enum_value_mem_read?
159
+ (enum_value & 21) != 0
160
+ end
161
+
162
+ def enum_value_mem_write?
163
+ (enum_value & 42) != 0
164
+ end
165
+
135
166
  def enum_kind_id
136
167
  C.get_enum_attribute_kind(self)
137
168
  end
@@ -140,6 +171,10 @@ module LLVM
140
171
  Support::C.get_enum_attribute_name_for_kind(enum_kind_id)
141
172
  end
142
173
 
174
+ def enum_value
175
+ C.get_enum_attribute_value(self)
176
+ end
177
+
143
178
  # wraps get_string_attribute_kind
144
179
  def string_kind
145
180
  FFI::MemoryPointer.new(:uint64) do |size_ptr|
@@ -4,7 +4,7 @@ require 'ffi'
4
4
 
5
5
  module LLVM::C
6
6
  extend FFI::Library
7
- ffi_lib ["libLLVM-16.so.1", "libLLVM.so.16", "LLVM-16"]
7
+ ffi_lib ["libLLVM-18.so.1", "libLLVM.so.18", "LLVM-18"]
8
8
 
9
9
  def self.attach_function(name, *_)
10
10
  begin; super; rescue FFI::NotFoundError => e
@@ -189,7 +189,7 @@ module LLVM
189
189
  # Builds an unwind Instruction.
190
190
  # @LLVMinst unwind
191
191
  def unwind
192
- Instruction.from_ptr(C.build_unwind(self))
192
+ raise DeprecationError
193
193
  end
194
194
 
195
195
  # Generates an instruction with no defined semantics. Can be used to
@@ -939,18 +939,18 @@ module LLVM
939
939
  end
940
940
 
941
941
  private def call2_infer_function_and_type(type, fun)
942
- fun = insert_block.parent.global_parent.functions[fun.to_s] unless fun.is_a?(LLVM::Value)
942
+ fun2 = fun.is_a?(LLVM::Value) ? fun : insert_block.parent.global_parent.functions[fun.to_s]
943
943
 
944
- msg = "Function provided to call instruction was neither a value nor a function name: #{fun.inspect}"
945
- raise ArgumentError, msg if fun.nil?
944
+ msg = "Function provided to call instruction was neither a value nor a function name:"
945
+ raise ArgumentError, "#{msg} #{fun}" if fun2.nil?
946
946
 
947
- msg = "Type must be provided to call2 when function argument is not a function type: #{fun.inspect}"
948
- raise ArgumentError, msg if !fun.is_a?(Function) && type.nil?
947
+ msg = "Type must be provided to call2 when function argument is not a function type:"
948
+ raise ArgumentError, "#{msg} #{fun}" if !fun2.is_a?(Function) && type.nil?
949
949
 
950
- type ||= fun.function_type
950
+ type ||= fun2.function_type
951
951
  must_be_type!(type)
952
952
 
953
- [type, fun]
953
+ [type, fun2]
954
954
  end
955
955
 
956
956
  def call2(type, fun, *args)
@@ -24,6 +24,10 @@ module LLVM
24
24
  @ptr = nil
25
25
  end
26
26
 
27
+ def clone_module
28
+ Module.from_ptr(C.clone_module(self))
29
+ end
30
+
27
31
  def inspect
28
32
  {
29
33
  triple: triple,
@@ -13,9 +13,8 @@ module LLVM
13
13
  #
14
14
  # @param [LLVM::ExecutionEngine, LLVM::TargetMachine] machine
15
15
  def initialize(machine = nil)
16
- if machine
17
- warn("[DEPRECATION] PassManager.new should be called without parameters")
18
- end
16
+ warn("[DEPRECATION] PassManager.new should be called without parameters") if machine
17
+
19
18
  @ptr = C.create_pass_manager()
20
19
  end
21
20
 
@@ -60,6 +60,10 @@ module LLVM
60
60
  ConstantExpr.from_ptr(C.const_null(self))
61
61
  end
62
62
 
63
+ def poison
64
+ ConstantExpr.from_ptr(C.get_poison(self))
65
+ end
66
+
63
67
  # Creates a pointer type with this type and the given address space.
64
68
  def pointer(address_space = 0)
65
69
  Type.pointer(self, address_space)
@@ -364,8 +364,21 @@ module LLVM
364
364
  end
365
365
 
366
366
  # Creates a ConstantInt from an integer.
367
- def self.from_i(n, signed = true)
368
- from_ptr(C.const_int(type, n, signed ? 1 : 0))
367
+ def self.from_i(int, signed = true)
368
+ width = type.width
369
+ return type.poison if !fits_width?(int, width, signed)
370
+
371
+ from_ptr(C.const_int(type, int, signed ? 1 : 0))
372
+ end
373
+
374
+ # does int fit in width
375
+ # allow 1 for signed i1 (though really it's -1 to 0)
376
+ def self.fits_width?(int, width, signed)
377
+ if signed
378
+ int.bit_length < width || int == 1
379
+ else
380
+ int >= 0 && int.bit_length <= width
381
+ end
369
382
  end
370
383
 
371
384
  def self.parse(str, radix = 10)
@@ -442,22 +455,22 @@ module LLVM
442
455
 
443
456
  # Unsigned division.
444
457
  def udiv(rhs)
445
- raise "constant udiv removed in LLVM 15"
458
+ self.class.from_i(to_ui / rhs.to_ui, false)
446
459
  end
447
460
 
448
461
  # Signed division.
449
462
  def /(rhs)
450
- raise "constant sdiv removed in LLVM 15"
463
+ self.class.from_i(to_si / rhs.to_si, true)
451
464
  end
452
465
 
453
466
  # Unsigned remainder.
454
467
  def urem(rhs)
455
- raise "constant urem removed in LLVM 15"
468
+ self.class.from_i(to_ui % rhs.to_ui, false)
456
469
  end
457
470
 
458
471
  # Signed remainder.
459
472
  def rem(rhs)
460
- raise "constant srem removed in LLVM 15"
473
+ self.class.from_i(to_si % rhs.to_si, true)
461
474
  end
462
475
 
463
476
  # Boolean negation.
@@ -468,15 +481,16 @@ module LLVM
468
481
  alias not ~
469
482
 
470
483
  # Integer AND.
484
+ # was: self.class.from_ptr(C.const_and(self, rhs))
471
485
  def &(rhs)
472
- self.class.from_ptr(C.const_and(self, rhs))
486
+ self.class.from_i(to_i & rhs.to_i)
473
487
  end
474
488
 
475
489
  alias and &
476
490
 
477
491
  # Integer OR.
478
492
  def |(rhs)
479
- self.class.from_ptr(C.const_or(self, rhs))
493
+ self.class.from_i(to_i | rhs.to_i)
480
494
  end
481
495
 
482
496
  alias or |
@@ -528,25 +542,45 @@ module LLVM
528
542
  ConstantExpr.from_ptr(C.const_int_to_ptr(self, type))
529
543
  end
530
544
 
545
+ def to_ui
546
+ to_i(false)
547
+ end
548
+
549
+ def to_si
550
+ to_i(true)
551
+ end
552
+
531
553
  # constant zext
554
+ # was: self.class.from_ptr(C.const_z_ext(self, type))
532
555
  def zext(type)
533
- self.class.from_ptr(C.const_z_ext(self, type))
556
+ type.from_i(to_ui)
534
557
  end
535
558
 
536
559
  # constant sext
560
+ # was: self.class.from_ptr(C.const_s_ext(self, type))
537
561
  def sext(type)
538
- self.class.from_ptr(C.const_s_ext(self, type))
562
+ type.from_i(to_si)
539
563
  end
540
564
  alias_method :ext, :sext
541
565
 
542
566
  # constant trunc
567
+ # was: self.class.from_ptr(C.const_trunc(self, type))
543
568
  def trunc(type)
544
- self.class.from_ptr(C.const_trunc(self, type))
569
+ type.from_i(to_i)
545
570
  end
546
571
 
547
572
  # LLVMValueRef LLVMConstSIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
573
+ # was: self.class.from_ptr(C.const_si_to_fp(self, type))
548
574
  def to_f(type)
549
- self.class.from_ptr(C.const_si_to_fp(self, type))
575
+ type.from_f(to_i.to_f)
576
+ end
577
+
578
+ def to_i(signed = true)
579
+ if signed
580
+ C.const_int_get_sext_value(self)
581
+ else
582
+ C.const_int_get_zext_value(self)
583
+ end
550
584
  end
551
585
  end
552
586
 
@@ -570,7 +604,7 @@ module LLVM
570
604
 
571
605
  # Native integer type
572
606
  bits = FFI.type_size(:int) * 8
573
- ::LLVM::Int = const_get("Int#{bits}")
607
+ ::LLVM::Int = const_get(:"Int#{bits}")
574
608
 
575
609
  # Creates a LLVM Int (subclass of ConstantInt) at the NATIVE_INT_SIZE from a integer (val).
576
610
  def self.Int(val)
@@ -600,27 +634,31 @@ module LLVM
600
634
 
601
635
  # Negation.
602
636
  def -@
603
- raise "constant fneg removed in LLVM 16"
637
+ self.class.from_f(-to_f)
604
638
  end
605
639
 
606
640
  # Returns the result of adding this ConstantReal to rhs.
607
641
  def +(rhs)
608
- raise "constant fadd removed in LLVM 15"
642
+ self.class.from_f(to_f + rhs.to_f)
643
+ end
644
+
645
+ def -(rhs)
646
+ self.class.from_f(to_f - rhs.to_f)
609
647
  end
610
648
 
611
649
  # Returns the result of multiplying this ConstantReal by rhs.
612
650
  def *(rhs)
613
- raise "constant fmul removed in LLVM 15"
651
+ self.class.from_f(to_f * rhs.to_f)
614
652
  end
615
653
 
616
654
  # Returns the result of dividing this ConstantReal by rhs.
617
655
  def /(rhs)
618
- raise "constant fdiv removed in LLVM 15"
656
+ self.class.from_f(to_f / rhs.to_f) # rubocop:disable Style/FloatDivision
619
657
  end
620
658
 
621
659
  # Remainder.
622
660
  def rem(rhs)
623
- raise "constant frem removed in LLVM 15"
661
+ self.class.from_f(to_f.divmod(rhs.to_f).last)
624
662
  end
625
663
 
626
664
  # Floating point comparison using the predicate specified via the first
@@ -647,19 +685,31 @@ module LLVM
647
685
 
648
686
  # constant FPToSI
649
687
  # LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
688
+ # was: self.class.from_ptr(C.const_fp_to_si(self, type))
650
689
  def to_i(type)
651
- self.class.from_ptr(C.const_fp_to_si(self, type))
690
+ type.from_i(to_f.to_i)
652
691
  end
653
692
 
654
693
  # Constant FPExt
655
694
  # this is a signed extension
695
+ # was: self.class.from_ptr(C.const_fp_ext(self, type))
656
696
  def ext(type)
657
- self.class.from_ptr(C.const_fp_ext(self, type))
697
+ type.from_f(to_f)
658
698
  end
659
699
  alias_method :sext, :ext
660
700
 
701
+ # was: self.class.from_ptr(C.const_fp_trunc(self, type))
661
702
  def trunc(type)
662
- self.class.from_ptr(C.const_fp_trunc(self, type))
703
+ type.from_f(to_f)
704
+ end
705
+
706
+ # get double from value
707
+ def to_f
708
+ double = nil
709
+ FFI::MemoryPointer.new(:bool, 1) do |loses_info|
710
+ double = C.const_real_get_double(self, loses_info)
711
+ end
712
+ double
663
713
  end
664
714
 
665
715
  end
@@ -846,6 +896,18 @@ module LLVM
846
896
  function_attributes.to_a
847
897
  end
848
898
 
899
+ def readnone?
900
+ attributes.detect(&:readnone?)
901
+ end
902
+
903
+ def readonly?
904
+ attributes.detect(&:readonly?)
905
+ end
906
+
907
+ def writeonly?
908
+ attributes.detect(&:writeonly?)
909
+ end
910
+
849
911
  def function_attributes
850
912
  AttributeCollection.new(self, -1)
851
913
  end
@@ -869,12 +931,16 @@ module LLVM
869
931
  attr_ref = case attr
870
932
  when Attribute
871
933
  attr
872
- when Symbol
934
+ when Symbol, String
873
935
  attr_kind_id = attribute_id(attr)
874
- ctx = Context.global
875
- C.create_enum_attribute(ctx, attr_kind_id, 0)
936
+ if attr_kind_id.is_a?(Integer)
937
+ ctx = Context.global
938
+ C.create_enum_attribute(ctx, attr_kind_id, 0)
939
+ else
940
+ attr_kind_id
941
+ end
876
942
  else
877
- raise "Adding unknown attribute type"
943
+ raise "Adding unknown attribute type: #{attr.inspect}"
878
944
  end
879
945
  C.add_attribute_at_index(@fun, @index, attr_ref)
880
946
  end
@@ -911,12 +977,31 @@ module LLVM
911
977
  end
912
978
 
913
979
  def attribute_id(attr_name)
980
+ upgrade = upgrade_attr(attr_name)
981
+ return upgrade if upgrade
982
+
914
983
  attr_mem = FFI::MemoryPointer.from_string(attribute_name(attr_name))
915
984
  attr_kind_id = C.get_enum_attribute_kind_for_name(attr_mem, attr_mem.size - 1)
916
985
 
917
986
  raise "No attribute named: #{attr_name}" if attr_kind_id.zero?
918
987
  attr_kind_id
919
988
  end
989
+
990
+ # Upgrade attributes from before LLVM 16
991
+ # readnone, readonly, writeonly
992
+ def upgrade_attr(attr)
993
+ case attr.to_sym
994
+ when :readnone
995
+ LLVM::Attribute.memory
996
+ when :readonly
997
+ LLVM::Attribute.memory(memory: :read)
998
+ when :writeonly
999
+ LLVM::Attribute.memory(memory: :write)
1000
+ when :inaccessiblememonly
1001
+ LLVM::Attribute.memory(inaccessiblemem: :readwrite)
1002
+ end
1003
+ end
1004
+
920
1005
  end
921
1006
 
922
1007
  # @private
data/lib/llvm/core.rb CHANGED
@@ -195,6 +195,12 @@ module LLVM
195
195
  # * @see llvm::Value::getValueID()
196
196
  # */
197
197
  attach_function :get_value_kind, :LLVMGetValueKind, [:pointer], :value_kind
198
+
199
+ attach_function :get_poison, :LLVMGetPoison, [:pointer], :pointer
200
+
201
+ attach_function :const_int_get_sext_value, :LLVMConstIntGetSExtValue, [:pointer], :long_long
202
+
203
+ attach_function :const_int_get_zext_value, :LLVMConstIntGetZExtValue, [:pointer], :ulong_long
198
204
  end
199
205
 
200
206
  # Yields a pointer suitable for storing an LLVM output message.
@@ -239,6 +245,7 @@ module LLVM
239
245
  require 'llvm/core/value'
240
246
  require 'llvm/core/builder'
241
247
  require 'llvm/core/pass_manager'
248
+ require 'llvm/transforms/pass_builder'
242
249
  require 'llvm/core/bitcode'
243
250
  require 'llvm/core/attribute'
244
251
  end