106f32e7eSjoerg //===-- llvm-split: command line tool for testing module splitter ---------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This program can be used to test the llvm::SplitModule function.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg 
1306f32e7eSjoerg #include "llvm/ADT/StringExtras.h"
1406f32e7eSjoerg #include "llvm/Bitcode/BitcodeWriter.h"
1506f32e7eSjoerg #include "llvm/IR/LLVMContext.h"
1606f32e7eSjoerg #include "llvm/IR/Verifier.h"
1706f32e7eSjoerg #include "llvm/IRReader/IRReader.h"
1806f32e7eSjoerg #include "llvm/Support/CommandLine.h"
1906f32e7eSjoerg #include "llvm/Support/FileSystem.h"
2006f32e7eSjoerg #include "llvm/Support/SourceMgr.h"
2106f32e7eSjoerg #include "llvm/Support/ToolOutputFile.h"
2206f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
2306f32e7eSjoerg #include "llvm/Transforms/Utils/SplitModule.h"
2406f32e7eSjoerg 
2506f32e7eSjoerg using namespace llvm;
2606f32e7eSjoerg 
2706f32e7eSjoerg static cl::opt<std::string>
2806f32e7eSjoerg InputFilename(cl::Positional, cl::desc("<input bitcode file>"),
2906f32e7eSjoerg     cl::init("-"), cl::value_desc("filename"));
3006f32e7eSjoerg 
3106f32e7eSjoerg static cl::opt<std::string>
3206f32e7eSjoerg OutputFilename("o", cl::desc("Override output filename"),
3306f32e7eSjoerg                cl::value_desc("filename"));
3406f32e7eSjoerg 
3506f32e7eSjoerg static cl::opt<unsigned> NumOutputs("j", cl::Prefix, cl::init(2),
3606f32e7eSjoerg                                     cl::desc("Number of output files"));
3706f32e7eSjoerg 
3806f32e7eSjoerg static cl::opt<bool>
3906f32e7eSjoerg     PreserveLocals("preserve-locals", cl::Prefix, cl::init(false),
4006f32e7eSjoerg                    cl::desc("Split without externalizing locals"));
4106f32e7eSjoerg 
main(int argc,char ** argv)4206f32e7eSjoerg int main(int argc, char **argv) {
4306f32e7eSjoerg   LLVMContext Context;
4406f32e7eSjoerg   SMDiagnostic Err;
4506f32e7eSjoerg   cl::ParseCommandLineOptions(argc, argv, "LLVM module splitter\n");
4606f32e7eSjoerg 
4706f32e7eSjoerg   std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);
4806f32e7eSjoerg 
4906f32e7eSjoerg   if (!M) {
5006f32e7eSjoerg     Err.print(argv[0], errs());
5106f32e7eSjoerg     return 1;
5206f32e7eSjoerg   }
5306f32e7eSjoerg 
5406f32e7eSjoerg   unsigned I = 0;
55*da58b97aSjoerg   SplitModule(
56*da58b97aSjoerg       *M, NumOutputs,
57*da58b97aSjoerg       [&](std::unique_ptr<Module> MPart) {
5806f32e7eSjoerg         std::error_code EC;
59*da58b97aSjoerg         std::unique_ptr<ToolOutputFile> Out(new ToolOutputFile(
60*da58b97aSjoerg             OutputFilename + utostr(I++), EC, sys::fs::OF_None));
6106f32e7eSjoerg         if (EC) {
6206f32e7eSjoerg           errs() << EC.message() << '\n';
6306f32e7eSjoerg           exit(1);
6406f32e7eSjoerg         }
6506f32e7eSjoerg 
66*da58b97aSjoerg         if (verifyModule(*MPart, &errs())) {
67*da58b97aSjoerg           errs() << "Broken module!\n";
68*da58b97aSjoerg           exit(1);
69*da58b97aSjoerg         }
70*da58b97aSjoerg 
7106f32e7eSjoerg         WriteBitcodeToFile(*MPart, Out->os());
7206f32e7eSjoerg 
7306f32e7eSjoerg         // Declare success.
7406f32e7eSjoerg         Out->keep();
75*da58b97aSjoerg       },
76*da58b97aSjoerg       PreserveLocals);
7706f32e7eSjoerg 
7806f32e7eSjoerg   return 0;
7906f32e7eSjoerg }
80