diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h index 02abdf0a1ef0d..9ad61dbc03572 100644 --- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h +++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h @@ -29,10 +29,11 @@ class BottomUpVec final : public FunctionPass { void tryVectorize(ArrayRef Seeds); // The PM containing the pipeline of region passes. - RegionPassManager RPM; + // TODO: Remove maybe_unused once we build regions to run passes on. + [[maybe_unused]] RegionPassManager *RPM; public: - BottomUpVec(); + BottomUpVec(RegionPassManager *RPM); bool runOnFunction(Function &F) final; }; diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCountPass.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCountPass.h new file mode 100644 index 0000000000000..c4e97caf11aeb --- /dev/null +++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCountPass.h @@ -0,0 +1,23 @@ +#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PRINTINSTRUCTIONCOUNTPASS_H +#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PRINTINSTRUCTIONCOUNTPASS_H + +#include "llvm/SandboxIR/Pass.h" +#include "llvm/SandboxIR/Region.h" + +namespace llvm::sandboxir { + +/// A Region pass that prints the instruction count for the region to stdout. +/// Used to test -sbvec-passes while we don't have any actual optimization +/// passes. +class PrintInstructionCountPass final : public RegionPass { +public: + PrintInstructionCountPass() : RegionPass("null") {} + bool runOnRegion(Region &R) final { + outs() << "InstructionCount: " << std::distance(R.begin(), R.end()) << "\n"; + return false; + } +}; + +} // namespace llvm::sandboxir + +#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PRINTINSTRUCTIONCOUNTPASS_H diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h index b7cb418c00326..ad11046db43b2 100644 --- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h +++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h @@ -20,6 +20,11 @@ class TargetTransformInfo; class SandboxVectorizerPass : public PassInfoMixin { TargetTransformInfo *TTI = nullptr; + // A pipeline of region passes. Typically, this will be run by BottomUpVec on + // each region it creates, but it can also be run on regions created from + // IR metadata in tests. + sandboxir::RegionPassManager RPM; + // The main vectorizer pass. sandboxir::BottomUpVec BottomUpVecPass; diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp index 77198f932a3ec..ba1dc8e8cbbf6 100644 --- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp +++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp @@ -10,40 +10,13 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/SandboxIR/Function.h" #include "llvm/SandboxIR/Instruction.h" +#include "llvm/SandboxIR/Region.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h" namespace llvm::sandboxir { -static cl::opt - PrintPassPipeline("sbvec-print-pass-pipeline", cl::init(false), cl::Hidden, - cl::desc("Prints the pass pipeline and returns.")); - -/// A magic string for the default pass pipeline. -static const char *DefaultPipelineMagicStr = "*"; - -static cl::opt 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 std::unique_ptr createRegionPass(StringRef Name) { -#define REGION_PASS(NAME, CREATE_PASS) \ - if (Name == NAME) \ - return std::make_unique(CREATE_PASS); -#include "PassRegistry.def" - return nullptr; -} - -BottomUpVec::BottomUpVec() : FunctionPass("bottom-up-vec"), RPM("rpm") { - // Create a pipeline to be run on each Region created by BottomUpVec. - if (UserDefinedPassPipeline == DefaultPipelineMagicStr) { - // TODO: Add default passes to RPM. - } else { - // Create the user-defined pipeline. - RPM.setPassPipeline(UserDefinedPassPipeline, createRegionPass); - } -} +BottomUpVec::BottomUpVec(RegionPassManager *RPM) + : FunctionPass("bottom-up-vec"), RPM(RPM) {} // TODO: This is a temporary function that returns some seeds. // Replace this with SeedCollector's function when it lands. @@ -82,11 +55,6 @@ void BottomUpVec::vectorizeRec(ArrayRef Bndl) { void BottomUpVec::tryVectorize(ArrayRef Bndl) { vectorizeRec(Bndl); } bool BottomUpVec::runOnFunction(Function &F) { - if (PrintPassPipeline) { - RPM.printPipeline(outs()); - return false; - } - Change = false; // TODO: Start from innermost BBs first for (auto &BB : F) { diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def index bbb0dcba1ea51..c0ad1710d06b9 100644 --- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def +++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def @@ -18,5 +18,6 @@ #endif REGION_PASS("null", NullPass()) +REGION_PASS("print-instruction-count", PrintInstructionCountPass()) #undef REGION_PASS diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp index ba4899cc624e9..60867207155f5 100644 --- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp @@ -10,13 +10,55 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/SandboxIR/Constant.h" #include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h" +#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h" +#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCountPass.h" -using namespace llvm; +using namespace llvm::sandboxir; + +namespace llvm { #define SV_NAME "sandbox-vectorizer" #define DEBUG_TYPE SV_NAME -SandboxVectorizerPass::SandboxVectorizerPass() = default; +static cl::opt + PrintPassPipeline("sbvec-print-pass-pipeline", cl::init(false), cl::Hidden, + cl::desc("Prints the pass pipeline and returns.")); + +/// A magic string for the default pass pipeline. +static const char *DefaultPipelineMagicStr = "*"; + +static cl::opt 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 cl::opt UseRegionsFromMetadata( + "sbvec-use-regions-from-metadata", cl::init(false), cl::Hidden, + cl::desc("Skips bottom-up vectorization, builds regions from metadata " + "already present in the IR and runs the region pass pipeline.")); + +static std::unique_ptr createRegionPass(StringRef Name) { +#define REGION_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) \ + return std::make_unique(CREATE_PASS); +#include "Passes/PassRegistry.def" + return nullptr; +} + +sandboxir::RegionPassManager createRegionPassManager() { + sandboxir::RegionPassManager RPM("rpm"); + // Create a pipeline to be run on each Region created by BottomUpVec. + if (UserDefinedPassPipeline == DefaultPipelineMagicStr) { + // TODO: Add default passes to RPM. + } else { + // Create the user-defined pipeline. + RPM.setPassPipeline(UserDefinedPassPipeline, createRegionPass); + } + return RPM; +} + +SandboxVectorizerPass::SandboxVectorizerPass() + : RPM(createRegionPassManager()), BottomUpVecPass(&RPM) {} SandboxVectorizerPass::SandboxVectorizerPass(SandboxVectorizerPass &&) = default; @@ -37,6 +79,11 @@ PreservedAnalyses SandboxVectorizerPass::run(Function &F, } bool SandboxVectorizerPass::runImpl(Function &LLVMF) { + if (PrintPassPipeline) { + RPM.printPipeline(outs()); + return false; + } + // If the target claims to have no vector registers early return. if (!TTI->getNumberOfRegisters(TTI->getRegisterClassForType(true))) { LLVM_DEBUG(dbgs() << "SBVec: Target has no vector registers, return.\n"); @@ -52,5 +99,16 @@ bool SandboxVectorizerPass::runImpl(Function &LLVMF) { // Create SandboxIR for LLVMF and run BottomUpVec on it. sandboxir::Context Ctx(LLVMF.getContext()); sandboxir::Function &F = *Ctx.createFunction(&LLVMF); - return BottomUpVecPass.runOnFunction(F); + if (UseRegionsFromMetadata) { + SmallVector> Regions = + sandboxir::Region::createRegionsFromMD(F); + for (auto &R : Regions) { + RPM.runOnRegion(*R); + } + return false; + } else { + return BottomUpVecPass.runOnFunction(F); + } } + +} // namespace llvm diff --git a/llvm/test/Transforms/SandboxVectorizer/regions-from-metadata.ll b/llvm/test/Transforms/SandboxVectorizer/regions-from-metadata.ll new file mode 100644 index 0000000000000..3874876996f8c --- /dev/null +++ b/llvm/test/Transforms/SandboxVectorizer/regions-from-metadata.ll @@ -0,0 +1,16 @@ +; RUN: opt -disable-output --passes=sandbox-vectorizer \ +; RUN: -sbvec-passes=print-instruction-count \ +; RUN: -sbvec-use-regions-from-metadata %s | FileCheck %s + +define i8 @foo(i8 %v0, i8 %v1) { + %t0 = add i8 %v0, 1, !sandboxvec !0 + %t1 = add i8 %t0, %v1, !sandboxvec !1 + %t2 = add i8 %t1, %v1, !sandboxvec !1 + ret i8 %t2 +} + +!0 = distinct !{!"sandboxregion"} +!1 = distinct !{!"sandboxregion"} + +; CHECK: InstructionCount: 1 +; CHECK: InstructionCount: 2