xref: /llvm-project/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp (revision 102c384b5792eaa4e1b0095f9794637a23196ea3)
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 
9 #include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h"
10 #include "llvm/Analysis/TargetTransformInfo.h"
11 #include "llvm/SandboxIR/Constant.h"
12 #include "llvm/SandboxIR/PassManager.h"
13 #include "llvm/Support/CommandLine.h"
14 #include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h"
15 
16 using namespace llvm;
17 
18 #define SV_NAME "sandbox-vectorizer"
19 #define DEBUG_TYPE SV_NAME
20 
21 cl::opt<bool>
22     PrintPassPipeline("sbvec-print-pass-pipeline", cl::init(false), cl::Hidden,
23                       cl::desc("Prints the pass pipeline and returns."));
24 
25 /// A magic string for the default pass pipeline.
26 const char *DefaultPipelineMagicStr = "*";
27 
28 cl::opt<std::string> UserDefinedPassPipeline(
29     "sbvec-passes", cl::init(DefaultPipelineMagicStr), cl::Hidden,
30     cl::desc("Comma-separated list of vectorizer passes. If not set "
31              "we run the predefined pipeline."));
32 
33 PreservedAnalyses SandboxVectorizerPass::run(Function &F,
34                                              FunctionAnalysisManager &AM) {
35   TTI = &AM.getResult<TargetIRAnalysis>(F);
36 
37   bool Changed = runImpl(F);
38   if (!Changed)
39     return PreservedAnalyses::all();
40 
41   PreservedAnalyses PA;
42   PA.preserveSet<CFGAnalyses>();
43   return PA;
44 }
45 
46 bool SandboxVectorizerPass::runImpl(Function &LLVMF) {
47   // If the target claims to have no vector registers early return.
48   if (!TTI->getNumberOfRegisters(TTI->getRegisterClassForType(true))) {
49     LLVM_DEBUG(dbgs() << "SBVec: Target has no vector registers, return.\n");
50     return false;
51   }
52   LLVM_DEBUG(dbgs() << "SBVec: Analyzing " << LLVMF.getName() << ".\n");
53   // Early return if the attribute NoImplicitFloat is used.
54   if (LLVMF.hasFnAttribute(Attribute::NoImplicitFloat)) {
55     LLVM_DEBUG(dbgs() << "SBVec: NoImplicitFloat attribute, return.\n");
56     return false;
57   }
58 
59   sandboxir::Context Ctx(LLVMF.getContext());
60   // Create SandboxIR for `LLVMF`.
61   sandboxir::Function &F = *Ctx.createFunction(&LLVMF);
62   // Create the passes and register them with the PassRegistry.
63   sandboxir::PassRegistry PR;
64   auto &BottomUpVecPass = static_cast<sandboxir::FunctionPass &>(
65       PR.registerPass(std::make_unique<sandboxir::BottomUpVec>()));
66 
67   sandboxir::FunctionPassManager *PM = nullptr;
68   if (UserDefinedPassPipeline == DefaultPipelineMagicStr) {
69     // Create the default pass pipeline.
70     PM = &static_cast<sandboxir::FunctionPassManager &>(PR.registerPass(
71         std::make_unique<sandboxir::FunctionPassManager>("pm")));
72     PM->addPass(&BottomUpVecPass);
73   } else {
74     // Create the user-defined pipeline.
75     PM = &PR.parseAndCreatePassPipeline(UserDefinedPassPipeline);
76   }
77 
78   if (PrintPassPipeline) {
79     PM->printPipeline(outs());
80     return false;
81   }
82 
83   // Run the pass pipeline.
84   bool Change = PM->runOnFunction(F);
85   return Change;
86 }
87