Jlm
Loading...
Searching...
No Matches
IntegerOperations.cpp
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
8
9namespace jlm::llvm
10{
11
12template<typename TBinOp>
15{
16 static_assert(std::is_base_of_v<IntegerBinaryOperation, TBinOp>);
17
18 if constexpr (std::is_same_v<TBinOp, IntegerEqOperation>)
19 return IntegerValueRepresentation(r1.eq(r2));
20 else if constexpr (std::is_same_v<TBinOp, IntegerNeOperation>)
21 return IntegerValueRepresentation(r1.ne(r2));
22 else if constexpr (std::is_same_v<TBinOp, IntegerSgeOperation>)
23 return IntegerValueRepresentation(r1.sge(r2));
24 else if constexpr (std::is_same_v<TBinOp, IntegerSgtOperation>)
25 return IntegerValueRepresentation(r1.sgt(r2));
26 else if constexpr (std::is_same_v<TBinOp, IntegerSleOperation>)
27 return IntegerValueRepresentation(r1.sle(r2));
28 else if constexpr (std::is_same_v<TBinOp, IntegerSltOperation>)
29 return IntegerValueRepresentation(r1.slt(r2));
30 else if constexpr (std::is_same_v<TBinOp, IntegerUgeOperation>)
31 return IntegerValueRepresentation(r1.uge(r2));
32 else if constexpr (std::is_same_v<TBinOp, IntegerUgtOperation>)
33 return IntegerValueRepresentation(r1.ugt(r2));
34 else if constexpr (std::is_same_v<TBinOp, IntegerUleOperation>)
35 return IntegerValueRepresentation(r1.ule(r2));
36 else if constexpr (std::is_same_v<TBinOp, IntegerUltOperation>)
37 return IntegerValueRepresentation(r1.ult(r2));
38 else if constexpr (std::is_same_v<TBinOp, IntegerAddOperation>)
39 return IntegerValueRepresentation(r1.add(r2));
40 else if constexpr (std::is_same_v<TBinOp, IntegerSubOperation>)
41 return IntegerValueRepresentation(r1.sub(r2));
42 else if constexpr (std::is_same_v<TBinOp, IntegerMulOperation>)
43 return IntegerValueRepresentation(r1.mul(r2));
44 else if constexpr (std::is_same_v<TBinOp, IntegerSDivOperation>)
45 return IntegerValueRepresentation(r1.sdiv(r2));
46 else if constexpr (std::is_same_v<TBinOp, IntegerUDivOperation>)
47 return IntegerValueRepresentation(r1.udiv(r2));
48 else if constexpr (std::is_same_v<TBinOp, IntegerSRemOperation>)
49 return IntegerValueRepresentation(r1.smod(r2));
50 else if constexpr (std::is_same_v<TBinOp, IntegerURemOperation>)
51 return IntegerValueRepresentation(r1.umod(r2));
52 else if constexpr (std::is_same_v<TBinOp, IntegerAShrOperation>)
54 else if constexpr (std::is_same_v<TBinOp, IntegerShlOperation>)
55 return IntegerValueRepresentation(r1.shl(r2.to_uint()));
56 else if constexpr (std::is_same_v<TBinOp, IntegerLShrOperation>)
57 return IntegerValueRepresentation(r1.shr(r2.to_uint()));
58 else if constexpr (std::is_same_v<TBinOp, IntegerOrOperation>)
59 return IntegerValueRepresentation(r1.lor(r2));
60 else if constexpr (std::is_same_v<TBinOp, IntegerAndOperation>)
61 return IntegerValueRepresentation(r1.land(r2));
62 else if constexpr (std::is_same_v<TBinOp, IntegerXorOperation>)
63 return IntegerValueRepresentation(r1.lxor(r2));
64 else
65 static_assert(sizeof(TBinOp) == 0, "Unsupported binary operation!");
66}
67
75template<typename TBinOp>
76static std::optional<std::vector<rvsdg::Output *>>
77foldBinaryOperationConstants(const std::vector<rvsdg::Output *> & operands)
78{
79 static_assert(std::is_base_of_v<IntegerBinaryOperation, TBinOp>);
80
81 JLM_ASSERT(operands.size() == 2);
82 auto & operand1 = *operands[0];
83 auto & operand2 = *operands[1];
84
85 const auto & tracedOperand1 = llvm::traceOutput(operand1);
86 auto [c1Node, c1Operation] =
88 if (!c1Operation)
89 return std::nullopt;
90
91 const auto & tracedOperand2 = llvm::traceOutput(operand2);
92 auto [c2Node, c2Operation] =
94 if (!c2Operation)
95 return std::nullopt;
96
97 auto & c1Representation = c1Operation->Representation();
98 auto & c2Representation = c2Operation->Representation();
99 const auto & resultRepresentation =
100 foldBinaryOperation<TBinOp>(c1Representation, c2Representation);
101
102 auto result =
103 IntegerConstantOperation::Create(*operand1.region(), resultRepresentation).output(0);
104
105 return std::vector<rvsdg::Output *>({ result });
106}
107
109
110std::unique_ptr<rvsdg::Operation>
112{
113 return std::make_unique<IntegerConstantOperation>(*this);
114}
115
116std::string
118{
119 if (Representation().is_known() && Representation().nbits() <= 64)
120 return util::strfmt("I", Representation().nbits(), "(", Representation().to_uint(), ")");
121
122 return Representation().str();
123}
124
125bool
126IntegerConstantOperation::operator==(const Operation & other) const noexcept
127{
128 const auto constant = dynamic_cast<const IntegerConstantOperation *>(&other);
129 return constant && constant->Representation() == Representation();
130}
131
133
134IntegerAddOperation::~IntegerAddOperation() noexcept = default;
135
136bool
137IntegerAddOperation::operator==(const Operation & other) const noexcept
138{
139 const auto addOperation = dynamic_cast<const IntegerAddOperation *>(&other);
140 return addOperation && addOperation->Type() == Type();
141}
142
143std::string
145{
146 return "IAdd";
147}
148
149std::unique_ptr<rvsdg::Operation>
151{
152 return std::make_unique<IntegerAddOperation>(*this);
153}
154
161
170
173{
174 return flags::associative | flags::commutative;
175}
176
177std::optional<std::vector<rvsdg::Output *>>
179 const IntegerAddOperation &,
180 const std::vector<rvsdg::Output *> & operands)
181{
182 return foldBinaryOperationConstants<IntegerAddOperation>(operands);
183}
184
186
187bool
188IntegerSubOperation::operator==(const Operation & other) const noexcept
189{
190 const auto subOperation = dynamic_cast<const IntegerSubOperation *>(&other);
191 return subOperation && subOperation->Type() == Type();
192}
193
194std::string
196{
197 return "ISub";
198}
199
200std::unique_ptr<rvsdg::Operation>
202{
203 return std::make_unique<IntegerSubOperation>(*this);
204}
205
212
221
224{
225 return flags::none;
226}
227
228std::optional<std::vector<rvsdg::Output *>>
230 const IntegerSubOperation & operation,
231 const std::vector<rvsdg::Output *> & operands)
232{
233 JLM_ASSERT(operands.size() == 2);
234 const auto & operand1 = *operands[0];
235 const auto & operand2 = *operands[1];
236
237 auto & tracedOperand1 = llvm::traceOutput(operand1);
238 auto & tracedOperand2 = llvm::traceOutput(operand2);
239
240 if (&tracedOperand1 != &tracedOperand2)
241 return std::nullopt;
242
243 return rvsdg::outputs(
244 &IntegerConstantOperation::Create(*operand1.region(), operation.Type().nbits(), 0));
245}
246
247std::optional<std::vector<rvsdg::Output *>>
249 const IntegerSubOperation &,
250 const std::vector<rvsdg::Output *> & operands)
251{
252 return foldBinaryOperationConstants<IntegerSubOperation>(operands);
253}
254
256
257bool
258IntegerMulOperation::operator==(const Operation & other) const noexcept
259{
260 const auto mulOperation = dynamic_cast<const IntegerMulOperation *>(&other);
261 return mulOperation && mulOperation->Type() == Type();
262}
263
264std::string
266{
267 return "IMul";
268}
269
270std::unique_ptr<rvsdg::Operation>
272{
273 return std::make_unique<IntegerMulOperation>(*this);
274}
275
282
291
294{
295 return flags::associative | flags::commutative;
296}
297
298std::optional<std::vector<rvsdg::Output *>>
300 const IntegerMulOperation &,
301 const std::vector<rvsdg::Output *> & operands)
302{
303 return foldBinaryOperationConstants<IntegerMulOperation>(operands);
304}
305
307
308bool
309IntegerSDivOperation::operator==(const Operation & other) const noexcept
310{
311 const auto sdivOperation = dynamic_cast<const IntegerSDivOperation *>(&other);
312 return sdivOperation && sdivOperation->Type() == Type();
313}
314
315std::string
317{
318 return "ISDiv";
319}
320
321std::unique_ptr<rvsdg::Operation>
323{
324 return std::make_unique<IntegerSDivOperation>(*this);
325}
326
333
342
345{
346 return flags::none;
347}
348
349std::optional<std::vector<rvsdg::Output *>>
351 const IntegerSDivOperation &,
352 const std::vector<rvsdg::Output *> & operands)
353{
354 return foldBinaryOperationConstants<IntegerSDivOperation>(operands);
355}
356
358
359bool
360IntegerUDivOperation::operator==(const Operation & other) const noexcept
361{
362 const auto udivOperation = dynamic_cast<const IntegerUDivOperation *>(&other);
363 return udivOperation && udivOperation->Type() == Type();
364}
365
366std::string
368{
369 return "IUDiv";
370}
371
372std::unique_ptr<rvsdg::Operation>
374{
375 return std::make_unique<IntegerUDivOperation>(*this);
376}
377
384
393
396{
397 return flags::none;
398}
399
400std::optional<std::vector<rvsdg::Output *>>
402 const IntegerUDivOperation &,
403 const std::vector<rvsdg::Output *> & operands)
404{
405 return foldBinaryOperationConstants<IntegerUDivOperation>(operands);
406}
407
409
410bool
411IntegerSRemOperation::operator==(const Operation & other) const noexcept
412{
413 const auto smodOperation = dynamic_cast<const IntegerSRemOperation *>(&other);
414 return smodOperation && smodOperation->Type() == Type();
415}
416
417std::string
419{
420 return "ISMod";
421}
422
423std::unique_ptr<rvsdg::Operation>
425{
426 return std::make_unique<IntegerSRemOperation>(*this);
427}
428
435
444
447{
448 return flags::none;
449}
450
451std::optional<std::vector<rvsdg::Output *>>
453 const IntegerSRemOperation &,
454 const std::vector<rvsdg::Output *> & operands)
455{
456 return foldBinaryOperationConstants<IntegerSRemOperation>(operands);
457}
458
460
461bool
462IntegerURemOperation::operator==(const Operation & other) const noexcept
463{
464 const auto umodOperation = dynamic_cast<const IntegerURemOperation *>(&other);
465 return umodOperation && umodOperation->Type() == Type();
466}
467
468std::string
470{
471 return "IUMod";
472}
473
474std::unique_ptr<rvsdg::Operation>
476{
477 return std::make_unique<IntegerURemOperation>(*this);
478}
479
486
495
498{
499 return flags::none;
500}
501
502std::optional<std::vector<rvsdg::Output *>>
504 const IntegerURemOperation &,
505 const std::vector<rvsdg::Output *> & operands)
506{
507 return foldBinaryOperationConstants<IntegerURemOperation>(operands);
508}
509
511
512bool
513IntegerAShrOperation::operator==(const Operation & other) const noexcept
514{
515 const auto ashrOperation = dynamic_cast<const IntegerAShrOperation *>(&other);
516 return ashrOperation && ashrOperation->Type() == Type();
517}
518
519std::string
521{
522 return "IAShr";
523}
524
525std::unique_ptr<rvsdg::Operation>
527{
528 return std::make_unique<IntegerAShrOperation>(*this);
529}
530
537
546
549{
550 return flags::none;
551}
552
553std::optional<std::vector<rvsdg::Output *>>
555 const IntegerAShrOperation &,
556 const std::vector<rvsdg::Output *> & operands)
557{
558 return foldBinaryOperationConstants<IntegerAShrOperation>(operands);
559}
560
562
563bool
564IntegerShlOperation::operator==(const Operation & other) const noexcept
565{
566 const auto shlOperation = dynamic_cast<const IntegerShlOperation *>(&other);
567 return shlOperation && shlOperation->Type() == Type();
568}
569
570std::string
572{
573 return "IShl";
574}
575
576std::unique_ptr<rvsdg::Operation>
578{
579 return std::make_unique<IntegerShlOperation>(*this);
580}
581
588
597
600{
601 return flags::none;
602}
603
604std::optional<std::vector<rvsdg::Output *>>
606 const IntegerShlOperation &,
607 const std::vector<rvsdg::Output *> & operands)
608{
609 return foldBinaryOperationConstants<IntegerShlOperation>(operands);
610}
611
613
614bool
615IntegerLShrOperation::operator==(const Operation & other) const noexcept
616{
617 const auto shrOperation = dynamic_cast<const IntegerLShrOperation *>(&other);
618 return shrOperation && shrOperation->Type() == Type();
619}
620
621std::string
623{
624 return "IShr";
625}
626
627std::unique_ptr<rvsdg::Operation>
629{
630 return std::make_unique<IntegerLShrOperation>(*this);
631}
632
639
648
651{
652 return flags::none;
653}
654
655std::optional<std::vector<rvsdg::Output *>>
657 const IntegerLShrOperation &,
658 const std::vector<rvsdg::Output *> & operands)
659{
660 return foldBinaryOperationConstants<IntegerLShrOperation>(operands);
661}
662
664
665bool
666IntegerAndOperation::operator==(const Operation & other) const noexcept
667{
668 const auto andOperation = dynamic_cast<const IntegerAndOperation *>(&other);
669 return andOperation && andOperation->Type() == Type();
670}
671
672std::string
674{
675 return "IAnd";
676}
677
678std::unique_ptr<rvsdg::Operation>
680{
681 return std::make_unique<IntegerAndOperation>(*this);
682}
683
690
699
702{
703 return flags::associative | flags::commutative;
704}
705
706std::optional<std::vector<rvsdg::Output *>>
708 const IntegerAndOperation &,
709 const std::vector<rvsdg::Output *> & operands)
710{
711 return foldBinaryOperationConstants<IntegerAndOperation>(operands);
712}
713
714IntegerOrOperation::~IntegerOrOperation() noexcept = default;
715
716bool
717IntegerOrOperation::operator==(const Operation & other) const noexcept
718{
719 const auto orOperation = dynamic_cast<const IntegerOrOperation *>(&other);
720 return orOperation && orOperation->Type() == Type();
721}
722
723std::string
725{
726 return "IOr";
727}
728
729std::unique_ptr<rvsdg::Operation>
731{
732 return std::make_unique<IntegerOrOperation>(*this);
733}
734
741
750
753{
754 return flags::associative | flags::commutative;
755}
756
757std::optional<std::vector<rvsdg::Output *>>
759 const IntegerOrOperation &,
760 const std::vector<rvsdg::Output *> & operands)
761{
762 return foldBinaryOperationConstants<IntegerOrOperation>(operands);
763}
764
766
767bool
768IntegerXorOperation::operator==(const Operation & other) const noexcept
769{
770 const auto xorOperation = dynamic_cast<const IntegerXorOperation *>(&other);
771 return xorOperation && xorOperation->Type() == Type();
772}
773
774std::string
776{
777 return "IXor";
778}
779
780std::unique_ptr<rvsdg::Operation>
782{
783 return std::make_unique<IntegerXorOperation>(*this);
784}
785
792
801
804{
805 return flags::associative | flags::commutative;
806}
807
808std::optional<std::vector<rvsdg::Output *>>
810 const IntegerXorOperation &,
811 const std::vector<rvsdg::Output *> & operands)
812{
813 return foldBinaryOperationConstants<IntegerXorOperation>(operands);
814}
815
816IntegerEqOperation::~IntegerEqOperation() noexcept = default;
817
818bool
819IntegerEqOperation::operator==(const Operation & other) const noexcept
820{
821 const auto eqOperation = dynamic_cast<const IntegerEqOperation *>(&other);
822 return eqOperation && eqOperation->result(0) == result(0);
823}
824
825std::string
827{
828 return "IEq";
829}
830
831std::unique_ptr<rvsdg::Operation>
833{
834 return std::make_unique<IntegerEqOperation>(*this);
835}
836
843
852
855{
856 return flags::commutative;
857}
858
859std::optional<std::vector<rvsdg::Output *>>
861 const IntegerEqOperation &,
862 const std::vector<rvsdg::Output *> & operands)
863{
864 return foldBinaryOperationConstants<IntegerEqOperation>(operands);
865}
866
867IntegerNeOperation::~IntegerNeOperation() noexcept = default;
868
869bool
870IntegerNeOperation::operator==(const Operation & other) const noexcept
871{
872 const auto neOperation = dynamic_cast<const IntegerNeOperation *>(&other);
873 return neOperation && neOperation->result(0) == result(0);
874}
875
876std::string
878{
879 return "INe";
880}
881
882std::unique_ptr<rvsdg::Operation>
884{
885 return std::make_unique<IntegerNeOperation>(*this);
886}
887
894
903
906{
907 return flags::commutative;
908}
909
910std::optional<std::vector<rvsdg::Output *>>
912 const IntegerNeOperation &,
913 const std::vector<rvsdg::Output *> & operands)
914{
915 return foldBinaryOperationConstants<IntegerNeOperation>(operands);
916}
917
919
920bool
921IntegerSgeOperation::operator==(const Operation & other) const noexcept
922{
923 const auto sgeOperation = dynamic_cast<const IntegerSgeOperation *>(&other);
924 return sgeOperation && sgeOperation->result(0) == result(0);
925}
926
927std::string
929{
930 return "ISge";
931}
932
933std::unique_ptr<rvsdg::Operation>
935{
936 return std::make_unique<IntegerSgeOperation>(*this);
937}
938
945
954
957{
958 return flags::none;
959}
960
961std::optional<std::vector<rvsdg::Output *>>
963 const IntegerSgeOperation &,
964 const std::vector<rvsdg::Output *> & operands)
965{
966 return foldBinaryOperationConstants<IntegerSgeOperation>(operands);
967}
968
970
971bool
972IntegerSgtOperation::operator==(const Operation & other) const noexcept
973{
974 const auto sgtOperation = dynamic_cast<const IntegerSgtOperation *>(&other);
975 return sgtOperation && sgtOperation->result(0) == result(0);
976}
977
978std::string
980{
981 return "ISgt";
982}
983
984std::unique_ptr<rvsdg::Operation>
986{
987 return std::make_unique<IntegerSgtOperation>(*this);
988}
989
996
1005
1008{
1009 return flags::none;
1010}
1011
1012std::optional<std::vector<rvsdg::Output *>>
1014 const IntegerSgtOperation &,
1015 const std::vector<rvsdg::Output *> & operands)
1016{
1017 return foldBinaryOperationConstants<IntegerSgtOperation>(operands);
1018}
1019
1021
1022bool
1023IntegerSleOperation::operator==(const Operation & other) const noexcept
1024{
1025 const auto sleOperation = dynamic_cast<const IntegerSleOperation *>(&other);
1026 return sleOperation && sleOperation->result(0) == result(0);
1027}
1028
1029std::string
1031{
1032 return "ISle";
1033}
1034
1035std::unique_ptr<rvsdg::Operation>
1037{
1038 return std::make_unique<IntegerSleOperation>(*this);
1039}
1040
1047
1056
1059{
1060 return flags::none;
1061}
1062
1063std::optional<std::vector<rvsdg::Output *>>
1065 const IntegerSleOperation &,
1066 const std::vector<rvsdg::Output *> & operands)
1067{
1068 return foldBinaryOperationConstants<IntegerSleOperation>(operands);
1069}
1070
1072
1073bool
1074IntegerSltOperation::operator==(const Operation & other) const noexcept
1075{
1076 const auto sltOperation = dynamic_cast<const IntegerSltOperation *>(&other);
1077 return sltOperation && sltOperation->result(0) == result(0);
1078}
1079
1080std::string
1082{
1083 return "ISlt";
1084}
1085
1086std::unique_ptr<rvsdg::Operation>
1088{
1089 return std::make_unique<IntegerSltOperation>(*this);
1090}
1091
1098
1107
1110{
1111 return flags::none;
1112}
1113
1114std::optional<std::vector<rvsdg::Output *>>
1116 const IntegerSltOperation &,
1117 const std::vector<rvsdg::Output *> & operands)
1118{
1119 return foldBinaryOperationConstants<IntegerSltOperation>(operands);
1120}
1121
1123
1124bool
1125IntegerUgeOperation::operator==(const Operation & other) const noexcept
1126{
1127 const auto ugeOperation = dynamic_cast<const IntegerUgeOperation *>(&other);
1128 return ugeOperation && ugeOperation->result(0) == result(0);
1129}
1130
1131std::string
1133{
1134 return "IUge";
1135}
1136
1137std::unique_ptr<rvsdg::Operation>
1139{
1140 return std::make_unique<IntegerUgeOperation>(*this);
1141}
1142
1149
1158
1161{
1162 return flags::none;
1163}
1164
1165std::optional<std::vector<rvsdg::Output *>>
1167 const IntegerUgeOperation &,
1168 const std::vector<rvsdg::Output *> & operands)
1169{
1170 return foldBinaryOperationConstants<IntegerUgeOperation>(operands);
1171}
1172
1174
1175bool
1176IntegerUgtOperation::operator==(const Operation & other) const noexcept
1177{
1178 const auto ugtOperation = dynamic_cast<const IntegerUgtOperation *>(&other);
1179 return ugtOperation && ugtOperation->result(0) == result(0);
1180}
1181
1182std::string
1184{
1185 return "IUgt";
1186}
1187
1188std::unique_ptr<rvsdg::Operation>
1190{
1191 return std::make_unique<IntegerUgtOperation>(*this);
1192}
1193
1200
1209
1212{
1213 return flags::none;
1214}
1215
1216std::optional<std::vector<rvsdg::Output *>>
1218 const IntegerUgtOperation &,
1219 const std::vector<rvsdg::Output *> & operands)
1220{
1221 return foldBinaryOperationConstants<IntegerUgtOperation>(operands);
1222}
1223
1225
1226bool
1227IntegerUleOperation::operator==(const Operation & other) const noexcept
1228{
1229 const auto uleOperation = dynamic_cast<const IntegerUleOperation *>(&other);
1230 return uleOperation && uleOperation->result(0) == result(0);
1231}
1232
1233std::string
1235{
1236 return "IUle";
1237}
1238
1239std::unique_ptr<rvsdg::Operation>
1241{
1242 return std::make_unique<IntegerUleOperation>(*this);
1243}
1244
1251
1260
1263{
1264 return flags::none;
1265}
1266
1267std::optional<std::vector<rvsdg::Output *>>
1269 const IntegerUleOperation &,
1270 const std::vector<rvsdg::Output *> & operands)
1271{
1272 return foldBinaryOperationConstants<IntegerUleOperation>(operands);
1273}
1274
1276
1277bool
1278IntegerUltOperation::operator==(const Operation & other) const noexcept
1279{
1280 const auto ultOperation = dynamic_cast<const IntegerUltOperation *>(&other);
1281 return ultOperation && ultOperation->result(0) == result(0);
1282}
1283
1284std::string
1286{
1287 return "IUlt";
1288}
1289
1290std::unique_ptr<rvsdg::Operation>
1292{
1293 return std::make_unique<IntegerUltOperation>(*this);
1294}
1295
1302
1311
1314{
1315 return flags::none;
1316}
1317
1318std::optional<std::vector<rvsdg::Output *>>
1320 const IntegerUltOperation &,
1321 const std::vector<rvsdg::Output *> & operands)
1322{
1323 return foldBinaryOperationConstants<IntegerUltOperation>(operands);
1324}
1325
1326}
std::unique_ptr< Operation > copy() const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerAShrOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::string debug_string() const override
enum flags flags() const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
~IntegerAShrOperation() noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const 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
std::string debug_string() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerAddOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
std::unique_ptr< Operation > copy() const override
enum flags flags() const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerAndOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::string debug_string() const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
~IntegerAndOperation() noexcept override
~IntegerBinaryOperation() noexcept override
const rvsdg::BitType & Type() const noexcept
static rvsdg::Node & Create(rvsdg::Region &region, IntegerValueRepresentation representation)
bool operator==(const Operation &other) const noexcept override
const IntegerValueRepresentation & Representation() const noexcept
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
enum flags flags() const noexcept override
std::string debug_string() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerEqOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
~IntegerEqOperation() noexcept override
~IntegerLShrOperation() noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerLShrOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
enum flags flags() const noexcept override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
~IntegerMulOperation() noexcept override
std::string debug_string() const override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerMulOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const 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
std::string debug_string() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerNeOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
enum flags flags() const noexcept override
~IntegerNeOperation() noexcept override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerOrOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
~IntegerOrOperation() noexcept override
enum flags flags() const noexcept override
std::string debug_string() const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSDivOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::string debug_string() const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
~IntegerSDivOperation() noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
std::unique_ptr< Operation > copy() const override
enum flags flags() const noexcept override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSRemOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::string debug_string() const override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
~IntegerSRemOperation() noexcept override
std::unique_ptr< Operation > copy() const override
enum flags flags() const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSgeOperation &operation, const std::vector< rvsdg::Output * > &operands)
enum flags flags() const noexcept override
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
~IntegerSgeOperation() noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSgtOperation &operation, const std::vector< rvsdg::Output * > &operands)
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
enum flags flags() const noexcept override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
~IntegerSgtOperation() noexcept override
std::unique_ptr< Operation > copy() const override
~IntegerShlOperation() noexcept override
enum flags flags() const noexcept override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
std::string debug_string() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerShlOperation &operation, const std::vector< rvsdg::Output * > &operands)
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
std::string debug_string() const override
enum flags flags() const noexcept override
~IntegerSleOperation() noexcept override
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSleOperation &operation, const std::vector< rvsdg::Output * > &operands)
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
std::unique_ptr< Operation > copy() const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
std::string debug_string() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSltOperation &operation, const std::vector< rvsdg::Output * > &operands)
enum flags flags() const noexcept override
~IntegerSltOperation() noexcept override
~IntegerSubOperation() noexcept override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
std::string debug_string() const override
enum flags flags() const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSubOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeAdditiveInverse(const IntegerSubOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUDivOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::string debug_string() const override
~IntegerUDivOperation() 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
std::unique_ptr< Operation > copy() const override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
enum flags flags() const noexcept override
~IntegerURemOperation() noexcept override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerURemOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUgeOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
~IntegerUgeOperation() noexcept override
enum flags flags() const noexcept override
enum flags flags() const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
~IntegerUgtOperation() noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUgtOperation &operation, const std::vector< rvsdg::Output * > &operands)
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
enum flags flags() const noexcept override
std::string debug_string() const override
~IntegerUleOperation() noexcept override
std::unique_ptr< Operation > copy() const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUleOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
enum flags flags() const noexcept override
std::string debug_string() const override
~IntegerUltOperation() noexcept override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUltOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::string debug_string() const override
rvsdg::Output * reduce_operand_pair(rvsdg::binop_reduction_path_t path, rvsdg::Output *op1, rvsdg::Output *op2) const override
~IntegerXorOperation() noexcept override
enum flags flags() const noexcept override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerXorOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
rvsdg::binop_reduction_path_t can_reduce_operand_pair(const rvsdg::Output *op1, const rvsdg::Output *op2) const noexcept override
size_t nbits() const noexcept
Definition type.hpp:26
BitValueRepresentation shl(size_t shift) const
void udiv(const BitValueRepresentation &divisor, BitValueRepresentation &quotient, BitValueRepresentation &remainder) const
BitValueRepresentation smod(const BitValueRepresentation &other) const
void mul(const BitValueRepresentation &factor1, const BitValueRepresentation &factor2, BitValueRepresentation &product) const
char sgt(const BitValueRepresentation &other) const
char sge(const BitValueRepresentation &other) const
BitValueRepresentation sdiv(const BitValueRepresentation &other) const
char ne(const BitValueRepresentation &other) const
char ule(const BitValueRepresentation &other) const
char ult(const BitValueRepresentation &other) const
char lor(char a, char b) const noexcept
char ugt(const BitValueRepresentation &other) const
char eq(const BitValueRepresentation &other) const
char lxor(char a, char b) const noexcept
BitValueRepresentation sub(const BitValueRepresentation &other) const
char slt(const BitValueRepresentation &other) const
BitValueRepresentation ashr(size_t shift) const
BitValueRepresentation shr(size_t shift) const
BitValueRepresentation umod(const BitValueRepresentation &other) const
char sle(const BitValueRepresentation &other) const
char land(char a, char b) const noexcept
char uge(const BitValueRepresentation &other) const
char add(char a, char b, char c) const noexcept
NodeOutput * output(size_t index) const noexcept
Definition node.hpp:650
const std::shared_ptr< const rvsdg::Type > & result(size_t index) const noexcept
Definition operation.cpp:36
#define JLM_ASSERT(x)
Definition common.hpp:16
Global memory state passed between functions.
rvsdg::Output & traceOutput(rvsdg::Output &output, const rvsdg::Region *withinRegion)
Definition Trace.cpp:62
rvsdg::BitValueRepresentation IntegerValueRepresentation
static IntegerValueRepresentation foldBinaryOperation(const IntegerValueRepresentation &r1, const IntegerValueRepresentation &r2)
static std::optional< std::vector< rvsdg::Output * > > foldBinaryOperationConstants(const std::vector< rvsdg::Output * > &operands)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
Definition node.hpp:1058
size_t binop_reduction_path_t
Definition binary.hpp:19
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872
static const binop_reduction_path_t binop_reduction_none
Definition binary.hpp:203
static std::string strfmt(Args... args)
Definition strfmt.hpp:35