93 static std::unique_ptr<Context>
96 return std::make_unique<Context>(ipGraphModule);
103 std::unordered_map<const rvsdg::Output *, const llvm::Variable *>
VariableMap_;
129 static std::unique_ptr<Statistics>
132 return std::make_unique<Statistics>(sourceFile);
143 const auto variable =
Context_->GetVariable(&output);
144 if (
const auto functionVariable =
dynamic_cast<const FunctionVariable *
>(variable))
146 return *functionVariable->function();
149 if (
const auto globalValue =
dynamic_cast<const GlobalValue *
>(variable))
151 return *globalValue->node();
154 throw std::logic_error(
"Unhandled variable type.");
157 std::unique_ptr<DataNodeInit>
160 const auto subregion = deltaNode.
subregion();
163 for (
size_t n = 0; n < deltaNode.
ninputs(); n++)
169 if (subregion->numNodes() == 0)
171 auto value =
Context_->GetVariable(subregion->result(0)->origin());
172 return std::make_unique<DataNodeInit>(value);
179 const auto output = node->output(0);
182 std::vector<const Variable *>
operands;
183 for (
size_t n = 0; n < node->ninputs(); n++)
187 auto op = node->GetOperation().copy();
189 std::unique_ptr<rvsdg::SimpleOperation>(
190 util::assertedCast<rvsdg::SimpleOperation>(op.release())),
192 Context_->InsertVariable(output, tacs.back()->result(0));
195 return std::make_unique<DataNodeInit>(std::move(tacs));
202 Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock);
203 Context_->SetLastProcessedBasicBlock(entryBlock);
209 Context_->GetLastProcessedBasicBlock()->add_outedge(exitBlock);
210 Context_->SetLastProcessedBasicBlock(exitBlock);
213 std::unique_ptr<ControlFlowGraph>
217 const auto & lambdaOperation = *util::assertedCast<LlvmLambdaOperation>(&lambda.
GetOperation());
221 controlFlowGraph->exit()->divert_inedges(entryBlock);
222 Context_->SetLastProcessedBasicBlock(entryBlock);
223 Context_->SetControlFlowGraph(controlFlowGraph.get());
228 auto name =
util::strfmt(
"_a", functionArgument->index(),
"_");
231 functionArgument->Type(),
232 lambdaOperation.GetArgumentAttributes(functionArgument->index()));
233 const auto variable = controlFlowGraph->entry()->append_argument(std::move(argument));
234 Context_->InsertVariable(functionArgument, variable);
240 const auto variable =
Context_->GetVariable(input->origin());
241 Context_->InsertVariable(inner, variable);
248 controlFlowGraph->exit()->append_result(
Context_->GetVariable(result->origin()));
250 Context_->GetLastProcessedBasicBlock()->add_outedge(controlFlowGraph->exit());
251 Context_->SetLastProcessedBasicBlock(
nullptr);
252 Context_->SetControlFlowGraph(
nullptr);
256 return controlFlowGraph;
262 std::vector<const Variable *>
operands;
263 for (
size_t n = 0; n < simpleNode.
ninputs(); n++)
268 std::unique_ptr<rvsdg::SimpleOperation>(
269 util::assertedCast<rvsdg::SimpleOperation>(operation.release())),
272 for (
size_t n = 0; n < simpleNode.
noutputs(); n++)
275 Context_->GetLastProcessedBasicBlock()->last()->result(n));
281 const auto numSubregions = gammaNode.
nsubregions();
283 const auto controlFlowGraph =
Context_->GetControlFlowGraph();
287 Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock);
290 std::vector<ControlFlowGraphNode *> phi_nodes;
293 for (
size_t n = 0; n < gammaNode.
nsubregions(); n++)
295 const auto subregion = gammaNode.
subregion(n);
298 for (
size_t i = 0; i < entryvars.size(); i++)
300 auto & entryvar = entryvars[i];
302 entryvar.branchArgument[n],
303 Context_->GetVariable(entryvar.input->origin()));
308 entryBlock->add_outedge(regionEntryBlock);
309 Context_->SetLastProcessedBasicBlock(regionEntryBlock);
312 phi_nodes.push_back(
Context_->GetLastProcessedBasicBlock());
313 Context_->GetLastProcessedBasicBlock()->add_outedge(exitBlock);
317 for (
size_t n = 0; n < gammaNode.
noutputs(); n++)
319 const auto output = gammaNode.
output(n);
321 bool invariant =
true;
322 std::vector<std::pair<const Variable *, ControlFlowGraphNode *>> arguments;
323 for (
size_t r = 0; r < gammaNode.
nsubregions(); r++)
327 auto v =
Context_->GetVariable(origin);
328 arguments.push_back(std::make_pair(v, phi_nodes[r]));
335 Context_->InsertVariable(output, arguments[0].first);
341 Context_->InsertVariable(output, exitBlock->last()->result(0));
344 Context_->SetLastProcessedBasicBlock(exitBlock);
362 const auto subregion = thetaNode.
subregion();
365 auto preEntryBlock =
Context_->GetLastProcessedBasicBlock();
367 preEntryBlock->add_outedge(entryBlock);
368 Context_->SetLastProcessedBasicBlock(entryBlock);
371 std::vector<llvm::ThreeAddressCode *> phis;
372 for (
const auto & loopVar : thetaNode.
GetLoopVars())
374 auto variable =
Context_->GetVariable(loopVar.input->origin());
379 variable = phi->result(0);
381 Context_->InsertVariable(loopVar.pre, variable);
388 for (
const auto & loopVar : thetaNode.
GetLoopVars())
390 auto resultVariable =
Context_->GetVariable(loopVar.post->origin());
391 Context_->InsertVariable(loopVar.output, resultVariable);
394 auto entryVariable =
Context_->GetVariable(loopVar.input->origin());
395 const auto phi = phis[phiIndex++];
398 { preEntryBlock,
Context_->GetLastProcessedBasicBlock() },
399 resultVariable->Type()),
400 { entryVariable, resultVariable });
405 Context_->GetLastProcessedBasicBlock()->append_last(
408 Context_->GetLastProcessedBasicBlock()->add_outedge(exitBlock);
409 Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock);
410 Context_->SetLastProcessedBasicBlock(exitBlock);
416 auto & ipGraphModule =
Context_->GetIpGraphModule();
417 auto & ipGraph = ipGraphModule.ipgraph();
419 const auto & operation = *util::assertedCast<LlvmLambdaOperation>(&lambdaNode.
GetOperation());
425 operation.callingConvention(),
426 operation.attributes());
432 functionNode->add_dependency(&ipGraphNode);
435 const auto variable = ipGraphModule.create_variable(functionNode);
442 const auto subregion = phiNode.
subregion();
443 auto & ipGraphModule =
Context_->GetIpGraphModule();
444 auto & ipGraph = ipGraphModule.ipgraph();
447 for (
size_t n = 0; n < phiNode.
ninputs(); n++)
454 for (
size_t n = 0; n < subregion->nresults(); n++)
456 JLM_ASSERT(subregion->argument(n)->input() ==
nullptr);
457 const auto & origin = *subregion->result(n)->origin();
459 if (
const auto lambdaNode = rvsdg::TryGetOwnerNode<rvsdg::LambdaNode>(origin))
461 const auto & lambdaOperation =
465 lambdaOperation.name(),
466 lambdaOperation.Type(),
467 lambdaOperation.linkage(),
468 lambdaOperation.callingConvention(),
469 lambdaOperation.attributes());
470 Context_->InsertVariable(subregion->argument(n), ipGraphModule.create_variable(functionNode));
472 else if (
const auto deltaNode = rvsdg::TryGetOwnerNode<rvsdg::DeltaNode>(origin))
474 auto op = util::assertedCast<const llvm::DeltaOperation>(&deltaNode->GetOperation());
483 Context_->InsertVariable(subregion->argument(n), ipGraphModule.create_global_value(dataNode));
488 "Unhandled node type: ",
489 rvsdg::AssertGetOwnerNode<rvsdg::Node>(origin).DebugString())
495 for (
size_t n = 0; n < subregion->nresults(); n++)
497 JLM_ASSERT(subregion->argument(n)->input() ==
nullptr);
498 const auto result = subregion->result(n);
499 const auto & origin = *result->origin();
501 if (
const auto lambdaNode = rvsdg::TryGetOwnerNode<rvsdg::LambdaNode>(origin))
503 const auto variable =
504 util::assertedCast<const FunctionVariable>(
Context_->GetVariable(subregion->argument(n)));
506 Context_->InsertVariable(lambdaNode->output(), variable);
508 for (
auto [input, _] : lambdaNode->GetContextVars())
511 variable->function()->add_dependency(&ipGraphNode);
514 else if (
const auto deltaNode = rvsdg::TryGetOwnerNode<rvsdg::DeltaNode>(origin))
516 const auto variable =
517 util::assertedCast<const GlobalValue>(
Context_->GetVariable(subregion->argument(n)));
519 Context_->InsertVariable(&deltaNode->output(), variable);
521 for (
auto & [input, _] : deltaNode->GetContextVars())
524 variable->node()->add_dependency(&ipGraphNode);
530 "Unhandled node type: ",
531 rvsdg::AssertGetOwnerNode<rvsdg::Node>(origin).DebugString())
538 for (
size_t n = 0; n < phiNode.
noutputs(); n++)
541 Context_->GetVariable(subregion->result(n)->origin()));
547 auto & ipGraphModule =
Context_->GetIpGraphModule();
549 auto op = util::assertedCast<const llvm::DeltaOperation>(&deltaNode.
GetOperation());
552 ipGraphModule.ipgraph(),
564 dataNode->add_dependency(&ipGraphNode);
567 const auto variable = ipGraphModule.create_global_value(dataNode);
578 else if (
const auto gammaNode =
dynamic_cast<const rvsdg::GammaNode *
>(&node))
582 else if (
const auto thetaNode =
dynamic_cast<const rvsdg::ThetaNode *
>(&node))
586 else if (
const auto phiNode =
dynamic_cast<const rvsdg::PhiNode *
>(&node))
590 else if (
const auto deltaNode =
dynamic_cast<const rvsdg::DeltaNode *
>(&node))
616 auto & ipGraphModule =
Context_->GetIpGraphModule();
617 auto & ipGraph = ipGraphModule.ipgraph();
619 for (
size_t n = 0; n < graph.
GetRootRegion().narguments(); n++)
622 if (
const auto functionType =
623 std::dynamic_pointer_cast<const rvsdg::FunctionType>(graphImport->ValueType()))
629 graphImport->linkage(),
630 graphImport->callingConvention(),
632 const auto variable = ipGraphModule.create_variable(functionNode);
633 Context_->InsertVariable(graphImport, variable);
640 graphImport->ValueType(),
641 graphImport->linkage(),
643 graphImport->isConstant(),
644 graphImport->getAlignment());
645 const auto variable = ipGraphModule.create_global_value(dataNode);
646 Context_->InsertVariable(graphImport, variable);
651 std::unique_ptr<InterProceduralGraphModule>
657 statistics->Start(rvsdgModule.
Rvsdg());
684 statistics->End(*ipGraphModule);
687 return ipGraphModule;
690 std::unique_ptr<InterProceduralGraphModule>
static jlm::util::StatisticsCollector statisticsCollector
static std::unique_ptr< Argument > create(const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > type, const AttributeSet &attributes)
static BasicBlock * create(ControlFlowGraph &cfg)
static std::unique_ptr< llvm::ThreeAddressCode > create(size_t nalternatives, const Variable *operand)
static std::unique_ptr< ControlFlowGraph > create(InterProceduralGraphModule &im)
static DataNode * Create(InterProceduralGraph &clg, const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > valueType, const llvm::Linkage &linkage, std::string section, const bool constant, const size_t alignment)
static FunctionNode * create(InterProceduralGraph &ipg, const std::string &name, std::shared_ptr< const rvsdg::FunctionType > type, const llvm::Linkage &linkage, const CallingConvention &callingConvention, const AttributeSet &attributes)
static std::unique_ptr< InterProceduralGraphModule > create(const jlm::util::FilePath &sourceFilename, const std::string &targetTriple, const std::string &dataLayout)
static void createAndRun(rvsdg::RvsdgModule &rvsdgModule, Configuration configuration)
const util::FilePath & SourceFileName() const noexcept
const std::string & TargetTriple() const noexcept
const std::string & DataLayout() const noexcept
InterProceduralGraphModule & IPGraphModule_
const llvm::Variable * GetVariable(const rvsdg::Output *output)
void InsertVariable(const rvsdg::Output *output, const llvm::Variable *variable)
ControlFlowGraph * GetControlFlowGraph() const noexcept
ControlFlowGraph * ControlFlowGraph_
std::unordered_map< const rvsdg::Output *, const llvm::Variable * > VariableMap_
BasicBlock * LastProcessedBasicBlock
BasicBlock * GetLastProcessedBasicBlock() const noexcept
Context & operator=(const Context &)=delete
Context & operator=(Context &&)=delete
Context(Context &&)=delete
Context(InterProceduralGraphModule &ipGraphModule)
Context(const Context &)=delete
void SetControlFlowGraph(ControlFlowGraph *cfg) noexcept
InterProceduralGraphModule & GetIpGraphModule() const noexcept
void SetLastProcessedBasicBlock(BasicBlock *lastProcessedBasicBlock) noexcept
static std::unique_ptr< Context > Create(InterProceduralGraphModule &ipGraphModule)
void Start(const rvsdg::Graph &graph) noexcept
static std::unique_ptr< Statistics > Create(const util::FilePath &sourceFile)
void End(const InterProceduralGraphModule &im)
Statistics(const util::FilePath &filename)
~Statistics() override=default
std::unique_ptr< DataNodeInit > CreateInitialization(const rvsdg::DeltaNode &deltaNode)
RvsdgToIpGraphConverter()
InterProceduralGraphNode & getInterProceduralGraphNode(const rvsdg::Output &output) const
std::unique_ptr< Context > Context_
std::unique_ptr< InterProceduralGraphModule > ConvertModule(LlvmRvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector)
static std::unique_ptr< InterProceduralGraphModule > CreateAndConvertModule(LlvmRvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector)
void ConvertDeltaNode(const rvsdg::DeltaNode &deltaNode)
static bool RequiresSsaPhiOperation(const rvsdg::ThetaNode::LoopVar &loopVar)
~RvsdgToIpGraphConverter()
void ConvertImports(const rvsdg::Graph &graph)
void ConvertNode(const rvsdg::Node &node)
void ConvertRegion(rvsdg::Region ®ion)
void ConvertThetaNode(const rvsdg::ThetaNode &thetaNode)
void ConvertNodes(const rvsdg::Graph &graph)
void ConvertLambdaNode(const rvsdg::LambdaNode &lambdaNode)
void ConvertSimpleNode(const rvsdg::SimpleNode &simpleNode)
void ConvertGammaNode(const rvsdg::GammaNode &gammaNode)
void ConvertPhiNode(const rvsdg::PhiNode &phiNode)
std::unique_ptr< ControlFlowGraph > CreateControlFlowGraph(const rvsdg::LambdaNode &lambda)
static std::unique_ptr< llvm::ThreeAddressCode > create(const std::vector< std::pair< const Variable *, ControlFlowGraphNode * >> &arguments, std::shared_ptr< const jlm::rvsdg::Type > type)
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
const std::shared_ptr< const jlm::rvsdg::Type > Type() const noexcept
std::vector< ContextVar > GetContextVars() const noexcept
Gets all bound context variables.
rvsdg::Region * subregion() const noexcept
const DeltaOperation & GetOperation() const noexcept override
rvsdg::Output & output() const noexcept
Conditional operator / pattern matching.
std::vector< EntryVar > GetEntryVars() const
Gets all entry variables for this gamma.
rvsdg::Input * predicate() const noexcept
Region & GetRootRegion() const noexcept
std::vector< rvsdg::Output * > GetFunctionArguments() const
rvsdg::Region * subregion() const noexcept
std::vector< rvsdg::Input * > GetFunctionResults() const
rvsdg::Output * output() const noexcept
std::vector< ContextVar > GetContextVars() const noexcept
Gets all bound context variables.
LambdaOperation & GetOperation() const noexcept override
virtual std::string DebugString() const =0
size_t ninputs() const noexcept
size_t noutputs() const noexcept
virtual std::unique_ptr< Operation > copy() const =0
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
size_t nusers() const noexcept
A phi node represents the fixpoint of mutually recursive definitions.
rvsdg::Region * subregion() const noexcept
Represent acyclic RVSDG subgraphs.
RegionResult * result(size_t index) const noexcept
RegionArgument * argument(size_t index) const noexcept
const SimpleOperation & GetOperation() const noexcept override
NodeInput * input(size_t index) const noexcept
NodeOutput * output(size_t index) const noexcept
size_t nsubregions() const noexcept
StructuralOutput * output(size_t index) const noexcept
StructuralInput * input(size_t index) const noexcept
rvsdg::Region * subregion(size_t index) const noexcept
std::vector< LoopVar > GetLoopVars() const
Returns all loop variables.
rvsdg::Region * subregion() const noexcept
ElementType * first() const noexcept
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
util::Timer & GetTimer(const std::string &name)
util::Timer & AddTimer(std::string name)
void AddMeasurement(std::string name, T value)
#define JLM_UNREACHABLE(msg)
Global memory state passed between functions.
std::vector< std::unique_ptr< llvm::ThreeAddressCode > > tacsvector_t
void straighten(ControlFlowGraph &cfg)
size_t ntacs(const AggregationNode &root)
bool is_closed(const ControlFlowGraph &cfg)
static bool ThetaLoopVarIsInvariant(const ThetaNode::LoopVar &loopVar) noexcept
size_t nnodes(const jlm::rvsdg::Region *region) noexcept
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
static std::string strfmt(Args... args)
Description of a loop-carried variable.
rvsdg::Output * pre
Variable before iteration (input argument to subregion).
static const char * NumRvsdgNodes
static const char * NumThreeAddressCodes
static const char * Timer