[llvm] e551b73 - [LTO][Legacy] Add new API to query Mach-O CPU (sub)type

Francis Visoiu Mistrih via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 28 12:57:49 PST 2020


Author: Francis Visoiu Mistrih
Date: 2020-02-28T12:56:05-08:00
New Revision: e551b737c3c787f770709b9659c68b029e6b92dc

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

LOG: [LTO][Legacy] Add new API to query Mach-O CPU (sub)type

Tools working with object files on Darwin (e.g. lipo) may need to know
properties like the CPU type and subtype of a bitcode file. The logic of
converting a triple to a Mach-O CPU_(SUB_)TYPE should be provided by
LLVM instead of relying on tools to re-implement it.

Differential Revision: https://reviews.llvm.org/D75067

Added: 
    llvm/test/LTO/X86/print-macho-cpu.ll

Modified: 
    llvm/docs/LinkTimeOptimization.rst
    llvm/include/llvm-c/lto.h
    llvm/include/llvm/LTO/legacy/LTOModule.h
    llvm/lib/LTO/LTOModule.cpp
    llvm/test/tools/llvm-lto/error.ll
    llvm/tools/llvm-lto/llvm-lto.cpp
    llvm/tools/lto/lto.cpp
    llvm/tools/lto/lto.exports

Removed: 
    


################################################################################
diff  --git a/llvm/docs/LinkTimeOptimization.rst b/llvm/docs/LinkTimeOptimization.rst
index 010a7881623c..9e0c2cc9f622 100644
--- a/llvm/docs/LinkTimeOptimization.rst
+++ b/llvm/docs/LinkTimeOptimization.rst
@@ -249,6 +249,12 @@ symbols and getting the name and attributes of each symbol via:
 
 The attributes of a symbol include the alignment, visibility, and kind.
 
+Tools working with object files on Darwin (e.g. lipo) may need to know properties like the CPU type:
+
+.. code-block:: c
+
+  lto_module_get_macho_cputype(lto_module_t mod, unsigned int *out_cputype, unsigned int *out_cpusubtype)
+
 ``lto_code_gen_t``
 ------------------
 

diff  --git a/llvm/include/llvm-c/lto.h b/llvm/include/llvm-c/lto.h
index 97a8f4823320..4dbc77f294c6 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 26
+#define LTO_API_VERSION 27
 
 /**
  * \since prior to LTO_API_VERSION=3
@@ -297,6 +297,21 @@ lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index);
 extern const char*
 lto_module_get_linkeropts(lto_module_t mod);
 
+/**
+ * If targeting mach-o on darwin, this function gets the CPU type and subtype
+ * that will end up being encoded in the mach-o header. These are the values
+ * that can be found in mach/machine.h.
+ *
+ * \p out_cputype and \p out_cpusubtype must be non-NULL.
+ *
+ * Returns true on error (check lto_get_error_message() for details).
+ *
+ * \since LTO_API_VERSION=27
+ */
+extern lto_bool_t lto_module_get_macho_cputype(lto_module_t mod,
+                                               unsigned int *out_cputype,
+                                               unsigned int *out_cpusubtype);
+
 /**
  * Diagnostic severity.
  *

diff  --git a/llvm/include/llvm/LTO/legacy/LTOModule.h b/llvm/include/llvm/LTO/legacy/LTOModule.h
index 84b9b8c02942..998a4557dd22 100644
--- a/llvm/include/llvm/LTO/legacy/LTOModule.h
+++ b/llvm/include/llvm/LTO/legacy/LTOModule.h
@@ -165,6 +165,10 @@ struct LTOModule {
 
   static const char *getDependentLibrary(lto::InputFile *input, size_t index, size_t *size);
 
+  Expected<uint32_t> getMachOCPUType() const;
+
+  Expected<uint32_t> getMachOCPUSubType() const;
+
 private:
   /// Parse metadata from the module
   // FIXME: it only parses "llvm.linker.options" metadata at the moment

diff  --git a/llvm/lib/LTO/LTOModule.cpp b/llvm/lib/LTO/LTOModule.cpp
index 587b332e7064..0d37e919ff5a 100644
--- a/llvm/lib/LTO/LTOModule.cpp
+++ b/llvm/lib/LTO/LTOModule.cpp
@@ -28,6 +28,7 @@
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/MachO.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
@@ -676,3 +677,11 @@ const char *LTOModule::getDependentLibrary(lto::InputFile *input, size_t index,
   *size = S.size();
   return S.data();
 }
+
+Expected<uint32_t> LTOModule::getMachOCPUType() const {
+  return MachO::getCPUType(Triple(Mod->getTargetTriple()));
+}
+
+Expected<uint32_t> LTOModule::getMachOCPUSubType() const {
+  return MachO::getCPUSubType(Triple(Mod->getTargetTriple()));
+}

diff  --git a/llvm/test/LTO/X86/print-macho-cpu.ll b/llvm/test/LTO/X86/print-macho-cpu.ll
new file mode 100644
index 000000000000..36a209d06eb0
--- /dev/null
+++ b/llvm/test/LTO/X86/print-macho-cpu.ll
@@ -0,0 +1,8 @@
+; RUN: rm -rf %t && mkdir -p %t
+; RUN: llvm-as -o %t/1.bc %s
+; RUN: llvm-lto -print-macho-cpu-only %t/1.bc | FileCheck %s
+
+target triple = "x86_64-apple-darwin"
+; CHECK: 1.bc:
+; CHECK-NEXT: cputype: 16777223
+; CHECK-NEXT: cpusubtype: 3

diff  --git a/llvm/test/tools/llvm-lto/error.ll b/llvm/test/tools/llvm-lto/error.ll
index c4c31d05aba8..e1f9e8813ab3 100644
--- a/llvm/test/tools/llvm-lto/error.ll
+++ b/llvm/test/tools/llvm-lto/error.ll
@@ -7,5 +7,8 @@
 ; RUN: not llvm-lto --list-dependent-libraries-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-LIBS
 ; CHECK-LIBS: llvm-lto: {{.*}}/Inputs/empty.bc: Could not read LTO input file: The file was not recognized as a valid object file
 
+; RUN: not llvm-lto --print-macho-cpu-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-MACHO
+; CHECK-MACHO: llvm-lto: error: The file was not recognized as a valid object file
+
 ; RUN: not llvm-lto --thinlto %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-THIN
 ; CHECK-THIN: llvm-lto: error loading file '{{.*}}/Inputs/empty.bc': file too small to contain bitcode header

diff  --git a/llvm/tools/llvm-lto/llvm-lto.cpp b/llvm/tools/llvm-lto/llvm-lto.cpp
index 12851799f336..af3fa0acc39c 100644
--- a/llvm/tools/llvm-lto/llvm-lto.cpp
+++ b/llvm/tools/llvm-lto/llvm-lto.cpp
@@ -223,6 +223,10 @@ static cl::opt<bool> CheckHasObjC(
     "check-for-objc", cl::init(false),
     cl::desc("Only check if the module has objective-C defined in it"));
 
+static cl::opt<bool> PrintMachOCPUOnly(
+    "print-macho-cpu-only", cl::init(false),
+    cl::desc("Instead of running LTO, print the mach-o cpu in each IR file"));
+
 namespace {
 
 struct ModuleInfo {
@@ -404,6 +408,30 @@ static void listDependentLibraries() {
   }
 }
 
+static void printMachOCPUOnly() {
+  LLVMContext Context;
+  Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
+                               true);
+  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  for (auto &Filename : InputFilenames) {
+    ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
+        LTOModule::createFromFile(Context, Filename, Options);
+    if (!ModuleOrErr)
+      error(ModuleOrErr, "llvm-lto: ");
+
+    Expected<uint32_t> CPUType = (*ModuleOrErr)->getMachOCPUType();
+    Expected<uint32_t> CPUSubType = (*ModuleOrErr)->getMachOCPUSubType();
+    if (!CPUType)
+      error("Error while printing mach-o cputype: " +
+            toString(CPUType.takeError()));
+    if (!CPUSubType)
+      error("Error while printing mach-o cpusubtype: " +
+            toString(CPUSubType.takeError()));
+    outs() << llvm::format("%s:\ncputype: %u\ncpusubtype: %u\n",
+                           Filename.c_str(), *CPUType, *CPUSubType);
+  }
+}
+
 /// Create a combined index file from the input IR files and write it.
 ///
 /// This is meant to enable testing of ThinLTO combined index generation,
@@ -905,6 +933,11 @@ int main(int argc, char **argv) {
     return 0;
   }
 
+  if (PrintMachOCPUOnly) {
+    printMachOCPUOnly();
+    return 0;
+  }
+
   if (ThinLTOMode.getNumOccurrences()) {
     if (ThinLTOMode.getNumOccurrences() > 1)
       report_fatal_error("You can't specify more than one -thinlto-action");

diff  --git a/llvm/tools/lto/lto.cpp b/llvm/tools/lto/lto.cpp
index 9933af94de1e..683c2b2ae300 100644
--- a/llvm/tools/lto/lto.cpp
+++ b/llvm/tools/lto/lto.cpp
@@ -327,6 +327,27 @@ const char* lto_module_get_linkeropts(lto_module_t mod) {
   return unwrap(mod)->getLinkerOpts().data();
 }
 
+lto_bool_t lto_module_get_macho_cputype(lto_module_t mod,
+                                        unsigned int *out_cputype,
+                                        unsigned int *out_cpusubtype) {
+  LTOModule *M = unwrap(mod);
+  Expected<uint32_t> CPUType = M->getMachOCPUType();
+  if (!CPUType) {
+    sLastErrorString = toString(CPUType.takeError());
+    return true;
+  }
+  *out_cputype = *CPUType;
+
+  Expected<uint32_t> CPUSubType = M->getMachOCPUSubType();
+  if (!CPUSubType) {
+    sLastErrorString = toString(CPUSubType.takeError());
+    return true;
+  }
+  *out_cpusubtype = *CPUSubType;
+
+  return false;
+}
+
 void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
                                         lto_diagnostic_handler_t diag_handler,
                                         void *ctxt) {

diff  --git a/llvm/tools/lto/lto.exports b/llvm/tools/lto/lto.exports
index fd2212cb5f33..1f0a6b23d3fd 100644
--- a/llvm/tools/lto/lto.exports
+++ b/llvm/tools/lto/lto.exports
@@ -9,6 +9,7 @@ lto_module_create_from_memory_with_path
 lto_module_create_in_local_context
 lto_module_create_in_codegen_context
 lto_module_get_linkeropts
+lto_module_get_macho_cputype
 lto_module_get_num_symbols
 lto_module_get_symbol_attribute
 lto_module_get_symbol_name


        


More information about the llvm-commits mailing list