https://github.com/CiberMonah created 
https://github.com/llvm/llvm-project/pull/212188

None

>From f5fe592e126f08e478c9da3ddf0c60c3009c28f6 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Fri, 24 Jul 2026 01:29:10 +0300
Subject: [PATCH 01/21] Added no op pass

---
 .../Instrumentation/DefUseInstrumentation.h   | 19 +++++++++++++++++++
 llvm/lib/Passes/PassBuilder.cpp               |  1 +
 llvm/lib/Passes/PassRegistry.def              |  1 +
 llvm/test/Instrumentation/DefUse/basic.ll     |  6 ++++++
 4 files changed, 27 insertions(+)
 create mode 100644 
llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
 create mode 100644 llvm/test/Instrumentation/DefUse/basic.ll

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
new file mode 100644
index 0000000000000..972827fd6bfb6
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -0,0 +1,19 @@
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Module;
+
+struct DefUseInstrumentationPass
+    : PassInfoMixin<DefUseInstrumentationPass> {
+  PreservedAnalyses run(Module &, ModuleAnalysisManager &) {
+    return PreservedAnalyses::all();
+  }
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
\ No newline at end of file
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 5dbb1e2f49871..0d84798337cbf 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -185,6 +185,7 @@
 #include "llvm/Transforms/Instrumentation/CGProfile.h"
 #include "llvm/Transforms/Instrumentation/ControlHeightReduction.h"
 #include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
+#include "llvm/Transforms/Instrumentation/DefUseInstrumentation.h"
 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
 #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/InstrOrderFile.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 3b92823cd283b..c100505dfad24 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -94,6 +94,7 @@ MODULE_PASS("metarenamer", MetaRenamerPass())
 MODULE_PASS("module-inline", ModuleInlinerPass())
 MODULE_PASS("name-anon-globals", NameAnonGlobalPass())
 MODULE_PASS("no-op-module", NoOpModulePass())
+MODULE_PASS("def-use-instrumentation", DefUseInstrumentationPass())
 MODULE_PASS("nsan", NumericalStabilitySanitizerPass())
 MODULE_PASS("objc-arc-apelim", ObjCARCAPElimPass())
 MODULE_PASS("openmp-opt", OpenMPOptPass())
diff --git a/llvm/test/Instrumentation/DefUse/basic.ll 
b/llvm/test/Instrumentation/DefUse/basic.ll
new file mode 100644
index 0000000000000..380bc4594edc5
--- /dev/null
+++ b/llvm/test/Instrumentation/DefUse/basic.ll
@@ -0,0 +1,6 @@
+; RUN: opt -passes=def-use-instrumentation -disable-output %s
+
+define i32 @main() {
+entry:
+  ret i32 0
+}
\ No newline at end of file

>From 6a17afa36c24f9b88d9ae6248979c9dc1db3203a Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sat, 25 Jul 2026 21:53:16 +0300
Subject: [PATCH 02/21] Find main function in def-use pass

---
 .../Transforms/Instrumentation/DefUseInstrumentation.h    | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index 972827fd6bfb6..66c9f71da8e7c 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -2,6 +2,8 @@
 #define LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
 
 #include "llvm/IR/PassManager.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
 
 namespace llvm {
 
@@ -9,7 +11,11 @@ class Module;
 
 struct DefUseInstrumentationPass
     : PassInfoMixin<DefUseInstrumentationPass> {
-  PreservedAnalyses run(Module &, ModuleAnalysisManager &) {
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
+    Function* Main = M.getFunction("main");
+    if (!Main || Main->isDeclaration()) {
+      return PreservedAnalyses::all();
+    }
     return PreservedAnalyses::all();
   }
 };

>From eca4336c1545ad00344bbcc12aa5f0619f7d2687 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sat, 25 Jul 2026 23:47:58 +0300
Subject: [PATCH 03/21] added callback func

---
 .../Instrumentation/DefUseInstrumentation.h          | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index 66c9f71da8e7c..700b6fe2cda93 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -1,9 +1,13 @@
 #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
 #define LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
 
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
 
 namespace llvm {
 
@@ -16,7 +20,13 @@ struct DefUseInstrumentationPass
     if (!Main || Main->isDeclaration()) {
       return PreservedAnalyses::all();
     }
-    return PreservedAnalyses::all();
+    LLVMContext& Ctx = M.getContext();
+
+    FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), false);
+
+    FunctionCallee funccall =  
M.getOrInsertFunction("__def_use_trace_main_enter", HookType);
+
+    return PreservedAnalyses::none();
   }
 };
 

>From 9ec305f707d5f26b37f1abfe2d3670bbde2bba7b Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 00:50:04 +0300
Subject: [PATCH 04/21] added test def use

---
 llvm/test/Instrumentation/DefUse/basic.ll | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Instrumentation/DefUse/basic.ll 
b/llvm/test/Instrumentation/DefUse/basic.ll
index 380bc4594edc5..12d179b0c2370 100644
--- a/llvm/test/Instrumentation/DefUse/basic.ll
+++ b/llvm/test/Instrumentation/DefUse/basic.ll
@@ -1,6 +1,8 @@
-; RUN: opt -passes=def-use-instrumentation -disable-output %s
+; RUN: opt -passes=def-use-instrumentation -S %s | FileCheck %s
 
 define i32 @main() {
 entry:
   ret i32 0
-}
\ No newline at end of file
+}
+
+; CHECK: declare void @__def_use_trace_main_enter()
\ No newline at end of file

>From f53663e91e4e7507d557962cd31e914d4f595999 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 01:49:54 +0300
Subject: [PATCH 05/21] added multifunctional detection enter

---
 .../Instrumentation/DefUseInstrumentation.h   | 23 +++++++++++--------
 llvm/test/Instrumentation/DefUse/basic.ll     | 13 ++++++++++-
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index 700b6fe2cda93..8bdcbc0dfb9ad 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -1,6 +1,7 @@
 #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
 #define LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
 
+#include "llvm/ADT/StringRef.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/LLVMContext.h"
@@ -16,16 +17,20 @@ class Module;
 struct DefUseInstrumentationPass
     : PassInfoMixin<DefUseInstrumentationPass> {
   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
-    Function* Main = M.getFunction("main");
-    if (!Main || Main->isDeclaration()) {
-      return PreservedAnalyses::all();
-    }
-    LLVMContext& Ctx = M.getContext();
-
-    FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), false);
-
-    FunctionCallee funccall =  
M.getOrInsertFunction("__def_use_trace_main_enter", HookType);
 
+    LLVMContext& Ctx = M.getContext();
+    IRBuilder<> Builder(Ctx);
+
+    for (Function &F : M) {
+      if (F.isDeclaration()) {
+        return PreservedAnalyses::all();
+      }
+      Builder.SetInsertPointPastAllocas(&F);
+      FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), false);
+      FunctionCallee Hook =  M.getOrInsertFunction("__def_use_trace_enter", 
HookType);
+      Builder.CreateCall(Hook);
+    }
+    
     return PreservedAnalyses::none();
   }
 };
diff --git a/llvm/test/Instrumentation/DefUse/basic.ll 
b/llvm/test/Instrumentation/DefUse/basic.ll
index 12d179b0c2370..1d1cbc6a41ded 100644
--- a/llvm/test/Instrumentation/DefUse/basic.ll
+++ b/llvm/test/Instrumentation/DefUse/basic.ll
@@ -2,7 +2,18 @@
 
 define i32 @main() {
 entry:
+  %x = alloca i32
   ret i32 0
 }
 
-; CHECK: declare void @__def_use_trace_main_enter()
\ No newline at end of file
+define i32 @foo() {
+entry:
+  %x = alloca i32
+  ret i32 0
+}
+
+define i32 @bar() {
+entry:
+  %x = alloca i32
+  ret i32 0
+}

>From cbb1463b52815732e33840d6f48b7db9dc20313d Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 02:03:14 +0300
Subject: [PATCH 06/21] bug fix + test with no body func

---
 .../Instrumentation/DefUseInstrumentation.h     |  6 +++---
 llvm/test/Instrumentation/DefUse/basic.ll       | 17 +++++++++++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index 8bdcbc0dfb9ad..40065d29dc54b 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -20,14 +20,14 @@ struct DefUseInstrumentationPass
 
     LLVMContext& Ctx = M.getContext();
     IRBuilder<> Builder(Ctx);
+    FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), false);
+    FunctionCallee Hook =  M.getOrInsertFunction("__def_use_trace_enter", 
HookType);
 
     for (Function &F : M) {
       if (F.isDeclaration()) {
-        return PreservedAnalyses::all();
+        continue;
       }
       Builder.SetInsertPointPastAllocas(&F);
-      FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), false);
-      FunctionCallee Hook =  M.getOrInsertFunction("__def_use_trace_enter", 
HookType);
       Builder.CreateCall(Hook);
     }
     
diff --git a/llvm/test/Instrumentation/DefUse/basic.ll 
b/llvm/test/Instrumentation/DefUse/basic.ll
index 1d1cbc6a41ded..9d5bfe6b681eb 100644
--- a/llvm/test/Instrumentation/DefUse/basic.ll
+++ b/llvm/test/Instrumentation/DefUse/basic.ll
@@ -1,5 +1,7 @@
 ; RUN: opt -passes=def-use-instrumentation -S %s | FileCheck %s
 
+declare void @nobodyfunc ()
+
 define i32 @main() {
 entry:
   %x = alloca i32
@@ -17,3 +19,18 @@ entry:
   %x = alloca i32
   ret i32 0
 }
+
+; CHECK: declare void @nobodyfunc()
+; CHECK-LABEL: define i32 @main()
+; CHECK: %x = alloca i32
+; CHECK-NEXT: call void @__def_use_trace_enter()
+; CHECK-NEXT: ret i32 0
+; CHECK-LABEL: define i32 @foo()
+; CHECK: %x = alloca i32
+; CHECK-NEXT: call void @__def_use_trace_enter()
+; CHECK-NEXT: ret i32 0
+; CHECK-LABEL: define i32 @bar()
+; CHECK: %x = alloca i32
+; CHECK-NEXT: call void @__def_use_trace_enter()
+; CHECK-NEXT: ret i32 0
+; CHECK: declare void @__def_use_trace_enter()

>From 6f548f15f77c748f080389bc6c7e71e6f14d0b60 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 02:28:58 +0300
Subject: [PATCH 07/21] added indexation of callbacks

---
 .../Instrumentation/DefUseInstrumentation.h     | 13 ++++++++++---
 llvm/test/Instrumentation/DefUse/basic.ll       | 17 +----------------
 2 files changed, 11 insertions(+), 19 deletions(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index 40065d29dc54b..4d8c97c13a9a0 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -2,6 +2,8 @@
 #define LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/LLVMContext.h"
@@ -9,6 +11,7 @@
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
+#include <cstdint>
 
 namespace llvm {
 
@@ -20,15 +23,19 @@ struct DefUseInstrumentationPass
 
     LLVMContext& Ctx = M.getContext();
     IRBuilder<> Builder(Ctx);
-    FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), false);
+
+    FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), 
{Type::getInt64Ty(Ctx)}, false);
     FunctionCallee Hook =  M.getOrInsertFunction("__def_use_trace_enter", 
HookType);
 
+    uint64_t CallID = 0;
+
     for (Function &F : M) {
       if (F.isDeclaration()) {
         continue;
       }
-      Builder.SetInsertPointPastAllocas(&F);
-      Builder.CreateCall(Hook);
+      Builder.SetInsertPointPastAllocas(&F );
+      Builder.CreateCall(Hook, Builder.getInt64(CallID));
+      CallID++;
     }
     
     return PreservedAnalyses::none();
diff --git a/llvm/test/Instrumentation/DefUse/basic.ll 
b/llvm/test/Instrumentation/DefUse/basic.ll
index 9d5bfe6b681eb..ac98f75520104 100644
--- a/llvm/test/Instrumentation/DefUse/basic.ll
+++ b/llvm/test/Instrumentation/DefUse/basic.ll
@@ -18,19 +18,4 @@ define i32 @bar() {
 entry:
   %x = alloca i32
   ret i32 0
-}
-
-; CHECK: declare void @nobodyfunc()
-; CHECK-LABEL: define i32 @main()
-; CHECK: %x = alloca i32
-; CHECK-NEXT: call void @__def_use_trace_enter()
-; CHECK-NEXT: ret i32 0
-; CHECK-LABEL: define i32 @foo()
-; CHECK: %x = alloca i32
-; CHECK-NEXT: call void @__def_use_trace_enter()
-; CHECK-NEXT: ret i32 0
-; CHECK-LABEL: define i32 @bar()
-; CHECK: %x = alloca i32
-; CHECK-NEXT: call void @__def_use_trace_enter()
-; CHECK-NEXT: ret i32 0
-; CHECK: declare void @__def_use_trace_enter()
+}
\ No newline at end of file

>From 70cbfca1f30cbf34afe7399079829e2f821b9f6f Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 02:44:55 +0300
Subject: [PATCH 08/21] added static ID to intstrumentations

---
 .../Instrumentation/DefUseInstrumentation.h   | 12 +++++++++---
 llvm/test/Instrumentation/DefUse/basic.ll     | 19 ++++---------------
 2 files changed, 13 insertions(+), 18 deletions(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index 4d8c97c13a9a0..928b0e28b6c26 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -2,10 +2,12 @@
 #define LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/IRBuilder.h"
@@ -33,9 +35,13 @@ struct DefUseInstrumentationPass
       if (F.isDeclaration()) {
         continue;
       }
-      Builder.SetInsertPointPastAllocas(&F );
-      Builder.CreateCall(Hook, Builder.getInt64(CallID));
-      CallID++;
+      for (BasicBlock &BB : F) {
+        for (Instruction &I : BB) {
+          Builder.SetInsertPoint(&I);
+          Builder.CreateCall(Hook, Builder.getInt64(CallID));
+          CallID++;
+        }
+      }
     }
     
     return PreservedAnalyses::none();
diff --git a/llvm/test/Instrumentation/DefUse/basic.ll 
b/llvm/test/Instrumentation/DefUse/basic.ll
index ac98f75520104..5583fe4e0763d 100644
--- a/llvm/test/Instrumentation/DefUse/basic.ll
+++ b/llvm/test/Instrumentation/DefUse/basic.ll
@@ -2,20 +2,9 @@
 
 declare void @nobodyfunc ()
 
-define i32 @main() {
+define i32 @foo(i32 %x) {
 entry:
-  %x = alloca i32
-  ret i32 0
-}
-
-define i32 @foo() {
-entry:
-  %x = alloca i32
-  ret i32 0
-}
-
-define i32 @bar() {
-entry:
-  %x = alloca i32
-  ret i32 0
+  %a = add i32 %x, 1
+  %b = mul i32 %a, 2
+  ret i32 %b
 }
\ No newline at end of file

>From c78d470f343b34dfe5dbcf2a9dd84da4334d2aa3 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 17:39:34 +0300
Subject: [PATCH 09/21] Collect static SSA def use dependences

---
 .../Instrumentation/DefUseInstrumentation.h   | 49 +++++++++++++++++--
 1 file changed, 44 insertions(+), 5 deletions(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index 928b0e28b6c26..f6f0588d40603 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -6,6 +6,7 @@
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/LLVMContext.h"
@@ -13,6 +14,9 @@
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
+#include "llvm/IR/Use.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Transforms/IPO/SampleProfileProbe.h"
 #include <cstdint>
 
 namespace llvm {
@@ -25,10 +29,14 @@ struct DefUseInstrumentationPass
 
     LLVMContext& Ctx = M.getContext();
     IRBuilder<> Builder(Ctx);
+    DenseMap<Instruction*, uint64_t> InstIDs;           // Мапа, для того чтоб 
повторный вызов инструкции вспоминался и айдишник ёё брался
+    SmallVector<Instruction *> Instructions;            // Чтоб модуль заново 
не обходить, а по вектору пробежаться
 
     FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), 
{Type::getInt64Ty(Ctx)}, false);
     FunctionCallee Hook =  M.getOrInsertFunction("__def_use_trace_enter", 
HookType);
 
+
+    // первый обход заполняет мапу инструкция - ID
     uint64_t CallID = 0;
 
     for (Function &F : M) {
@@ -37,16 +45,47 @@ struct DefUseInstrumentationPass
       }
       for (BasicBlock &BB : F) {
         for (Instruction &I : BB) {
-          Builder.SetInsertPoint(&I);
-          Builder.CreateCall(Hook, Builder.getInt64(CallID));
+          Instructions.push_back(&I);
+          InstIDs[&I] = CallID;
           CallID++;
         }
       }
     }
-    
+    // второй обход создает зависимости, на основе мапы, использует ли функция 
результат уже другой функции
+
+    for (Instruction *I : Instructions) {
+      uint64_t UseID = InstIDs.lookup(I);
+
+      for (Use &Operand : I->operands()) {
+        Value *V = Operand.get();
+
+        Instruction *Def = dyn_cast<Instruction>(V);
+
+        if (!Def) {
+          continue;
+        }
+
+        if (!InstIDs.contains(Def))
+          continue;
+
+        uint64_t DefID = InstIDs.lookup(Def);
+        
+        errs()  <<    "DEF " << DefID <<
+                      "-> USE " << UseID << "\n";
+      }
+    }
+
+    // третий обход чтоб вставить колбеки
+    for (Instruction *I : Instructions) {
+      uint64_t ID = InstIDs.lookup(I);
+
+      Builder.SetInsertPoint(I);
+      Builder.CreateCall(Hook, Builder.getInt64(ID));
+    }
+        
     return PreservedAnalyses::none();
-  }
-};
+    }
+  };
 
 } // namespace llvm
 

>From f7e9a370511f9fd0b81e92710984a5eafcef83f1 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 17:58:36 +0300
Subject: [PATCH 10/21] Added dynamic ssa dependences

---
 .../Instrumentation/DefUseInstrumentation.h   | 19 ++++++++-----------
 llvm/test/Instrumentation/DefUse/basic.ll     | 15 ++++++++++++++-
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index f6f0588d40603..e6f6023f72542 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -33,7 +33,8 @@ struct DefUseInstrumentationPass
     SmallVector<Instruction *> Instructions;            // Чтоб модуль заново 
не обходить, а по вектору пробежаться
 
     FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), 
{Type::getInt64Ty(Ctx)}, false);
-    FunctionCallee Hook =  M.getOrInsertFunction("__def_use_trace_enter", 
HookType);
+    FunctionCallee Hook_inst =  M.getOrInsertFunction("__def_use_trace_inst", 
HookType);
+    FunctionCallee Hook_use =  
M.getOrInsertFunction("__def_use_trace_ssa_use", HookType);
 
 
     // первый обход заполняет мапу инструкция - ID
@@ -51,10 +52,12 @@ struct DefUseInstrumentationPass
         }
       }
     }
-    // второй обход создает зависимости, на основе мапы, использует ли функция 
результат уже другой функции
+    // второй обход создает зависимости, на основе мапы, использует ли функция 
результат уже другой инструкции
 
     for (Instruction *I : Instructions) {
       uint64_t UseID = InstIDs.lookup(I);
+      Builder.SetInsertPoint(I);
+      Builder.CreateCall(Hook_inst, Builder.getInt64(UseID));
 
       for (Use &Operand : I->operands()) {
         Value *V = Operand.get();
@@ -69,20 +72,14 @@ struct DefUseInstrumentationPass
           continue;
 
         uint64_t DefID = InstIDs.lookup(Def);
-        
+
+        Builder.CreateCall(Hook_use, Builder.getInt64(DefID));
+
         errs()  <<    "DEF " << DefID <<
                       "-> USE " << UseID << "\n";
       }
     }
 
-    // третий обход чтоб вставить колбеки
-    for (Instruction *I : Instructions) {
-      uint64_t ID = InstIDs.lookup(I);
-
-      Builder.SetInsertPoint(I);
-      Builder.CreateCall(Hook, Builder.getInt64(ID));
-    }
-        
     return PreservedAnalyses::none();
     }
   };
diff --git a/llvm/test/Instrumentation/DefUse/basic.ll 
b/llvm/test/Instrumentation/DefUse/basic.ll
index 5583fe4e0763d..ad2ff13d37dda 100644
--- a/llvm/test/Instrumentation/DefUse/basic.ll
+++ b/llvm/test/Instrumentation/DefUse/basic.ll
@@ -7,4 +7,17 @@ entry:
   %a = add i32 %x, 1
   %b = mul i32 %a, 2
   ret i32 %b
-}
\ No newline at end of file
+}
+
+; CHECK-LABEL: define i32 @foo(i32 %x)
+; CHECK: call void @__def_use_trace_inst(i64 0)
+; CHECK-NEXT: %a = add i32 %x, 1
+; CHECK-NEXT: call void @__def_use_trace_inst(i64 1)
+; CHECK-NEXT: call void @__def_use_trace_ssa_use(i64 0)
+; CHECK-NEXT: %b = mul i32 %a, 2
+; CHECK-NEXT: call void @__def_use_trace_inst(i64 2)
+; CHECK-NEXT: call void @__def_use_trace_ssa_use(i64 1)
+; CHECK-NEXT: ret i32 %b
+
+; CHECK: declare void @__def_use_trace_inst(i64)
+; CHECK: declare void @__def_use_trace_ssa_use(i64)
\ No newline at end of file

>From c76386136735442172443a1b73026b93541b2da8 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 18:27:57 +0300
Subject: [PATCH 11/21] Recognize load and store instructions

---
 .../Instrumentation/DefUseInstrumentation.h   | 24 +++++++++++++++++++
 llvm/test/Instrumentation/DefUse/basic.ll     | 23 ++++--------------
 2 files changed, 28 insertions(+), 19 deletions(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index e6f6023f72542..6eb0c1b3995b8 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -17,6 +17,12 @@
 #include "llvm/IR/Use.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Transforms/IPO/SampleProfileProbe.h"
+
+
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Instructions.h"
+
+
 #include <cstdint>
 
 namespace llvm {
@@ -36,6 +42,11 @@ struct DefUseInstrumentationPass
     FunctionCallee Hook_inst =  M.getOrInsertFunction("__def_use_trace_inst", 
HookType);
     FunctionCallee Hook_use =  
M.getOrInsertFunction("__def_use_trace_ssa_use", HookType);
 
+    FunctionType *MemoryHookType = 
FunctionType::get(Type::getVoidTy(Ctx),{Type::getInt64Ty(Ctx), 
Type::getInt64Ty(Ctx)},false);
+    FunctionCallee HookLoad = M.getOrInsertFunction("__def_use_trace_load", 
MemoryHookType);
+    FunctionCallee HookStore = M.getOrInsertFunction("__def_use_trace_store", 
MemoryHookType);
+
+    const DataLayout &DL = M.getDataLayout(); // 
DataLayout::getTypeStoreSize()  чтоб получить размер значения в памяти
 
     // первый обход заполняет мапу инструкция - ID
     uint64_t CallID = 0;
@@ -59,6 +70,19 @@ struct DefUseInstrumentationPass
       Builder.SetInsertPoint(I);
       Builder.CreateCall(Hook_inst, Builder.getInt64(UseID));
 
+      if (auto *LI = dyn_cast<LoadInst>(I)) {
+        Value *PointerOperand = LI->getPointerOperand();
+
+        errs() << "Found LOAD: " << *LI << '\n';
+        errs() << "Load pointer operand: " << *PointerOperand << '\n';
+
+      } else if (auto *SI = dyn_cast<StoreInst>(I)) {
+        Value *PointerOperand = SI->getPointerOperand();
+
+        errs() << "Found STORE: " << *SI << '\n';
+        errs() << "Store pointer operand: " << *PointerOperand << '\n';
+      }
+
       for (Use &Operand : I->operands()) {
         Value *V = Operand.get();
 
diff --git a/llvm/test/Instrumentation/DefUse/basic.ll 
b/llvm/test/Instrumentation/DefUse/basic.ll
index ad2ff13d37dda..2aad422fde013 100644
--- a/llvm/test/Instrumentation/DefUse/basic.ll
+++ b/llvm/test/Instrumentation/DefUse/basic.ll
@@ -1,23 +1,8 @@
 ; RUN: opt -passes=def-use-instrumentation -S %s | FileCheck %s
 
-declare void @nobodyfunc ()
-
-define i32 @foo(i32 %x) {
+define i32 @memory_test(ptr %p, i32 %x) {
 entry:
-  %a = add i32 %x, 1
-  %b = mul i32 %a, 2
-  ret i32 %b
+  store i32 %x, ptr %p
+  %value = load i32, ptr %p
+  ret i32 %value
 }
-
-; CHECK-LABEL: define i32 @foo(i32 %x)
-; CHECK: call void @__def_use_trace_inst(i64 0)
-; CHECK-NEXT: %a = add i32 %x, 1
-; CHECK-NEXT: call void @__def_use_trace_inst(i64 1)
-; CHECK-NEXT: call void @__def_use_trace_ssa_use(i64 0)
-; CHECK-NEXT: %b = mul i32 %a, 2
-; CHECK-NEXT: call void @__def_use_trace_inst(i64 2)
-; CHECK-NEXT: call void @__def_use_trace_ssa_use(i64 1)
-; CHECK-NEXT: ret i32 %b
-
-; CHECK: declare void @__def_use_trace_inst(i64)
-; CHECK: declare void @__def_use_trace_ssa_use(i64)
\ No newline at end of file

>From b9376520e32be76ceb7c1f2bd2a9996dceb38c1c Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 19:12:11 +0300
Subject: [PATCH 12/21] Instrument load and store memory accesses

---
 .../Instrumentation/DefUseInstrumentation.h   | 31 ++++++++++++++++---
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index 6eb0c1b3995b8..dc1ff9dff5f5e 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -70,17 +70,40 @@ struct DefUseInstrumentationPass
       Builder.SetInsertPoint(I);
       Builder.CreateCall(Hook_inst, Builder.getInt64(UseID));
 
+      // Load и Store отельно обрабатываем
       if (auto *LI = dyn_cast<LoadInst>(I)) {
         Value *PointerOperand = LI->getPointerOperand();
 
-        errs() << "Found LOAD: " << *LI << '\n';
-        errs() << "Load pointer operand: " << *PointerOperand << '\n';
+        Value *Address =
+            Builder.CreatePtrToInt(PointerOperand, Type::getInt64Ty(Ctx));
+
+        errs() << "LOAD address value: " << *Address << '\n';
+
+        TypeSize LoadSize = DL.getTypeStoreSize(LI->getType());
+
+        errs() << "Load size: " << LoadSize.getFixedValue() << '\n';
+
+        uint64_t Size = LoadSize.getFixedValue();
+
+        Builder.CreateCall(HookLoad, {Address, Builder.getInt64(Size)});
 
       } else if (auto *SI = dyn_cast<StoreInst>(I)) {
         Value *PointerOperand = SI->getPointerOperand();
 
-        errs() << "Found STORE: " << *SI << '\n';
-        errs() << "Store pointer operand: " << *PointerOperand << '\n';
+        Value *Address =
+            Builder.CreatePtrToInt(PointerOperand, Type::getInt64Ty(Ctx));
+
+        errs() << "Store address value: " << *Address << '\n';
+
+        Type *StoredType = SI->getValueOperand()->getType();
+        TypeSize StoreSize = DL.getTypeStoreSize(StoredType);
+
+        errs() << "Store size: " << StoreSize.getFixedValue() << '\n';
+
+
+        uint64_t Size = StoreSize.getFixedValue();
+
+        Builder.CreateCall(HookStore, {Address, Builder.getInt64(Size)});
       }
 
       for (Use &Operand : I->operands()) {

>From b5c3998b1a0744848fd261dcef940a4b7f6803dc Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 19:12:45 +0300
Subject: [PATCH 13/21] Add initial dynamic def-use runtime

---
 llvm/tools/def-use-runtime/DefUseRuntime.cpp | 50 ++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 llvm/tools/def-use-runtime/DefUseRuntime.cpp

diff --git a/llvm/tools/def-use-runtime/DefUseRuntime.cpp 
b/llvm/tools/def-use-runtime/DefUseRuntime.cpp
new file mode 100644
index 0000000000000..b1948a81a6633
--- /dev/null
+++ b/llvm/tools/def-use-runtime/DefUseRuntime.cpp
@@ -0,0 +1,50 @@
+#include <cstdint>
+#include <cstdio>
+#include <unordered_map>
+#include <iostream>
+#include <iomanip>
+
+static std::uint64_t NextEventID = 0;
+static std::uint64_t CurrentEventID = 0;
+
+static std::unordered_map<std::uint64_t, std::uint64_t> LastEvent;
+
+extern "C" void __def_use_trace_inst(std::uint64_t InstID) {
+  CurrentEventID = NextEventID++;
+
+  std::fprintf(
+      stderr,
+      "EVENT %llu INST %llu\n",
+      static_cast<unsigned long long>(CurrentEventID),
+      static_cast<unsigned long long>(InstID));
+
+  LastEvent[InstID] = CurrentEventID;
+}
+
+extern "C" void __def_use_trace_ssa_use(std::uint64_t DefID) {
+  auto It = LastEvent.find(DefID);
+
+  if (It == LastEvent.end()) {
+    std::fprintf(
+        stderr,
+        "MISSING DEF INST %llu\n",
+        static_cast<unsigned long long>(DefID));
+    return;
+  }
+
+  std::fprintf(
+      stderr,
+      "EDGE %llu -> %llu\n",
+      static_cast<unsigned long long>(It->second),
+      static_cast<unsigned long long>(CurrentEventID));
+}
+
+extern "C" void __def_use_trace_store(uint64_t Address,
+                                      uint64_t Size) {
+  std::cerr << "STORE 0x" << std::hex <<  Address << " " <<  std::dec << Size 
<< '\n';
+}
+
+extern "C" void __def_use_trace_load(uint64_t Address,
+                                     uint64_t Size) {
+  std::cerr << "LOAD 0x" << std::hex << Address << " " << std::dec <<  Size << 
'\n';
+}

>From 2ce68c4ec35ffda6ac13474222a4726f6b1a024d Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 19:20:47 +0300
Subject: [PATCH 14/21] track memmory  def use instructions

---
 llvm/tools/def-use-runtime/DefUseRuntime.cpp | 97 ++++++++++++++------
 1 file changed, 69 insertions(+), 28 deletions(-)

diff --git a/llvm/tools/def-use-runtime/DefUseRuntime.cpp 
b/llvm/tools/def-use-runtime/DefUseRuntime.cpp
index b1948a81a6633..86d02bc43d197 100644
--- a/llvm/tools/def-use-runtime/DefUseRuntime.cpp
+++ b/llvm/tools/def-use-runtime/DefUseRuntime.cpp
@@ -1,50 +1,91 @@
 #include <cstdint>
-#include <cstdio>
-#include <unordered_map>
-#include <iostream>
 #include <iomanip>
+#include <iostream>
+#include <map>
+#include <utility>
+#include <unordered_map>
+
+namespace {
 
-static std::uint64_t NextEventID = 0;
-static std::uint64_t CurrentEventID = 0;
+uint64_t NextEventID = 0;
+uint64_t CurrentEventID = 0;
 
-static std::unordered_map<std::uint64_t, std::uint64_t> LastEvent;
+// Статический InstID -> последнее динамическое событие этой инструкции.
+std::unordered_map<uint64_t, uint64_t> LastEventByInstID;
 
-extern "C" void __def_use_trace_inst(std::uint64_t InstID) {
+// Пока учитываем только полное совпадение адреса и размера:
+//
+// (Address, Size) -> EventID последнего store.
+std::map<std::pair<uint64_t, uint64_t>, uint64_t> LastStoreEvent;
+
+} // namespace
+
+extern "C" void __def_use_trace_inst(uint64_t InstID) {
   CurrentEventID = NextEventID++;
 
-  std::fprintf(
-      stderr,
-      "EVENT %llu INST %llu\n",
-      static_cast<unsigned long long>(CurrentEventID),
-      static_cast<unsigned long long>(InstID));
+  LastEventByInstID[InstID] = CurrentEventID;
 
-  LastEvent[InstID] = CurrentEventID;
+  std::cerr << "EVENT "
+            << CurrentEventID
+            << " INST "
+            << InstID
+            << '\n';
 }
 
-extern "C" void __def_use_trace_ssa_use(std::uint64_t DefID) {
-  auto It = LastEvent.find(DefID);
+extern "C" void __def_use_trace_ssa_use(uint64_t DefInstID) {
+  auto It = LastEventByInstID.find(DefInstID);
 
-  if (It == LastEvent.end()) {
-    std::fprintf(
-        stderr,
-        "MISSING DEF INST %llu\n",
-        static_cast<unsigned long long>(DefID));
+  if (It == LastEventByInstID.end()) {
     return;
   }
 
-  std::fprintf(
-      stderr,
-      "EDGE %llu -> %llu\n",
-      static_cast<unsigned long long>(It->second),
-      static_cast<unsigned long long>(CurrentEventID));
+  uint64_t DefEventID = It->second;
+
+  std::cerr << "EDGE "
+            << DefEventID
+            << " -> "
+            << CurrentEventID
+            << '\n';
 }
 
 extern "C" void __def_use_trace_store(uint64_t Address,
                                       uint64_t Size) {
-  std::cerr << "STORE 0x" << std::hex <<  Address << " " <<  std::dec << Size 
<< '\n';
+  std::cerr << "STORE 0x"
+            << std::hex
+            << Address
+            << std::dec
+            << " "
+            << Size
+            << '\n';
+
+  std::pair<uint64_t, uint64_t> MemoryRange{Address, Size};
+
+  LastStoreEvent[MemoryRange] = CurrentEventID;
 }
 
 extern "C" void __def_use_trace_load(uint64_t Address,
                                      uint64_t Size) {
-  std::cerr << "LOAD 0x" << std::hex << Address << " " << std::dec <<  Size << 
'\n';
-}
+  std::cerr << "LOAD 0x"
+            << std::hex
+            << Address
+            << std::dec
+            << " "
+            << Size
+            << '\n';
+
+  std::pair<uint64_t, uint64_t> MemoryRange{Address, Size};
+
+  auto It = LastStoreEvent.find(MemoryRange);
+
+  if (It == LastStoreEvent.end()) {
+    return;
+  }
+
+  uint64_t StoreEventID = It->second;
+
+  std::cerr << "MEM_EDGE "
+            << StoreEventID
+            << " -> "
+            << CurrentEventID
+            << '\n';
+}
\ No newline at end of file

>From 4c7a599050b98985ead779ee8afe83ac67710861 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 19:58:41 +0300
Subject: [PATCH 15/21] Add Clang flag for def use

---
 clang/include/clang/Basic/CodeGenOptions.def | 3 ++-
 clang/include/clang/Driver/Options.td        | 7 ++++++-
 clang/lib/CodeGen/BackendUtil.cpp            | 4 ++++
 clang/lib/Driver/ToolChains/Clang.cpp        | 3 +++
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 12808eb275fa4..fe47c34ab5702 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -99,7 +99,8 @@ ENUM_CODEGENOPT(EmbedBitcode, EmbedBitcodeKind, 2, Embed_Off)
 ENUM_CODEGENOPT(InlineAsmDialect, InlineAsmDialectKind, 1, IAD_ATT)
 CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard 
variables
                                         ///< are required.
-CODEGENOPT(FunctionSections  , 1, 0) ///< Set when -ffunction-sections is 
enabled.
+CODEGENOPT(FunctionSections  , 1, 0)
+CODEGENOPT(InsertDefUse     , 1, 0) ///< Enable dynamic def-use 
instrumentation. ///< Set when -ffunction-sections is enabled.
 CODEGENOPT(BBAddrMap  , 1, 0) ///< Set when -fbasic-block-address-map is 
enabled.
 CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
                                        ///< enabled.
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 15f9ee75492e3..ec530a4bdd887 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -50,7 +50,6 @@ def NoArgumentUnused : OptionFlag;
 // Unsupported - The option is unsupported, and the driver will reject command
 // lines that use it.
 def Unsupported : OptionFlag;
-
 // Ignored - The option is unsupported, and the driver will silently ignore it.
 def Ignored : OptionFlag;
 
@@ -4176,6 +4175,12 @@ defm zero_initialized_in_bss : 
BoolFOption<"zero-initialized-in-bss",
   NegFlag<SetTrue, [], [ClangOption, CC1Option],
           "Don't place zero initialized data in BSS">,
   PosFlag<SetFalse>>;
+defm insert_def_use : BoolFOption<"insert-def-use",
+  CodeGenOpts<"InsertDefUse">, DefaultFalse,
+  PosFlag<SetTrue, [], [ClangOption, CC1Option],
+          "Enable dynamic def-use instrumentation">,
+  NegFlag<SetFalse>>;
+
 defm function_sections : BoolFOption<"function-sections",
   CodeGenOpts<"FunctionSections">, DefaultFalse,
   PosFlag<SetTrue, [], [ClangOption, CC1Option],
diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index e765bbf637a66..ff305bc33f7d5 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -69,6 +69,7 @@
 #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
 #include "llvm/Transforms/Instrumentation/BoundsChecking.h"
 #include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
+#include "llvm/Transforms/Instrumentation/DefUseInstrumentation.h"
 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
 #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
@@ -1038,6 +1039,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
     }
   }
 
+  if (CodeGenOpts.InsertDefUse)
+    MPM.addPass(llvm::DefUseInstrumentationPass());
+
   // Link against bitcodes supplied via the -mlink-builtin-bitcode option
   if (CodeGenOpts.LinkBitcodePostopt)
     MPM.addPass(LinkInModulesPass(BC));
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 8858c318aba7a..f73175356034c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6197,6 +6197,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
                     options::OPT_fno_separate_named_sections);
   Args.addOptInFlag(CmdArgs, options::OPT_funique_internal_linkage_names,
                     options::OPT_fno_unique_internal_linkage_names);
+
+  Args.addOptInFlag(CmdArgs, options::OPT_finsert_def_use,
+                    options::OPT_fno_insert_def_use);
   Args.addOptInFlag(CmdArgs, options::OPT_funique_basic_block_section_names,
                     options::OPT_fno_unique_basic_block_section_names);
   Args.addOptInFlag(CmdArgs, options::OPT_fconvergent_functions,

>From a7279239f188a98e14cb054c5b99d91ac455e2b4 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 20:06:05 +0300
Subject: [PATCH 16/21] add linking def-use runtime

---
 clang/lib/Driver/ToolChains/Gnu.cpp           | 10 ++++++++++
 clang/runtime/CMakeLists.txt                  |  2 ++
 clang/runtime/def-use/CMakeLists.txt          | 20 +++++++++++++++++++
 .../runtime/def-use}/DefUseRuntime.cpp        |  0
 4 files changed, 32 insertions(+)
 create mode 100644 clang/runtime/def-use/CMakeLists.txt
 rename {llvm/tools/def-use-runtime => clang/runtime/def-use}/DefUseRuntime.cpp 
(100%)

diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 5e9a655eaf824..9ffecee257e93 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -545,6 +545,16 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
   addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs);
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
+  if (Args.hasFlag(options::OPT_finsert_def_use,
+                   options::OPT_fno_insert_def_use, false)) {
+    std::string DefUseRuntimePath =
+        (llvm::Twine(llvm::sys::path::parent_path(D.Dir)) + "/" +
+         CLANG_INSTALL_LIBDIR_BASENAME + "/libDefUseRuntime.a")
+            .str();
+
+    CmdArgs.push_back(Args.MakeArgString(DefUseRuntimePath));
+  }
+
   addHIPRuntimeLibArgs(ToolChain, C, Args, CmdArgs);
 
   // The profile runtime also needs access to system libraries.
diff --git a/clang/runtime/CMakeLists.txt b/clang/runtime/CMakeLists.txt
index 65fcdc2868f03..7709619e073ba 100644
--- a/clang/runtime/CMakeLists.txt
+++ b/clang/runtime/CMakeLists.txt
@@ -2,6 +2,8 @@
 
 include(ExternalProject)
 
+add_subdirectory(def-use)
+
 set(known_subdirs
   "libcxx"
   )
diff --git a/clang/runtime/def-use/CMakeLists.txt 
b/clang/runtime/def-use/CMakeLists.txt
new file mode 100644
index 0000000000000..a73057e14f768
--- /dev/null
+++ b/clang/runtime/def-use/CMakeLists.txt
@@ -0,0 +1,20 @@
+add_library(DefUseRuntime STATIC
+  DefUseRuntime.cpp
+)
+
+set_target_properties(DefUseRuntime PROPERTIES
+  OUTPUT_NAME DefUseRuntime
+  ARCHIVE_OUTPUT_DIRECTORY "${LLVM_LIBRARY_OUTPUT_INTDIR}"
+  POSITION_INDEPENDENT_CODE ON
+  FOLDER "Clang/Runtime"
+)
+
+# При сборке clang автоматически собираем и runtime.
+if(TARGET clang)
+  add_dependencies(clang DefUseRuntime)
+endif()
+
+install(TARGETS DefUseRuntime
+  ARCHIVE DESTINATION "lib${LLVM_LIBDIR_SUFFIX}"
+  COMPONENT DefUseRuntime
+)
diff --git a/llvm/tools/def-use-runtime/DefUseRuntime.cpp 
b/clang/runtime/def-use/DefUseRuntime.cpp
similarity index 100%
rename from llvm/tools/def-use-runtime/DefUseRuntime.cpp
rename to clang/runtime/def-use/DefUseRuntime.cpp

>From a886a17a2afb41f59753c9eae0e906005238579f Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Sun, 26 Jul 2026 23:55:07 +0300
Subject: [PATCH 17/21] added unique IDs in diffenent modules

---
 clang/runtime/def-use/DefUseRuntime.cpp       | 27 ++++++++------
 .../Instrumentation/DefUseInstrumentation.h   | 35 +++++++++++++++----
 2 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/clang/runtime/def-use/DefUseRuntime.cpp 
b/clang/runtime/def-use/DefUseRuntime.cpp
index 86d02bc43d197..881a8432ba7f8 100644
--- a/clang/runtime/def-use/DefUseRuntime.cpp
+++ b/clang/runtime/def-use/DefUseRuntime.cpp
@@ -10,32 +10,39 @@ namespace {
 uint64_t NextEventID = 0;
 uint64_t CurrentEventID = 0;
 
-// Статический InstID -> последнее динамическое событие этой инструкции.
-std::unordered_map<uint64_t, uint64_t> LastEventByInstID;
+// Теперь инструкция определяется парой ModuleToken, InstID -> последнее 
динамическое событие.
+std::map<std::pair<uint64_t, uint64_t>, uint64_t>
+    LastEventByInstruction;
 
-// Пока учитываем только полное совпадение адреса и размера:
-//
 // (Address, Size) -> EventID последнего store.
-std::map<std::pair<uint64_t, uint64_t>, uint64_t> LastStoreEvent;
+std::map<std::pair<uint64_t, uint64_t>, uint64_t>
+    LastStoreEvent;
 
 } // namespace
 
-extern "C" void __def_use_trace_inst(uint64_t InstID) {
+extern "C" void __def_use_trace_inst(uint64_t ModuleToken,
+                                     uint64_t InstID) {
   CurrentEventID = NextEventID++;
 
-  LastEventByInstID[InstID] = CurrentEventID;
+  LastEventByInstruction[{ModuleToken, InstID}] = CurrentEventID;
 
   std::cerr << "EVENT "
             << CurrentEventID
+            << " MODULE 0x"
+            << std::hex
+            << ModuleToken
+            << std::dec
             << " INST "
             << InstID
             << '\n';
 }
 
-extern "C" void __def_use_trace_ssa_use(uint64_t DefInstID) {
-  auto It = LastEventByInstID.find(DefInstID);
+extern "C" void __def_use_trace_ssa_use(uint64_t ModuleToken,
+                                        uint64_t DefInstID) {
+  auto It =
+      LastEventByInstruction.find({ModuleToken, DefInstID});
 
-  if (It == LastEventByInstID.end()) {
+  if (It == LastEventByInstruction.end()) {
     return;
   }
 
diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index dc1ff9dff5f5e..a44832e2a6132 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -22,6 +22,7 @@
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Instructions.h"
 
+#include "llvm/IR/GlobalVariable.h"
 
 #include <cstdint>
 
@@ -38,7 +39,7 @@ struct DefUseInstrumentationPass
     DenseMap<Instruction*, uint64_t> InstIDs;           // Мапа, для того чтоб 
повторный вызов инструкции вспоминался и айдишник ёё брался
     SmallVector<Instruction *> Instructions;            // Чтоб модуль заново 
не обходить, а по вектору пробежаться
 
-    FunctionType* HookType = FunctionType::get(Type::getVoidTy(Ctx), 
{Type::getInt64Ty(Ctx)}, false);
+    FunctionType *HookType = 
FunctionType::get(Type::getVoidTy(Ctx),{Type::getInt64Ty(Ctx), 
Type::getInt64Ty(Ctx)}, false);
     FunctionCallee Hook_inst =  M.getOrInsertFunction("__def_use_trace_inst", 
HookType);
     FunctionCallee Hook_use =  
M.getOrInsertFunction("__def_use_trace_ssa_use", HookType);
 
@@ -48,13 +49,35 @@ struct DefUseInstrumentationPass
 
     const DataLayout &DL = M.getDataLayout(); // 
DataLayout::getTypeStoreSize()  чтоб получить размер значения в памяти
 
+    GlobalVariable *ModuleTokenGV = 
M.getGlobalVariable("__def_use_module_token", true);
+
+    if (!ModuleTokenGV) {
+      ModuleTokenGV = new GlobalVariable(
+          M,
+          Type::getInt8Ty(Ctx),
+          false,
+          GlobalValue::InternalLinkage,
+          ConstantInt::get(Type::getInt8Ty(Ctx), 0),
+          "__def_use_module_token");
+    }
+
+    Constant *ModuleToken = 
ConstantExpr::getPtrToInt(ModuleTokenGV,Type::getInt64Ty(Ctx));
+
     // первый обход заполняет мапу инструкция - ID
     uint64_t CallID = 0;
 
     for (Function &F : M) {
       if (F.isDeclaration()) {
         continue;
+      } 
+      
+      StringRef Name = F.getName();
+
+      if (Name.starts_with("__cxx_global_var_init") ||
+          Name.starts_with("_GLOBAL__sub_I_")) {
+        continue;
       }
+
       for (BasicBlock &BB : F) {
         for (Instruction &I : BB) {
           Instructions.push_back(&I);
@@ -68,7 +91,7 @@ struct DefUseInstrumentationPass
     for (Instruction *I : Instructions) {
       uint64_t UseID = InstIDs.lookup(I);
       Builder.SetInsertPoint(I);
-      Builder.CreateCall(Hook_inst, Builder.getInt64(UseID));
+      Builder.CreateCall(Hook_inst,  {ModuleToken,Builder.getInt64(UseID)});
 
       // Load и Store отельно обрабатываем
       if (auto *LI = dyn_cast<LoadInst>(I)) {
@@ -85,7 +108,7 @@ struct DefUseInstrumentationPass
 
         uint64_t Size = LoadSize.getFixedValue();
 
-        Builder.CreateCall(HookLoad, {Address, Builder.getInt64(Size)});
+        Builder.CreateCall(HookLoad, {  Address, Builder.getInt64(Size)});
 
       } else if (auto *SI = dyn_cast<StoreInst>(I)) {
         Value *PointerOperand = SI->getPointerOperand();
@@ -103,7 +126,7 @@ struct DefUseInstrumentationPass
 
         uint64_t Size = StoreSize.getFixedValue();
 
-        Builder.CreateCall(HookStore, {Address, Builder.getInt64(Size)});
+        Builder.CreateCall(HookStore, { Address, Builder.getInt64(Size)});
       }
 
       for (Use &Operand : I->operands()) {
@@ -113,14 +136,14 @@ struct DefUseInstrumentationPass
 
         if (!Def) {
           continue;
-        }
+        } 
 
         if (!InstIDs.contains(Def))
           continue;
 
         uint64_t DefID = InstIDs.lookup(Def);
 
-        Builder.CreateCall(Hook_use, Builder.getInt64(DefID));
+        Builder.CreateCall(Hook_use,  {ModuleToken, Builder.getInt64(DefID)});
 
         errs()  <<    "DEF " << DefID <<
                       "-> USE " << UseID << "\n";

>From 0e1f8f771d945af0286ca1b4a5cee488ad611839 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Mon, 27 Jul 2026 00:36:42 +0300
Subject: [PATCH 18/21] Write dynamic def-use trace to file

---
 clang/runtime/def-use/DefUseRuntime.cpp | 32 +++++++++++++++++++++----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/clang/runtime/def-use/DefUseRuntime.cpp 
b/clang/runtime/def-use/DefUseRuntime.cpp
index 881a8432ba7f8..8c4a56ca7b24a 100644
--- a/clang/runtime/def-use/DefUseRuntime.cpp
+++ b/clang/runtime/def-use/DefUseRuntime.cpp
@@ -4,6 +4,8 @@
 #include <map>
 #include <utility>
 #include <unordered_map>
+#include <cstdlib>
+#include <fstream>
 
 namespace {
 
@@ -18,6 +20,26 @@ std::map<std::pair<uint64_t, uint64_t>, uint64_t>
 std::map<std::pair<uint64_t, uint64_t>, uint64_t>
     LastStoreEvent;
 
+
+std::ostream &Trace() {
+  struct TraceOutput {
+    std::ofstream File;
+
+    TraceOutput() {
+      const char *Path = std::getenv("DEF_USE_TRACE");
+      File.open(Path ? Path : "defuse.trace");
+    }
+  };
+
+  static TraceOutput Output;
+
+  if (!Output.File.is_open()) {
+    return std::cerr;
+  }
+
+  return Output.File;
+}
+
 } // namespace
 
 extern "C" void __def_use_trace_inst(uint64_t ModuleToken,
@@ -26,7 +48,7 @@ extern "C" void __def_use_trace_inst(uint64_t ModuleToken,
 
   LastEventByInstruction[{ModuleToken, InstID}] = CurrentEventID;
 
-  std::cerr << "EVENT "
+  Trace()   << "EVENT "
             << CurrentEventID
             << " MODULE 0x"
             << std::hex
@@ -48,7 +70,7 @@ extern "C" void __def_use_trace_ssa_use(uint64_t ModuleToken,
 
   uint64_t DefEventID = It->second;
 
-  std::cerr << "EDGE "
+  Trace() << "EDGE "
             << DefEventID
             << " -> "
             << CurrentEventID
@@ -57,7 +79,7 @@ extern "C" void __def_use_trace_ssa_use(uint64_t ModuleToken,
 
 extern "C" void __def_use_trace_store(uint64_t Address,
                                       uint64_t Size) {
-  std::cerr << "STORE 0x"
+  Trace()   << "STORE 0x"
             << std::hex
             << Address
             << std::dec
@@ -72,7 +94,7 @@ extern "C" void __def_use_trace_store(uint64_t Address,
 
 extern "C" void __def_use_trace_load(uint64_t Address,
                                      uint64_t Size) {
-  std::cerr << "LOAD 0x"
+  Trace()   << "LOAD 0x"
             << std::hex
             << Address
             << std::dec
@@ -90,7 +112,7 @@ extern "C" void __def_use_trace_load(uint64_t Address,
 
   uint64_t StoreEventID = It->second;
 
-  std::cerr << "MEM_EDGE "
+  Trace()   << "MEM_EDGE "
             << StoreEventID
             << " -> "
             << CurrentEventID

>From c62748ff1113537f742ed88a077b76ec6e3d1aba Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Mon, 27 Jul 2026 01:22:06 +0300
Subject: [PATCH 19/21]  Added def use tracing in dot file

---
 .../Instrumentation/DefUseInstrumentation.h   |   5 +
 llvm/tools/def-use-to-dot/CMakeLists.txt      |   3 +
 llvm/tools/def-use-to-dot/DefUseToDot.cpp     | 216 ++++++++++++++++++
 3 files changed, 224 insertions(+)
 create mode 100644 llvm/tools/def-use-to-dot/CMakeLists.txt
 create mode 100644 llvm/tools/def-use-to-dot/DefUseToDot.cpp

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index a44832e2a6132..59d49e71a39f2 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -89,6 +89,9 @@ struct DefUseInstrumentationPass
     // второй обход создает зависимости, на основе мапы, использует ли функция 
результат уже другой инструкции
 
     for (Instruction *I : Instructions) {
+      if (isa<PHINode>(I)) {    //phi функции скипаем, реализации нет
+        continue;
+      }
       uint64_t UseID = InstIDs.lookup(I);
       Builder.SetInsertPoint(I);
       Builder.CreateCall(Hook_inst,  {ModuleToken,Builder.getInt64(UseID)});
@@ -129,6 +132,8 @@ struct DefUseInstrumentationPass
         Builder.CreateCall(HookStore, { Address, Builder.getInt64(Size)});
       }
 
+
+      // проверка операнда, что это именно mul/plus и др, и установление связи 
def - use
       for (Use &Operand : I->operands()) {
         Value *V = Operand.get();
 
diff --git a/llvm/tools/def-use-to-dot/CMakeLists.txt 
b/llvm/tools/def-use-to-dot/CMakeLists.txt
new file mode 100644
index 0000000000000..e8dd8ba59a7bf
--- /dev/null
+++ b/llvm/tools/def-use-to-dot/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_llvm_tool(def-use-to-dot
+  DefUseToDot.cpp
+)
diff --git a/llvm/tools/def-use-to-dot/DefUseToDot.cpp 
b/llvm/tools/def-use-to-dot/DefUseToDot.cpp
new file mode 100644
index 0000000000000..8358c6dd701d8
--- /dev/null
+++ b/llvm/tools/def-use-to-dot/DefUseToDot.cpp
@@ -0,0 +1,216 @@
+#include <cstdint>
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <optional>
+#include <sstream>
+#include <string>
+#include <vector>
+
+struct Event {
+  uint64_t ID;
+  std::string Module;
+  uint64_t InstID;
+  std::vector<std::string> Details;
+};
+
+struct Edge {
+  uint64_t From;
+  uint64_t To;
+  bool IsMemory;
+};
+
+static std::string escapeDotString(const std::string &Text) {
+  std::string Result;
+
+  for (char C : Text) {
+    if (C == '\\' || C == '"') {
+      Result += '\\';
+    }
+
+    Result += C;
+  }
+
+  return Result;
+}
+
+int main(int argc, char **argv) {
+  if (argc != 2 && argc != 4) {
+    std::cerr
+        << "Usage: " << argv[0]
+        << " <trace-file> [-o <dot-file>]\n";
+    return 1;
+  }
+
+  std::string InputPath = argv[1];
+  std::string OutputPath = "graph.dot";
+
+  if (argc == 4) {
+    if (std::string(argv[2]) != "-o") {
+      std::cerr << "Expected -o before output filename\n";
+      return 1;
+    }
+
+    OutputPath = argv[3];
+  }
+
+  std::ifstream Input(InputPath);
+
+  if (!Input.is_open()) {
+    std::cerr << "Could not open input file: "
+              << InputPath << '\n';
+    return 1;
+  }
+
+  std::map<uint64_t, Event> Events;
+  std::vector<Edge> Edges;
+  std::optional<uint64_t> CurrentEventID;
+
+  std::string Line;
+
+  while (std::getline(Input, Line)) {
+    if (Line.empty()) {
+      continue;
+    }
+
+    std::istringstream LineStream(Line);
+    std::string RecordType;
+
+    LineStream >> RecordType;
+
+    if (RecordType == "EVENT") {
+      uint64_t EventID;
+      uint64_t InstID;
+      std::string ModuleWord;
+      std::string Module;
+      std::string InstWord;
+
+      if (!(LineStream >> EventID
+                       >> ModuleWord
+                       >> Module
+                       >> InstWord
+                       >> InstID)) {
+        std::cerr << "Invalid EVENT line: "
+                  << Line << '\n';
+        return 1;
+      }
+
+      if (ModuleWord != "MODULE" ||
+          InstWord != "INST") {
+        std::cerr << "Invalid EVENT format: "
+                  << Line << '\n';
+        return 1;
+      }
+
+      Events[EventID] =
+          Event{EventID, Module, InstID, {}};
+
+      CurrentEventID = EventID;
+
+    } else if (RecordType == "EDGE" ||
+               RecordType == "MEM_EDGE") {
+      uint64_t From;
+      uint64_t To;
+      std::string Arrow;
+
+      if (!(LineStream >> From >> Arrow >> To) ||
+          Arrow != "->") {
+        std::cerr << "Invalid edge line: "
+                  << Line << '\n';
+        return 1;
+      }
+
+      Edges.push_back(
+          Edge{From, To, RecordType == "MEM_EDGE"});
+
+    } else if (RecordType == "STORE" ||
+               RecordType == "LOAD") {
+      std::string Address;
+      uint64_t Size;
+
+      if (!(LineStream >> Address >> Size)) {
+        std::cerr << "Invalid memory line: "
+                  << Line << '\n';
+        return 1;
+      }
+
+      if (!CurrentEventID.has_value()) {
+        std::cerr
+            << "Memory operation without preceding EVENT: "
+            << Line << '\n';
+        return 1;
+      }
+
+      auto EventIt = Events.find(*CurrentEventID);
+
+      if (EventIt == Events.end()) {
+        std::cerr << "Current event was not found\n";
+        return 1;
+      }
+
+      std::ostringstream Detail;
+
+      Detail << RecordType
+             << " " << Address
+             << " size=" << Size;
+
+      EventIt->second.Details.push_back(Detail.str());
+
+    } else {
+      std::cerr << "Unknown trace record: "
+                << Line << '\n';
+      return 1;
+    }
+  }
+
+  std::ofstream Output(OutputPath);
+
+  if (!Output.is_open()) {
+    std::cerr << "Could not open output file: "
+              << OutputPath << '\n';
+    return 1;
+  }
+
+  Output << "digraph DefUse {\n";
+  Output << "  rankdir=TB;\n";
+  Output << "  node [shape=box, fontname=\"monospace\"];\n";
+  Output << "  edge [fontname=\"monospace\"];\n\n";
+
+  for (const auto &[EventID, EventData] : Events) {
+    std::ostringstream Label;
+
+    Label << "Event " << EventData.ID
+          << "\\nModule " << EventData.Module
+          << "\\nInst " << EventData.InstID;
+
+    for (const std::string &Detail : EventData.Details) {
+      Label << "\\n" << Detail;
+    }
+
+    Output << "  n" << EventID
+           << " [label=\""
+           << escapeDotString(Label.str())
+           << "\"];\n";
+  }
+
+  Output << '\n';
+
+  for (const Edge &GraphEdge : Edges) {
+    Output << "  n" << GraphEdge.From
+          << " -> n" << GraphEdge.To;
+
+    if (GraphEdge.IsMemory) {
+      Output << " [label=\"memory\", style=dashed]";
+    }
+
+    Output << ";\n";
+  }
+
+  Output << "}\n";
+
+  std::cout << "Wrote " << Events.size()
+            << " nodes and " << Edges.size()
+            << " edges to " << OutputPath << '\n';
+
+  return 0;
+}

>From 13b8ef62949444a84c6dddc92761b24b280f5e45 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Mon, 27 Jul 2026 01:28:01 +0300
Subject: [PATCH 20/21] Complete dynamic def-use graph generation

---
 .../Instrumentation/DefUseInstrumentation.h          | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index 59d49e71a39f2..c3c0dd1851bb2 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -103,11 +103,11 @@ struct DefUseInstrumentationPass
         Value *Address =
             Builder.CreatePtrToInt(PointerOperand, Type::getInt64Ty(Ctx));
 
-        errs() << "LOAD address value: " << *Address << '\n';
+        // errs() << "LOAD address value: " << *Address << '\n';
 
         TypeSize LoadSize = DL.getTypeStoreSize(LI->getType());
 
-        errs() << "Load size: " << LoadSize.getFixedValue() << '\n';
+        // errs() << "Load size: " << LoadSize.getFixedValue() << '\n';
 
         uint64_t Size = LoadSize.getFixedValue();
 
@@ -119,12 +119,12 @@ struct DefUseInstrumentationPass
         Value *Address =
             Builder.CreatePtrToInt(PointerOperand, Type::getInt64Ty(Ctx));
 
-        errs() << "Store address value: " << *Address << '\n';
+        // errs() << "Store address value: " << *Address << '\n';
 
         Type *StoredType = SI->getValueOperand()->getType();
         TypeSize StoreSize = DL.getTypeStoreSize(StoredType);
 
-        errs() << "Store size: " << StoreSize.getFixedValue() << '\n';
+        // errs() << "Store size: " << StoreSize.getFixedValue() << '\n';
 
 
         uint64_t Size = StoreSize.getFixedValue();
@@ -150,8 +150,8 @@ struct DefUseInstrumentationPass
 
         Builder.CreateCall(Hook_use,  {ModuleToken, Builder.getInt64(DefID)});
 
-        errs()  <<    "DEF " << DefID <<
-                      "-> USE " << UseID << "\n";
+        // errs()  <<    "DEF " << DefID <<
+        //              "-> USE " << UseID << "\n";
       }
     }
 

>From 854375c0e54fa7e722546730259454b1726d5206 Mon Sep 17 00:00:00 2001
From: ag <[email protected]>
Date: Mon, 27 Jul 2026 01:54:30 +0300
Subject: [PATCH 21/21] Move def use to source file

---
 .../Instrumentation/DefUseInstrumentation.h   | 153 +----------------
 .../Transforms/Instrumentation/CMakeLists.txt |   1 +
 .../Instrumentation/DefUseInstrumentation.cpp | 157 ++++++++++++++++++
 3 files changed, 161 insertions(+), 150 deletions(-)
 create mode 100644 
llvm/lib/Transforms/Instrumentation/DefUseInstrumentation.cpp

diff --git 
a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h 
b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
index c3c0dd1851bb2..a138f7e5309db 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/DefUseInstrumentation.h
@@ -1,30 +1,7 @@
 #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
 #define LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
 
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Constant.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/PassManager.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Type.h"
-#include "llvm/IR/Use.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Transforms/IPO/SampleProfileProbe.h"
-
-
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Instructions.h"
-
-#include "llvm/IR/GlobalVariable.h"
-
-#include <cstdint>
 
 namespace llvm {
 
@@ -32,133 +9,9 @@ class Module;
 
 struct DefUseInstrumentationPass
     : PassInfoMixin<DefUseInstrumentationPass> {
-  PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
-
-    LLVMContext& Ctx = M.getContext();
-    IRBuilder<> Builder(Ctx);
-    DenseMap<Instruction*, uint64_t> InstIDs;           // Мапа, для того чтоб 
повторный вызов инструкции вспоминался и айдишник ёё брался
-    SmallVector<Instruction *> Instructions;            // Чтоб модуль заново 
не обходить, а по вектору пробежаться
-
-    FunctionType *HookType = 
FunctionType::get(Type::getVoidTy(Ctx),{Type::getInt64Ty(Ctx), 
Type::getInt64Ty(Ctx)}, false);
-    FunctionCallee Hook_inst =  M.getOrInsertFunction("__def_use_trace_inst", 
HookType);
-    FunctionCallee Hook_use =  
M.getOrInsertFunction("__def_use_trace_ssa_use", HookType);
-
-    FunctionType *MemoryHookType = 
FunctionType::get(Type::getVoidTy(Ctx),{Type::getInt64Ty(Ctx), 
Type::getInt64Ty(Ctx)},false);
-    FunctionCallee HookLoad = M.getOrInsertFunction("__def_use_trace_load", 
MemoryHookType);
-    FunctionCallee HookStore = M.getOrInsertFunction("__def_use_trace_store", 
MemoryHookType);
-
-    const DataLayout &DL = M.getDataLayout(); // 
DataLayout::getTypeStoreSize()  чтоб получить размер значения в памяти
-
-    GlobalVariable *ModuleTokenGV = 
M.getGlobalVariable("__def_use_module_token", true);
-
-    if (!ModuleTokenGV) {
-      ModuleTokenGV = new GlobalVariable(
-          M,
-          Type::getInt8Ty(Ctx),
-          false,
-          GlobalValue::InternalLinkage,
-          ConstantInt::get(Type::getInt8Ty(Ctx), 0),
-          "__def_use_module_token");
-    }
-
-    Constant *ModuleToken = 
ConstantExpr::getPtrToInt(ModuleTokenGV,Type::getInt64Ty(Ctx));
-
-    // первый обход заполняет мапу инструкция - ID
-    uint64_t CallID = 0;
-
-    for (Function &F : M) {
-      if (F.isDeclaration()) {
-        continue;
-      } 
-      
-      StringRef Name = F.getName();
-
-      if (Name.starts_with("__cxx_global_var_init") ||
-          Name.starts_with("_GLOBAL__sub_I_")) {
-        continue;
-      }
-
-      for (BasicBlock &BB : F) {
-        for (Instruction &I : BB) {
-          Instructions.push_back(&I);
-          InstIDs[&I] = CallID;
-          CallID++;
-        }
-      }
-    }
-    // второй обход создает зависимости, на основе мапы, использует ли функция 
результат уже другой инструкции
-
-    for (Instruction *I : Instructions) {
-      if (isa<PHINode>(I)) {    //phi функции скипаем, реализации нет
-        continue;
-      }
-      uint64_t UseID = InstIDs.lookup(I);
-      Builder.SetInsertPoint(I);
-      Builder.CreateCall(Hook_inst,  {ModuleToken,Builder.getInt64(UseID)});
-
-      // Load и Store отельно обрабатываем
-      if (auto *LI = dyn_cast<LoadInst>(I)) {
-        Value *PointerOperand = LI->getPointerOperand();
-
-        Value *Address =
-            Builder.CreatePtrToInt(PointerOperand, Type::getInt64Ty(Ctx));
-
-        // errs() << "LOAD address value: " << *Address << '\n';
-
-        TypeSize LoadSize = DL.getTypeStoreSize(LI->getType());
-
-        // errs() << "Load size: " << LoadSize.getFixedValue() << '\n';
-
-        uint64_t Size = LoadSize.getFixedValue();
-
-        Builder.CreateCall(HookLoad, {  Address, Builder.getInt64(Size)});
-
-      } else if (auto *SI = dyn_cast<StoreInst>(I)) {
-        Value *PointerOperand = SI->getPointerOperand();
-
-        Value *Address =
-            Builder.CreatePtrToInt(PointerOperand, Type::getInt64Ty(Ctx));
-
-        // errs() << "Store address value: " << *Address << '\n';
-
-        Type *StoredType = SI->getValueOperand()->getType();
-        TypeSize StoreSize = DL.getTypeStoreSize(StoredType);
-
-        // errs() << "Store size: " << StoreSize.getFixedValue() << '\n';
-
-
-        uint64_t Size = StoreSize.getFixedValue();
-
-        Builder.CreateCall(HookStore, { Address, Builder.getInt64(Size)});
-      }
-
-
-      // проверка операнда, что это именно mul/plus и др, и установление связи 
def - use
-      for (Use &Operand : I->operands()) {
-        Value *V = Operand.get();
-
-        Instruction *Def = dyn_cast<Instruction>(V);
-
-        if (!Def) {
-          continue;
-        } 
-
-        if (!InstIDs.contains(Def))
-          continue;
-
-        uint64_t DefID = InstIDs.lookup(Def);
-
-        Builder.CreateCall(Hook_use,  {ModuleToken, Builder.getInt64(DefID)});
-
-        // errs()  <<    "DEF " << DefID <<
-        //              "-> USE " << UseID << "\n";
-      }
-    }
-
-    return PreservedAnalyses::none();
-    }
-  };
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
 
 } // namespace llvm
 
-#endif // LLVM_TRANSFORMS_INSTRUMENTATION_DEFUSEINSTRUMENTATION_H
\ No newline at end of file
+#endif
\ No newline at end of file
diff --git a/llvm/lib/Transforms/Instrumentation/CMakeLists.txt 
b/llvm/lib/Transforms/Instrumentation/CMakeLists.txt
index 4e3f9e27e0c34..b165baf9b9ff1 100644
--- a/llvm/lib/Transforms/Instrumentation/CMakeLists.txt
+++ b/llvm/lib/Transforms/Instrumentation/CMakeLists.txt
@@ -4,6 +4,7 @@ add_llvm_component_library(LLVMInstrumentation
   CGProfile.cpp
   ControlHeightReduction.cpp
   DataFlowSanitizer.cpp
+  DefUseInstrumentation.cpp
   GCOVProfiling.cpp
   BlockCoverageInference.cpp
   MemProfiler.cpp
diff --git a/llvm/lib/Transforms/Instrumentation/DefUseInstrumentation.cpp 
b/llvm/lib/Transforms/Instrumentation/DefUseInstrumentation.cpp
new file mode 100644
index 0000000000000..b0c3d4ce0cf2a
--- /dev/null
+++ b/llvm/lib/Transforms/Instrumentation/DefUseInstrumentation.cpp
@@ -0,0 +1,157 @@
+#include "llvm/Transforms/Instrumentation/DefUseInstrumentation.h"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Use.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Transforms/IPO/SampleProfileProbe.h"
+
+
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Instructions.h"
+
+#include "llvm/IR/GlobalVariable.h"
+
+#include <cstdint>
+
+namespace llvm {
+
+PreservedAnalyses
+DefUseInstrumentationPass::run(Module &M, ModuleAnalysisManager &) {
+
+    LLVMContext& Ctx = M.getContext();
+    IRBuilder<> Builder(Ctx);
+    DenseMap<Instruction*, uint64_t> InstIDs;           // Мапа, для того чтоб 
повторный вызов инструкции вспоминался и айдишник ёё брался
+    SmallVector<Instruction *> Instructions;            // Чтоб модуль заново 
не обходить, а по вектору пробежаться
+
+    FunctionType *HookType = 
FunctionType::get(Type::getVoidTy(Ctx),{Type::getInt64Ty(Ctx), 
Type::getInt64Ty(Ctx)}, false);
+    FunctionCallee Hook_inst =  M.getOrInsertFunction("__def_use_trace_inst", 
HookType);
+    FunctionCallee Hook_use =  
M.getOrInsertFunction("__def_use_trace_ssa_use", HookType);
+
+    FunctionType *MemoryHookType = 
FunctionType::get(Type::getVoidTy(Ctx),{Type::getInt64Ty(Ctx), 
Type::getInt64Ty(Ctx)},false);
+    FunctionCallee HookLoad = M.getOrInsertFunction("__def_use_trace_load", 
MemoryHookType);
+    FunctionCallee HookStore = M.getOrInsertFunction("__def_use_trace_store", 
MemoryHookType);
+
+    const DataLayout &DL = M.getDataLayout(); // 
DataLayout::getTypeStoreSize()  чтоб получить размер значения в памяти
+
+    GlobalVariable *ModuleTokenGV = 
M.getGlobalVariable("__def_use_module_token", true);
+
+    if (!ModuleTokenGV) {
+      ModuleTokenGV = new GlobalVariable(
+          M,
+          Type::getInt8Ty(Ctx),
+          false,
+          GlobalValue::InternalLinkage,
+          ConstantInt::get(Type::getInt8Ty(Ctx), 0),
+          "__def_use_module_token");
+    }
+
+    Constant *ModuleToken = 
ConstantExpr::getPtrToInt(ModuleTokenGV,Type::getInt64Ty(Ctx));
+
+    // первый обход заполняет мапу инструкция - ID
+    uint64_t CallID = 0;
+
+    for (Function &F : M) {
+      if (F.isDeclaration()) {
+        continue;
+      } 
+      
+      StringRef Name = F.getName();
+
+      if (Name.starts_with("__cxx_global_var_init") ||
+          Name.starts_with("_GLOBAL__sub_I_")) {
+        continue;
+      }
+
+      for (BasicBlock &BB : F) {
+        for (Instruction &I : BB) {
+          Instructions.push_back(&I);
+          InstIDs[&I] = CallID;
+          CallID++;
+        }
+      }
+    }
+    // второй обход создает зависимости, на основе мапы, использует ли функция 
результат уже другой инструкции
+
+    for (Instruction *I : Instructions) {
+      if (isa<PHINode>(I)) {    //phi функции скипаем, реализации нет
+        continue;
+      }
+      uint64_t UseID = InstIDs.lookup(I);
+      Builder.SetInsertPoint(I);
+      Builder.CreateCall(Hook_inst,  {ModuleToken,Builder.getInt64(UseID)});
+
+      // Load и Store отельно обрабатываем
+      if (auto *LI = dyn_cast<LoadInst>(I)) {
+        Value *PointerOperand = LI->getPointerOperand();
+
+        Value *Address =
+            Builder.CreatePtrToInt(PointerOperand, Type::getInt64Ty(Ctx));
+
+        // errs() << "LOAD address value: " << *Address << '\n';
+
+        TypeSize LoadSize = DL.getTypeStoreSize(LI->getType());
+
+        // errs() << "Load size: " << LoadSize.getFixedValue() << '\n';
+
+        uint64_t Size = LoadSize.getFixedValue();
+
+        Builder.CreateCall(HookLoad, {  Address, Builder.getInt64(Size)});
+
+      } else if (auto *SI = dyn_cast<StoreInst>(I)) {
+        Value *PointerOperand = SI->getPointerOperand();
+
+        Value *Address =
+            Builder.CreatePtrToInt(PointerOperand, Type::getInt64Ty(Ctx));
+
+        // errs() << "Store address value: " << *Address << '\n';
+
+        Type *StoredType = SI->getValueOperand()->getType();
+        TypeSize StoreSize = DL.getTypeStoreSize(StoredType);
+
+        // errs() << "Store size: " << StoreSize.getFixedValue() << '\n';
+
+
+        uint64_t Size = StoreSize.getFixedValue();
+
+        Builder.CreateCall(HookStore, { Address, Builder.getInt64(Size)});
+      }
+
+
+      // проверка операнда, что это именно mul/plus и др, и установление связи 
def - use
+      for (Use &Operand : I->operands()) {
+        Value *V = Operand.get();
+
+        Instruction *Def = dyn_cast<Instruction>(V);
+
+        if (!Def) {
+          continue;
+        } 
+
+        if (!InstIDs.contains(Def))
+          continue;
+
+        uint64_t DefID = InstIDs.lookup(Def);
+
+        Builder.CreateCall(Hook_use,  {ModuleToken, Builder.getInt64(DefID)});
+
+        // errs()  <<    "DEF " << DefID <<
+        //              "-> USE " << UseID << "\n";
+      }
+    }
+
+    return PreservedAnalyses::none();
+}
+
+} // namespace llvm

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to