OLD | NEW |
1 //===- subzero/src/llvm2ice.cpp - Driver for testing ----------------------===// | 1 //===- subzero/src/llvm2ice.cpp - Driver for testing ----------------------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines a driver that uses LLVM capabilities to parse a | 10 // This file defines a driver that uses LLVM capabilities to parse a |
11 // bitcode file and build the LLVM IR, and then convert the LLVM basic | 11 // bitcode file and build the LLVM IR, and then convert the LLVM basic |
12 // blocks, instructions, and operands into their Subzero equivalents. | 12 // blocks, instructions, and operands into their Subzero equivalents. |
13 // | 13 // |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 | 15 |
16 #include <fstream> | 16 #include <fstream> |
17 #include <iostream> | 17 #include <iostream> |
18 | 18 |
19 #include "llvm/ADT/STLExtras.h" | 19 #include "llvm/ADT/STLExtras.h" |
20 #include "llvm/IR/LLVMContext.h" | 20 #include "llvm/IR/LLVMContext.h" |
21 #include "llvm/IRReader/IRReader.h" | 21 #include "llvm/IRReader/IRReader.h" |
22 #include "llvm/Support/CommandLine.h" | 22 #include "llvm/Support/CommandLine.h" |
| 23 #include "llvm/Support/FileSystem.h" |
23 #include "llvm/Support/raw_os_ostream.h" | 24 #include "llvm/Support/raw_os_ostream.h" |
24 #include "llvm/Support/SourceMgr.h" | 25 #include "llvm/Support/SourceMgr.h" |
25 | 26 |
26 #include "IceCfg.h" | 27 #include "IceCfg.h" |
27 #include "IceClFlags.h" | 28 #include "IceClFlags.h" |
28 #include "IceConverter.h" | 29 #include "IceConverter.h" |
29 #include "PNaClTranslator.h" | 30 #include "PNaClTranslator.h" |
30 | 31 |
31 using namespace llvm; | 32 using namespace llvm; |
32 | 33 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 cl::init(true)); | 167 cl::init(true)); |
167 | 168 |
168 static cl::opt<bool> | 169 static cl::opt<bool> |
169 UseIntegratedAssembler("integrated-as", | 170 UseIntegratedAssembler("integrated-as", |
170 cl::desc("Use integrated assembler (default yes)"), | 171 cl::desc("Use integrated assembler (default yes)"), |
171 cl::init(true)); | 172 cl::init(true)); |
172 | 173 |
173 static cl::alias UseIas("ias", cl::desc("Alias for -integrated-as"), | 174 static cl::alias UseIas("ias", cl::desc("Alias for -integrated-as"), |
174 cl::NotHidden, cl::aliasopt(UseIntegratedAssembler)); | 175 cl::NotHidden, cl::aliasopt(UseIntegratedAssembler)); |
175 | 176 |
| 177 static cl::opt<bool> |
| 178 UseELFWriter("elf-writer", |
| 179 cl::desc("Use ELF writer with the integrated assembler"), |
| 180 cl::init(false)); |
| 181 |
176 static cl::opt<bool> AlwaysExitSuccess( | 182 static cl::opt<bool> AlwaysExitSuccess( |
177 "exit-success", cl::desc("Exit with success status, even if errors found"), | 183 "exit-success", cl::desc("Exit with success status, even if errors found"), |
178 cl::init(false)); | 184 cl::init(false)); |
179 | 185 |
180 static cl::opt<bool> | 186 static cl::opt<bool> |
181 GenerateBuildAtts("build-atts", | 187 GenerateBuildAtts("build-atts", |
182 cl::desc("Generate list of build attributes associated with " | 188 cl::desc("Generate list of build attributes associated with " |
183 "this executable."), | 189 "this executable."), |
184 cl::init(false)); | 190 cl::init(false)); |
185 | 191 |
186 static int GetReturnValue(int Val) { | 192 static int GetReturnValue(int Val) { |
187 if (AlwaysExitSuccess) | 193 if (AlwaysExitSuccess) |
188 return 0; | 194 return 0; |
189 return Val; | 195 return Val; |
190 } | 196 } |
191 | 197 |
192 static struct { | 198 static struct { |
193 const char *FlagName; | 199 const char *FlagName; |
194 int FlagValue; | 200 int FlagValue; |
195 } ConditionalBuildAttributes[] = {{"dump", ALLOW_DUMP}, | 201 } ConditionalBuildAttributes[] = {{"dump", ALLOW_DUMP}, |
196 {"llvm_cl", ALLOW_LLVM_CL}, | 202 {"llvm_cl", ALLOW_LLVM_CL}, |
197 {"llvm_ir", ALLOW_LLVM_IR}, | 203 {"llvm_ir", ALLOW_LLVM_IR}, |
198 {"llvm_ir_as_input", ALLOW_LLVM_IR_AS_INPUT}, | 204 {"llvm_ir_as_input", ALLOW_LLVM_IR_AS_INPUT}, |
199 {"disable_ir_gen", ALLOW_DISABLE_IR_GEN}}; | 205 {"disable_ir_gen", ALLOW_DISABLE_IR_GEN}}; |
200 | 206 |
201 // Validates values of build attributes. Prints them to Stream if | 207 // Validates values of build attributes. Prints them to Stream if |
202 // Stream is non-null. | 208 // Stream is non-null. |
203 static void ValidateAndGenerateBuildAttributes(raw_os_ostream *Stream) { | 209 static void ValidateAndGenerateBuildAttributes(Ice::Ostream *Stream) { |
204 | 210 |
205 if (Stream) | 211 if (Stream) |
206 *Stream << TargetArch << "\n"; | 212 *Stream << TargetArch << "\n"; |
207 | 213 |
208 for (size_t i = 0; i < array_lengthof(ConditionalBuildAttributes); ++i) { | 214 for (size_t i = 0; i < array_lengthof(ConditionalBuildAttributes); ++i) { |
209 switch (ConditionalBuildAttributes[i].FlagValue) { | 215 switch (ConditionalBuildAttributes[i].FlagValue) { |
210 case 0: | 216 case 0: |
211 if (Stream) | 217 if (Stream) |
212 *Stream << "no_" << ConditionalBuildAttributes[i].FlagName << "\n"; | 218 *Stream << "no_" << ConditionalBuildAttributes[i].FlagName << "\n"; |
213 break; | 219 break; |
(...skipping 21 matching lines...) Expand all Loading... |
235 DisableTranslation = true; | 241 DisableTranslation = true; |
236 | 242 |
237 Ice::VerboseMask VMask = Ice::IceV_None; | 243 Ice::VerboseMask VMask = Ice::IceV_None; |
238 // Don't generate verbose messages if routines | 244 // Don't generate verbose messages if routines |
239 // to dump messages are not available. | 245 // to dump messages are not available. |
240 if (ALLOW_DUMP) { | 246 if (ALLOW_DUMP) { |
241 for (unsigned i = 0; i != VerboseList.size(); ++i) | 247 for (unsigned i = 0; i != VerboseList.size(); ++i) |
242 VMask |= VerboseList[i]; | 248 VMask |= VerboseList[i]; |
243 } | 249 } |
244 | 250 |
245 std::ofstream Ofs; | 251 std::ofstream Lfs; |
246 if (OutputFilename != "-") { | 252 std::unique_ptr<Ice::Ostream> Ls; |
247 Ofs.open(OutputFilename.c_str(), std::ofstream::out); | 253 if (LogFilename != "-") { |
| 254 Lfs.open(LogFilename.c_str(), std::ofstream::out); |
| 255 Ls.reset(new raw_os_ostream(Lfs)); |
| 256 } else { |
| 257 Ls.reset(new raw_os_ostream(std::cout)); |
248 } | 258 } |
249 raw_os_ostream *Os = | 259 Ls->SetUnbuffered(); |
250 new raw_os_ostream(OutputFilename == "-" ? std::cout : Ofs); | |
251 Os->SetUnbuffered(); | |
252 | 260 |
253 ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Os : nullptr); | 261 ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Ls.get() : nullptr); |
254 if (GenerateBuildAtts) | 262 if (GenerateBuildAtts) |
255 return GetReturnValue(0); | 263 return GetReturnValue(0); |
256 | 264 |
257 std::ofstream Lfs; | |
258 if (LogFilename != "-") { | |
259 Lfs.open(LogFilename.c_str(), std::ofstream::out); | |
260 } | |
261 raw_os_ostream *Ls = new raw_os_ostream(LogFilename == "-" ? std::cout : Lfs); | |
262 Ls->SetUnbuffered(); | |
263 | |
264 if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) { | 265 if (!ALLOW_DISABLE_IR_GEN && DisableIRGeneration) { |
265 *Ls << "Error: Build doesn't allow --no-ir-gen when not " | 266 *Ls << "Error: Build doesn't allow --no-ir-gen when not " |
266 << "ALLOW_DISABLE_IR_GEN!\n"; | 267 << "ALLOW_DISABLE_IR_GEN!\n"; |
267 return GetReturnValue(1); | 268 return GetReturnValue(1); |
268 } | 269 } |
269 | 270 |
270 Ice::ClFlags Flags; | 271 Ice::ClFlags Flags; |
271 Flags.DisableInternal = DisableInternal; | 272 Flags.DisableInternal = DisableInternal; |
272 Flags.SubzeroTimingEnabled = SubzeroTimingEnabled; | 273 Flags.SubzeroTimingEnabled = SubzeroTimingEnabled; |
273 Flags.DisableTranslation = DisableTranslation; | 274 Flags.DisableTranslation = DisableTranslation; |
274 Flags.FunctionSections = FunctionSections; | 275 Flags.FunctionSections = FunctionSections; |
275 Flags.DataSections = DataSections; | 276 Flags.DataSections = DataSections; |
276 Flags.UseIntegratedAssembler = UseIntegratedAssembler; | 277 Flags.UseIntegratedAssembler = UseIntegratedAssembler; |
| 278 Flags.UseELFWriter = UseELFWriter; |
277 Flags.UseSandboxing = UseSandboxing; | 279 Flags.UseSandboxing = UseSandboxing; |
278 Flags.PhiEdgeSplit = EnablePhiEdgeSplit; | 280 Flags.PhiEdgeSplit = EnablePhiEdgeSplit; |
279 Flags.DecorateAsm = DecorateAsm; | 281 Flags.DecorateAsm = DecorateAsm; |
280 Flags.DumpStats = DumpStats; | 282 Flags.DumpStats = DumpStats; |
281 Flags.AllowUninitializedGlobals = AllowUninitializedGlobals; | 283 Flags.AllowUninitializedGlobals = AllowUninitializedGlobals; |
282 Flags.TimeEachFunction = TimeEachFunction; | 284 Flags.TimeEachFunction = TimeEachFunction; |
283 Flags.DefaultGlobalPrefix = DefaultGlobalPrefix; | 285 Flags.DefaultGlobalPrefix = DefaultGlobalPrefix; |
284 Flags.DefaultFunctionPrefix = DefaultFunctionPrefix; | 286 Flags.DefaultFunctionPrefix = DefaultFunctionPrefix; |
285 Flags.TimingFocusOn = TimingFocusOn; | 287 Flags.TimingFocusOn = TimingFocusOn; |
286 Flags.VerboseFocusOn = VerboseFocusOn; | 288 Flags.VerboseFocusOn = VerboseFocusOn; |
287 Flags.TranslateOnly = TranslateOnly; | 289 Flags.TranslateOnly = TranslateOnly; |
288 Flags.DisableIRGeneration = DisableIRGeneration; | 290 Flags.DisableIRGeneration = DisableIRGeneration; |
289 | 291 |
290 // Force -build-on-read=0 for .ll files. | 292 // Force -build-on-read=0 for .ll files. |
291 const std::string LLSuffix = ".ll"; | 293 const std::string LLSuffix = ".ll"; |
292 if (IRFilename.length() >= LLSuffix.length() && | 294 if (IRFilename.length() >= LLSuffix.length() && |
293 IRFilename.compare(IRFilename.length() - LLSuffix.length(), | 295 IRFilename.compare(IRFilename.length() - LLSuffix.length(), |
294 LLSuffix.length(), LLSuffix) == 0) | 296 LLSuffix.length(), LLSuffix) == 0) |
295 BuildOnRead = false; | 297 BuildOnRead = false; |
296 | 298 |
297 Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix, | 299 // With the ELF writer, use a raw_fd_ostream to allow seeking. |
298 Flags); | 300 // Also don't buffer, otherwise it gets pretty slow. |
| 301 std::unique_ptr<Ice::Ostream> Os; |
| 302 std::unique_ptr<Ice::ELFStreamer> ELFStr; |
| 303 std::ofstream Ofs; |
| 304 if (UseELFWriter) { |
| 305 if (OutputFilename == "-") { |
| 306 *Ls << "Error: writing binary ELF to stdout is unsupported\n"; |
| 307 return GetReturnValue(1); |
| 308 } |
| 309 std::string ErrorInfo; |
| 310 raw_fd_ostream *FdOs = |
| 311 new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, sys::fs::F_None); |
| 312 Os.reset(FdOs); |
| 313 if (!ErrorInfo.empty()) { |
| 314 *Ls << "Failed to open output file: " << OutputFilename << ":\n" |
| 315 << ErrorInfo << "\n"; |
| 316 return GetReturnValue(1); |
| 317 } |
| 318 ELFStr.reset(new Ice::ELFStreamer(*FdOs)); |
| 319 } else { |
| 320 if (OutputFilename != "-") { |
| 321 Ofs.open(OutputFilename.c_str(), std::ofstream::out); |
| 322 Os.reset(new raw_os_ostream(Ofs)); |
| 323 } else { |
| 324 Os.reset(new raw_os_ostream(std::cout)); |
| 325 } |
| 326 Os->SetUnbuffered(); |
| 327 } |
| 328 |
| 329 Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TargetArch, |
| 330 OptLevel, TestPrefix, Flags); |
299 | 331 |
300 Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); | 332 Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx); |
301 | 333 |
| 334 if (UseELFWriter) { |
| 335 Ctx.getObjectWriter()->writeInitialELFHeader(); |
| 336 } |
| 337 |
302 int ErrorStatus = 0; | 338 int ErrorStatus = 0; |
303 if (BuildOnRead) { | 339 if (BuildOnRead) { |
304 Ice::PNaClTranslator Translator(&Ctx, Flags); | 340 Ice::PNaClTranslator Translator(&Ctx, Flags); |
305 Translator.translate(IRFilename); | 341 Translator.translate(IRFilename); |
306 ErrorStatus = Translator.getErrorStatus(); | 342 ErrorStatus = Translator.getErrorStatus(); |
307 } else if (ALLOW_LLVM_IR) { | 343 } else if (ALLOW_LLVM_IR) { |
308 // Parse the input LLVM IR file into a module. | 344 // Parse the input LLVM IR file into a module. |
309 SMDiagnostic Err; | 345 SMDiagnostic Err; |
310 Ice::TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); | 346 Ice::TimerMarker T1(Ice::TimerStack::TT_parse, &Ctx); |
311 Module *Mod = | 347 Module *Mod = |
312 NaClParseIRFile(IRFilename, InputFileFormat, Err, getGlobalContext()); | 348 NaClParseIRFile(IRFilename, InputFileFormat, Err, getGlobalContext()); |
313 | 349 |
314 if (!Mod) { | 350 if (!Mod) { |
315 Err.print(argv[0], errs()); | 351 Err.print(argv[0], errs()); |
316 return GetReturnValue(1); | 352 return GetReturnValue(1); |
317 } | 353 } |
318 | 354 |
319 Ice::Converter Converter(Mod, &Ctx, Flags); | 355 Ice::Converter Converter(Mod, &Ctx, Flags); |
320 Converter.convertToIce(); | 356 Converter.convertToIce(); |
321 ErrorStatus = Converter.getErrorStatus(); | 357 ErrorStatus = Converter.getErrorStatus(); |
322 } else { | 358 } else { |
323 *Ls << "Error: Build doesn't allow LLVM IR, " | 359 *Ls << "Error: Build doesn't allow LLVM IR, " |
324 << "--build-on-read=0 not allowed\n"; | 360 << "--build-on-read=0 not allowed\n"; |
325 return GetReturnValue(1); | 361 return GetReturnValue(1); |
326 } | 362 } |
| 363 if (UseELFWriter) { |
| 364 Ctx.getObjectWriter()->writeNonUserSections(); |
| 365 } |
327 if (SubzeroTimingEnabled) | 366 if (SubzeroTimingEnabled) |
328 Ctx.dumpTimers(); | 367 Ctx.dumpTimers(); |
329 if (TimeEachFunction) { | 368 if (TimeEachFunction) { |
330 const bool DumpCumulative = false; | 369 const bool DumpCumulative = false; |
331 Ctx.dumpTimers(Ice::GlobalContext::TSK_Funcs, DumpCumulative); | 370 Ctx.dumpTimers(Ice::GlobalContext::TSK_Funcs, DumpCumulative); |
332 } | 371 } |
333 const bool FinalStats = true; | 372 const bool FinalStats = true; |
334 Ctx.dumpStats("_FINAL_", FinalStats); | 373 Ctx.dumpStats("_FINAL_", FinalStats); |
335 return GetReturnValue(ErrorStatus); | 374 return GetReturnValue(ErrorStatus); |
336 } | 375 } |
OLD | NEW |