blob: a67b1453fc28ddf0a9ba185b658176ee459f521b [file] [log] [blame]
jeanPerier57f536a2020-03-12 04:47:221//===- tco.cpp - Tilikum Crossing Opt ---------------------------*- C++ -*-===//
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// This is to be like LLVM's opt program, only for FIR. Such a program is
10// required for roundtrip testing, etc.
11//
12//===----------------------------------------------------------------------===//
13
Eric Schweitzf800a9b2021-02-12 21:09:1014#include "flang/Optimizer/Support/InitFIR.h"
jeanPerier57f536a2020-03-12 04:47:2215#include "flang/Optimizer/Support/KindMapping.h"
River Riddle65fcddf2020-11-19 18:43:1216#include "mlir/IR/BuiltinOps.h"
jeanPerier57f536a2020-03-12 04:47:2217#include "mlir/IR/MLIRContext.h"
jeanPerier57f536a2020-03-12 04:47:2218#include "mlir/Parser.h"
19#include "mlir/Pass/Pass.h"
20#include "mlir/Pass/PassManager.h"
21#include "mlir/Transforms/Passes.h"
22#include "llvm/Support/CommandLine.h"
23#include "llvm/Support/ErrorOr.h"
24#include "llvm/Support/InitLLVM.h"
25#include "llvm/Support/MemoryBuffer.h"
26#include "llvm/Support/SourceMgr.h"
27#include "llvm/Support/ToolOutputFile.h"
28#include "llvm/Support/raw_ostream.h"
29
30using namespace llvm;
31
32static cl::opt<std::string>
33 inputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
34
35static cl::opt<std::string> outputFilename("o",
36 cl::desc("Specify output filename"),
37 cl::value_desc("filename"),
38 cl::init("-"));
39
40static cl::opt<bool> emitFir("emit-fir",
41 cl::desc("Parse and pretty-print the input"),
42 cl::init(false));
43
44static void printModuleBody(mlir::ModuleOp mod, raw_ostream &output) {
45 for (auto &op : mod.getBody()->without_terminator())
46 output << op << '\n';
47}
48
49// compile a .fir file
Sourabh Singh Tomarbca06192021-02-04 19:25:2250static mlir::LogicalResult
51compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
jeanPerier57f536a2020-03-12 04:47:2252 // check that there is a file to load
53 ErrorOr<std::unique_ptr<MemoryBuffer>> fileOrErr =
54 MemoryBuffer::getFileOrSTDIN(inputFilename);
55
56 if (std::error_code EC = fileOrErr.getError()) {
57 errs() << "Could not open file: " << EC.message() << '\n';
Sourabh Singh Tomarbca06192021-02-04 19:25:2258 return mlir::failure();
jeanPerier57f536a2020-03-12 04:47:2259 }
60
61 // load the file into a module
62 SourceMgr sourceMgr;
63 sourceMgr.AddNewSourceBuffer(std::move(*fileOrErr), SMLoc());
Alex Zinenko2996a8d2021-02-10 09:11:5064 mlir::DialectRegistry registry;
Eric Schweitzf800a9b2021-02-12 21:09:1065 fir::support::registerDialects(registry);
Alex Zinenko2996a8d2021-02-10 09:11:5066 mlir::MLIRContext context(registry);
Mehdi Aminif6615b22020-08-23 21:20:4967 auto owningRef = mlir::parseSourceFile(sourceMgr, &context);
jeanPerier57f536a2020-03-12 04:47:2268
69 if (!owningRef) {
70 errs() << "Error can't load file " << inputFilename << '\n';
Sourabh Singh Tomarbca06192021-02-04 19:25:2271 return mlir::failure();
jeanPerier57f536a2020-03-12 04:47:2272 }
73 if (mlir::failed(owningRef->verify())) {
74 errs() << "Error verifying FIR module\n";
Sourabh Singh Tomarbca06192021-02-04 19:25:2275 return mlir::failure();
jeanPerier57f536a2020-03-12 04:47:2276 }
77
78 std::error_code ec;
79 ToolOutputFile out(outputFilename, ec, sys::fs::OF_None);
80
81 // run passes
Mehdi Aminif6615b22020-08-23 21:20:4982 mlir::PassManager pm{&context};
jeanPerier57f536a2020-03-12 04:47:2283 mlir::applyPassManagerCLOptions(pm);
84 if (emitFir) {
85 // parse the input and pretty-print it back out
86 // -emit-fir intentionally disables all the passes
87 } else {
88 // TODO: Actually add passes when added to FIR code base
89 // add all the passes
90 // the user can disable them individually
91 }
92
93 // run the pass manager
94 if (mlir::succeeded(pm.run(*owningRef))) {
95 // passes ran successfully, so keep the output
96 if (emitFir)
97 printModuleBody(*owningRef, out.os());
98 out.keep();
Sourabh Singh Tomarbca06192021-02-04 19:25:2299 return mlir::success();
jeanPerier57f536a2020-03-12 04:47:22100 }
101
102 // pass manager failed
103 printModuleBody(*owningRef, errs());
104 errs() << "\n\nFAILED: " << inputFilename << '\n';
Sourabh Singh Tomarbca06192021-02-04 19:25:22105 return mlir::failure();
jeanPerier57f536a2020-03-12 04:47:22106}
107
108int main(int argc, char **argv) {
Eric Schweitzf800a9b2021-02-12 21:09:10109 fir::support::registerFIRPasses();
jeanPerier57f536a2020-03-12 04:47:22110 [[maybe_unused]] InitLLVM y(argc, argv);
111 mlir::registerPassManagerCLOptions();
112 mlir::PassPipelineCLParser passPipe("", "Compiler passes to run");
113 cl::ParseCommandLineOptions(argc, argv, "Tilikum Crossing Optimizer\n");
Sourabh Singh Tomarbca06192021-02-04 19:25:22114 return mlir::failed(compileFIR(passPipe));
jeanPerier57f536a2020-03-12 04:47:22115}