diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2012-10-18 11:07:10 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-18 12:00:05 +0200 |
commit | 3fd7a3a8e9bb3c42c1ecb954d99ee3b4218c011e (patch) | |
tree | 7244afed74e89708c193bdec81b38c2f080ab17a /qv4isel_llvm.cpp | |
parent | 4dfe770add60b91ccd799d53a6af73be1072876d (diff) |
Moved LLVM specific code out of main.cpp.
Change-Id: I16c79667625d5034acb91cec13c22ed58b74984f
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'qv4isel_llvm.cpp')
-rw-r--r-- | qv4isel_llvm.cpp | 118 |
1 files changed, 110 insertions, 8 deletions
diff --git a/qv4isel_llvm.cpp b/qv4isel_llvm.cpp index c2cc4c1d2a..f6e79c963a 100644 --- a/qv4isel_llvm.cpp +++ b/qv4isel_llvm.cpp @@ -39,16 +39,117 @@ ** ****************************************************************************/ -#include "qv4isel_llvm_p.h" -#include "qv4ir_p.h" - -#include <QtCore/QTextStream> +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunused-parameter" +#endif // __clang__ -#include <llvm/Support/system_error.h> -#include <llvm/Support/MemoryBuffer.h> +#include <llvm/Analysis/Passes.h> +#include <llvm/Assembly/PrintModulePass.h> #include <llvm/Bitcode/ReaderWriter.h> +#include <llvm/PassManager.h> +#include <llvm/Support/FormattedStream.h> +#include <llvm/Support/Host.h> +#include <llvm/Support/MemoryBuffer.h> +#include <llvm/Support/raw_ostream.h> +#include <llvm/Support/system_error.h> +#include <llvm/Support/TargetRegistry.h> +#include <llvm/Support/TargetSelect.h> +#include <llvm/Target/TargetMachine.h> +#include <llvm/Target/TargetData.h> +#include <llvm/Transforms/Scalar.h> +#include <llvm/Transforms/IPO.h> #include <llvm/Linker.h> + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif // __clang__ + +#include <QtCore/QFileInfo> +#include <QtCore/QLibrary> +#include <QtCore/QStringList> +#include <QtCore/QTextStream> #include <cstdio> +#include <iostream> + +// These includes have to come last, because WTF/Platform.h defines some macros +// with very unfriendly names that collide with class fields in LLVM. +#include "qv4isel_llvm_p.h" +#include "qv4ir_p.h" + +namespace QQmlJS { + +void compileWithLLVM(IR::Module *module, const QString &fileName) +{ + Q_ASSERT(module); + + const QString moduleName = QFileInfo(fileName).fileName(); + + LLVMInstructionSelection llvmIsel(llvm::getGlobalContext()); + llvm::Module *llvmModule = llvmIsel.getLLVMModule(module, moduleName); + if (!llvmModule) + return; + + // TODO: if output type is .ll, print the module to file + + llvm::PassManager PM; + + const std::string triple = llvm::sys::getDefaultTargetTriple(); + + LLVMInitializeX86TargetInfo(); + LLVMInitializeX86Target(); + LLVMInitializeX86AsmPrinter(); + LLVMInitializeX86AsmParser(); + LLVMInitializeX86Disassembler(); + LLVMInitializeX86TargetMC(); + + std::string err; + const llvm::Target *target = llvm::TargetRegistry::lookupTarget(triple, err); + if (! err.empty()) { + std::cerr << err << ", triple: " << triple << std::endl; + assert(!"cannot create target for the host triple"); + } + + std::string cpu; + std::string features; + llvm::TargetOptions options; + llvm::TargetMachine *targetMachine = target->createTargetMachine(triple, cpu, features, options, llvm::Reloc::PIC_); + assert(targetMachine); + + llvm::TargetMachine::CodeGenFileType ft; + QString ofName; + + ft = llvm::TargetMachine::CGFT_ObjectFile; + ofName = fileName + QLatin1String(".o"); + + // TODO: +// ft = llvm::TargetMachine::CGFT_AssemblyFile; +// ofName = fileName + QLatin1String(".s"); + + llvm::raw_fd_ostream dest(ofName.toUtf8().constData(), err, llvm::raw_fd_ostream::F_Binary); + llvm::formatted_raw_ostream destf(dest); + if (!err.empty()) { + std::cerr << err << std::endl; + delete llvmModule; + } + + PM.add(llvm::createScalarReplAggregatesPass()); + PM.add(llvm::createInstructionCombiningPass()); + PM.add(llvm::createGlobalOptimizerPass()); + PM.add(llvm::createFunctionInliningPass(25)); + if (targetMachine->addPassesToEmitFile(PM, destf, ft)) { + std::cerr << err << " (probably no DataLayout in TargetMachine)" << std::endl; + } else { + PM.run(*llvmModule); + + destf.flush(); + dest.flush(); + } + + delete llvmModule; +} + +} // QQmlJS using namespace QQmlJS; @@ -72,9 +173,10 @@ LLVMInstructionSelection::LLVMInstructionSelection(llvm::LLVMContext &context) { } -llvm::Module *LLVMInstructionSelection::getLLVMModule(IR::Module *module) +llvm::Module *LLVMInstructionSelection::getLLVMModule(IR::Module *module, const QString &moduleName) { - llvm::Module *llvmModule = new llvm::Module("a.out", getContext()); + llvm::StringRef moduleId(moduleName.toUtf8().constData()); + llvm::Module *llvmModule = new llvm::Module(moduleId, getContext()); qSwap(_llvmModule, llvmModule); _numberTy = getDoubleTy(); |