1
- // ===--- AccessedStorageDumper.cpp - Dump accessed storage for functions ---===//
1
+ // ===--- AccessedStorageDumper.cpp - Dump accessed storage ------------- ---===//
2
2
//
3
3
// This source file is part of the Swift.org open source project
4
4
//
5
- // Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
5
+ // Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6
6
// Licensed under Apache License v2.0 with Runtime Library Exception
7
7
//
8
8
// See https://swift.org/LICENSE.txt for license information
17
17
#include " swift/SIL/SILValue.h"
18
18
#include " swift/SILOptimizer/PassManager/Passes.h"
19
19
#include " swift/SILOptimizer/PassManager/Transforms.h"
20
+ #include " llvm/Support/CommandLine.h"
20
21
#include " llvm/Support/Debug.h"
21
22
22
23
using namespace swift ;
23
24
24
- static void dumpAccessedStorage (SILInstruction *inst) {
25
- visitAccessedAddress (
26
- inst,
27
- [&](Operand *operand) {
28
- inst->print (llvm::outs ());
29
- findAccessedStorage (operand->get ()).print (llvm::outs ());
30
- }
31
- );
32
- }
25
+ static llvm::cl::opt<bool > EnableDumpUses (
26
+ " enable-accessed-storage-dump-uses" , llvm::cl::init(false ),
27
+ llvm::cl::desc(" With --sil-access-storage-dumper, dump all uses" ));
33
28
34
29
namespace {
35
30
36
31
// / Dumps sorage information for each access.
37
32
class AccessedStorageDumper : public SILModuleTransform {
33
+ llvm::SmallVector<Operand *, 32 > uses;
34
+
35
+ void dumpAccessedStorage (Operand *operand) {
36
+ findAccessedStorage (operand->get ()).print (llvm::outs ());
37
+ auto pathAndBase = AccessPathWithBase::compute (operand->get ());
38
+ pathAndBase.print (llvm::outs ());
39
+
40
+ if (!pathAndBase.accessPath .isValid () || !EnableDumpUses)
41
+ return ;
42
+
43
+ uses.clear ();
44
+ pathAndBase.collectUses (uses, /* collectContainingUses*/ false );
45
+ llvm::outs () << " Exact Uses {\n " ;
46
+ for (auto *useOperand : uses) {
47
+ llvm::outs () << *useOperand->getUser () << " " ;
48
+ auto usePathAndBase = AccessPathWithBase::compute (useOperand->get ());
49
+ usePathAndBase.accessPath .printPath (llvm::outs ());
50
+ assert (pathAndBase.accessPath .contains (usePathAndBase.accessPath )
51
+ && " access path does not contain use access path" );
52
+ }
53
+ llvm::outs () << " }\n " ;
54
+ uses.clear ();
55
+ pathAndBase.collectUses (uses, /* collectContainingUses*/ true );
56
+ llvm::outs () << " Overlapping Uses {\n " ;
57
+ for (auto *useOperand : uses) {
58
+ llvm::outs () << *useOperand->getUser () << " " ;
59
+ auto usePathAndBase = AccessPathWithBase::compute (useOperand->get ());
60
+ usePathAndBase.accessPath .printPath (llvm::outs ());
61
+ assert (pathAndBase.accessPath .mayOverlap (usePathAndBase.accessPath )
62
+ && " access path does not contain use access path" );
63
+ }
64
+ llvm::outs () << " }\n " ;
65
+ }
38
66
39
67
void run () override {
40
68
for (auto &fn : *getModule ()) {
@@ -45,8 +73,12 @@ class AccessedStorageDumper : public SILModuleTransform {
45
73
}
46
74
for (auto &bb : fn) {
47
75
for (auto &inst : bb) {
48
- if (inst.mayReadOrWriteMemory ())
49
- dumpAccessedStorage (&inst);
76
+ if (inst.mayReadOrWriteMemory ()) {
77
+ llvm::outs () << " ###For MemOp: " << inst;
78
+ visitAccessedAddress (&inst, [this ](Operand *operand) {
79
+ dumpAccessedStorage (operand);
80
+ });
81
+ }
50
82
}
51
83
}
52
84
}
0 commit comments