8000 Hunk cherry-pick from 8a2198773e: fix InterceptorEnabled visibility. by MorthimerMcMare · Pull Request #50 · focs-lab/llvm-project · GitHub
[go: up one dir, main page]

Skip to content
< 8000 div class="clearfix mt-4 px-3 px-md-4 px-lg-5">

Hunk cherry-pick from 8a2198773e: fix InterceptorEnabled visibility. #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
9fbf126
Escape Analysis init
apaznikov Oct 14, 2024
312d6bb
Updated GEP aliasing logic
apaznikov Oct 15, 2024
b4d7468
Fixed EA aliasing/GEP/GP logic
apaznikov Oct 18, 2024
11ce82d
Enabling Escape Analysis in TSan
apaznikov Oct 18, 2024
56b5364
Make Alias relation (partly) symmetrical. Refactoring
apaznikov Oct 23, 2024
ed8da00
Added escaping function arguments support
apaznikov Oct 24, 2024
5d97016
Passing value is neither escaping nor aliasing
apaznikov Oct 25, 2024
a837b65
Add mutual (recursive) aliases support
apaznikov Oct 28, 2024
40cb7f6
Make EA BB-wise, update TSan integration
apaznikov Oct 29, 2024
819b16c
Efforts for support of 'already escaped objects' (such as pointer arg…
apaznikov Oct 31, 2024
d432a4b
Considering external 'already escaped' objects, fix aliasing, refacto…
apaznikov Nov 4, 2024
7bbbe09
Fix bugs with external objects
apaznikov Nov 4, 2024
2ebed05
Add global_arrays.ll (ConstExprGEP) test, combine return.ll and simpl…
apaznikov Nov 6, 2024
ab460b0
Make getUnderlyingMayEscapeObjectsNew return the list of object (in p…
apaznikov Nov 6, 2024
28e1f2f
Move to more wide use of ValueTracking infrastructure in getUnderlyin…
apaznikov Nov 7, 2024
f7fe4ca
Migration to getUnderlyingMayEscObjectsNew
apaznikov Nov 8, 2024
2f95b0b
Added inttoptr/ptrtoint tests
apaznikov Nov 11, 2024
348eeb0
Minor refactoring (mostly compOutEscapeState)
apaznikov Nov 12, 2024
1945512
Added GlobalEscapeAnalysis pass infrastructure
apaznikov Nov 13, 2024
9ac70ee
Updated escape/no-escape with passing to calls or aliasing to ptr arg…
apaznikov Nov 15, 2024
4c86254
Starting work on propagation of argument escape info: add argument to…
apaznikov Nov 26, 2024
cefcd9e
Finished IPA EA, refactoring, tests
apaznikov Nov 27, 2024
020af62
Added recursive call conservative algorithm
apaznikov Nov 28, 2024
b155fe5
Fix std::optional<std::reference_wrapper<ArgumentEscapesMap>> ArgsEsc…
apaznikov Nov 29, 2024
bc3186e
Added recursive call conservative algorithm
apaznikov Nov 28, 2024
fbbe19e
Fix std::optional<std::reference_wrapper<ArgumentEscapesMap>> ArgsEsc…
apaznikov Nov 29, 2024
b342f09
Efforts on TSan and IPA EA integration
apaznikov Nov 29, 2024
178fd58
Add Global EA usage to TSan
apaznikov Dec 3, 2024
d0c40d7
Finished support of IPA EA & TSan, fixed bugs
apaznikov Dec 3, 2024
f862a25
Add support of function returning escaped value -- draft
apaznikov Dec 4, 2024
56855b2
Minor fixes for argument escape logic (DBG)
apaznikov Dec 5, 2024
2efb371
Add support of function returning escaped value -- draft 2
apaznikov Dec 5, 2024
2aa25f7
Add EscapeReasonTy
apaznikov Dec 5, 2024
6fbd3bd
Fix addEscapingObject logic for EscReason support
apaznikov Dec 5, 2024
dbc01a3
Fix logic with EscReasons, isEscapeForFunc, etc
apaznikov Dec 6, 2024
24ded0c
Fixed merging escape states, fixed printing, minor fixes, add tests w…
apaznikov Dec 9, 2024
de71362
Support of SCC in IPA - in progress
apaznikov Dec 9, 2024
a03d550
Many fixes for recursive functions, argument, aliasing processing and…
apaznikov Dec 11, 2024
460e60e
Refactoring and debug
apaznikov Dec 12, 2024
ce24c31
Fixed logic mainly with EscapeReason/Argument checks. Add support for…
apaznikov Dec 13, 2024
142270d
Merge branch 'tsan-with-ea-IPA-DBG-rec-calls-TMP' into tsan-with-ea-IPA
apaznikov Dec 13, 2024
781082f
Refactor to simplify and unify logic
apaznikov Dec 13, 2024
2772c1e
Refactor EscapeAnalysis API to improve readability and maintainability
apaznikov Dec 15, 2024
7962dcd
Add support of calls returning pointers (should lead escape)
apaznikov Dec 16, 2024
ed91d09
Use CaptureTracker first, and then EscapeAnalysis
apaznikov Dec 17, 2024
83ca510
Added EscapeReason statistics to TSan. Refactor escape analysis to tr…
apaznikov Dec 18, 2024
01b846c
Add support IPA return info
apaznikov Dec 19, 2024
3f11e06
Try traverse -- DEBUG
apaznikov Dec 19, 2024
87eef69
Argument escape tracking - DEBUG.
apaznikov Dec 20, 2024
408ec0d
Add top-down argument escape analysis (DEBUG)
apaznikov Dec 23, 2024
a69e19e
Add support for detecting functions passed to ObjC selectors
apaznikov Dec 26, 2024
3c7af95
Remove debug logs and enhance escape analysis logic, add test for top…
apaznikov Dec 26, 2024
1d44daa
Fix incorrect assertion in escape analysis.
apaznikov Dec 29, 2024
675f201
Efforts for new pointer escape logic: add UnderlObjInfo, updates in a…
apaznikov Jan 3, 2025
d2329e4
Refactor logic for treating escaping pointers: now pointers (if they …
apaznikov Jan 10, 2025
8eaf60e
Make isEscapedForBBInFuncTSan more optimistic
apaznikov Jan 10, 2025
e6ff26f
Use IPA version `isEscapedForBBIPA` in isEscapedForBBInFuncTSan
apaznikov Jan 10, 2025
b3a7a9a
Fixed IPA escape analysis logic
apaznikov Jan 13, 2025
d9a48f9
Added support of SCCs for TopDownIPA, fixed evalTopDownArgEscStatus (…
apaznikov Jan 14, 2025
006c2d3
Large update for memcpy/memset/memmove
apaznikov Jan 17, 2025
2690475
Enable interceptor toggling via `InterceptorEnabled` global variable …
apaznikov Jan 27, 2025
c946299
Introduce global InterceptorEnabled for interceptor control
apaznikov Feb 4, 2025
f7cfec5
Add intercepted call handling (strlen, strcmp, memchr)
apaznikov Feb 5, 2025
22a26b0
Fixed bug and cleanup debug output
apaznikov Feb 5, 2025
d76f5b0
Enable/disable in sanitizer_common_interceptors.inc
apaznikov Feb 6, 2025
ef66b29
Add __tsan_enable/__tsan_disalbe intrinsics
apaznikov Feb 24, 2025
16216da
Minor fixes
apaznikov Mar 24, 2025
10d6ed8
hunk cherry-pick from 8a2198773e: fix InterceptorEnabled visibility.
MorthimerMcMare Apr 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added recursive call conservative algorithm
  • Loading branch information
apaznikov committed Nov 29, 2024
commit bc3186ea07d5dc09ce870880efbe73bf55e52b90
8 changes: 8 additions & 0 deletions llvm/include/llvm/Analysis/EscapeAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ class EscapeAnalysisInfo {
/// Interface to access safety global (interprocedural) analysis results.
class EscapeAnalysisGlobalInfo {
DenseMap<const Function *, EscapeAnalysisInfo> FuncEscapeInfo;

static void setAllPtrArgsEscaped(ArgumentEscapesMap &ArgsEscapes,
const Function *F);

/// Check if call graph node is the recursive call
/// (relevant for SCC with 1 node)
static bool isRecursiveCallGraphNode(const Function *F, CallGraphNode *CGN);

public:
explicit EscapeAnalysisGlobalInfo(CallGraph &CG);
void print(Module &M, raw_ostream &O) const;
Expand Down
111 changes: 78 additions & 33 deletions llvm/lib/Analysis/EscapeAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,11 @@ EscapeAnalysisInfo::getEscapeKindForOpnd(const Use &U) const {
// provided by IPA callgraph traversal
const auto FuncIt = ArgsEscapes->find(Callee);
assert(FuncIt != ArgsEscapes->end() &&
"ArgsEscapes must contain information about called function\n");
"ArgsEscapes must contain information about called function");

const auto ArgEscIt = FuncIt->second.find(Call->getDataOperandNo(&U));
assert(ArgEscIt != FuncIt->second.end() &&
"ArgEscapes must contain information about all arguments\n");
"ArgEscapes must contain information about all arguments");
if (ArgEscIt->second)
return {EscapeKind::MAY_ESCAPE, std::nullopt};
} else {
Expand Down Expand Up @@ -672,35 +672,20 @@ void EscapeAnalysisInfo::printEscapingForBB(const BasicBlock *BB,
if ((It == BBEscapeStates.end()) || (It->second.getEscapedObjs().empty()))
return;

bool NonExternalEscaped = false;
OS << "Escaping objects for BB " << BB->getName() << ":\n";
for (const auto *V : It->second.getEscapedObjs()) {
if (isExternalEscapedObject(V))
// I'm not sure, we should not print objects escaping by definition
// (such as global variables or pointer arguments),
// but let's omit them for now
continue;

if (!NonExternalEscaped) {
NonExternalEscaped = true;
OS << "Escaping objects for BB " << BB->getName() << ":\n";
}
OS << *V << "\n";
}
OS << "\n";
}

void EscapeAnalysisInfo::print(raw_ostream &OS) const {
////
// This is function-wise output
//
// const auto FuncEscapingAllocas = BBEscapeStates[&F.back()].EscapedObjects;
// if (FuncEscapingAllocas.empty())
// return;
// OS << "Escaping variables:\n";
// for (const auto *V : FuncEscapingAllocas)
// OS << *V << "\n";
// OS << "\n";

for (const auto &BB: AnalyzedFunc)
printEscapingForBB(&BB, OS);
}
Expand All @@ -725,31 +710,91 @@ EscapeAnalysisPrinterPass::run(Function &F, FunctionAnalysisManager &AM) const {
// Escape analysis global (IPA)
//===----------------------------------------------------------------------===//

void EscapeAnalysisGlobalInfo::setAllPtrArgsEscaped(
ArgumentEscapesMap &ArgsEscapes, const Function *F) {
for (const auto &Arg : F->args())
if (Arg.getType()->isPointerTy())
ArgsEscapes[F][Arg.getArgNo()] = true;
}

bool EscapeAnalysisGlobalInfo::isRecursiveCallGraphNode(const Function *F,
CallGraphNode *CGN) {
for (auto CI = CGN->begin(), CE = CGN->end(); CI != CE; ++CI) {
CallGraphNode *Callee = CI->second;
if (Callee && Callee->getFunction() == F)
return true;
}
return false;
}

EscapeAnalysisGlobalInfo::EscapeAnalysisGlobalInfo(CallGraph &CG) {
// Map to store escape information for function arguments.
ArgumentEscapesMap ArgsEscapes;

// We do a bottom-up SCC traversal of the call graph. In other words, we
// visit all callees before callers (leaf-first).
for (scc_iterator<CallGraph *> I = scc_begin(&CG); !I.isAtEnd(); ++I) {
const std::vector<CallGraphNode *> &SCC = *I;

// This is needed to (conservatively) consider recursive calls and SCCs.
// First, find all SCCs and set all pointer argument as escaped
for (scc_iterator<CallGraph *> It = scc_begin(&CG); !It.isAtEnd(); ++It) {
const std::vector<CallGraphNode *> &SCC = *It;
assert(!SCC.empty() && "SCC with no functions?");

const Function *F = SCC[0]->getFunction();
LLVM_DEBUG(dbgs() << "SCC: " << SCC.size() << "\n";
for (const CallGraphNode *CGN: SCC) {
if (CGN->getFunction())
dbgs() << "\t" << CGN->getFunction()->getName() << "\n";
});

if (!EscapeAnalysisInfo::isLocalFunc(F))
// Calls externally or not exact - can't say anything useful.
// Just skip, because all all externals calls will be treated as escaped
// during local escape analysis
continue;
if (SCC.size() == 1) {
// Check if it's recursive call or not
const auto *F = SCC[0]->getFunction();
if (!EscapeAnalysisInfo::isLocalFunc(F))
continue;

const auto [Iter, Inserted] = FuncEscapeInfo.try_emplace(F, *F, ArgsEscapes);
assert(Inserted && "One function - one insert\n");
for (const auto &Arg : F->args()) {
LLVM_DEBUG(dbgs() << "\t@@@@@@@@@ ESC ARG " << Arg << " -- "
<< Iter->second.isEscapedForFunc(&Arg) << "\n";);
unsigned ArgNo = Arg.getArgNo();
ArgsEscapes[F][ArgNo] = Iter->second.isEscapedForFunc(&Arg);
if (isRecursiveCallGraphNode(F, SCC[0])) {
LLVM_DEBUG(dbgs() << "\t" << F->getName().str() << " is recursive.\n");
setAllPtrArgsEscaped(ArgsEscapes, F);
} else {
LLVM_DEBUG(dbgs() << "\t" << F->getName().str() << " is not recursive.\n");
}
} else { // SCC.size() > 1
for (const CallGraphNode *CGN: SCC) {
const auto F = CGN->getFunction();
if (!EscapeAnalysisInfo::isLocalFunc(F))
continue;
setAllPtrArgsEscaped(ArgsEscapes, F);
}
}
}

// Main callgraph traversal
for (scc_iterator<CallGraph *> It = scc_begin(&CG); !It.isAtEnd(); ++It) {
const std::vector<CallGraphNode *> &SCC = *It;
assert(!SCC.empty() && "SCC with no functions?");

for (const CallGraphNode *CGN : SCC) {
const auto *F = CGN->getFunction();
if (!EscapeAnalysisInfo::isLocalFunc(F))
// Just skip, because all externals calls will be treated as escaped
// during local escape analysis
continue;

const auto [Iter, Inserted] =
FuncEscapeInfo.try_emplace(F, *F, ArgsEscapes);
assert(Inserted && "One function - one insert\n");

// If we didn't consider argument esc 6D4E ape status during previous stage
// add arguments escape info
if (!ArgsEscapes.count(F)) {
LLVM_DEBUG(dbgs() << "update arg info\n");
for (const auto &Arg : F->args()) {
LLVM_DEBUG(dbgs() << "\t@@@@@@@@@ ESC ARG " << Arg << " -- "
<< Iter->second.isEscapedForFunc(&Arg) << "\n";);
unsigned ArgNo = Arg.getArgNo();
ArgsEscapes[F][ArgNo] = Iter->second.isEscapedForFunc(&Arg);
}
}
}
}
}
Expand Down
47 changes: 44 additions & 3 deletions llvm/test/Analysis/EscapeAnalysis/ipa-simple.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
; RUN: opt < %s -passes='print<escape-analysis-global>' -disable-output 2>&1 | FileCheck %s

; C code:
; void level2_func1(int *x) {
; GPtr = x; // Escape through GPtr
; }
;
; void level2_func2(int *x) {
; *x = 333;
; }
;
; void level1_func1(int *x) {
; level2_func1(x);
; }
;
; void level1_func2(int *x) {
; *x = 333;
; int *p = x;
; printf("%p\n", &p); // Escape through external func call
; }
;
; void level1_func3(int *x, int *p) {
; *x = 42;
; level2_func2(x);
; level2_func1(p);
; }
;
; void external_func(int *x);
;
; void parent_func1() {
; int x;
; level1_func1(&x);
; level1_func2(&x);
; int y;
; external_func(&y);
; int z, p;
; level1_func3(&z, &p);
; }

; ModuleID = 'ipa-simple.ll'

; CHECK: Printing analysis 'Escape Analysis' for module '<stdin>':
Expand All @@ -25,7 +62,9 @@ entry:

define dso_local void @level1_func1(ptr noundef %x) #0 {
; CHECK: Printing analysis 'Escape Analysis' for function 'level1_func1':
; CHECK-NOT: Escaping objects for BB entry:
; CHECK-NEXT: Escaping objects for BB entry:
; CHECK-DAG: ptr %x
; CHECK-DAG: %p = alloca ptr, align 8
entry:
call void @level2_func1(ptr noundef %x)
ret void
Expand All @@ -34,7 +73,8 @@ entry:
define dso_local void @level1_func2(ptr noundef %x) {
; CHECK: Printing analysis 'Escape Analysis' for function 'level1_func2':
; CHECK-NEXT: Escaping objects for BB entry:
; CHECK-DAG: %p = alloca ptr, align 8
; CHECK-DAG: %p = alloca ptr, align 8
; CHECK-DAG: ptr %x
entry:
%p = alloca ptr, align 8
store i32 333, ptr %x, align 4
Expand All @@ -47,7 +87,8 @@ declare i32 @printf(ptr noundef, ...)

define dso_local void @level1_func3(ptr noundef %x, ptr noundef %p) {
; CHECK: Printing analysis 'Escape Analysis' for function 'level1_func3':
; CHECK-NOT: Escaping objects for BB entry:
; CHECK-NEXT: Escaping objects for BB entry:
; CHECK-DAG: ptr %x
entry:
store i32 42, ptr %x, align 4
call void @level2_func2(ptr noundef %x)
Expand Down
0