LLVM 23.0.0git
SandboxVectorizer.cpp
Go to the documentation of this file.
1//===- SandboxVectorizer.cpp - Vectorizer based on Sandbox IR -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/IR/Module.h"
14#include "llvm/Support/Regex.h"
17
18using namespace llvm;
19
20static cl::opt<bool>
21 PrintPassPipeline("sbvec-print-pass-pipeline", cl::init(false), cl::Hidden,
22 cl::desc("Prints the pass pipeline and returns."));
23
24/// A magic string for the default pass pipeline.
25static const char *DefaultPipelineMagicStr = "*";
26
29 cl::desc("Comma-separated list of vectorizer passes. If not set "
30 "we run the predefined pipeline."));
31
32// This option is useful for bisection debugging.
33// For example you may use it to figure out which filename is the one causing a
34// miscompile. You can specify a regex for the filename like: "/[a-m][^/]*"
35// which will enable any file name starting with 'a' to 'm' and disable the
36// rest. If the miscompile goes away, then we try "/[n-z][^/]*" for the other
37// half of the range, from 'n' to 'z'. If we can reproduce the miscompile then
38// we can keep looking in [n-r] and [s-z] and so on, in a binary-search fashion.
39//
40// Please note that we are using [^/]* and not .* to make sure that we are
41// matching the actual filename and not some other directory in the path.
43 "sbvec-allow-files", cl::init(".*"), cl::Hidden,
44 cl::desc("Run the vectorizer only on file paths that match any in the "
45 "list of comma-separated regex's."));
46static constexpr char AllowFilesDelim = ',';
47
50 // TODO: Add passes to the default pipeline. It currently contains:
51 // - Seed collection, which creates seed regions and runs the pipeline
52 // - Bottom-up Vectorizer pass that starts from a seed
53 // - Load-Store Vectorizer pass for load-store chains
54 // - Accept or revert IR state pass
55 FPM.setPassPipeline(
56 "seed-collection<tr-save,bottom-up-vec,load-store-vec,tr-accept-or-"
57 "revert>",
59 } else {
60 // Create the user-defined pipeline.
61 FPM.setPassPipeline(
64 }
65}
66
68 default;
69
71
74 TTI = &AM.getResult<TargetIRAnalysis>(F);
75 AA = &AM.getResult<AAManager>(F);
77
78 bool Changed = runImpl(F);
79 if (!Changed)
81
84 return PA;
85}
86
87bool 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 Regex FileNameRegex(".*" + FileNameToMatch + "$");
98 assert(FileNameRegex.isValid() && "Bad regex!");
99 if (FileNameRegex.match(SrcFilePath))
100 return true;
101 } while (DelimPos != std::string::npos);
102 return false;
103}
104
105bool SandboxVectorizerPass::runImpl(Function &LLVMF) {
106 if (Ctx == nullptr)
107 Ctx = std::make_unique<sandboxir::Context>(LLVMF.getContext());
108
109 if (PrintPassPipeline) {
110 FPM.printPipeline(outs());
111 return false;
112 }
113
114 // This is used for debugging.
115 if (LLVM_UNLIKELY(AllowFiles != ".*")) {
116 const auto &SrcFilePath = LLVMF.getParent()->getSourceFileName();
117 if (!allowFile(SrcFilePath))
118 return false;
119 }
120
121 // If the target claims to have no vector registers early return.
122 if (!TTI->getNumberOfRegisters(TTI->getRegisterClassForType(true))) {
124 << "Target has no vector registers, return.\n");
125 return false;
126 }
127 LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Analyzing " << LLVMF.getName()
128 << ".\n");
129 // Early return if the attribute NoImplicitFloat is used.
130 if (LLVMF.hasFnAttribute(Attribute::NoImplicitFloat)) {
132 << "NoImplicitFloat attribute, return.\n");
133 return false;
134 }
135
136 // Create SandboxIR for LLVMF and run BottomUpVec on it.
137 sandboxir::Function &F = *Ctx->createFunction(&LLVMF);
138 sandboxir::Analyses A(*AA, *SE, *TTI);
139 bool Change = FPM.runOnFunction(F, A);
140 // Given that sandboxir::Context `Ctx` is defined at a pass-level scope, the
141 // maps from LLVM IR to Sandbox IR may go stale as later passes remove LLVM IR
142 // objects. To avoid issues caused by this clear the context's state.
143 // NOTE: The alternative would be to define Ctx and FPM within runOnFunction()
144 Ctx->clear();
145 return Change;
146}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:336
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
static cl::opt< std::string > UserDefinedPassPipeline("sbvec-passes", cl::init(DefaultPipelineMagicStr), cl::Hidden, cl::desc("Comma-separated list of vectorizer passes. If not set " "we run the predefined pipeline."))
static constexpr char AllowFilesDelim
static const char * DefaultPipelineMagicStr
A magic string for the default pass pipeline.
cl::opt< std::string > AllowFiles("sbvec-allow-files", cl::init(".*"), cl::Hidden, cl::desc("Run the vectorizer only on file paths that match any in the " "list of comma-separated regex's."))
static cl::opt< bool > PrintPassPipeline("sbvec-print-pass-pipeline", cl::init(false), cl::Hidden, cl::desc("Prints the pass pipeline and returns."))
#define LLVM_DEBUG(...)
Definition Debug.h:114
This pass exposes codegen information to IR-level passes.
#define DEBUG_PREFIX
Definition Debug.h:19
A manager for alias analyses.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:358
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:728
Module * getParent()
Get the module that this global value is contained inside of...
const std::string & getSourceFileName() const
Get the module's original source file name.
Definition Module.h:263
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Analysis pass that exposes the ScalarEvolution for a function.
Analysis pass providing the TargetTransformInfo.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
static std::unique_ptr< FunctionPass > createFunctionPass(StringRef Name, StringRef Args, StringRef AuxArg)
Changed
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.