Skip to content

Commit e551b73

Browse files
committed
[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
1 parent 67c1615 commit e551b73

File tree

9 files changed

+101
-1
lines changed

9 files changed

+101
-1
lines changed

llvm/docs/LinkTimeOptimization.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ symbols and getting the name and attributes of each symbol via:
249249
250250
The attributes of a symbol include the alignment, visibility, and kind.
251251

252+
Tools working with object files on Darwin (e.g. lipo) may need to know properties like the CPU type:
253+
254+
.. code-block:: c
255+
256+
lto_module_get_macho_cputype(lto_module_t mod, unsigned int *out_cputype, unsigned int *out_cpusubtype)
257+
252258
``lto_code_gen_t``
253259
------------------
254260

llvm/include/llvm-c/lto.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ typedef bool lto_bool_t;
4646
* @{
4747
*/
4848

49-
#define LTO_API_VERSION 26
49+
#define LTO_API_VERSION 27
5050

5151
/**
5252
* \since prior to LTO_API_VERSION=3
@@ -297,6 +297,21 @@ lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index);
297297
extern const char*
298298
lto_module_get_linkeropts(lto_module_t mod);
299299

300+
/**
301+
* If targeting mach-o on darwin, this function gets the CPU type and subtype
302+
* that will end up being encoded in the mach-o header. These are the values
303+
* that can be found in mach/machine.h.
304+
*
305+
* \p out_cputype and \p out_cpusubtype must be non-NULL.
306+
*
307+
* Returns true on error (check lto_get_error_message() for details).
308+
*
309+
* \since LTO_API_VERSION=27
310+
*/
311+
extern lto_bool_t lto_module_get_macho_cputype(lto_module_t mod,
312+
unsigned int *out_cputype,
313+
unsigned int *out_cpusubtype);
314+
300315
/**
301316
* Diagnostic severity.
302317
*

llvm/include/llvm/LTO/legacy/LTOModule.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ struct LTOModule {
165165

166166
static const char *getDependentLibrary(lto::InputFile *input, size_t index, size_t *size);
167167

168+
Expected<uint32_t> getMachOCPUType() const;
169+
170+
Expected<uint32_t> getMachOCPUSubType() const;
171+
168172
private:
169173
/// Parse metadata from the module
170174
// FIXME: it only parses "llvm.linker.options" metadata at the moment

llvm/lib/LTO/LTOModule.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/MC/MCSymbol.h"
2929
#include "llvm/MC/SubtargetFeature.h"
3030
#include "llvm/Object/IRObjectFile.h"
31+
#include "llvm/Object/MachO.h"
3132
#include "llvm/Object/ObjectFile.h"
3233
#include "llvm/Support/FileSystem.h"
3334
#include "llvm/Support/Host.h"
@@ -676,3 +677,11 @@ const char *LTOModule::getDependentLibrary(lto::InputFile *input, size_t index,
676677
*size = S.size();
677678
return S.data();
678679
}
680+
681+
Expected<uint32_t> LTOModule::getMachOCPUType() const {
682+
return MachO::getCPUType(Triple(Mod->getTargetTriple()));
683+
}
684+
685+
Expected<uint32_t> LTOModule::getMachOCPUSubType() const {
686+
return MachO::getCPUSubType(Triple(Mod->getTargetTriple()));
687+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; RUN: rm -rf %t && mkdir -p %t
2+
; RUN: llvm-as -o %t/1.bc %s
3+
; RUN: llvm-lto -print-macho-cpu-only %t/1.bc | FileCheck %s
4+
5+
target triple = "x86_64-apple-darwin"
6+
; CHECK: 1.bc:
7+
; CHECK-NEXT: cputype: 16777223
8+
; CHECK-NEXT: cpusubtype: 3

llvm/test/tools/llvm-lto/error.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@
77
; RUN: not llvm-lto --list-dependent-libraries-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-LIBS
88
; CHECK-LIBS: llvm-lto: {{.*}}/Inputs/empty.bc: Could not read LTO input file: The file was not recognized as a valid object file
99

10+
; RUN: not llvm-lto --print-macho-cpu-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-MACHO
11+
; CHECK-MACHO: llvm-lto: error: The file was not recognized as a valid object file
12+
1013
; RUN: not llvm-lto --thinlto %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-THIN
1114
; CHECK-THIN: llvm-lto: error loading file '{{.*}}/Inputs/empty.bc': file too small to contain bitcode header

llvm/tools/llvm-lto/llvm-lto.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ static cl::opt<bool> CheckHasObjC(
223223
"check-for-objc", cl::init(false),
224224
cl::desc("Only check if the module has objective-C defined in it"));
225225

226+
static cl::opt<bool> PrintMachOCPUOnly(
227+
"print-macho-cpu-only", cl::init(false),
228+
cl::desc("Instead of running LTO, print the mach-o cpu in each IR file"));
229+
226230
namespace {
227231

228232
struct ModuleInfo {
@@ -404,6 +408,30 @@ static void listDependentLibraries() {
404408
}
405409
}
406410

411+
static void printMachOCPUOnly() {
412+
LLVMContext Context;
413+
Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
414+
true);
415+
TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
416+
for (auto &Filename : InputFilenames) {
417+
ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
418+
LTOModule::createFromFile(Context, Filename, Options);
419+
if (!ModuleOrErr)
420+
error(ModuleOrErr, "llvm-lto: ");
421+
422+
Expected<uint32_t> CPUType = (*ModuleOrErr)->getMachOCPUType();
423+
Expected<uint32_t> CPUSubType = (*ModuleOrErr)->getMachOCPUSubType();
424+
if (!CPUType)
425+
error("Error while printing mach-o cputype: " +
426+
toString(CPUType.takeError()));
427+
if (!CPUSubType)
428+
error("Error while printing mach-o cpusubtype: " +
429+
toString(CPUSubType.takeError()));
430+
outs() << llvm::format("%s:\ncputype: %u\ncpusubtype: %u\n",
431+
Filename.c_str(), *CPUType, *CPUSubType);
432+
}
433+
}
434+
407435
/// Create a combined index file from the input IR files and write it.
408436
///
409437
/// This is meant to enable testing of ThinLTO combined index generation,
@@ -905,6 +933,11 @@ int main(int argc, char **argv) {
905933
return 0;
906934
}
907935

936+
if (PrintMachOCPUOnly) {
937+
printMachOCPUOnly();
938+
return 0;
939+
}
940+
908941
if (ThinLTOMode.getNumOccurrences()) {
909942
if (ThinLTOMode.getNumOccurrences() > 1)
910943
report_fatal_error("You can't specify more than one -thinlto-action");

llvm/tools/lto/lto.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,27 @@ const char* lto_module_get_linkeropts(lto_module_t mod) {
327327
return unwrap(mod)->getLinkerOpts().data();
328328
}
329329

330+
lto_bool_t lto_module_get_macho_cputype(lto_module_t mod,
331+
unsigned int *out_cputype,
332+
unsigned int *out_cpusubtype) {
333+
LTOModule *M = unwrap(mod);
334+
Expected<uint32_t> CPUType = M->getMachOCPUType();
335+
if (!CPUType) {
336+
sLastErrorString = toString(CPUType.takeError());
337+
return true;
338+
}
339+
*out_cputype = *CPUType;
340+
341+
Expected<uint32_t> CPUSubType = M->getMachOCPUSubType();
342+
if (!CPUSubType) {
343+
sLastErrorString = toString(CPUSubType.takeError());
344+
return true;
345+
}
346+
*out_cpusubtype = *CPUSubType;
347+
348+
return false;
349+
}
350+
330351
void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
331352
lto_diagnostic_handler_t diag_handler,
332353
void *ctxt) {

llvm/tools/lto/lto.exports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ lto_module_create_from_memory_with_path
99
lto_module_create_in_local_context
1010
lto_module_create_in_codegen_context
1111
lto_module_get_linkeropts
12+
lto_module_get_macho_cputype
1213
lto_module_get_num_symbols
1314
lto_module_get_symbol_attribute
1415
lto_module_get_symbol_name

0 commit comments

Comments
 (0)