/builds/2mk6rsew/0/parcoach/parcoach/src/tools/launcher/Parcoacht.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "parcoach/Passes.h" |
2 | | |
3 | | #include "llvm/ADT/Triple.h" |
4 | | #include "llvm/Analysis/CallGraph.h" |
5 | | #include "llvm/Analysis/CallGraphSCCPass.h" |
6 | | #include "llvm/Analysis/LoopPass.h" |
7 | | #include "llvm/Analysis/RegionPass.h" |
8 | | #include "llvm/Analysis/TargetLibraryInfo.h" |
9 | | #include "llvm/Analysis/TargetTransformInfo.h" |
10 | | #include "llvm/AsmParser/Parser.h" |
11 | | #include "llvm/CodeGen/CommandFlags.h" |
12 | | #include "llvm/CodeGen/TargetPassConfig.h" |
13 | | #include "llvm/Config/llvm-config.h" |
14 | | #include "llvm/IR/DataLayout.h" |
15 | | #include "llvm/IR/DebugInfo.h" |
16 | | #include "llvm/IR/LLVMContext.h" |
17 | | #include "llvm/IR/LLVMRemarkStreamer.h" |
18 | | #include "llvm/IR/LegacyPassManager.h" |
19 | | #include "llvm/IR/LegacyPassNameParser.h" |
20 | | #include "llvm/IR/Module.h" |
21 | | #include "llvm/IR/ModuleSummaryIndex.h" |
22 | | #include "llvm/IR/Verifier.h" |
23 | | #include "llvm/IRReader/IRReader.h" |
24 | | #include "llvm/InitializePasses.h" |
25 | | #include "llvm/LinkAllIR.h" |
26 | | #include "llvm/LinkAllPasses.h" |
27 | | #include "llvm/Passes/PassBuilder.h" |
28 | | #include "llvm/Remarks/HotnessThresholdParser.h" |
29 | | #include "llvm/Support/Debug.h" |
30 | | #include "llvm/Support/FileSystem.h" |
31 | | #include "llvm/Support/Host.h" |
32 | | #include "llvm/Support/InitLLVM.h" |
33 | | #include "llvm/Support/PluginLoader.h" |
34 | | #include "llvm/Support/SourceMgr.h" |
35 | | #include "llvm/Support/SystemUtils.h" |
36 | | #include "llvm/Support/TargetSelect.h" |
37 | | #include "llvm/Support/ToolOutputFile.h" |
38 | | #include "llvm/Support/YAMLTraits.h" |
39 | | #include "llvm/Target/TargetMachine.h" |
40 | | #include "llvm/Transforms/IPO/AlwaysInliner.h" |
41 | | #include "llvm/Transforms/IPO/PassManagerBuilder.h" |
42 | | #include "llvm/Transforms/IPO/WholeProgramDevirt.h" |
43 | | #include "llvm/Transforms/Utils/Cloning.h" |
44 | | #include "llvm/Transforms/Utils/Debugify.h" |
45 | | |
46 | | using namespace llvm; |
47 | | |
48 | | namespace { |
49 | | |
50 | | cl::opt<std::string> InputFilename(cl::Positional, |
51 | | cl::desc("<input bitcode file>"), |
52 | | cl::init("-"), cl::value_desc("filename")); |
53 | | |
54 | | cl::opt<std::string> OutputFilename("o", cl::desc("Override output filename"), |
55 | | cl::value_desc("filename")); |
56 | | |
57 | | cl::opt<bool> OutputAssembly("S", cl::desc("Write output as LLVM assembly")); |
58 | | |
59 | | cl::opt<bool> NoOutput("disable-output", |
60 | | cl::desc("Do not write result bitcode file"), |
61 | | cl::Hidden); |
62 | | |
63 | | cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace")); |
64 | | |
65 | | cl::opt<unsigned> TimeTraceGranularity( |
66 | | "time-trace-granularity", |
67 | | cl::desc( |
68 | | "Minimum time granularity (in microseconds) traced by time profiler"), |
69 | | cl::init(500), cl::Hidden); |
70 | | |
71 | | cl::opt<std::string> |
72 | | TimeTraceFile("time-trace-file", |
73 | | cl::desc("Specify time trace file destination"), |
74 | | cl::value_desc("filename")); |
75 | | |
76 | | static cl::opt<bool> ShowVersion("parcoach-version", |
77 | | cl::desc("Show PARCOACH version")); |
78 | | |
79 | | enum OutputKind { |
80 | | OK_NoOutput, |
81 | | OK_OutputAssembly, |
82 | | OK_OutputBitcode, |
83 | | }; |
84 | | |
85 | | struct TimeTracer { |
86 | | StringRef InputFilename; |
87 | 1.83k | TimeTracer(StringRef ProgramName, StringRef Input) : InputFilename(Input) { |
88 | 1.83k | if (TimeTrace) |
89 | 2 | timeTraceProfilerInitialize(TimeTraceGranularity, ProgramName); |
90 | 1.83k | } |
91 | 1.83k | ~TimeTracer() { |
92 | 1.83k | if (TimeTrace) { |
93 | 2 | if (auto E = timeTraceProfilerWrite(TimeTraceFile, InputFilename)) { |
94 | 1 | handleAllErrors(std::move(E), [&](StringError const &SE) { |
95 | 1 | errs() << SE.getMessage() << "\n"; |
96 | 1 | }); |
97 | 1 | return; |
98 | 1 | } |
99 | 1 | timeTraceProfilerCleanup(); |
100 | 1 | } |
101 | 1.83k | } |
102 | | }; |
103 | | } // namespace |
104 | | |
105 | 1.83k | int main(int argc, char **argv) { |
106 | 1.83k | InitLLVM X(argc, argv); |
107 | | |
108 | | // Enable debug stream buffering. |
109 | 1.83k | EnableDebugBuffering = true; |
110 | | |
111 | 1.83k | InitializeAllTargets(); |
112 | 1.83k | InitializeAllTargetMCs(); |
113 | 1.83k | InitializeAllAsmPrinters(); |
114 | 1.83k | InitializeAllAsmParsers(); |
115 | | |
116 | | // Initialize passes |
117 | 1.83k | PassRegistry &Registry = *PassRegistry::getPassRegistry(); |
118 | 1.83k | initializeCore(Registry); |
119 | 1.83k | initializeAnalysis(Registry); |
120 | 1.83k | initializeTransformUtils(Registry); |
121 | 1.83k | initializeInstrumentation(Registry); |
122 | 1.83k | initializeTarget(Registry); |
123 | | |
124 | 1.83k | cl::ParseCommandLineOptions( |
125 | 1.83k | argc, argv, "parcoach: a static/dynamic analyzer for MPI collectives\n"); |
126 | | |
127 | 1.83k | if (ShowVersion) { |
128 | 1 | parcoach::PrintVersion(outs()); |
129 | 1 | return 0; |
130 | 1 | } |
131 | | |
132 | 1.83k | LLVMContext Context; |
133 | | |
134 | 1.83k | SMDiagnostic Err; |
135 | | // Load the input module... |
136 | 1.83k | std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context); |
137 | | |
138 | 1.83k | if (!M) { |
139 | 1 | Err.print(argv[0], errs()); |
140 | 1 | return 1; |
141 | 1 | } |
142 | | |
143 | 1.83k | TimeTracer Tracer(argv[0], InputFilename); |
144 | 1.83k | TimeTraceScope TTS("Parcoach", "The main entry point of the tool."); |
145 | | |
146 | | // Immediately run the verifier to catch any problems before starting up the |
147 | | // pass pipelines. Otherwise we can crash on broken code during |
148 | | // doInitialization(). |
149 | 1.83k | if (verifyModule(*M, &errs())) { |
150 | 1 | errs() << argv[0] << ": " << InputFilename |
151 | 1 | << ": error: input module is broken!\n"; |
152 | 1 | return 1; |
153 | 1 | } |
154 | | |
155 | | // Figure out what stream we are supposed to write to... |
156 | 1.82k | std::unique_ptr<ToolOutputFile> Out; |
157 | 1.82k | OutputKind OK{OK_NoOutput}; |
158 | | |
159 | 1.82k | if (OutputFilename.empty()) { |
160 | | // By default we don't necessarily instrument the code, so if we don't |
161 | | // explicitly specify an output, just assume we just print the analysis |
162 | | // result. |
163 | 71 | NoOutput = true; |
164 | 71 | } |
165 | | |
166 | 1.82k | if (!NoOutput) { |
167 | 1.75k | std::error_code EC; |
168 | 1.75k | sys::fs::OpenFlags Flags = |
169 | 1.75k | OutputAssembly ? sys::fs::OF_TextWithCRLF : sys::fs::OF_None; |
170 | 1.75k | Out.reset(new ToolOutputFile(OutputFilename, EC, Flags)); |
171 | 1.75k | if (EC) { |
172 | 1 | errs() << EC.message() << '\n'; |
173 | 1 | return 1; |
174 | 1 | } |
175 | 1.75k | OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode; |
176 | 1.75k | } |
177 | | |
178 | 1.82k | Triple ModuleTriple(M->getTargetTriple()); |
179 | | |
180 | | // Add an appropriate TargetLibraryInfo pass for the module's triple. |
181 | 1.82k | TargetLibraryInfoImpl TLII(ModuleTriple); |
182 | | |
183 | 1.82k | LoopAnalysisManager LAM; |
184 | 1.82k | FunctionAnalysisManager FAM; |
185 | 1.82k | CGSCCAnalysisManager CGAM; |
186 | 1.82k | ModuleAnalysisManager MAM; |
187 | | |
188 | 1.82k | PassInstrumentationCallbacks PIC; |
189 | 1.82k | PipelineTuningOptions PTO; |
190 | 1.82k | PassBuilder PB(nullptr, PTO, None, &PIC); |
191 | | |
192 | | // Register our TargetLibraryInfoImpl. |
193 | 1.82k | FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); }); |
194 | | |
195 | | // Register all the basic analyses with the managers. |
196 | 1.82k | PB.registerModuleAnalyses(MAM); |
197 | 1.82k | parcoach::RegisterModuleAnalyses(MAM); |
198 | 1.82k | PB.registerCGSCCAnalyses(CGAM); |
199 | 1.82k | PB.registerFunctionAnalyses(FAM); |
200 | 1.82k | parcoach::RegisterFunctionAnalyses(FAM); |
201 | 1.82k | PB.registerLoopAnalyses(LAM); |
202 | 1.82k | PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); |
203 | | |
204 | 1.82k | ModulePassManager MPM; |
205 | 1.82k | parcoach::RegisterPasses(MPM); |
206 | | |
207 | 1.82k | switch (OK) { |
208 | 71 | case OK_NoOutput: |
209 | 71 | break; // No output pass needed. |
210 | 1 | case OK_OutputAssembly: |
211 | 1 | MPM.addPass(PrintModulePass(Out->os(), "", false)); |
212 | 1 | break; |
213 | 1.75k | case OK_OutputBitcode: |
214 | 1.75k | MPM.addPass(BitcodeWriterPass(Out->os(), false, false, false)); |
215 | 1.75k | break; |
216 | 1.82k | } |
217 | | |
218 | 1.82k | MPM.run(*M, MAM); |
219 | | |
220 | 1.82k | if (Out) { |
221 | 1.75k | Out->keep(); |
222 | 1.75k | } |
223 | 1.82k | return 0; |
224 | 1.82k | } |