aboutsummaryrefslogtreecommitdiffstats
path: root/qv4isel_llvm.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2012-10-18 11:07:10 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-10-18 12:00:05 +0200
commit3fd7a3a8e9bb3c42c1ecb954d99ee3b4218c011e (patch)
tree7244afed74e89708c193bdec81b38c2f080ab17a /qv4isel_llvm.cpp
parent4dfe770add60b91ccd799d53a6af73be1072876d (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.cpp118
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();