1
- // ===-- llvm-split: command line tool for testing module splitter - --------===//
1
+ // ===-- llvm-split: command line tool for testing module splitting --------===//
2
2
//
3
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
4
// See https://llvm.org/LICENSE.txt for license information.
5
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
//
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.
10
11
//
11
12
// ===----------------------------------------------------------------------===//
12
13
15
16
#include " llvm/IR/LLVMContext.h"
16
17
#include " llvm/IR/Verifier.h"
17
18
#include " llvm/IRReader/IRReader.h"
19
+ #include " llvm/MC/TargetRegistry.h"
18
20
#include " llvm/Support/CommandLine.h"
19
21
#include " llvm/Support/FileSystem.h"
22
+ #include " llvm/Support/InitLLVM.h"
20
23
#include " llvm/Support/SourceMgr.h"
24
+ #include " llvm/Support/TargetSelect.h"
21
25
#include " llvm/Support/ToolOutputFile.h"
22
- #include " llvm/Support/raw_ostream.h"
23
26
#include " llvm/Support/WithColor.h"
27
+ #include " llvm/Support/raw_ostream.h"
28
+ #include " llvm/Target/TargetMachine.h"
29
+ #include " llvm/TargetParser/Triple.h"
24
30
#include " llvm/Transforms/Utils/SplitModule.h"
25
31
26
32
using namespace llvm ;
@@ -47,12 +53,45 @@ static cl::opt<bool>
47
53
cl::desc(" Split without externalizing locals" ),
48
54
cl::cat(SplitCategory));
49
55
56
+ static cl::opt<std::string>
57
+ MTarget (" mtarget" ,
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 -mtarget is not used" ),
65
+ cl::value_desc(" cpu" ), cl::cat(SplitCategory));
66
+
50
67
int main (int argc, char **argv) {
68
+ InitLLVM X (argc, argv);
69
+
70
+ // NOTE: If mtarget is not present we could avoid initializing targets to save
71
+ // time, but this is a testing tool and it's likely not worth the added
72
+ // complexity.
73
+ InitializeAllTargets ();
74
+ InitializeAllTargetMCs ();
75
+
51
76
LLVMContext Context;
52
77
SMDiagnostic Err;
53
78
cl::HideUnrelatedOptions ({&SplitCategory, &getColorCategory ()});
54
79
cl::ParseCommandLineOptions (argc, argv, " LLVM module splitter\n " );
55
80
81
+ TargetMachine *TM = nullptr ;
82
+ if (!MTarget.empty ()) {
83
+ std::string Error;
84
+ const Target *T = TargetRegistry::lookupTarget (MTarget, Error);
85
+ if (!T) {
86
+ errs () << " unknown target '" << MTarget << " ': " << Error << " \n " ;
87
+ return 1 ;
88
+ }
89
+
90
+ TargetOptions Options;
91
+ TM = T->createTargetMachine (MTarget, MCPU, /* FS*/ " " , Options, std::nullopt,
92
+ std::nullopt);
93
+ }
94
+
56
95
std::unique_ptr<Module> M = parseIRFile (InputFilename, Err, Context);
57
96
58
97
if (!M) {
@@ -61,28 +100,40 @@ int main(int argc, char **argv) {
61
100
}
62
101
63
102
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);
103
+ const auto HandleModulePart = [&](std::unique_ptr<Module> MPart) {
104
+ std::error_code EC;
105
+ std::unique_ptr<ToolOutputFile> Out (
106
+ new ToolOutputFile (OutputFilename + utostr (I++), EC, sys::fs::OF_None));
107
+ if (EC) {
108
+ errs () << EC.message () << ' \n ' ;
109
+ exit (1 );
110
+ }
111
+
112
+ if (verifyModule (*MPart, &errs ())) {
113
+ errs () << " Broken module!\n " ;
114
+ exit (1 );
115
+ }
116
+
117
+ WriteBitcodeToFile (*MPart, Out->os ());
118
+
119
+ // Declare success.
120
+ Out->keep ();
121
+ };
122
+
123
+ if (TM) {
124
+ if (PreserveLocals) {
125
+ errs () << " warning: -preserve-locals has no effect when using "
126
+ " TargetMachine::splitModule\n " ;
127
+ }
128
+
129
+ if (TM->splitModule (*M, NumOutputs, HandleModulePart))
130
+ return 0 ;
131
+
132
+ errs () << " warning:"
133
+ " TargetMachine::splitModule failed, falling back to default "
134
+ " splitModule implementation\n " ;
135
+ }
86
136
137
+ SplitModule (*M, NumOutputs, HandleModulePart, PreserveLocals);
87
138
return 0 ;
88
139
}
0 commit comments