diff options
author | Lars Knoll <[email protected]> | 2013-08-08 08:58:48 +0200 |
---|---|---|
committer | The Qt Project <[email protected]> | 2013-08-08 12:22:26 +0200 |
commit | 2d9262a4c6680e3818bf7c07a4d1cfa32b4c9dfe (patch) | |
tree | 04cce0c4ba54267fa7924ad43f8fcb40e6a83bd5 /src | |
parent | aa6f324c0cea89238c4f557cf00d49ddc8acc4a9 (diff) |
Remove the llvm isel backend
This code never worked.
Change-Id: I0fd7421ae983f3ad43e84e5d7579cdbb610ab2b2
Reviewed-by: Simon Hausmann <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/v4/llvm_installation.pri | 23 | ||||
-rw-r--r-- | src/qml/qml/v4/llvm_runtime.cpp | 513 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4_llvm_p.h | 65 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4isel_llvm.cpp | 1388 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4isel_llvm_p.h | 178 | ||||
-rw-r--r-- | src/qml/qml/v4/v4.pri | 37 |
6 files changed, 0 insertions, 2204 deletions
diff --git a/src/qml/qml/v4/llvm_installation.pri b/src/qml/qml/v4/llvm_installation.pri deleted file mode 100644 index 99e955fd2b..0000000000 --- a/src/qml/qml/v4/llvm_installation.pri +++ /dev/null @@ -1,23 +0,0 @@ -LLVM_CONFIG=llvm-config -# Pick up the qmake variable or environment variable for LLVM_INSTALL_DIR. If either was set, change the LLVM_CONFIG to use that. -isEmpty(LLVM_INSTALL_DIR):LLVM_INSTALL_DIR=$$(LLVM_INSTALL_DIR) -!isEmpty(LLVM_INSTALL_DIR):LLVM_CONFIG=$$LLVM_INSTALL_DIR/bin/llvm-config -exists ($${LLVM_CONFIG}) { - CONFIG += llvm-libs - message("Found LLVM in $$LLVM_INSTALL_DIR") -} - -llvm-libs { - win32 { - LLVM_INCLUDEPATH = $$LLVM_INSTALL_DIR/include -# TODO: check if the next line is needed somehow for the llvm_runtime target. - LLVM_LIBS += -ladvapi32 -lshell32 - } - - unix { - LLVM_INCLUDEPATH = $$system($$LLVM_CONFIG --includedir) - LLVM_LIBDIR = $$system($$LLVM_CONFIG --libdir) - } - - LLVM_DEFINES += __STDC_LIMIT_MACROS __STDC_CONSTANT_MACROS -} diff --git a/src/qml/qml/v4/llvm_runtime.cpp b/src/qml/qml/v4/llvm_runtime.cpp deleted file mode 100644 index 032ef82ab8..0000000000 --- a/src/qml/qml/v4/llvm_runtime.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv4runtime_p.h" -#include "qv4context_p.h" -#include "qv4engine_p.h" -#include <stdio.h> -#include <setjmp.h> - -using namespace QV4; - -extern "C" { - -Value __qmljs_llvm_return(ExecutionContext */*ctx*/, Value *result) -{ - return *result; -} - -Value *__qmljs_llvm_get_argument(ExecutionContext *ctx, int index) -{ - assert(ctx->type == ExecutionContext::Type_CallContext); - return &static_cast<CallContext *>(ctx)->arguments[index]; -} - -void __qmljs_llvm_init_undefined(Value *result) -{ - *result = Value::undefinedValue(); -} - -void __qmljs_llvm_init_null(Value *result) -{ - *result = Value::nullValue(); -} - -void __qmljs_llvm_init_boolean(Value *result, bool value) -{ - *result = Value::fromBoolean(value); -} - -void __qmljs_llvm_init_number(Value *result, double value) -{ - *result = Value::fromDouble(value); -} - -void __qmljs_llvm_init_string(ExecutionContext *ctx, Value *result, const char *str) -{ - *result = Value::fromString(ctx->engine->newString(QString::fromUtf8(str))); -} - -void __qmljs_llvm_init_closure(ExecutionContext *ctx, Value *result, - String *name, bool hasDirectEval, - bool usesArgumentsObject, bool isStrict, - bool hasNestedFunctions, - String **formals, unsigned formalCount, - String **locals, unsigned localCount) -{ - Function *clos = __qmljs_register_function(ctx, name, hasDirectEval, - usesArgumentsObject, isStrict, - hasNestedFunctions, - formals, formalCount, - locals, localCount); - __qmljs_init_closure(ctx, result, clos); -} - -bool __qmljs_llvm_to_boolean(ExecutionContext *ctx, const Value *value) -{ - return __qmljs_to_boolean(*value); -} - -void __qmljs_llvm_bit_and(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_bit_and(result, *left, *right); -} - -void __qmljs_llvm_bit_or(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_bit_or(result, *left, *right); -} - -void __qmljs_llvm_bit_xor(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_bit_xor(result, *left, *right); -} - -void __qmljs_llvm_add(ExecutionContext *ctx, Value *result, Value *left, Value *right) -{ - __qmljs_add(ctx, result, *left, *right); -} - -void __qmljs_llvm_sub(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_sub(result, *left, *right); -} - -void __qmljs_llvm_mul(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_mul(result, *left, *right); -} - -void __qmljs_llvm_div(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_div(result, *left, *right); -} - -void __qmljs_llvm_mod(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_mod(result, *left, *right); -} - -void __qmljs_llvm_shl(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_shl(result, *left, *right); -} - -void __qmljs_llvm_shr(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_shr(result, *left, *right); -} - -void __qmljs_llvm_ushr(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_ushr(result, *left, *right); -} - -void __qmljs_llvm_gt(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_gt(result, *left, *right); -} - -void __qmljs_llvm_lt(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_lt(result, *left, *right); -} - -void __qmljs_llvm_ge(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_ge(result, *left, *right); -} - -void __qmljs_llvm_le(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_le(result, *left, *right); -} - -void __qmljs_llvm_eq(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_eq(result, *left, *right); -} - -void __qmljs_llvm_ne(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_ne(result, *left, *right); -} - -void __qmljs_llvm_se(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_se(result, *left, *right); -} - -void __qmljs_llvm_sne(ExecutionContext *, Value *result, Value *left, Value *right) -{ - __qmljs_sne(result, *left, *right); -} - -void __qmljs_llvm_instanceof(ExecutionContext *ctx, Value *result, Value *left, Value *right) -{ - __qmljs_instanceof(ctx, result, *left, *right); -} - -void __qmljs_llvm_in(ExecutionContext *ctx, Value *result, Value *left, Value *right) -{ - __qmljs_in(ctx, result, *left, *right); -} - -void __qmljs_llvm_uplus(ExecutionContext *ctx, Value *result, const Value *value) -{ - __qmljs_uplus(result, *value); -} - -void __qmljs_llvm_uminus(ExecutionContext *ctx, Value *result, const Value *value) -{ - __qmljs_uminus(result, *value); -} - -void __qmljs_llvm_compl(ExecutionContext *ctx, Value *result, const Value *value) -{ - __qmljs_compl(result, *value); -} - -void __qmljs_llvm_not(ExecutionContext *ctx, Value *result, const Value *value) -{ - __qmljs_not(result, *value); -} - -void __qmljs_llvm_inplace_bit_and_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_bit_and_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_bit_or_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_bit_or_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_bit_xor_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_bit_xor_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_add_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_add_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_sub_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_sub_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_mul_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_mul_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_div_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_div_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_mod_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_mod_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_shl_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_shl_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_shr_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_shr_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_ushr_name(ExecutionContext *ctx, String *dest, Value *src) -{ - __qmljs_inplace_ushr_name(ctx, dest, *src); -} - -void __qmljs_llvm_inplace_bit_and_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_bit_and_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_bit_or_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_bit_or_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_bit_xor_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_bit_xor_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_add_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_add_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_sub_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_sub_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_mul_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_mul_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_div_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_div_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_mod_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_mod_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_shl_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_shl_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_shr_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_shr_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_ushr_element(ExecutionContext *ctx, Value *base, Value *index, Value *value) -{ - __qmljs_inplace_ushr_element(ctx, *base, *index, *value); -} - -void __qmljs_llvm_inplace_bit_and_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_bit_and_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_bit_or_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_bit_or_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_bit_xor_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_bit_xor_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_add_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_add_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_sub_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_sub_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_mul_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_mul_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_div_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_div_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_mod_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_mod_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_shl_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_shl_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_shr_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_shr_member(ctx, *base, member, *value); -} - -void __qmljs_llvm_inplace_ushr_member(ExecutionContext *ctx, Value *value, Value *base, String *member) -{ - __qmljs_inplace_ushr_member(ctx, *base, member, *value); -} - -String *__qmljs_llvm_identifier_from_utf8(ExecutionContext *ctx, const char *str) -{ - return ctx->engine->newIdentifier(QString::fromUtf8(str)); -} - -void __qmljs_llvm_call_activation_property(ExecutionContext *context, Value *result, String *name, Value *args, int argc) -{ - __qmljs_call_activation_property(context, result, name, args, argc); -} - -void __qmljs_llvm_call_value(ExecutionContext *context, Value *result, const Value *thisObject, const Value *func, Value *args, int argc) -{ - __qmljs_call_value(context, result, thisObject, *func, args, argc); -} - -void __qmljs_llvm_construct_activation_property(ExecutionContext *context, Value *result, String *name, Value *args, int argc) -{ - __qmljs_construct_activation_property(context, result, name, args, argc); -} - -void __qmljs_llvm_construct_value(ExecutionContext *context, Value *result, const Value *func, Value *args, int argc) -{ - __qmljs_construct_value(context, result, *func, args, argc); -} - -void __qmljs_llvm_get_activation_property(ExecutionContext *ctx, Value *result, String *name) -{ - __qmljs_get_activation_property(ctx, result, name); -} - -void __qmljs_llvm_set_activation_property(ExecutionContext *ctx, String *name, Value *value) -{ - __qmljs_set_activation_property(ctx, name, *value); -} - -void __qmljs_llvm_get_property(ExecutionContext *ctx, Value *result, Value *object, String *name) -{ - __qmljs_get_property(ctx, result, *object, name); -} - -void __qmljs_llvm_call_property(ExecutionContext *context, Value *result, const Value *base, String *name, Value *args, int argc) -{ - __qmljs_call_property(context, result, *base, name, args, argc); -} - -void __qmljs_llvm_construct_property(ExecutionContext *context, Value *result, const Value *base, String *name, Value *args, int argc) -{ - __qmljs_construct_property(context, result, *base, name, args, argc); -} - -void __qmljs_llvm_get_element(ExecutionContext *ctx, Value *result, Value *object, Value *index) -{ - __qmljs_get_element(ctx, result, *object, *index); -} - -void __qmljs_llvm_set_element(ExecutionContext *ctx, Value *object, Value *index, Value *value) -{ - __qmljs_set_element(ctx, *object, *index, *value); -} - -void __qmljs_llvm_set_property(ExecutionContext *ctx, Value *object, String *name, Value *value) -{ - __qmljs_set_property(ctx, *object, name, *value); -} - -void __qmljs_llvm_builtin_declare_var(ExecutionContext *ctx, bool deletable, String *name) -{ - __qmljs_builtin_declare_var(ctx, deletable, name); -} - -void __qmljs_llvm_typeof(ExecutionContext *ctx, Value *result, const Value *value) -{ - __qmljs_builtin_typeof(ctx, result, *value); -} - -void __qmljs_llvm_throw(ExecutionContext *context, Value *value) -{ - __qmljs_throw(context, *value); -} - -void __qmljs_llvm_delete_exception_handler(ExecutionContext *context) -{ - // ### FIXME. -} - -void __qmljs_llvm_foreach_iterator_object(ExecutionContext *context, Value *result, Value *in) -{ - __qmljs_foreach_iterator_object(context, result, *in); -} - -void __qmljs_llvm_foreach_next_property_name(Value *result, Value *it) -{ - __qmljs_foreach_next_property_name(result, *it); -} - -void __qmljs_llvm_get_this_object(ExecutionContext *ctx, Value *result) -{ - *result = ctx->thisObject; -} - -void __qmljs_llvm_delete_subscript(ExecutionContext *ctx, Value *result, Value *base, Value *index) -{ - __qmljs_delete_subscript(ctx, result, *base, *index); -} - -void __qmljs_llvm_delete_member(ExecutionContext *ctx, Value *result, Value *base, String *name) -{ - __qmljs_delete_member(ctx, result, *base, name); -} - -void __qmljs_llvm_delete_name(ExecutionContext *ctx, Value *result, String *name) -{ - __qmljs_delete_name(ctx, result, name); -} - -} // extern "C" diff --git a/src/qml/qml/v4/qv4_llvm_p.h b/src/qml/qml/v4/qv4_llvm_p.h deleted file mode 100644 index 50bd7d3831..0000000000 --- a/src/qml/qml/v4/qv4_llvm_p.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV4_LLVM_P_H -#define QV4_LLVM_P_H - -#include "qv4global_p.h" -#include "qv4jsir_p.h" - -#include <QtCore/QString> - -namespace QQmlJS { - -// Note: keep this enum in sync with the command-line option! -enum LLVMOutputType { - LLVMOutputJit = -1, - LLVMOutputIR = 0, // .ll - LLVMOutputBitcode = 1, // .bc - LLVMOutputAssembler = 2, // .s - LLVMOutputObject = 3 // .o -}; - -Q_QML_EXPORT int compileWithLLVM(V4IR::Module *module, const QString &fileName, LLVMOutputType outputType, int (*)(void *)); - -} // QQmlJS - -#endif // QV4_LLVM_P_H diff --git a/src/qml/qml/v4/qv4isel_llvm.cpp b/src/qml/qml/v4/qv4isel_llvm.cpp deleted file mode 100644 index 70378a4d8a..0000000000 --- a/src/qml/qml/v4/qv4isel_llvm.cpp +++ /dev/null @@ -1,1388 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wunused-parameter" -#endif // __clang__ - -#include <llvm/Analysis/Passes.h> -#include <llvm/Analysis/Verifier.h> -#include <llvm/Assembly/PrintModulePass.h> -#include <llvm/Bitcode/ReaderWriter.h> -#include <llvm/ExecutionEngine/ExecutionEngine.h> -#include <llvm/ExecutionEngine/JIT.h> -#include <llvm/ExecutionEngine/JITMemoryManager.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/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 "qv4_llvm_p.h" -#include "qv4jsir_p.h" -#include "qv4string_p.h" -#include "qv4global_p.h" - -namespace QQmlJS { - -Q_QML_EXPORT int compileWithLLVM(V4IR::Module *module, const QString &fileName, LLVMOutputType outputType, int (*exec)(void *)) -{ - Q_ASSERT(module); - Q_ASSERT(exec || outputType != LLVMOutputJit); - - // TODO: should this be done here? - LLVMInitializeX86TargetInfo(); - LLVMInitializeX86Target(); - LLVMInitializeX86AsmPrinter(); - LLVMInitializeX86AsmParser(); - LLVMInitializeX86Disassembler(); - LLVMInitializeX86TargetMC(); - - //---- - - llvm::InitializeNativeTarget(); - LLVM::InstructionSelection llvmIsel(llvm::getGlobalContext()); - - const QString moduleName = QFileInfo(fileName).fileName(); - llvm::StringRef moduleId(moduleName.toUtf8().constData()); - llvm::Module *llvmModule = new llvm::Module(moduleId, llvmIsel.getContext()); - - if (outputType == LLVMOutputJit) { - // The execution engine takes ownership of the model. No need to delete it anymore. - std::string errStr; - llvm::ExecutionEngine *execEngine = llvm::EngineBuilder(llvmModule) -// .setUseMCJIT(true) - .setErrorStr(&errStr).create(); - if (!execEngine) { - std::cerr << "Could not create LLVM JIT: " << errStr << std::endl; - return EXIT_FAILURE; - } - - llvm::FunctionPassManager functionPassManager(llvmModule); - // Set up the optimizer pipeline. Start with registering info about how the - // target lays out data structures. - functionPassManager.add(new llvm::DataLayout(*execEngine->getDataLayout())); - // Promote allocas to registers. - functionPassManager.add(llvm::createPromoteMemoryToRegisterPass()); - // Provide basic AliasAnalysis support for GVN. - functionPassManager.add(llvm::createBasicAliasAnalysisPass()); - // Do simple "peephole" optimizations and bit-twiddling optzns. - functionPassManager.add(llvm::createInstructionCombiningPass()); - // Reassociate expressions. - functionPassManager.add(llvm::createReassociatePass()); - // Eliminate Common SubExpressions. - functionPassManager.add(llvm::createGVNPass()); - // Simplify the control flow graph (deleting unreachable blocks, etc). - functionPassManager.add(llvm::createCFGSimplificationPass()); - - functionPassManager.doInitialization(); - - llvmIsel.buildLLVMModule(module, llvmModule, &functionPassManager); - - llvm::Function *entryPoint = llvmModule->getFunction("%entry"); - Q_ASSERT(entryPoint); - void *funcPtr = execEngine->getPointerToFunction(entryPoint); - return exec(funcPtr); - } else { - llvm::FunctionPassManager functionPassManager(llvmModule); - // Set up the optimizer pipeline. - // Promote allocas to registers. - functionPassManager.add(llvm::createPromoteMemoryToRegisterPass()); - // Provide basic AliasAnalysis support for GVN. - functionPassManager.add(llvm::createBasicAliasAnalysisPass()); - // Do simple "peephole" optimizations and bit-twiddling optzns. - functionPassManager.add(llvm::createInstructionCombiningPass()); - // Reassociate expressions. - functionPassManager.add(llvm::createReassociatePass()); - // Eliminate Common SubExpressions. - functionPassManager.add(llvm::createGVNPass()); - // Simplify the control flow graph (deleting unreachable blocks, etc). - functionPassManager.add(llvm::createCFGSimplificationPass()); - - functionPassManager.doInitialization(); - - llvmIsel.buildLLVMModule(module, llvmModule, &functionPassManager); - - // TODO: if output type is .ll, print the module to file - - const std::string triple = llvm::sys::getDefaultTargetTriple(); - - 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; - - if (outputType == LLVMOutputObject) { - ft = llvm::TargetMachine::CGFT_ObjectFile; - ofName = fileName + QLatin1String(".o"); - } else if (outputType == LLVMOutputAssembler) { - ft = llvm::TargetMachine::CGFT_AssemblyFile; - ofName = fileName + QLatin1String(".s"); - } else { - // ft is not used. - ofName = fileName + QLatin1String(".ll"); - } - - 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; - } - - llvm::PassManager globalPassManager; - globalPassManager.add(llvm::createScalarReplAggregatesPass()); - globalPassManager.add(llvm::createInstructionCombiningPass()); - globalPassManager.add(llvm::createGlobalOptimizerPass()); - globalPassManager.add(llvm::createFunctionInliningPass(25)); -// globalPassManager.add(llvm::createFunctionInliningPass(125)); - - if (outputType == LLVMOutputObject || outputType == LLVMOutputAssembler) { - if (targetMachine->addPassesToEmitFile(globalPassManager, destf, ft)) { - std::cerr << err << " (probably no DataLayout in TargetMachine)" << std::endl; - } else { - globalPassManager.run(*llvmModule); - - destf.flush(); - dest.flush(); - } - } else { // .ll - globalPassManager.run(*llvmModule); - llvmModule->print(destf, 0); - - destf.flush(); - dest.flush(); - } - - delete llvmModule; - return EXIT_SUCCESS; - } -} - -} // QQmlJS - -using namespace QQmlJS; -using namespace QQmlJS::LLVM; - -namespace { -QTextStream qerr(stderr, QIODevice::WriteOnly); -} - -InstructionSelection::InstructionSelection(llvm::LLVMContext &context) - : llvm::IRBuilder<>(context) - , _llvmModule(0) - , _llvmFunction(0) - , _llvmValue(0) - , _numberTy(0) - , _valueTy(0) - , _contextPtrTy(0) - , _stringPtrTy(0) - , _functionTy(0) - , _allocaInsertPoint(0) - , _function(0) - , _block(0) - , _fpm(0) -{ -} - -void InstructionSelection::buildLLVMModule(V4IR::Module *module, llvm::Module *llvmModule, llvm::FunctionPassManager *fpm) -{ - qSwap(_llvmModule, llvmModule); - qSwap(_fpm, fpm); - - _numberTy = getDoubleTy(); - - std::string err; - - llvm::OwningPtr<llvm::MemoryBuffer> buffer; - qDebug()<<"llvm runtime:"<<LLVM_RUNTIME; - llvm::error_code ec = llvm::MemoryBuffer::getFile(llvm::StringRef(LLVM_RUNTIME), buffer); - if (ec) { - qWarning() << ec.message().c_str(); - assert(!"cannot load QML/JS LLVM runtime, you can generate the runtime with the command `make llvm_runtime'"); - } - - llvm::Module *llvmRuntime = llvm::getLazyBitcodeModule(buffer.get(), getContext(), &err); - if (! err.empty()) { - qWarning() << err.c_str(); - assert(!"cannot load QML/JS LLVM runtime"); - } - - err.clear(); - llvm::Linker::LinkModules(_llvmModule, llvmRuntime, llvm::Linker::DestroySource, &err); - if (! err.empty()) { - qWarning() << err.c_str(); - assert(!"cannot link the QML/JS LLVM runtime"); - } - - _valueTy = _llvmModule->getTypeByName("struct.QV4::Value"); - _contextPtrTy = _llvmModule->getTypeByName("struct.QV4::ExecutionContext")->getPointerTo(); - _stringPtrTy = _llvmModule->getTypeByName("struct.QV4::String")->getPointerTo(); - - { - llvm::Type *args[] = { _contextPtrTy }; - _functionTy = llvm::FunctionType::get(getVoidTy(), llvm::makeArrayRef(args), false); - } - - - foreach (V4IR::Function *function, module->functions) - (void) compileLLVMFunction(function); - qSwap(_fpm, fpm); - qSwap(_llvmModule, llvmModule); -} - -void InstructionSelection::callBuiltinInvalid(V4IR::Name *func, V4IR::ExprList *args, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinTypeofMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinTypeofSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinTypeofName(const QString &name, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinTypeofValue(V4IR::Temp *value, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinDeleteMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinDeleteSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinDeleteName(const QString &name, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinDeleteValue(V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPostDecrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPostDecrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPostDecrementName(const QString &name, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPostDecrementValue(V4IR::Temp *value, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPostIncrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPostIncrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPostIncrementName(const QString &name, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPostIncrementValue(V4IR::Temp *value, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinThrow(V4IR::Temp *arg, int line) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinCreateExceptionHandler(V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinFinishTry() -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinForeachIteratorObject(V4IR::Temp *arg, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinForeachNextPropertyname(V4IR::Temp *arg, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPushWithScope(V4IR::Temp *arg) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinPopScope() -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinDeclareVar(bool deletable, const QString &name) -{ - llvm::ConstantInt *isDeletable = getInt1(deletable != 0); - llvm::Value *varName = getIdentifier(name); - CreateCall3(getRuntimeFunction("__qmljs_builtin_declare_var"), - _llvmFunction->arg_begin(), isDeletable, varName); -} - -void InstructionSelection::callBuiltinDefineGetterSetter(V4IR::Temp *object, const QString &name, V4IR::Temp *getter, V4IR::Temp *setter) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinDefineProperty(V4IR::Temp *object, const QString &name, V4IR::Temp *value) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinDefineArray(V4IR::Temp *result, V4IR::ExprList *args) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callBuiltinDefineObjectLiteral(V4IR::Temp *result, V4IR::ExprList *args) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::callSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::ExprList *args, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::constructActivationProperty(V4IR::Name *func, - V4IR::ExprList *args, - V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::constructProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::constructValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::loadThisObject(V4IR::Temp *temp) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::loadConst(V4IR::Const *con, V4IR::Temp *temp) -{ - llvm::Value *target = getLLVMTemp(temp); - llvm::Value *source = CreateLoad(createValue(con)); - CreateStore(source, target); -} - -void InstructionSelection::loadString(const QString &str, V4IR::Temp *targetTemp) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::loadRegexp(V4IR::RegExp *sourceRegexp, V4IR::Temp *targetTemp) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::getActivationProperty(const V4IR::Name *name, V4IR::Temp *temp) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -void InstructionSelection::setActivationProperty(V4IR::Temp *source, const QString &targetName) -{ - llvm::Value *name = getIdentifier(targetName); - llvm::Value *src = toValuePtr(source); - CreateCall3(getRuntimeFunction("__qmljs_llvm_set_activation_property"), - _llvmFunction->arg_begin(), name, src); -} - -void InstructionSelection::initClosure(V4IR::Closure *closure, V4IR::Temp *target) -{ - V4IR::Function *f = closure->value; - QString name; - if (f->name) - name = *f->name; - - llvm::Value *args[] = { - _llvmFunction->arg_begin(), - getLLVMTemp(target), - getIdentifier(name), - getInt1(f->hasDirectEval), - getInt1(f->usesArgumentsObject), - getInt1(f->isStrict), - getInt1(!f->nestedFunctions.isEmpty()), - genStringList(f->formals, "formals", "formal"), - getInt32(f->formals.size()), - genStringList(f->locals, "locals", "local"), - getInt32(f->locals.size()) - }; - llvm::Function *callee = _llvmModule->getFunction("__qmljs_llvm_init_closure"); - CreateCall(callee, args); -} - -void InstructionSelection::getProperty(V4IR::Temp *sourceBase, const QString &sourceName, V4IR::Temp *target) -{ - llvm::Value *base = getLLVMTempReference(sourceBase); - llvm::Value *name = getIdentifier(sourceName); - llvm::Value *t = getLLVMTemp(target); - CreateCall4(getRuntimeFunction("__qmljs_llvm_get_property"), - _llvmFunction->arg_begin(), t, base, name); -} - -void InstructionSelection::setProperty(V4IR::Temp *source, V4IR::Temp *targetBase, const QString &targetName) -{ - llvm::Value *base = getLLVMTempReference(targetBase); - llvm::Value *name = getIdentifier(targetName); - llvm::Value *src = toValuePtr(source); - CreateCall4(getRuntimeFunction("__qmljs_llvm_set_property"), - _llvmFunction->arg_begin(), base, name, src); -} - -void InstructionSelection::getElement(V4IR::Temp *sourceBase, V4IR::Temp *sourceIndex, V4IR::Temp *target) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); - - llvm::Value *base = getLLVMTempReference(sourceBase); - llvm::Value *index = getLLVMTempReference(sourceIndex); - llvm::Value *t = getLLVMTemp(target); - CreateCall4(getRuntimeFunction("__qmljs_llvm_get_element"), - _llvmFunction->arg_begin(), t, base, index); -} - -void InstructionSelection::setElement(V4IR::Temp *source, V4IR::Temp *targetBase, V4IR::Temp *targetIndex) -{ - llvm::Value *base = getLLVMTempReference(targetBase); - llvm::Value *index = getLLVMTempReference(targetIndex); - llvm::Value *src = toValuePtr(source); - CreateCall4(getRuntimeFunction("__qmljs_llvm_set_element"), - _llvmFunction->arg_begin(), base, index, src); -} - -void InstructionSelection::copyValue(V4IR::Temp *sourceTemp, V4IR::Temp *targetTemp) -{ - llvm::Value *t = getLLVMTemp(targetTemp); - llvm::Value *s = getLLVMTemp(sourceTemp); - CreateStore(s, t); -} - -void InstructionSelection::unop(V4IR::AluOp oper, V4IR::Temp *sourceTemp, V4IR::Temp *targetTemp) -{ - const char *opName = 0; - switch (oper) { - case V4IR::OpNot: opName = "__qmljs_not"; break; - case V4IR::OpUMinus: opName = "__qmljs_uminus"; break; - case V4IR::OpUPlus: opName = "__qmljs_uplus"; break; - case V4IR::OpCompl: opName = "__qmljs_compl"; break; - case V4IR::OpIncrement: opName = "__qmljs_increment"; break; - case V4IR::OpDecrement: opName = "__qmljs_decrement"; break; - default: assert(!"unreachable"); break; - } - - if (opName) { - llvm::Value *t = getLLVMTemp(targetTemp); - llvm::Value *s = getLLVMTemp(sourceTemp); - CreateCall3(getRuntimeFunction(opName), - _llvmFunction->arg_begin(), t, s); - } -} - -void InstructionSelection::binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource, V4IR::Temp *target) -{ - const char *opName = 0; - switch (oper) { - case V4IR::OpBitAnd: opName = "__qmljs_llvm_bit_and"; break; - case V4IR::OpBitOr: opName = "__qmljs_llvm_bit_or"; break; - case V4IR::OpBitXor: opName = "__qmljs_llvm_bit_xor"; break; - case V4IR::OpAdd: opName = "__qmljs_llvm_add"; break; - case V4IR::OpSub: opName = "__qmljs_llvm_sub"; break; - case V4IR::OpMul: opName = "__qmljs_llvm_mul"; break; - case V4IR::OpDiv: opName = "__qmljs_llvm_div"; break; - case V4IR::OpMod: opName = "__qmljs_llvm_mod"; break; - case V4IR::OpLShift: opName = "__qmljs_llvm_shl"; break; - case V4IR::OpRShift: opName = "__qmljs_llvm_shr"; break; - case V4IR::OpURShift: opName = "__qmljs_llvm_ushr"; break; - default: - Q_UNREACHABLE(); - break; - } - - if (opName) { - llvm::Value *t = getLLVMTemp(target); - llvm::Value *s1 = toValuePtr(leftSource); - llvm::Value *s2 = toValuePtr(rightSource); - CreateCall4(getRuntimeFunction(opName), - _llvmFunction->arg_begin(), t, s1, s2); - return; - } -} - -void InstructionSelection::inplaceNameOp(V4IR::AluOp oper, V4IR::Temp *rightSource, const QString &targetName) -{ - const char *opName = 0; - switch (oper) { - case V4IR::OpBitAnd: opName = "__qmljs_llvm_inplace_bit_and_name"; break; - case V4IR::OpBitOr: opName = "__qmljs_llvm_inplace_bit_or_name"; break; - case V4IR::OpBitXor: opName = "__qmljs_llvm_inplace_bit_xor_name"; break; - case V4IR::OpAdd: opName = "__qmljs_llvm_inplace_add_name"; break; - case V4IR::OpSub: opName = "__qmljs_llvm_inplace_sub_name"; break; - case V4IR::OpMul: opName = "__qmljs_llvm_inplace_mul_name"; break; - case V4IR::OpDiv: opName = "__qmljs_llvm_inplace_div_name"; break; - case V4IR::OpMod: opName = "__qmljs_llvm_inplace_mod_name"; break; - case V4IR::OpLShift: opName = "__qmljs_llvm_inplace_shl_name"; break; - case V4IR::OpRShift: opName = "__qmljs_llvm_inplace_shr_name"; break; - case V4IR::OpURShift: opName = "__qmljs_llvm_inplace_ushr_name"; break; - default: - Q_UNREACHABLE(); - break; - } - - if (opName) { - llvm::Value *dst = getIdentifier(targetName); - llvm::Value *src = toValuePtr(rightSource); - CreateCall3(getRuntimeFunction(opName), - _llvmFunction->arg_begin(), dst, src); - return; - } -} - -void InstructionSelection::inplaceElementOp(V4IR::AluOp oper, V4IR::Temp *source, V4IR::Temp *targetBaseTemp, V4IR::Temp *targetIndexTemp) -{ - const char *opName = 0; - switch (oper) { - case V4IR::OpBitAnd: opName = "__qmljs_llvm_inplace_bit_and_element"; break; - case V4IR::OpBitOr: opName = "__qmljs_llvm_inplace_bit_or_element"; break; - case V4IR::OpBitXor: opName = "__qmljs_llvm_inplace_bit_xor_element"; break; - case V4IR::OpAdd: opName = "__qmljs_llvm_inplace_add_element"; break; - case V4IR::OpSub: opName = "__qmljs_llvm_inplace_sub_element"; break; - case V4IR::OpMul: opName = "__qmljs_llvm_inplace_mul_element"; break; - case V4IR::OpDiv: opName = "__qmljs_llvm_inplace_div_element"; break; - case V4IR::OpMod: opName = "__qmljs_llvm_inplace_mod_element"; break; - case V4IR::OpLShift: opName = "__qmljs_llvm_inplace_shl_element"; break; - case V4IR::OpRShift: opName = "__qmljs_llvm_inplace_shr_element"; break; - case V4IR::OpURShift: opName = "__qmljs_llvm_inplace_ushr_element"; break; - default: - Q_UNREACHABLE(); - break; - } - - if (opName) { - llvm::Value *base = getLLVMTemp(targetBaseTemp); - llvm::Value *index = getLLVMTemp(targetIndexTemp); - llvm::Value *value = toValuePtr(source); - CreateCall4(getRuntimeFunction(opName), - _llvmFunction->arg_begin(), base, index, value); - } -} - -void InstructionSelection::inplaceMemberOp(V4IR::AluOp oper, V4IR::Temp *source, V4IR::Temp *targetBase, const QString &targetName) -{ - const char *opName = 0; - switch (oper) { - case V4IR::OpBitAnd: opName = "__qmljs_llvm_inplace_bit_and_member"; break; - case V4IR::OpBitOr: opName = "__qmljs_llvm_inplace_bit_or_member"; break; - case V4IR::OpBitXor: opName = "__qmljs_llvm_inplace_bit_xor_member"; break; - case V4IR::OpAdd: opName = "__qmljs_llvm_inplace_add_member"; break; - case V4IR::OpSub: opName = "__qmljs_llvm_inplace_sub_member"; break; - case V4IR::OpMul: opName = "__qmljs_llvm_inplace_mul_member"; break; - case V4IR::OpDiv: opName = "__qmljs_llvm_inplace_div_member"; break; - case V4IR::OpMod: opName = "__qmljs_llvm_inplace_mod_member"; break; - case V4IR::OpLShift: opName = "__qmljs_llvm_inplace_shl_member"; break; - case V4IR::OpRShift: opName = "__qmljs_llvm_inplace_shr_member"; break; - case V4IR::OpURShift: opName = "__qmljs_llvm_inplace_ushr_member"; break; - default: - Q_UNREACHABLE(); - break; - } - - if (opName) { - llvm::Value *base = getLLVMTemp(targetBase); - llvm::Value *member = getIdentifier(targetName); - llvm::Value *value = toValuePtr(source); - CreateCall4(getRuntimeFunction(opName), - _llvmFunction->arg_begin(), value, base, member); - } -} - -llvm::Function *InstructionSelection::getLLVMFunction(V4IR::Function *function) -{ - llvm::Function *&f = _functionMap[function]; - if (! f) { - QString name = QStringLiteral("__qmljs_native_"); - if (function->name) { - if (*function->name == QStringLiteral("%entry")) - name = *function->name; - else - name += *function->name; - } - f = llvm::Function::Create(_functionTy, llvm::Function::ExternalLinkage, // ### make it internal - qPrintable(name), _llvmModule); - } - return f; -} - -llvm::Function *InstructionSelection::compileLLVMFunction(V4IR::Function *function) -{ - llvm::Function *llvmFunction = getLLVMFunction(function); - - QHash<V4IR::BasicBlock *, llvm::BasicBlock *> blockMap; - QVector<llvm::Value *> tempMap; - - qSwap(_llvmFunction, llvmFunction); - qSwap(_function, function); - qSwap(_tempMap, tempMap); - qSwap(_blockMap, blockMap); - - // create the LLVM blocks - foreach (V4IR::BasicBlock *block, _function->basicBlocks) - (void) getLLVMBasicBlock(block); - - // entry block - SetInsertPoint(getLLVMBasicBlock(_function->basicBlocks.first())); - - llvm::Instruction *allocaInsertPoint = new llvm::BitCastInst(llvm::UndefValue::get(getInt32Ty()), - getInt32Ty(), "", GetInsertBlock()); - qSwap(_allocaInsertPoint, allocaInsertPoint); - - for (int i = 0; i < _function->tempCount; ++i) { - llvm::AllocaInst *t = newLLVMTemp(_valueTy); - _tempMap.append(t); - } - - foreach (llvm::Value *t, _tempMap) { - CreateStore(llvm::Constant::getNullValue(_valueTy), t); - } - -// CreateCall(getRuntimeFunction("__qmljs_llvm_init_this_object"), -// _llvmFunction->arg_begin()); - - foreach (V4IR::BasicBlock *block, _function->basicBlocks) { - qSwap(_block, block); - SetInsertPoint(getLLVMBasicBlock(_block)); - foreach (V4IR::Stmt *s, _block->statements) - s->accept(this); - qSwap(_block, block); - } - - qSwap(_allocaInsertPoint, allocaInsertPoint); - - allocaInsertPoint->eraseFromParent(); - - qSwap(_blockMap, blockMap); - qSwap(_tempMap, tempMap); - qSwap(_function, function); - qSwap(_llvmFunction, llvmFunction); - - // Validate the generated code, checking for consistency. - llvm::verifyFunction(*llvmFunction); - // Optimize the function. - if (_fpm) - _fpm->run(*llvmFunction); - - return llvmFunction; -} - -llvm::BasicBlock *InstructionSelection::getLLVMBasicBlock(V4IR::BasicBlock *block) -{ - llvm::BasicBlock *&llvmBlock = _blockMap[block]; - if (! llvmBlock) - llvmBlock = llvm::BasicBlock::Create(getContext(), llvm::Twine(), - _llvmFunction); - return llvmBlock; -} - -llvm::Value *InstructionSelection::getLLVMTempReference(V4IR::Expr *expr) -{ - if (V4IR::Temp *t = expr->asTemp()) - return getLLVMTemp(t); - - assert(!"TODO!"); - llvm::Value *addr = newLLVMTemp(_valueTy); -// CreateStore(getLLVMValue(expr), addr); - return addr; -} - -llvm::Value *InstructionSelection::getLLVMCondition(V4IR::Expr *expr) -{ - llvm::Value *value = 0; - if (V4IR::Temp *t = expr->asTemp()) { - value = getLLVMTemp(t); - } else { - assert(!"TODO!"); - Q_UNREACHABLE(); - -#if 0 - value = getLLVMValue(expr); - if (! value) { - Q_UNIMPLEMENTED(); - return getInt1(false); - } - - llvm::Value *tmp = newLLVMTemp(_valueTy); - CreateStore(value, tmp); - value = tmp; -#endif - } - - return CreateCall2(getRuntimeFunction("__qmljs_llvm_to_boolean"), - _llvmFunction->arg_begin(), - value); -} - -llvm::Value *InstructionSelection::getLLVMTemp(V4IR::Temp *temp) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); - return 0; -#if 0 - if (temp->idx < 0) { - const int index = -temp->idx -1; - return CreateCall2(getRuntimeFunction("__qmljs_llvm_get_argument"), - _llvmFunction->arg_begin(), getInt32(index)); - } - - return _tempMap[temp->idx]; -#endif -} - -llvm::Value *InstructionSelection::getStringPtr(const QString &s) -{ - llvm::Value *&value = _stringMap[s]; - if (! value) { - const QByteArray bytes = s.toUtf8(); - value = CreateGlobalStringPtr(llvm::StringRef(bytes.constData(), bytes.size())); - _stringMap[s] = value; - } - return value; -} - -llvm::Value *InstructionSelection::getIdentifier(const QString &s) -{ - llvm::Value *str = getStringPtr(s); - llvm::Value *id = CreateCall2(getRuntimeFunction("__qmljs_identifier_from_utf8"), - _llvmFunction->arg_begin(), str); - return id; -} - -void InstructionSelection::visitJump(V4IR::Jump *s) -{ - CreateBr(getLLVMBasicBlock(s->target)); -} - -void InstructionSelection::visitCJump(V4IR::CJump *s) -{ - CreateCondBr(getLLVMCondition(s->cond), - getLLVMBasicBlock(s->iftrue), - getLLVMBasicBlock(s->iffalse)); -} - -void InstructionSelection::visitRet(V4IR::Ret *s) -{ - V4IR::Temp *t = s->expr->asTemp(); - assert(t != 0); - llvm::Value *result = getLLVMTemp(t); - llvm::Value *ctx = _llvmFunction->arg_begin(); - CreateCall2(getRuntimeFunction("__qmljs_llvm_return"), ctx, result); - CreateRetVoid(); -} - -void InstructionSelection::visitTry(V4IR::Try *) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - -#if 0 -void InstructionSelection::visitString(V4IR::String *e) -{ - llvm::Value *tmp = newLLVMTemp(_valueTy); - CreateCall3(getRuntimeFunction("__qmljs_llvm_init_string"), - _llvmFunction->arg_begin(), tmp, - getStringPtr(*e->value)); - _llvmValue = CreateLoad(tmp); -} -#endif - -llvm::AllocaInst *InstructionSelection::newLLVMTemp(llvm::Type *type, llvm::Value *size) -{ - llvm::AllocaInst *addr = new llvm::AllocaInst(type, size, llvm::Twine(), _allocaInsertPoint); - return addr; -} - -llvm::Value * InstructionSelection::genArguments(V4IR::ExprList *exprs, int &argc) -{ - llvm::Value *args = 0; - - argc = 0; - for (V4IR::ExprList *it = exprs; it; it = it->next) - ++argc; - - if (argc) - args = newLLVMTemp(_valueTy, getInt32(argc)); - else - args = llvm::Constant::getNullValue(_valueTy->getPointerTo()); - - int i = 0; - for (V4IR::ExprList *it = exprs; it; it = it->next) { -// llvm::Value *arg = getLLVMValue(it->expr); -// CreateStore(arg, CreateConstGEP1_32(args, i++)); - } - - return args; -} - -void InstructionSelection::genCallMember(V4IR::Call *e, llvm::Value *result) -{ - if (! result) - result = newLLVMTemp(_valueTy); - - V4IR::Member *m = e->base->asMember(); - llvm::Value *thisObject = getLLVMTemp(m->base->asTemp()); - llvm::Value *name = getIdentifier(*m->name); - - int argc = 0; - llvm::Value *args = genArguments(e->args, argc); - - llvm::Value *actuals[] = { - _llvmFunction->arg_begin(), - result, - thisObject, - name, - args, - getInt32(argc) - }; - - CreateCall(getRuntimeFunction("__qmljs_llvm_call_property"), llvm::ArrayRef<llvm::Value *>(actuals)); - _llvmValue = CreateLoad(result); -} - -void InstructionSelection::genConstructMember(V4IR::New *e, llvm::Value *result) -{ - if (! result) - result = newLLVMTemp(_valueTy); - - V4IR::Member *m = e->base->asMember(); - llvm::Value *thisObject = getLLVMTemp(m->base->asTemp()); - llvm::Value *name = getIdentifier(*m->name); - - int argc = 0; - llvm::Value *args = genArguments(e->args, argc); - - llvm::Value *actuals[] = { - _llvmFunction->arg_begin(), - result, - thisObject, - name, - args, - getInt32(argc) - }; - - CreateCall(getRuntimeFunction("__qmljs_llvm_construct_property"), llvm::ArrayRef<llvm::Value *>(actuals)); - _llvmValue = CreateLoad(result); -} - -void InstructionSelection::genCallTemp(V4IR::Call *e, llvm::Value *result) -{ - if (! result) - result = newLLVMTemp(_valueTy); - - llvm::Value *func = getLLVMTempReference(e->base); - - int argc = 0; - llvm::Value *args = genArguments(e->args, argc); - - llvm::Value *thisObject = llvm::Constant::getNullValue(_valueTy->getPointerTo()); - - llvm::Value *actuals[] = { - _llvmFunction->arg_begin(), - result, - thisObject, - func, - args, - getInt32(argc) - }; - - CreateCall(getRuntimeFunction("__qmljs_llvm_call_value"), actuals); - - _llvmValue = CreateLoad(result); -} - -void InstructionSelection::genConstructTemp(V4IR::New *e, llvm::Value *result) -{ - if (! result) - result = newLLVMTemp(_valueTy); - - llvm::Value *func = getLLVMTempReference(e->base); - - int argc = 0; - llvm::Value *args = genArguments(e->args, argc); - - llvm::Value *actuals[] = { - _llvmFunction->arg_begin(), - result, - func, - args, - getInt32(argc) - }; - - CreateCall(getRuntimeFunction("__qmljs_llvm_construct_value"), actuals); - - _llvmValue = CreateLoad(result); -} - -void InstructionSelection::genCallName(V4IR::Call *e, llvm::Value *result) -{ - V4IR::Name *base = e->base->asName(); - - if (! result) - result = newLLVMTemp(_valueTy); - - if (! base->id) { - switch (base->builtin) { - case V4IR::Name::builtin_invalid: - break; - - case V4IR::Name::builtin_typeof: - CreateCall3(getRuntimeFunction("__qmljs_llvm_typeof"), - _llvmFunction->arg_begin(), result, getLLVMTempReference(e->args->expr)); - _llvmValue = CreateLoad(result); - return; - - case V4IR::Name::builtin_throw: - CreateCall2(getRuntimeFunction("__qmljs_llvm_throw"), - _llvmFunction->arg_begin(), getLLVMTempReference(e->args->expr)); - _llvmValue = llvm::UndefValue::get(_valueTy); - return; - - case V4IR::Name::builtin_finish_try: - // ### FIXME. - return; - - case V4IR::Name::builtin_foreach_iterator_object: - CreateCall3(getRuntimeFunction("__qmljs_llvm_foreach_iterator_object"), - _llvmFunction->arg_begin(), result, getLLVMTempReference(e->args->expr)); - _llvmValue = CreateLoad(result); - return; - - case V4IR::Name::builtin_foreach_next_property_name: - CreateCall2(getRuntimeFunction("__qmljs_llvm_foreach_next_property_name"), - result, getLLVMTempReference(e->args->expr)); - _llvmValue = CreateLoad(result); - return; - - case V4IR::Name::builtin_delete: { - if (V4IR::Subscript *subscript = e->args->expr->asSubscript()) { - CreateCall4(getRuntimeFunction("__qmljs_llvm_delete_subscript"), - _llvmFunction->arg_begin(), - result, - getLLVMTempReference(subscript->base), - getLLVMTempReference(subscript->index)); - _llvmValue = CreateLoad(result); - return; - } else if (V4IR::Member *member = e->args->expr->asMember()) { - CreateCall4(getRuntimeFunction("__qmljs_llvm_delete_member"), - _llvmFunction->arg_begin(), - result, - getLLVMTempReference(member->base), - getIdentifier(*member->name)); - _llvmValue = CreateLoad(result); - return; - } else if (V4IR::Name *name = e->args->expr->asName()) { - CreateCall3(getRuntimeFunction("__qmljs_llvm_delete_property"), - _llvmFunction->arg_begin(), - result, - getIdentifier(*name->id)); - _llvmValue = CreateLoad(result); - return; - } else { - CreateCall3(getRuntimeFunction("__qmljs_llvm_delete_value"), - _llvmFunction->arg_begin(), - result, - getLLVMTempReference(e->args->expr)); - _llvmValue = CreateLoad(result); - return; - } - } break; - - default: - Q_UNREACHABLE(); - } - } else { - llvm::Value *name = getIdentifier(*base->id); - - int argc = 0; - llvm::Value *args = genArguments(e->args, argc); - - CreateCall5(getRuntimeFunction("__qmljs_llvm_call_activation_property"), - _llvmFunction->arg_begin(), result, name, args, getInt32(argc)); - - _llvmValue = CreateLoad(result); - } -} - -void InstructionSelection::genConstructName(V4IR::New *e, llvm::Value *result) -{ - V4IR::Name *base = e->base->asName(); - - if (! result) - result = newLLVMTemp(_valueTy); - - if (! base->id) { - Q_UNREACHABLE(); - } else { - llvm::Value *name = getIdentifier(*base->id); - - int argc = 0; - llvm::Value *args = genArguments(e->args, argc); - - CreateCall5(getRuntimeFunction("__qmljs_llvm_construct_activation_property"), - _llvmFunction->arg_begin(), result, name, args, getInt32(argc)); - - _llvmValue = CreateLoad(result); - } -} - -#if 0 -void InstructionSelection::visitCall(V4IR::Call *e) -{ - if (e->base->asMember()) { - genCallMember(e); - } else if (e->base->asTemp()) { - genCallTemp(e); - } else if (e->base->asName()) { - genCallName(e); - } else if (V4IR::Temp *t = e->base->asTemp()) { - llvm::Value *base = getLLVMTemp(t); - - int argc = 0; - llvm::Value *args = genArguments(e->args, argc); - - llvm::Value *result = newLLVMTemp(_valueTy); - CreateStore(llvm::Constant::getNullValue(_valueTy), result); - CreateCall5(getRuntimeFunction("__qmljs_llvm_call_value"), - _llvmFunction->arg_begin(), result, base, args, getInt32(argc)); - _llvmValue = CreateLoad(result); - } else { - Q_UNIMPLEMENTED(); - } -} -#endif - -#if 0 -void InstructionSelection::visitNew(V4IR::New *e) -{ - if (e->base->asMember()) { - genConstructMember(e); - } else if (e->base->asTemp()) { - genConstructTemp(e); - } else if (e->base->asName()) { - genConstructName(e); - } else if (V4IR::Temp *t = e->base->asTemp()) { - llvm::Value *base = getLLVMTemp(t); - - int argc = 0; - llvm::Value *args = genArguments(e->args, argc); - - llvm::Value *result = newLLVMTemp(_valueTy); - CreateStore(llvm::Constant::getNullValue(_valueTy), result); - CreateCall5(getRuntimeFunction("__qmljs_llvm_construct_value"), - _llvmFunction->arg_begin(), result, base, args, getInt32(argc)); - _llvmValue = CreateLoad(result); - } else { - Q_UNIMPLEMENTED(); - } -} -#endif - -#if 0 -void InstructionSelection::visitSubscript(V4IR::Subscript *e) -{ - llvm::Value *result = newLLVMTemp(_valueTy); - llvm::Value *base = getLLVMTempReference(e->base); - llvm::Value *index = getLLVMTempReference(e->index); - CreateCall4(getRuntimeFunction("__qmljs_llvm_get_element"), - _llvmFunction->arg_begin(), result, base, index); - _llvmValue = CreateLoad(result); -} -#endif - -#if 0 -void InstructionSelection::visitMember(V4IR::Member *e) -{ - llvm::Value *result = newLLVMTemp(_valueTy); - llvm::Value *base = getLLVMTempReference(e->base); - llvm::Value *name = getIdentifier(*e->name); - - CreateCall4(getRuntimeFunction("__qmljs_llvm_get_property"), - _llvmFunction->arg_begin(), result, base, name); - _llvmValue = CreateLoad(result); -} -#endif - -llvm::Function *InstructionSelection::getRuntimeFunction(llvm::StringRef str) -{ - llvm::Function *func = _llvmModule->getFunction(str); - if (!func) { - std::cerr << "Cannot find runtime function \"" - << str.str() << "\"!" << std::endl; - assert(func); - } - return func; -} - -llvm::Value *InstructionSelection::createValue(V4IR::Const *e) -{ - llvm::Value *tmp = newLLVMTemp(_valueTy); - - switch (e->type) { - case V4IR::UndefinedType: - CreateCall(getRuntimeFunction("__qmljs_llvm_init_undefined"), tmp); - break; - - case V4IR::NullType: - CreateCall(getRuntimeFunction("__qmljs_llvm_init_null"), tmp); - break; - - case V4IR::BoolType: - CreateCall2(getRuntimeFunction("__qmljs_llvm_init_boolean"), tmp, - getInt1(e->value ? 1 : 0)); - break; - - case V4IR::NumberType: - CreateCall2(getRuntimeFunction("__qmljs_llvm_init_number"), tmp, - llvm::ConstantFP::get(_numberTy, e->value)); - break; - - default: - Q_UNREACHABLE(); - } - - return tmp; -} - -llvm::Value *InstructionSelection::toValuePtr(V4IR::Expr *e) -{ - if (V4IR::Temp *t = e->asTemp()) { - return getLLVMTemp(t); - } else if (V4IR::Const *c = e->asConst()) { - return createValue(c); - } else { - Q_UNREACHABLE(); - } -} - -llvm::Value *InstructionSelection::genStringList(const QList<const QString *> &strings, const char *arrayName, const char *elementName) -{ - llvm::Value *array = CreateAlloca(_stringPtrTy, getInt32(strings.size()), - arrayName); - for (int i = 0, ei = strings.size(); i < ei; ++i) { - llvm::Value *el; - if (const QString *string = strings.at(i)) - el = getIdentifier(*string); - else - el = llvm::Constant::getNullValue(_stringPtrTy); - llvm::Value *ptr = CreateGEP(array, getInt32(i), elementName); - CreateStore(el, ptr); - } - - return array; -} diff --git a/src/qml/qml/v4/qv4isel_llvm_p.h b/src/qml/qml/v4/qv4isel_llvm_p.h deleted file mode 100644 index ab0bcb0e23..0000000000 --- a/src/qml/qml/v4/qv4isel_llvm_p.h +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QV4ISEL_LLVM_P_H -#define QV4ISEL_LLVM_P_H - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wunused-parameter" -#endif // __clang__ - -#include <llvm/Module.h> -#include <llvm/PassManager.h> -#include <llvm/IRBuilder.h> - -#ifdef __clang__ -# pragma clang diagnostic pop -#endif // __clang__ - -#include "qv4isel_p.h" -#include "qv4jsir_p.h" - -namespace QQmlJS { -namespace LLVM { - -class InstructionSelection: - public llvm::IRBuilder<>, - public V4IR::InstructionSelection -{ -public: - InstructionSelection(llvm::LLVMContext &context); - - void buildLLVMModule(V4IR::Module *module, llvm::Module *llvmModule, llvm::FunctionPassManager *fpm); - -public: // methods from InstructionSelection: - virtual void callBuiltinInvalid(V4IR::Name *func, V4IR::ExprList *args, V4IR::Temp *result); - virtual void callBuiltinTypeofMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result); - virtual void callBuiltinTypeofSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result); - virtual void callBuiltinTypeofName(const QString &name, V4IR::Temp *result); - virtual void callBuiltinTypeofValue(V4IR::Temp *value, V4IR::Temp *result); - virtual void callBuiltinDeleteMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result); - virtual void callBuiltinDeleteSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result); - virtual void callBuiltinDeleteName(const QString &name, V4IR::Temp *result); - virtual void callBuiltinDeleteValue(V4IR::Temp *result); - virtual void callBuiltinPostDecrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result); - virtual void callBuiltinPostDecrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result); - virtual void callBuiltinPostDecrementName(const QString &name, V4IR::Temp *result); - virtual void callBuiltinPostDecrementValue(V4IR::Temp *value, V4IR::Temp *result); - virtual void callBuiltinPostIncrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result); - virtual void callBuiltinPostIncrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result); - virtual void callBuiltinPostIncrementName(const QString &name, V4IR::Temp *result); - virtual void callBuiltinPostIncrementValue(V4IR::Temp *value, V4IR::Temp *result); - virtual void callBuiltinThrow(V4IR::Temp *arg, int line); - virtual void callBuiltinCreateExceptionHandler(V4IR::Temp *result); - virtual void callBuiltinFinishTry(); - virtual void callBuiltinForeachIteratorObject(V4IR::Temp *arg, V4IR::Temp *result); - virtual void callBuiltinForeachNextPropertyname(V4IR::Temp *arg, V4IR::Temp *result); - virtual void callBuiltinPushWithScope(V4IR::Temp *arg); - virtual void callBuiltinPopScope(); - virtual void callBuiltinDeclareVar(bool deletable, const QString &name); - virtual void callBuiltinDefineGetterSetter(V4IR::Temp *object, const QString &name, V4IR::Temp *getter, V4IR::Temp *setter); - virtual void callBuiltinDefineProperty(V4IR::Temp *object, const QString &name, V4IR::Temp *value); - virtual void callBuiltinDefineArray(V4IR::Temp *result, V4IR::ExprList *args); - virtual void callBuiltinDefineObjectLiteral(V4IR::Temp *result, V4IR::ExprList *args); - virtual void callValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result); - virtual void callProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result); - virtual void callSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::ExprList *args, V4IR::Temp *result); - virtual void constructActivationProperty(V4IR::Name *func, V4IR::ExprList *args, V4IR::Temp *result); - virtual void constructProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result); - virtual void constructValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result); - virtual void loadThisObject(V4IR::Temp *temp); - virtual void loadConst(V4IR::Const *con, V4IR::Temp *temp); - virtual void loadString(const QString &str, V4IR::Temp *targetTemp); - virtual void loadRegexp(V4IR::RegExp *sourceRegexp, V4IR::Temp *targetTemp); - virtual void getActivationProperty(const V4IR::Name *name, V4IR::Temp *temp); - virtual void setActivationProperty(V4IR::Temp *source, const QString &targetName); - virtual void initClosure(V4IR::Closure *closure, V4IR::Temp *target); - virtual void getProperty(V4IR::Temp *sourceBase, const QString &sourceName, V4IR::Temp *target); - virtual void setProperty(V4IR::Temp *source, V4IR::Temp *targetBase, const QString &targetName); - virtual void getElement(V4IR::Temp *sourceBase, V4IR::Temp *sourceIndex, V4IR::Temp *target); - virtual void setElement(V4IR::Temp *source, V4IR::Temp *targetBase, V4IR::Temp *targetIndex); - virtual void copyValue(V4IR::Temp *sourceTemp, V4IR::Temp *targetTemp); - virtual void unop(V4IR::AluOp oper, V4IR::Temp *sourceTemp, V4IR::Temp *targetTemp); - virtual void binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource, V4IR::Temp *target); - virtual void inplaceNameOp(V4IR::AluOp oper, V4IR::Temp *rightSource, const QString &targetName); - virtual void inplaceElementOp(V4IR::AluOp oper, V4IR::Temp *source, V4IR::Temp *targetBaseTemp, V4IR::Temp *targetIndexTemp); - virtual void inplaceMemberOp(V4IR::AluOp oper, V4IR::Temp *source, V4IR::Temp *targetBase, const QString &targetName); - -public: // visitor methods for StmtVisitor: - virtual void visitJump(V4IR::Jump *); - virtual void visitCJump(V4IR::CJump *); - virtual void visitRet(V4IR::Ret *); - virtual void visitTry(V4IR::Try *); - -private: - llvm::Function *getRuntimeFunction(llvm::StringRef str); - llvm::Function *getLLVMFunction(V4IR::Function *function); - llvm::Function *compileLLVMFunction(V4IR::Function *function); - llvm::BasicBlock *getLLVMBasicBlock(V4IR::BasicBlock *block); - llvm::Value *getLLVMTempReference(V4IR::Expr *expr); - llvm::Value *getLLVMCondition(V4IR::Expr *expr); - llvm::Value *getLLVMTemp(V4IR::Temp *temp); - llvm::Value *getStringPtr(const QString &s); - llvm::Value *getIdentifier(const QString &s); - llvm::AllocaInst *newLLVMTemp(llvm::Type *type, llvm::Value *size = 0); - llvm::Value * genArguments(V4IR::ExprList *args, int &argc); - void genCallTemp(V4IR::Call *e, llvm::Value *result = 0); - void genCallName(V4IR::Call *e, llvm::Value *result = 0); - void genCallMember(V4IR::Call *e, llvm::Value *result = 0); - void genConstructTemp(V4IR::New *e, llvm::Value *result = 0); - void genConstructName(V4IR::New *e, llvm::Value *result = 0); - void genConstructMember(V4IR::New *e, llvm::Value *result = 0); - llvm::Value *createValue(V4IR::Const *e); - llvm::Value *toValuePtr(V4IR::Expr *e); - llvm::Value *genStringList(const QList<const QString *> &strings, - const char *arrayName, const char *elementName); - - -private: - llvm::Module *_llvmModule; - llvm::Function *_llvmFunction; - llvm::Value *_llvmValue; - llvm::Type *_numberTy; - llvm::Type *_valueTy; - llvm::Type *_contextPtrTy; - llvm::Type *_stringPtrTy; - llvm::FunctionType *_functionTy; - llvm::Instruction *_allocaInsertPoint; - V4IR::Function *_function; - V4IR::BasicBlock *_block; - QHash<V4IR::Function *, llvm::Function *> _functionMap; - QHash<V4IR::BasicBlock *, llvm::BasicBlock *> _blockMap; - QVector<llvm::Value *> _tempMap; - QHash<QString, llvm::Value *> _stringMap; - llvm::FunctionPassManager *_fpm; -}; - -} // LLVM namespace -} // QQmlJS namespace - -#endif // QV4ISEL_LLVM_P_H diff --git a/src/qml/qml/v4/v4.pri b/src/qml/qml/v4/v4.pri index 1c63b4962a..4e230f42e0 100644 --- a/src/qml/qml/v4/v4.pri +++ b/src/qml/qml/v4/v4.pri @@ -1,10 +1,7 @@ -include(llvm_installation.pri) include(../../../3rdparty/masm/masm-defs.pri) CONFIG += exceptions -!llvm: DEFINES += QMLJS_NO_LLVM - CONFIG += warn_off INCLUDEPATH += $$PWD @@ -20,7 +17,6 @@ SOURCES += \ $$PWD/qv4value.cpp \ $$PWD/qv4syntaxchecker.cpp \ $$PWD/qv4isel_masm.cpp \ - $$PWD/llvm_runtime.cpp \ $$PWD/qv4isel_p.cpp \ $$PWD/qv4debugging.cpp \ $$PWD/qv4lookup.cpp \ @@ -117,39 +113,6 @@ HEADERS += \ $$PWD/qv4stacktrace_p.h \ $$PWD/qv4exception_p.h -llvm-libs { - -SOURCES += \ - $$PWD/qv4isel_llvm.cpp - -HEADERS += \ - $$PWD/qv4isel_llvm_p.h \ - $$PWD/qv4_llvm_p.h - -LLVM_RUNTIME_BC = $$PWD/llvm_runtime.bc -DEFINES += LLVM_RUNTIME="\"\\\"$$LLVM_RUNTIME_BC\\\"\"" -DEFINES += QMLJS_WITH_LLVM - -INCLUDEPATH += \ - $$system($$LLVM_CONFIG --includedir) - -QMAKE_CXXFLAGS += $$system($$LLVM_CONFIG --cppflags) -fvisibility-inlines-hidden -QMAKE_CXXFLAGS -= -pedantic -QMAKE_CXXFLAGS -= -Wcovered-switch-default - -LIBS += \ - $$system($$LLVM_CONFIG --ldflags) \ - $$system($$LLVM_CONFIG --libs core jit bitreader linker ipo target x86 arm native) - -QMAKE_EXTRA_TARGETS += gen_llvm_runtime - -GEN_LLVM_RUNTIME_FLAGS = $$system($$LLVM_CONFIG --cppflags) -GEN_LLVM_RUNTIME_FLAGS -= -pedantic - -gen_llvm_runtime.target = llvm_runtime -gen_llvm_runtime.commands = clang -O2 -emit-llvm -c -I$$PWD -I$$PWD/../3rdparty/masm $$join(QT.core.includes, " -I", "-I") $$GEN_LLVM_RUNTIME_FLAGS -DQMLJS_LLVM_RUNTIME llvm_runtime.cpp -o $$LLVM_RUNTIME_BC -} - # Use SSE2 floating point math on 32 bit instead of the default # 387 to make test results pass on 32 and on 64 bit builds. linux-g++*:isEqual(QT_ARCH,i386) { |