1 //===- mlir-opt.cpp - MLIR Optimizer Driver -------------------------------===//
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 // Main entry function for mlir-opt for when built as standalone binary.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "mlir/IR/AsmState.h"
14 #include "mlir/IR/Dialect.h"
15 #include "mlir/IR/MLIRContext.h"
16 #include "mlir/InitAllDialects.h"
17 #include "mlir/InitAllPasses.h"
18 #include "mlir/Pass/Pass.h"
19 #include "mlir/Pass/PassManager.h"
20 #include "mlir/Support/FileUtilities.h"
21 #include "mlir/Support/MlirOptMain.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/InitLLVM.h"
24 #include "llvm/Support/SourceMgr.h"
25 #include "llvm/Support/ToolOutputFile.h"
26 
27 using namespace llvm;
28 using namespace mlir;
29 
30 namespace mlir {
31 // Defined in the test directory, no public header.
32 void registerConvertToTargetEnvPass();
33 void registerInliner();
34 void registerMemRefBoundCheck();
35 void registerPassManagerTestPass();
36 void registerPatternsTestPass();
37 void registerPrintOpAvailabilityPass();
38 void registerSideEffectTestPasses();
39 void registerSimpleParametricTilingPass();
40 void registerSymbolTestPasses();
41 void registerTestAffineDataCopyPass();
42 void registerTestAllReduceLoweringPass();
43 void registerTestAffineLoopUnswitchingPass();
44 void registerTestLinalgMatmulToVectorPass();
45 void registerTestLoopPermutationPass();
46 void registerTestCallGraphPass();
47 void registerTestConstantFold();
48 void registerTestConvertGPUKernelToCubinPass();
49 void registerTestDominancePass();
50 void registerTestFunc();
51 void registerTestGpuMemoryPromotionPass();
52 void registerTestLinalgTransforms();
53 void registerTestLivenessPass();
54 void registerTestLoopFusion();
55 void registerTestLoopMappingPass();
56 void registerTestMatchers();
57 void registerTestMemRefDependenceCheck();
58 void registerTestMemRefStrideCalculation();
59 void registerTestOpaqueLoc();
60 void registerTestParallelismDetection();
61 void registerTestGpuParallelLoopMappingPass();
62 void registerTestVectorConversions();
63 void registerTestVectorToLoopsPass();
64 void registerVectorizerTestPass();
65 } // namespace mlir
66 
67 static cl::opt<std::string>
68     inputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
69 
70 static cl::opt<std::string> outputFilename("o", cl::desc("Output filename"),
71                                            cl::value_desc("filename"),
72                                            cl::init("-"));
73 
74 static cl::opt<bool>
75     splitInputFile("split-input-file",
76                    cl::desc("Split the input file into pieces and process each "
77                             "chunk independently"),
78                    cl::init(false));
79 
80 static cl::opt<bool>
81     verifyDiagnostics("verify-diagnostics",
82                       cl::desc("Check that emitted diagnostics match "
83                                "expected-* lines on the corresponding line"),
84                       cl::init(false));
85 
86 static cl::opt<bool>
87     verifyPasses("verify-each",
88                  cl::desc("Run the verifier after each transformation pass"),
89                  cl::init(true));
90 
91 static cl::opt<bool> allowUnregisteredDialects(
92     "allow-unregistered-dialect",
93     cl::desc("Allow operation with no registered dialects"), cl::init(false));
94 
95 void registerTestPasses() {
96   registerConvertToTargetEnvPass();
97   registerInliner();
98   registerMemRefBoundCheck();
99   registerPassManagerTestPass();
100   registerPatternsTestPass();
101   registerPrintOpAvailabilityPass();
102   registerSideEffectTestPasses();
103   registerSimpleParametricTilingPass();
104   registerSymbolTestPasses();
105   registerTestAffineDataCopyPass();
106   registerTestAllReduceLoweringPass();
107   registerTestAffineLoopUnswitchingPass();
108   registerTestLinalgMatmulToVectorPass();
109   registerTestLoopPermutationPass();
110   registerTestCallGraphPass();
111   registerTestConstantFold();
112 #if MLIR_CUDA_CONVERSIONS_ENABLED
113   registerTestConvertGPUKernelToCubinPass();
114 #endif
115   registerTestDominancePass();
116   registerTestFunc();
117   registerTestGpuMemoryPromotionPass();
118   registerTestLinalgTransforms();
119   registerTestLivenessPass();
120   registerTestLoopFusion();
121   registerTestLoopMappingPass();
122   registerTestMatchers();
123   registerTestMemRefDependenceCheck();
124   registerTestMemRefStrideCalculation();
125   registerTestOpaqueLoc();
126   registerTestParallelismDetection();
127   registerTestGpuParallelLoopMappingPass();
128   registerTestVectorConversions();
129   registerTestVectorToLoopsPass();
130   registerVectorizerTestPass();
131 }
132 
133 static cl::opt<bool>
134     showDialects("show-dialects",
135                  cl::desc("Print the list of registered dialects"),
136                  cl::init(false));
137 
138 int main(int argc, char **argv) {
139   registerAllDialects();
140   registerAllPasses();
141   registerTestPasses();
142   InitLLVM y(argc, argv);
143 
144   // Register any command line options.
145   registerAsmPrinterCLOptions();
146   registerMLIRContextCLOptions();
147   registerPassManagerCLOptions();
148   PassPipelineCLParser passPipeline("", "Compiler passes to run");
149 
150   // Parse pass names in main to ensure static initialization completed.
151   cl::ParseCommandLineOptions(argc, argv, "MLIR modular optimizer driver\n");
152 
153   MLIRContext context;
154   if(showDialects) {
155     llvm::outs() << "Registered Dialects:\n";
156     for(Dialect *dialect : context.getRegisteredDialects()) {
157       llvm::outs() << dialect->getNamespace() << "\n";
158     }
159     return 0;
160   }
161 
162   // Set up the input file.
163   std::string errorMessage;
164   auto file = openInputFile(inputFilename, &errorMessage);
165   if (!file) {
166     llvm::errs() << errorMessage << "\n";
167     return 1;
168   }
169 
170   auto output = openOutputFile(outputFilename, &errorMessage);
171   if (!output) {
172     llvm::errs() << errorMessage << "\n";
173     exit(1);
174   }
175 
176   if (failed(MlirOptMain(output->os(), std::move(file), passPipeline,
177                          splitInputFile, verifyDiagnostics, verifyPasses,
178                          allowUnregisteredDialects))) {
179     return 1;
180   }
181   // Keep the output file if the invocation of MlirOptMain was successful.
182   output->keep();
183   return 0;
184 }
185