ruby-llvm 18.1.8 → 18.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,13 +20,13 @@ module LLVM
20
20
  when :instruction
21
21
  Instruction.from_ptr(ptr)
22
22
  when :const_int
23
- Int.from_ptr(ptr)
23
+ ConstantInt.from_ptr(ptr)
24
24
  when :const_fp
25
- Float.from_ptr(ptr)
25
+ ConstantReal.from_ptr(ptr)
26
26
  when :poison
27
27
  Poison.from_ptr(ptr)
28
28
  when :global_variable
29
- GlobalValue.from_ptr(ptr)
29
+ GlobalVariable.from_ptr(ptr)
30
30
  else
31
31
  raise "from_ptr_kind cannot handle: #{kind}"
32
32
  end
@@ -51,8 +51,35 @@ module LLVM
51
51
  C.get_value_kind(self)
52
52
  end
53
53
 
54
+ def allocated_type?
55
+ case self
56
+ when Instruction
57
+ true
58
+ else
59
+ false
60
+ end
61
+ end
62
+
63
+ # allocated type of alloca
64
+ # also works on geps of allocas
54
65
  def allocated_type
55
- Type.from_ptr(C.get_allocated_type(self), nil)
66
+ return if !allocated_type?
67
+
68
+ alloc_type = C.get_allocated_type(self)
69
+ return nil if alloc_type.nil?
70
+
71
+ Type.from_ptr(alloc_type, nil)
72
+ end
73
+
74
+ def gep_source_element_type?
75
+ is_a?(Instruction)
76
+ end
77
+
78
+ # element type of gep
79
+ def gep_source_element_type
80
+ return if !gep_source_element_type?
81
+
82
+ Type.from_ptr(C.get_gep_source_element_type(self))
56
83
  end
57
84
 
58
85
  # Returns the value's name.
@@ -63,12 +90,13 @@ module LLVM
63
90
  # Sets the value's name to str.
64
91
  def name=(str)
65
92
  C.set_value_name(self, str)
66
- str
67
93
  end
68
94
 
69
95
  # Print the value's IR to stdout.
70
96
  def dump
97
+ # :nocov:
71
98
  C.dump_value(self)
99
+ # :nocov:
72
100
  end
73
101
 
74
102
  def to_s
@@ -77,26 +105,22 @@ module LLVM
77
105
 
78
106
  # Returns whether the value is constant.
79
107
  def constant?
80
- case C.is_constant(self)
81
- when 0 then false
82
- when 1 then true
83
- end
108
+ C.is_constant(self)
84
109
  end
85
110
 
86
111
  # Returns whether the value is null.
87
112
  def null?
88
- case C.is_null(self)
89
- when 0 then false
90
- when 1 then true
91
- end
113
+ C.is_null(self)
92
114
  end
93
115
 
94
116
  # Returns whether the value is undefined.
95
- def undefined?
96
- case C.is_undef(self)
97
- when 0 then false
98
- when 1 then true
99
- end
117
+ def undef?
118
+ C.is_undef(self)
119
+ end
120
+ alias_method :undefined?, :undef?
121
+
122
+ def poison?
123
+ C.is_poison(self)
100
124
  end
101
125
 
102
126
  # Adds attr to this value's attributes.
@@ -144,7 +168,6 @@ module LLVM
144
168
  return if index.nil?
145
169
  index + 1
146
170
  end
147
-
148
171
  end
149
172
 
150
173
  class Argument < Value
@@ -213,11 +236,12 @@ module LLVM
213
236
  # Iterates through each Instruction in the collection.
214
237
  def each
215
238
  return to_enum :each unless block_given?
216
- inst, last = first, last
239
+ inst = first
240
+ final = last
217
241
 
218
242
  while inst
219
243
  yield inst
220
- break if inst == last
244
+ break if inst == final
221
245
  inst = inst.next
222
246
  end
223
247
 
@@ -288,6 +312,10 @@ module LLVM
288
312
  from_ptr(C.get_undef(type))
289
313
  end
290
314
 
315
+ def self.poison(type)
316
+ from_ptr(C.get_poison(type))
317
+ end
318
+
291
319
  # Creates a null pointer constant of Type.
292
320
  def self.null_ptr(type)
293
321
  from_ptr(C.const_pointer_null(type))
@@ -299,7 +327,7 @@ module LLVM
299
327
  end
300
328
 
301
329
  # @deprecated
302
- alias bit_cast bitcast_to
330
+ alias_method :bit_cast, :bitcast_to
303
331
 
304
332
  # Returns the element pointer at the given indices of the constant.
305
333
  # For more information on gep go to: http://llvm.org/docs/GetElementPtr.html
@@ -339,6 +367,10 @@ module LLVM
339
367
  from_ptr(C.const_string(str, str.length, null_terminate ? 0 : 1))
340
368
  end
341
369
 
370
+ def self.string_in_context(context, str, null_terminate = true)
371
+ from_ptr(C.const_string_in_context(context, str, str.length, null_terminate ? 0 : 1))
372
+ end
373
+
342
374
  # ConstantArray.const(type, 3) {|i| ... } or
343
375
  # ConstantArray.const(type, [...])
344
376
  def self.const(type, size_or_values, &block)
@@ -359,38 +391,44 @@ module LLVM
359
391
  end
360
392
 
361
393
  class ConstantInt < Constant
362
- def self.all_ones
363
- from_ptr(C.const_all_ones(type))
364
- end
365
-
366
- # Creates a ConstantInt from an integer.
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
382
- end
383
-
384
- def self.parse(str, radix = 10)
385
- from_ptr(C.const_int_of_string(type, str, radix))
386
- end
394
+ extend Gem::Deprecate
395
+
396
+ # def type
397
+ # super
398
+ # end
399
+ #
400
+ # def self.all_ones
401
+ # from_ptr(C.const_all_ones(type))
402
+ # end
403
+ #
404
+ # # Creates a ConstantInt from an integer.
405
+ # def self.from_i(int, signed = true)
406
+ # width = type.width
407
+ # return type.poison if !fits_width?(int, width, signed)
408
+ #
409
+ # from_ptr(C.const_int(type, int, signed ? 1 : 0))
410
+ # end
411
+ #
412
+ # # does int fit in width
413
+ # # allow 1 for signed i1 (though really it's -1 to 0)
414
+ # def self.fits_width?(int, width, signed)
415
+ # if signed
416
+ # int.bit_length < width || int == 1
417
+ # else
418
+ # int >= 0 && int.bit_length <= width
419
+ # end
420
+ # end
421
+ #
422
+ # def self.parse(str, radix = 10)
423
+ # from_ptr(C.const_int_of_string(type, str, radix))
424
+ # end
387
425
 
388
426
  # Negation.
389
427
  def -@
390
428
  self.class.from_ptr(C.const_neg(self))
391
429
  end
392
430
 
393
- alias neg -@
431
+ alias_method :neg, :-@
394
432
 
395
433
  # "No signed wrap" negation.
396
434
  def nsw_neg
@@ -398,16 +436,20 @@ module LLVM
398
436
  end
399
437
 
400
438
  # "No unsigned wrap" negation.
439
+ # @deprecated
401
440
  def nuw_neg
441
+ # :nocov:
402
442
  self.class.from_ptr(C.const_nuw_neg(self))
443
+ # :nocov:
403
444
  end
445
+ deprecate :nuw_neg, "neg", 2025, 3
404
446
 
405
447
  # Addition.
406
448
  def +(rhs)
407
449
  self.class.from_ptr(C.const_add(self, rhs))
408
450
  end
409
451
 
410
- alias add +
452
+ alias_method :add, :+
411
453
 
412
454
  # "No signed wrap" addition.
413
455
  def nsw_add(rhs)
@@ -424,7 +466,7 @@ module LLVM
424
466
  self.class.from_ptr(C.const_sub(self, rhs))
425
467
  end
426
468
 
427
- alias sub -
469
+ alias_method :sub, :-
428
470
 
429
471
  # "No signed wrap" subtraction.
430
472
  def nsw_sub(rhs)
@@ -441,7 +483,7 @@ module LLVM
441
483
  self.class.from_ptr(C.const_mul(self, rhs))
442
484
  end
443
485
 
444
- alias mul *
486
+ alias_method :mul, :*
445
487
 
446
488
  # "No signed wrap" multiplication.
447
489
  def nsw_mul(rhs)
@@ -455,22 +497,26 @@ module LLVM
455
497
 
456
498
  # Unsigned division.
457
499
  def udiv(rhs)
458
- self.class.from_i(to_ui / rhs.to_ui, false)
500
+ width = [type.width, rhs.type.width].max
501
+ LLVM::Type.integer(width).from_i(to_ui / rhs.to_ui, false)
459
502
  end
460
503
 
461
504
  # Signed division.
462
505
  def /(rhs)
463
- self.class.from_i(to_si / rhs.to_si, true)
506
+ width = [type.width, rhs.type.width].max
507
+ LLVM::Type.integer(width).from_i(to_si / rhs.to_si, true)
464
508
  end
465
509
 
466
510
  # Unsigned remainder.
467
511
  def urem(rhs)
468
- self.class.from_i(to_ui % rhs.to_ui, false)
512
+ width = [type.width, rhs.type.width].max
513
+ LLVM::Type.integer(width).from_i(to_ui % rhs.to_ui, false)
469
514
  end
470
515
 
471
516
  # Signed remainder.
472
517
  def rem(rhs)
473
- self.class.from_i(to_si % rhs.to_si, true)
518
+ width = [type.width, rhs.type.width].max
519
+ LLVM::Type.integer(width).from_i(to_si % rhs.to_si, true)
474
520
  end
475
521
 
476
522
  # Boolean negation.
@@ -478,47 +524,53 @@ module LLVM
478
524
  self.class.from_ptr(C.const_not(self))
479
525
  end
480
526
 
481
- alias not ~
527
+ alias_method :not, :~
482
528
 
483
529
  # Integer AND.
484
530
  # was: self.class.from_ptr(C.const_and(self, rhs))
485
531
  def &(rhs)
486
- self.class.from_i(to_i & rhs.to_i)
532
+ width = [type.width, rhs.type.width].max
533
+ LLVM::Type.integer(width).from_i(to_i & rhs.to_i)
487
534
  end
488
535
 
489
- alias and &
536
+ alias_method :and, :&
490
537
 
491
538
  # Integer OR.
492
539
  def |(rhs)
493
- self.class.from_i(to_i | rhs.to_i)
540
+ width = [type.width, rhs.type.width].max
541
+ LLVM::Type.integer(width).from_i(to_i | rhs.to_i)
494
542
  end
495
543
 
496
- alias or |
544
+ alias_method :or, :|
497
545
 
498
546
  # Integer XOR.
499
547
  def ^(rhs)
500
548
  self.class.from_ptr(C.const_xor(self, rhs))
501
549
  end
502
550
 
503
- alias xor ^
551
+ alias_method :xor, :^
504
552
 
505
553
  # Shift left.
506
554
  def <<(bits)
507
- self.class.from_ptr(C.const_shl(self, bits))
555
+ width = [type.width, bits.type.width].max
556
+ LLVM::Type.integer(width).from_i(to_i << bits.to_i)
508
557
  end
509
558
 
510
- alias shl <<
559
+ alias_method :shl, :<<
511
560
 
512
561
  # Shift right.
513
- def >>(bits)
514
- self.class.from_ptr(C.const_l_shr(self, bits))
562
+ def lshr(bits)
563
+ width = [type.width, bits.type.width].max
564
+ LLVM::Type.integer(width).from_i(to_ui >> bits.to_i)
515
565
  end
516
566
 
517
- alias shr >>
567
+ alias_method :shr, :lshr
568
+ alias_method :>>, :lshr
518
569
 
519
570
  # Arithmatic shift right.
520
571
  def ashr(bits)
521
- self.class.from_ptr(C.const_a_shr(self, bits))
572
+ width = [type.width, bits.type.width].max
573
+ LLVM::Type.integer(width).from_i(to_i >> bits.to_i)
522
574
  end
523
575
 
524
576
  # Integer comparison using the predicate specified via the first parameter.
@@ -533,12 +585,12 @@ module LLVM
533
585
  # :sge - signed greater than or equal to
534
586
  # :slt - signed less than
535
587
  # :sle - signed less than or equal to
536
- def icmp(pred, rhs)
537
- self.class.from_ptr(C.const_i_cmp(pred, self, rhs))
588
+ def icmp(_pred, _rhs)
589
+ raise DeprecationError
538
590
  end
539
591
 
540
592
  # Conversion to pointer.
541
- def int_to_ptr(type)
593
+ def int_to_ptr(type = LLVM.Pointer)
542
594
  ConstantExpr.from_ptr(C.const_int_to_ptr(self, type))
543
595
  end
544
596
 
@@ -584,19 +636,14 @@ module LLVM
584
636
  end
585
637
  end
586
638
 
639
+ # creates LLVM::Int1, LLVM::Int64, etc
587
640
  def self.const_missing(const)
588
641
  case const.to_s
589
642
  when /Int(\d+)/
590
643
  width = Regexp.last_match(1).to_i
591
- name = "Int#{width}"
592
- eval <<-KLASS
593
- class #{name} < ConstantInt
594
- def self.type
595
- Type.from_ptr(C.int_type(#{width}), :integer)
596
- end
597
- end
598
- KLASS
599
- const_get(name)
644
+ name = "Int#{width}"
645
+ value = LLVM::Type.integer(width).freeze
646
+ const_set(name, value)
600
647
  else
601
648
  super
602
649
  end
@@ -623,42 +670,39 @@ module LLVM
623
670
  ::LLVM::FALSE = ::LLVM::Int1.from_i(0)
624
671
 
625
672
  class ConstantReal < Constant
626
- # Creates a ConstantReal from a float of Type.
627
- def self.from_f(n)
628
- from_ptr(C.const_real(type, n))
629
- end
630
-
631
- def self.parse(type, str)
632
- from_ptr(C.const_real_of_string(type, str))
633
- end
634
-
635
673
  # Negation.
674
+ # fneg
636
675
  def -@
637
- self.class.from_f(-to_f)
676
+ type.from_f(-to_f)
638
677
  end
639
678
 
640
679
  # Returns the result of adding this ConstantReal to rhs.
641
680
  def +(rhs)
642
- self.class.from_f(to_f + rhs.to_f)
681
+ type = LLVM::RealType.fits([self.type, rhs.type])
682
+ type.from_f(to_f + rhs.to_f)
643
683
  end
644
684
 
645
685
  def -(rhs)
646
- self.class.from_f(to_f - rhs.to_f)
686
+ type = LLVM::RealType.fits([self.type, rhs.type])
687
+ type.from_f(to_f - rhs.to_f)
647
688
  end
648
689
 
649
690
  # Returns the result of multiplying this ConstantReal by rhs.
650
691
  def *(rhs)
651
- self.class.from_f(to_f * rhs.to_f)
692
+ type = LLVM::RealType.fits([self.type, rhs.type])
693
+ type.from_f(to_f * rhs.to_f)
652
694
  end
653
695
 
654
696
  # Returns the result of dividing this ConstantReal by rhs.
655
697
  def /(rhs)
656
- self.class.from_f(to_f / rhs.to_f) # rubocop:disable Style/FloatDivision
698
+ type = LLVM::RealType.fits([self.type, rhs.type])
699
+ type.from_f(to_f / rhs.to_f) # rubocop:disable Style/FloatDivision
657
700
  end
658
701
 
659
702
  # Remainder.
660
703
  def rem(rhs)
661
- self.class.from_f(to_f.divmod(rhs.to_f).last)
704
+ type = LLVM::RealType.fits([self.type, rhs.type])
705
+ type.from_f(to_f.divmod(rhs.to_f).last)
662
706
  end
663
707
 
664
708
  # Floating point comparison using the predicate specified via the first
@@ -679,8 +723,8 @@ module LLVM
679
723
  # :sle - unordered and less than or equal to
680
724
  # :true - always true
681
725
  # :false- always false
682
- def fcmp(pred, rhs)
683
- self.class.from_ptr(C.llmv_const_f_cmp(pred, self, rhs))
726
+ def fcmp(_pred, _rhs)
727
+ raise DeprecationError
684
728
  end
685
729
 
686
730
  # constant FPToSI
@@ -711,29 +755,6 @@ module LLVM
711
755
  end
712
756
  double
713
757
  end
714
-
715
- end
716
-
717
- class Float < ConstantReal
718
- # Return a Type representation of the float.
719
- def self.type
720
- Type.from_ptr(C.float_type, :float)
721
- end
722
- end
723
-
724
- # Create a LLVM::Float from a Ruby Float (val).
725
- def self.Float(val)
726
- Float.from_f(val)
727
- end
728
-
729
- class Double < ConstantReal
730
- def self.type
731
- Type.from_ptr(C.double_type, :double)
732
- end
733
- end
734
-
735
- def self.Double(val)
736
- Double.from_f(val)
737
758
  end
738
759
 
739
760
  class ConstantStruct < Constant
@@ -761,6 +782,11 @@ module LLVM
761
782
 
762
783
  def self.const(size_or_values, &block)
763
784
  vals = LLVM::Support.allocate_pointers(size_or_values, &block)
785
+
786
+ # size 0, or empty values
787
+ # this will segfault in const_vector
788
+ raise ArgumentError if vals.size.zero? # rubocop:disable Style/ZeroLengthPredicate
789
+
764
790
  from_ptr(C.const_vector(vals, vals.size / vals.type_size))
765
791
  end
766
792
 
@@ -810,27 +836,6 @@ module LLVM
810
836
  C.set_alignment(self, bytes)
811
837
  end
812
838
 
813
- def initializer
814
- Value.from_ptr(C.get_initializer(self))
815
- end
816
-
817
- def initializer=(val)
818
- C.set_initializer(self, val)
819
- end
820
-
821
- def global_constant?
822
- C.is_global_constant(self) != 0
823
- end
824
-
825
- def global_constant=(flag)
826
- if flag.kind_of?(Integer)
827
- warn 'Warning: Passing Integer value to LLVM::GlobalValue#global_constant=(Boolean) is deprecated.'
828
- flag = !flag.zero?
829
- end
830
-
831
- C.set_global_constant(self, flag ? 1 : 0)
832
- end
833
-
834
839
  def unnamed_addr?
835
840
  C.has_unnamed_addr(self) != 0
836
841
  end
@@ -852,7 +857,6 @@ module LLVM
852
857
  # Sets the function's calling convention and returns it.
853
858
  def call_conv=(conv)
854
859
  C.set_function_call_conv(self, conv)
855
- conv
856
860
  end
857
861
 
858
862
  # gets the calling convention of the function
@@ -873,7 +877,6 @@ module LLVM
873
877
  # @return self
874
878
  def personality_function=(personality_function)
875
879
  C.set_personality_fn(self, personality_function)
876
- self
877
880
  end
878
881
 
879
882
  # Returns an Enumerable of the BasicBlocks in this function.
@@ -937,7 +940,6 @@ module LLVM
937
940
  end
938
941
 
939
942
  class AttributeCollection
940
-
941
943
  def initialize(fun, index)
942
944
  @fun = fun
943
945
  @index = index
@@ -1017,7 +1019,6 @@ module LLVM
1017
1019
  LLVM::Attribute.memory(inaccessiblemem: :readwrite)
1018
1020
  end
1019
1021
  end
1020
-
1021
1022
  end
1022
1023
 
1023
1024
  # @private
@@ -1133,23 +1134,42 @@ module LLVM
1133
1134
  end
1134
1135
 
1135
1136
  def initializer=(val)
1137
+ raise ArgumentError unless val.is_a? Constant
1138
+
1136
1139
  C.set_initializer(self, val)
1137
1140
  end
1138
1141
 
1139
1142
  def thread_local?
1140
- case C.is_thread_local(self)
1141
- when 0 then false
1142
- else true
1143
- end
1143
+ C.is_thread_local(self)
1144
1144
  end
1145
1145
 
1146
1146
  def thread_local=(local)
1147
1147
  C.set_thread_local(self, local ? 1 : 0)
1148
1148
  end
1149
+
1150
+ def global_constant?
1151
+ C.is_global_constant(self)
1152
+ end
1153
+
1154
+ def global_constant=(flag)
1155
+ if flag.kind_of?(Integer)
1156
+ warn 'Warning: Passing Integer value to LLVM::GlobalValue#global_constant=(Boolean) is deprecated.'
1157
+ flag = !flag.zero?
1158
+ end
1159
+
1160
+ C.set_global_constant(self, flag ? 1 : 0)
1161
+ end
1162
+
1163
+ def externally_initialized?
1164
+ C.is_externally_initialized(self)
1165
+ end
1166
+
1167
+ def externally_initialized=(boolean)
1168
+ C.set_externally_initialized(self, boolean)
1169
+ end
1149
1170
  end
1150
1171
 
1151
1172
  class Instruction < User
1152
-
1153
1173
  def self.from_ptr(ptr)
1154
1174
  kind = C.get_value_kind(ptr)
1155
1175
  kind == :instruction ? super : LLVM::Value.from_ptr_kind(ptr)
@@ -1180,17 +1200,45 @@ module LLVM
1180
1200
  def inspect
1181
1201
  { self.class.name => { opcode: opcode, ptr: @ptr } }.to_s
1182
1202
  end
1203
+
1204
+ def nsw!
1205
+ C.set_nsw(self, true)
1206
+ self
1207
+ end
1208
+
1209
+ def clear_nsw!
1210
+ C.set_nsw(self, false)
1211
+ self
1212
+ end
1213
+
1214
+ def nuw!
1215
+ C.set_nuw(self, true)
1216
+ self
1217
+ end
1218
+
1219
+ def clear_nuw!
1220
+ C.set_nuw(self, false)
1221
+ self
1222
+ end
1223
+
1224
+ def exact!
1225
+ C.set_exact(self, true)
1226
+ self
1227
+ end
1228
+
1229
+ def clear_exact!
1230
+ C.set_exact(self, false)
1231
+ self
1232
+ end
1183
1233
  end
1184
1234
 
1185
1235
  class Poison < Value
1186
-
1187
1236
  end
1188
1237
 
1189
1238
  class CallInst < Instruction
1190
1239
  # Sets the call convention to conv.
1191
1240
  def call_conv=(conv)
1192
1241
  C.set_instruction_call_conv(self, conv)
1193
- conv
1194
1242
  end
1195
1243
 
1196
1244
  # Returns the call insatnce's call convention.
@@ -1233,7 +1281,6 @@ module LLVM
1233
1281
  end
1234
1282
  end
1235
1283
 
1236
-
1237
1284
  # @private
1238
1285
  class IndirectBr < Instruction
1239
1286
  # Adds a basic block reference as a destination for this indirect branch.
@@ -1241,6 +1288,6 @@ module LLVM
1241
1288
  C.add_destination(self, dest)
1242
1289
  end
1243
1290
 
1244
- alias :<< :add_dest
1291
+ alias_method :<<, :add_dest
1245
1292
  end
1246
1293
  end