8
8
9
9
#include " llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h"
10
10
#include " llvm/Analysis/TargetTransformInfo.h"
11
+ #include " llvm/IR/Module.h"
11
12
#include " llvm/SandboxIR/Constant.h"
12
13
#include " llvm/Support/CommandLine.h"
13
14
#include " llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h"
15
+ #include < regex>
14
16
15
17
using namespace llvm ;
16
18
@@ -29,6 +31,22 @@ static cl::opt<std::string> UserDefinedPassPipeline(
29
31
cl::desc(" Comma-separated list of vectorizer passes. If not set "
30
32
" we run the predefined pipeline." ));
31
33
34
+ // This option is useful for bisection debugging.
35
+ // For example you may use it to figure out which filename is the one causing a
36
+ // miscompile. You can specify a regex for the filename like: "/[a-m][^/]*"
37
+ // which will enable any file name starting with 'a' to 'm' and disable the
38
+ // rest. If the miscompile goes away, then we try "/[n-z][^/]*" for the other
39
+ // half of the range, from 'n' to 'z'. If we can reproduce the miscompile then
40
+ // we can keep looking in [n-r] and [s-z] and so on, in a binary-search fashion.
41
+ //
42
+ // Please note that we are using [^/]* and not .* to make sure that we are
43
+ // matching the actual filename and not some other directory in the path.
44
+ cl::opt<std::string> AllowFiles (
45
+ " sbvec-allow-files" , cl::init(" .*" ), cl::Hidden,
46
+ cl::desc(" Run the vectorizer only on file paths that match any in the "
47
+ " list of comma-separated regex's." ));
48
+ static constexpr const char AllowFilesDelim = ' ,' ;
49
+
32
50
SandboxVectorizerPass::SandboxVectorizerPass () : FPM(" fpm" ) {
33
51
if (UserDefinedPassPipeline == DefaultPipelineMagicStr) {
34
52
// TODO: Add passes to the default pipeline. It currently contains:
@@ -66,6 +84,23 @@ PreservedAnalyses SandboxVectorizerPass::run(Function &F,
66
84
return PA;
67
85
}
68
86
87
+ bool SandboxVectorizerPass::allowFile (const std::string &SrcFilePath) {
88
+ // Iterate over all files in AllowFiles separated by `AllowFilesDelim`.
89
+ size_t DelimPos = 0 ;
90
+ do {
91
+ size_t LastPos = DelimPos != 0 ? DelimPos + 1 : DelimPos;
92
+ DelimPos = AllowFiles.find (AllowFilesDelim, LastPos);
93
+ auto FileNameToMatch = AllowFiles.substr (LastPos, DelimPos - LastPos);
94
+ if (FileNameToMatch.empty ())
95
+ return false ;
96
+ // Note: This only runs when debugging so its OK not to reuse the regex.
97
+ std::regex FileNameRegex (std::string (" .*" ) + FileNameToMatch);
98
+ if (std::regex_match (SrcFilePath, FileNameRegex))
99
+ return true ;
100
+ } while (DelimPos != std::string::npos);
101
+ return false ;
102
+ }
103
+
69
104
bool SandboxVectorizerPass::runImpl (Function &LLVMF) {
70
105
if (Ctx == nullptr )
71
106
Ctx = std::make_unique<sandboxir::Context>(LLVMF.getContext ());
@@ -75,6 +110,13 @@ bool SandboxVectorizerPass::runImpl(Function &LLVMF) {
75
110
return false ;
76
111
}
77
112
113
+ // This is used for debugging.
114
+ if (LLVM_UNLIKELY (AllowFiles != " .*" )) {
115
+ const auto &SrcFilePath = LLVMF.getParent ()->getSourceFileName ();
116
+ if (!allowFile (SrcFilePath))
117
+ return false ;
118
+ }
119
+
78
120
// If the target claims to have no vector registers early return.
79
121
if (!TTI->getNumberOfRegisters (TTI->getRegisterClassForType (true ))) {
80
122
LLVM_DEBUG (dbgs () << " SBVec: Target has no vector registers, return.\n " );
0 commit comments