Jlm
Loading...
Searching...
No Matches
JlmToMlirConverter.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2024 Louis Maurin <louis7maurin@gmail.com>
3 * Copyright 2023 Magnus Sjalander <work@sjalander.com>
4 * See COPYING for terms of redistribution.
5 */
6
22#include <jlm/rvsdg/node.hpp>
25
26#include <llvm/Support/raw_os_ostream.h>
27
28#include <mlir/Dialect/Arith/IR/Arith.h>
29#include <mlir/IR/Builders.h>
30#include <mlir/IR/Verifier.h>
31
32#include <unordered_map>
33
34namespace jlm::mlir
35{
36
37void
38JlmToMlirConverter::Print(::mlir::rvsdg::OmegaNode & omega, const util::FilePath & filePath)
39{
40 if (failed(::mlir::verify(omega)))
41 {
42 omega.emitError("module verification error");
43 throw util::Error("Verification of RVSDG-MLIR failed");
44 }
45 if (filePath == "")
46 {
47 ::llvm::raw_os_ostream os(std::cout);
48 omega.print(os);
49 }
50 else
51 {
52 std::error_code ec;
53 ::llvm::raw_fd_ostream os(filePath.to_str(), ec);
54 omega.print(os);
55 }
56}
57
58::mlir::rvsdg::OmegaNode
60{
61 auto & graph = rvsdgModule.Rvsdg();
62
63 auto omega = Builder_->create<::mlir::rvsdg::OmegaNode>(Builder_->getUnknownLoc());
64 auto & omegaBlock = omega.getRegion().emplaceBlock();
65
66 ::llvm::SmallVector<::mlir::Value> regionResults =
67 ConvertRegion(graph.GetRootRegion(), omegaBlock, true);
68
69 // Build result types from the region results
70 ::llvm::SmallVector<::mlir::Type> resultTypes;
71 for (auto & result : regionResults)
72 {
73 resultTypes.push_back(result.getType());
74 }
75
76 // Collect export names from root region results.
77 // The order of graph.GetRootRegion().results() matches regionResults.
78 ::llvm::SmallVector<::mlir::Attribute> exportNames;
79 for (auto & result : graph.GetRootRegion().Results())
80 {
81 if (auto graphExport = dynamic_cast<const rvsdg::GraphExport *>(result))
82 {
83 exportNames.push_back(Builder_->getStringAttr(graphExport->Name()));
84 }
85 else
86 {
87 JLM_UNREACHABLE("This should not happen. All omega results should be a GraphExport");
88 }
89 }
90
91 // Create OmegaResult with proper signature including export names.
92 auto exportNamesAttr = ::mlir::ArrayAttr::get(Builder_->getContext(), exportNames);
93 ::llvm::SmallVector<::mlir::NamedAttribute> namedAttrs;
94 namedAttrs.push_back({ Builder_->getStringAttr("exportNames"), exportNamesAttr });
95
96 auto omegaResult = Builder_->create<::mlir::rvsdg::OmegaResult>(
97 Builder_->getUnknownLoc(),
98 resultTypes,
99 regionResults,
100 namedAttrs);
101 omegaBlock.push_back(omegaResult);
102
103 return omega;
104}
105
106::llvm::SmallVector<::mlir::Value>
107JlmToMlirConverter::ConvertRegion(rvsdg::Region & region, ::mlir::Block & block, bool isRoot)
108{
109 std::unordered_map<rvsdg::Output *, ::mlir::Value> valueMap;
110 size_t argIndex = 0;
111 for (size_t i = 0; i < region.narguments(); ++i)
112 {
113 auto arg = region.argument(i);
114 if (isRoot) // Omega arguments are treated separately
115 {
116 auto imp = util::assertedCast<llvm::LlvmGraphImport>(arg);
117 block.push_back(Builder_->create<::mlir::rvsdg::OmegaArgument>(
118 Builder_->getUnknownLoc(),
119 ConvertType(*imp->ImportedType()),
120 ConvertType(*imp->ValueType()),
121 Builder_->getStringAttr(llvm::linkageToString(imp->linkage())),
122 Builder_->getStringAttr(imp->Name())));
123 valueMap[arg] = block.back().getResult(0); // Add the output of the omega argument
124 }
125 else
126 {
127 block.addArgument(ConvertType(*arg->Type()), Builder_->getUnknownLoc());
128 valueMap[arg] = block.getArgument(argIndex);
129 ++argIndex;
130 }
131 }
132
133 // Create an MLIR operation for each RVSDG node.
134 // The mapping from RVSDG output to MLIR result is added to the valueMap for quick lookup.
135 for (rvsdg::Node * rvsdgNode : rvsdg::TopDownTraverser(&region))
136 {
137 ::llvm::SmallVector<::mlir::Value> inputs = GetConvertedInputs(*rvsdgNode, valueMap);
138
139 auto convertedNode = ConvertNode(*rvsdgNode, block, inputs);
140 for (size_t i = 0; i < rvsdgNode->noutputs(); i++)
141 {
142 valueMap[rvsdgNode->output(i)] = convertedNode->getResult(i);
143 }
144 }
145
146 // This code is used to get the results of the region
148 ::llvm::SmallVector<::mlir::Value> results;
149 for (size_t i = 0; i < region.nresults(); i++)
150 {
151 auto it = valueMap.find(region.result(i)->origin());
152 if (it != valueMap.end())
153 {
154 results.push_back(it->second);
155 }
156 else
157 {
158 auto message = util::strfmt(
159 "Unimplemented input type: ",
160 region.result(i)->origin()->debug_string(),
161 ": ",
162 region.result(i)->origin()->Type()->debug_string(),
163 " for region result: ",
164 region.result(i)->debug_string(),
165 " at index: ",
166 i);
167 JLM_UNREACHABLE(message.c_str());
168 }
169 }
170
171 return results;
172}
173
174::llvm::SmallVector<::mlir::Value>
176 const rvsdg::Node & node,
177 const std::unordered_map<rvsdg::Output *, ::mlir::Value> & valueMap)
178{
179 ::llvm::SmallVector<::mlir::Value> inputs;
180 for (size_t i = 0; i < node.ninputs(); i++)
181 {
182 auto it = valueMap.find(node.input(i)->origin());
183 if (it != valueMap.end())
184 {
185 inputs.push_back(it->second);
186 }
187 else
188 {
189 auto message = util::strfmt(
190 "Unimplemented input type: ",
191 node.input(i)->origin()->debug_string(),
192 ": ",
193 node.input(i)->origin()->Type()->debug_string(),
194 " for node: ",
195 node.DebugString(),
196 " at index: ",
197 i);
198 JLM_UNREACHABLE(message.c_str());
199 }
200 }
201 return inputs;
202}
203
204::mlir::Operation *
206 const rvsdg::Node & node,
207 ::mlir::Block & block,
208 const ::llvm::SmallVector<::mlir::Value> & inputs)
209{
210 if (auto simpleNode = dynamic_cast<const rvsdg::SimpleNode *>(&node))
211 {
212 return ConvertSimpleNode(*simpleNode, block, inputs);
213 }
214 else if (auto lambda = dynamic_cast<const rvsdg::LambdaNode *>(&node))
215 {
216 return ConvertLambda(*lambda, block, inputs);
217 }
218 else if (auto gamma = dynamic_cast<const rvsdg::GammaNode *>(&node))
219 {
220 return ConvertGamma(*gamma, block, inputs);
221 }
222 else if (auto theta = dynamic_cast<const rvsdg::ThetaNode *>(&node))
223 {
224 return ConvertTheta(*theta, block, inputs);
225 }
226 else if (auto delta = dynamic_cast<const rvsdg::DeltaNode *>(&node))
227 {
228 return ConvertDelta(*delta, block, inputs);
229 }
230 else
231 {
232 auto message = util::strfmt("Unimplemented structural node: ", node.DebugString());
233 JLM_UNREACHABLE(message.c_str());
234 }
235}
236
237::mlir::Operation *
240 ::llvm::SmallVector<::mlir::Value> inputs)
241{
242 switch (op.fpop())
243 {
245 return Builder_->create<::mlir::arith::AddFOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
247 return Builder_->create<::mlir::arith::SubFOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
249 return Builder_->create<::mlir::arith::MulFOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
251 return Builder_->create<::mlir::arith::DivFOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
253 return Builder_->create<::mlir::arith::RemFOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
254 default:
255 JLM_UNREACHABLE("Unknown binary bitop");
256 }
257}
258
259::mlir::Operation *
261 const llvm::FCmpOperation & op,
262 ::llvm::SmallVector<::mlir::Value> inputs)
263{
264 const auto & map = GetFpCmpPredicateMap();
265 auto predicate = map.LookupValue(op.cmp());
266 return Builder_->create<::mlir::arith::CmpFOp>(
267 Builder_->getUnknownLoc(),
268 Builder_->getAttr<::mlir::arith::CmpFPredicateAttr>(predicate),
269 inputs[0],
270 inputs[1]);
271}
272
273::mlir::Operation *
275 const rvsdg::SimpleOperation & bitOp,
276 ::llvm::SmallVector<::mlir::Value> inputs)
277{
278 ::mlir::Operation * MlirOp = nullptr;
280 {
281 MlirOp =
282 Builder_->create<::mlir::arith::AddIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
283 }
285 {
286 MlirOp =
287 Builder_->create<::mlir::arith::AndIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
288 }
290 {
291 MlirOp =
292 Builder_->create<::mlir::arith::ShRUIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
293 }
295 {
296 MlirOp =
297 Builder_->create<::mlir::arith::MulIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
298 }
300 {
301 MlirOp =
302 Builder_->create<::mlir::arith::OrIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
303 }
305 {
306 MlirOp =
307 Builder_->create<::mlir::arith::DivSIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
308 }
310 {
311 MlirOp =
312 Builder_->create<::mlir::arith::ShLIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
313 }
315 {
316 MlirOp =
317 Builder_->create<::mlir::arith::ShRUIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
318 }
320 {
321 MlirOp =
322 Builder_->create<::mlir::arith::RemSIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
323 }
325 {
326 JLM_UNREACHABLE("Binary bit bitOp smulh not supported");
327 }
329 {
330 MlirOp =
331 Builder_->create<::mlir::arith::SubIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
332 }
334 {
335 MlirOp =
336 Builder_->create<::mlir::arith::DivUIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
337 }
339 {
340 MlirOp =
341 Builder_->create<::mlir::arith::RemUIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
342 }
344 {
345 JLM_UNREACHABLE("Binary bit bitOp umulh not supported");
346 }
348 {
349 MlirOp =
350 Builder_->create<::mlir::arith::XOrIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
351 }
352 else
353 {
354 JLM_UNREACHABLE("Unknown binary bitop");
355 }
356
357 return MlirOp;
358}
359
360::mlir::Operation *
362 const rvsdg::SimpleOperation & bitOp,
363 ::llvm::SmallVector<::mlir::Value> inputs)
364{
365 auto compPredicate = ::mlir::arith::CmpIPredicate::eq;
367 compPredicate = ::mlir::arith::CmpIPredicate::eq;
369 compPredicate = ::mlir::arith::CmpIPredicate::ne;
371 compPredicate = ::mlir::arith::CmpIPredicate::sge;
373 compPredicate = ::mlir::arith::CmpIPredicate::sgt;
375 compPredicate = ::mlir::arith::CmpIPredicate::sle;
377 compPredicate = ::mlir::arith::CmpIPredicate::slt;
379 compPredicate = ::mlir::arith::CmpIPredicate::uge;
381 compPredicate = ::mlir::arith::CmpIPredicate::ugt;
383 compPredicate = ::mlir::arith::CmpIPredicate::ule;
385 compPredicate = ::mlir::arith::CmpIPredicate::ult;
386 else
387 {
388 auto message = util::strfmt("Unknown compare operation: ", bitOp.debug_string());
389 JLM_UNREACHABLE(message.c_str());
390 }
391
392 auto MlirOp = Builder_->create<::mlir::arith::CmpIOp>(
393 Builder_->getUnknownLoc(),
394 compPredicate,
395 inputs[0],
396 inputs[1]);
397 return MlirOp;
398}
399
400::mlir::Operation *
402 const llvm::PtrCmpOperation & operation,
403 ::llvm::SmallVector<::mlir::Value> inputs)
404{
405 static std::unordered_map<llvm::ICmpPredicate, ::mlir::LLVM::ICmpPredicate> map = {
406 { llvm::ICmpPredicate::Eq, ::mlir::LLVM::ICmpPredicate::eq },
407 { llvm::ICmpPredicate::Ne, ::mlir::LLVM::ICmpPredicate::ne },
408 { llvm::ICmpPredicate::Ugt, ::mlir::LLVM::ICmpPredicate::ugt },
409 { llvm::ICmpPredicate::Uge, ::mlir::LLVM::ICmpPredicate::uge },
410 { llvm::ICmpPredicate::Ult, ::mlir::LLVM::ICmpPredicate::ult },
411 { llvm::ICmpPredicate::Ule, ::mlir::LLVM::ICmpPredicate::ule },
412 { llvm::ICmpPredicate::Sgt, ::mlir::LLVM::ICmpPredicate::sgt },
413 { llvm::ICmpPredicate::Sge, ::mlir::LLVM::ICmpPredicate::sge },
414 { llvm::ICmpPredicate::Slt, ::mlir::LLVM::ICmpPredicate::slt },
415 { llvm::ICmpPredicate::Sle, ::mlir::LLVM::ICmpPredicate::sle },
416 };
417
418 const auto mlirPredicate = map.at(operation.predicate());
419 auto MlirOp = Builder_->create<::mlir::LLVM::ICmpOp>(
420 Builder_->getUnknownLoc(),
421 mlirPredicate,
422 inputs[0],
423 inputs[1]);
424 return MlirOp;
425}
426
434static ::mlir::ArrayAttr
436 ::mlir::MLIRContext * context,
437 const std::vector<llvm::MemoryNodeId> & memoryNodeIndices)
438{
439 auto int64Type = ::mlir::IntegerType::get(context, 64);
440 ::llvm::SmallVector<::mlir::Attribute> intAttributes;
441 for (auto memoryNodeId : memoryNodeIndices)
442 {
443 intAttributes.push_back(::mlir::IntegerAttr::get(int64Type, memoryNodeId));
444 }
445 return ::mlir::ArrayAttr::get(context, intAttributes);
446}
447
448::mlir::Operation *
450 const rvsdg::SimpleNode & node,
451 ::mlir::Block & block,
452 const ::llvm::SmallVector<::mlir::Value> & inputs)
453{
454 ::mlir::Operation * MlirOp = nullptr;
455 auto & operation = node.GetOperation();
456 if (auto bitOp = dynamic_cast<const rvsdg::BitConstantOperation *>(&operation))
457 {
458 auto value = bitOp->value();
459 MlirOp = Builder_->create<::mlir::arith::ConstantIntOp>(
460 Builder_->getUnknownLoc(),
461 value.to_uint(),
462 value.nbits());
463 }
464 else if (
465 auto integerConstOp = dynamic_cast<const jlm::llvm::IntegerConstantOperation *>(&operation))
466 {
467 auto isNegative = integerConstOp->Representation().is_negative();
468 auto value = isNegative ? integerConstOp->Representation().to_int()
469 : integerConstOp->Representation().to_uint();
470 MlirOp = Builder_->create<::mlir::arith::ConstantIntOp>(
471 Builder_->getUnknownLoc(),
472 value,
473 integerConstOp->Representation().nbits());
474 }
475 else if (auto fpBinOp = dynamic_cast<const jlm::llvm::FBinaryOperation *>(&operation))
476 {
477 MlirOp = ConvertFpBinaryNode(*fpBinOp, inputs);
478 }
480 {
481 MlirOp = Builder_->create<::mlir::LLVM::FMulAddOp>(
482 Builder_->getUnknownLoc(),
483 inputs[0],
484 inputs[1],
485 inputs[2]);
486 }
488 {
490 *dynamic_cast<const jlm::llvm::IntegerBinaryOperation *>(&operation),
491 inputs);
492 }
493 else if (auto fpOp = dynamic_cast<const llvm::ConstantFP *>(&operation))
494 {
495 auto size = ConvertFPType(fpOp->size());
496 auto value = fpOp->constant();
497 MlirOp =
498 Builder_->create<::mlir::arith::ConstantFloatOp>(Builder_->getUnknownLoc(), value, size);
499 }
500 else if (auto zeroOp = dynamic_cast<const llvm::ConstantAggregateZeroOperation *>(&operation))
501 {
502 auto type = ConvertType(*zeroOp->result(0));
503 MlirOp = Builder_->create<::mlir::LLVM::ZeroOp>(Builder_->getUnknownLoc(), type);
504 }
505 else if (auto arrOp = dynamic_cast<const llvm::ConstantDataArrayOperation *>(&operation))
506 {
507 auto arrayType = ConvertType(*arrOp->result(0));
508 MlirOp = Builder_->create<::mlir::jlm::ConstantDataArray>(
509 Builder_->getUnknownLoc(),
510 arrayType,
511 inputs);
512 }
513 else if (auto zeroOp = dynamic_cast<const llvm::ConstantAggregateZeroOperation *>(&operation))
514 {
515 auto type = ConvertType(*zeroOp->result(0));
516 MlirOp = Builder_->create<::mlir::LLVM::ZeroOp>(Builder_->getUnknownLoc(), type);
517 }
518 else if (
519 auto constantPointerNullOp =
520 dynamic_cast<const llvm::ConstantPointerNullOperation *>(&operation))
521 {
522 // NULL pointers are a special case of ZeroOp
523 auto type = ConvertType(*constantPointerNullOp->result(0));
524 MlirOp = Builder_->create<::mlir::LLVM::ZeroOp>(Builder_->getUnknownLoc(), type);
525 }
527 {
528 MlirOp = ConvertBitBinaryNode(operation, inputs);
529 }
530 else if (auto fpBinOp = dynamic_cast<const jlm::llvm::FBinaryOperation *>(&operation))
531 {
532 MlirOp = ConvertFpBinaryNode(*fpBinOp, inputs);
533 }
535 {
536 MlirOp = Builder_->create<::mlir::arith::NegFOp>(Builder_->getUnknownLoc(), inputs[0]);
537 }
538 else if (auto fpextOp = dynamic_cast<const jlm::llvm::FPExtOperation *>(&operation))
539 {
540 MlirOp = Builder_->create<::mlir::arith::ExtFOp>(
541 Builder_->getUnknownLoc(),
542 ConvertType(*fpextOp->result(0)),
543 inputs[0]);
544 }
545
547 {
548 MlirOp = BitCompareNode(operation, inputs);
549 }
550 else if (auto fpCmpOp = dynamic_cast<const llvm::FCmpOperation *>(&operation))
551 {
552 MlirOp = ConvertFpCompareNode(*fpCmpOp, inputs);
553 }
554 else if (auto pointerCompareOp = dynamic_cast<const llvm::PtrCmpOperation *>(&operation))
555 {
556 MlirOp = ConvertPointerCompareNode(*pointerCompareOp, inputs);
557 }
558 else if (const auto zextOperation = dynamic_cast<const llvm::ZExtOperation *>(&operation))
559 {
560 MlirOp = Builder_->create<::mlir::arith::ExtUIOp>(
561 Builder_->getUnknownLoc(),
562 Builder_->getIntegerType(zextOperation->ndstbits()),
563 inputs[0]);
564 }
565 else if (auto sextOp = dynamic_cast<const jlm::llvm::SExtOperation *>(&operation))
566 {
567 MlirOp = Builder_->create<::mlir::arith::ExtSIOp>(
568 Builder_->getUnknownLoc(),
569 Builder_->getIntegerType(sextOp->ndstbits()),
570 inputs[0]);
571 }
572 else if (auto sitofpOp = dynamic_cast<const llvm::SIToFPOperation *>(&operation))
573 {
574 MlirOp = Builder_->create<::mlir::arith::SIToFPOp>(
575 Builder_->getUnknownLoc(),
576 ConvertType(*sitofpOp->result(0)),
577 inputs[0]);
578 }
579 else if (auto truncOp = dynamic_cast<const jlm::llvm::TruncOperation *>(&operation))
580 {
581 MlirOp = Builder_->create<::mlir::arith::TruncIOp>(
582 Builder_->getUnknownLoc(),
583 ConvertType(*truncOp->result(0)),
584 inputs[0]);
585 }
586 // ** region structural nodes **
587 else if (auto ctlOp = dynamic_cast<const rvsdg::ControlConstantOperation *>(&operation))
588 {
589 MlirOp = Builder_->create<::mlir::rvsdg::ConstantCtrl>(
590 Builder_->getUnknownLoc(),
591 ConvertType(*node.output(0)->Type()), // Control, ouput type
592 ctlOp->value().alternative());
593 }
594 else if (auto vaOp = dynamic_cast<const llvm::VariadicArgumentListOperation *>(&operation))
595 {
596 MlirOp = Builder_->create<::mlir::jlm::CreateVarArgList>(
597 Builder_->getUnknownLoc(),
598 ConvertType(*vaOp->result(0)),
599 inputs);
600 }
601 else if (auto undefOp = dynamic_cast<const llvm::UndefValueOperation *>(&operation))
602 {
603 MlirOp = Builder_->create<::mlir::jlm::Undef>(
604 Builder_->getUnknownLoc(),
605 ConvertType(undefOp->GetType()));
606 }
607 else if (auto freeOp = dynamic_cast<const jlm::llvm::FreeOperation *>(&operation))
608 {
609 auto nMemstates = freeOp->narguments() - 2; // Subtract for pointer and io state
610
611 std::vector<::mlir::Type> memoryStates(
612 nMemstates,
613 Builder_->getType<::mlir::rvsdg::MemStateEdgeType>());
614 MlirOp = Builder_->create<::mlir::jlm::Free>(
615 Builder_->getUnknownLoc(),
616 ::mlir::TypeRange(::llvm::ArrayRef(memoryStates)),
617 Builder_->getType<::mlir::rvsdg::IOStateEdgeType>(),
618 inputs[0],
619 ::mlir::ValueRange({ std::next(inputs.begin()), std::prev(inputs.end()) }),
620 inputs[inputs.size() - 1]);
621 }
622 else if (auto alloca_op = dynamic_cast<const jlm::llvm::AllocaOperation *>(&operation))
623 {
624 MlirOp = Builder_->create<::mlir::jlm::Alloca>(
625 Builder_->getUnknownLoc(),
626 ConvertType(*alloca_op->result(0)), // ptr
627 ConvertType(*alloca_op->result(1)), // memstate
628 ConvertType(*alloca_op->allocatedType()), // value type
629 inputs[0], // size
630 alloca_op->alignment(), // alignment
631 ::mlir::ValueRange({ std::next(inputs.begin()), inputs.end() })); // inputMemStates
632 }
633 else if (auto malloc_op = dynamic_cast<const jlm::llvm::MallocOperation *>(&operation))
634 {
635 MlirOp = Builder_->create<::mlir::jlm::Malloc>(
636 Builder_->getUnknownLoc(),
637 ConvertType(*malloc_op->result(0)), // ptr
638 ConvertType(*malloc_op->result(1)), // IOState
639 ConvertType(*malloc_op->result(2)), // memstate
640 inputs[0], // size
641 inputs[1] // IOState
642 );
643 }
644 else if (auto load_op = dynamic_cast<const jlm::llvm::LoadOperation *>(&operation))
645 {
646 // Can have more than a single memory state
647 ::llvm::SmallVector<::mlir::Type> memStateTypes;
648 for (size_t i = 1; i < load_op->nresults(); i++)
649 {
650 memStateTypes.push_back(ConvertType(*load_op->result(i)));
651 }
652 MlirOp = Builder_->create<::mlir::jlm::Load>(
653 Builder_->getUnknownLoc(),
654 ConvertType(*load_op->result(0)), // ptr
655 GetMemStateRange(load_op->nresults() - 1), // memstate(s)
656 inputs[0], // pointer
657 Builder_->getUI32IntegerAttr(load_op->GetAlignment()), // alignment
658 ::mlir::ValueRange({ std::next(inputs.begin()), inputs.end() }) // inputMemStates
659 );
660 }
661 else if (auto store_op = dynamic_cast<const jlm::llvm::StoreOperation *>(&operation))
662 {
663 MlirOp = Builder_->create<::mlir::jlm::Store>(
664 Builder_->getUnknownLoc(),
665 GetMemStateRange(store_op->nresults()), // memstate(s)
666 inputs[0], // ptr
667 inputs[1], // value
668 Builder_->getUI32IntegerAttr(store_op->GetAlignment()), // alignment
669 ::mlir::ValueRange({ std::next(std::next(inputs.begin())), inputs.end() }) // inputMemStates
670 );
671 }
673 {
674 MlirOp = Builder_->create<::mlir::rvsdg::MemStateMerge>(
675 Builder_->getUnknownLoc(),
676 ConvertType(*node.output(0)->Type()),
677 inputs);
678 }
680 {
681 MlirOp = Builder_->create<::mlir::jlm::IOBarrier>(
682 Builder_->getUnknownLoc(),
683 ConvertType(*node.output(0)->Type()),
684 inputs[0],
685 inputs[1]);
686 }
687 else if (auto op = dynamic_cast<const llvm::GetElementPtrOperation *>(&operation))
688 {
689 MlirOp = Builder_->create<::mlir::LLVM::GEPOp>(
690 Builder_->getUnknownLoc(),
691 ConvertType(*op->result(0)), // resultType
692 ConvertType(*op->getPointeeType()), // elementType
693 inputs[0], // basePtr
694 ::mlir::ValueRange({ std::next(inputs.begin()), inputs.end() })); // indices
695 }
696 else if (auto selectOp = dynamic_cast<const llvm::SelectOperation *>(&operation))
697 {
698 assert(selectOp->nresults() == 1);
699 assert(inputs.size() == 3);
700 MlirOp = Builder_->create<::mlir::arith::SelectOp>(
701 Builder_->getUnknownLoc(),
702 ConvertType(*selectOp->result(0)),
703 inputs[0],
704 inputs[1],
705 inputs[2]);
706 }
707 else if (auto matchOp = dynamic_cast<const rvsdg::MatchOperation *>(&operation))
708 {
709 // ** region Create the MLIR mapping vector **
713 ::llvm::SmallVector<::mlir::Attribute> mappingVector;
714 for (auto mapping : *matchOp)
715 {
716 ::mlir::rvsdg::MatchRuleAttr matchRule = ::mlir::rvsdg::MatchRuleAttr::get(
717 Builder_->getContext(),
718 ::llvm::ArrayRef(static_cast<int64_t>(mapping.first)),
719 mapping.second);
720
721 mappingVector.push_back(matchRule);
722 }
724 mappingVector.push_back(::mlir::rvsdg::MatchRuleAttr::get(
725 Builder_->getContext(),
726 ::llvm::ArrayRef<int64_t>(),
727 matchOp->default_alternative()));
728 // ** endregion Create the MLIR mapping vector **
729
730 MlirOp = Builder_->create<::mlir::rvsdg::Match>(
731 Builder_->getUnknownLoc(),
732 ConvertType(*node.output(0)->Type()), // Control, ouput type
733 inputs[0], // input
734 ::mlir::ArrayAttr::get(Builder_->getContext(), ::llvm::ArrayRef(mappingVector)));
735 }
736 else if (auto callOp = dynamic_cast<const jlm::llvm::CallOperation *>(&operation))
737 {
738 auto functionType = *callOp->GetFunctionType();
739 ::llvm::SmallVector<::mlir::Type> argumentTypes;
740 for (size_t i = 0; i < functionType.NumArguments(); i++)
741 {
742 argumentTypes.push_back(ConvertType(functionType.ArgumentType(i)));
743 }
744 ::llvm::SmallVector<::mlir::Type> resultTypes;
745 for (size_t i = 0; i < functionType.NumResults(); i++)
746 {
747 resultTypes.push_back(ConvertType(functionType.ResultType(i)));
748 }
749 MlirOp = Builder_->create<::mlir::jlm::Call>(
750 Builder_->getUnknownLoc(),
751 resultTypes,
752 inputs[0], // func ptr
753 ::mlir::ValueRange(
754 { std::next(inputs.begin()), std::prev(std::prev(inputs.end())) }), // args
755 inputs[inputs.size() - 2], // io
756 inputs[inputs.size() - 1] // mem
757 );
758 }
759 else if (
760 auto lambdaStateSplit =
761 dynamic_cast<const llvm::LambdaEntryMemoryStateSplitOperation *>(&operation))
762 {
763 auto memoryNodeIndicesAttr =
764 memoryNodeIndicesToArrayAttr(Builder_->getContext(), lambdaStateSplit->getMemoryNodeIds());
765
766 ::llvm::SmallVector<::mlir::Type> resultTypes;
767 for (size_t i = 0; i < lambdaStateSplit->nresults(); i++)
768 {
769 resultTypes.push_back(ConvertType(*lambdaStateSplit->result(i).get()));
770 }
771 MlirOp = Builder_->create<::mlir::rvsdg::LambdaEntryMemoryStateSplit>(
772 Builder_->getUnknownLoc(),
773 ::llvm::ArrayRef(resultTypes), // output types
774 inputs[0], // input
775 memoryNodeIndicesAttr);
776 }
777 else if (
778 auto lambdaStateMerge =
779 dynamic_cast<const jlm::llvm::LambdaExitMemoryStateMergeOperation *>(&operation))
780 {
781 auto memoryNodeIndicesAttr =
782 memoryNodeIndicesToArrayAttr(Builder_->getContext(), lambdaStateMerge->getMemoryNodeIds());
783
784 ::llvm::SmallVector<::mlir::Type> resultTypes;
785 for (size_t i = 0; i < lambdaStateMerge->nresults(); i++)
786 {
787 resultTypes.push_back(ConvertType(*lambdaStateMerge->result(i).get()));
788 }
789 MlirOp = Builder_->create<::mlir::rvsdg::LambdaExitMemoryStateMerge>(
790 Builder_->getUnknownLoc(),
791 ::llvm::ArrayRef(resultTypes), // output type
792 ::mlir::ValueRange(inputs), // inputs
793 memoryNodeIndicesAttr);
794 }
795 else if (
796 auto callStateSplit =
797 dynamic_cast<const jlm::llvm::CallExitMemoryStateSplitOperation *>(&operation))
798 {
799 auto memoryNodeIndicesAttr =
800 memoryNodeIndicesToArrayAttr(Builder_->getContext(), callStateSplit->getMemoryNodeIds());
801
802 ::llvm::SmallVector<::mlir::Type> resultTypes;
803 for (size_t i = 0; i < callStateSplit->nresults(); i++)
804 {
805 resultTypes.push_back(ConvertType(*callStateSplit->result(i).get()));
806 }
807 MlirOp = Builder_->create<::mlir::rvsdg::CallExitMemoryStateSplit>(
808 Builder_->getUnknownLoc(),
809 ::llvm::ArrayRef(resultTypes), // output types
810 inputs[0], // input
811 memoryNodeIndicesAttr);
812 }
813 else if (
814 auto callStateMerge =
815 dynamic_cast<const jlm::llvm::CallEntryMemoryStateMergeOperation *>(&operation))
816 {
817 auto memoryNodeIndicesAttr =
818 memoryNodeIndicesToArrayAttr(Builder_->getContext(), callStateMerge->getMemoryNodeIds());
819
820 ::llvm::SmallVector<::mlir::Type> resultTypes;
821 for (size_t i = 0; i < callStateMerge->nresults(); i++)
822 {
823 resultTypes.push_back(ConvertType(*callStateMerge->result(i).get()));
824 }
825 MlirOp = Builder_->create<::mlir::rvsdg::CallEntryMemoryStateMerge>(
826 Builder_->getUnknownLoc(),
827 ::llvm::ArrayRef(resultTypes), // output type
828 ::mlir::ValueRange(inputs), // inputs
829 memoryNodeIndicesAttr);
830 }
831 else if (auto memoryStateJoin = dynamic_cast<const llvm::MemoryStateJoinOperation *>(&operation))
832 {
833 ::mlir::Type resultType = ConvertType(*memoryStateJoin->result(0));
834
835 MlirOp = Builder_->create<::mlir::rvsdg::MemoryStateJoin>(
836 Builder_->getUnknownLoc(),
837 resultType,
838 ::mlir::ValueRange(inputs));
839 }
840 // ** endregion structural nodes **
841 else
842 {
843 auto message = util::strfmt("Unimplemented simple node: ", operation.debug_string());
844 JLM_UNREACHABLE(message.c_str());
845 }
846
847 block.push_back(MlirOp);
848 return MlirOp;
849}
850
851::llvm::SmallVector<::mlir::Type>
853{
854 ::llvm::SmallVector<::mlir::Type> typeRange;
855 for (size_t i = 0; i < nresults; ++i)
856 {
857 typeRange.push_back(Builder_->getType<::mlir::rvsdg::MemStateEdgeType>());
858 }
859 return typeRange;
860}
861
862::mlir::Operation *
864 const rvsdg::LambdaNode & lambdaNode,
865 ::mlir::Block & block,
866 const ::llvm::SmallVector<::mlir::Value> & inputs)
867{
868 // Add function attributes, e.g., the function name and linkage
869 ::llvm::SmallVector<::mlir::NamedAttribute> attributes;
870 auto symbolName = Builder_->getNamedAttr(
871 Builder_->getStringAttr("sym_name"),
872 Builder_->getStringAttr(
873 dynamic_cast<llvm::LlvmLambdaOperation &>(lambdaNode.GetOperation()).name()));
874 attributes.push_back(symbolName);
875 auto linkage = Builder_->getNamedAttr(
876 Builder_->getStringAttr("linkage"),
877 Builder_->getStringAttr(llvm::linkageToString(
878 dynamic_cast<llvm::LlvmLambdaOperation &>(lambdaNode.GetOperation()).linkage())));
879 attributes.push_back(linkage);
880
881 auto lambda = Builder_->create<::mlir::rvsdg::LambdaNode>(
882 Builder_->getUnknownLoc(),
883 ConvertType(*lambdaNode.output()->Type()),
884 inputs,
885 ::llvm::ArrayRef<::mlir::NamedAttribute>(attributes));
886 block.push_back(lambda);
887
888 auto & lambdaBlock = lambda.getRegion().emplaceBlock();
889 auto regionResults = ConvertRegion(*lambdaNode.subregion(), lambdaBlock);
890 auto lambdaResult =
891 Builder_->create<::mlir::rvsdg::LambdaResult>(Builder_->getUnknownLoc(), regionResults);
892 lambdaBlock.push_back(lambdaResult);
893
894 return lambda;
895}
896
897::mlir::Operation *
899 const rvsdg::GammaNode & gammaNode,
900 ::mlir::Block & block,
901 const ::llvm::SmallVector<::mlir::Value> & inputs)
902{
903 auto & gammaOp = *util::assertedCast<const rvsdg::GammaOperation>(&gammaNode.GetOperation());
904
905 ::llvm::SmallVector<::mlir::Type> typeRangeOuput;
906 for (size_t i = 0; i < gammaNode.noutputs(); ++i)
907 {
908 typeRangeOuput.push_back(ConvertType(*gammaNode.output(i)->Type()));
909 }
910
911 // The predicate is always the first input
912 // Predicate is used to select the region to execute
913 ::mlir::Value predicate = inputs[0];
914
915 auto gamma = Builder_->create<::mlir::rvsdg::GammaNode>(
916 Builder_->getUnknownLoc(),
917 ::mlir::TypeRange(::llvm::ArrayRef(typeRangeOuput)), // Ouputs types
918 predicate,
919 ::mlir::ValueRange({ std::next(inputs.begin()), inputs.end() }), // Inputs
920 gammaOp.nalternatives() // regionsCount
921 );
922 block.push_back(gamma);
923
924 for (size_t i = 0; i < gammaOp.nalternatives(); ++i)
925 {
926 auto & gammaBlock = gamma.getRegion(i).emplaceBlock();
927 auto regionResults = ConvertRegion(*gammaNode.subregion(i), gammaBlock);
928 auto gammaResult =
929 Builder_->create<::mlir::rvsdg::GammaResult>(Builder_->getUnknownLoc(), regionResults);
930 gammaBlock.push_back(gammaResult);
931 }
932
933 return gamma;
934}
935
936::mlir::Operation *
938 const rvsdg::ThetaNode & thetaNode,
939 ::mlir::Block & block,
940 const ::llvm::SmallVector<::mlir::Value> & inputs)
941{
942 ::llvm::SmallVector<::mlir::Type> outputTypeRange;
943 for (size_t i = 0; i < thetaNode.noutputs(); ++i)
944 {
945 outputTypeRange.push_back(ConvertType(*thetaNode.output(i)->Type()));
946 }
947
948 ::llvm::SmallVector<::mlir::NamedAttribute> attributes;
949
950 auto theta = Builder_->create<::mlir::rvsdg::ThetaNode>(
951 Builder_->getUnknownLoc(),
952 ::mlir::TypeRange(::llvm::ArrayRef(outputTypeRange)),
953 ::mlir::ValueRange(::llvm::ArrayRef(inputs)),
954 attributes);
955
956 block.push_back(theta);
957 auto & thetaBlock = theta.getRegion().emplaceBlock();
958 auto regionResults = ConvertRegion(*thetaNode.subregion(), thetaBlock);
959 auto results = ::mlir::ValueRange({ std::next(regionResults.begin()), regionResults.end() });
960 auto thetaResult = Builder_->create<::mlir::rvsdg::ThetaResult>(
961 Builder_->getUnknownLoc(),
962 regionResults[0],
963 results);
964 thetaBlock.push_back(thetaResult);
965 return theta;
966}
967
968::mlir::Operation *
970 const rvsdg::DeltaNode & deltaNode,
971 ::mlir::Block & block,
972 const ::llvm::SmallVector<::mlir::Value> & inputs)
973{
974 auto op = util::assertedCast<const llvm::LlvmDeltaOperation>(&deltaNode.GetOperation());
975 auto delta = Builder_->create<::mlir::rvsdg::DeltaNode>(
976 Builder_->getUnknownLoc(),
977 Builder_->getType<::mlir::LLVM::LLVMPointerType>(),
978 inputs,
979 ::llvm::StringRef(op->name()),
980 ::llvm::StringRef(llvm::linkageToString(op->linkage())),
981 ::llvm::StringRef(op->Section()),
982 op->constant());
983 block.push_back(delta);
984 auto & deltaBlock = delta.getRegion().emplaceBlock();
985 auto regionResults = ConvertRegion(*deltaNode.subregion(), deltaBlock);
986 JLM_ASSERT(regionResults.size() == 1); // Delta nodes have 1 output
987 auto deltaResult =
988 Builder_->create<::mlir::rvsdg::DeltaResult>(Builder_->getUnknownLoc(), regionResults[0]);
989 deltaBlock.push_back(deltaResult);
990 return delta;
991}
992
993::mlir::FloatType
995{
996 switch (size)
997 {
999 return Builder_->getF16Type();
1001 return Builder_->getF32Type();
1003 return Builder_->getF64Type();
1005 return Builder_->getF80Type();
1007 return Builder_->getF128Type();
1008 default:
1009 auto message = util::strfmt(
1010 "Floating point type conversion not implemented: ",
1011 llvm::FloatingPointType(size).debug_string());
1012 JLM_UNREACHABLE(message.c_str());
1013 }
1014}
1015
1016::mlir::FunctionType
1018{
1019 ::llvm::SmallVector<::mlir::Type> argumentTypes;
1020 for (size_t i = 0; i < functionType.NumArguments(); i++)
1021 {
1022 argumentTypes.push_back(ConvertType(functionType.ArgumentType(i)));
1023 }
1024 ::llvm::SmallVector<::mlir::Type> resultTypes;
1025 for (size_t i = 0; i < functionType.NumResults(); i++)
1026 {
1027 resultTypes.push_back(ConvertType(functionType.ResultType(i)));
1028 }
1029 return Builder_->getFunctionType(argumentTypes, resultTypes);
1030}
1031
1032::mlir::Type
1034{
1035 if (auto bt = dynamic_cast<const rvsdg::BitType *>(&type))
1036 {
1037 return Builder_->getIntegerType(bt->nbits());
1038 }
1039 else if (auto fpt = dynamic_cast<const jlm::llvm::FloatingPointType *>(&type))
1040 {
1041 return ConvertFPType(fpt->size());
1042 }
1043 else if (rvsdg::is<llvm::IOStateType>(type))
1044 {
1045 return Builder_->getType<::mlir::rvsdg::IOStateEdgeType>();
1046 }
1047 else if (rvsdg::is<llvm::MemoryStateType>(type))
1048 {
1049 return Builder_->getType<::mlir::rvsdg::MemStateEdgeType>();
1050 }
1051 else if (auto clt = dynamic_cast<const rvsdg::ControlType *>(&type))
1052 {
1053 return Builder_->getType<::mlir::rvsdg::RVSDG_CTRLType>(clt->nalternatives());
1054 }
1055 else if (rvsdg::is<llvm::PointerType>(type))
1056 {
1057 return Builder_->getType<::mlir::LLVM::LLVMPointerType>();
1058 }
1059 else if (auto arrayType = dynamic_cast<const llvm::ArrayType *>(&type))
1060 {
1061 return Builder_->getType<::mlir::LLVM::LLVMArrayType>(
1062 ConvertType(arrayType->element_type()),
1063 arrayType->nelements());
1064 }
1065 else if (auto functionType = dynamic_cast<const jlm::rvsdg::FunctionType *>(&type))
1066 {
1067 return ConvertFunctionType(*functionType);
1068 }
1070 {
1071 return Builder_->getType<::mlir::jlm::VarargListType>();
1072 }
1073 else if (rvsdg::is<const rvsdg::UnitType>(type))
1074 {
1075 return Builder_->getType<::mlir::NoneType>();
1076 }
1077 else if (auto structType = dynamic_cast<const llvm::StructType *>(&type))
1078 {
1079 std::vector<::mlir::Type> elements;
1080 for (size_t i = 0; i < structType->numElements(); i++)
1081 {
1082 elements.push_back(ConvertType(*structType->getElementType(i)));
1083 }
1084
1085 if (structType->IsLiteral())
1086 {
1087 return ::mlir::LLVM::LLVMStructType::getLiteral(
1088 Builder_->getContext(),
1089 elements,
1090 structType->IsPacked());
1091 }
1092 else
1093 {
1094 auto mlirStructType = ::mlir::LLVM::LLVMStructType::getIdentified(
1095 Builder_->getContext(),
1096 structType->GetName());
1097 if (mlirStructType.isInitialized())
1098 return mlirStructType;
1099 if (mlirStructType.setBody(elements, structType->IsPacked()).failed())
1100 {
1101 throw util::Error("Not able to set the body of struct in the MLIR backend.");
1102 }
1103 return mlirStructType;
1104 }
1105 }
1106 else
1107 {
1108 auto message = util::strfmt("Type conversion not implemented: ", type.debug_string());
1109 JLM_UNREACHABLE(message.c_str());
1110 }
1111}
1112
1113::mlir::Operation *
1115 const jlm::llvm::IntegerBinaryOperation & operation,
1116 ::llvm::SmallVector<::mlir::Value> inputs)
1117{
1119 {
1120 return Builder_->create<::mlir::arith::AddIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
1121 }
1123 {
1124 return Builder_->create<::mlir::arith::SubIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
1125 }
1127 {
1128 return Builder_->create<::mlir::arith::MulIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
1129 }
1131 {
1132 return Builder_->create<::mlir::arith::DivSIOp>(
1133 Builder_->getUnknownLoc(),
1134 inputs[0],
1135 inputs[1]);
1136 }
1138 {
1139 return Builder_->create<::mlir::arith::DivUIOp>(
1140 Builder_->getUnknownLoc(),
1141 inputs[0],
1142 inputs[1]);
1143 }
1145 {
1146 return Builder_->create<::mlir::arith::RemSIOp>(
1147 Builder_->getUnknownLoc(),
1148 inputs[0],
1149 inputs[1]);
1150 }
1152 {
1153 return Builder_->create<::mlir::arith::RemUIOp>(
1154 Builder_->getUnknownLoc(),
1155 inputs[0],
1156 inputs[1]);
1157 }
1159 {
1160 return Builder_->create<::mlir::LLVM::AShrOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
1161 }
1163 {
1164 return Builder_->create<::mlir::LLVM::ShlOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
1165 }
1167 {
1168 return Builder_->create<::mlir::LLVM::LShrOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
1169 }
1171 {
1172 return Builder_->create<::mlir::arith::AndIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
1173 }
1174 else if (rvsdg::is<jlm::llvm::IntegerOrOperation>(operation))
1175 {
1176 return Builder_->create<::mlir::arith::OrIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
1177 }
1179 {
1180 return Builder_->create<::mlir::arith::XOrIOp>(Builder_->getUnknownLoc(), inputs[0], inputs[1]);
1181 }
1182 else if (rvsdg::is<jlm::llvm::IntegerEqOperation>(operation))
1183 {
1184 return Builder_->create<::mlir::arith::CmpIOp>(
1185 Builder_->getUnknownLoc(),
1186 ::mlir::arith::CmpIPredicate::eq,
1187 inputs[0],
1188 inputs[1]);
1189 }
1190 else if (rvsdg::is<jlm::llvm::IntegerNeOperation>(operation))
1191 {
1192 return Builder_->create<::mlir::arith::CmpIOp>(
1193 Builder_->getUnknownLoc(),
1194 ::mlir::arith::CmpIPredicate::ne,
1195 inputs[0],
1196 inputs[1]);
1197 }
1199 {
1200 return Builder_->create<::mlir::arith::CmpIOp>(
1201 Builder_->getUnknownLoc(),
1202 ::mlir::arith::CmpIPredicate::sge,
1203 inputs[0],
1204 inputs[1]);
1205 }
1207 {
1208 return Builder_->create<::mlir::arith::CmpIOp>(
1209 Builder_->getUnknownLoc(),
1210 ::mlir::arith::CmpIPredicate::sgt,
1211 inputs[0],
1212 inputs[1]);
1213 }
1215 {
1216 return Builder_->create<::mlir::arith::CmpIOp>(
1217 Builder_->getUnknownLoc(),
1218 ::mlir::arith::CmpIPredicate::sle,
1219 inputs[0],
1220 inputs[1]);
1221 }
1223 {
1224 return Builder_->create<::mlir::arith::CmpIOp>(
1225 Builder_->getUnknownLoc(),
1226 ::mlir::arith::CmpIPredicate::slt,
1227 inputs[0],
1228 inputs[1]);
1229 }
1231 {
1232 return Builder_->create<::mlir::arith::CmpIOp>(
1233 Builder_->getUnknownLoc(),
1234 ::mlir::arith::CmpIPredicate::uge,
1235 inputs[0],
1236 inputs[1]);
1237 }
1239 {
1240 return Builder_->create<::mlir::arith::CmpIOp>(
1241 Builder_->getUnknownLoc(),
1242 ::mlir::arith::CmpIPredicate::ugt,
1243 inputs[0],
1244 inputs[1]);
1245 }
1247 {
1248 return Builder_->create<::mlir::arith::CmpIOp>(
1249 Builder_->getUnknownLoc(),
1250 ::mlir::arith::CmpIPredicate::ule,
1251 inputs[0],
1252 inputs[1]);
1253 }
1255 {
1256 return Builder_->create<::mlir::arith::CmpIOp>(
1257 Builder_->getUnknownLoc(),
1258 ::mlir::arith::CmpIPredicate::ult,
1259 inputs[0],
1260 inputs[1]);
1261 }
1262 else
1263 {
1264 auto message =
1265 util::strfmt("Unimplemented integer binary operation: ", operation.debug_string());
1266 JLM_UNREACHABLE(message.c_str());
1267 }
1268}
1269
1270} // namespace jlm::mlir
Call operation class.
Definition call.hpp:251
ConstantPointerNullOperation class.
const llvm::fpop & fpop() const noexcept
const fpcmp & cmp() const noexcept
const jlm::llvm::Linkage & linkage() const noexcept
Definition lambda.hpp:48
const std::string & name() const noexcept
Definition lambda.hpp:42
ICmpPredicate predicate() const noexcept
StructType class.
Definition types.hpp:184
UndefValueOperation class.
::mlir::Operation * ConvertDelta(const rvsdg::DeltaNode &node, ::mlir::Block &block, const ::llvm::SmallVector<::mlir::Value > &inputs)
::llvm::SmallVector<::mlir::Value > ConvertRegion(rvsdg::Region &region, ::mlir::Block &block, bool isRoot=false)
::mlir::FloatType ConvertFPType(const llvm::fpsize size)
::mlir::FunctionType ConvertFunctionType(const jlm::rvsdg::FunctionType &functionType)
::mlir::Operation * ConvertTheta(const rvsdg::ThetaNode &thetaNode, ::mlir::Block &block, const ::llvm::SmallVector<::mlir::Value > &inputs)
::mlir::Type ConvertType(const rvsdg::Type &type)
::mlir::Operation * ConvertNode(const rvsdg::Node &node, ::mlir::Block &block, const ::llvm::SmallVector<::mlir::Value > &inputs)
::mlir::Operation * BitCompareNode(const rvsdg::SimpleOperation &bitOp, ::llvm::SmallVector<::mlir::Value > inputs)
::llvm::SmallVector<::mlir::Type > GetMemStateRange(size_t nresults)
::mlir::Operation * ConvertPointerCompareNode(const llvm::PtrCmpOperation &pointerCompareOp, ::llvm::SmallVector<::mlir::Value > inputs)
::mlir::Operation * ConvertGamma(const rvsdg::GammaNode &gammaNode, ::mlir::Block &block, const ::llvm::SmallVector<::mlir::Value > &inputs)
static void Print(::mlir::rvsdg::OmegaNode &omega, const util::FilePath &filePath)
static ::llvm::SmallVector<::mlir::Value > GetConvertedInputs(const rvsdg::Node &node, const std::unordered_map< rvsdg::Output *, ::mlir::Value > &valueMap)
::mlir::Operation * ConvertFpBinaryNode(const jlm::llvm::FBinaryOperation &op, ::llvm::SmallVector<::mlir::Value > inputs)
::mlir::Operation * ConvertLambda(const rvsdg::LambdaNode &node, ::mlir::Block &block, const ::llvm::SmallVector<::mlir::Value > &inputs)
::mlir::Operation * ConvertIntegerBinaryOperation(const jlm::llvm::IntegerBinaryOperation &operation, ::llvm::SmallVector<::mlir::Value > inputs)
::mlir::Operation * ConvertBitBinaryNode(const rvsdg::SimpleOperation &bitOp, ::llvm::SmallVector<::mlir::Value > inputs)
::mlir::Operation * ConvertSimpleNode(const rvsdg::SimpleNode &node, ::mlir::Block &block, const ::llvm::SmallVector<::mlir::Value > &inputs)
::mlir::rvsdg::OmegaNode ConvertModule(const llvm::LlvmRvsdgModule &rvsdgModule)
std::unique_ptr<::mlir::OpBuilder > Builder_
::mlir::Operation * ConvertFpCompareNode(const jlm::llvm::FCmpOperation &op, ::llvm::SmallVector<::mlir::Value > inputs)
const DeltaOperation & GetOperation() const noexcept override
Definition delta.cpp:71
rvsdg::Region * subregion() const noexcept
Definition delta.hpp:234
Function type class.
const jlm::rvsdg::Type & ArgumentType(size_t index) const noexcept
size_t NumArguments() const noexcept
size_t NumResults() const noexcept
const jlm::rvsdg::Type & ResultType(size_t index) const noexcept
Conditional operator / pattern matching.
Definition gamma.hpp:99
const GammaOperation & GetOperation() const noexcept override
Definition gamma.cpp:254
Output * origin() const noexcept
Definition node.hpp:58
rvsdg::Output * output() const noexcept
Definition lambda.cpp:177
rvsdg::Region * subregion() const noexcept
Definition lambda.hpp:138
LambdaOperation & GetOperation() const noexcept override
Definition lambda.cpp:52
NodeInput * input(size_t index) const noexcept
Definition node.hpp:615
virtual std::string DebugString() const =0
size_t ninputs() const noexcept
Definition node.hpp:609
size_t noutputs() const noexcept
Definition node.hpp:644
virtual std::string debug_string() const =0
virtual std::string debug_string() const
Definition node.cpp:168
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition node.hpp:366
std::string debug_string() const override
Definition region.cpp:100
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
RegionArgument * argument(size_t index) const noexcept
Definition region.hpp:466
size_t nresults() const noexcept
Definition region.hpp:494
RegionResult * result(size_t index) const noexcept
Definition region.hpp:500
size_t narguments() const noexcept
Definition region.hpp:460
Graph & Rvsdg() noexcept
const SimpleOperation & GetOperation() const noexcept override
NodeOutput * output(size_t index) const noexcept
rvsdg::Region * subregion(size_t index) const noexcept
StructuralOutput * output(size_t index) const noexcept
rvsdg::Region * subregion() const noexcept
Definition theta.hpp:79
virtual std::string debug_string() const =0
const std::string & to_str() const noexcept
Definition file.hpp:275
#define JLM_ASSERT(x)
Definition common.hpp:16
#define JLM_UNREACHABLE(msg)
Definition common.hpp:43
std::string_view linkageToString(const Linkage linkage)
Definition Linkage.cpp:17
const util::BijectiveMap<::mlir::arith::CmpFPredicate, llvm::fpcmp > & GetFpCmpPredicateMap()
::mlir::ArrayAttr memoryNodeIndicesToArrayAttr(::mlir::MLIRContext *context, const std::vector< llvm::MemoryNodeId > &memoryNodeIndices)
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872
detail::TopDownTraverserGeneric< false > TopDownTraverser
Traverser for visiting every node in a region in a top down order.
static std::string strfmt(Args... args)
Definition strfmt.hpp:35