Jlm
IntegerOperations.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2025 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #ifndef JLM_LLVM_IR_OPERATORS_INTEGEROPERATIONS_HPP
7 #define JLM_LLVM_IR_OPERATORS_INTEGEROPERATIONS_HPP
8 
9 #include <jlm/rvsdg/binary.hpp>
12 #include <jlm/rvsdg/nullary.hpp>
13 
14 namespace jlm::llvm
15 {
16 
17 // FIXME: Implement our own value representation instead of re-using the bitstring value
18 // representation
20 
25 {
26 public:
28 
30  : NullaryOperation(rvsdg::BitType::Create(representation.nbits())),
31  Representation_(std::move(representation))
32  {}
33 
34  std::unique_ptr<Operation>
35  copy() const override;
36 
37  std::string
38  debug_string() const override;
39 
40  bool
41  operator==(const Operation & other) const noexcept override;
42 
43  [[nodiscard]] const IntegerValueRepresentation &
44  Representation() const noexcept
45  {
46  return Representation_;
47  }
48 
49  static rvsdg::Node &
51  {
52  return rvsdg::CreateOpNode<IntegerConstantOperation>(region, std::move(representation));
53  }
54 
55  static rvsdg::Node &
56  Create(rvsdg::Region & region, std::size_t numBits, std::int64_t value)
57  {
58  return Create(region, { numBits, value });
59  }
60 
61 private:
63 };
64 
69 {
70 public:
71  ~IntegerBinaryOperation() noexcept override;
72 
74  const std::size_t numArgumentBits,
75  const std::size_t numResultBits) noexcept
77  { rvsdg::BitType::Create(numArgumentBits), rvsdg::BitType::Create(numArgumentBits) },
78  rvsdg::BitType::Create(numResultBits))
79  {}
80 
81  [[nodiscard]] const rvsdg::BitType &
82  Type() const noexcept
83  {
84  return *util::assertedCast<const rvsdg::BitType>(argument(0).get());
85  }
86 };
87 
94 {
95 public:
96  ~IntegerAddOperation() noexcept override;
97 
98  explicit IntegerAddOperation(const std::size_t numBits)
99  : IntegerBinaryOperation(numBits, numBits)
100  {}
101 
102  bool
103  operator==(const Operation & other) const noexcept override;
104 
105  std::string
106  debug_string() const override;
107 
108  [[nodiscard]] std::unique_ptr<Operation>
109  copy() const override;
110 
112  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
113  const noexcept override;
114 
115  rvsdg::Output *
117  const override;
118 
119  enum flags
120  flags() const noexcept override;
121 };
122 
129 {
130 public:
131  ~IntegerSubOperation() noexcept override;
132 
133  explicit IntegerSubOperation(const std::size_t numBits)
134  : IntegerBinaryOperation(numBits, numBits)
135  {}
136 
137  bool
138  operator==(const Operation & other) const noexcept override;
139 
140  std::string
141  debug_string() const override;
142 
143  [[nodiscard]] std::unique_ptr<Operation>
144  copy() const override;
145 
147  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
148  const noexcept override;
149 
150  rvsdg::Output *
152  const override;
153 
154  enum flags
155  flags() const noexcept override;
156 };
157 
164 {
165 public:
166  ~IntegerMulOperation() noexcept override;
167 
168  explicit IntegerMulOperation(const std::size_t numBits)
169  : IntegerBinaryOperation(numBits, numBits)
170  {}
171 
172  bool
173  operator==(const Operation & other) const noexcept override;
174 
175  std::string
176  debug_string() const override;
177 
178  [[nodiscard]] std::unique_ptr<Operation>
179  copy() const override;
180 
182  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
183  const noexcept override;
184 
185  rvsdg::Output *
187  const override;
188 
189  enum flags
190  flags() const noexcept override;
191 };
192 
199 {
200 public:
201  ~IntegerSDivOperation() noexcept override;
202 
203  explicit IntegerSDivOperation(const std::size_t numBits)
204  : IntegerBinaryOperation(numBits, numBits)
205  {}
206 
207  bool
208  operator==(const Operation & other) const noexcept override;
209 
210  std::string
211  debug_string() const override;
212 
213  [[nodiscard]] std::unique_ptr<Operation>
214  copy() const override;
215 
217  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
218  const noexcept override;
219 
220  rvsdg::Output *
222  const override;
223 
224  enum flags
225  flags() const noexcept override;
226 };
227 
234 {
235 public:
236  ~IntegerUDivOperation() noexcept override;
237 
238  explicit IntegerUDivOperation(const std::size_t numBits)
239  : IntegerBinaryOperation(numBits, numBits)
240  {}
241 
242  bool
243  operator==(const Operation & other) const noexcept override;
244 
245  std::string
246  debug_string() const override;
247 
248  [[nodiscard]] std::unique_ptr<Operation>
249  copy() const override;
250 
252  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
253  const noexcept override;
254 
255  rvsdg::Output *
257  const override;
258 
259  enum flags
260  flags() const noexcept override;
261 };
262 
269 {
270 public:
271  ~IntegerSRemOperation() noexcept override;
272 
273  explicit IntegerSRemOperation(const std::size_t numBits)
274  : IntegerBinaryOperation(numBits, numBits)
275  {}
276 
277  bool
278  operator==(const Operation & other) const noexcept override;
279 
280  std::string
281  debug_string() const override;
282 
283  [[nodiscard]] std::unique_ptr<Operation>
284  copy() const override;
285 
287  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
288  const noexcept override;
289 
290  rvsdg::Output *
292  const override;
293 
294  enum flags
295  flags() const noexcept override;
296 };
297 
304 {
305 public:
306  ~IntegerURemOperation() noexcept override;
307 
308  explicit IntegerURemOperation(const std::size_t numBits)
309  : IntegerBinaryOperation(numBits, numBits)
310  {}
311 
312  bool
313  operator==(const Operation & other) const noexcept override;
314 
315  std::string
316  debug_string() const override;
317 
318  [[nodiscard]] std::unique_ptr<Operation>
319  copy() const override;
320 
322  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
323  const noexcept override;
324 
325  rvsdg::Output *
327  const override;
328 
329  enum flags
330  flags() const noexcept override;
331 };
332 
339 {
340 public:
341  ~IntegerAShrOperation() noexcept override;
342 
343  explicit IntegerAShrOperation(const std::size_t numBits)
344  : IntegerBinaryOperation(numBits, numBits)
345  {}
346 
347  bool
348  operator==(const Operation & other) const noexcept override;
349 
350  std::string
351  debug_string() const override;
352 
353  [[nodiscard]] std::unique_ptr<Operation>
354  copy() const override;
355 
357  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
358  const noexcept override;
359 
360  rvsdg::Output *
362  const override;
363 
364  enum flags
365  flags() const noexcept override;
366 };
367 
374 {
375 public:
376  ~IntegerShlOperation() noexcept override;
377 
378  explicit IntegerShlOperation(const std::size_t numBits)
379  : IntegerBinaryOperation(numBits, numBits)
380  {}
381 
382  bool
383  operator==(const Operation & other) const noexcept override;
384 
385  std::string
386  debug_string() const override;
387 
388  [[nodiscard]] std::unique_ptr<Operation>
389  copy() const override;
390 
392  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
393  const noexcept override;
394 
395  rvsdg::Output *
397  const override;
398 
399  enum flags
400  flags() const noexcept override;
401 };
402 
409 {
410 public:
411  ~IntegerLShrOperation() noexcept override;
412 
413  explicit IntegerLShrOperation(const std::size_t numBits)
414  : IntegerBinaryOperation(numBits, numBits)
415  {}
416 
417  bool
418  operator==(const Operation & other) const noexcept override;
419 
420  std::string
421  debug_string() const override;
422 
423  [[nodiscard]] std::unique_ptr<Operation>
424  copy() const override;
425 
427  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
428  const noexcept override;
429 
430  rvsdg::Output *
432  const override;
433 
434  enum flags
435  flags() const noexcept override;
436 };
437 
444 {
445 public:
446  ~IntegerAndOperation() noexcept override;
447 
448  explicit IntegerAndOperation(const std::size_t numBits)
449  : IntegerBinaryOperation(numBits, numBits)
450  {}
451 
452  bool
453  operator==(const Operation & other) const noexcept override;
454 
455  std::string
456  debug_string() const override;
457 
458  [[nodiscard]] std::unique_ptr<Operation>
459  copy() const override;
460 
462  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
463  const noexcept override;
464 
465  rvsdg::Output *
467  const override;
468 
469  enum flags
470  flags() const noexcept override;
471 };
472 
479 {
480 public:
481  ~IntegerOrOperation() noexcept override;
482 
483  explicit IntegerOrOperation(const std::size_t numBits)
484  : IntegerBinaryOperation(numBits, numBits)
485  {}
486 
487  bool
488  operator==(const Operation & other) const noexcept override;
489 
490  std::string
491  debug_string() const override;
492 
493  [[nodiscard]] std::unique_ptr<Operation>
494  copy() const override;
495 
497  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
498  const noexcept override;
499 
500  rvsdg::Output *
502  const override;
503 
504  enum flags
505  flags() const noexcept override;
506 };
507 
514 {
515 public:
516  ~IntegerXorOperation() noexcept override;
517 
518  explicit IntegerXorOperation(const std::size_t numBits)
519  : IntegerBinaryOperation(numBits, numBits)
520  {}
521 
522  bool
523  operator==(const Operation & other) const noexcept override;
524 
525  std::string
526  debug_string() const override;
527 
528  [[nodiscard]] std::unique_ptr<Operation>
529  copy() const override;
530 
532  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
533  const noexcept override;
534 
535  rvsdg::Output *
537  const override;
538 
539  enum flags
540  flags() const noexcept override;
541 };
542 
549 {
550 public:
551  ~IntegerEqOperation() noexcept override;
552 
553  explicit IntegerEqOperation(const std::size_t numBits)
554  : IntegerBinaryOperation(numBits, 1)
555  {}
556 
557  bool
558  operator==(const Operation & other) const noexcept override;
559 
560  std::string
561  debug_string() const override;
562 
563  [[nodiscard]] std::unique_ptr<Operation>
564  copy() const override;
565 
567  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
568  const noexcept override;
569 
570  rvsdg::Output *
572  const override;
573 
574  enum flags
575  flags() const noexcept override;
576 };
577 
584 {
585 public:
586  ~IntegerNeOperation() noexcept override;
587 
588  explicit IntegerNeOperation(const std::size_t numBits)
589  : IntegerBinaryOperation(numBits, 1)
590  {}
591 
592  bool
593  operator==(const Operation & other) const noexcept override;
594 
595  std::string
596  debug_string() const override;
597 
598  [[nodiscard]] std::unique_ptr<Operation>
599  copy() const override;
600 
602  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
603  const noexcept override;
604 
605  rvsdg::Output *
607  const override;
608 
609  enum flags
610  flags() const noexcept override;
611 };
612 
619 {
620 public:
621  ~IntegerSgeOperation() noexcept override;
622 
623  explicit IntegerSgeOperation(const std::size_t numBits)
624  : IntegerBinaryOperation(numBits, 1)
625  {}
626 
627  bool
628  operator==(const Operation & other) const noexcept override;
629 
630  std::string
631  debug_string() const override;
632 
633  [[nodiscard]] std::unique_ptr<Operation>
634  copy() const override;
635 
637  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
638  const noexcept override;
639 
640  rvsdg::Output *
642  const override;
643 
644  enum flags
645  flags() const noexcept override;
646 };
647 
654 {
655 public:
656  ~IntegerSgtOperation() noexcept override;
657 
658  explicit IntegerSgtOperation(const std::size_t numBits)
659  : IntegerBinaryOperation(numBits, 1)
660  {}
661 
662  bool
663  operator==(const Operation & other) const noexcept override;
664 
665  std::string
666  debug_string() const override;
667 
668  [[nodiscard]] std::unique_ptr<Operation>
669  copy() const override;
670 
672  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
673  const noexcept override;
674 
675  rvsdg::Output *
677  const override;
678 
679  enum flags
680  flags() const noexcept override;
681 };
682 
689 {
690 public:
691  ~IntegerSleOperation() noexcept override;
692 
693  explicit IntegerSleOperation(const std::size_t numBits)
694  : IntegerBinaryOperation(numBits, 1)
695  {}
696 
697  bool
698  operator==(const Operation & other) const noexcept override;
699 
700  std::string
701  debug_string() const override;
702 
703  [[nodiscard]] std::unique_ptr<Operation>
704  copy() const override;
705 
707  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
708  const noexcept override;
709 
710  rvsdg::Output *
712  const override;
713 
714  enum flags
715  flags() const noexcept override;
716 };
717 
724 {
725 public:
726  ~IntegerSltOperation() noexcept override;
727 
728  explicit IntegerSltOperation(const std::size_t numBits)
729  : IntegerBinaryOperation(numBits, 1)
730  {}
731 
732  bool
733  operator==(const Operation & other) const noexcept override;
734 
735  std::string
736  debug_string() const override;
737 
738  [[nodiscard]] std::unique_ptr<Operation>
739  copy() const override;
740 
742  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
743  const noexcept override;
744 
745  rvsdg::Output *
747  const override;
748 
749  enum flags
750  flags() const noexcept override;
751 };
752 
759 {
760 public:
761  ~IntegerUgeOperation() noexcept override;
762 
763  explicit IntegerUgeOperation(const std::size_t numBits)
764  : IntegerBinaryOperation(numBits, 1)
765  {}
766 
767  bool
768  operator==(const Operation & other) const noexcept override;
769 
770  std::string
771  debug_string() const override;
772 
773  [[nodiscard]] std::unique_ptr<Operation>
774  copy() const override;
775 
777  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
778  const noexcept override;
779 
780  rvsdg::Output *
782  const override;
783 
784  enum flags
785  flags() const noexcept override;
786 };
787 
794 {
795 public:
796  ~IntegerUgtOperation() noexcept override;
797 
798  explicit IntegerUgtOperation(const std::size_t numBits)
799  : IntegerBinaryOperation(numBits, 1)
800  {}
801 
802  bool
803  operator==(const Operation & other) const noexcept override;
804 
805  std::string
806  debug_string() const override;
807 
808  [[nodiscard]] std::unique_ptr<Operation>
809  copy() const override;
810 
812  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
813  const noexcept override;
814 
815  rvsdg::Output *
817  const override;
818 
819  enum flags
820  flags() const noexcept override;
821 };
822 
829 {
830 public:
831  ~IntegerUleOperation() noexcept override;
832 
833  explicit IntegerUleOperation(const std::size_t numBits)
834  : IntegerBinaryOperation(numBits, 1)
835  {}
836 
837  bool
838  operator==(const Operation & other) const noexcept override;
839 
840  std::string
841  debug_string() const override;
842 
843  [[nodiscard]] std::unique_ptr<Operation>
844  copy() const override;
845 
847  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
848  const noexcept override;
849 
850  rvsdg::Output *
852  const override;
853 
854  enum flags
855  flags() const noexcept override;
856 };
857 
864 {
865 public:
866  ~IntegerUltOperation() noexcept override;
867 
868  explicit IntegerUltOperation(const std::size_t numBits)
869  : IntegerBinaryOperation(numBits, 1)
870  {}
871 
872  bool
873  operator==(const Operation & other) const noexcept override;
874 
875  std::string
876  debug_string() const override;
877 
878  [[nodiscard]] std::unique_ptr<Operation>
879  copy() const override;
880 
882  can_reduce_operand_pair(const rvsdg::Output * op1, const rvsdg::Output * op2)
883  const noexcept override;
884 
885  rvsdg::Output *
887  const override;
888 
889  enum flags
890  flags() const noexcept override;
891 };
892 
893 }
894 
895 #endif // JLM_LLVM_IR_OPERATORS_INTEGEROPERATIONS_HPP
~IntegerAShrOperation() noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
bool operator==(const Operation &other) const noexcept override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
enum flags flags() const noexcept override
~IntegerAddOperation() noexcept override
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
~IntegerAndOperation() noexcept override
const rvsdg::BitType & Type() const noexcept
~IntegerBinaryOperation() noexcept override
static rvsdg::Node & Create(rvsdg::Region &region, IntegerValueRepresentation representation)
bool operator==(const Operation &other) const noexcept override
IntegerValueRepresentation Representation_
IntegerConstantOperation(IntegerValueRepresentation representation)
std::unique_ptr< Operation > copy() const override
const IntegerValueRepresentation & Representation() const noexcept
static rvsdg::Node & Create(rvsdg::Region &region, std::size_t numBits, std::int64_t value)
std::string debug_string() const override
~IntegerEqOperation() noexcept override
~IntegerLShrOperation() noexcept override
~IntegerMulOperation() noexcept override
~IntegerNeOperation() noexcept override
~IntegerOrOperation() noexcept override
~IntegerSDivOperation() noexcept override
~IntegerSRemOperation() noexcept override
~IntegerSgeOperation() noexcept override
~IntegerSgtOperation() noexcept override
~IntegerShlOperation() noexcept override
~IntegerSleOperation() noexcept override
~IntegerSltOperation() noexcept override
~IntegerSubOperation() noexcept override
~IntegerUDivOperation() noexcept override
~IntegerURemOperation() noexcept override
~IntegerUgeOperation() noexcept override
~IntegerUgtOperation() noexcept override
~IntegerUleOperation() noexcept override
~IntegerUltOperation() noexcept override
~IntegerXorOperation() noexcept override
BinaryOperation(const std::vector< std::shared_ptr< const jlm::rvsdg::Type >> operands, std::shared_ptr< const jlm::rvsdg::Type > result)
Definition: binary.hpp:37
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition: type.cpp:45
Nullary operator (operator taking no formal arguments)
Definition: nullary.hpp:22
NullaryOperation(std::shared_ptr< const Type > resultType)
Definition: nullary.hpp:26
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
const std::shared_ptr< const rvsdg::Type > & argument(size_t index) const noexcept
Definition: operation.cpp:23
Global memory state passed between functions.
size_t binop_reduction_path_t
Definition: binary.hpp:19