diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-02-18 21:59:43 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-02-18 21:59:43 -0500 |
| commit | d7968c6d33b054a8293edd89ce248f385e108469 (patch) | |
| tree | 6f8120d2bb3187a90ba5e855c87332386141bf63 /src/zig_llvm.cpp | |
| parent | dba12cd693495009ae624393337a04e80b0ea565 (diff) | |
| download | zig-d7968c6d33b054a8293edd89ce248f385e108469.tar.gz zig-d7968c6d33b054a8293edd89ce248f385e108469.zip | |
improvements which allow zig to emit multiple things at once
example: zig build-obj test.zig -femit-llvm-ir -femit-asm
this will generate all three: test.o test.s test.ll
Diffstat (limited to 'src/zig_llvm.cpp')
| -rw-r--r-- | src/zig_llvm.cpp | 101 |
1 files changed, 59 insertions, 42 deletions
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 614d31dc5a..64706500d5 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -161,17 +161,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) { } bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, - const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, - bool is_small, bool time_report) + char **error_message, bool is_debug, + bool is_small, bool time_report, + const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename) { TimePassesIsEnabled = time_report; - std::error_code EC; - raw_fd_ostream dest(filename, EC, sys::fs::F_None); - if (EC) { - *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); - return true; + raw_fd_ostream *dest_asm = nullptr; + raw_fd_ostream *dest_bin = nullptr; + + if (asm_filename) { + std::error_code EC; + dest_asm = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None); + if (EC) { + *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); + return true; + } } + if (bin_filename) { + std::error_code EC; + dest_bin = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None); + if (EC) { + *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); + return true; + } + } + TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref); target_machine->setO0WantsFastISel(true); @@ -222,49 +237,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM } PMBuilder->populateFunctionPassManager(FPM); - // Set up the per-module pass manager. - legacy::PassManager MPM; - MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); - PMBuilder->populateModulePassManager(MPM); - - // Set output pass. - TargetMachine::CodeGenFileType ft; - if (output_type != ZigLLVM_EmitLLVMIr) { - switch (output_type) { - case ZigLLVM_EmitAssembly: - ft = TargetMachine::CGFT_AssemblyFile; - break; - case ZigLLVM_EmitBinary: - ft = TargetMachine::CGFT_ObjectFile; - break; - default: - abort(); + { + // Set up the per-module pass manager. + legacy::PassManager MPM; + MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); + PMBuilder->populateModulePassManager(MPM); + + // Set output passes. + if (dest_bin) { + if (target_machine->addPassesToEmitFile(MPM, *dest_bin, nullptr, TargetMachine::CGFT_ObjectFile)) { + *error_message = strdup("TargetMachine can't emit an object file"); + return true; + } } - - if (target_machine->addPassesToEmitFile(MPM, dest, nullptr, ft)) { - *error_message = strdup("TargetMachine can't emit a file of this type"); - return true; + if (dest_asm) { + if (target_machine->addPassesToEmitFile(MPM, *dest_asm, nullptr, TargetMachine::CGFT_AssemblyFile)) { + *error_message = strdup("TargetMachine can't emit an assembly file"); + return true; + } } - } - // run per function optimization passes - FPM.doInitialization(); - for (Function &F : *module) - if (!F.isDeclaration()) - FPM.run(F); - FPM.doFinalization(); + // run per function optimization passes + FPM.doInitialization(); + for (Function &F : *module) + if (!F.isDeclaration()) + FPM.run(F); + FPM.doFinalization(); - MPM.run(*module); + MPM.run(*module); - if (output_type == ZigLLVM_EmitLLVMIr) { - if (LLVMPrintModuleToFile(module_ref, filename, error_message)) { - return true; + if (llvm_ir_filename) { + if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) { + return true; + } } - } - if (time_report) { - TimerGroup::printAll(errs()); + if (time_report) { + TimerGroup::printAll(errs()); + } + + // MPM goes out of scope and writes to the out streams } + + delete dest_asm; + delete dest_bin; + return false; } |
