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,42 @@ 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
+ 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
+
50
67
int main (int argc, char **argv) {
68
+ InitLLVM X (argc, argv);
69
+
51
70
LLVMContext Context;
52
71
SMDiagnostic Err;
53
72
cl::HideUnrelatedOptions ({&SplitCategory, &getColorCategory ()});
54
73
cl::ParseCommandLineOptions (argc, argv, " LLVM module splitter\n " );
55
74
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
+
56
92
std::unique_ptr<Module> M = parseIRFile (InputFilename, Err, Context);
57
93
58
94
if (!M) {
@@ -61,28 +97,40 @@ int main(int argc, char **argv) {
61
97
}
62
98
63
99
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
+ }
86
133
134
+ SplitModule (*M, NumOutputs, HandleModulePart, PreserveLocals);
87
135
return 0 ;
88
136
}
0 commit comments