Jlm
Loading...
Searching...
No Matches
operators.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 2015 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
10#include <jlm/llvm/ir/Trace.hpp>
11#include <jlm/rvsdg/delta.hpp>
12#include <jlm/rvsdg/lambda.hpp>
13#include <jlm/rvsdg/Trace.hpp>
15
16#include <llvm/ADT/SmallVector.h>
17#include <llvm/IR/InstrTypes.h>
18#include <stdexcept>
19
20namespace jlm::llvm
21{
22
23SsaPhiOperation::~SsaPhiOperation() noexcept = default;
24
25bool
26SsaPhiOperation::operator==(const Operation & other) const noexcept
27{
28 const auto op = dynamic_cast<const SsaPhiOperation *>(&other);
29 return op && op->IncomingNodes_ == IncomingNodes_ && op->result(0) == result(0);
30}
31
32std::string
34{
35 std::string str("[");
36 for (size_t n = 0; n < narguments(); n++)
37 {
39 if (n != narguments() - 1)
40 str += ", ";
41 }
42 str += "]";
43
44 return "PHI" + str;
45}
46
47std::unique_ptr<rvsdg::Operation>
49{
50 return std::make_unique<SsaPhiOperation>(*this);
51}
52
54
55bool
56AssignmentOperation::operator==(const Operation & other) const noexcept
57{
58 const auto op = dynamic_cast<const AssignmentOperation *>(&other);
59 return op && op->argument(0) == argument(0);
60}
61
62std::string
64{
65 return "ASSIGN";
66}
67
68std::unique_ptr<rvsdg::Operation>
70{
71 return std::make_unique<AssignmentOperation>(*this);
72}
73
74SelectOperation::~SelectOperation() noexcept = default;
75
76bool
77SelectOperation::operator==(const Operation & other) const noexcept
78{
79 const auto op = dynamic_cast<const SelectOperation *>(&other);
80 return op && op->result(0) == result(0);
81}
82
83std::string
85{
86 return "Select";
87}
88
89std::unique_ptr<rvsdg::Operation>
91{
92 return std::make_unique<SelectOperation>(*this);
93}
94
96
97bool
98VectorSelectOperation::operator==(const Operation & other) const noexcept
99{
100 const auto op = dynamic_cast<const VectorSelectOperation *>(&other);
101 return op && op->type() == type();
102}
103
104std::string
106{
107 return "VectorSelect";
108}
109
110std::unique_ptr<rvsdg::Operation>
112{
113 return std::make_unique<VectorSelectOperation>(*this);
114}
115
116BranchOperation::~BranchOperation() noexcept = default;
117
118bool
119BranchOperation::operator==(const Operation & other) const noexcept
120{
121 const auto op = dynamic_cast<const BranchOperation *>(&other);
122 return op && op->argument(0) == argument(0);
123}
124
125std::string
127{
128 return "Branch";
129}
130
131std::unique_ptr<rvsdg::Operation>
133{
134 return std::make_unique<BranchOperation>(*this);
135}
136
138
139bool
140ConstantPointerNullOperation::operator==(const Operation & other) const noexcept
141{
142 return dynamic_cast<const ConstantPointerNullOperation *>(&other);
143}
144
145std::string
147{
148 return "ConstantPointerNull";
149}
150
151std::unique_ptr<rvsdg::Operation>
153{
154 return std::make_unique<ConstantPointerNullOperation>(*this);
155}
156
158
159bool
160ConstantDataArrayOperation::operator==(const Operation & other) const noexcept
161{
162 const auto op = dynamic_cast<const ConstantDataArrayOperation *>(&other);
163 return op && op->result(0) == result(0);
164}
165
166std::string
168{
169 return "ConstantDataArray";
170}
171
172std::unique_ptr<rvsdg::Operation>
174{
175 return std::make_unique<ConstantDataArrayOperation>(*this);
176}
177
180{
182 { ::llvm::CmpInst::ICMP_EQ, ICmpPredicate::Eq },
183 { ::llvm::CmpInst::ICMP_NE, ICmpPredicate::Ne },
184 { ::llvm::CmpInst::ICMP_UGT, ICmpPredicate::Ugt },
185 { ::llvm::CmpInst::ICMP_UGE, ICmpPredicate::Uge },
186 { ::llvm::CmpInst::ICMP_ULT, ICmpPredicate::Ult },
187 { ::llvm::CmpInst::ICMP_ULE, ICmpPredicate::Ule },
188 { ::llvm::CmpInst::ICMP_SGT, ICmpPredicate::Sgt },
189 { ::llvm::CmpInst::ICMP_SGE, ICmpPredicate::Sge },
190 { ::llvm::CmpInst::ICMP_SLT, ICmpPredicate::Slt },
191 { ::llvm::CmpInst::ICMP_SLE, ICmpPredicate::Sle },
192 };
193 return map;
194}
195
197convertICmpPredicateToJlm(::llvm::CmpInst::Predicate predicate)
198{
199 const auto & map = getICmpPredicateMap();
200 return map.LookupKey(predicate);
201}
202
203[[nodiscard]] ::llvm::CmpInst::Predicate
205{
206 const auto & map = getICmpPredicateMap();
207 return map.LookupValue(predicate);
208}
209
210[[nodiscard]] std::string_view
212{
213 switch (predicate)
214 {
216 return "eq";
218 return "ne";
220 return "ugt";
222 return "uge";
224 return "ult";
226 return "ule";
228 return "sgt";
230 return "sge";
232 return "slt";
234 return "sle";
235 default:
236 throw std::runtime_error("Unknown ICmpPredicate");
237 }
238}
239
240PtrCmpOperation::~PtrCmpOperation() noexcept = default;
241
242bool
243PtrCmpOperation::operator==(const Operation & other) const noexcept
244{
245 auto op = dynamic_cast<const PtrCmpOperation *>(&other);
246 return op && op->argument(0) == argument(0) && op->predicate_ == predicate_;
247}
248
249std::string
251{
252 return util::strfmt("PtrCmp[", iCmpPredicateToString(predicate_), "]");
253}
254
255std::unique_ptr<rvsdg::Operation>
257{
258 return std::make_unique<PtrCmpOperation>(*this);
259}
260
267
276
277template<typename TOperation>
278static bool
280{
281 auto [node, operation] = rvsdg::TryGetSimpleNodeAndOptionalOp<TOperation>(operand);
282 return operation != nullptr;
283}
284
285static bool
287{
288 if (isOutputOf<AllocaOperation>(output))
289 {
290 return true;
291 }
292
294 {
295 return true;
296 }
297
298 if (dynamic_cast<const LlvmGraphImport *>(&output))
299 {
300 return true;
301 }
302
303 auto [fnToPtrNode, fnToPtrOperation] =
305 if (fnToPtrOperation != nullptr)
306 {
307 const auto & tracedOutput =
308 rvsdg::traceOutputIntraProcedurally(*fnToPtrNode->input(0)->origin(), false);
310 {
311 return true;
312 }
313 }
314
315 return false;
316}
317
318std::optional<std::vector<rvsdg::Output *>>
320 const PtrCmpOperation & ptrCmpOperation,
321 const std::vector<rvsdg::Output *> & operands)
322{
323 if (ptrCmpOperation.predicate() != ICmpPredicate::Eq
324 && ptrCmpOperation.predicate() != ICmpPredicate::Ne)
325 return std::nullopt;
326
327 JLM_ASSERT(operands.size() == 2);
328 auto & tracedOperand1 = rvsdg::traceOutput(*operands[0], false);
329 auto & tracedOperand2 = rvsdg::traceOutput(*operands[1], false);
330
331 if (isOutputOf<ConstantPointerNullOperation>(tracedOperand1)
332 && isOutputOf<ConstantPointerNullOperation>(tracedOperand2))
333 {
334 auto & region = *operands[0]->region();
335 switch (ptrCmpOperation.predicate())
336 {
341 default:
342 throw std::logic_error("Unhandled predicate!");
343 }
344 }
345
346 const bool hasRequiredOperands =
347 (isOutputOf<ConstantPointerNullOperation>(tracedOperand1) && isAllocationSide(tracedOperand2))
348 || (isOutputOf<ConstantPointerNullOperation>(tracedOperand2)
349 && isAllocationSide(tracedOperand1));
350 if (hasRequiredOperands)
351 {
352 auto & region = *operands[0]->region();
353 switch (ptrCmpOperation.predicate())
354 {
359 default:
360 throw std::logic_error("Unhandled predicate!");
361 }
362 }
363
364 return std::nullopt;
365}
366
367std::optional<std::vector<rvsdg::Output *>>
369 const PtrCmpOperation & ptrCmpOperation,
370 const std::vector<rvsdg::Output *> & operands)
371{
372 JLM_ASSERT(operands.size() == 2);
373 auto & operand1 = operands[0];
374 auto & operand2 = operands[1];
375
376 const auto & tracedOperand1 = rvsdg::traceOutput(*operand1, true);
377 const auto & tracedOperand2 = rvsdg::traceOutput(*operand2, true);
378 if (&tracedOperand1 != &tracedOperand2)
379 return std::nullopt;
380
381 switch (ptrCmpOperation.predicate())
382 {
388 return rvsdg::outputs(&IntegerConstantOperation::Create(*operand1->region(), 1, 1));
389
395 return rvsdg::outputs(&IntegerConstantOperation::Create(*operand1->region(), 1, 0));
396 default:
397 throw std::logic_error("Unhandled predicate!");
398 }
399}
400
401ConstantFP::~ConstantFP() noexcept = default;
402
403bool
404ConstantFP::operator==(const Operation & other) const noexcept
405{
406 auto op = dynamic_cast<const ConstantFP *>(&other);
407 return op && size() == op->size() && constant().bitwiseIsEqual(op->constant());
408}
409
410std::string
412{
413 ::llvm::SmallVector<char, 32> v;
414 constant().toString(v, 32, 0);
415
416 std::string s("FP(");
417 for (const auto & c : v)
418 s += c;
419 s += ")";
420
421 return s;
422}
423
424std::unique_ptr<rvsdg::Operation>
426{
427 return std::make_unique<ConstantFP>(*this);
428}
429
430FCmpOperation::~FCmpOperation() noexcept = default;
431
432bool
433FCmpOperation::operator==(const Operation & other) const noexcept
434{
435 auto op = dynamic_cast<const FCmpOperation *>(&other);
436 return op && op->argument(0) == argument(0) && op->cmp_ == cmp_;
437}
438
439std::string
441{
442 static std::unordered_map<fpcmp, std::string> map({ { fpcmp::oeq, "oeq" },
443 { fpcmp::ogt, "ogt" },
444 { fpcmp::oge, "oge" },
445 { fpcmp::olt, "olt" },
446 { fpcmp::ole, "ole" },
447 { fpcmp::one, "one" },
448 { fpcmp::ord, "ord" },
449 { fpcmp::ueq, "ueq" },
450 { fpcmp::ugt, "ugt" },
451 { fpcmp::uge, "uge" },
452 { fpcmp::ult, "ult" },
453 { fpcmp::ule, "ule" },
454 { fpcmp::une, "une" },
455 { fpcmp::uno, "uno" } });
456
457 JLM_ASSERT(map.find(cmp()) != map.end());
458 return "FCmp " + map[cmp()];
459}
460
461std::unique_ptr<rvsdg::Operation>
463{
464 return std::make_unique<FCmpOperation>(*this);
465}
466
472
479
480std::optional<std::vector<rvsdg::Output *>>
482 const FCmpOperation & operation,
483 const std::vector<rvsdg::Output *> & operands)
484{
485 JLM_ASSERT(operands.size() == 2);
486 auto & operand1 = *operands[0];
487 auto & operand2 = *operands[1];
488 JLM_ASSERT(!is<VectorType>(operand1.Type()));
489
490 const auto & tracedOperand1 = llvm::traceOutput(operand1, false);
491 auto [c1Node, c1Operation] = rvsdg::TryGetSimpleNodeAndOptionalOp<ConstantFP>(tracedOperand1);
492 if (!c1Operation)
493 return std::nullopt;
494
495 const auto & tracedOperand2 = llvm::traceOutput(operand2, false);
496 auto [c2Node, c2Operation] = rvsdg::TryGetSimpleNodeAndOptionalOp<ConstantFP>(tracedOperand2);
497 if (!c2Operation)
498 return std::nullopt;
499
500 auto & c1Representation = c1Operation->constant();
501 auto & c2Representation = c2Operation->constant();
502 const auto cmpResult = c1Representation.compare(c2Representation);
503
504 bool boolResult = false;
505 switch (operation.cmp())
506 {
507 case fpcmp::FALSE:
508 boolResult = false;
509 break;
510 case fpcmp::TRUE:
511 boolResult = true;
512 break;
513
514 case fpcmp::oeq:
515 boolResult = (cmpResult == ::llvm::APFloat::cmpEqual);
516 break;
517 case fpcmp::ogt:
518 boolResult = (cmpResult == ::llvm::APFloat::cmpGreaterThan);
519 break;
520 case fpcmp::oge:
521 boolResult =
522 (cmpResult == ::llvm::APFloat::cmpGreaterThan || cmpResult == ::llvm::APFloat::cmpEqual);
523 break;
524 case fpcmp::olt:
525 boolResult = (cmpResult == ::llvm::APFloat::cmpLessThan);
526 break;
527 case fpcmp::ole:
528 boolResult =
529 (cmpResult == ::llvm::APFloat::cmpLessThan || cmpResult == ::llvm::APFloat::cmpEqual);
530 break;
531 case fpcmp::one:
532 boolResult =
533 (cmpResult == ::llvm::APFloat::cmpLessThan || cmpResult == ::llvm::APFloat::cmpGreaterThan);
534 break;
535 case fpcmp::ord:
536 boolResult = (cmpResult != ::llvm::APFloat::cmpUnordered);
537 break;
538
539 case fpcmp::uno:
540 boolResult = (cmpResult == ::llvm::APFloat::cmpUnordered);
541 break;
542 case fpcmp::ueq:
543 boolResult =
544 (cmpResult == ::llvm::APFloat::cmpUnordered || cmpResult == ::llvm::APFloat::cmpEqual);
545 break;
546 case fpcmp::ugt:
547 boolResult =
548 (cmpResult == ::llvm::APFloat::cmpUnordered
549 || cmpResult == ::llvm::APFloat::cmpGreaterThan);
550 break;
551 case fpcmp::uge:
552 boolResult =
553 (cmpResult == ::llvm::APFloat::cmpUnordered || cmpResult == ::llvm::APFloat::cmpGreaterThan
554 || cmpResult == ::llvm::APFloat::cmpEqual);
555 break;
556 case fpcmp::ult:
557 boolResult =
558 (cmpResult == ::llvm::APFloat::cmpUnordered || cmpResult == ::llvm::APFloat::cmpLessThan);
559 break;
560 case fpcmp::ule:
561 boolResult =
562 (cmpResult == ::llvm::APFloat::cmpUnordered || cmpResult == ::llvm::APFloat::cmpLessThan
563 || cmpResult == ::llvm::APFloat::cmpEqual);
564 break;
565 case fpcmp::une:
566 boolResult = (cmpResult != ::llvm::APFloat::cmpEqual);
567 break;
568
569 default:
570 throw std::logic_error("Invalid FCmp operation");
571 }
572
573 auto result =
574 IntegerConstantOperation::Create(*operand1.region(), 1, boolResult ? 1 : 0).output(0);
575
576 return std::vector<rvsdg::Output *>({ result });
577}
578
580
581bool
582UndefValueOperation::operator==(const Operation & other) const noexcept
583{
584 auto op = dynamic_cast<const UndefValueOperation *>(&other);
585 return op && op->GetType() == GetType();
586}
587
588std::string
590{
591 return util::strfmt("Undef[", GetType().debug_string(), "]");
592}
593
594std::unique_ptr<rvsdg::Operation>
596{
597 return std::make_unique<UndefValueOperation>(*this);
598}
599
601
602bool
603PoisonValueOperation::operator==(const Operation & other) const noexcept
604{
605 auto operation = dynamic_cast<const PoisonValueOperation *>(&other);
606 return operation && operation->GetType() == GetType();
607}
608
609std::string
611{
612 return "poison";
613}
614
615std::unique_ptr<rvsdg::Operation>
617{
618 return std::make_unique<PoisonValueOperation>(*this);
619}
620
621FreezeOperation::~FreezeOperation() noexcept = default;
622
623bool
624FreezeOperation::operator==(const Operation & other) const noexcept
625{
626 auto operation = dynamic_cast<const FreezeOperation *>(&other);
627 return operation && operation->getType() == getType();
628}
629
630std::string
632{
633 return "freeze";
634}
635
636std::unique_ptr<rvsdg::Operation>
638{
639 return std::make_unique<FreezeOperation>(*this);
640}
641
642FBinaryOperation::~FBinaryOperation() noexcept = default;
643
644bool
645FBinaryOperation::operator==(const Operation & other) const noexcept
646{
647 auto op = dynamic_cast<const FBinaryOperation *>(&other);
648 return op && op->fpop() == fpop() && op->size() == size();
649}
650
651std::string
653{
654 static std::unordered_map<llvm::fpop, std::string> map({ { fpop::add, "add" },
655 { fpop::sub, "sub" },
656 { fpop::mul, "mul" },
657 { fpop::div, "div" },
658 { fpop::mod, "mod" } });
659
660 JLM_ASSERT(map.find(fpop()) != map.end());
661 return "FPOP " + map[fpop()];
662}
663
664std::unique_ptr<rvsdg::Operation>
666{
667 return std::make_unique<FBinaryOperation>(*this);
668}
669
676
685
686std::optional<std::vector<rvsdg::Output *>>
688 const FBinaryOperation & operation,
689 const std::vector<rvsdg::Output *> & operands)
690{
691 JLM_ASSERT(operands.size() == 2);
692 auto & operand1 = *operands[0];
693 auto & operand2 = *operands[1];
694
695 const auto & tracedOperand1 = llvm::traceOutput(operand1, false);
696 auto [c1Node, c1Operation] = rvsdg::TryGetSimpleNodeAndOptionalOp<ConstantFP>(tracedOperand1);
697 if (!c1Operation)
698 return std::nullopt;
699
700 const auto & tracedOperand2 = llvm::traceOutput(operand2, false);
701 auto [c2Node, c2Operation] = rvsdg::TryGetSimpleNodeAndOptionalOp<ConstantFP>(tracedOperand2);
702 if (!c2Operation)
703 return std::nullopt;
704
705 auto c1Representation = c1Operation->constant();
706 const auto & c2Representation = c2Operation->constant();
707
708 switch (operation.fpop())
709 {
710 case fpop::add:
711 return outputs(&ConstantFP::createNode(
712 *operand1.region(),
713 operation.size(),
714 c1Representation + c2Representation));
715 case fpop::sub:
716 return outputs(&ConstantFP::createNode(
717 *operand1.region(),
718 operation.size(),
719 c1Representation - c2Representation));
720 case fpop::mul:
721 return outputs(&ConstantFP::createNode(
722 *operand1.region(),
723 operation.size(),
724 c1Representation * c2Representation));
725 case fpop::div:
726 return outputs(&ConstantFP::createNode(
727 *operand1.region(),
728 operation.size(),
729 c1Representation / c2Representation));
730 case fpop::mod:
731 c1Representation.mod(c2Representation);
732 return outputs(&ConstantFP::createNode(*operand1.region(), operation.size(), c1Representation));
733 default:
734 throw std::logic_error("Unsupported floating-point operation");
735 }
736}
737
738FNegOperation::~FNegOperation() noexcept = default;
739
740bool
741FNegOperation::operator==(const Operation & other) const noexcept
742{
743 const auto op = dynamic_cast<const FNegOperation *>(&other);
744 return op && op->size() == size();
745}
746
747std::string
749{
750 return "FNeg";
751}
752
753std::unique_ptr<rvsdg::Operation>
755{
756 return std::make_unique<FNegOperation>(*this);
757}
758
760
761bool
762VariadicArgumentListOperation::operator==(const Operation & other) const noexcept
763{
764 auto op = dynamic_cast<const VariadicArgumentListOperation *>(&other);
765 if (!op || op->narguments() != narguments())
766 return false;
767
768 for (size_t n = 0; n < narguments(); n++)
769 {
770 if (op->argument(n) != argument(n))
771 return false;
772 }
773
774 return true;
775}
776
777std::string
779{
780 return "VariadicArguments";
781}
782
783std::unique_ptr<rvsdg::Operation>
785{
786 return std::make_unique<VariadicArgumentListOperation>(*this);
787}
788
790
791bool
792ConstantStructOperation::operator==(const Operation & other) const noexcept
793{
794 auto op = dynamic_cast<const ConstantStructOperation *>(&other);
795 return op && op->result(0) == result(0);
796}
797
798std::string
800{
801 const auto name = type().IsLiteral() ? "" : type().GetName();
802 return util::strfmt("ConstantStruct[", name, "]");
803}
804
805std::unique_ptr<rvsdg::Operation>
807{
808 return std::make_unique<ConstantStructOperation>(*this);
809}
810
812
813bool
814ConstantArrayOperation::operator==(const Operation & other) const noexcept
815{
816 const auto op = dynamic_cast<const ConstantArrayOperation *>(&other);
817 return op && op->result(0) == result(0);
818}
819
820std::string
822{
823 return "ConstantArray";
824}
825
826std::unique_ptr<rvsdg::Operation>
828{
829 return std::make_unique<ConstantArrayOperation>(*this);
830}
831
833
834bool
835ConstantAggregateZeroOperation::operator==(const Operation & other) const noexcept
836{
837 const auto op = dynamic_cast<const ConstantAggregateZeroOperation *>(&other);
838 return op && op->result(0) == result(0);
839}
840
841std::string
843{
844 return "ConstantAggregateZero";
845}
846
847std::unique_ptr<rvsdg::Operation>
849{
850 return std::make_unique<ConstantAggregateZeroOperation>(*this);
851}
852
854
855bool
856ExtractElementOperation::operator==(const Operation & other) const noexcept
857{
858 auto op = dynamic_cast<const ExtractElementOperation *>(&other);
859 return op && op->argument(0) == argument(0) && op->argument(1) == argument(1);
860}
861
862std::string
864{
865 return "ExtractElement";
866}
867
868std::unique_ptr<rvsdg::Operation>
870{
871 return std::make_unique<ExtractElementOperation>(*this);
872}
873
875
876bool
877ShuffleVectorOperation::operator==(const Operation & other) const noexcept
878{
879 auto op = dynamic_cast<const ShuffleVectorOperation *>(&other);
880 return op && op->argument(0) == argument(0) && op->Mask() == Mask();
881}
882
883std::string
885{
886 return "ShuffleVector";
887}
888
889std::unique_ptr<rvsdg::Operation>
891{
892 return std::make_unique<ShuffleVectorOperation>(*this);
893}
894
896
897bool
898ConstantVectorOperation::operator==(const Operation & other) const noexcept
899{
900 auto op = dynamic_cast<const ConstantVectorOperation *>(&other);
901 return op && op->result(0) == result(0);
902}
903
904std::string
906{
907 return "ConstantVector";
908}
909
910std::unique_ptr<rvsdg::Operation>
912{
913 return std::make_unique<ConstantVectorOperation>(*this);
914}
915
917
918bool
919InsertElementOperation::operator==(const Operation & other) const noexcept
920{
921 auto op = dynamic_cast<const InsertElementOperation *>(&other);
922 return op && op->argument(0) == argument(0) && op->argument(1) == argument(1)
923 && op->argument(2) == argument(2);
924}
925
926std::string
928{
929 return "InsertElement";
930}
931
932std::unique_ptr<rvsdg::Operation>
934{
935 return std::make_unique<InsertElementOperation>(*this);
936}
937
939
940bool
941VectorUnaryOperation::operator==(const Operation & other) const noexcept
942{
943 auto op = dynamic_cast<const VectorUnaryOperation *>(&other);
944 return op && op->operation() == operation();
945}
946
947std::string
949{
950 return util::strfmt("Vector", operation().debug_string());
951}
952
953std::unique_ptr<rvsdg::Operation>
955{
956 return std::make_unique<VectorUnaryOperation>(*this);
957}
958
960
961bool
962VectorBinaryOperation::operator==(const Operation & other) const noexcept
963{
964 auto op = dynamic_cast<const VectorBinaryOperation *>(&other);
965 return op && op->operation() == operation();
966}
967
968std::string
970{
971 return util::strfmt("Vector", operation().debug_string());
972}
973
974std::unique_ptr<rvsdg::Operation>
976{
977 return std::make_unique<VectorBinaryOperation>(*this);
978}
979
981
982bool
983ConstantDataVectorOperation::operator==(const Operation & other) const noexcept
984{
985 auto op = dynamic_cast<const ConstantDataVectorOperation *>(&other);
986 return op && op->result(0) == result(0);
987}
988
989std::string
991{
992 return "ConstantDataVector";
993}
994
995std::unique_ptr<rvsdg::Operation>
997{
998 return std::make_unique<ConstantDataVectorOperation>(*this);
999}
1000
1001MallocOperation::~MallocOperation() noexcept = default;
1002
1003bool
1004MallocOperation::operator==(const Operation & other) const noexcept
1005{
1006 // Avoid CNE for malloc operator
1007 return this == &other;
1008}
1009
1010std::string
1012{
1013 return "Malloc";
1014}
1015
1016std::unique_ptr<rvsdg::Operation>
1018{
1019 return std::make_unique<MallocOperation>(*this);
1020}
1021
1022/* free operator */
1023
1024FreeOperation::~FreeOperation() noexcept = default;
1025
1026bool
1027FreeOperation::operator==(const Operation & other) const noexcept
1028{
1029 // Avoid CNE for free operator
1030 return this == &other;
1031}
1032
1033std::string
1035{
1036 return "FREE";
1037}
1038
1039std::unique_ptr<rvsdg::Operation>
1041{
1042 return std::make_unique<FreeOperation>(*this);
1043}
1044}
std::unique_ptr< Operation > copy() const override
Definition operators.cpp:69
~AssignmentOperation() noexcept override
std::string debug_string() const override
Definition operators.cpp:63
std::string debug_string() const override
~BranchOperation() noexcept override
std::unique_ptr< Operation > copy() const override
std::unique_ptr< Operation > copy() const override
~ConstantAggregateZeroOperation() noexcept override
std::string debug_string() const override
~ConstantArrayOperation() noexcept override
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
~ConstantDataArrayOperation() noexcept override
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
~ConstantDataVectorOperation() noexcept override
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
~ConstantFP() noexcept override
static rvsdg::Node & createNode(rvsdg::Region &region, fpsize size, const ::llvm::APFloat &constant)
const fpsize & size() const noexcept
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
const ::llvm::APFloat & constant() const noexcept
ConstantPointerNullOperation class.
std::string debug_string() const override
~ConstantPointerNullOperation() noexcept override
std::unique_ptr< Operation > copy() const override
std::unique_ptr< Operation > copy() const override
~ConstantStructOperation() noexcept override
std::string debug_string() const override
const StructType & type() const noexcept
std::unique_ptr< Operation > copy() const override
~ConstantVectorOperation() noexcept override
std::string debug_string() const override
std::string debug_string() const override
~ExtractElementOperation() noexcept override
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
jlm::rvsdg::binop_reduction_path_t can_reduce_operand_pair(const jlm::rvsdg::Output *op1, const jlm::rvsdg::Output *op2) const noexcept override
const llvm::fpop & fpop() const noexcept
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const FBinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
const fpsize & size() const noexcept
jlm::rvsdg::Output * reduce_operand_pair(jlm::rvsdg::binop_reduction_path_t path, jlm::rvsdg::Output *op1, jlm::rvsdg::Output *op2) const override
~FBinaryOperation() noexcept override
const fpcmp & cmp() const noexcept
jlm::rvsdg::binop_reduction_path_t can_reduce_operand_pair(const jlm::rvsdg::Output *op1, const jlm::rvsdg::Output *op2) const noexcept override
~FCmpOperation() noexcept override
std::string debug_string() const override
jlm::rvsdg::Output * reduce_operand_pair(jlm::rvsdg::binop_reduction_path_t path, jlm::rvsdg::Output *op1, jlm::rvsdg::Output *op2) const override
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const FCmpOperation &operation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
~FNegOperation() noexcept override
std::string debug_string() const override
const fpsize & size() const noexcept
std::unique_ptr< Operation > copy() const override
~FreeOperation() noexcept override
std::string debug_string() const override
FreezeOperation class.
std::string debug_string() const override
~FreezeOperation() noexcept override
std::unique_ptr< Operation > copy() const override
const jlm::rvsdg::Type & getType() const noexcept
std::string debug_string() const override
~InsertElementOperation() noexcept override
std::unique_ptr< Operation > copy() const override
static rvsdg::Node & Create(rvsdg::Region &region, IntegerValueRepresentation representation)
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
~MallocOperation() noexcept override
PoisonValueOperation class.
~PoisonValueOperation() noexcept override
const jlm::rvsdg::Type & GetType() const noexcept
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
~PtrCmpOperation() noexcept override
ICmpPredicate predicate() const noexcept
jlm::rvsdg::binop_reduction_path_t can_reduce_operand_pair(const jlm::rvsdg::Output *op1, const jlm::rvsdg::Output *op2) const noexcept override
std::string debug_string() const override
jlm::rvsdg::Output * reduce_operand_pair(jlm::rvsdg::binop_reduction_path_t path, jlm::rvsdg::Output *op1, jlm::rvsdg::Output *op2) const override
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const PtrCmpOperation &ptrCmpOperation, const std::vector< rvsdg::Output * > &operands)
std::unique_ptr< Operation > copy() const override
static std::optional< std::vector< rvsdg::Output * > > normalizeNullPointerComparison(const PtrCmpOperation &ptrCmpOperation, const std::vector< rvsdg::Output * > &operands)
std::string debug_string() const override
Definition operators.cpp:84
std::unique_ptr< Operation > copy() const override
Definition operators.cpp:90
~SelectOperation() noexcept override
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
~ShuffleVectorOperation() noexcept override
ControlFlowGraphNode * GetIncomingNode(size_t n) const noexcept
Definition operators.hpp:70
std::string debug_string() const override
Definition operators.cpp:33
std::unique_ptr< Operation > copy() const override
Definition operators.cpp:48
~SsaPhiOperation() noexcept override
std::vector< ControlFlowGraphNode * > IncomingNodes_
Definition operators.hpp:94
bool IsLiteral() const noexcept
Definition types.hpp:284
const std::string & GetName() const noexcept
Definition types.hpp:266
UndefValueOperation class.
~UndefValueOperation() noexcept override
std::string debug_string() const override
const rvsdg::Type & GetType() const noexcept
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
~VariadicArgumentListOperation() noexcept override
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
const rvsdg::BinaryOperation & operation() const noexcept
~VectorBinaryOperation() noexcept override
std::unique_ptr< Operation > copy() const override
std::string debug_string() const override
const rvsdg::Type & type() const noexcept
~VectorSelectOperation() noexcept override
~VectorUnaryOperation() noexcept override
std::string debug_string() const override
const rvsdg::UnaryOperation & operation() const noexcept
std::unique_ptr< Operation > copy() const override
const std::shared_ptr< const rvsdg::Type > & argument(size_t index) const noexcept
Definition operation.cpp:23
const std::shared_ptr< const rvsdg::Type > & result(size_t index) const noexcept
Definition operation.cpp:36
size_t narguments() const noexcept
Definition operation.cpp:17
#define JLM_ASSERT(x)
Definition common.hpp:16
#define JLM_UNREACHABLE(msg)
Definition common.hpp:43
Global memory state passed between functions.
ICmpPredicate convertICmpPredicateToJlm(::llvm::CmpInst::Predicate predicate)
std::string_view iCmpPredicateToString(ICmpPredicate predicate)
rvsdg::Output & traceOutput(rvsdg::Output &output, bool mayEnterSubregions, const rvsdg::Region *withinRegion)
Definition Trace.cpp:84
static bool isOutputOf(rvsdg::Output &operand)
static const util::BijectiveMap<::llvm::CmpInst::Predicate, ICmpPredicate > & getICmpPredicateMap()
static bool isAllocationSide(rvsdg::Output &output)
::llvm::CmpInst::Predicate convertICmpPredicateToLlvm(ICmpPredicate predicate)
Output & traceOutput(Output &output, bool mayEnterSubregions, const Region *withinRegion)
Definition Trace.cpp:454
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
Definition node.hpp:1058
size_t binop_reduction_path_t
Definition binary.hpp:19
Output & traceOutputIntraProcedurally(Output &output, bool mayEnterSubregions)
Definition Trace.cpp:442
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