88
99#include " llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h"
1010#include " llvm/Analysis/TargetTransformInfo.h"
11+ #include " llvm/IR/Module.h"
1112#include " llvm/SandboxIR/Constant.h"
1213#include " llvm/Support/CommandLine.h"
1314#include " llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h"
15+ #include < regex>
1416
1517using namespace llvm ;
1618
@@ -29,6 +31,22 @@ static cl::opt<std::string> UserDefinedPassPipeline(
2931 cl::desc(" Comma-separated list of vectorizer passes. If not set "
3032 " we run the predefined pipeline." ));
3133
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+
3250SandboxVectorizerPass::SandboxVectorizerPass () : FPM(" fpm" ) {
3351 if (UserDefinedPassPipeline == DefaultPipelineMagicStr) {
3452 // TODO: Add passes to the default pipeline. It currently contains:
@@ -66,6 +84,23 @@ PreservedAnalyses SandboxVectorizerPass::run(Function &F,
6684 return PA;
6785}
6886
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+
69104bool SandboxVectorizerPass::runImpl (Function &LLVMF) {
70105 if (Ctx == nullptr )
71106 Ctx = std::make_unique<sandboxir::Context>(LLVMF.getContext ());
@@ -75,6 +110,13 @@ bool SandboxVectorizerPass::runImpl(Function &LLVMF) {
75110 return false ;
76111 }
77112
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+
78120 // If the target claims to have no vector registers early return.
79121 if (!TTI->getNumberOfRegisters (TTI->getRegisterClassForType (true ))) {
80122 LLVM_DEBUG (dbgs () << " SBVec: Target has no vector registers, return.\n " );
0 commit comments