#include "LTOModule.h"
#include "LTOCodeGenerator.h"
-
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Analysis/LoopPass.h"
-#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/CodeGen/FileWriters.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Target/SubtargetFeature.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Target/TargetSelect.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/System/Host.h"
+#include "llvm/System/Program.h"
#include "llvm/System/Signals.h"
-#include "llvm/Target/SubtargetFeature.h"
-#include "llvm/Target/TargetOptions.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetSelect.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/Scalar.h"
#include "llvm/Config/config.h"
-
-
#include <cstdlib>
-#include <fstream>
#include <unistd.h>
#include <fcntl.h>
}
-bool LTOCodeGenerator::writeMergedModules(const char* path, std::string& errMsg)
-{
- if ( this->determineTarget(errMsg) )
- return true;
+bool LTOCodeGenerator::writeMergedModules(const char *path,
+ std::string &errMsg) {
+ if (determineTarget(errMsg))
+ return true;
- // mark which symbols can not be internalized
- this->applyScopeRestrictions();
+ // mark which symbols can not be internalized
+ applyScopeRestrictions();
- // create output file
- std::ofstream out(path, std::ios_base::out|std::ios::trunc|std::ios::binary);
- if ( out.fail() ) {
- errMsg = "could not open bitcode file for writing: ";
- errMsg += path;
- return true;
- }
-
- // write bitcode to it
- WriteBitcodeToFile(_linker.getModule(), out);
- if ( out.fail() ) {
- errMsg = "could not write bitcode file: ";
- errMsg += path;
- return true;
- }
+ // create output file
+ std::string ErrInfo;
+ raw_fd_ostream Out(path, ErrInfo,
+ raw_fd_ostream::F_Binary);
+ if (!ErrInfo.empty()) {
+ errMsg = "could not open bitcode file for writing: ";
+ errMsg += path;
+ return true;
+ }
- return false;
+ // write bitcode to it
+ WriteBitcodeToFile(_linker.getModule(), Out);
+
+ if (Out.has_error()) {
+ errMsg = "could not write bitcode file: ";
+ errMsg += path;
+ return true;
+ }
+
+ return false;
}
// generate assembly code
bool genResult = false;
{
- raw_fd_ostream asmFD(uniqueAsmPath.c_str(), errMsg,
- raw_fd_ostream::F_Force);
+ raw_fd_ostream asmFD(uniqueAsmPath.c_str(), errMsg);
formatted_raw_ostream asmFile(asmFD);
if (!errMsg.empty())
return NULL;
sys::RemoveFileOnSignal(uniqueObjPath);
// assemble the assembly code
- const std::string& uniqueObjStr = uniqueObjPath.toString();
- bool asmResult = this->assemble(uniqueAsmPath.toString(),
- uniqueObjStr, errMsg);
+ const std::string& uniqueObjStr = uniqueObjPath.str();
+ bool asmResult = this->assemble(uniqueAsmPath.str(), uniqueObjStr, errMsg);
if ( !asmResult ) {
// remove old buffer if compile() called twice
delete _nativeObjectFile;
// build argument list
std::vector<const char*> args;
- std::string targetTriple = _linker.getModule()->getTargetTriple();
+ llvm::Triple targetTriple(_linker.getModule()->getTargetTriple());
+ const char *arch = targetTriple.getArchNameForAssembler();
+
args.push_back(tool.c_str());
- if ( targetTriple.find("darwin") != std::string::npos ) {
+
+ if (targetTriple.getOS() == Triple::Darwin) {
// darwin specific command line options
- if (strncmp(targetTriple.c_str(), "i386-apple-", 11) == 0) {
- args.push_back("-arch");
- args.push_back("i386");
- }
- else if (strncmp(targetTriple.c_str(), "x86_64-apple-", 13) == 0) {
- args.push_back("-arch");
- args.push_back("x86_64");
- }
- else if (strncmp(targetTriple.c_str(), "powerpc-apple-", 14) == 0) {
- args.push_back("-arch");
- args.push_back("ppc");
- }
- else if (strncmp(targetTriple.c_str(), "powerpc64-apple-", 16) == 0) {
- args.push_back("-arch");
- args.push_back("ppc64");
- }
- else if (strncmp(targetTriple.c_str(), "arm-apple-", 10) == 0) {
- args.push_back("-arch");
- args.push_back("arm");
- }
- else if ((strncmp(targetTriple.c_str(), "armv4t-apple-", 13) == 0) ||
- (strncmp(targetTriple.c_str(), "thumbv4t-apple-", 15) == 0)) {
- args.push_back("-arch");
- args.push_back("armv4t");
- }
- else if ((strncmp(targetTriple.c_str(), "armv5-apple-", 12) == 0) ||
- (strncmp(targetTriple.c_str(), "armv5e-apple-", 13) == 0) ||
- (strncmp(targetTriple.c_str(), "thumbv5-apple-", 14) == 0) ||
- (strncmp(targetTriple.c_str(), "thumbv5e-apple-", 15) == 0)) {
- args.push_back("-arch");
- args.push_back("armv5");
- }
- else if ((strncmp(targetTriple.c_str(), "armv6-apple-", 12) == 0) ||
- (strncmp(targetTriple.c_str(), "thumbv6-apple-", 14) == 0)) {
- args.push_back("-arch");
- args.push_back("armv6");
- }
- else if ((strncmp(targetTriple.c_str(), "armv7-apple-", 12) == 0) ||
- (strncmp(targetTriple.c_str(), "thumbv7-apple-", 14) == 0)) {
+ if (arch != NULL) {
args.push_back("-arch");
- args.push_back("armv7");
+ args.push_back(arch);
}
// add -static to assembler command line when code model requires
- if ( (_assemblerPath != NULL) && (_codeModel == LTO_CODEGEN_PIC_MODEL_STATIC) )
+ if ( (_assemblerPath != NULL) &&
+ (_codeModel == LTO_CODEGEN_PIC_MODEL_STATIC) )
args.push_back("-static");
}
if ( needsCompilerOptions ) {
}
// construct LTModule, hand over ownership of module and target
- std::string FeatureStr = getFeatureString(Triple.c_str());
+ const std::string FeatureStr =
+ SubtargetFeatures::getDefaultSubtargetFeatures(llvm::Triple(Triple));
_target = march->createTargetMachine(Triple, FeatureStr);
}
return false;
}
-void LTOCodeGenerator::applyScopeRestrictions()
-{
- if ( !_scopeRestrictionsDone ) {
- Module* mergedModule = _linker.getModule();
-
- // Start off with a verification pass.
- PassManager passes;
- passes.add(createVerifierPass());
-
- // mark which symbols can not be internalized
- if ( !_mustPreserveSymbols.empty() ) {
- Mangler mangler(*mergedModule,
- _target->getMCAsmInfo()->getGlobalPrefix());
- std::vector<const char*> mustPreserveList;
- for (Module::iterator f = mergedModule->begin(),
- e = mergedModule->end(); f != e; ++f) {
- if ( !f->isDeclaration()
- && _mustPreserveSymbols.count(mangler.getMangledName(f)) )
- mustPreserveList.push_back(::strdup(f->getNameStr().c_str()));
- }
- for (Module::global_iterator v = mergedModule->global_begin(),
- e = mergedModule->global_end(); v != e; ++v) {
- if ( !v->isDeclaration()
- && _mustPreserveSymbols.count(mangler.getMangledName(v)) )
- mustPreserveList.push_back(::strdup(v->getNameStr().c_str()));
- }
- passes.add(createInternalizePass(mustPreserveList));
- }
- // apply scope restrictions
- passes.run(*mergedModule);
-
- _scopeRestrictionsDone = true;
+void LTOCodeGenerator::applyScopeRestrictions() {
+ if (_scopeRestrictionsDone) return;
+ Module *mergedModule = _linker.getModule();
+
+ // Start off with a verification pass.
+ PassManager passes;
+ passes.add(createVerifierPass());
+
+ // mark which symbols can not be internalized
+ if (!_mustPreserveSymbols.empty()) {
+ MCContext Context(*_target->getMCAsmInfo());
+ Mangler mangler(Context, *_target->getTargetData());
+ std::vector<const char*> mustPreserveList;
+ for (Module::iterator f = mergedModule->begin(),
+ e = mergedModule->end(); f != e; ++f) {
+ if (!f->isDeclaration() &&
+ _mustPreserveSymbols.count(mangler.getNameWithPrefix(f)))
+ mustPreserveList.push_back(::strdup(f->getNameStr().c_str()));
}
+ for (Module::global_iterator v = mergedModule->global_begin(),
+ e = mergedModule->global_end(); v != e; ++v) {
+ if (!v->isDeclaration() &&
+ _mustPreserveSymbols.count(mangler.getNameWithPrefix(v)))
+ mustPreserveList.push_back(::strdup(v->getNameStr().c_str()));
+ }
+ passes.add(createInternalizePass(mustPreserveList));
+ }
+
+ // apply scope restrictions
+ passes.run(*mergedModule);
+
+ _scopeRestrictionsDone = true;
}
/// Optimize merged modules using various IPO passes
Module* mergedModule = _linker.getModule();
- // If target supports exception handling then enable it now.
- switch (_target->getMCAsmInfo()->getExceptionHandlingType()) {
- case ExceptionHandling::Dwarf:
- llvm::DwarfExceptionHandling = true;
- break;
- case ExceptionHandling::SjLj:
- llvm::SjLjExceptionHandling = true;
- break;
- case ExceptionHandling::None:
- break;
- default:
- assert (0 && "Unknown exception handling model!");
- }
-
// if options were requested, set them
if ( !_codegenOptions.empty() )
cl::ParseCommandLineOptions(_codegenOptions.size(),
- (char**)&_codegenOptions[0]);
+ const_cast<char **>(&_codegenOptions[0]));
// Instantiate the pass manager to organize the passes.
PassManager passes;
// Make sure everything is still good.
passes.add(createVerifierPass());
- FunctionPassManager* codeGenPasses =
- new FunctionPassManager(new ExistingModuleProvider(mergedModule));
+ FunctionPassManager* codeGenPasses = new FunctionPassManager(mergedModule);
codeGenPasses->add(new TargetData(*_target->getTargetData()));
- ObjectCodeEmitter* oce = NULL;
-
- switch (_target->addPassesToEmitFile(*codeGenPasses, out,
- TargetMachine::AssemblyFile,
- CodeGenOpt::Aggressive)) {
- case FileModel::MachOFile:
- oce = AddMachOWriter(*codeGenPasses, out, *_target);
- break;
- case FileModel::ElfFile:
- oce = AddELFWriter(*codeGenPasses, out, *_target);
- break;
- case FileModel::AsmFile:
- break;
- case FileModel::Error:
- case FileModel::None:
- errMsg = "target file type not supported";
- return true;
- }
-
- if (_target->addPassesToEmitFileFinish(*codeGenPasses, oce,
- CodeGenOpt::Aggressive)) {
- errMsg = "target does not support generation of this file type";
- return true;
+ if (_target->addPassesToEmitFile(*codeGenPasses, out,
+ TargetMachine::CGFT_AssemblyFile,
+ CodeGenOpt::Aggressive)) {
+ errMsg = "target file type not supported";
+ return true;
}
// Run our queue of passes all at once now, efficiently.
codeGenPasses->doFinalization();
- out.flush();
-
return false; // success
}
/// Optimize merged modules using various IPO passes
void LTOCodeGenerator::setCodeGenDebugOptions(const char* options)
{
- std::string ops(options);
- for (std::string o = getToken(ops); !o.empty(); o = getToken(ops)) {
+ for (std::pair<StringRef, StringRef> o = getToken(options);
+ !o.first.empty(); o = getToken(o.second)) {
// ParseCommandLineOptions() expects argv[0] to be program name.
// Lazily add that.
if ( _codegenOptions.empty() )
_codegenOptions.push_back("libLTO");
- _codegenOptions.push_back(strdup(o.c_str()));
+ _codegenOptions.push_back(strdup(o.first.str().c_str()));
}
}