51 #include <llvm/IR/LLVMContext.h>
52 #include <llvm/IR/Module.h>
53 #include <llvm/Support/raw_ostream.h>
54 #include <llvm/Support/SourceMgr.h>
102 const std::regex fn_regex(function_name);
103 if (std::regex_match(
119 if (
auto theta = rvsdg::TryGetOwnerNode<rvsdg::ThetaNode>(*input->
origin()))
123 else if (argument ==
nullptr)
127 else if (argument->region() == &graph->GetRootRegion())
146 for (
size_t n = 0; n < structnode->nsubregions(); n++)
159 if (graphImport->Name().rfind(
"decouple_", 0) == 0)
164 if (graphImport->Name().rfind(
"hls_", 0) == 0)
169 throw util::Error(
"can not inline external function " + graphImport->Name());
172 JLM_ASSERT(rvsdg::is<rvsdg::LambdaOperation>(so->node()));
187 auto op = util::assertedCast<const llvm::DeltaOperation>(&odn->
GetOperation());
188 auto name = op->name();
197 std::cout <<
"renaming delta node " << op->name() <<
" to " << name <<
"\n";
206 op->getAlignment()));
211 auto input = ctxVar.input;
212 auto nd = db->AddContextVar(*input->origin()).inner;
213 rmap.
insert(ctxVar.inner, nd);
220 auto data = &db->finalize(result);
224 return rvsdg::TryGetOwnerNode<rvsdg::DeltaNode>(*data);
237 op.callingConvention(),
244 auto origin = cv.input->origin();
245 auto newcv = lambda->AddContextVar(*origin);
246 subregionmap.
insert(cv.inner, newcv.inner);
250 auto newArgs = lambda->GetFunctionArguments();
252 for (std::size_t n = 0; n < args.size(); ++n)
254 subregionmap.
insert(args[n], newArgs[n]);
261 std::vector<jlm::rvsdg::Output *> results;
263 results.push_back(&subregionmap.
lookup(*result->origin()));
266 lambda->finalize(results);
274 std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
295 for (
size_t i = 0; i < ln->ninputs(); ++i)
297 auto orig_node_output =
dynamic_cast<rvsdg::NodeOutput *
>(ln->input(i)->origin());
298 if (!orig_node_output)
302 auto & newGraphImport = oldGraphImport->
Copy(rhls->Rvsdg().GetRootRegion(),
nullptr);
303 smap.
insert(ln->input(i)->origin(), &newGraphImport);
306 auto orig_node = orig_node_output->node();
310 "Inlining of function "
316 auto op = util::assertedCast<const llvm::DeltaOperation>(&odn->GetOperation());
318 if (op->name().find(
'.') != std::string::npos)
321 op = util::assertedCast<const llvm::DeltaOperation>(&odn->GetOperation());
323 std::cout <<
"delta node " << op->name() <<
": " << op->Type()->debug_string() <<
"\n";
333 smap.
insert(ln->input(i)->origin(), &graphImport);
340 throw util::Error(
"Unsupported node type: " + orig_node->DebugString());
344 auto new_ln = ln->copy(&rhls->Rvsdg().GetRootRegion(), smap);
356 ln->output()->divert_users(&graphImport);
358 std::cout <<
"function "
360 <<
" extracted for HLS\n";
364 throw util::Error(
"HLS function " + function_name +
" not found");
373 std::unique_ptr<rvsdg::TransformationSequence>
376 auto predicateCorrelation = std::make_shared<llvm::PredicateCorrelation>();
377 auto deadNodeElimination = std::make_shared<llvm::DeadNodeElimination>();
378 auto commonNodeElimination = std::make_shared<CommonNodeElimination>();
379 auto invariantValueRedirection = std::make_shared<llvm::InvariantValueRedirection>(
381 auto loopUnswitching =
383 auto ioBarrierRemoval = std::make_shared<IOBarrierRemoval>();
384 auto ioStateElimination = std::make_shared<IOStateElimination>();
385 auto memoryStateSeparation = std::make_shared<MemoryStateSeparation>();
386 auto gammaMerge = std::make_shared<GammaMerge>();
387 auto unusedStateRemoval = std::make_shared<UnusedStateRemoval>();
388 auto constantDistribution = std::make_shared<ConstantDistribution>();
389 auto gammaNodeConversion = std::make_shared<GammaNodeConversion>();
390 auto thetaNodeConversion = std::make_shared<ThetaNodeConversion>();
391 auto rhlsDeadNodeElimination = std::make_shared<RhlsDeadNodeElimination>();
392 auto allocaNodeConversion = std::make_shared<AllocaNodeConversion>();
393 auto streamConversion = std::make_shared<StreamConversion>();
394 auto addressQueueInsertion = std::make_shared<AddressQueueInsertion>();
395 auto memoryStateDecoupling = std::make_shared<MemoryStateDecoupling>();
396 auto memoryConverter = std::make_shared<MemoryConverter>();
397 auto nodeReduction = std::make_shared<llvm::NodeReduction>();
398 auto memoryStateSplitConversion = std::make_shared<MemoryStateSplitConversion>();
399 auto redundantBufferElimination = std::make_shared<RedundantBufferElimination>();
400 auto sinkInsertion = std::make_shared<SinkInsertion>();
401 auto forkInsertion = std::make_shared<ForkInsertion>();
402 auto bufferInsertion = std::make_shared<BufferInsertion>();
403 auto rhlsVerification = std::make_shared<RhlsVerification>();
406 [[maybe_unused]]
auto dumpDot = std::make_shared<DumpDotTransformation>();
408 std::vector<std::shared_ptr<rvsdg::Transformation>> sequence({
411 commonNodeElimination,
412 invariantValueRedirection,
413 predicateCorrelation,
415 commonNodeElimination,
419 memoryStateSeparation,
424 commonNodeElimination,
429 constantDistribution,
433 commonNodeElimination,
434 rhlsDeadNodeElimination,
435 allocaNodeConversion,
437 addressQueueInsertion,
438 memoryStateDecoupling,
442 memoryStateSplitConversion,
443 redundantBufferElimination,
450 return std::make_unique<rvsdg::TransformationSequence>(
459 const std::unique_ptr<llvm::LlvmRvsdgModule> reference(
463 for (
size_t i = 0; i < reference->Rvsdg().GetRootRegion().narguments(); ++i)
465 auto graphImport = util::assertedCast<const llvm::LlvmGraphImport>(
466 reference->Rvsdg().GetRootRegion().argument(i));
467 std::cout <<
"impport " << graphImport->Name() <<
": " << graphImport->Type()->debug_string()
470 ::llvm::LLVMContext ctx;
475 ::llvm::raw_fd_ostream os(path.
to_str(), EC);
476 lm2->print(os,
nullptr);
static jlm::util::StatisticsCollector statisticsCollector
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
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 Linkage &linkage, std::string section, bool constant, const size_t alignment)
static void inlineCall(rvsdg::SimpleNode &callNode, rvsdg::LambdaNode &caller, const rvsdg::LambdaNode &callee)
Invariant Value Redirection.
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 & createGlobalImport(rvsdg::Graph &graph, std::shared_ptr< const rvsdg::Type > valueType, std::shared_ptr< const rvsdg::Type > importedType, std::string name, Linkage linkage, const bool isConstant, const size_t alignment)
static LlvmGraphImport & createFunctionImport(rvsdg::Graph &graph, std::shared_ptr< const rvsdg::FunctionType > functionType, std::string name, Linkage linkage, CallingConvention callingConvention)
LlvmGraphImport & Copy(rvsdg::Region ®ion, rvsdg::StructuralInput *input) const override
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)
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
static std::shared_ptr< const LoopUnswitchingDefaultHeuristic > create()
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
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
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)
std::unique_ptr< rvsdg::TransformationSequence > createTransformationSequence(rvsdg::DotWriter &dotWriter, const bool dumpRvsdgGraphs)
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< 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)
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)