aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsstoragegeneralizer.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QmlCompiler: Coerce values when calling methodsUlf Hermann2024-12-191-0/+1
| | | | | | | | | | | | | | | The type of the register may not be the one to be passed to the method. We cannot rely on the run time internals to coerce the value anymore since we've moved the type determination out of the generated code. To make this happen, we need to adjust the storage types of read registers in the storage generalizer. Pick-to: 6.9 Fixes: QTBUG-132329 Change-Id: I642027f349f7c05f714ec36ef4e23f9d59b4a8df Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Store QQmlJSRegisterContent in place where we canUlf Hermann2024-12-031-1/+1
| | | | | | | | | | There is no need anymore to create a new QQmlJSRegisterContentPrivate just to add a storage type. Furthermore, we should record the generalization origin when generalizing storage. Task-number: QTBUG-124670 Change-Id: Ib1413e645fbc927806f85c7aa235c95a4cbfaa96 Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Pass QQmlJSRegisterContent by valueUlf Hermann2024-12-031-1/+1
| | | | | | | | | It's only a single pointer these days. Task-number: QTBUG-124670 Change-Id: Id51fe268108733b07d77c70531f38914a8adfdae Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Move type adjustment into QQmlJSRegisterContentUlf Hermann2024-11-281-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | This is the central piece of the refactoring. Instead of re-writing the QQmlJSScopes on adjustment we now rewrite the QQmlJSRegisterContents. The main benefit of this is that we can locally link QQmlJSRegisterContents together without invoking QQmlJSTypeResolver. The other benefit is that we gain more control over where the re-written types show up. QQmlJSScope is stored in many places that should really not be re-written. QQmlJSRegisterContent is only used locally when analyzing a binding or function. Finally, we can now chain the type adjustments with other operations on QQmlJSRegisterContents, without restrictions. This makes a few methods of QQmlJSTypeResolver obsolete. Those will be removed in a separate step. In order to get this right, we need to deviate from the notion that every read register is either a rename or a conversion. Rather, we must pass any "as-is" read of a register through that way. We rely on those to be re-written when the original register is. Task-number: QTBUG-124670 Change-Id: I0d968dfe495b82d9d9f67d598447bd2ad5bdcd04 Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Split QQmlJSRegisterContent in public and private classesUlf Hermann2024-11-201-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | We want an easy way to hold pointers to other QQmlJSRegisterContents in QQmlJSRegisterContent. Furthermore, copying a QQmlJSRegisterContent so far is very expensive. Solve both problems by introducing the PIMPL pattern with a shared d-pointer. This also changes the equality semantics of QQmlJSRegisterContent. Two QQmlJSRegisterContents are only equal if they contain the same d-pointer now, not if their contents are otherwise equal. However, since we generally don't rely on immediate equality of QQmlJSRegisterContent anyway, this is not a problem. QQmlJSTypeResolver::equals() still works. There is one place where the equality was used, though. That one is adapted. Furthermore, we now want to keep the register contents in a pool that's automatically cleared when we're done with our analysis. Therefore the creation methods cannot be static anymore and storedIn() as well as castTo() need to go through the pool as well. Task-number: QTBUG-124670 Change-Id: I0a51b609fc769ccb33c1d82930bda83c2a40e1a5 Reviewed-by: Olivier De Cannière <[email protected]>
* Compiler: Create infrastructure to support multiple warningsOlivier De Cannière2024-08-211-4/+2
| | | | | | | | | | | | | | | | | Currently only one DiagnosticMessage can be stored at a time when using the compiler. However, we want to be able to show more than one to the user. Therefore, use a list that gets passed inside the compiler instead of a pointer to the sole error. This also means that the error is valid by its very existence. There is no need to check validity explicitly anymore. Task-number: QTBUG-127624 Change-Id: I356db917b86703b508dc1ad52de7825d82eafd71 Reviewed-by: Ulf Hermann <[email protected]> Reviewed-by: Sami Shalayel <[email protected]>
* QmlCompiler: Create QQmlJSRegisterContent unstoredUlf Hermann2024-06-161-0/+1
| | | | | | | | | | Add a separate pass to populate the stored types and only run that after we're done with all the type propagation and optimization. Task-number: QTBUG-124670 Change-Id: I740063908b22684f5d2c72d6261fad98850d8636 Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Properly enforce signatures of AOT-compiled functionsUlf Hermann2024-04-261-4/+4
| | | | | | | | | | | | | Pass the metatypes of the contained types rather than the stored types. [ChangeLog][QtQml][Important Behavior Changes] The AOT compiled code for type-annotated JavaScript functions does not let you pass or return values of the wrong type anymore. Fixes: QTBUG-119885 Change-Id: I685d398c0745d32a999a3abd76c622a2c0d6651f Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* Compiler: Extract Basic blocks generation into its own compiler passOlivier De Cannière2024-04-191-6/+5
| | | | | | | | | | | | | | | The old basic blocks pass was responsible for two things: the basic blocks generation and dead code analysis/type adjustments based on those blocks and the type propagation performed earlier. Now the basic blocks get generated first, even before the type propagation and the dead code analysis and type adjustments are now grouped in a pass called QQmlJSOptimizations. The rest of the passes remain unchanged. Change-Id: I7b4303eaf67c761a49b82ab194e5d035d24d2615 Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Ulf Hermann <[email protected]>
* QmlCompiler: std::move() registers where possibleUlf Hermann2022-12-231-3/+2
| | | | | | | | | | | | In the common case that we read a register only once, in the same basic block, generate a std::move() in order to move it into place. Especially for QVariants holding large internal objects, this should help performance. Fixes: QTBUG-101452 Change-Id: I015892e1046ca7b739dbd296756f3f012dba5f9b Reviewed-by: Sami Shalayel <[email protected]>
* QmlCompiler: Allow lists as arguments to methodsUlf Hermann2022-11-101-2/+4
| | | | | | | | | | | | | | | | | | | Since lists are allowed as property types, you should be able to pass them as arguments to methods, too. For now we only handle QML-defined methods, implemented by adding JavaScript functions to your QML elements. The usual type coercion rules apply if you pass JavaScript arrays to such methods. That is, it usually works. We now resolve properties with the "list" flag to their actual types (QQmlListProperty or QList) already when populating the QQmlJSScope, and store the list types as members of QQmlJSScope rather than as a special map in QQmlJSTypeResolver. This allows us to do the same to lists passed as arguments and simplifies some of the type analysis. Fixes: QTBUG-107171 Change-Id: Idf71ccdc1d59f472c17084a36b5d7879c4d959c0 Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* Use SPDX license identifiersLucie Gérard2022-06-111-27/+2
| | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Pick-to: 6.4 Task-number: QTBUG-67283 Change-Id: I63563bbeb6f60f89d2c99660400dca7fab78a294 Reviewed-by: Shawn Rutledge <[email protected]>
* QmlCompiler: Add basic block analysis passUlf Hermann2022-03-091-22/+9
| | | | | | | | | | | | | | | | | | | This basic block analysis pass uses the tracked types to determine dead stores. This is better than the one we already have in the code generator because it also tracks dead stores through renames and it allows removal of lookup results. Furthermore, it adjusts each store to write the type most favorable to its readers. This avoids unnecessary conversions at run time. It cannot replace the other dead store elimination, yet, because it doesn't see whether the results of rename operations are read after the rename. This capability will be added in a separate change that also tracks the register numbers. Once this is in place, we can delete the other basic blocks pass. Task-number: QTBUG-100157 Change-Id: I766c919412b6cf43befa7bdb1a6e5e11b41fe55b Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Store arguments as QQmlJSRegisterContentUlf Hermann2022-03-031-12/+5
| | | | | | | | This way we can uniquely track the stored types throughout the compilation. Change-Id: Ibf3814a37f105c2eede2a08f547ab5fbfa1c16e2 Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Make InstructionAnnotations a QFlatMapUlf Hermann2022-02-251-2/+2
| | | | | | | | | We will need to iterate the annotations in program order. Therefore, we need an order map. QFlatMap fits here. Change-Id: I9a7fe68b0e5aa817257ceabb4853b1554d3ad709 Reviewed-by: Andrei Golubev <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Improve register trackingUlf Hermann2022-02-151-13/+19
| | | | | | | | | | | | | | | | | | | You can only change one register per instruction, and it doesn't have to be the accumulator. We don't have to store the full register set in every instruction annotation. It's enough to store the changed register. This simplifies the logic around choosing the in/out accumulator types. Now you can rely on the "in" accumulator to always be in the register set, and the "out" accumulator to be the changed register if applicable. There will typically be less than 10 registers active at any given instruction. Therefore, use QFlatMap to store them, rather than QHash. Also, rename the storage for the type conversions so that we can actually see what they are. Change-Id: I694ac2bce7911a4c290c1dccef34d28cde50a1d3 Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Document the compile passesUlf Hermann2021-11-261-0/+14
| | | | | | | Task-number: QTBUG-98305 Change-Id: I910d48183c1d78edf6c9d5ca80ceca07d276c702 Reviewed-by: Andrei Golubev <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Move type generalization into separate compile passUlf Hermann2021-11-261-0/+88
We want to be able to skip it. Task-number: QTBUG-98305 Change-Id: Ibb0293d348f2828a28be4c458cf955b4cc706caa Reviewed-by: Fabian Kosmale <[email protected]>