Index: llvm/include/llvm-c/lto.h =================================================================== --- llvm/include/llvm-c/lto.h +++ llvm/include/llvm-c/lto.h @@ -46,7 +46,7 @@ * @{ */ -#define LTO_API_VERSION 27 +#define LTO_API_VERSION 28 /** * \since prior to LTO_API_VERSION=3 @@ -527,7 +527,24 @@ lto_api_version(void); /** - * Sets options to help debug codegen bugs. + * Parses options immediately, making them available as early as possible. For + * example during executing codegen::InitTargetOptionsFromCodeGenFlags. Since + * parsing shud only happen once, only one of lto_codegen_debug_options or + * lto_codegen_debug_options_early should be called. + * + * This function takes one or more options separated by spaces. + * Warning: passing file paths through this function may confuse the argument + * parser if the paths contain spaces. + * + * \since LTO_API_VERSION=28 + */ +extern void +lto_codegen_debug_options_early(const char *opt); + +/** + * Sets options to help debug codegen bugs. Since parsing shud only happen once, + * only one of lto_codegen_debug_options or lto_codegen_debug_options_early + * should be called. * * This function takes one or more options separated by spaces. * Warning: passing file paths through this function may confuse the argument Index: llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h =================================================================== --- llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h +++ llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h @@ -240,5 +240,9 @@ lto::Config Config; }; + +/// A convenience function that calls cl::ParseCommandLineOptions on the given +/// set of options. +void parseCommandLineOptions(std::vector &Options); } #endif Index: llvm/lib/LTO/LTOCodeGenerator.cpp =================================================================== --- llvm/lib/LTO/LTOCodeGenerator.cpp +++ llvm/lib/LTO/LTOCodeGenerator.cpp @@ -598,11 +598,16 @@ } void LTOCodeGenerator::parseCodeGenDebugOptions() { + if (!CodegenOptions.empty()) + llvm::parseCommandLineOptions(CodegenOptions); +} + +void llvm::parseCommandLineOptions(std::vector &Options) { // if options were requested, set them - if (!CodegenOptions.empty()) { + if (!Options.empty()) { // ParseCommandLineOptions() expects argv[0] to be program name. std::vector CodegenArgv(1, "libLLVMLTO"); - for (std::string &Arg : CodegenOptions) + for (std::string &Arg : Options) CodegenArgv.push_back(Arg.c_str()); cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data()); } Index: llvm/tools/lto/lto.cpp =================================================================== --- llvm/tools/lto/lto.cpp +++ llvm/tools/lto/lto.cpp @@ -66,6 +66,9 @@ // Holds the command-line option parsing state of the LTO module. static bool parsedOptions = false; +// Set to true if options were parsed early. +static bool parsedOptionsEarly = false; + static LLVMContext *LTOContext = nullptr; struct LTOToolDiagnosticHandler : public DiagnosticHandler { @@ -460,7 +463,22 @@ return !unwrap(cg)->compile_to_file(name); } +void lto_codegen_debug_options_early(const char *opt) { + if (opt) { + // Need to put each suboption in a null-terminated string before passing to + // parseCommandLineOptions(). + std::vector Options; + for (std::pair o = getToken(opt); !o.first.empty(); + o = getToken(o.second)) + Options.push_back(o.first.str()); + + llvm::parseCommandLineOptions(Options); + parsedOptionsEarly = true; + } +} + void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) { + assert(!parsedOptionsEarly && "early option processing already happened"); SmallVector Options; for (std::pair o = getToken(opt); !o.first.empty(); o = getToken(o.second))