20 std::vector<const jlm::llvm::InterProceduralGraphNode *> & node_stack,
22 std::vector<std::unordered_set<const jlm::llvm::InterProceduralGraphNode *>> & sccs)
24 map.emplace(node, std::make_pair(index, index));
25 node_stack.push_back(node);
28 for (
auto callee : *node)
30 if (map.find(callee) == map.end())
34 map[node].second = std::min(map[node].second, map[callee].second);
36 else if (std::find(node_stack.begin(), node_stack.end(), callee) != node_stack.end())
39 map[node].second = std::min(map[node].second, map[callee].first);
43 if (map[node].second == map[node].first)
45 std::unordered_set<const jlm::llvm::InterProceduralGraphNode *> scc;
49 w = node_stack.back();
50 node_stack.pop_back();
64 nodes_.push_back(std::move(node));
67 std::vector<std::unordered_set<const InterProceduralGraphNode *>>
70 std::vector<std::unordered_set<const InterProceduralGraphNode *>> sccs;
72 std::unordered_map<const InterProceduralGraphNode *, std::pair<size_t, size_t>> map;
73 std::vector<const InterProceduralGraphNode *> node_stack;
76 for (
auto & node : *
this)
78 if (map.find(&node) == map.end())
88 for (
auto & node : nodes_)
90 if (node->name() == name)
101 util::graph::Writer & writer,
108 for (
auto & node : interProceduralGraph)
112 dotNode.SetLabel(node.name());
116 for (
auto & node : interProceduralGraph)
119 for (
auto & depNode : node)
123 auto & inputPort = dotNode.CreateInputPort();
124 dotGraph.
CreateEdge(inputPort, outputPort,
false);
135 toDot(graphWriter, *
this);
140 std::ofstream outputFile(outputFilePath.
to_str());
160 std::shared_ptr<const jlm::rvsdg::Type>
175 return cfg() !=
nullptr;
182 throw util::Error(
"CFG does not match the function node's type.");
204 std::shared_ptr<const rvsdg::Type>
rvsdg::FunctionType fcttype() const
std::shared_ptr< const jlm::rvsdg::Type > Type() const override
const llvm::Linkage & linkage() const noexcept override
const DataNodeInit * initialization() const noexcept
const PointerType & type() const noexcept override
bool hasBody() const noexcept override
const jlm::rvsdg::Type & type() const noexcept override
const rvsdg::FunctionType & fcttype() const noexcept
std::shared_ptr< const rvsdg::FunctionType > FunctionType_
void add_cfg(std::unique_ptr< ControlFlowGraph > cfg)
Adds cfg to the function node. If the function node already has a CFG, then it is replaced with cfg.
std::unique_ptr< ControlFlowGraph > cfg_
bool hasBody() const noexcept override
const llvm::Linkage & linkage() const noexcept override
~FunctionNode() noexcept override
llvm::ControlFlowGraph * cfg() const noexcept
std::shared_ptr< const jlm::rvsdg::Type > Type() const override
~FunctionVariable() noexcept override
virtual ~InterProceduralGraphNode() noexcept
std::vector< std::unordered_set< const InterProceduralGraphNode * > > find_sccs() const
const InterProceduralGraphNode * find(const std::string &name) const noexcept
std::vector< std::unique_ptr< InterProceduralGraphNode > > nodes_
void add_node(std::unique_ptr< InterProceduralGraphNode > node)
static util::graph::Graph & toDot(util::graph::Writer &writer, const InterProceduralGraph &interProceduralGraph)
static std::shared_ptr< const PointerType > Create()
static FilePath createUniqueFileName(const FilePath &directory, const std::string &fileNamePrefix, const std::string &fileNameSuffix)
Generates a unique file in a given directory with a prefix and suffix.
static FilePath TempDirectoryPath()
const std::string & to_str() const noexcept
void SetProgramObject(const T &object)
InOutNode & CreateInOutNode(size_t inputPorts, size_t outputPorts)
Element & GetFromProgramObject(const ProgramObject &object) const
Edge & CreateEdge(Port &from, Port &to, bool directed)
OutputPort & CreateOutputPort()
void outputAllGraphs(std::ostream &out, OutputFormat format)
static void strongconnect(const jlm::llvm::InterProceduralGraphNode *node, std::unordered_map< const jlm::llvm::InterProceduralGraphNode *, std::pair< size_t, size_t >> &map, std::vector< const jlm::llvm::InterProceduralGraphNode * > &node_stack, size_t &index, std::vector< std::unordered_set< const jlm::llvm::InterProceduralGraphNode * >> &sccs)
Global memory state passed between functions.
static void strongconnect(ControlFlowGraphNode *node, ControlFlowGraphNode *exit, std::unordered_map< ControlFlowGraphNode *, std::pair< size_t, size_t >> &map, std::vector< ControlFlowGraphNode * > &node_stack, size_t &index, std::vector< StronglyConnectedComponent > &sccs)
std::string getDotViewer()
int executeProgramAndWait(const std::string &programName, const std::vector< std::string > &programArguments)