23 #include <mlir/Parser/Parser.h>
24 #include <mlir/Transforms/TopologicalSortUtils.h>
29 std::unique_ptr<llvm::LlvmRvsdgModule>
32 auto config = ::mlir::ParserConfig(
Context_.get());
33 std::unique_ptr<::mlir::Block> block = std::make_unique<::mlir::Block>();
34 auto result = ::mlir::parseSourceFile(filePath.
to_str(), block.get(), config);
42 std::unique_ptr<llvm::LlvmRvsdgModule>
45 auto & topNode = block->front();
46 if (
auto module = ::mlir::dyn_cast<::mlir::ModuleOp>(topNode))
48 auto & newTopNode = module.getBodyRegion().front().front();
49 auto omegaNode = ::mlir::dyn_cast<::mlir::rvsdg::OmegaNode>(newTopNode);
52 JLM_UNREACHABLE(
"frontend : Top node in module op is not an OmegaNode.");
56 auto omegaNode = ::mlir::dyn_cast<::mlir::rvsdg::OmegaNode>(topNode);
64 std::unique_ptr<llvm::LlvmRvsdgModule>
69 auto & graph = rvsdgModule->Rvsdg();
70 auto & root = graph.GetRootRegion();
76 ::llvm::SmallVector<jlm::rvsdg::Output *>
85 ::llvm::SmallVector<jlm::rvsdg::Output *>
87 ::mlir::Operation & mlirOp,
88 const std::unordered_map<void *, rvsdg::Output *> & outputMap)
90 ::llvm::SmallVector<jlm::rvsdg::Output *> inputs;
91 for (::mlir::Value operand : mlirOp.getOperands())
93 auto key = operand.getAsOpaquePointer();
94 JLM_ASSERT(outputMap.find(key) != outputMap.end());
95 inputs.push_back(outputMap.at(key));
100 ::llvm::SmallVector<jlm::rvsdg::Output *>
103 ::mlir::sortTopologically(&block);
107 std::unordered_map<void *, rvsdg::Output *> outputMap;
109 for (
size_t i = 0; i < block.getNumArguments(); i++)
111 auto arg = block.getArgument(i);
112 auto key = arg.getAsOpaquePointer();
113 outputMap[key] = rvsdgRegion.
argument(i);
116 for (
auto & mlirOp : block.getOperations())
118 if (
auto argument = ::mlir::dyn_cast<::mlir::rvsdg::OmegaArgument>(mlirOp))
120 auto valueType = argument.getValueType();
121 auto importedType = argument.getImportedValue().getType();
126 *rvsdgRegion.
graph(),
129 argument.getNameAttr().cast<::mlir::StringAttr>().str(),
135 auto key = argument.getResult().getAsOpaquePointer();
136 outputMap[key] = &jlmArgument;
140 ::llvm::SmallVector<jlm::rvsdg::Output *> inputs =
GetConvertedInputs(mlirOp, outputMap);
144 for (
size_t i = 0; i < mlirOp.getNumResults(); i++)
146 auto result = mlirOp.getResult(i);
147 auto key = result.getAsOpaquePointer();
154 ::mlir::Operation * terminator = block.getTerminator();
161 ::mlir::arith::CmpIOp & CompOp,
162 const ::llvm::SmallVector<rvsdg::Output *> & inputs,
165 if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::eq)
167 return &rvsdg::CreateOpNode<jlm::llvm::IntegerEqOperation>({ inputs[0], inputs[1] }, nbits);
169 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::ne)
171 return &rvsdg::CreateOpNode<jlm::llvm::IntegerNeOperation>({ inputs[0], inputs[1] }, nbits);
173 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::sge)
175 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSgeOperation>({ inputs[0], inputs[1] }, nbits);
177 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::sgt)
179 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSgtOperation>({ inputs[0], inputs[1] }, nbits);
181 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::sle)
183 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSleOperation>({ inputs[0], inputs[1] }, nbits);
185 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::slt)
187 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSltOperation>({ inputs[0], inputs[1] }, nbits);
189 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::uge)
191 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUgeOperation>({ inputs[0], inputs[1] }, nbits);
193 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::ugt)
195 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUgtOperation>({ inputs[0], inputs[1] }, nbits);
197 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::ule)
199 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUleOperation>({ inputs[0], inputs[1] }, nbits);
201 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::ult)
203 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUltOperation>({ inputs[0], inputs[1] }, nbits);
213 ::mlir::LLVM::ICmpOp & operation,
215 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
217 if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::eq)
219 auto newOp = std::make_unique<llvm::PtrCmpOperation>(
225 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
227 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::ne)
229 auto newOp = std::make_unique<llvm::PtrCmpOperation>(
235 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
237 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::sge)
239 auto newOp = std::make_unique<llvm::PtrCmpOperation>(
245 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
247 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::sgt)
249 auto newOp = std::make_unique<llvm::PtrCmpOperation>(
255 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
257 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::sle)
259 auto newOp = std::make_unique<llvm::PtrCmpOperation>(
265 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
267 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::slt)
269 auto newOp = std::make_unique<llvm::PtrCmpOperation>(
275 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
285 const ::mlir::Operation & mlirOperation,
286 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
288 if (inputs.size() != 2)
292 if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::AddFOp>(&mlirOperation))
295 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
297 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::SubFOp>(&mlirOperation))
300 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
302 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::MulFOp>(&mlirOperation))
305 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
307 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::DivFOp>(&mlirOperation))
310 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
312 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::RemFOp>(&mlirOperation))
315 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
321 return &rvsdg::CreateOpNode<llvm::FBinaryOperation>({ inputs[0], inputs[1] }, op, size);
328 return map.LookupKey(op);
333 ::mlir::Operation & mlirOperation,
334 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
336 if (inputs.size() != 2 || mlirOperation.getNumResults() != 1)
339 auto type = mlirOperation.getResult(0).getType();
342 if (type.isa<::mlir::IntegerType>())
344 auto integerType = type.cast<::mlir::IntegerType>();
345 width = integerType.getWidth();
347 else if (type.isIndex())
356 if (::mlir::isa<::mlir::arith::AddIOp>(mlirOperation))
358 return &rvsdg::CreateOpNode<jlm::llvm::IntegerAddOperation>({ inputs[0], inputs[1] }, width);
360 else if (::mlir::isa<::mlir::arith::SubIOp>(mlirOperation))
362 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSubOperation>({ inputs[0], inputs[1] }, width);
364 else if (::mlir::isa<::mlir::arith::MulIOp>(mlirOperation))
366 return &rvsdg::CreateOpNode<jlm::llvm::IntegerMulOperation>({ inputs[0], inputs[1] }, width);
368 else if (::mlir::isa<::mlir::arith::DivSIOp>(mlirOperation))
370 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSDivOperation>({ inputs[0], inputs[1] }, width);
372 else if (::mlir::isa<::mlir::arith::DivUIOp>(mlirOperation))
374 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUDivOperation>({ inputs[0], inputs[1] }, width);
376 else if (::mlir::isa<::mlir::arith::RemSIOp>(mlirOperation))
378 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSRemOperation>({ inputs[0], inputs[1] }, width);
380 else if (::mlir::isa<::mlir::arith::RemUIOp>(mlirOperation))
382 return &rvsdg::CreateOpNode<jlm::llvm::IntegerURemOperation>({ inputs[0], inputs[1] }, width);
384 else if (::mlir::isa<::mlir::LLVM::ShlOp>(mlirOperation))
386 return &rvsdg::CreateOpNode<jlm::llvm::IntegerShlOperation>({ inputs[0], inputs[1] }, width);
388 else if (::mlir::isa<::mlir::LLVM::AShrOp>(mlirOperation))
390 return &rvsdg::CreateOpNode<jlm::llvm::IntegerAShrOperation>({ inputs[0], inputs[1] }, width);
392 else if (::mlir::isa<::mlir::LLVM::LShrOp>(mlirOperation))
394 return &rvsdg::CreateOpNode<jlm::llvm::IntegerLShrOperation>({ inputs[0], inputs[1] }, width);
396 else if (::mlir::isa<::mlir::arith::AndIOp>(mlirOperation))
398 return &rvsdg::CreateOpNode<jlm::llvm::IntegerAndOperation>({ inputs[0], inputs[1] }, width);
400 else if (::mlir::isa<::mlir::arith::OrIOp>(mlirOperation))
402 return &rvsdg::CreateOpNode<jlm::llvm::IntegerOrOperation>({ inputs[0], inputs[1] }, width);
404 else if (::mlir::isa<::mlir::arith::XOrIOp>(mlirOperation))
406 return &rvsdg::CreateOpNode<jlm::llvm::IntegerXorOperation>({ inputs[0], inputs[1] }, width);
414 static std::vector<llvm::MemoryNodeId>
417 std::vector<llvm::MemoryNodeId> memoryNodeIds;
418 for (
auto memoryNodeId : arrayAttr)
420 memoryNodeIds.push_back(memoryNodeId.cast<::mlir::IntegerAttr>().getInt());
422 return memoryNodeIds;
425 std::vector<jlm::rvsdg::Output *>
427 ::mlir::Operation & mlirOperation,
429 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
435 if (convertedBitBinaryNode)
444 if (convertedFloatBinaryNode)
449 if (::mlir::isa<::mlir::LLVM::FMulAddOp>(&mlirOperation))
457 if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::ExtUIOp>(&mlirOperation))
459 auto st = std::dynamic_pointer_cast<const rvsdg::BitType>(inputs[0]->Type());
462 ::mlir::Type type = castedOp.getType();
465 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::ExtSIOp>(&mlirOperation))
467 auto outputType = castedOp.getOut().getType();
468 auto convertedOutputType =
ConvertType(outputType);
469 if (!::mlir::isa<::mlir::IntegerType>(castedOp.getType()))
472 castedOp.getType().cast<::mlir::IntegerType>().getWidth(),
475 else if (
auto sitofpOp = ::mlir::dyn_cast<::mlir::arith::SIToFPOp>(&mlirOperation))
477 auto st = std::dynamic_pointer_cast<const jlm::rvsdg::BitType>(inputs[0]->Type());
481 auto mlirOutputType = sitofpOp.getType();
484 return rvsdg::outputs(&rvsdg::CreateOpNode<llvm::SIToFPOperation>(
485 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()),
490 else if (::mlir::isa<::mlir::rvsdg::OmegaNode>(&mlirOperation))
495 else if (::mlir::isa<::mlir::rvsdg::LambdaNode>(&mlirOperation))
499 else if (
auto callOp = ::mlir::dyn_cast<::mlir::jlm::Call>(&mlirOperation))
501 std::vector<std::shared_ptr<const rvsdg::Type>> argumentTypes;
502 for (
auto arg : callOp.getArgs())
504 auto type = arg.getType();
510 std::vector<std::shared_ptr<const rvsdg::Type>> resultTypes;
511 for (
auto res : callOp.getResults())
513 auto type = res.getType();
517 if (inputs.size() != 1 + argumentTypes.size())
518 throw std::runtime_error(
"Function call should take target and parameters as input");
521 const auto target = inputs[0];
522 const auto arguments = std::vector(std::next(inputs.begin()), inputs.end());
525 std::move(functionType),
531 else if (
auto constant = ::mlir::dyn_cast<::mlir::arith::ConstantIntOp>(&mlirOperation))
533 auto type = constant.getType();
534 JLM_ASSERT(type.getTypeID() == ::mlir::IntegerType::getTypeID());
535 auto integerType = ::mlir::cast<::mlir::IntegerType>(type);
539 integerType.getWidth(),
542 else if (
auto constant = ::mlir::dyn_cast<::mlir::arith::ConstantFloatOp>(&mlirOperation))
544 auto type = constant.getType();
545 if (!::mlir::isa<::mlir::FloatType>(type))
547 auto floatType = ::mlir::cast<::mlir::FloatType>(type);
551 &rvsdg::CreateOpNode<llvm::ConstantFP>(rvsdgRegion, size, constant.value()));
556 else if (
auto constant = ::mlir::dyn_cast<::mlir::arith::ConstantIndexOp>(&mlirOperation))
558 auto type = constant.getType();
559 JLM_ASSERT(type.getTypeID() == ::mlir::IndexType::getTypeID());
566 else if (
auto indexCast = ::mlir::dyn_cast<::mlir::arith::IndexCastOp>(&mlirOperation))
568 auto outputType = indexCast.getResult().getType();
569 auto inputType = indexCast.getIn().getType();
570 unsigned inputBits = inputType.getIntOrFloatBitWidth();
571 unsigned outputBits = outputType.getIntOrFloatBitWidth();
573 if (inputType.isIndex())
578 return { inputs.begin(), inputs.end() };
594 return { inputs.begin(), inputs.end() };
609 else if (
auto negOp = ::mlir::dyn_cast<::mlir::arith::NegFOp>(&mlirOperation))
611 auto type = negOp.getResult().getType();
612 auto floatType = ::mlir::cast<::mlir::FloatType>(type);
615 return rvsdg::outputs(&rvsdg::CreateOpNode<jlm::llvm::FNegOperation>({ inputs[0] }, size));
618 else if (
auto extOp = ::mlir::dyn_cast<::mlir::arith::ExtFOp>(&mlirOperation))
620 auto type = extOp.getResult().getType();
621 auto floatType = ::mlir::cast<::mlir::FloatType>(type);
624 return rvsdg::outputs(&rvsdg::CreateOpNode<jlm::llvm::FPExtOperation>(
630 else if (
auto truncOp = ::mlir::dyn_cast<::mlir::arith::TruncIOp>(&mlirOperation))
632 auto type = truncOp.getResult().getType();
633 auto intType = ::mlir::cast<::mlir::IntegerType>(type);
636 else if (
auto constant = ::mlir::dyn_cast<::mlir::arith::ConstantFloatOp>(&mlirOperation))
638 auto type = constant.getType();
639 auto floatType = ::mlir::cast<::mlir::FloatType>(type);
642 return rvsdg::outputs(&rvsdg::CreateOpNode<jlm::llvm::ConstantFP>({}, size, constant.value()));
646 else if (
auto ComOp = ::mlir::dyn_cast<::mlir::arith::CmpIOp>(&mlirOperation))
648 auto type = ComOp.getOperandTypes()[0];
649 if (type.isa<::mlir::IntegerType>())
651 auto integerType = ::mlir::cast<::mlir::IntegerType>(type);
654 else if (type.isIndex())
664 else if (
auto ComOp = ::mlir::dyn_cast<::mlir::arith::CmpFOp>(&mlirOperation))
666 auto type = ComOp.getOperandTypes()[0];
667 auto floatType = ::mlir::cast<::mlir::FloatType>(type);
669 std::vector(inputs.begin(), inputs.end()),
675 else if (
auto iComOp = ::mlir::dyn_cast<::mlir::LLVM::ICmpOp>(&mlirOperation))
680 else if (
auto UndefOp = ::mlir::dyn_cast<::mlir::jlm::Undef>(&mlirOperation))
682 auto type = UndefOp.getResult().getType();
687 else if (
auto ArrayOp = ::mlir::dyn_cast<::mlir::jlm::ConstantDataArray>(&mlirOperation))
692 else if (
auto ZeroOp = ::mlir::dyn_cast<::mlir::LLVM::ZeroOp>(&mlirOperation))
694 auto type = ZeroOp.getType();
696 if (::mlir::isa<::mlir::LLVM::LLVMPointerType>(type))
703 else if (
auto VarArgOp = ::mlir::dyn_cast<::mlir::jlm::CreateVarArgList>(&mlirOperation))
707 std::vector(inputs.begin(), inputs.end())) };
712 else if (
auto FreeOp = ::mlir::dyn_cast<::mlir::jlm::Free>(&mlirOperation))
715 std::vector(inputs.begin(), inputs.end()),
719 else if (
auto AllocaOp = ::mlir::dyn_cast<::mlir::jlm::Alloca>(&mlirOperation))
721 auto outputType = AllocaOp.getValueType();
727 if (!rvsdg::is<const rvsdg::BitType>(inputs[0]->Type()))
730 auto jlmBitType = std::dynamic_pointer_cast<const jlm::rvsdg::BitType>(inputs[0]->Type());
732 return rvsdg::outputs(&rvsdg::CreateOpNode<llvm::AllocaOperation>(
733 std::vector(inputs.begin(), inputs.end()),
736 AllocaOp.getAlignment()));
738 else if (
auto MemstateMergeOp = ::mlir::dyn_cast<::mlir::rvsdg::MemStateMerge>(&mlirOperation))
740 auto operands = std::vector(inputs.begin(), inputs.end());
744 auto LambdaEntryMemstateSplitOp =
745 ::mlir::dyn_cast<::mlir::rvsdg::LambdaEntryMemoryStateSplit>(&mlirOperation))
750 auto operands = std::vector(inputs.begin(), inputs.end());
753 std::move(memoryNodeIds)));
755 if (
auto LambdaExitMemstateMergeOp =
756 ::mlir::dyn_cast<::mlir::rvsdg::LambdaExitMemoryStateMerge>(&mlirOperation))
761 auto operands = std::vector(inputs.begin(), inputs.end());
765 std::move(memoryNodeIds)));
768 auto CallEntryMemstateMergeOp =
769 ::mlir::dyn_cast<::mlir::rvsdg::CallEntryMemoryStateMerge>(&mlirOperation))
773 auto operands = std::vector(inputs.begin(), inputs.end());
777 std::move(memoryNodeIds)));
780 auto CallExitMemstateSplitOp =
781 ::mlir::dyn_cast<::mlir::rvsdg::CallExitMemoryStateSplit>(&mlirOperation))
785 auto operands = std::vector(inputs.begin(), inputs.end());
788 std::move(memoryNodeIds)));
790 else if (::mlir::isa<::mlir::rvsdg::MemoryStateJoin>(&mlirOperation))
792 std::vector
operands(inputs.begin(), inputs.end());
795 else if (
auto IOBarrierOp = ::mlir::dyn_cast<::mlir::jlm::IOBarrier>(&mlirOperation))
797 auto type = IOBarrierOp.getResult().getType();
798 return rvsdg::outputs(&rvsdg::CreateOpNode<llvm::IOBarrierOperation>(
799 std::vector(inputs.begin(), inputs.end()),
802 else if (
auto MallocOp = ::mlir::dyn_cast<::mlir::jlm::Malloc>(&mlirOperation))
806 else if (
auto StoreOp = ::mlir::dyn_cast<::mlir::jlm::Store>(&mlirOperation))
808 auto address = inputs[0];
809 auto value = inputs[1];
810 auto memoryStateInputs = std::vector(std::next(inputs.begin(), 2), inputs.end());
815 StoreOp.getAlignment()));
817 else if (
auto LoadOp = ::mlir::dyn_cast<::mlir::jlm::Load>(&mlirOperation))
819 auto address = inputs[0];
820 auto memoryStateInputs = std::vector(std::next(inputs.begin()), inputs.end());
821 auto outputType = LoadOp.getOutput().getType();
829 LoadOp.getAlignment()));
831 else if (
auto GepOp = ::mlir::dyn_cast<::mlir::LLVM::GEPOp>(&mlirOperation))
833 auto elemType = GepOp.getElemType();
838 std::vector<rvsdg::Output *> indices;
840 size_t dynamicInput = 1;
841 for (int32_t constant : GepOp.getRawConstantIndices())
844 if (constant == ::mlir::LLVM::GEPOp::kDynamicIndex)
846 indices.push_back(inputs[dynamicInput++]);
860 else if (
auto MlirCtrlConst = ::mlir::dyn_cast<::mlir::rvsdg::ConstantCtrl>(&mlirOperation))
862 JLM_ASSERT(::mlir::isa<::mlir::rvsdg::RVSDG_CTRLType>(MlirCtrlConst.getType()));
865 ::mlir::cast<::mlir::rvsdg::RVSDG_CTRLType>(MlirCtrlConst.getType()).getNumOptions(),
866 MlirCtrlConst.getValue()) };
868 else if (
auto mlirGammaNode = ::mlir::dyn_cast<::mlir::rvsdg::GammaNode>(&mlirOperation))
872 mlirGammaNode.getNumRegions()
876 for (
size_t i = 1; i < inputs.size(); i++)
878 rvsdgGammaNode->AddEntryVar(inputs[i]);
881 ::llvm::SmallVector<::llvm::SmallVector<jlm::rvsdg::Output *>> regionResults;
882 for (
size_t i = 0; i < mlirGammaNode.getNumRegions(); i++)
884 regionResults.push_back(
885 ConvertRegion(mlirGammaNode.getRegion(i), *rvsdgGammaNode->subregion(i)));
890 for (
size_t exitvarIndex = 0; exitvarIndex < regionResults[0].size(); exitvarIndex++)
892 std::vector<rvsdg::Output *> exitvars;
893 for (
size_t regionIndex = 0; regionIndex < mlirGammaNode.getNumRegions(); regionIndex++)
895 JLM_ASSERT(regionResults[regionIndex].size() == regionResults[0].size());
896 exitvars.push_back(regionResults[regionIndex][exitvarIndex]);
898 rvsdgGammaNode->AddExitVar(exitvars);
903 else if (
auto mlirThetaNode = ::mlir::dyn_cast<::mlir::rvsdg::ThetaNode>(&mlirOperation))
908 for (
size_t i = 0; i < inputs.size(); i++)
910 rvsdgThetaNode->AddLoopVar(inputs[i]);
913 auto regionResults =
ConvertRegion(mlirThetaNode.getRegion(), *rvsdgThetaNode->subregion());
915 rvsdgThetaNode->set_predicate(regionResults[0]);
917 auto loopvars = rvsdgThetaNode->GetLoopVars();
918 for (
size_t i = 1; i < regionResults.size(); i++)
920 loopvars[i - 1].post->divert_to(regionResults[i]);
925 else if (
auto mlirDeltaNode = ::mlir::dyn_cast<::mlir::rvsdg::DeltaNode>(&mlirOperation))
927 auto & deltaRegion = mlirDeltaNode.getRegion();
928 auto & deltaBlock = deltaRegion.front();
929 auto terminator = deltaBlock.getTerminator();
931 auto mlirOutputType = terminator->getOperand(0).getType();
933 auto linakgeString = mlirDeltaNode.getLinkage().str();
938 mlirDeltaNode.getName().str(),
940 mlirDeltaNode.getSection().str(),
941 mlirDeltaNode.getConstant(),
944 auto outputVector =
ConvertRegion(mlirDeltaNode.getRegion(), *rvsdgDeltaNode->subregion());
946 if (outputVector.size() != 1)
949 rvsdgDeltaNode->finalize(outputVector[0]);
953 else if (
auto mlirMatch = ::mlir::dyn_cast<::mlir::rvsdg::Match>(&mlirOperation))
955 std::unordered_map<uint64_t, uint64_t> mapping;
956 uint64_t defaultAlternative = 0;
957 for (
auto & attr : mlirMatch.getMapping())
959 JLM_ASSERT(attr.isa<::mlir::rvsdg::MatchRuleAttr>());
960 auto matchRuleAttr = attr.cast<::mlir::rvsdg::MatchRuleAttr>();
961 if (matchRuleAttr.isDefault())
963 defaultAlternative = matchRuleAttr.getIndex();
967 mapping[matchRuleAttr.getValues().front()] = matchRuleAttr.getIndex();
974 mlirMatch.getMapping().size()
977 else if (
auto selectOp = ::mlir::dyn_cast<::mlir::arith::SelectOp>(&mlirOperation))
979 auto type = selectOp.getType();
981 return rvsdg::outputs(&rvsdg::CreateOpNode<jlm::llvm::SelectOperation>(
982 std::vector(inputs.begin(), inputs.end()),
985 else if (
auto mlirOmegaResult = ::mlir::dyn_cast<::mlir::rvsdg::OmegaResult>(&mlirOperation))
987 for (
auto input : inputs)
989 auto origin = rvsdg::TryGetOwnerNode<rvsdg::Node>(*input);
997 auto op = util::assertedCast<const llvm::DeltaOperation>(&delta->GetOperation());
1006 ::mlir::isa<::mlir::rvsdg::LambdaResult>(&mlirOperation)
1007 || ::mlir::isa<::mlir::rvsdg::GammaResult>(&mlirOperation)
1008 || ::mlir::isa<::mlir::rvsdg::ThetaResult>(&mlirOperation)
1009 || ::mlir::isa<::mlir::rvsdg::DeltaResult>(&mlirOperation)
1011 || ::mlir::isa<::mlir::rvsdg::OmegaArgument>(&mlirOperation))
1017 mlirOperation.dump();
1019 "Operation not implemented: ",
1020 mlirOperation.getName().getStringRef().str(),
1042 auto message =
util::strfmt(
"Unsupported floating point size: ", size,
"\n");
1051 if (!stringValue.compare(
"external_linkage"))
1055 else if (!stringValue.compare(
"available_externally_linkage"))
1059 else if (!stringValue.compare(
"link_once_any_linkage"))
1063 else if (!stringValue.compare(
"link_once_odr_linkage"))
1067 else if (!stringValue.compare(
"weak_any_linkage"))
1071 else if (!stringValue.compare(
"weak_odr_linkage"))
1075 else if (!stringValue.compare(
"appending_linkage"))
1079 else if (!stringValue.compare(
"internal_linkage"))
1083 else if (!stringValue.compare(
"private_linkage"))
1087 else if (!stringValue.compare(
"external_weak_linkage"))
1091 else if (!stringValue.compare(
"common_linkage"))
1095 auto message =
util::strfmt(
"Unsupported linkage: ", stringValue,
"\n");
1101 ::mlir::Operation & mlirOperation,
1103 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
1106 auto functionNameAttribute = mlirOperation.getAttr(::llvm::StringRef(
"sym_name"));
1107 JLM_ASSERT(functionNameAttribute !=
nullptr);
1108 auto functionName = ::mlir::cast<::mlir::StringAttr>(functionNameAttribute);
1110 auto lambdaOp = ::mlir::dyn_cast<::mlir::rvsdg::LambdaNode>(&mlirOperation);
1111 auto & lambdaRegion = lambdaOp.getRegion();
1112 auto numNonContextVars = lambdaRegion.getNumArguments() - lambdaOp.getNumOperands();
1113 auto & lambdaBlock = lambdaRegion.front();
1114 auto lamdbaTerminator = lambdaBlock.getTerminator();
1117 std::vector<std::shared_ptr<const rvsdg::Type>> argumentTypes;
1118 for (
size_t argumentIndex = 0; argumentIndex < numNonContextVars; argumentIndex++)
1120 auto type = lambdaRegion.getArgument(argumentIndex).getType();
1123 std::vector<std::shared_ptr<const rvsdg::Type>> resultTypes;
1124 for (
auto returnType : lamdbaTerminator->getOperandTypes())
1136 functionName.getValue().str(),
1139 for (
auto input : inputs)
1141 rvsdgLambda->AddContextVar(*input);
1144 auto jlmLambdaRegion = rvsdgLambda->subregion();
1145 auto regionResults =
ConvertRegion(lambdaRegion, *jlmLambdaRegion);
1147 rvsdgLambda->finalize(std::vector<rvsdg::Output *>(regionResults.begin(), regionResults.end()));
1152 std::shared_ptr<const rvsdg::Type>
1155 if (
auto ctrlType = ::mlir::dyn_cast<::mlir::rvsdg::RVSDG_CTRLType>(type))
1159 else if (
auto intType = ::mlir::dyn_cast<::mlir::IntegerType>(type))
1163 else if (::mlir::isa<::mlir::Float16Type>(type))
1167 else if (::mlir::isa<::mlir::Float32Type>(type))
1171 else if (::mlir::isa<::mlir::Float64Type>(type))
1175 else if (::mlir::isa<::mlir::Float80Type>(type))
1179 else if (::mlir::isa<::mlir::Float128Type>(type))
1183 else if (::mlir::isa<::mlir::rvsdg::MemStateEdgeType>(type))
1187 else if (::mlir::isa<::mlir::rvsdg::IOStateEdgeType>(type))
1191 else if (::mlir::isa<::mlir::LLVM::LLVMPointerType>(type))
1195 else if (::mlir::isa<::mlir::jlm::VarargListType>(type))
1199 else if (
auto arrayType = ::mlir::dyn_cast<::mlir::LLVM::LLVMArrayType>(type))
1201 auto mlirElementType = arrayType.getElementType();
1202 std::shared_ptr<const rvsdg::Type> elementType =
ConvertType(mlirElementType);
1205 else if (
auto functionType = ::mlir::dyn_cast<::mlir::FunctionType>(type))
1207 std::vector<std::shared_ptr<const rvsdg::Type>> argumentTypes;
1208 for (
auto argumentType : functionType.getInputs())
1210 argumentTypes.push_back(
ConvertType(argumentType));
1212 std::vector<std::shared_ptr<const rvsdg::Type>> resultTypes;
1213 for (
auto resultType : functionType.getResults())
1219 else if (type.isIndex())
1224 else if (
auto structType = ::mlir::dyn_cast<::mlir::LLVM::LLVMStructType>(type))
1231 std::vector<std::shared_ptr<const rvsdg::Type>> types;
1232 for (
auto element : structType.getBody())
1237 std::shared_ptr<const llvm::StructType> jlmStructType;
1238 if (structType.isIdentified())
1241 structType.getName().str(),
1243 structType.isPacked());
1251 return jlmStructType;
static std::shared_ptr< const ArrayType > Create(std::shared_ptr< const Type > type, size_t nelements)
static AttributeList createEmptyList()
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands, std::vector< MemoryNodeId > memoryNodeIds)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, std::vector< MemoryNodeId > memoryNodeIds)
static std::vector< rvsdg::Output * > Create(rvsdg::Output *function, std::shared_ptr< const rvsdg::FunctionType > functionType, const std::vector< rvsdg::Output * > &arguments)
static jlm::rvsdg::Output * Create(rvsdg::Region ®ion, std::shared_ptr< const jlm::rvsdg::Type > type)
static jlm::rvsdg::Output * Create(const std::vector< jlm::rvsdg::Output * > &elements)
static std::unique_ptr< llvm::ThreeAddressCode > Create(std::shared_ptr< const rvsdg::Type > type)
static std::unique_ptr< DeltaOperation > Create(std::shared_ptr< const rvsdg::Type > type, const std::string &name, const Linkage &linkage, std::string section, bool constant, const size_t alignment)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &multiplier, rvsdg::Output &multiplicand, rvsdg::Output &summand)
static std::shared_ptr< const FloatingPointType > Create(fpsize size)
static rvsdg::Output * create(rvsdg::Output *baseAddress, const std::vector< rvsdg::Output * > &indices, std::shared_ptr< const rvsdg::Type > pointeeType)
static std::shared_ptr< const IOStateType > Create()
static rvsdg::Node & Create(rvsdg::Region ®ion, IntegerValueRepresentation representation)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &operand, std::vector< MemoryNodeId > memoryNodeIds)
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands, const std::vector< MemoryNodeId > &memoryNodeIds)
static LlvmGraphImport & create(rvsdg::Graph &graph, std::shared_ptr< const rvsdg::Type > valueType, std::shared_ptr< const rvsdg::Type > importedType, std::string name, Linkage linkage, CallingConvention callingConvention, const bool isConstant, const size_t alignment)
static std::unique_ptr< LlvmLambdaOperation > Create(std::shared_ptr< const jlm::rvsdg::FunctionType > type, std::string name, const jlm::llvm::Linkage &linkage, jlm::llvm::CallingConvention callingConvention, jlm::llvm::AttributeSet attributes)
static std::unique_ptr< LlvmRvsdgModule > Create(const util::FilePath &sourceFileName, const std::string &targetTriple, const std::string &dataLayout)
static rvsdg::SimpleNode & CreateNode(rvsdg::Region ®ion, std::unique_ptr< LoadNonVolatileOperation > loadOperation, const std::vector< rvsdg::Output * > &operands)
static rvsdg::SimpleNode & createNode(rvsdg::Output &size, rvsdg::Output &ioState)
static rvsdg::SimpleNode & CreateNode(const std::vector< rvsdg::Output * > &operands)
static rvsdg::Output * Create(const std::vector< rvsdg::Output * > &operands)
static std::shared_ptr< const MemoryStateType > Create()
static std::shared_ptr< const PointerType > Create()
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *operand, const std::shared_ptr< const rvsdg::Type > &type)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &address, rvsdg::Output &value, const std::vector< rvsdg::Output * > &memoryStates, size_t alignment)
static std::shared_ptr< const StructType > CreateIdentified(const std::string &name, std::vector< std::shared_ptr< const Type >> types, bool isPacked)
static std::shared_ptr< const StructType > CreateLiteral(std::vector< std::shared_ptr< const Type >> types, bool isPacked)
static std::unique_ptr< llvm::ThreeAddressCode > create(const Variable *operand, const std::shared_ptr< const jlm::rvsdg::Type > &type)
static jlm::rvsdg::Output * Create(rvsdg::Region ®ion, std::shared_ptr< const jlm::rvsdg::Type > type)
static std::shared_ptr< const VariableArgumentType > Create()
static rvsdg::Output * Create(rvsdg::Region ®ion, const std::vector< rvsdg::Output * > &operands)
static rvsdg::Output & Create(rvsdg::Output &operand, const std::shared_ptr< const rvsdg::Type > &resultType)
static ::llvm::SmallVector< jlm::rvsdg::Output * > GetConvertedInputs(::mlir::Operation &mlirOp, const std::unordered_map< void *, rvsdg::Output * > &outputMap)
std::unique_ptr<::mlir::MLIRContext > Context_
std::vector< jlm::rvsdg::Output * > ConvertOperation(::mlir::Operation &mlirOperation, rvsdg::Region &rvsdgRegion, const ::llvm::SmallVector< rvsdg::Output * > &inputs)
rvsdg::Node * ConvertFPBinaryNode(const ::mlir::Operation &mlirOperation, const ::llvm::SmallVector< rvsdg::Output * > &inputs)
static size_t GetIndexBitWidth()
rvsdg::Node * ConvertICmpOp(::mlir::LLVM::ICmpOp &operation, rvsdg::Region &rvsdgRegion, const ::llvm::SmallVector< rvsdg::Output * > &inputs)
rvsdg::Node * ConvertLambda(::mlir::Operation &mlirLambda, rvsdg::Region &rvsdgRegion, const ::llvm::SmallVector< rvsdg::Output * > &inputs)
llvm::fpsize ConvertFPSize(unsigned int size)
llvm::Linkage ConvertLinkage(std::string stringValue)
util::BijectiveMap<::mlir::LLVM::LLVMStructType *, std::shared_ptr< const llvm::StructType > > StructTypeMap_
std::unique_ptr< llvm::LlvmRvsdgModule > ReadAndConvertMlir(const util::FilePath &filePath)
jlm::llvm::fpcmp TryConvertFPCMP(const ::mlir::arith::CmpFPredicate &op)
rvsdg::Node * ConvertCmpIOp(::mlir::arith::CmpIOp &CompOp, const ::llvm::SmallVector< rvsdg::Output * > &inputs, size_t nbits)
::llvm::SmallVector< jlm::rvsdg::Output * > ConvertBlock(::mlir::Block &block, rvsdg::Region &rvsdgRegion)
std::unique_ptr< llvm::LlvmRvsdgModule > ConvertOmega(::mlir::rvsdg::OmegaNode &omegaNode)
::llvm::SmallVector< jlm::rvsdg::Output * > ConvertRegion(::mlir::Region ®ion, rvsdg::Region &rvsdgRegion)
std::shared_ptr< const rvsdg::Type > ConvertType(const ::mlir::Type &type)
std::unique_ptr< llvm::LlvmRvsdgModule > ConvertMlir(std::unique_ptr<::mlir::Block > &block)
rvsdg::Node * ConvertBitBinaryNode(::mlir::Operation &mlirOperation, const ::llvm::SmallVector< rvsdg::Output * > &inputs)
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
static Output & create(Region ®ion, ControlValueRepresentation value)
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
static DeltaNode * Create(rvsdg::Region *parent, std::unique_ptr< DeltaOperation > op)
static std::shared_ptr< const FunctionType > Create(std::vector< std::shared_ptr< const jlm::rvsdg::Type >> argumentTypes, std::vector< std::shared_ptr< const jlm::rvsdg::Type >> resultTypes)
static GammaNode * create(jlm::rvsdg::Output *predicate, size_t nalternatives)
static GraphExport & Create(Output &origin, std::string name)
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
static Output * Create(Output &predicate, const std::unordered_map< uint64_t, uint64_t > &mapping, const uint64_t defaultAlternative, const size_t numAlternatives)
Represent acyclic RVSDG subgraphs.
Graph * graph() const noexcept
RegionArgument * argument(size_t index) const noexcept
static SimpleNode & Create(Region ®ion, std::unique_ptr< Operation > operation, const std::vector< rvsdg::Output * > &operands)
static ThetaNode * create(rvsdg::Region *parent)
const std::string & to_str() const noexcept
#define JLM_UNREACHABLE(msg)
@ availableExternallyLinkage
Linkage linkageFromString(const std::string_view stringValue)
const util::BijectiveMap<::mlir::arith::CmpFPredicate, llvm::fpcmp > & GetFpCmpPredicateMap()
static std::vector< llvm::MemoryNodeId > arrayAttrToMemoryNodeIds(::mlir::ArrayAttr arrayAttr)
@ Value
Designate a value type.
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
static std::string strfmt(Args... args)