diff --git a/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h b/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h --- a/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h +++ b/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h @@ -213,6 +213,9 @@ bool determineTarget(); std::unique_ptr createTargetMachine(); + bool useAIXSystemAssembler(); + bool runAIXSystemAssembler(SmallString<128> &AssemblyFile); + void emitError(const std::string &ErrMsg); void emitWarning(const std::string &ErrMsg); diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -51,6 +51,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" @@ -114,6 +115,11 @@ "lto-stats-file", cl::desc("Save statistics to the specified file"), cl::Hidden); + +cl::opt AIXSystemAssemblerPath( + "lto-aix-system-assembler", + cl::desc("Absolute path to the system assembler, picked up on AIX only"), + cl::value_desc("path")); } LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context) @@ -237,7 +243,61 @@ return true; } +bool LTOCodeGenerator::useAIXSystemAssembler() { + const auto &Triple = TargetMach->getTargetTriple(); + return Triple.isOSAIX(); +} + +bool LTOCodeGenerator::runAIXSystemAssembler(SmallString<128> &AssemblyFile) { + assert(useAIXSystemAssembler() && + "Runing AIX system assembler when integrated assembler is available!"); + + // Set the system assembler path. + std::string AssemblerPath(llvm::AIXSystemAssemblerPath.empty() + ? "/usr/bin/as" + : llvm::AIXSystemAssemblerPath.c_str()); + + // Prepare inputs for the assember. + const auto &Triple = TargetMach->getTargetTriple(); + const char *Arch = Triple.isArch64Bit() ? "-a64" : "-a32"; + std::string ObjectFileName(AssemblyFile); + ObjectFileName[ObjectFileName.size() - 1] = 'o'; + SmallVector Args = { + "/bin/env", "LDR_CNTRL=MAXDATA32=0x80000000@${LDR_CNTRL}", + AssemblerPath, Arch, + "-many", "-o", + ObjectFileName, AssemblyFile}; + + // Invoke the assembler. + int RC = sys::ExecuteAndWait(Args[0], Args); + + // Handle errors. + if (RC < -1) { + emitError("LTO assembler exited abnormally"); + return false; + } + if (RC < 0) { + emitError("Unable to invoke LTO assembler"); + return false; + } + if (RC > 0) { + emitError("LTO assembler invocation returned non-zero"); + return false; + } + + // Cleanup. + remove(AssemblyFile.c_str()); + + // Fix the output file name. + AssemblyFile = ObjectFileName; + + return true; +} + bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) { + if (useAIXSystemAssembler()) + setFileType(CGFT_AssemblyFile); + // make unique temp output file to put generated code SmallString<128> Filename; @@ -268,6 +328,10 @@ else if (AreStatisticsEnabled()) PrintStatistics(); + if (useAIXSystemAssembler()) + if (!runAIXSystemAssembler(Filename)) + return false; + NativeObjectPath = Filename.c_str(); *Name = NativeObjectPath.c_str(); return true; diff --git a/llvm/test/tools/llvm-lto/aix.ll b/llvm/test/tools/llvm-lto/aix.ll --- a/llvm/test/tools/llvm-lto/aix.ll +++ b/llvm/test/tools/llvm-lto/aix.ll @@ -1,4 +1,4 @@ -; REQUIRES: powerpc-registered-target +; REQUIRES: system-aix ; RUN: llvm-as < %s > %t1 ; RUN: llvm-lto %t1 | FileCheck %s