16#include <llvm/ADT/SmallVector.h>
17#include <llvm/IR/InstrTypes.h>
29 return op && op->
IncomingNodes_ == IncomingNodes_ && op->result(0) == result(0);
47std::unique_ptr<rvsdg::Operation>
50 return std::make_unique<SsaPhiOperation>(*
this);
59 return op && op->
argument(0) == argument(0);
68std::unique_ptr<rvsdg::Operation>
71 return std::make_unique<AssignmentOperation>(*
this);
80 return op && op->
result(0) == result(0);
89std::unique_ptr<rvsdg::Operation>
92 return std::make_unique<SelectOperation>(*
this);
101 return op && op->
type() == type();
107 return "VectorSelect";
110std::unique_ptr<rvsdg::Operation>
113 return std::make_unique<VectorSelectOperation>(*
this);
122 return op && op->
argument(0) == argument(0);
131std::unique_ptr<rvsdg::Operation>
134 return std::make_unique<BranchOperation>(*
this);
148 return "ConstantPointerNull";
151std::unique_ptr<rvsdg::Operation>
154 return std::make_unique<ConstantPointerNullOperation>(*
this);
163 return op && op->
result(0) == result(0);
169 return "ConstantDataArray";
172std::unique_ptr<rvsdg::Operation>
175 return std::make_unique<ConstantDataArrayOperation>(*
this);
200 return map.LookupKey(predicate);
203[[nodiscard]] ::llvm::CmpInst::Predicate
207 return map.LookupValue(predicate);
210[[nodiscard]] std::string_view
236 throw std::runtime_error(
"Unknown ICmpPredicate");
246 return op && op->
argument(0) == argument(0) && op->predicate_ == predicate_;
255std::unique_ptr<rvsdg::Operation>
258 return std::make_unique<PtrCmpOperation>(*
this);
277template<
typename TOperation>
282 return operation !=
nullptr;
288 if (isOutputOf<AllocaOperation>(output))
303 auto [fnToPtrNode, fnToPtrOperation] =
305 if (fnToPtrOperation !=
nullptr)
307 const auto & tracedOutput =
318std::optional<std::vector<rvsdg::Output *>>
321 const std::vector<rvsdg::Output *> & operands)
331 if (isOutputOf<ConstantPointerNullOperation>(tracedOperand1)
332 && isOutputOf<ConstantPointerNullOperation>(tracedOperand2))
334 auto & region = *operands[0]->region();
342 throw std::logic_error(
"Unhandled predicate!");
346 const bool hasRequiredOperands =
347 (isOutputOf<ConstantPointerNullOperation>(tracedOperand1) &&
isAllocationSide(tracedOperand2))
348 || (isOutputOf<ConstantPointerNullOperation>(tracedOperand2)
350 if (hasRequiredOperands)
352 auto & region = *operands[0]->region();
360 throw std::logic_error(
"Unhandled predicate!");
367std::optional<std::vector<rvsdg::Output *>>
370 const std::vector<rvsdg::Output *> & operands)
373 auto & operand1 = operands[0];
374 auto & operand2 = operands[1];
378 if (&tracedOperand1 != &tracedOperand2)
397 throw std::logic_error(
"Unhandled predicate!");
404ConstantFP::operator==(const Operation & other) const noexcept
406 auto op =
dynamic_cast<const ConstantFP *
>(&other);
407 return op && size() == op->
size() && constant().bitwiseIsEqual(op->constant());
413 ::llvm::SmallVector<char, 32> v;
416 std::string s(
"FP(");
417 for (
const auto & c : v)
424std::unique_ptr<rvsdg::Operation>
427 return std::make_unique<ConstantFP>(*
this);
436 return op && op->
argument(0) == argument(0) && op->cmp_ == cmp_;
442 static std::unordered_map<fpcmp, std::string> map({ {
fpcmp::oeq,
"oeq" },
458 return "FCmp " + map[
cmp()];
461std::unique_ptr<rvsdg::Operation>
464 return std::make_unique<FCmpOperation>(*
this);
480std::optional<std::vector<rvsdg::Output *>>
483 const std::vector<rvsdg::Output *> & operands)
486 auto & operand1 = *operands[0];
487 auto & operand2 = *operands[1];
500 auto & c1Representation = c1Operation->constant();
501 auto & c2Representation = c2Operation->constant();
502 const auto cmpResult = c1Representation.compare(c2Representation);
504 bool boolResult =
false;
505 switch (operation.
cmp())
515 boolResult = (cmpResult == ::llvm::APFloat::cmpEqual);
518 boolResult = (cmpResult == ::llvm::APFloat::cmpGreaterThan);
522 (cmpResult == ::llvm::APFloat::cmpGreaterThan || cmpResult == ::llvm::APFloat::cmpEqual);
525 boolResult = (cmpResult == ::llvm::APFloat::cmpLessThan);
529 (cmpResult == ::llvm::APFloat::cmpLessThan || cmpResult == ::llvm::APFloat::cmpEqual);
533 (cmpResult == ::llvm::APFloat::cmpLessThan || cmpResult == ::llvm::APFloat::cmpGreaterThan);
536 boolResult = (cmpResult != ::llvm::APFloat::cmpUnordered);
540 boolResult = (cmpResult == ::llvm::APFloat::cmpUnordered);
544 (cmpResult == ::llvm::APFloat::cmpUnordered || cmpResult == ::llvm::APFloat::cmpEqual);
548 (cmpResult == ::llvm::APFloat::cmpUnordered
549 || cmpResult == ::llvm::APFloat::cmpGreaterThan);
553 (cmpResult == ::llvm::APFloat::cmpUnordered || cmpResult == ::llvm::APFloat::cmpGreaterThan
554 || cmpResult == ::llvm::APFloat::cmpEqual);
558 (cmpResult == ::llvm::APFloat::cmpUnordered || cmpResult == ::llvm::APFloat::cmpLessThan);
562 (cmpResult == ::llvm::APFloat::cmpUnordered || cmpResult == ::llvm::APFloat::cmpLessThan
563 || cmpResult == ::llvm::APFloat::cmpEqual);
566 boolResult = (cmpResult != ::llvm::APFloat::cmpEqual);
570 throw std::logic_error(
"Invalid FCmp operation");
576 return std::vector<rvsdg::Output *>({
result });
585 return op && op->
GetType() == GetType();
594std::unique_ptr<rvsdg::Operation>
597 return std::make_unique<UndefValueOperation>(*
this);
606 return operation && operation->
GetType() == GetType();
615std::unique_ptr<rvsdg::Operation>
618 return std::make_unique<PoisonValueOperation>(*
this);
627 return operation && operation->
getType() == getType();
636std::unique_ptr<rvsdg::Operation>
639 return std::make_unique<FreezeOperation>(*
this);
648 return op && op->
fpop() ==
fpop() && op->size() == size();
654 static std::unordered_map<llvm::fpop, std::string> map({ {
fpop::add,
"add" },
661 return "FPOP " + map[
fpop()];
664std::unique_ptr<rvsdg::Operation>
667 return std::make_unique<FBinaryOperation>(*
this);
686std::optional<std::vector<rvsdg::Output *>>
689 const std::vector<rvsdg::Output *> & operands)
692 auto & operand1 = *operands[0];
693 auto & operand2 = *operands[1];
705 auto c1Representation = c1Operation->constant();
706 const auto & c2Representation = c2Operation->constant();
708 switch (operation.
fpop())
714 c1Representation + c2Representation));
719 c1Representation - c2Representation));
724 c1Representation * c2Representation));
729 c1Representation / c2Representation));
731 c1Representation.mod(c2Representation);
734 throw std::logic_error(
"Unsupported floating-point operation");
744 return op && op->
size() == size();
753std::unique_ptr<rvsdg::Operation>
756 return std::make_unique<FNegOperation>(*
this);
765 if (!op || op->narguments() != narguments())
768 for (
size_t n = 0; n < narguments(); n++)
770 if (op->argument(n) != argument(n))
780 return "VariadicArguments";
783std::unique_ptr<rvsdg::Operation>
786 return std::make_unique<VariadicArgumentListOperation>(*
this);
795 return op && op->
result(0) == result(0);
805std::unique_ptr<rvsdg::Operation>
808 return std::make_unique<ConstantStructOperation>(*
this);
817 return op && op->
result(0) == result(0);
823 return "ConstantArray";
826std::unique_ptr<rvsdg::Operation>
829 return std::make_unique<ConstantArrayOperation>(*
this);
838 return op && op->
result(0) == result(0);
844 return "ConstantAggregateZero";
847std::unique_ptr<rvsdg::Operation>
850 return std::make_unique<ConstantAggregateZeroOperation>(*
this);
859 return op && op->
argument(0) == argument(0) && op->argument(1) == argument(1);
865 return "ExtractElement";
868std::unique_ptr<rvsdg::Operation>
871 return std::make_unique<ExtractElementOperation>(*
this);
880 return op && op->
argument(0) == argument(0) && op->Mask() == Mask();
886 return "ShuffleVector";
889std::unique_ptr<rvsdg::Operation>
892 return std::make_unique<ShuffleVectorOperation>(*
this);
901 return op && op->
result(0) == result(0);
907 return "ConstantVector";
910std::unique_ptr<rvsdg::Operation>
913 return std::make_unique<ConstantVectorOperation>(*
this);
922 return op && op->
argument(0) == argument(0) && op->argument(1) == argument(1)
923 && op->argument(2) == argument(2);
929 return "InsertElement";
932std::unique_ptr<rvsdg::Operation>
935 return std::make_unique<InsertElementOperation>(*
this);
944 return op && op->
operation() == operation();
953std::unique_ptr<rvsdg::Operation>
956 return std::make_unique<VectorUnaryOperation>(*
this);
965 return op && op->
operation() == operation();
974std::unique_ptr<rvsdg::Operation>
977 return std::make_unique<VectorBinaryOperation>(*
this);
986 return op && op->
result(0) == result(0);
992 return "ConstantDataVector";
995std::unique_ptr<rvsdg::Operation>
998 return std::make_unique<ConstantDataVectorOperation>(*
this);
1007 return this == &other;
1016std::unique_ptr<rvsdg::Operation>
1019 return std::make_unique<MallocOperation>(*
this);
1030 return this == &other;
1039std::unique_ptr<rvsdg::Operation>
1042 return std::make_unique<FreeOperation>(*
this);
std::unique_ptr< Operation > copy() const override
~AssignmentOperation() noexcept override
std::string debug_string() const override
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 ®ion, 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
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
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 ®ion, 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
std::unique_ptr< Operation > copy() const override
~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
std::string debug_string() const override
std::unique_ptr< Operation > copy() const override
~SsaPhiOperation() noexcept override
std::vector< ControlFlowGraphNode * > IncomingNodes_
bool IsLiteral() const noexcept
const std::string & GetName() const noexcept
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
const std::shared_ptr< const rvsdg::Type > & result(size_t index) const noexcept
size_t narguments() const noexcept
#define JLM_UNREACHABLE(msg)
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)
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)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
size_t binop_reduction_path_t
Output & traceOutputIntraProcedurally(Output &output, bool mayEnterSubregions)
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
static const binop_reduction_path_t binop_reduction_none
static std::string strfmt(Args... args)