1- // ===-- llvm-split: command line tool for testing module splitter - --------===//
1+ // ===-- llvm-split: command line tool for testing module splitting --------===//
22//
33// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44// See https://llvm.org/LICENSE.txt for license information.
55// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66//
77// ===----------------------------------------------------------------------===//
88//
9- // This program can be used to test the llvm::SplitModule function.
9+ // This program can be used to test the llvm::SplitModule and
10+ // TargetMachine::splitModule functions.
1011//
1112// ===----------------------------------------------------------------------===//
1213
1516#include " llvm/IR/LLVMContext.h"
1617#include " llvm/IR/Verifier.h"
1718#include " llvm/IRReader/IRReader.h"
19+ #include " llvm/MC/TargetRegistry.h"
1820#include " llvm/Support/CommandLine.h"
1921#include " llvm/Support/FileSystem.h"
22+ #include " llvm/Support/InitLLVM.h"
2023#include " llvm/Support/SourceMgr.h"
24+ #include " llvm/Support/TargetSelect.h"
2125#include " llvm/Support/ToolOutputFile.h"
22- #include " llvm/Support/raw_ostream.h"
2326#include " llvm/Support/WithColor.h"
27+ #include " llvm/Support/raw_ostream.h"
28+ #include " llvm/Target/TargetMachine.h"
29+ #include " llvm/TargetParser/Triple.h"
2430#include " llvm/Transforms/Utils/SplitModule.h"
2531
2632using namespace llvm ;
@@ -47,12 +53,42 @@ static cl::opt<bool>
4753 cl::desc(" Split without externalizing locals" ),
4854 cl::cat(SplitCategory));
4955
56+ static cl::opt<std::string>
57+ MTriple (" mtriple" ,
58+ cl::desc (" Target triple. When present, a TargetMachine is created "
59+ " and TargetMachine::splitModule is used instead of the "
60+ " common SplitModule logic." ),
61+ cl::value_desc(" triple" ), cl::cat(SplitCategory));
62+
63+ static cl::opt<std::string>
64+ MCPU (" mcpu" , cl::desc(" Target CPU, ignored if -mtriple is not used" ),
65+ cl::value_desc(" cpu" ), cl::cat(SplitCategory));
66+
5067int main (int argc, char **argv) {
68+ InitLLVM X (argc, argv);
69+
5170 LLVMContext Context;
5271 SMDiagnostic Err;
5372 cl::HideUnrelatedOptions ({&SplitCategory, &getColorCategory ()});
5473 cl::ParseCommandLineOptions (argc, argv, " LLVM module splitter\n " );
5574
75+ TargetMachine *TM = nullptr ;
76+ if (!MTriple.empty ()) {
77+ InitializeAllTargets ();
78+ InitializeAllTargetMCs ();
79+
80+ std::string Error;
81+ const Target *T = TargetRegistry::lookupTarget (MTriple, Error);
82+ if (!T) {
83+ errs () << " unknown target '" << MTriple << " ': " << Error << " \n " ;
84+ return 1 ;
85+ }
86+
87+ TargetOptions Options;
88+ TM = T->createTargetMachine (MTriple, MCPU, /* FS*/ " " , Options, std::nullopt ,
89+ std::nullopt );
90+ }
91+
5692 std::unique_ptr<Module> M = parseIRFile (InputFilename, Err, Context);
5793
5894 if (!M) {
@@ -61,28 +97,40 @@ int main(int argc, char **argv) {
6197 }
6298
6399 unsigned I = 0 ;
64- SplitModule (
65- *M, NumOutputs,
66- [&](std::unique_ptr<Module> MPart) {
67- std::error_code EC;
68- std::unique_ptr<ToolOutputFile> Out (new ToolOutputFile (
69- OutputFilename + utostr (I++), EC, sys::fs::OF_None));
70- if (EC) {
71- errs () << EC.message () << ' \n ' ;
72- exit (1 );
73- }
74-
75- if (verifyModule (*MPart, &errs ())) {
76- errs () << " Broken module!\n " ;
77- exit (1 );
78- }
79-
80- WriteBitcodeToFile (*MPart, Out->os ());
81-
82- // Declare success.
83- Out->keep ();
84- },
85- PreserveLocals);
100+ const auto HandleModulePart = [&](std::unique_ptr<Module> MPart) {
101+ std::error_code EC;
102+ std::unique_ptr<ToolOutputFile> Out (
103+ new ToolOutputFile (OutputFilename + utostr (I++), EC, sys::fs::OF_None));
104+ if (EC) {
105+ errs () << EC.message () << ' \n ' ;
106+ exit (1 );
107+ }
108+
109+ if (verifyModule (*MPart, &errs ())) {
110+ errs () << " Broken module!\n " ;
111+ exit (1 );
112+ }
113+
114+ WriteBitcodeToFile (*MPart, Out->os ());
115+
116+ // Declare success.
117+ Out->keep ();
118+ };
119+
120+ if (TM) {
121+ if (PreserveLocals) {
122+ errs () << " warning: -preserve-locals has no effect when using "
123+ " TargetMachine::splitModule\n " ;
124+ }
125+
126+ if (TM->splitModule (*M, NumOutputs, HandleModulePart))
127+ return 0 ;
128+
129+ errs () << " warning: "
130+ " TargetMachine::splitModule failed, falling back to default "
131+ " splitModule implementation\n " ;
132+ }
86133
134+ SplitModule (*M, NumOutputs, HandleModulePart, PreserveLocals);
87135 return 0 ;
88136}
0 commit comments