21 #include <mlir/Parser/Parser.h>
22 #include <mlir/Transforms/TopologicalSortUtils.h>
27 std::unique_ptr<llvm::LlvmRvsdgModule>
30 auto config = ::mlir::ParserConfig(
Context_.get());
31 std::unique_ptr<::mlir::Block> block = std::make_unique<::mlir::Block>();
32 auto result = ::mlir::parseSourceFile(filePath.
to_str(), block.get(), config);
40 std::unique_ptr<llvm::LlvmRvsdgModule>
43 auto & topNode = block->front();
44 if (
auto module = ::mlir::dyn_cast<::mlir::ModuleOp>(topNode))
46 auto & newTopNode = module.getBodyRegion().front().front();
47 auto omegaNode = ::mlir::dyn_cast<::mlir::rvsdg::OmegaNode>(newTopNode);
50 JLM_UNREACHABLE(
"frontend : Top node in module op is not an OmegaNode.");
54 auto omegaNode = ::mlir::dyn_cast<::mlir::rvsdg::OmegaNode>(topNode);
62 std::unique_ptr<llvm::LlvmRvsdgModule>
67 auto & graph = rvsdgModule->Rvsdg();
68 auto & root = graph.GetRootRegion();
74 ::llvm::SmallVector<jlm::rvsdg::Output *>
83 ::llvm::SmallVector<jlm::rvsdg::Output *>
85 ::mlir::Operation & mlirOp,
86 const std::unordered_map<void *, rvsdg::Output *> & outputMap)
88 ::llvm::SmallVector<jlm::rvsdg::Output *> inputs;
89 for (::mlir::Value operand : mlirOp.getOperands())
91 auto key = operand.getAsOpaquePointer();
92 JLM_ASSERT(outputMap.find(key) != outputMap.end());
93 inputs.push_back(outputMap.at(key));
98 ::llvm::SmallVector<jlm::rvsdg::Output *>
101 ::mlir::sortTopologically(&block);
105 std::unordered_map<void *, rvsdg::Output *> outputMap;
107 for (
size_t i = 0; i < block.getNumArguments(); i++)
109 auto arg = block.getArgument(i);
110 auto key = arg.getAsOpaquePointer();
111 outputMap[key] = rvsdgRegion.
argument(i);
114 for (
auto & mlirOp : block.getOperations())
116 if (
auto argument = ::mlir::dyn_cast<::mlir::rvsdg::OmegaArgument>(mlirOp))
118 auto valueType = argument.getValueType();
119 auto importedType = argument.getImportedValue().getType();
124 *rvsdgRegion.
graph(),
127 argument.getNameAttr().cast<::mlir::StringAttr>().str(),
130 auto key = argument.getResult().getAsOpaquePointer();
135 ::llvm::SmallVector<jlm::rvsdg::Output *> inputs =
GetConvertedInputs(mlirOp, outputMap);
139 for (
size_t i = 0; i < mlirOp.getNumResults(); i++)
141 auto result = mlirOp.getResult(i);
142 auto key = result.getAsOpaquePointer();
149 ::mlir::Operation * terminator = block.getTerminator();
156 ::mlir::arith::CmpIOp & CompOp,
157 const ::llvm::SmallVector<rvsdg::Output *> & inputs,
160 if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::eq)
162 return &rvsdg::CreateOpNode<jlm::llvm::IntegerEqOperation>({ inputs[0], inputs[1] }, nbits);
164 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::ne)
166 return &rvsdg::CreateOpNode<jlm::llvm::IntegerNeOperation>({ inputs[0], inputs[1] }, nbits);
168 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::sge)
170 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSgeOperation>({ inputs[0], inputs[1] }, nbits);
172 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::sgt)
174 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSgtOperation>({ inputs[0], inputs[1] }, nbits);
176 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::sle)
178 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSleOperation>({ inputs[0], inputs[1] }, nbits);
180 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::slt)
182 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSltOperation>({ inputs[0], inputs[1] }, nbits);
184 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::uge)
186 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUgeOperation>({ inputs[0], inputs[1] }, nbits);
188 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::ugt)
190 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUgtOperation>({ inputs[0], inputs[1] }, nbits);
192 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::ule)
194 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUleOperation>({ inputs[0], inputs[1] }, nbits);
196 else if (CompOp.getPredicate() == ::mlir::arith::CmpIPredicate::ult)
198 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUltOperation>({ inputs[0], inputs[1] }, nbits);
208 ::mlir::LLVM::ICmpOp & operation,
210 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
212 if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::eq)
219 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
221 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::ne)
228 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
230 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::sge)
237 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
239 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::sgt)
246 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
248 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::sle)
255 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
257 else if (operation.getPredicate() == ::mlir::LLVM::ICmpPredicate::slt)
264 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()));
274 const ::mlir::Operation & mlirOperation,
275 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
277 if (inputs.size() != 2)
281 if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::AddFOp>(&mlirOperation))
284 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
286 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::SubFOp>(&mlirOperation))
289 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
291 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::MulFOp>(&mlirOperation))
294 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
296 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::DivFOp>(&mlirOperation))
299 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
301 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::RemFOp>(&mlirOperation))
304 size =
ConvertFPSize(castedOp.getType().cast<::mlir::FloatType>().getWidth());
310 return &rvsdg::CreateOpNode<llvm::FBinaryOperation>({ inputs[0], inputs[1] }, op, size);
317 return map.LookupKey(op);
322 ::mlir::Operation & mlirOperation,
323 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
325 if (inputs.size() != 2 || mlirOperation.getNumResults() != 1)
328 auto type = mlirOperation.getResult(0).getType();
331 if (
type.isa<::mlir::IntegerType>())
333 auto integerType =
type.cast<::mlir::IntegerType>();
334 width = integerType.getWidth();
336 else if (
type.isIndex())
345 if (::mlir::isa<::mlir::arith::AddIOp>(mlirOperation))
347 return &rvsdg::CreateOpNode<jlm::llvm::IntegerAddOperation>({ inputs[0], inputs[1] }, width);
349 else if (::mlir::isa<::mlir::arith::SubIOp>(mlirOperation))
351 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSubOperation>({ inputs[0], inputs[1] }, width);
353 else if (::mlir::isa<::mlir::arith::MulIOp>(mlirOperation))
355 return &rvsdg::CreateOpNode<jlm::llvm::IntegerMulOperation>({ inputs[0], inputs[1] }, width);
357 else if (::mlir::isa<::mlir::arith::DivSIOp>(mlirOperation))
359 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSDivOperation>({ inputs[0], inputs[1] }, width);
361 else if (::mlir::isa<::mlir::arith::DivUIOp>(mlirOperation))
363 return &rvsdg::CreateOpNode<jlm::llvm::IntegerUDivOperation>({ inputs[0], inputs[1] }, width);
365 else if (::mlir::isa<::mlir::arith::RemSIOp>(mlirOperation))
367 return &rvsdg::CreateOpNode<jlm::llvm::IntegerSRemOperation>({ inputs[0], inputs[1] }, width);
369 else if (::mlir::isa<::mlir::arith::RemUIOp>(mlirOperation))
371 return &rvsdg::CreateOpNode<jlm::llvm::IntegerURemOperation>({ inputs[0], inputs[1] }, width);
373 else if (::mlir::isa<::mlir::LLVM::ShlOp>(mlirOperation))
375 return &rvsdg::CreateOpNode<jlm::llvm::IntegerShlOperation>({ inputs[0], inputs[1] }, width);
377 else if (::mlir::isa<::mlir::LLVM::AShrOp>(mlirOperation))
379 return &rvsdg::CreateOpNode<jlm::llvm::IntegerAShrOperation>({ inputs[0], inputs[1] }, width);
381 else if (::mlir::isa<::mlir::LLVM::LShrOp>(mlirOperation))
383 return &rvsdg::CreateOpNode<jlm::llvm::IntegerLShrOperation>({ inputs[0], inputs[1] }, width);
385 else if (::mlir::isa<::mlir::arith::AndIOp>(mlirOperation))
387 return &rvsdg::CreateOpNode<jlm::llvm::IntegerAndOperation>({ inputs[0], inputs[1] }, width);
389 else if (::mlir::isa<::mlir::arith::OrIOp>(mlirOperation))
391 return &rvsdg::CreateOpNode<jlm::llvm::IntegerOrOperation>({ inputs[0], inputs[1] }, width);
393 else if (::mlir::isa<::mlir::arith::XOrIOp>(mlirOperation))
395 return &rvsdg::CreateOpNode<jlm::llvm::IntegerXorOperation>({ inputs[0], inputs[1] }, width);
403 static std::vector<llvm::MemoryNodeId>
406 std::vector<llvm::MemoryNodeId> memoryNodeIds;
407 for (
auto memoryNodeId : arrayAttr)
409 memoryNodeIds.push_back(memoryNodeId.cast<::mlir::IntegerAttr>().getInt());
411 return memoryNodeIds;
414 std::vector<jlm::rvsdg::Output *>
416 ::mlir::Operation & mlirOperation,
418 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
424 if (convertedBitBinaryNode)
433 if (convertedFloatBinaryNode)
438 if (::mlir::isa<::mlir::LLVM::FMulAddOp>(&mlirOperation))
446 if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::ExtUIOp>(&mlirOperation))
448 auto st = std::dynamic_pointer_cast<const rvsdg::BitType>(inputs[0]->Type());
451 ::mlir::Type
type = castedOp.getType();
454 else if (
auto castedOp = ::mlir::dyn_cast<::mlir::arith::ExtSIOp>(&mlirOperation))
456 auto outputType = castedOp.getOut().getType();
457 auto convertedOutputType =
ConvertType(outputType);
458 if (!::mlir::isa<::mlir::IntegerType>(castedOp.getType()))
461 castedOp.getType().cast<::mlir::IntegerType>().getWidth(),
464 else if (
auto sitofpOp = ::mlir::dyn_cast<::mlir::arith::SIToFPOp>(&mlirOperation))
466 auto st = std::dynamic_pointer_cast<const jlm::rvsdg::BitType>(inputs[0]->Type());
470 auto mlirOutputType = sitofpOp.getType();
473 return rvsdg::outputs(&rvsdg::CreateOpNode<llvm::SIToFPOperation>(
474 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()),
479 else if (::mlir::isa<::mlir::rvsdg::OmegaNode>(&mlirOperation))
484 else if (::mlir::isa<::mlir::rvsdg::LambdaNode>(&mlirOperation))
488 else if (
auto callOp = ::mlir::dyn_cast<::mlir::jlm::Call>(&mlirOperation))
490 std::vector<std::shared_ptr<const rvsdg::Type>> argumentTypes;
491 for (
auto arg : callOp.getArgs())
493 auto type = arg.getType();
498 std::vector<std::shared_ptr<const rvsdg::Type>> resultTypes;
499 for (
auto res : callOp.getResults())
501 auto type = res.getType();
506 std::vector<jlm::rvsdg::Output *>(inputs.begin(), inputs.end()),
507 std::make_shared<rvsdg::FunctionType>(argumentTypes, resultTypes)));
509 else if (
auto constant = ::mlir::dyn_cast<::mlir::arith::ConstantIntOp>(&mlirOperation))
511 auto type = constant.getType();
513 auto integerType = ::mlir::cast<::mlir::IntegerType>(
type);
517 integerType.getWidth(),
520 else if (
auto constant = ::mlir::dyn_cast<::mlir::arith::ConstantFloatOp>(&mlirOperation))
522 auto type = constant.getType();
523 if (!::mlir::isa<::mlir::FloatType>(
type))
525 auto floatType = ::mlir::cast<::mlir::FloatType>(
type);
529 &rvsdg::CreateOpNode<llvm::ConstantFP>(rvsdgRegion, size, constant.value()));
534 else if (
auto constant = ::mlir::dyn_cast<::mlir::arith::ConstantIndexOp>(&mlirOperation))
536 auto type = constant.getType();
544 else if (
auto indexCast = ::mlir::dyn_cast<::mlir::arith::IndexCastOp>(&mlirOperation))
546 auto outputType = indexCast.getResult().getType();
547 auto inputType = indexCast.getIn().getType();
548 unsigned inputBits = inputType.getIntOrFloatBitWidth();
549 unsigned outputBits = outputType.getIntOrFloatBitWidth();
551 if (inputType.isIndex())
556 return { inputs.begin(), inputs.end() };
572 return { inputs.begin(), inputs.end() };
587 else if (
auto negOp = ::mlir::dyn_cast<::mlir::arith::NegFOp>(&mlirOperation))
589 auto type = negOp.getResult().getType();
590 auto floatType = ::mlir::cast<::mlir::FloatType>(
type);
593 return rvsdg::outputs(&rvsdg::CreateOpNode<jlm::llvm::FNegOperation>({ inputs[0] }, size));
596 else if (
auto extOp = ::mlir::dyn_cast<::mlir::arith::ExtFOp>(&mlirOperation))
598 auto type = extOp.getResult().getType();
599 auto floatType = ::mlir::cast<::mlir::FloatType>(
type);
602 return rvsdg::outputs(&rvsdg::CreateOpNode<jlm::llvm::FPExtOperation>(
608 else if (
auto truncOp = ::mlir::dyn_cast<::mlir::arith::TruncIOp>(&mlirOperation))
610 auto type = truncOp.getResult().getType();
611 auto intType = ::mlir::cast<::mlir::IntegerType>(
type);
614 else if (
auto constant = ::mlir::dyn_cast<::mlir::arith::ConstantFloatOp>(&mlirOperation))
616 auto type = constant.getType();
617 auto floatType = ::mlir::cast<::mlir::FloatType>(
type);
620 return rvsdg::outputs(&rvsdg::CreateOpNode<jlm::llvm::ConstantFP>({}, size, constant.value()));
624 else if (
auto ComOp = ::mlir::dyn_cast<::mlir::arith::CmpIOp>(&mlirOperation))
626 auto type = ComOp.getOperandTypes()[0];
627 if (
type.isa<::mlir::IntegerType>())
629 auto integerType = ::mlir::cast<::mlir::IntegerType>(
type);
632 else if (
type.isIndex())
642 else if (
auto ComOp = ::mlir::dyn_cast<::mlir::arith::CmpFOp>(&mlirOperation))
644 auto type = ComOp.getOperandTypes()[0];
645 auto floatType = ::mlir::cast<::mlir::FloatType>(
type);
647 std::vector(inputs.begin(), inputs.end()),
653 else if (
auto iComOp = ::mlir::dyn_cast<::mlir::LLVM::ICmpOp>(&mlirOperation))
658 else if (
auto UndefOp = ::mlir::dyn_cast<::mlir::jlm::Undef>(&mlirOperation))
660 auto type = UndefOp.getResult().getType();
665 else if (
auto ArrayOp = ::mlir::dyn_cast<::mlir::jlm::ConstantDataArray>(&mlirOperation))
670 else if (
auto ZeroOp = ::mlir::dyn_cast<::mlir::LLVM::ZeroOp>(&mlirOperation))
672 auto type = ZeroOp.getType();
674 if (::mlir::isa<::mlir::LLVM::LLVMPointerType>(
type))
681 else if (
auto VarArgOp = ::mlir::dyn_cast<::mlir::jlm::CreateVarArgList>(&mlirOperation))
685 std::vector(inputs.begin(), inputs.end())) };
690 else if (
auto FreeOp = ::mlir::dyn_cast<::mlir::jlm::Free>(&mlirOperation))
693 std::vector(inputs.begin(), inputs.end()),
697 else if (
auto AllocaOp = ::mlir::dyn_cast<::mlir::jlm::Alloca>(&mlirOperation))
699 auto outputType = AllocaOp.getValueType();
705 if (!rvsdg::is<const rvsdg::BitType>(inputs[0]->Type()))
708 auto jlmBitType = std::dynamic_pointer_cast<const jlm::rvsdg::BitType>(inputs[0]->Type());
710 return rvsdg::outputs(&rvsdg::CreateOpNode<llvm::AllocaOperation>(
711 std::vector(inputs.begin(), inputs.end()),
714 AllocaOp.getAlignment()));
716 else if (
auto MemstateMergeOp = ::mlir::dyn_cast<::mlir::rvsdg::MemStateMerge>(&mlirOperation))
718 auto operands = std::vector(inputs.begin(), inputs.end());
722 auto LambdaEntryMemstateSplitOp =
723 ::mlir::dyn_cast<::mlir::rvsdg::LambdaEntryMemoryStateSplit>(&mlirOperation))
728 auto operands = std::vector(inputs.begin(), inputs.end());
731 std::move(memoryNodeIds)));
733 if (
auto LambdaExitMemstateMergeOp =
734 ::mlir::dyn_cast<::mlir::rvsdg::LambdaExitMemoryStateMerge>(&mlirOperation))
739 auto operands = std::vector(inputs.begin(), inputs.end());
743 std::move(memoryNodeIds)));
746 auto CallEntryMemstateMergeOp =
747 ::mlir::dyn_cast<::mlir::rvsdg::CallEntryMemoryStateMerge>(&mlirOperation))
751 auto operands = std::vector(inputs.begin(), inputs.end());
755 std::move(memoryNodeIds)));
758 auto CallExitMemstateSplitOp =
759 ::mlir::dyn_cast<::mlir::rvsdg::CallExitMemoryStateSplit>(&mlirOperation))
763 auto operands = std::vector(inputs.begin(), inputs.end());
766 std::move(memoryNodeIds)));
768 else if (::mlir::isa<::mlir::rvsdg::MemoryStateJoin>(&mlirOperation))
770 std::vector
operands(inputs.begin(), inputs.end());
773 else if (
auto IOBarrierOp = ::mlir::dyn_cast<::mlir::jlm::IOBarrier>(&mlirOperation))
775 auto type = IOBarrierOp.getResult().getType();
776 return rvsdg::outputs(&rvsdg::CreateOpNode<llvm::IOBarrierOperation>(
777 std::vector(inputs.begin(), inputs.end()),
780 else if (
auto MallocOp = ::mlir::dyn_cast<::mlir::jlm::Malloc>(&mlirOperation))
784 else if (
auto StoreOp = ::mlir::dyn_cast<::mlir::jlm::Store>(&mlirOperation))
786 auto address = inputs[0];
787 auto value = inputs[1];
788 auto memoryStateInputs = std::vector(std::next(inputs.begin(), 2), inputs.end());
793 StoreOp.getAlignment()));
795 else if (
auto LoadOp = ::mlir::dyn_cast<::mlir::jlm::Load>(&mlirOperation))
797 auto address = inputs[0];
798 auto memoryStateInputs = std::vector(std::next(inputs.begin()), inputs.end());
799 auto outputType = LoadOp.getOutput().getType();
807 LoadOp.getAlignment()));
809 else if (
auto GepOp = ::mlir::dyn_cast<::mlir::LLVM::GEPOp>(&mlirOperation))
811 auto elemType = GepOp.getElemType();
816 std::vector<rvsdg::Output *> indices;
818 size_t dynamicInput = 1;
819 for (int32_t constant : GepOp.getRawConstantIndices())
822 if (constant == ::mlir::LLVM::GEPOp::kDynamicIndex)
824 indices.push_back(inputs[dynamicInput++]);
842 else if (
auto MlirCtrlConst = ::mlir::dyn_cast<::mlir::rvsdg::ConstantCtrl>(&mlirOperation))
844 JLM_ASSERT(::mlir::isa<::mlir::rvsdg::RVSDG_CTRLType>(MlirCtrlConst.getType()));
847 ::mlir::cast<::mlir::rvsdg::RVSDG_CTRLType>(MlirCtrlConst.getType()).getNumOptions(),
848 MlirCtrlConst.getValue()) };
850 else if (
auto mlirGammaNode = ::mlir::dyn_cast<::mlir::rvsdg::GammaNode>(&mlirOperation))
854 mlirGammaNode.getNumRegions()
858 for (
size_t i = 1; i < inputs.size(); i++)
860 rvsdgGammaNode->AddEntryVar(inputs[i]);
863 ::llvm::SmallVector<::llvm::SmallVector<jlm::rvsdg::Output *>> regionResults;
864 for (
size_t i = 0; i < mlirGammaNode.getNumRegions(); i++)
866 regionResults.push_back(
867 ConvertRegion(mlirGammaNode.getRegion(i), *rvsdgGammaNode->subregion(i)));
872 for (
size_t exitvarIndex = 0; exitvarIndex < regionResults[0].size(); exitvarIndex++)
874 std::vector<rvsdg::Output *> exitvars;
875 for (
size_t regionIndex = 0; regionIndex < mlirGammaNode.getNumRegions(); regionIndex++)
877 JLM_ASSERT(regionResults[regionIndex].size() == regionResults[0].size());
878 exitvars.push_back(regionResults[regionIndex][exitvarIndex]);
880 rvsdgGammaNode->AddExitVar(exitvars);
885 else if (
auto mlirThetaNode = ::mlir::dyn_cast<::mlir::rvsdg::ThetaNode>(&mlirOperation))
890 for (
size_t i = 0; i < inputs.size(); i++)
892 rvsdgThetaNode->AddLoopVar(inputs[i]);
895 auto regionResults =
ConvertRegion(mlirThetaNode.getRegion(), *rvsdgThetaNode->subregion());
897 rvsdgThetaNode->set_predicate(regionResults[0]);
899 auto loopvars = rvsdgThetaNode->GetLoopVars();
900 for (
size_t i = 1; i < regionResults.size(); i++)
902 loopvars[i - 1].post->divert_to(regionResults[i]);
907 else if (
auto mlirDeltaNode = ::mlir::dyn_cast<::mlir::rvsdg::DeltaNode>(&mlirOperation))
909 auto & deltaRegion = mlirDeltaNode.getRegion();
910 auto & deltaBlock = deltaRegion.front();
911 auto terminator = deltaBlock.getTerminator();
913 auto mlirOutputType = terminator->getOperand(0).getType();
915 auto linakgeString = mlirDeltaNode.getLinkage().str();
920 mlirDeltaNode.getName().str(),
922 mlirDeltaNode.getSection().str(),
923 mlirDeltaNode.getConstant()));
925 auto outputVector =
ConvertRegion(mlirDeltaNode.getRegion(), *rvsdgDeltaNode->subregion());
927 if (outputVector.size() != 1)
930 rvsdgDeltaNode->finalize(outputVector[0]);
934 else if (
auto mlirMatch = ::mlir::dyn_cast<::mlir::rvsdg::Match>(&mlirOperation))
936 std::unordered_map<uint64_t, uint64_t> mapping;
937 uint64_t defaultAlternative = 0;
938 for (
auto & attr : mlirMatch.getMapping())
940 JLM_ASSERT(attr.isa<::mlir::rvsdg::MatchRuleAttr>());
941 auto matchRuleAttr = attr.cast<::mlir::rvsdg::MatchRuleAttr>();
942 if (matchRuleAttr.isDefault())
944 defaultAlternative = matchRuleAttr.getIndex();
948 mapping[matchRuleAttr.getValues().front()] = matchRuleAttr.getIndex();
955 mlirMatch.getMapping().size()
958 else if (
auto selectOp = ::mlir::dyn_cast<::mlir::arith::SelectOp>(&mlirOperation))
960 auto type = selectOp.getType();
962 return rvsdg::outputs(&rvsdg::CreateOpNode<jlm::llvm::SelectOperation>(
963 std::vector(inputs.begin(), inputs.end()),
966 else if (
auto mlirOmegaResult = ::mlir::dyn_cast<::mlir::rvsdg::OmegaResult>(&mlirOperation))
968 for (
auto input : inputs)
970 auto origin = rvsdg::TryGetOwnerNode<rvsdg::Node>(*input);
978 auto op = util::assertedCast<const llvm::DeltaOperation>(&delta->GetOperation());
987 ::mlir::isa<::mlir::rvsdg::LambdaResult>(&mlirOperation)
988 || ::mlir::isa<::mlir::rvsdg::GammaResult>(&mlirOperation)
989 || ::mlir::isa<::mlir::rvsdg::ThetaResult>(&mlirOperation)
990 || ::mlir::isa<::mlir::rvsdg::DeltaResult>(&mlirOperation)
992 || ::mlir::isa<::mlir::rvsdg::OmegaArgument>(&mlirOperation))
998 mlirOperation.dump();
1000 "Operation not implemented: ",
1001 mlirOperation.getName().getStringRef().str(),
1023 auto message =
util::strfmt(
"Unsupported floating point size: ", size,
"\n");
1032 if (!stringValue.compare(
"external_linkage"))
1036 else if (!stringValue.compare(
"available_externally_linkage"))
1040 else if (!stringValue.compare(
"link_once_any_linkage"))
1044 else if (!stringValue.compare(
"link_once_odr_linkage"))
1048 else if (!stringValue.compare(
"weak_any_linkage"))
1052 else if (!stringValue.compare(
"weak_odr_linkage"))
1056 else if (!stringValue.compare(
"appending_linkage"))
1060 else if (!stringValue.compare(
"internal_linkage"))
1064 else if (!stringValue.compare(
"private_linkage"))
1068 else if (!stringValue.compare(
"external_weak_linkage"))
1072 else if (!stringValue.compare(
"common_linkage"))
1076 auto message =
util::strfmt(
"Unsupported linkage: ", stringValue,
"\n");
1082 ::mlir::Operation & mlirOperation,
1084 const ::llvm::SmallVector<rvsdg::Output *> & inputs)
1087 auto functionNameAttribute = mlirOperation.getAttr(::llvm::StringRef(
"sym_name"));
1088 JLM_ASSERT(functionNameAttribute !=
nullptr);
1089 auto functionName = ::mlir::cast<::mlir::StringAttr>(functionNameAttribute);
1091 auto lambdaOp = ::mlir::dyn_cast<::mlir::rvsdg::LambdaNode>(&mlirOperation);
1092 auto & lambdaRegion = lambdaOp.getRegion();
1093 auto numNonContextVars = lambdaRegion.getNumArguments() - lambdaOp.getNumOperands();
1094 auto & lambdaBlock = lambdaRegion.front();
1095 auto lamdbaTerminator = lambdaBlock.getTerminator();
1098 std::vector<std::shared_ptr<const rvsdg::Type>> argumentTypes;
1099 for (
size_t argumentIndex = 0; argumentIndex < numNonContextVars; argumentIndex++)
1101 auto type = lambdaRegion.getArgument(argumentIndex).getType();
1104 std::vector<std::shared_ptr<const rvsdg::Type>> resultTypes;
1105 for (
auto returnType : lamdbaTerminator->getOperandTypes())
1117 functionName.getValue().str(),
1120 for (
auto input : inputs)
1122 rvsdgLambda->AddContextVar(*input);
1125 auto jlmLambdaRegion = rvsdgLambda->subregion();
1126 auto regionResults =
ConvertRegion(lambdaRegion, *jlmLambdaRegion);
1128 rvsdgLambda->finalize(std::vector<rvsdg::Output *>(regionResults.begin(), regionResults.end()));
1133 std::shared_ptr<const rvsdg::Type>
1136 if (
auto ctrlType = ::mlir::dyn_cast<::mlir::rvsdg::RVSDG_CTRLType>(
type))
1140 else if (
auto intType = ::mlir::dyn_cast<::mlir::IntegerType>(
type))
1144 else if (::mlir::isa<::mlir::Float16Type>(
type))
1148 else if (::mlir::isa<::mlir::Float32Type>(
type))
1152 else if (::mlir::isa<::mlir::Float64Type>(
type))
1156 else if (::mlir::isa<::mlir::Float80Type>(
type))
1160 else if (::mlir::isa<::mlir::Float128Type>(
type))
1164 else if (::mlir::isa<::mlir::rvsdg::MemStateEdgeType>(
type))
1168 else if (::mlir::isa<::mlir::rvsdg::IOStateEdgeType>(
type))
1172 else if (::mlir::isa<::mlir::LLVM::LLVMPointerType>(
type))
1176 else if (::mlir::isa<::mlir::jlm::VarargListType>(
type))
1180 else if (
auto arrayType = ::mlir::dyn_cast<::mlir::LLVM::LLVMArrayType>(
type))
1182 auto mlirElementType = arrayType.getElementType();
1183 std::shared_ptr<const rvsdg::Type> elementType =
ConvertType(mlirElementType);
1186 else if (
auto functionType = ::mlir::dyn_cast<::mlir::FunctionType>(
type))
1188 std::vector<std::shared_ptr<const rvsdg::Type>> argumentTypes;
1189 for (
auto argumentType : functionType.getInputs())
1191 argumentTypes.push_back(
ConvertType(argumentType));
1193 std::vector<std::shared_ptr<const rvsdg::Type>> resultTypes;
1194 for (
auto resultType : functionType.getResults())
1200 else if (
type.isIndex())
1205 else if (
auto structType = ::mlir::dyn_cast<::mlir::LLVM::LLVMStructType>(
type))
1212 std::vector<std::shared_ptr<const rvsdg::Type>> types;
1213 for (
auto element : structType.getBody())
1218 std::shared_ptr<const llvm::StructType> jlmStructType;
1219 if (structType.isIdentified())
1222 structType.getName().str(),
1224 structType.isPacked());
1232 return jlmStructType;
static std::shared_ptr< const ArrayType > Create(std::shared_ptr< const Type > type, size_t nelements)
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 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 llvm::Linkage &linkage, std::string section, bool constant)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &multiplier, rvsdg::Output &multiplicand, rvsdg::Output &summand)
static std::shared_ptr< const FloatingPointType > Create(fpsize size)
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *baseAddress, const std::vector< const Variable * > &offsets, std::shared_ptr< const rvsdg::Type > pointeeType, std::shared_ptr< const rvsdg::Type > resultType)
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::Node & 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, bool isConstant=false)
static std::unique_ptr< LlvmLambdaOperation > Create(std::shared_ptr< const jlm::rvsdg::FunctionType > type, std::string name, const jlm::llvm::Linkage &linkage, 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
size_t narguments() 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)
static std::string type(const Node *n)
@ 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)