xref: /llvm-project/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp (revision 79cbad188afd5268235b00267d37ce39544dbd3c)
152dca6ffSvporpo //===- SandboxVectorizer.cpp - Vectorizer based on Sandbox IR -------------===//
252dca6ffSvporpo //
352dca6ffSvporpo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
452dca6ffSvporpo // See https://llvm.org/LICENSE.txt for license information.
552dca6ffSvporpo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
652dca6ffSvporpo //
752dca6ffSvporpo //===----------------------------------------------------------------------===//
852dca6ffSvporpo 
952dca6ffSvporpo #include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h"
107ea9f0d8SVasileios Porpodas #include "llvm/Analysis/TargetTransformInfo.h"
112018f4ccSVasileios Porpodas #include "llvm/SandboxIR/Constant.h"
122e8ad49eSJorge Gorbe Moya #include "llvm/Support/CommandLine.h"
132e8ad49eSJorge Gorbe Moya #include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h"
1452dca6ffSvporpo 
1552dca6ffSvporpo using namespace llvm;
1652dca6ffSvporpo 
1752dca6ffSvporpo #define SV_NAME "sandbox-vectorizer"
1852dca6ffSvporpo #define DEBUG_TYPE SV_NAME
1952dca6ffSvporpo 
202e8ad49eSJorge Gorbe Moya static cl::opt<bool>
212e8ad49eSJorge Gorbe Moya     PrintPassPipeline("sbvec-print-pass-pipeline", cl::init(false), cl::Hidden,
222e8ad49eSJorge Gorbe Moya                       cl::desc("Prints the pass pipeline and returns."));
232e8ad49eSJorge Gorbe Moya 
242e8ad49eSJorge Gorbe Moya /// A magic string for the default pass pipeline.
252e8ad49eSJorge Gorbe Moya static const char *DefaultPipelineMagicStr = "*";
262e8ad49eSJorge Gorbe Moya 
272e8ad49eSJorge Gorbe Moya static cl::opt<std::string> UserDefinedPassPipeline(
282e8ad49eSJorge Gorbe Moya     "sbvec-passes", cl::init(DefaultPipelineMagicStr), cl::Hidden,
292e8ad49eSJorge Gorbe Moya     cl::desc("Comma-separated list of vectorizer passes. If not set "
302e8ad49eSJorge Gorbe Moya              "we run the predefined pipeline."));
312e8ad49eSJorge Gorbe Moya 
322e8ad49eSJorge Gorbe Moya SandboxVectorizerPass::SandboxVectorizerPass() : FPM("fpm") {
332e8ad49eSJorge Gorbe Moya   if (UserDefinedPassPipeline == DefaultPipelineMagicStr) {
342e8ad49eSJorge Gorbe Moya     // TODO: Add region passes to the default pipeline.
352e8ad49eSJorge Gorbe Moya     FPM.setPassPipeline(
362e8ad49eSJorge Gorbe Moya         "bottom-up-vec<>",
372e8ad49eSJorge Gorbe Moya         sandboxir::SandboxVectorizerPassBuilder::createFunctionPass);
382e8ad49eSJorge Gorbe Moya   } else {
392e8ad49eSJorge Gorbe Moya     // Create the user-defined pipeline.
402e8ad49eSJorge Gorbe Moya     FPM.setPassPipeline(
412e8ad49eSJorge Gorbe Moya         UserDefinedPassPipeline,
422e8ad49eSJorge Gorbe Moya         sandboxir::SandboxVectorizerPassBuilder::createFunctionPass);
432e8ad49eSJorge Gorbe Moya   }
442e8ad49eSJorge Gorbe Moya }
45102c384bSJorge Gorbe Moya 
46756ec99cSJorge Gorbe Moya SandboxVectorizerPass::SandboxVectorizerPass(SandboxVectorizerPass &&) =
47756ec99cSJorge Gorbe Moya     default;
48102c384bSJorge Gorbe Moya 
49756ec99cSJorge Gorbe Moya SandboxVectorizerPass::~SandboxVectorizerPass() = default;
50102c384bSJorge Gorbe Moya 
5152dca6ffSvporpo PreservedAnalyses SandboxVectorizerPass::run(Function &F,
5252dca6ffSvporpo                                              FunctionAnalysisManager &AM) {
5352dca6ffSvporpo   TTI = &AM.getResult<TargetIRAnalysis>(F);
54ce0d0858Svporpo   AA = &AM.getResult<AAManager>(F);
55a461869dSvporpo   SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
5652dca6ffSvporpo 
5752dca6ffSvporpo   bool Changed = runImpl(F);
5852dca6ffSvporpo   if (!Changed)
5952dca6ffSvporpo     return PreservedAnalyses::all();
6052dca6ffSvporpo 
6152dca6ffSvporpo   PreservedAnalyses PA;
6252dca6ffSvporpo   PA.preserveSet<CFGAnalyses>();
6352dca6ffSvporpo   return PA;
6452dca6ffSvporpo }
6552dca6ffSvporpo 
66d5bc1f4aSVasileios Porpodas bool SandboxVectorizerPass::runImpl(Function &LLVMF) {
675942a99fSvporpo   if (Ctx == nullptr)
685942a99fSvporpo     Ctx = std::make_unique<sandboxir::Context>(LLVMF.getContext());
695942a99fSvporpo 
702e8ad49eSJorge Gorbe Moya   if (PrintPassPipeline) {
712e8ad49eSJorge Gorbe Moya     FPM.printPipeline(outs());
722e8ad49eSJorge Gorbe Moya     return false;
732e8ad49eSJorge Gorbe Moya   }
742e8ad49eSJorge Gorbe Moya 
75c1c42518Svporpo   // If the target claims to have no vector registers early return.
76c1c42518Svporpo   if (!TTI->getNumberOfRegisters(TTI->getRegisterClassForType(true))) {
77c1c42518Svporpo     LLVM_DEBUG(dbgs() << "SBVec: Target has no vector registers, return.\n");
78c1c42518Svporpo     return false;
79c1c42518Svporpo   }
80d5bc1f4aSVasileios Porpodas   LLVM_DEBUG(dbgs() << "SBVec: Analyzing " << LLVMF.getName() << ".\n");
81c1c42518Svporpo   // Early return if the attribute NoImplicitFloat is used.
82d5bc1f4aSVasileios Porpodas   if (LLVMF.hasFnAttribute(Attribute::NoImplicitFloat)) {
83c1c42518Svporpo     LLVM_DEBUG(dbgs() << "SBVec: NoImplicitFloat attribute, return.\n");
84c1c42518Svporpo     return false;
85c1c42518Svporpo   }
86c1c42518Svporpo 
87756ec99cSJorge Gorbe Moya   // Create SandboxIR for LLVMF and run BottomUpVec on it.
885942a99fSvporpo   sandboxir::Function &F = *Ctx->createFunction(&LLVMF);
896312beefSvporpo   sandboxir::Analyses A(*AA, *SE, *TTI);
90334a1cdbSvporpo   bool Change = FPM.runOnFunction(F, A);
91*79cbad18Svporpo   // Given that sandboxir::Context `Ctx` is defined at a pass-level scope, the
92*79cbad18Svporpo   // maps from LLVM IR to Sandbox IR may go stale as later passes remove LLVM IR
93*79cbad18Svporpo   // objects. To avoid issues caused by this clear the context's state.
94*79cbad18Svporpo   // NOTE: The alternative would be to define Ctx and FPM within runOnFunction()
95*79cbad18Svporpo   Ctx->clear();
96334a1cdbSvporpo   return Change;
9739f2d2f1Svporpo }
98