50 #include <llvm/IR/LLVMContext.h>
51 #include <llvm/IR/Module.h>
52 #include <llvm/Support/raw_ostream.h>
53 #include <llvm/Support/SourceMgr.h>
70 tgi.
Run(rm, statisticsCollector);
71 dne.
Run(rm, statisticsCollector);
72 cne.
Run(rm, statisticsCollector);
73 ivr.
Run(rm, statisticsCollector);
74 red.
Run(rm, statisticsCollector);
75 dne.
Run(rm, statisticsCollector);
87 tgi.
Run(rm, statisticsCollector);
88 dne.
Run(rm, statisticsCollector);
89 cne.
Run(rm, statisticsCollector);
90 ivr.
Run(rm, statisticsCollector);
91 dne.
Run(rm, statisticsCollector);
92 cne.
Run(rm, statisticsCollector);
93 dne.
Run(rm, statisticsCollector);
99 auto xml_file = fopen(file_name.c_str(),
"w");
107 const std::regex fn_regex(function_name);
108 if (std::regex_match(
124 if (
auto theta = rvsdg::TryGetOwnerNode<rvsdg::ThetaNode>(*input->
origin()))
128 else if (argument ==
nullptr)
132 else if (argument->region() == &graph->GetRootRegion())
151 for (
size_t n = 0; n < structnode->nsubregions(); n++)
164 if (graphImport->Name().rfind(
"decouple_", 0) == 0)
169 if (graphImport->Name().rfind(
"hls_", 0) == 0)
174 throw util::Error(
"can not inline external function " + graphImport->Name());
177 JLM_ASSERT(rvsdg::is<rvsdg::LambdaOperation>(so->node()));
198 for (
size_t n = 0; n < structnode->nsubregions(); n++)
208 std::cout <<
"alloca " << delta_name <<
": " << po->value_type().debug_string() <<
"\n";
223 bt->Representation().nbits(),
231 auto delta = &db->finalize(cout);
234 node->output(0)->divert_users(delta_local);
238 auto & mux_in = *node->output(1)->Users().begin();
239 auto mux_node = rvsdg::TryGetOwnerNode<rvsdg::Node>(mux_in);
244 auto other_index = mux_in.index() ? 0 : 1;
245 mux_node->output(0)->divert_users(mux_node->input(other_index)->origin());
262 auto op = util::assertedCast<const llvm::DeltaOperation>(&odn->
GetOperation());
263 auto name = op->name();
272 std::cout <<
"renaming delta node " << op->name() <<
" to " << name <<
"\n";
285 auto input = ctxVar.input;
286 auto nd = db->AddContextVar(*input->origin()).inner;
287 rmap.
insert(ctxVar.inner, nd);
294 auto data = &db->finalize(result);
298 return rvsdg::TryGetOwnerNode<rvsdg::DeltaNode>(*data);
313 auto origin = cv.input->origin();
314 auto newcv = lambda->AddContextVar(*origin);
315 subregionmap.
insert(cv.inner, newcv.inner);
319 auto newArgs = lambda->GetFunctionArguments();
321 for (std::size_t n = 0; n < args.size(); ++n)
323 subregionmap.
insert(args[n], newArgs[n]);
330 std::vector<jlm::rvsdg::Output *> results;
332 results.push_back(&subregionmap.
lookup(*result->origin()));
335 lambda->finalize(results);
343 std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
364 for (
size_t i = 0; i < ln->ninputs(); ++i)
366 auto orig_node_output =
dynamic_cast<rvsdg::NodeOutput *
>(ln->input(i)->origin());
367 if (!orig_node_output)
373 oldGraphImport->ValueType(),
374 oldGraphImport->ImportedType(),
375 oldGraphImport->Name(),
376 oldGraphImport->linkage());
377 smap.
insert(ln->input(i)->origin(), &newGraphImport);
380 auto orig_node = orig_node_output->node();
384 "Inlining of function "
390 auto op = util::assertedCast<const llvm::DeltaOperation>(&odn->GetOperation());
392 if (op->name().find(
'.') != std::string::npos)
395 op = util::assertedCast<const llvm::DeltaOperation>(&odn->GetOperation());
397 std::cout <<
"delta node " << op->name() <<
": " << op->Type()->debug_string() <<
"\n";
405 smap.
insert(ln->input(i)->origin(), &graphImport);
412 throw util::Error(
"Unsupported node type: " + orig_node->DebugString());
416 auto new_ln = ln->copy(&rhls->Rvsdg().GetRootRegion(), smap);
428 ln->output()->divert_users(&graphImport);
430 std::cout <<
"function "
432 <<
" extracted for HLS\n";
436 throw util::Error(
"HLS function " + function_name +
" not found");
445 std::unique_ptr<rvsdg::TransformationSequence>
448 auto predicateCorrelation = std::make_shared<llvm::PredicateCorrelation>();
449 auto deadNodeElimination = std::make_shared<llvm::DeadNodeElimination>();
450 auto commonNodeElimination = std::make_shared<CommonNodeElimination>();
451 auto invariantValueRedirection = std::make_shared<llvm::InvariantValueRedirection>();
452 auto loopUnswitching = std::make_shared<llvm::LoopUnswitching>();
453 auto ioBarrierRemoval = std::make_shared<IOBarrierRemoval>();
454 auto ioStateElimination = std::make_shared<IOStateElimination>();
455 auto memoryStateSeparation = std::make_shared<MemoryStateSeparation>();
456 auto gammaMerge = std::make_shared<GammaMerge>();
457 auto unusedStateRemoval = std::make_shared<UnusedStateRemoval>();
458 auto constantDistribution = std::make_shared<ConstantDistribution>();
459 auto gammaNodeConversion = std::make_shared<GammaNodeConversion>();
460 auto thetaNodeConversion = std::make_shared<ThetaNodeConversion>();
461 auto rhlsDeadNodeElimination = std::make_shared<RhlsDeadNodeElimination>();
462 auto allocaNodeConversion = std::make_shared<AllocaNodeConversion>();
463 auto streamConversion = std::make_shared<StreamConversion>();
464 auto addressQueueInsertion = std::make_shared<AddressQueueInsertion>();
465 auto memoryStateDecoupling = std::make_shared<MemoryStateDecoupling>();
466 auto memoryConverter = std::make_shared<MemoryConverter>();
467 auto nodeReduction = std::make_shared<llvm::NodeReduction>();
468 auto memoryStateSplitConversion = std::make_shared<MemoryStateSplitConversion>();
469 auto redundantBufferElimination = std::make_shared<RedundantBufferElimination>();
470 auto sinkInsertion = std::make_shared<SinkInsertion>();
471 auto forkInsertion = std::make_shared<ForkInsertion>();
472 auto bufferInsertion = std::make_shared<BufferInsertion>();
473 auto rhlsVerification = std::make_shared<RhlsVerification>();
476 [[maybe_unused]]
auto dumpDot = std::make_shared<DumpDotTransformation>();
478 std::vector<std::shared_ptr<rvsdg::Transformation>> sequence({
481 commonNodeElimination,
482 invariantValueRedirection,
483 predicateCorrelation,
485 commonNodeElimination,
489 memoryStateSeparation,
494 commonNodeElimination,
499 constantDistribution,
503 commonNodeElimination,
504 rhlsDeadNodeElimination,
505 allocaNodeConversion,
507 addressQueueInsertion,
508 memoryStateDecoupling,
512 memoryStateSplitConversion,
513 redundantBufferElimination,
520 return std::make_unique<rvsdg::TransformationSequence>(
529 const std::unique_ptr<llvm::LlvmRvsdgModule> reference(
533 for (
size_t i = 0; i < reference->Rvsdg().GetRootRegion().narguments(); ++i)
535 auto graphImport = util::assertedCast<const llvm::LlvmGraphImport>(
536 reference->Rvsdg().GetRootRegion().argument(i));
537 std::cout <<
"impport " << graphImport->Name() <<
": " << graphImport->Type()->debug_string()
540 ::llvm::LLVMContext ctx;
545 ::llvm::raw_fd_ostream os(path.
to_str(), EC);
546 lm2->print(os,
nullptr);
Common Node Elimination This is mainly a copy of the CNE optimization in the LLVM backend with the ad...
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
rvsdg::GraphExport * GetRvsdgExport() const noexcept
static jlm::rvsdg::Output * Create(rvsdg::Region ®ion, std::shared_ptr< const jlm::rvsdg::Type > type)
Dead Node Elimination Optimization.
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
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 void inlineCall(rvsdg::SimpleNode &callNode, rvsdg::LambdaNode &caller, const rvsdg::LambdaNode &callee)
static rvsdg::Node & Create(rvsdg::Region ®ion, IntegerValueRepresentation representation)
Invariant Value Redirection Optimization.
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
static std::unique_ptr<::llvm::Module > CreateAndConvertModule(InterProceduralGraphModule &ipGraphModule, ::llvm::LLVMContext &ctx)
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)
const std::string & name() const noexcept
const util::FilePath & SourceFileName() const noexcept
const std::string & TargetTriple() const noexcept
static std::unique_ptr< LlvmRvsdgModule > Create(const util::FilePath &sourceFileName, const std::string &targetTriple, const std::string &dataLayout)
std::unique_ptr< RvsdgModule > copy() const override
const std::string & DataLayout() const noexcept
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
static std::shared_ptr< const PointerType > Create()
static std::unique_ptr< InterProceduralGraphModule > CreateAndConvertModule(LlvmRvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector)
std::vector< ContextVar > GetContextVars() const noexcept
Gets all bound context variables.
rvsdg::Region * subregion() const noexcept
const DeltaOperation & GetOperation() const noexcept override
static DeltaNode * Create(rvsdg::Region *parent, std::unique_ptr< DeltaOperation > op)
rvsdg::Output & output() const noexcept
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
static GraphExport & Create(Output &origin, std::string name)
Region & GetRootRegion() const noexcept
std::vector< rvsdg::Output * > GetFunctionArguments() const
rvsdg::Region * subregion() const noexcept
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
std::vector< rvsdg::Input * > GetFunctionResults() const
std::vector< ContextVar > GetContextVars() const noexcept
Gets all bound context variables.
LambdaOperation & GetOperation() const noexcept override
rvsdg::Region * region() const noexcept
NodeOutput * output(size_t index) const noexcept
void divert_users(jlm::rvsdg::Output *new_origin)
Represents the argument of a region.
Represent acyclic RVSDG subgraphs.
RegionResult * result(size_t index) const noexcept
void copy(Region *target, SubstitutionMap &smap) const
Copy a region with substitutions.
Graph * graph() const noexcept
void insert(const Output *original, Output *substitute)
Output & lookup(const Output &original) const
std::string name() const noexcept
Returns the name of the file, excluding the path.
const std::string & to_str() const noexcept
void dump_xml(llvm::LlvmRvsdgModule &rvsdgModule, const std::string &file_name)
void convert_alloca(rvsdg::Region *region)
rvsdg::LambdaNode * change_linkage(rvsdg::LambdaNode *ln, llvm::Linkage link)
rvsdg::DeltaNode * rename_delta(rvsdg::DeltaNode *odn)
bool function_match(rvsdg::LambdaNode *ln, const std::string &function_name)
void split_opt(llvm::LlvmRvsdgModule &rm)
void inline_calls(rvsdg::Region *region)
static void divert_users(jlm::rvsdg::Output *output, Context &ctx)
void instrument_ref(llvm::LlvmRvsdgModule &rm)
void dump_ref(llvm::LlvmRvsdgModule &rhls, const util::FilePath &path)
void pre_opt(jlm::llvm::LlvmRvsdgModule &rm)
std::unique_ptr< rvsdg::TransformationSequence > createTransformationSequence(rvsdg::DotWriter &dotWriter, const bool dumpRvsdgDotGraphs)
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > split_hls_function(llvm::LlvmRvsdgModule &rm, const std::string &function_name)
const jlm::rvsdg::Output * trace_call(jlm::rvsdg::Input *input)
void rvsdg2ref(llvm::LlvmRvsdgModule &rhls, const util::FilePath &path)
CallSummary ComputeCallSummary(const rvsdg::LambdaNode &lambdaNode)
static void remove(Node *node)
Output & RouteToRegion(Output &output, Region ®ion)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
void view_xml(const rvsdg::Region *region, FILE *out)
static std::string strfmt(Args... args)