aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-10-24 16:30:28 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-11-01 16:10:58 +0000
commit1d428b22f7ce4ecdff10a040070d619bb9c528f6 (patch)
tree978d06a34f3ce4f5062c0dc88b738e1978ce0148
parent3b161eebf7f48cc654f8e31aca5be3816dbc5036 (diff)
QmlCompiler: Generate jump code also when skipping an instruction
The next instruction may still need the type conversions even if we don't need to generate any code for the current instruction. Also, generate trace info for generate_DeadTemporalZoneCheck so that we can recognize it in the generated code. Amends commit 2c410317b6077fdcfb2cdeb4b730c1b0c544147e. Pick-to: 6.5 Fixes: QTBUG-118514 Change-Id: I70ad3691486176de2177e9d5f538f7c99d121bfa Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> (cherry picked from commit c662ae7cbf49bdfc9fd96d34301a86fe96550773) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/qmlcompiler/qqmljscodegenerator.cpp5
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt1
-rw-r--r--tests/auto/qml/qmlcppcodegen/data/conversionInDeadCode.qml32
-rw-r--r--tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp20
4 files changed, 57 insertions, 1 deletions
diff --git a/src/qmlcompiler/qqmljscodegenerator.cpp b/src/qmlcompiler/qqmljscodegenerator.cpp
index 611e0db73c..7ee6e24cb4 100644
--- a/src/qmlcompiler/qqmljscodegenerator.cpp
+++ b/src/qmlcompiler/qqmljscodegenerator.cpp
@@ -1976,6 +1976,7 @@ void QQmlJSCodeGenerator::generate_UnwindToLabel(int level, int offset)
void QQmlJSCodeGenerator::generate_DeadTemporalZoneCheck(int name)
{
Q_UNUSED(name)
+ INJECT_TRACE_INFO(generate_DeadTemporalZoneCheck);
// Nothing to do here. If we have statically asserted the dtz check in the type propagator
// the value cannot be empty. Otherwise we can't get here.
}
@@ -2751,8 +2752,10 @@ QV4::Moth::ByteCodeHandler::Verdict QQmlJSCodeGenerator::startInstruction(
// If the instruction has no side effects and doesn't write any register, it's dead.
// We might still need the label, though, and the source code comment.
- if (!m_state.hasSideEffects() && changedRegisterVariable().isEmpty())
+ if (!m_state.hasSideEffects() && changedRegisterVariable().isEmpty()) {
+ generateJumpCodeWithTypeConversions(0);
return SkipInstruction;
+ }
return ProcessInstruction;
}
diff --git a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
index 34e87ecb22..37d953ec8e 100644
--- a/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
+++ b/tests/auto/qml/qmlcppcodegen/data/CMakeLists.txt
@@ -86,6 +86,7 @@ set(qml_files
construct.qml
contextParam.qml
conversionDecrement.qml
+ conversionInDeadCode.qml
conversions.qml
conversions2.qml
convertToOriginalReadAcumulatorForUnaryOperators.qml
diff --git a/tests/auto/qml/qmlcppcodegen/data/conversionInDeadCode.qml b/tests/auto/qml/qmlcppcodegen/data/conversionInDeadCode.qml
new file mode 100644
index 0000000000..b2e7b40c00
--- /dev/null
+++ b/tests/auto/qml/qmlcppcodegen/data/conversionInDeadCode.qml
@@ -0,0 +1,32 @@
+pragma Strict
+import QtQml
+
+QtObject {
+ // This does not look like dead code, but each access to 'result' generates a
+ // DeadTemoralZoneCheck instruction that we ignore when compiling to C++
+ // after checking statically that 'result' is alive throughout the function.
+ // Therefore, this function is a torture test for the dead code elimination.
+ function calc(a: int, b: int) : int {
+ let result = a;
+ if (b < 0) {
+ if (b < -1)
+ result -= b;
+ if (b < -2)
+ result /= b;
+ } else {
+ if (b > 1)
+ result *= b;
+ if (b > 2)
+ result += b;
+ }
+ return result;
+ }
+
+ property int a: calc(10, -3);
+ property int b: calc(10, -2);
+ property int c: calc(10, -1);
+ property int d: calc(10, 0);
+ property int e: calc(10, 1);
+ property int f: calc(10, 2);
+ property int g: calc(10, 3);
+}
diff --git a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
index a54528816e..b1e97b2560 100644
--- a/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
+++ b/tests/auto/qml/qmlcppcodegen/tst_qmlcppcodegen.cpp
@@ -60,6 +60,7 @@ private slots:
void construct();
void contextParam();
void conversionDecrement();
+ void conversionInDeadCode();
void conversions();
void convertToOriginalReadAcumulatorForUnaryOperators();
void cppValueTypeList();
@@ -1057,6 +1058,25 @@ void tst_QmlCppCodegen::conversionDecrement()
QCOMPARE(o->property("currentPageIndex").toInt(), 3);
}
+void tst_QmlCppCodegen::conversionInDeadCode()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, QUrl(u"qrc:/qt/qml/TestTypes/conversionInDeadCode.qml"_s));
+
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+
+ QCOMPARE(o->property("a").toInt(), -4);
+ QCOMPARE(o->property("b").toInt(), 12);
+ QCOMPARE(o->property("c").toInt(), 10);
+ QCOMPARE(o->property("d").toInt(), 10);
+ QCOMPARE(o->property("e").toInt(), 10);
+ QCOMPARE(o->property("f").toInt(), 20);
+ QCOMPARE(o->property("g").toInt(), 33);
+}
+
void tst_QmlCppCodegen::conversions()
{
QQmlEngine engine;