[llvm] 563cdea - [LTO][Legacy] Decouple option parsing from LTOCodeGenerator

Jinsong Ji via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 31 09:44:18 PDT 2021


Author: Wael Yehia
Date: 2021-03-31T16:43:26Z
New Revision: 563cdeaafd5812cb90656380a8f9d6b85d2abf08

URL: https://github.com/llvm/llvm-project/commit/563cdeaafd5812cb90656380a8f9d6b85d2abf08
DIFF: https://github.com/llvm/llvm-project/commit/563cdeaafd5812cb90656380a8f9d6b85d2abf08.diff

LOG: [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

Added: 
    

Modified: 
    llvm/include/llvm-c/lto.h
    llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
    llvm/lib/LTO/LTOCodeGenerator.cpp
    llvm/tools/lto/lto.cpp
    llvm/tools/lto/lto.exports

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm-c/lto.h b/llvm/include/llvm-c/lto.h
index 4dbc77f294c67..f6fc8588f5f71 100644
--- a/llvm/include/llvm-c/lto.h
+++ b/llvm/include/llvm-c/lto.h
@@ -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
@@ -527,7 +527,23 @@ extern unsigned int
 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.
  * Warning: passing file paths through this function may confuse the argument

diff  --git a/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h b/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
index 46c01f233a9c2..31688e43e1747 100644
--- a/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
+++ b/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
@@ -240,5 +240,9 @@ struct LTOCodeGenerator {
 
   lto::Config Config;
 };
+
+/// A convenience function that calls cl::ParseCommandLineOptions on the given
+/// set of options.
+void parseCommandLineOptions(std::vector<std::string> &Options);
 }
 #endif

diff  --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp
index 8e5587051c26f..7bffcbf01b03a 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -598,17 +598,20 @@ void LTOCodeGenerator::setCodeGenDebugOptions(ArrayRef<StringRef> Options) {
 }
 
 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.
     std::vector<const char *> 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());
   }
 }
 
-
 void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI) {
   // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
   lto_codegen_diagnostic_severity_t Severity;

diff  --git a/llvm/tools/lto/lto.cpp b/llvm/tools/lto/lto.cpp
index e88cb473e95b9..2a560a0d5e83e 100644
--- a/llvm/tools/lto/lto.cpp
+++ b/llvm/tools/lto/lto.cpp
@@ -63,8 +63,12 @@ static std::string sLastErrorString;
 // *** Not thread safe ***
 static bool initialized = false;
 
-// Holds the command-line option parsing state of the LTO module.
-static bool parsedOptions = false;
+// Represent the state of parsing command line debug options.
+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;
 
@@ -418,10 +422,11 @@ void lto_codegen_add_must_preserve_symbol(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();
     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);
 }
 
+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) {
+  assert(optionParsingState != OptParsingState::Early &&
+         "early option processing already happened");
   SmallVector<StringRef, 4> Options;
   for (std::pair<StringRef, StringRef> o = getToken(opt); !o.first.empty();
        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,
                                      const char *const *options, int number) {
+  assert(optionParsingState != OptParsingState::Early &&
+         "early option processing already happened");
   SmallVector<StringRef, 4> Options;
   for (int i = 0; i < number; ++i)
     Options.push_back(options[i]);

diff  --git a/llvm/tools/lto/lto.exports b/llvm/tools/lto/lto.exports
index 1f0a6b23d3fd8..1948bba29b67e 100644
--- a/llvm/tools/lto/lto.exports
+++ b/llvm/tools/lto/lto.exports
@@ -43,6 +43,7 @@ lto_codegen_optimize
 lto_codegen_compile_optimized
 lto_codegen_set_should_internalize
 lto_codegen_set_should_embed_uselists
+lto_set_debug_options
 LLVMCreateDisasm
 LLVMCreateDisasmCPU
 LLVMDisasmDispose


        


More information about the llvm-commits mailing list