[llvm] Ret (PR #104839)

via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 19 12:41:45 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Kun Liu (Ryan-hub-bit)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/104839.diff


5 Files Affected:

- (added) llvm/include/llvm/Transforms/IPO/InterProceduralGraph.h (+58) 
- (modified) llvm/lib/Passes/PassBuilder.cpp (+1) 
- (modified) llvm/lib/Passes/PassRegistry.def (+1) 
- (modified) llvm/lib/Transforms/IPO/CMakeLists.txt (+1) 
- (added) llvm/lib/Transforms/IPO/InterProceduralGraph.cpp (+118) 


``````````diff
diff --git a/llvm/include/llvm/Transforms/IPO/InterProceduralGraph.h b/llvm/include/llvm/Transforms/IPO/InterProceduralGraph.h
new file mode 100644
index 00000000000000..d34813717b68a6
--- /dev/null
+++ b/llvm/include/llvm/Transforms/IPO/InterProceduralGraph.h
@@ -0,0 +1,58 @@
+#ifndef INTERPROCEDURALGRAPH_PASS_H
+#define INTERPROCEDURALGRAPH_PASS_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+#include <vector>
+#include <set>
+
+namespace llvm {
+
+// Forward declaration of the pass
+class InterproceduralGraphPass;
+
+// Node structure to represent graph nodes
+struct Node {
+    std::string name;
+    // Additional properties can be added here
+};
+
+// Edge structure to represent graph edges
+struct Edge {
+    std::string from;
+    std::string to;
+};
+
+// InterproceduralGraph class to manage graph nodes and edges
+struct InterproceduralGraph {
+    std::map<std::string, Node> nodes;
+    std::vector<Edge> edges;
+    std::set<std::string> functionsWithIndirectCalls;
+
+    void addNode(Node node);
+    void addEdge(const std::string &from, const std::string &to);
+    void addIntraproceduralEdges(Function &F);
+    void addInterproceduralEdges(CallGraph &CG);
+    void addIndirectCallEdges();
+    std::set<std::string> getPossibleIndirectTargets(const std::string &FuncName);
+    void outputGraph();
+};
+
+// InterproceduralGraphPass class to define the pass
+class InterproceduralGraphPass : public PassInfoMixin<InterproceduralGraphPass> {
+public:
+    // Function to run the pass
+    PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+
+    // Function to check if the pass is required
+    //static bool isRequired();
+};
+
+} // namespace llvm
+
+#endif // INTERPROCEDURALGRAPH_PASS_H
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 17eed97fd950c9..eb1178ac692803 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -181,6 +181,7 @@
 #include "llvm/Transforms/IPO/StripSymbols.h"
 #include "llvm/Transforms/IPO/SyntheticCountsPropagation.h"
 #include "llvm/Transforms/IPO/WholeProgramDevirt.h"
+#include "llvm/Transforms/IPO/InterProceduralGraph.h"
 #include "llvm/Transforms/InstCombine/InstCombine.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 6b5e1cf83c4698..9f51f9d1098a67 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -44,6 +44,7 @@ MODULE_ALIAS_ANALYSIS("globals-aa", GlobalsAA())
 #ifndef MODULE_PASS
 #define MODULE_PASS(NAME, CREATE_PASS)
 #endif
+MODULE_PASS("inter-procedural-graph", InterproceduralGraphPass())
 MODULE_PASS("always-inline", AlwaysInlinerPass())
 MODULE_PASS("annotation2metadata", Annotation2MetadataPass())
 MODULE_PASS("assign-guid", AssignGUIDPass())
diff --git a/llvm/lib/Transforms/IPO/CMakeLists.txt b/llvm/lib/Transforms/IPO/CMakeLists.txt
index 92a9697720efd4..f42c0bce6a9993 100644
--- a/llvm/lib/Transforms/IPO/CMakeLists.txt
+++ b/llvm/lib/Transforms/IPO/CMakeLists.txt
@@ -27,6 +27,7 @@ add_llvm_component_library(LLVMipo
   InferFunctionAttrs.cpp
   Inliner.cpp
   Internalize.cpp
+  InterProceduralGraph.cpp
   LoopExtractor.cpp
   LowerTypeTests.cpp
   MemProfContextDisambiguation.cpp
diff --git a/llvm/lib/Transforms/IPO/InterProceduralGraph.cpp b/llvm/lib/Transforms/IPO/InterProceduralGraph.cpp
new file mode 100644
index 00000000000000..c0f41b71eacd56
--- /dev/null
+++ b/llvm/lib/Transforms/IPO/InterProceduralGraph.cpp
@@ -0,0 +1,118 @@
+#include "llvm/Transforms/IPO/InterProceduralGraph.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+#include <vector>
+#include <set>
+
+using namespace llvm;
+
+namespace {
+
+struct Node {
+    std::string name;
+    // Additional properties can be added here
+};
+
+struct Edge {
+    std::string from;
+    std::string to;
+};
+
+struct InterproceduralGraph {
+    std::map<std::string, Node> nodes;
+    std::vector<Edge> edges;
+    std::set<std::string> functionsWithIndirectCalls;
+
+    void addNode(Node node) {
+        nodes[node.name] = node;
+    }
+
+    void addEdge(const std::string &from, const std::string &to) {
+        edges.push_back({from, to});
+    }
+
+    void addIntraproceduralEdges(Function &F) {
+        for (BasicBlock &BB : F) {
+            for (Instruction &I : BB) {
+                if (auto *CI = dyn_cast<CallInst>(&I)) {
+                    if (auto *Callee = dyn_cast<Function>(CI->getCalledFunction())) {
+                        if (Callee && !Callee->isDeclaration()) {
+                            addEdge(F.getName().str(), Callee->getName().str());
+                            functionsWithIndirectCalls.insert(Callee->getName().str());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    void addInterproceduralEdges(CallGraph &CG) {
+        for (auto &nodePair : CG) {
+            const Function *caller = nodePair.first;
+            CallGraphNode *cgn = nodePair.second.get();
+
+            for (auto it = cgn->begin(); it != cgn->end(); ++it) {
+                CallGraphNode::CallRecord callRecord = *it;
+                const Function *callee = callRecord.second->getFunction();
+                if (callee) {
+                    addEdge(caller->getName().str(), callee->getName().str());
+                }
+            }
+        }
+    }
+
+    void addIndirectCallEdges() {
+        for (const auto &FuncName : functionsWithIndirectCalls) {
+            for (const auto &TargetFuncName : getPossibleIndirectTargets(FuncName)) {
+                addEdge(FuncName, TargetFuncName);
+            }
+        }
+    }
+
+    std::set<std::string> getPossibleIndirectTargets(const std::string &FuncName) {
+        return std::set<std::string>();
+    }
+
+    void outputGraph() {
+        errs() << "Nodes:\n";
+        for (const auto &NodePair : nodes) {
+            errs() << "  " << NodePair.first << "\n";
+        }
+
+        errs() << "Edges:\n";
+        for (const auto &Edge : edges) {
+            errs() << "  " << Edge.from << " -> " << Edge.to << "\n";
+        }
+    }
+};
+
+class InterproceduralGraphPass : public PassInfoMixin<InterproceduralGraphPass> {
+public:
+     PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
+        InterproceduralGraph IPG;
+
+        CallGraph &CG = AM.getResult<CallGraphAnalysis>(M);
+
+        for (Function &F : M) {
+            Node functionNode;
+            functionNode.name = F.getName();
+            IPG.addNode(functionNode);
+            IPG.addIntraproceduralEdges(F);
+        }
+
+        IPG.addInterproceduralEdges(CG);
+        IPG.addIndirectCallEdges();
+        IPG.outputGraph();
+
+        return PreservedAnalyses::none();
+    }
+
+    //static bool isRequired() { return true; }
+};
+
+} // end of anonymous namespace

``````````

</details>


https://github.com/llvm/llvm-project/pull/104839


More information about the llvm-commits mailing list