From 22a0c200c6ba61e9c8067625b7386b460d47aa8a Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Wed, 25 Jan 2023 00:46:32 -0600 Subject: [PATCH] [GDScript] Perform update-and-assign operations in place when possible. This turns two bytecode operations into one by using the assignment destination directly as the output of the binary operator. This manifests in operations like `+=`. --- modules/gdscript/gdscript_compiler.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index c78dd1528f4..57011c27817 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1171,8 +1171,18 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code bool has_operation = assignment->operation != GDScriptParser::AssignmentNode::OP_NONE; if (has_operation) { // Perform operation. - GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype(), codegen.script)); GDScriptCodeGenerator::Address og_value = _parse_expression(codegen, r_error, assignment->assignee); + + if (!has_setter && !assignment->use_conversion_assign) { + // If there's nothing special about the assignment, perform the assignment as part of the operator + gen->write_binary_operator(target, assignment->variant_op, og_value, assigned_value); + if (assigned_value.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); // Pop assigned value if not done before. + } + return GDScriptCodeGenerator::Address(); + } + + GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype(), codegen.script)); gen->write_binary_operator(op_result, assignment->variant_op, og_value, assigned_value); to_assign = op_result;