[llvm] My dce (PR #120468)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 19 20:08:52 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/5] 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/5] 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/5] 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/5] 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/5] 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";
+}
More information about the llvm-commits
mailing list