1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[LTO][Legacy] Decouple option parsing from LTOCodeGenerator

in this patch we add a new libLTO API to specify debug options independent of an lto_code_gen_t.
This allows clients to pass codegen flags (through libLTO) which otherwise today are ignored.

Reviewed By: steven_wu

Differential Revision: https://reviews.llvm.org/D92611
This commit is contained in:
Wael Yehia 2021-03-31 16:42:12 +00:00 committed by Jinsong Ji
parent c662f4964b
commit 1925a6cfe8
5 changed files with 56 additions and 10 deletions

View File

@ -46,7 +46,7 @@ typedef bool lto_bool_t;
* @{ * @{
*/ */
#define LTO_API_VERSION 27 #define LTO_API_VERSION 28
/** /**
* \since prior to LTO_API_VERSION=3 * \since prior to LTO_API_VERSION=3
@ -527,7 +527,23 @@ extern unsigned int
lto_api_version(void); 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_set_debug_options 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_set_debug_options(const char *const *options, int number);
/**
* Sets options to help debug codegen bugs. Since parsing shud only happen once,
* only one of lto_codegen_debug_options or lto_set_debug_options
* should be called.
* *
* This function takes one or more options separated by spaces. * This function takes one or more options separated by spaces.
* Warning: passing file paths through this function may confuse the argument * Warning: passing file paths through this function may confuse the argument

View File

@ -240,5 +240,9 @@ private:
lto::Config Config; lto::Config Config;
}; };
/// A convenience function that calls cl::ParseCommandLineOptions on the given
/// set of options.
void parseCommandLineOptions(std::vector<std::string> &Options);
} }
#endif #endif

View File

@ -598,17 +598,20 @@ void LTOCodeGenerator::setCodeGenDebugOptions(ArrayRef<StringRef> Options) {
} }
void LTOCodeGenerator::parseCodeGenDebugOptions() { void LTOCodeGenerator::parseCodeGenDebugOptions() {
// if options were requested, set them if (!CodegenOptions.empty())
if (!CodegenOptions.empty()) { llvm::parseCommandLineOptions(CodegenOptions);
}
void llvm::parseCommandLineOptions(std::vector<std::string> &Options) {
if (!Options.empty()) {
// ParseCommandLineOptions() expects argv[0] to be program name. // ParseCommandLineOptions() expects argv[0] to be program name.
std::vector<const char *> CodegenArgv(1, "libLLVMLTO"); std::vector<const char *> CodegenArgv(1, "libLLVMLTO");
for (std::string &Arg : CodegenOptions) for (std::string &Arg : Options)
CodegenArgv.push_back(Arg.c_str()); CodegenArgv.push_back(Arg.c_str());
cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data()); cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data());
} }
} }
void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) { void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) {
// Map the LLVM internal diagnostic severity to the LTO diagnostic severity. // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
lto_codegen_diagnostic_severity_t Severity; lto_codegen_diagnostic_severity_t Severity;

View File

@ -63,8 +63,12 @@ static std::string sLastErrorString;
// *** Not thread safe *** // *** Not thread safe ***
static bool initialized = false; static bool initialized = false;
// Holds the command-line option parsing state of the LTO module. // Represent the state of parsing command line debug options.
static bool parsedOptions = false; static enum class OptParsingState {
NotParsed, // Initial state.
Early, // After lto_set_debug_options is called.
Done // After maybeParseOptions is called.
} optionParsingState = OptParsingState::NotParsed;
static LLVMContext *LTOContext = nullptr; static LLVMContext *LTOContext = nullptr;
@ -418,10 +422,11 @@ void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg,
} }
static void maybeParseOptions(lto_code_gen_t cg) { static void maybeParseOptions(lto_code_gen_t cg) {
if (!parsedOptions) { if (optionParsingState != OptParsingState::Done) {
// Parse options if any were set by the lto_codegen_debug_options* function.
unwrap(cg)->parseCodeGenDebugOptions(); unwrap(cg)->parseCodeGenDebugOptions();
lto_add_attrs(cg); lto_add_attrs(cg);
parsedOptions = true; optionParsingState = OptParsingState::Done;
} }
} }
@ -460,7 +465,22 @@ bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
return !unwrap(cg)->compile_to_file(name); return !unwrap(cg)->compile_to_file(name);
} }
void lto_set_debug_options(const char *const *options, int number) {
assert(optionParsingState == OptParsingState::NotParsed &&
"option processing already happened");
// Need to put each suboption in a null-terminated string before passing to
// parseCommandLineOptions().
std::vector<std::string> Options;
for (int i = 0; i < number; ++i)
Options.push_back(options[i]);
llvm::parseCommandLineOptions(Options);
optionParsingState = OptParsingState::Early;
}
void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) { void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
assert(optionParsingState != OptParsingState::Early &&
"early option processing already happened");
SmallVector<StringRef, 4> Options; SmallVector<StringRef, 4> Options;
for (std::pair<StringRef, StringRef> o = getToken(opt); !o.first.empty(); for (std::pair<StringRef, StringRef> o = getToken(opt); !o.first.empty();
o = getToken(o.second)) o = getToken(o.second))
@ -471,6 +491,8 @@ void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
void lto_codegen_debug_options_array(lto_code_gen_t cg, void lto_codegen_debug_options_array(lto_code_gen_t cg,
const char *const *options, int number) { const char *const *options, int number) {
assert(optionParsingState != OptParsingState::Early &&
"early option processing already happened");
SmallVector<StringRef, 4> Options; SmallVector<StringRef, 4> Options;
for (int i = 0; i < number; ++i) for (int i = 0; i < number; ++i)
Options.push_back(options[i]); Options.push_back(options[i]);

View File

@ -43,6 +43,7 @@ lto_codegen_optimize
lto_codegen_compile_optimized lto_codegen_compile_optimized
lto_codegen_set_should_internalize lto_codegen_set_should_internalize
lto_codegen_set_should_embed_uselists lto_codegen_set_should_embed_uselists
lto_set_debug_options
LLVMCreateDisasm LLVMCreateDisasm
LLVMCreateDisasmCPU LLVMCreateDisasmCPU
LLVMDisasmDispose LLVMDisasmDispose