89 static std::unique_ptr<Context>
92 return std::make_unique<Context>(ipGraphModule);
99 std::unordered_map<const rvsdg::Output *, const llvm::Variable *>
VariableMap_;
125 static std::unique_ptr<Statistics>
128 return std::make_unique<Statistics>(sourceFile);
136 std::unique_ptr<DataNodeInit>
139 const auto subregion = deltaNode.
subregion();
142 for (
size_t n = 0; n < deltaNode.
ninputs(); n++)
148 if (subregion->numNodes() == 0)
150 auto value =
Context_->GetVariable(subregion->result(0)->origin());
151 return std::make_unique<DataNodeInit>(value);
158 const auto output = node->output(0);
161 std::vector<const Variable *>
operands;
162 for (
size_t n = 0; n < node->ninputs(); n++)
166 auto op = node->GetOperation().copy();
168 std::unique_ptr<rvsdg::SimpleOperation>(
169 util::assertedCast<rvsdg::SimpleOperation>(op.release())),
171 Context_->InsertVariable(output, tacs.back()->result(0));
174 return std::make_unique<DataNodeInit>(std::move(tacs));
181 Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock);
182 Context_->SetLastProcessedBasicBlock(entryBlock);
188 Context_->GetLastProcessedBasicBlock()->add_outedge(exitBlock);
189 Context_->SetLastProcessedBasicBlock(exitBlock);
192 std::unique_ptr<ControlFlowGraph>
196 const auto & lambdaOperation = *util::assertedCast<LlvmLambdaOperation>(&lambda.
GetOperation());
200 controlFlowGraph->exit()->divert_inedges(entryBlock);
201 Context_->SetLastProcessedBasicBlock(entryBlock);
202 Context_->SetControlFlowGraph(controlFlowGraph.get());
207 auto name =
util::strfmt(
"_a", functionArgument->index(),
"_");
210 functionArgument->Type(),
211 lambdaOperation.GetArgumentAttributes(functionArgument->index()));
212 const auto variable = controlFlowGraph->entry()->append_argument(std::move(argument));
213 Context_->InsertVariable(functionArgument, variable);
219 const auto variable =
Context_->GetVariable(input->origin());
220 Context_->InsertVariable(inner, variable);
227 controlFlowGraph->exit()->append_result(
Context_->GetVariable(result->origin()));
229 Context_->GetLastProcessedBasicBlock()->add_outedge(controlFlowGraph->exit());
230 Context_->SetLastProcessedBasicBlock(
nullptr);
231 Context_->SetControlFlowGraph(
nullptr);
235 return controlFlowGraph;
241 std::vector<const Variable *>
operands;
242 for (
size_t n = 0; n < simpleNode.
ninputs(); n++)
247 std::unique_ptr<rvsdg::SimpleOperation>(
248 util::assertedCast<rvsdg::SimpleOperation>(operation.release())),
251 for (
size_t n = 0; n < simpleNode.
noutputs(); n++)
254 Context_->GetLastProcessedBasicBlock()->last()->result(n));
260 const auto numSubregions = gammaNode.
nsubregions();
262 const auto controlFlowGraph =
Context_->GetControlFlowGraph();
266 Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock);
269 std::vector<ControlFlowGraphNode *> phi_nodes;
272 for (
size_t n = 0; n < gammaNode.
nsubregions(); n++)
274 const auto subregion = gammaNode.
subregion(n);
277 for (
size_t i = 0; i < entryvars.size(); i++)
279 auto & entryvar = entryvars[i];
281 entryvar.branchArgument[n],
282 Context_->GetVariable(entryvar.input->origin()));
287 entryBlock->add_outedge(regionEntryBlock);
288 Context_->SetLastProcessedBasicBlock(regionEntryBlock);
291 phi_nodes.push_back(
Context_->GetLastProcessedBasicBlock());
292 Context_->GetLastProcessedBasicBlock()->add_outedge(exitBlock);
296 for (
size_t n = 0; n < gammaNode.
noutputs(); n++)
298 const auto output = gammaNode.
output(n);
300 bool invariant =
true;
301 std::vector<std::pair<const Variable *, ControlFlowGraphNode *>> arguments;
302 for (
size_t r = 0; r < gammaNode.
nsubregions(); r++)
306 auto v =
Context_->GetVariable(origin);
307 arguments.push_back(std::make_pair(v, phi_nodes[r]));
314 Context_->InsertVariable(output, arguments[0].first);
320 Context_->InsertVariable(output, exitBlock->last()->result(0));
323 Context_->SetLastProcessedBasicBlock(exitBlock);
332 if (is<GlobalVariable>(&v))
347 const auto subregion = thetaNode.
subregion();
350 auto preEntryBlock =
Context_->GetLastProcessedBasicBlock();
352 preEntryBlock->add_outedge(entryBlock);
353 Context_->SetLastProcessedBasicBlock(entryBlock);
356 std::vector<llvm::ThreeAddressCode *> phis;
357 for (
const auto & loopVar : thetaNode.
GetLoopVars())
359 auto variable =
Context_->GetVariable(loopVar.input->origin());
364 variable = phi->result(0);
366 Context_->InsertVariable(loopVar.pre, variable);
373 for (
const auto & loopVar : thetaNode.
GetLoopVars())
375 auto entryVariable =
Context_->GetVariable(loopVar.input->origin());
378 auto resultVariable =
Context_->GetVariable(loopVar.post->origin());
379 const auto phi = phis[phiIndex++];
382 { preEntryBlock,
Context_->GetLastProcessedBasicBlock() },
383 resultVariable->Type()),
384 { entryVariable, resultVariable });
385 Context_->InsertVariable(loopVar.output, resultVariable);
389 Context_->InsertVariable(loopVar.output,
Context_->GetVariable(loopVar.post->origin()));
394 Context_->GetLastProcessedBasicBlock()->append_last(
397 Context_->GetLastProcessedBasicBlock()->add_outedge(exitBlock);
398 Context_->GetLastProcessedBasicBlock()->add_outedge(entryBlock);
399 Context_->SetLastProcessedBasicBlock(exitBlock);
405 auto & ipGraphModule =
Context_->GetIpGraphModule();
406 auto & ipGraph = ipGraphModule.ipgraph();
408 const auto & operation = *util::assertedCast<LlvmLambdaOperation>(&lambdaNode.
GetOperation());
414 operation.attributes());
415 const auto variable = ipGraphModule.create_variable(functionNode);
424 const auto subregion = phiNode.
subregion();
425 auto & ipGraphModule =
Context_->GetIpGraphModule();
426 auto & ipGraph = ipGraphModule.ipgraph();
429 for (
size_t n = 0; n < phiNode.
ninputs(); n++)
436 for (
size_t n = 0; n < subregion->nresults(); n++)
438 JLM_ASSERT(subregion->argument(n)->input() ==
nullptr);
439 const auto & origin = *subregion->result(n)->origin();
441 if (
const auto lambdaNode = rvsdg::TryGetOwnerNode<rvsdg::LambdaNode>(origin))
443 const auto & lambdaOperation =
447 lambdaOperation.name(),
448 lambdaOperation.Type(),
449 lambdaOperation.linkage(),
450 lambdaOperation.attributes());
451 Context_->InsertVariable(subregion->argument(n), ipGraphModule.create_variable(functionNode));
453 else if (
const auto deltaNode = rvsdg::TryGetOwnerNode<rvsdg::DeltaNode>(origin))
455 auto op = util::assertedCast<const llvm::DeltaOperation>(&deltaNode->GetOperation());
463 Context_->InsertVariable(subregion->argument(n), ipGraphModule.create_global_value(dataNode));
468 "Unhandled node type: ",
469 rvsdg::AssertGetOwnerNode<rvsdg::Node>(origin).DebugString())
475 for (
size_t n = 0; n < subregion->nresults(); n++)
477 JLM_ASSERT(subregion->argument(n)->input() ==
nullptr);
478 const auto result = subregion->result(n);
479 const auto & origin = *result->origin();
481 if (
const auto lambdaNode = rvsdg::TryGetOwnerNode<rvsdg::LambdaNode>(origin))
483 const auto variable =
484 util::assertedCast<const FunctionVariable>(
Context_->GetVariable(subregion->argument(n)));
486 Context_->InsertVariable(lambdaNode->output(), variable);
488 else if (
const auto deltaNode = rvsdg::TryGetOwnerNode<rvsdg::DeltaNode>(origin))
490 const auto variable =
491 util::assertedCast<const GlobalValue>(
Context_->GetVariable(subregion->argument(n)));
493 Context_->InsertVariable(&deltaNode->output(), variable);
498 "Unhandled node type: ",
499 rvsdg::AssertGetOwnerNode<rvsdg::Node>(origin).DebugString())
506 for (
size_t n = 0; n < phiNode.
noutputs(); n++)
509 Context_->GetVariable(subregion->result(n)->origin()));
515 auto & ipGraphModule =
Context_->GetIpGraphModule();
517 auto op = util::assertedCast<const llvm::DeltaOperation>(&deltaNode.
GetOperation());
520 ipGraphModule.ipgraph(),
527 const auto variable = ipGraphModule.create_global_value(dataNode);
538 else if (
const auto gammaNode =
dynamic_cast<const rvsdg::GammaNode *
>(&node))
542 else if (
const auto thetaNode =
dynamic_cast<const rvsdg::ThetaNode *
>(&node))
546 else if (
const auto phiNode =
dynamic_cast<const rvsdg::PhiNode *
>(&node))
550 else if (
const auto deltaNode =
dynamic_cast<const rvsdg::DeltaNode *
>(&node))
576 auto & ipGraphModule =
Context_->GetIpGraphModule();
577 auto & ipGraph = ipGraphModule.ipgraph();
579 for (
size_t n = 0; n < graph.
GetRootRegion().narguments(); n++)
582 if (
const auto functionType =
583 std::dynamic_pointer_cast<const rvsdg::FunctionType>(graphImport->ValueType()))
585 const auto functionNode =
587 const auto variable = ipGraphModule.create_variable(functionNode);
588 Context_->InsertVariable(graphImport, variable);
595 graphImport->ValueType(),
596 graphImport->linkage(),
599 const auto variable = ipGraphModule.create_global_value(dataNode);
600 Context_->InsertVariable(graphImport, variable);
605 std::unique_ptr<InterProceduralGraphModule>
611 statistics->Start(rvsdgModule.
Rvsdg());
622 statistics->End(*ipGraphModule);
625 return ipGraphModule;
628 std::unique_ptr<InterProceduralGraphModule>
634 return converter.
ConvertModule(rvsdgModule, 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, bool constant)
static FunctionNode * create(InterProceduralGraph &ipg, const std::string &name, std::shared_ptr< const rvsdg::FunctionType > type, const llvm::Linkage &linkage, const AttributeSet &attributes)
static std::unique_ptr< InterProceduralGraphModule > create(const jlm::util::FilePath &sourceFilename, const std::string &targetTriple, const std::string &dataLayout)
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()
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, const Variable &v)
~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
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