[llvm] My dce (PR #120468)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 20 13:03:35 PST 2025
https://github.com/RashmiSalankar updated https://github.com/llvm/llvm-project/pull/120468
>From 645debab0879a98f13755f5b531f93345708eb80 Mon Sep 17 00:00:00 2001
From: Rashmi Salankar <rashmi.salankar at gmail.com>
Date: Fri, 13 Dec 2024 01:06:54 +0530
Subject: [PATCH 1/7] Dummy pass works now
---
.../Transforms/Utils/MyDeadCodeEliminationPass.h | 14 ++++++++++++++
llvm/lib/Passes/PassBuilder.cpp | 1 +
llvm/lib/Passes/PassRegistry.def | 1 +
llvm/lib/Transforms/Utils/CMakeLists.txt | 5 +++++
.../Transforms/Utils/MyDeadCodeEliminationPass.cpp | 10 ++++++++++
5 files changed, 31 insertions(+)
create mode 100644 llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
create mode 100644 llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
diff --git a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
new file mode 100644
index 00000000000000..1642827e6b2e05
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_TRANSFORMS_MYDEADCODEELIMINATIONPASS_H
+#define LLVM_TRANSFORMS_MYDEADCODEELIMINATIONPASS_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class MyDeadCodeEliminationPass : public PassInfoMixin<MyDeadCodeEliminationPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // namespace llvm
+#endif // LLVM_TRANSFORMS_MYDEADCODEELIMINATIONPASS_H
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 77dea7d06d0900..80809e3ea1b486 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -302,6 +302,7 @@
#include "llvm/Transforms/Scalar/StructurizeCFG.h"
#include "llvm/Transforms/Scalar/TailRecursionElimination.h"
#include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
+#include "llvm/Transforms/Utils/MyDeadCodeEliminationPass.h"
#include "llvm/Transforms/Utils/AddDiscriminators.h"
#include "llvm/Transforms/Utils/AssumeBundleBuilder.h"
#include "llvm/Transforms/Utils/BreakCriticalEdges.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 772ec5fd10e633..c797955ee969e9 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -328,6 +328,7 @@ FUNCTION_ALIAS_ANALYSIS("tbaa", TypeBasedAA())
#ifndef FUNCTION_PASS
#define FUNCTION_PASS(NAME, CREATE_PASS)
#endif
+FUNCTION_PASS("my-dce", MyDeadCodeEliminationPass())
FUNCTION_PASS("aa-eval", AAEvaluator())
FUNCTION_PASS("adce", ADCEPass())
FUNCTION_PASS("add-discriminators", AddDiscriminatorsPass())
diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt
index 65bd3080662c4d..221cb31e20dd9a 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -1,4 +1,5 @@
add_llvm_component_library(LLVMTransformUtils
+ MyDeadCodeEliminationPass.cpp
AddDiscriminators.cpp
AMDGPUEmitPrintf.cpp
ASanStackFrameLayout.cpp
@@ -93,6 +94,10 @@ add_llvm_component_library(LLVMTransformUtils
${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms
${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms/Utils
+ target_include_directories(LLVMMyDeadCodeElimination PRIVATE
+ ${LLVM_MAIN_INCLUDE_DIR}
+ )
+
DEPENDS
intrinsics_gen
diff --git a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
new file mode 100644
index 00000000000000..bb35a05a8140f3
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
@@ -0,0 +1,10 @@
+#include "llvm/Transforms/Utils/MyDeadCodeEliminationPass.h"
+
+using namespace llvm;
+
+PreservedAnalyses MyDeadCodeEliminationPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ errs() << "I'm here in my Pass" << "\n";
+ return PreservedAnalyses::all();
+/* The PreservedAnalyses return value says that all analyses (e.g. dominator tree) are still valid after this pass since we didn’t modify any functions */
+}
>From a61f476669c59178cf5f2604a68f6718a7dcbc15 Mon Sep 17 00:00:00 2001
From: Rashmi Salankar <rashmi.salankar at gmail.com>
Date: Sun, 15 Dec 2024 03:38:58 +0530
Subject: [PATCH 2/7] Basic implementation of Potential Dead Code intructions
done.
---
.../Utils/MyDeadCodeEliminationPass.h | 12 +++++--
.../Utils/MyDeadCodeEliminationPass.cpp | 35 ++++++++++++++++---
2 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
index 1642827e6b2e05..3876ee32851322 100644
--- a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
+++ b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
@@ -1,14 +1,20 @@
-#ifndef LLVM_TRANSFORMS_MYDEADCODEELIMINATIONPASS_H
-#define LLVM_TRANSFORMS_MYDEADCODEELIMINATIONPASS_H
+#ifndef LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
+#define LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
#include "llvm/IR/PassManager.h"
+#include "llvm/IR/Function.h"
namespace llvm {
class MyDeadCodeEliminationPass : public PassInfoMixin<MyDeadCodeEliminationPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+private:
+ void analyzeInstructions(Function &F);
};
} // namespace llvm
-#endif // LLVM_TRANSFORMS_MYDEADCODEELIMINATIONPASS_H
+
+#endif // LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
+
diff --git a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
index bb35a05a8140f3..8045989adf8f2b 100644
--- a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
+++ b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
@@ -1,10 +1,37 @@
#include "llvm/Transforms/Utils/MyDeadCodeEliminationPass.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-PreservedAnalyses MyDeadCodeEliminationPass::run(Function &F,
- FunctionAnalysisManager &AM) {
+PreservedAnalyses MyDeadCodeEliminationPass::run(Function &F, FunctionAnalysisManager &AM) {
errs() << "I'm here in my Pass" << "\n";
- return PreservedAnalyses::all();
-/* The PreservedAnalyses return value says that all analyses (e.g. dominator tree) are still valid after this pass since we didn’t modify any functions */
+
+ // Call the helper function to analyze instructions
+ analyzeInstructions(F);
+
+ return PreservedAnalyses::all(); // Preserve analyses since the code isn't modified.
}
+
+void MyDeadCodeEliminationPass::analyzeInstructions(Function &F) {
+ for (BasicBlock &BB : F) {
+ for (Instruction &I : BB) {
+ errs() << "Instruction: " << I << "\n";
+
+ // Check if the instruction is "dead" (not used anywhere)
+ if (I.use_empty()) {
+ errs() << "Potential dead instruction: " << I << "\n";
+ }
+
+ // Count instruction types
+ if (isa<LoadInst>(&I)) {
+ errs() << "Load Instruction\n";
+ } else if (isa<StoreInst>(&I)) {
+ errs() << "Store Instruction\n";
+ }
+ }
+ }
+}
+
>From 9a6d64525443d1383a22670e7825a0a33dc87da8 Mon Sep 17 00:00:00 2001
From: Rashmi Salankar <rashmi.salankar at gmail.com>
Date: Sun, 15 Dec 2024 03:58:07 +0530
Subject: [PATCH 3/7] Implemented Iterative Solution for probable dead
statements
---
.../Utils/MyDeadCodeEliminationPass.h | 9 +++-
.../Utils/MyDeadCodeEliminationPass.cpp | 54 +++++++++++++------
2 files changed, 46 insertions(+), 17 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
index 3876ee32851322..24187cb4436b76 100644
--- a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
+++ b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
@@ -3,15 +3,22 @@
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
+#include <unordered_set>
namespace llvm {
class MyDeadCodeEliminationPass : public PassInfoMixin<MyDeadCodeEliminationPass> {
public:
+ // Main run method for the pass
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
private:
- void analyzeInstructions(Function &F);
+ // Helper function for iterative analysis
+ void analyzeInstructionsIteratively(Function &F);
+
+ // Helper function to check if an instruction is dead
+ bool isInstructionDead(Instruction *Inst, const std::unordered_set<Instruction *> &potentialDeadInstructions);
};
} // namespace llvm
diff --git a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
index 8045989adf8f2b..f906341acd3a5f 100644
--- a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
+++ b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
@@ -3,35 +3,57 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/raw_ostream.h"
+#include <unordered_set>
using namespace llvm;
PreservedAnalyses MyDeadCodeEliminationPass::run(Function &F, FunctionAnalysisManager &AM) {
errs() << "I'm here in my Pass" << "\n";
- // Call the helper function to analyze instructions
- analyzeInstructions(F);
+ // Call the helper function to iteratively analyze instructions
+ analyzeInstructionsIteratively(F);
return PreservedAnalyses::all(); // Preserve analyses since the code isn't modified.
}
-void MyDeadCodeEliminationPass::analyzeInstructions(Function &F) {
- for (BasicBlock &BB : F) {
- for (Instruction &I : BB) {
- errs() << "Instruction: " << I << "\n";
-
- // Check if the instruction is "dead" (not used anywhere)
- if (I.use_empty()) {
- errs() << "Potential dead instruction: " << I << "\n";
+void MyDeadCodeEliminationPass::analyzeInstructionsIteratively(Function &F) {
+ std::unordered_set<Instruction *> potentialDeadInstructions; // To track potential dead instructions
+ bool foundNewDead; // Flag to track if we find new dead instructions in an iteration
+
+ do {
+ foundNewDead = false; // Reset the flag at the start of each iteration
+
+ for (BasicBlock &BB : F) {
+ for (Instruction &I : BB) {
+ // Skip if already identified as dead
+ if (potentialDeadInstructions.count(&I)) {
+ continue;
+ }
+
+ // Check if the instruction is "dead" (not used anywhere or used only by dead instructions)
+ if (isInstructionDead(&I, potentialDeadInstructions)) {
+ errs() << "Potential dead instruction: " << I << "\n";
+ potentialDeadInstructions.insert(&I);
+ foundNewDead = true; // Mark that we found a new dead instruction
+ }
}
+ }
+ } while (foundNewDead); // Continue until no new dead instructions are found
+}
- // Count instruction types
- if (isa<LoadInst>(&I)) {
- errs() << "Load Instruction\n";
- } else if (isa<StoreInst>(&I)) {
- errs() << "Store Instruction\n";
- }
+bool MyDeadCodeEliminationPass::isInstructionDead(Instruction *Inst, const std::unordered_set<Instruction *> &potentialDeadInstructions) {
+ // Check if the instruction's result is not used, or all users are in the potentialDeadInstructions set
+ if (Inst->use_empty()) {
+ return true; // No users, definitely dead
+ }
+
+ for (const Use &U : Inst->uses()) {
+ auto *User = dyn_cast<Instruction>(U.getUser());
+ if (!User || potentialDeadInstructions.find(User) == potentialDeadInstructions.end()) {
+ return false; // Found a user that is not "dead"
}
}
+
+ return true; // All users are "dead"
}
>From 4434099c2b5faf74ca0c71c984b9a13373820afd Mon Sep 17 00:00:00 2001
From: Rashmi Salankar <rashmi.salankar at gmail.com>
Date: Thu, 19 Dec 2024 01:59:21 +0530
Subject: [PATCH 4/7] Added more features. Running but needs to be corrected
and enhanced
---
.../Utils/MyDeadCodeEliminationPass.h | 18 +--
.../Utils/MyDeadCodeEliminationPass.cpp | 130 +++++++++++++-----
2 files changed, 106 insertions(+), 42 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
index 24187cb4436b76..913501b5d4b583 100644
--- a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
+++ b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
@@ -2,23 +2,23 @@
#define LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
#include "llvm/IR/PassManager.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
+#include "llvm/Analysis/LoopInfo.h"
#include <unordered_set>
+#include <string>
namespace llvm {
class MyDeadCodeEliminationPass : public PassInfoMixin<MyDeadCodeEliminationPass> {
public:
- // Main run method for the pass
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
private:
- // Helper function for iterative analysis
- void analyzeInstructionsIteratively(Function &F);
-
- // Helper function to check if an instruction is dead
- bool isInstructionDead(Instruction *Inst, const std::unordered_set<Instruction *> &potentialDeadInstructions);
+ void analyzeInstructionsIteratively(Function &F, FunctionAnalysisManager &AM);
+ bool isInstructionDead(Instruction *Inst, const std::unordered_set<Instruction *> &potentialDeadInstructions);
+ void printBasicBlockFeatures(const Instruction &I, const BasicBlock &BB);
+ void printInstructionFeatures(const Instruction &I, const Function &F, const LoopInfo &LI);
+ void printUsageFeatures(const Instruction &I, const std::unordered_set<Instruction *> &potentialDeadInstructions);
+ std::string getInstructionPosition(const Instruction &I, const BasicBlock &BB);
};
} // namespace llvm
diff --git a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
index f906341acd3a5f..eb8d6dd472737b 100644
--- a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
+++ b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
@@ -3,57 +3,121 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Analysis/LoopInfo.h"
#include <unordered_set>
using namespace llvm;
PreservedAnalyses MyDeadCodeEliminationPass::run(Function &F, FunctionAnalysisManager &AM) {
- errs() << "I'm here in my Pass" << "\n";
+ errs() << "Starting MyDeadCodeEliminationPass\n";
- // Call the helper function to iteratively analyze instructions
- analyzeInstructionsIteratively(F);
+ analyzeInstructionsIteratively(F, AM);
- return PreservedAnalyses::all(); // Preserve analyses since the code isn't modified.
+ return PreservedAnalyses::all();
}
-void MyDeadCodeEliminationPass::analyzeInstructionsIteratively(Function &F) {
- std::unordered_set<Instruction *> potentialDeadInstructions; // To track potential dead instructions
- bool foundNewDead; // Flag to track if we find new dead instructions in an iteration
+void MyDeadCodeEliminationPass::analyzeInstructionsIteratively(Function &F, FunctionAnalysisManager &AM) {
+ auto &LI = AM.getResult<LoopAnalysis>(F);
+ std::unordered_set<Instruction *> potentialDeadInstructions;
+ bool foundNewDead;
- do {
- foundNewDead = false; // Reset the flag at the start of each iteration
+ do {
+ foundNewDead = false;
- for (BasicBlock &BB : F) {
- for (Instruction &I : BB) {
- // Skip if already identified as dead
- if (potentialDeadInstructions.count(&I)) {
- continue;
+ for (BasicBlock &BB : F) {
+ for (Instruction &I : BB) {
+ if (potentialDeadInstructions.count(&I)) {
+ continue;
+ }
+
+ // Check if the instruction is "likely dead"
+ if (isInstructionDead(&I, potentialDeadInstructions)) {
+ errs() << "Likely Dead Instruction: " << I << "\n";
+ potentialDeadInstructions.insert(&I);
+ foundNewDead = true;
+ }
+
+ // Print all features for this instruction
+ errs() << "------------------------------------------\n";
+ errs() << "Instruction: " << I << "\n";
+ printBasicBlockFeatures(I, BB);
+ printInstructionFeatures(I, F, LI);
+ printUsageFeatures(I, potentialDeadInstructions);
+ errs() << "------------------------------------------\n";
+ }
}
+ } while (foundNewDead);
+}
+
+bool MyDeadCodeEliminationPass::isInstructionDead(Instruction *Inst, const std::unordered_set<Instruction *> &potentialDeadInstructions) {
+ if (Inst->use_empty()) {
+ return true;
+ }
- // Check if the instruction is "dead" (not used anywhere or used only by dead instructions)
- if (isInstructionDead(&I, potentialDeadInstructions)) {
- errs() << "Potential dead instruction: " << I << "\n";
- potentialDeadInstructions.insert(&I);
- foundNewDead = true; // Mark that we found a new dead instruction
+ for (const Use &U : Inst->uses()) {
+ auto *User = dyn_cast<Instruction>(U.getUser());
+ if (!User || potentialDeadInstructions.find(User) == potentialDeadInstructions.end()) {
+ return false;
}
- }
}
- } while (foundNewDead); // Continue until no new dead instructions are found
+
+ return true;
}
-bool MyDeadCodeEliminationPass::isInstructionDead(Instruction *Inst, const std::unordered_set<Instruction *> &potentialDeadInstructions) {
- // Check if the instruction's result is not used, or all users are in the potentialDeadInstructions set
- if (Inst->use_empty()) {
- return true; // No users, definitely dead
- }
-
- for (const Use &U : Inst->uses()) {
- auto *User = dyn_cast<Instruction>(U.getUser());
- if (!User || potentialDeadInstructions.find(User) == potentialDeadInstructions.end()) {
- return false; // Found a user that is not "dead"
+void MyDeadCodeEliminationPass::printBasicBlockFeatures(const Instruction &I, const BasicBlock &BB) {
+ errs() << "Parent Basic Block: " << BB.getName() << "\n";
+ errs() << " Number of Predecessors: " << std::distance(pred_begin(&BB), pred_end(&BB)) << "\n";
+ errs() << " Number of Successors: " << std::distance(succ_begin(&BB), succ_end(&BB)) << "\n";
+ errs() << " Position in Basic Block: " << getInstructionPosition(I, BB) << "\n";
+ errs() << " Total Instructions in Basic Block: " << BB.size() << "\n";
+}
+
+void MyDeadCodeEliminationPass::printInstructionFeatures(const Instruction &I, const Function &F, const LoopInfo &LI) {
+ errs() << "Instruction Type: " << I.getOpcodeName() << "\n";
+ errs() << "Operand Count: " << I.getNumOperands() << "\n";
+ errs() << "Is Terminator: " << (I.isTerminator() ? "Yes" : "No") << "\n";
+ errs() << "Is Memory Related: " << (isa<LoadInst>(&I) || isa<StoreInst>(&I) ? "Yes" : "No") << "\n";
+
+ if (LI.getLoopFor(I.getParent())) {
+ errs() << "Part of a Loop: Yes\n";
+ } else {
+ errs() << "Part of a Loop: No\n";
}
- }
+}
+
+
+void MyDeadCodeEliminationPass::printUsageFeatures(const Instruction &I, const std::unordered_set<Instruction *> &potentialDeadInstructions) {
+ errs() << "Uses: ";
+ for (const Use &U : I.uses()) {
+ const auto *User = dyn_cast<Instruction>(U.getUser());
+ if (User) {
+ errs() << User->getOpcodeName() << " ";
+ // Fix: Cast to match the type stored in the set
+ if (potentialDeadInstructions.count(const_cast<Instruction *>(User))) {
+ errs() << "(likely dead) ";
+ }
+ }
+ }
+ errs() << "\n";
+ errs() << "Number of Users: " << I.getNumUses() << "\n";
+}
+
- return true; // All users are "dead"
+std::string MyDeadCodeEliminationPass::getInstructionPosition(const Instruction &I, const BasicBlock &BB) {
+ size_t Position = 1;
+ for (const Instruction &Inst : BB) {
+ if (&Inst == &I) {
+ break;
+ }
+ ++Position;
+ }
+ if (Position == 1) {
+ return "First";
+ } else if (&I == &BB.back()) {
+ return "Last";
+ } else {
+ return "Intermediate (" + std::to_string(Position) + ")";
+ }
}
>From 63ab0c8e166c2a2ccf9b7e546a699a52a8815e05 Mon Sep 17 00:00:00 2001
From: Rashmi Salankar <rashmi.salankar at gmail.com>
Date: Mon, 20 Jan 2025 09:36:14 +0530
Subject: [PATCH 5/7] Added 20 features.
---
.../Utils/MyDeadCodeEliminationPass.h | 89 +++--
.../Utils/MyDeadCodeEliminationPass.cpp | 303 +++++++++++-------
2 files changed, 242 insertions(+), 150 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
index 913501b5d4b583..ce18b2153dc7b7 100644
--- a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
+++ b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
@@ -1,27 +1,62 @@
-#ifndef LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
-#define LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
-
-#include "llvm/IR/PassManager.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include <unordered_set>
-#include <string>
-
-namespace llvm {
-
-class MyDeadCodeEliminationPass : public PassInfoMixin<MyDeadCodeEliminationPass> {
-public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-
-private:
- void analyzeInstructionsIteratively(Function &F, FunctionAnalysisManager &AM);
- bool isInstructionDead(Instruction *Inst, const std::unordered_set<Instruction *> &potentialDeadInstructions);
- void printBasicBlockFeatures(const Instruction &I, const BasicBlock &BB);
- void printInstructionFeatures(const Instruction &I, const Function &F, const LoopInfo &LI);
- void printUsageFeatures(const Instruction &I, const std::unordered_set<Instruction *> &potentialDeadInstructions);
- std::string getInstructionPosition(const Instruction &I, const BasicBlock &BB);
-};
-
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
-
+#ifndef LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
+#define LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/PassManager.h"
+#include <string>
+#include <unordered_set>
+
+namespace llvm {
+
+class MyDeadCodeEliminationPass
+ : public PassInfoMixin<MyDeadCodeEliminationPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+private:
+ void analyzeInstructionsIteratively(Function &F, FunctionAnalysisManager &AM);
+
+ bool isInstructionDead(
+ Instruction *Inst,
+ const std::unordered_set<Instruction *> &potentialDeadInstructions);
+
+ void printInstructionFeatures(const Instruction &I, const Function &F,
+ const LoopInfo &LI);
+
+ void printBasicBlockFeatures(const Instruction &I, const BasicBlock &BB);
+
+ void printUsageFeatures(
+ const Instruction &I,
+ const std::unordered_set<Instruction *> &potentialDeadInstructions);
+
+ std::string getInstructionPosition(const Instruction &I,
+ const BasicBlock &BB);
+
+ int getInstructionDepth(
+ const Instruction &I,
+ const std::unordered_set<Instruction *> &potentialDeadInstructions);
+
+ int getLoopNestingDepth(const LoopInfo &LI, const BasicBlock &BB);
+
+ bool isDominatedByEntry(const DominatorTree &DT, const BasicBlock &BB);
+
+ bool isInColdPath(const BasicBlock &BB, const BlockFrequencyInfo &BFI);
+
+ void writeInstructionFeaturesToCSV(const Instruction &I, const Function &F,
+ const LoopInfo &LI,
+ const DominatorTree &DT,
+ const BlockFrequencyInfo &BFI,
+ const std::string &FilePath);
+
+ std::string getFunctionInstructionPosition(const Instruction &I, const Function &F);
+
+ bool isUsingFunctionArguments(const Instruction &I, const Function &F);
+
+ void printInstructionFeatures(const Instruction &I, const BasicBlock &B,
+ const Function &F, const LoopInfo &L);
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_MYDEADCODEELIMINATIONPASS_H
diff --git a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
index eb8d6dd472737b..2bf628170b10c2 100644
--- a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
+++ b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
@@ -1,123 +1,180 @@
-#include "llvm/Transforms/Utils/MyDeadCodeEliminationPass.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include <unordered_set>
-
-using namespace llvm;
-
-PreservedAnalyses MyDeadCodeEliminationPass::run(Function &F, FunctionAnalysisManager &AM) {
- errs() << "Starting MyDeadCodeEliminationPass\n";
-
- analyzeInstructionsIteratively(F, AM);
-
- return PreservedAnalyses::all();
-}
-
-void MyDeadCodeEliminationPass::analyzeInstructionsIteratively(Function &F, FunctionAnalysisManager &AM) {
- auto &LI = AM.getResult<LoopAnalysis>(F);
- std::unordered_set<Instruction *> potentialDeadInstructions;
- bool foundNewDead;
-
- do {
- foundNewDead = false;
-
- for (BasicBlock &BB : F) {
- for (Instruction &I : BB) {
- if (potentialDeadInstructions.count(&I)) {
- continue;
- }
-
- // Check if the instruction is "likely dead"
- if (isInstructionDead(&I, potentialDeadInstructions)) {
- errs() << "Likely Dead Instruction: " << I << "\n";
- potentialDeadInstructions.insert(&I);
- foundNewDead = true;
- }
-
- // Print all features for this instruction
- errs() << "------------------------------------------\n";
- errs() << "Instruction: " << I << "\n";
- printBasicBlockFeatures(I, BB);
- printInstructionFeatures(I, F, LI);
- printUsageFeatures(I, potentialDeadInstructions);
- errs() << "------------------------------------------\n";
- }
- }
- } while (foundNewDead);
-}
-
-bool MyDeadCodeEliminationPass::isInstructionDead(Instruction *Inst, const std::unordered_set<Instruction *> &potentialDeadInstructions) {
- if (Inst->use_empty()) {
- return true;
- }
-
- for (const Use &U : Inst->uses()) {
- auto *User = dyn_cast<Instruction>(U.getUser());
- if (!User || potentialDeadInstructions.find(User) == potentialDeadInstructions.end()) {
- return false;
- }
- }
-
- return true;
-}
-
-void MyDeadCodeEliminationPass::printBasicBlockFeatures(const Instruction &I, const BasicBlock &BB) {
- errs() << "Parent Basic Block: " << BB.getName() << "\n";
- errs() << " Number of Predecessors: " << std::distance(pred_begin(&BB), pred_end(&BB)) << "\n";
- errs() << " Number of Successors: " << std::distance(succ_begin(&BB), succ_end(&BB)) << "\n";
- errs() << " Position in Basic Block: " << getInstructionPosition(I, BB) << "\n";
- errs() << " Total Instructions in Basic Block: " << BB.size() << "\n";
-}
-
-void MyDeadCodeEliminationPass::printInstructionFeatures(const Instruction &I, const Function &F, const LoopInfo &LI) {
- errs() << "Instruction Type: " << I.getOpcodeName() << "\n";
- errs() << "Operand Count: " << I.getNumOperands() << "\n";
- errs() << "Is Terminator: " << (I.isTerminator() ? "Yes" : "No") << "\n";
- errs() << "Is Memory Related: " << (isa<LoadInst>(&I) || isa<StoreInst>(&I) ? "Yes" : "No") << "\n";
-
- if (LI.getLoopFor(I.getParent())) {
- errs() << "Part of a Loop: Yes\n";
- } else {
- errs() << "Part of a Loop: No\n";
- }
-}
-
-
-void MyDeadCodeEliminationPass::printUsageFeatures(const Instruction &I, const std::unordered_set<Instruction *> &potentialDeadInstructions) {
- errs() << "Uses: ";
- for (const Use &U : I.uses()) {
- const auto *User = dyn_cast<Instruction>(U.getUser());
- if (User) {
- errs() << User->getOpcodeName() << " ";
- // Fix: Cast to match the type stored in the set
- if (potentialDeadInstructions.count(const_cast<Instruction *>(User))) {
- errs() << "(likely dead) ";
- }
- }
- }
- errs() << "\n";
- errs() << "Number of Users: " << I.getNumUses() << "\n";
-}
-
-
-std::string MyDeadCodeEliminationPass::getInstructionPosition(const Instruction &I, const BasicBlock &BB) {
- size_t Position = 1;
- for (const Instruction &Inst : BB) {
- if (&Inst == &I) {
- break;
- }
- ++Position;
- }
- if (Position == 1) {
- return "First";
- } else if (&I == &BB.back()) {
- return "Last";
- } else {
- return "Intermediate (" + std::to_string(Position) + ")";
- }
-}
-
+// MyDeadCodeEliminationPass.cpp
+#include "llvm/Transforms/Utils/MyDeadCodeEliminationPass.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/raw_ostream.h"
+#include <unordered_set>
+#include "llvm/IR/Module.h"
+
+
+using namespace llvm;
+
+PreservedAnalyses MyDeadCodeEliminationPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ errs() << "Starting MyDeadCodeEliminationPass\n";
+
+ analyzeInstructionsIteratively(F, AM);
+
+ return PreservedAnalyses::all();
+}
+
+void MyDeadCodeEliminationPass::analyzeInstructionsIteratively(
+ Function &F, FunctionAnalysisManager &AM) {
+ auto &LI = AM.getResult<LoopAnalysis>(F);
+ std::unordered_set<Instruction *> potentialDeadInstructions;
+ bool foundNewDead;
+
+ do {
+ foundNewDead = false;
+
+ for (BasicBlock &BB : F) {
+ for (Instruction &I : BB) {
+ if (potentialDeadInstructions.count(&I)) {
+ continue;
+ }
+
+ // Check if the instruction is "likely dead"
+ if (isInstructionDead(&I, potentialDeadInstructions)) {
+ errs() << "Likely Dead Instruction: " << I << "\n";
+ potentialDeadInstructions.insert(&I);
+ foundNewDead = true;
+ }
+
+ // Print all features for this instruction
+ errs() << "------------------------------------------\n";
+ errs() << "Instruction: " << I << "\n";
+ printInstructionFeatures(I, BB, F, LI);
+ errs() << "------------------------------------------\n";
+ }
+ }
+ } while (foundNewDead);
+}
+
+bool MyDeadCodeEliminationPass::isInstructionDead(
+ Instruction *Inst,
+ const std::unordered_set<Instruction *> &potentialDeadInstructions) {
+ if (Inst->use_empty()) {
+ return true;
+ }
+
+ for (const Use &U : Inst->uses()) {
+ auto *User = dyn_cast<Instruction>(U.getUser());
+ if (!User || potentialDeadInstructions.find(User) ==
+ potentialDeadInstructions.end()) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void MyDeadCodeEliminationPass::printInstructionFeatures(const Instruction &I,
+ const BasicBlock &BB,
+ const Function &F,
+ const LoopInfo &LI) {
+ // Direct Features
+ errs() << "1. Opcode: " << I.getOpcodeName() << "\n";
+ errs() << "2. Number of Operands: " << I.getNumOperands() << "\n";
+ errs() << "3. Is Terminator: " << (I.isTerminator() ? "Yes" : "No") << "\n";
+ errs() << "4. Is Volatile: "
+ << (isa<LoadInst>(&I) || isa<StoreInst>(&I) ? "Yes" : "No") << "\n";
+ errs() << "5. Has Metadata: " << (I.hasMetadata() ? "Yes" : "No") << "\n";
+
+ if (isa<LoadInst>(&I)) {
+ llvm::Align alignment = cast<LoadInst>(&I)->getAlign();
+ errs() << "6. Alignment: " << alignment.value() << "\n";
+ } else if (isa<StoreInst>(&I)) {
+ llvm::Align alignment = cast<StoreInst>(&I)->getAlign();
+ errs() << "6. Alignment: " << alignment.value() << "\n";
+ } else {
+ errs() << "6. Alignment: Not applicable\n";
+ }
+
+
+ /* Alignment alignment = cast<LoadInst>(&I)->getAlign();
+ errs() << "6. Alignment: " << alignment.value() << "\n";*/
+ /* errs() << "6. Alignment: "
+ << (isa<LoadInst>(&I)
+ ? cast<LoadInst>(&I)->getAlign().valueOrOne().value()
+ : 0)
+ << "\n";*/
+ errs() << "7. Instruction Size: "
+ << (I.getType()->isSized()
+ ? I.getModule()->getDataLayout().getTypeSizeInBits(I.getType())
+ : 0)
+ << " bits\n";
+ errs() << "8. Is PHI Node: " << (isa<PHINode>(&I) ? "Yes" : "No") << "\n";
+ errs() << "9. Number of Users: " << I.getNumUses() << "\n";
+ errs() << "10. Is Used in Loops: "
+ << (LI.getLoopFor(I.getParent()) ? "Yes" : "No") << "\n";
+ errs() << "11. Has Side Effects: " << (I.mayHaveSideEffects() ? "Yes" : "No")
+ << "\n";
+
+ // Basic Block-Level Features
+ errs() << "12. Basic Block Predecessor Count: "
+ << std::distance(pred_begin(&BB), pred_end(&BB)) << "\n";
+ errs() << "13. Basic Block Successor Count: "
+ << std::distance(succ_begin(&BB), succ_end(&BB)) << "\n";
+ errs() << "14. Instruction Position in Basic Block: "
+ << getInstructionPosition(I, BB) << "\n";
+ errs() << "15. Basic Block Size: " << BB.size() << "\n";
+ errs() << "16. Is Dominated by Entry: "
+ << (F.getEntryBlock().getName() == BB.getName() ? "Yes" : "No")
+ << "\n";
+ errs() << "17. Loop Nesting Depth: " << (LI.getLoopDepth(&BB)) << "\n";
+
+ // Function-Level Features
+ errs() << "18. Function Argument Usage: "
+ << (isUsingFunctionArguments(I, F) ? "Yes" : "No") << "\n";
+ errs() << "19. Instruction Position in Function: "
+ << getFunctionInstructionPosition(I, F) << "\n";
+ errs() << "20. Function's Loop Count: " << LI.getLoopsInPreorder().size()
+ << "\n";
+}
+
+bool MyDeadCodeEliminationPass::isUsingFunctionArguments(const Instruction &I,
+ const Function &F) {
+ for (const Use &U : I.operands()) {
+ if (isa<Argument>(U)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::string
+MyDeadCodeEliminationPass::getInstructionPosition(const Instruction &I,
+ const BasicBlock &BB) {
+ size_t Position = 1;
+ for (const Instruction &Inst : BB) {
+ if (&Inst == &I) {
+ break;
+ }
+ ++Position;
+ }
+ if (Position == 1) {
+ return "First";
+ } else if (&I == &BB.back()) {
+ return "Last";
+ } else {
+ return "Intermediate (" + std::to_string(Position) + ")";
+ }
+}
+
+std::string
+MyDeadCodeEliminationPass::getFunctionInstructionPosition(const Instruction &I,
+ const Function &F) {
+ size_t Position = 1;
+ for (const BasicBlock &BB : F) {
+ for (const Instruction &Inst : BB) {
+ if (&Inst == &I) {
+ return std::to_string(Position);
+ }
+ ++Position;
+ }
+ }
+ return "Unknown";
+}
>From 0892a715b65942d6fcaa2b3ccd2c3260b563c383 Mon Sep 17 00:00:00 2001
From: Rashmi Salankar <rashmi.salankar at gmail.com>
Date: Mon, 20 Jan 2025 10:21:08 +0530
Subject: [PATCH 6/7] Added 5 more features.
---
.../Utils/MyDeadCodeEliminationPass.h | 3 +-
.../Utils/MyDeadCodeEliminationPass.cpp | 59 ++++++++++++-------
2 files changed, 39 insertions(+), 23 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
index ce18b2153dc7b7..737d29d4c29bb6 100644
--- a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
+++ b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
@@ -54,7 +54,8 @@ class MyDeadCodeEliminationPass
bool isUsingFunctionArguments(const Instruction &I, const Function &F);
void printInstructionFeatures(const Instruction &I, const BasicBlock &B,
- const Function &F, const LoopInfo &L);
+ const Function &F, const LoopInfo &L,
+ const DominatorTree &DT);
};
} // namespace llvm
diff --git a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
index 2bf628170b10c2..dac60afa11c783 100644
--- a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
+++ b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
@@ -1,13 +1,15 @@
-// MyDeadCodeEliminationPass.cpp
#include "llvm/Transforms/Utils/MyDeadCodeEliminationPass.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include <unordered_set>
-#include "llvm/IR/Module.h"
+#include "llvm/Analysis/DominanceFrontier.h"
+#include "llvm/IR/Dominators.h"
using namespace llvm;
@@ -24,6 +26,7 @@ PreservedAnalyses MyDeadCodeEliminationPass::run(Function &F,
void MyDeadCodeEliminationPass::analyzeInstructionsIteratively(
Function &F, FunctionAnalysisManager &AM) {
auto &LI = AM.getResult<LoopAnalysis>(F);
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F); // Retrieve DominatorTree
std::unordered_set<Instruction *> potentialDeadInstructions;
bool foundNewDead;
@@ -46,13 +49,14 @@ void MyDeadCodeEliminationPass::analyzeInstructionsIteratively(
// Print all features for this instruction
errs() << "------------------------------------------\n";
errs() << "Instruction: " << I << "\n";
- printInstructionFeatures(I, BB, F, LI);
+ printInstructionFeatures(I, BB, F, LI, DT);
errs() << "------------------------------------------\n";
}
}
} while (foundNewDead);
}
+
bool MyDeadCodeEliminationPass::isInstructionDead(
Instruction *Inst,
const std::unordered_set<Instruction *> &potentialDeadInstructions) {
@@ -74,7 +78,8 @@ bool MyDeadCodeEliminationPass::isInstructionDead(
void MyDeadCodeEliminationPass::printInstructionFeatures(const Instruction &I,
const BasicBlock &BB,
const Function &F,
- const LoopInfo &LI) {
+ const LoopInfo &LI,
+ const DominatorTree &DT) {
// Direct Features
errs() << "1. Opcode: " << I.getOpcodeName() << "\n";
errs() << "2. Number of Operands: " << I.getNumOperands() << "\n";
@@ -93,14 +98,6 @@ void MyDeadCodeEliminationPass::printInstructionFeatures(const Instruction &I,
errs() << "6. Alignment: Not applicable\n";
}
-
- /* Alignment alignment = cast<LoadInst>(&I)->getAlign();
- errs() << "6. Alignment: " << alignment.value() << "\n";*/
- /* errs() << "6. Alignment: "
- << (isa<LoadInst>(&I)
- ? cast<LoadInst>(&I)->getAlign().valueOrOne().value()
- : 0)
- << "\n";*/
errs() << "7. Instruction Size: "
<< (I.getType()->isSized()
? I.getModule()->getDataLayout().getTypeSizeInBits(I.getType())
@@ -112,26 +109,44 @@ void MyDeadCodeEliminationPass::printInstructionFeatures(const Instruction &I,
<< (LI.getLoopFor(I.getParent()) ? "Yes" : "No") << "\n";
errs() << "11. Has Side Effects: " << (I.mayHaveSideEffects() ? "Yes" : "No")
<< "\n";
+ errs() << "12. Is Constant: " << (isa<Constant>(&I) ? "Yes" : "No") << "\n";
+
// Basic Block-Level Features
- errs() << "12. Basic Block Predecessor Count: "
+ errs() << "13. Basic Block Predecessor Count: "
<< std::distance(pred_begin(&BB), pred_end(&BB)) << "\n";
- errs() << "13. Basic Block Successor Count: "
+ errs() << "14. Basic Block Successor Count: "
<< std::distance(succ_begin(&BB), succ_end(&BB)) << "\n";
- errs() << "14. Instruction Position in Basic Block: "
+ errs() << "15. Instruction Position in Basic Block: "
<< getInstructionPosition(I, BB) << "\n";
- errs() << "15. Basic Block Size: " << BB.size() << "\n";
- errs() << "16. Is Dominated by Entry: "
+ errs() << "16. Is Entry Block: "
+ << (F.getEntryBlock().getName() == BB.getName() ? "Yes" : "No") << "\n";
+ // Assuming DT (DominatorTree) is available:
+ bool isDominated = DT.dominates(&F.getEntryBlock(), &BB);
+ errs() << "17. Is Dominated by Entry: " << (isDominated ? "Yes" : "No") << "\n";
+
+
+
+ /* errs() << "17. Is Dominated by Entry: "
<< (F.getEntryBlock().getName() == BB.getName() ? "Yes" : "No")
- << "\n";
- errs() << "17. Loop Nesting Depth: " << (LI.getLoopDepth(&BB)) << "\n";
+ << "\n";*/
+ errs() << "18. Loop Nesting Depth: " << (LI.getLoopDepth(&BB)) << "\n";
// Function-Level Features
- errs() << "18. Function Argument Usage: "
+ errs() << "19. Function Argument Usage: "
<< (isUsingFunctionArguments(I, F) ? "Yes" : "No") << "\n";
- errs() << "19. Instruction Position in Function: "
+ errs() << "20. Instruction Position in Function: "
<< getFunctionInstructionPosition(I, F) << "\n";
- errs() << "20. Function's Loop Count: " << LI.getLoopsInPreorder().size()
+ errs() << "21. Function's Loop Count: " << LI.getLoopsInPreorder().size()
+ << "\n";
+ errs() << "22. Function Call Depth: " << 0 /* Placeholder */ << "\n";
+
+ // Module-Level Features
+ errs() << "23. Module Size: " << F.getParent()->size() << "\n";
+ errs() << "24. Is in Cold Path: "
+ << "Unknown" /* Placeholder */ << "\n";
+ errs() << "25. Call Graph Features: "
+ << "Unavailable"
<< "\n";
}
>From 6be81ae9502af003bf75290a95b120bdf5d0c1ea Mon Sep 17 00:00:00 2001
From: Rashmi Salankar <rashmi.salankar at gmail.com>
Date: Tue, 21 Jan 2025 02:24:40 +0530
Subject: [PATCH 7/7] Created csv file from the features
---
.../Utils/MyDeadCodeEliminationPass.h | 7 +
.../Utils/MyDeadCodeEliminationPass.cpp | 171 +++++++++++-------
2 files changed, 113 insertions(+), 65 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
index 737d29d4c29bb6..d083d667ab455b 100644
--- a/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
+++ b/llvm/include/llvm/Transforms/Utils/MyDeadCodeEliminationPass.h
@@ -7,6 +7,7 @@
#include <string>
#include <unordered_set>
+class MyDataSet;
namespace llvm {
class MyDeadCodeEliminationPass
@@ -56,6 +57,12 @@ class MyDeadCodeEliminationPass
void printInstructionFeatures(const Instruction &I, const BasicBlock &B,
const Function &F, const LoopInfo &L,
const DominatorTree &DT);
+ void analyzeInstructionsIteratively(Function &F, FunctionAnalysisManager &AM,
+ MyDataSet &dataSet);
+
+ std::vector<std::string> collectInstructionFeatures(const Instruction &I, const BasicBlock &BB,
+ const Function &F, const LoopInfo &LI,
+ const DominatorTree &DT);
};
} // namespace llvm
diff --git a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
index dac60afa11c783..d49f3519932632 100644
--- a/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
+++ b/llvm/lib/Transforms/Utils/MyDeadCodeEliminationPass.cpp
@@ -1,32 +1,83 @@
#include "llvm/Transforms/Utils/MyDeadCodeEliminationPass.h"
+#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
+#include <fstream> // For CSV file handling
#include <unordered_set>
-#include "llvm/Analysis/DominanceFrontier.h"
-#include "llvm/IR/Dominators.h"
+// Class to handle CSV file operations
+class MyDataSet {
+private:
+ std::ofstream outFile;
+
+public:
+ // Constructor opens the file and writes the header row
+ MyDataSet(const std::string &fileName) {
+ outFile.open(fileName);
+ if (outFile.is_open()) {
+ outFile << "Opcode,Number of Operands,Is Terminator,Is Volatile,Has "
+ "Metadata,";
+ outFile << "Alignment,Instruction Size,Is PHI Node,Number of Users,Is "
+ "Used in Loops,";
+ outFile << "Has Side Effects,Is Constant,Basic Block Predecessor "
+ "Count,Basic Block Successor Count,";
+ outFile << "Instruction Position in Basic Block,Is Entry Block,Is "
+ "Dominated by Entry,";
+ outFile << "Loop Nesting Depth,Function Argument Usage,Instruction "
+ "Position in Function,";
+ outFile << "Function's Loop Count,Function Call Depth,Module Size,Is in "
+ "Cold Path,Call Graph Features\n";
+ } else {
+ llvm::errs() << "Failed to open file: " << fileName << "\n";
+ }
+ }
+
+ // Method to write a single row
+ void WriteRow(const std::vector<std::string> &features) {
+ if (!outFile.is_open())
+ return;
+ for (size_t i = 0; i < features.size(); ++i) {
+ outFile << features[i];
+ if (i != features.size() - 1)
+ outFile << ",";
+ }
+ outFile << "\n";
+ }
+
+ // Destructor closes the file
+ ~MyDataSet() {
+ if (outFile.is_open()) {
+ outFile.close();
+ }
+ }
+};
+
using namespace llvm;
PreservedAnalyses MyDeadCodeEliminationPass::run(Function &F,
FunctionAnalysisManager &AM) {
errs() << "Starting MyDeadCodeEliminationPass\n";
- analyzeInstructionsIteratively(F, AM);
+ // Create an instance of MyDataSet to manage the CSV file
+ MyDataSet dataSet("InstructionFeatures.csv");
+
+ analyzeInstructionsIteratively(F, AM, dataSet);
return PreservedAnalyses::all();
}
void MyDeadCodeEliminationPass::analyzeInstructionsIteratively(
- Function &F, FunctionAnalysisManager &AM) {
+ Function &F, FunctionAnalysisManager &AM, MyDataSet &dataSet) {
auto &LI = AM.getResult<LoopAnalysis>(F);
- auto &DT = AM.getResult<DominatorTreeAnalysis>(F); // Retrieve DominatorTree
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
std::unordered_set<Instruction *> potentialDeadInstructions;
bool foundNewDead;
@@ -46,17 +97,23 @@ void MyDeadCodeEliminationPass::analyzeInstructionsIteratively(
foundNewDead = true;
}
+ // Collect features and write to CSV
+ std::vector<std::string> features =
+ collectInstructionFeatures(I, BB, F, LI, DT);
+ dataSet.WriteRow(features);
+
// Print all features for this instruction
errs() << "------------------------------------------\n";
errs() << "Instruction: " << I << "\n";
- printInstructionFeatures(I, BB, F, LI, DT);
+ for (size_t i = 0; i < features.size(); ++i) {
+ errs() << (i + 1) << ". " << features[i] << "\n";
+ }
errs() << "------------------------------------------\n";
}
}
} while (foundNewDead);
}
-
bool MyDeadCodeEliminationPass::isInstructionDead(
Instruction *Inst,
const std::unordered_set<Instruction *> &potentialDeadInstructions) {
@@ -75,79 +132,63 @@ bool MyDeadCodeEliminationPass::isInstructionDead(
return true;
}
-void MyDeadCodeEliminationPass::printInstructionFeatures(const Instruction &I,
- const BasicBlock &BB,
- const Function &F,
- const LoopInfo &LI,
- const DominatorTree &DT) {
+std::vector<std::string> MyDeadCodeEliminationPass::collectInstructionFeatures(
+ const Instruction &I, const BasicBlock &BB, const Function &F,
+ const LoopInfo &LI, const DominatorTree &DT) {
+
+ std::vector<std::string> features;
+
// Direct Features
- errs() << "1. Opcode: " << I.getOpcodeName() << "\n";
- errs() << "2. Number of Operands: " << I.getNumOperands() << "\n";
- errs() << "3. Is Terminator: " << (I.isTerminator() ? "Yes" : "No") << "\n";
- errs() << "4. Is Volatile: "
- << (isa<LoadInst>(&I) || isa<StoreInst>(&I) ? "Yes" : "No") << "\n";
- errs() << "5. Has Metadata: " << (I.hasMetadata() ? "Yes" : "No") << "\n";
+ features.push_back(I.getOpcodeName());
+ features.push_back(std::to_string(I.getNumOperands()));
+ features.push_back(I.isTerminator() ? "Yes" : "No");
+ features.push_back((isa<LoadInst>(&I) || isa<StoreInst>(&I)) ? "Yes" : "No");
+ features.push_back(I.hasMetadata() ? "Yes" : "No");
if (isa<LoadInst>(&I)) {
llvm::Align alignment = cast<LoadInst>(&I)->getAlign();
- errs() << "6. Alignment: " << alignment.value() << "\n";
+ features.push_back(std::to_string(alignment.value()));
} else if (isa<StoreInst>(&I)) {
llvm::Align alignment = cast<StoreInst>(&I)->getAlign();
- errs() << "6. Alignment: " << alignment.value() << "\n";
+ features.push_back(std::to_string(alignment.value()));
} else {
- errs() << "6. Alignment: Not applicable\n";
+ features.push_back("Not applicable");
}
- errs() << "7. Instruction Size: "
- << (I.getType()->isSized()
- ? I.getModule()->getDataLayout().getTypeSizeInBits(I.getType())
- : 0)
- << " bits\n";
- errs() << "8. Is PHI Node: " << (isa<PHINode>(&I) ? "Yes" : "No") << "\n";
- errs() << "9. Number of Users: " << I.getNumUses() << "\n";
- errs() << "10. Is Used in Loops: "
- << (LI.getLoopFor(I.getParent()) ? "Yes" : "No") << "\n";
- errs() << "11. Has Side Effects: " << (I.mayHaveSideEffects() ? "Yes" : "No")
- << "\n";
- errs() << "12. Is Constant: " << (isa<Constant>(&I) ? "Yes" : "No") << "\n";
-
+ features.push_back(
+ I.getType()->isSized()
+ ? std::to_string(
+ I.getModule()->getDataLayout().getTypeSizeInBits(I.getType()))
+ : "0");
+ features.push_back(isa<PHINode>(&I) ? "Yes" : "No");
+ features.push_back(std::to_string(I.getNumUses()));
+ features.push_back(LI.getLoopFor(I.getParent()) ? "Yes" : "No");
+ features.push_back(I.mayHaveSideEffects() ? "Yes" : "No");
+ features.push_back(isa<Constant>(&I) ? "Yes" : "No");
// Basic Block-Level Features
- errs() << "13. Basic Block Predecessor Count: "
- << std::distance(pred_begin(&BB), pred_end(&BB)) << "\n";
- errs() << "14. Basic Block Successor Count: "
- << std::distance(succ_begin(&BB), succ_end(&BB)) << "\n";
- errs() << "15. Instruction Position in Basic Block: "
- << getInstructionPosition(I, BB) << "\n";
- errs() << "16. Is Entry Block: "
- << (F.getEntryBlock().getName() == BB.getName() ? "Yes" : "No") << "\n";
- // Assuming DT (DominatorTree) is available:
- bool isDominated = DT.dominates(&F.getEntryBlock(), &BB);
- errs() << "17. Is Dominated by Entry: " << (isDominated ? "Yes" : "No") << "\n";
-
-
-
- /* errs() << "17. Is Dominated by Entry: "
- << (F.getEntryBlock().getName() == BB.getName() ? "Yes" : "No")
- << "\n";*/
- errs() << "18. Loop Nesting Depth: " << (LI.getLoopDepth(&BB)) << "\n";
+ features.push_back(
+ std::to_string(std::distance(pred_begin(&BB), pred_end(&BB))));
+ features.push_back(
+ std::to_string(std::distance(succ_begin(&BB), succ_end(&BB))));
+ features.push_back(getInstructionPosition(I, BB));
+ features.push_back(F.getEntryBlock().getName() == BB.getName() ? "Yes"
+ : "No");
+ features.push_back(DT.dominates(&F.getEntryBlock(), &BB) ? "Yes" : "No");
+ features.push_back(std::to_string(LI.getLoopDepth(&BB)));
// Function-Level Features
- errs() << "19. Function Argument Usage: "
- << (isUsingFunctionArguments(I, F) ? "Yes" : "No") << "\n";
- errs() << "20. Instruction Position in Function: "
- << getFunctionInstructionPosition(I, F) << "\n";
- errs() << "21. Function's Loop Count: " << LI.getLoopsInPreorder().size()
- << "\n";
- errs() << "22. Function Call Depth: " << 0 /* Placeholder */ << "\n";
+ features.push_back(isUsingFunctionArguments(I, F) ? "Yes" : "No");
+ features.push_back(getFunctionInstructionPosition(I, F));
+ features.push_back(std::to_string(LI.getLoopsInPreorder().size()));
+ features.push_back("0"); // Placeholder for Function Call Depth
// Module-Level Features
- errs() << "23. Module Size: " << F.getParent()->size() << "\n";
- errs() << "24. Is in Cold Path: "
- << "Unknown" /* Placeholder */ << "\n";
- errs() << "25. Call Graph Features: "
- << "Unavailable"
- << "\n";
+ features.push_back(std::to_string(F.getParent()->size()));
+ features.push_back("Unknown"); // Placeholder for Is in Cold Path
+ features.push_back("Unavailable"); // Placeholder for Call Graph Features
+
+ return features;
}
bool MyDeadCodeEliminationPass::isUsingFunctionArguments(const Instruction &I,
More information about the llvm-commits
mailing list