From: Luca Bruno Date: Sat, 1 Feb 2014 10:10:52 +0000 (+0100) Subject: Return (owned) for temp variables when possible to avoid useless copies X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b758dca2107221fbfd7fb6bd8e8ce9115d7eea2b;p=thirdparty%2Fvala.git Return (owned) for temp variables when possible to avoid useless copies --- diff --git a/codegen/valaccodetransformer.vala b/codegen/valaccodetransformer.vala index b63c20211..cfa7fa2b1 100644 --- a/codegen/valaccodetransformer.vala +++ b/codegen/valaccodetransformer.vala @@ -377,11 +377,9 @@ public class Vala.CCodeTransformer : CodeTransformer { var target_type = copy_type (expr.target_type); push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); - // FIXME: use create_temp_access behavior - var replacement = expression (b.add_temp_declaration (copy_type (expr.value_type), expr, true)); + var local = b.add_temp_declaration (copy_type (expr.value_type), expr); + var replacement = return_temp_access (local, expr.value_type, target_type, formal_target_type); - replacement.target_type = copy_type (target_type); - replacement.formal_target_type = copy_type (formal_target_type); context.analyzer.replaced_nodes.add (expr); old_parent_node.replace_expression (expr, replacement); b.check (this); @@ -514,13 +512,13 @@ public class Vala.CCodeTransformer : CodeTransformer { Report.error (expr.source_reference, "Field initializers must not throw errors"); } else { var old_parent_node = expr.parent_node; - var target_type = expr.target_type != null ? expr.target_type.copy () : null; + var target_type = copy_type (expr.target_type); + var formal_target_type = copy_type (expr.formal_target_type); push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); - // FIXME: use create_temp_access behavior - var replacement = expression (b.add_temp_declaration (expr.value_type, expr, true)); + var local = b.add_temp_declaration (expr.value_type, expr); + var replacement = return_temp_access (local, expr.value_type, target_type, formal_target_type); - replacement.target_type = target_type; context.analyzer.replaced_nodes.add (expr); old_parent_node.replace_expression (expr, replacement); b.check (this); diff --git a/vala/valacodebuilder.vala b/vala/valacodebuilder.vala index 51433956b..7a09f3b6e 100644 --- a/vala/valacodebuilder.vala +++ b/vala/valacodebuilder.vala @@ -247,9 +247,8 @@ public class Vala.CodeBuilder { add_statement (new ContinueStatement (source_reference)); } - public string add_temp_declaration (DataType? type, Expression? initializer = null, bool floating = false) { + public string add_temp_declaration (DataType? type, Expression? initializer = null) { var local = new LocalVariable (type, CodeNode.get_temp_name (), initializer, source_reference); - // FIXME: use create_temp_access behavior var stmt = new DeclarationStatement (local, source_reference); insert_block.insert_before (insert_statement, stmt); decl_nodes.add (stmt); diff --git a/vala/valacodetransformer.vala b/vala/valacodetransformer.vala index 4b78a9470..c70ce2073 100644 --- a/vala/valacodetransformer.vala +++ b/vala/valacodetransformer.vala @@ -77,6 +77,23 @@ public class Vala.CodeTransformer : CodeVisitor { return ret; } + // Create an access to a temporary variable, with proper reference transfer if needed to avoid unnecessary copies + public Expression return_temp_access (string local, DataType value_type, DataType? target_type, DataType? formal_target_type = null) { + Expression temp_access = new MemberAccess.simple (local, b.source_reference); + + var target_owned = target_type != null && target_type.value_owned; + if (target_owned && value_type.is_disposable ()) { + temp_access = new ReferenceTransferExpression (temp_access, b.source_reference); + temp_access.target_type = target_type != null ? target_type.copy () : value_type.copy (); + temp_access.target_type.value_owned = true; + temp_access.formal_target_type = copy_type (formal_target_type); + } else { + temp_access.target_type = copy_type (target_type); + } + + return temp_access; + } + public bool get_cached_wrapper (string key, out CodeNode node) { node = wrapper_cache.get (key); return node != null; diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 474ca18c1..060c81bb9 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -935,22 +935,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return false; } - // Create an access to a temporary variable, with proper reference transfer if needed - public static Expression create_temp_access (LocalVariable local, DataType? target_type) { - Expression temp_access = new MemberAccess.simple (local.name, local.source_reference); - - var target_owned = target_type != null && target_type.value_owned; - if (target_owned && local.variable_type.is_disposable ()) { - temp_access = new ReferenceTransferExpression (temp_access, local.source_reference); - temp_access.target_type = target_type != null ? target_type.copy () : local.variable_type.copy (); - temp_access.target_type.value_owned = true; - } else { - temp_access.target_type = target_type != null ? target_type.copy () : null; - } - - return temp_access; - } - public void visit_member_initializer (MemberInitializer init, DataType type) { init.symbol_reference = symbol_lookup_inherited (type.data_type, init.name); if (!(init.symbol_reference is Field || init.symbol_reference is Property)) {