Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2196410/?format=api
{ "id": 2196410, "url": "http://patchwork.ozlabs.org/api/patches/2196410/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/066b01dc9d17$99e96250$cdbc26f0$@symas.com/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<066b01dc9d17$99e96250$cdbc26f0$@symas.com>", "list_archive_url": null, "date": "2026-02-13T18:35:59", "name": "[committed] cobol: Optimized alpha-to-alpha moves. [PR119455]", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "c91892b6e96269e83213127fed669517e974e757", "submitter": { "id": 88065, "url": "http://patchwork.ozlabs.org/api/people/88065/?format=api", "name": "Robert Dubner", "email": "rdubner@symas.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/066b01dc9d17$99e96250$cdbc26f0$@symas.com/mbox/", "series": [ { "id": 492131, "url": "http://patchwork.ozlabs.org/api/series/492131/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=492131", "date": "2026-02-13T18:35:59", "name": "[committed] cobol: Optimized alpha-to-alpha moves. [PR119455]", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/492131/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2196410/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2196410/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)", "sourceware.org;\n dmarc=none (p=none dis=none) header.from=symas.com", "sourceware.org; spf=pass smtp.mailfrom=symas.com", "server2.sourceware.org;\n arc=none smtp.remote-ip=52.37.197.7" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fCLV92TLMz1xpl\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 14 Feb 2026 05:36:33 +1100 (AEDT)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 1A3F64BAD148\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 13 Feb 2026 18:36:31 +0000 (GMT)", "from zmcc-2-mx.zmailcloud.com (zmcc-2-mx.zmailcloud.com\n [52.37.197.7])\n by sourceware.org (Postfix) with ESMTPS id 05F434B9DB6E\n for <gcc-patches@gcc.gnu.org>; Fri, 13 Feb 2026 18:36:01 +0000 (GMT)", "from zmcc-3.zmailcloud.com\n (ec2-3-15-255-223.us-east-2.compute.amazonaws.com [3.15.255.223])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by zmcc-2-mx.zmailcloud.com (Postfix) with ESMTPS id DAC18C8EC83\n for <gcc-patches@gcc.gnu.org>; Fri, 13 Feb 2026 12:35:59 -0600 (CST)", "from zmcc-3.zmailcloud.com (localhost [127.0.0.1])\n by zmcc-3-mta-1.zmailcloud.com (Postfix) with ESMTPS id 77A09A00E1A5\n for <gcc-patches@gcc.gnu.org>; Fri, 13 Feb 2026 12:35:59 -0600 (CST)", "from localhost (localhost [127.0.0.1])\n by zmcc-3-mta-1.zmailcloud.com (Postfix) with ESMTP id 6A11AA00E1A4\n for <gcc-patches@gcc.gnu.org>; Fri, 13 Feb 2026 12:35:59 -0600 (CST)", "from zmcc-3.zmailcloud.com ([127.0.0.1])\n by localhost (zmcc-3-mta-1.zmailcloud.com [127.0.0.1]) (amavis, port 10026)\n with ESMTP id ZwC1PQUtp_vs for <gcc-patches@gcc.gnu.org>;\n Fri, 13 Feb 2026 12:35:59 -0600 (CST)", "from zmcc-3-mailbox-1.zmailcloud.com\n (zmcc-3-mailbox-1.zmailcloud.com [172.31.18.168])\n by zmcc-3-mta-1.zmailcloud.com (Postfix) with ESMTP id 56DFFA00E1A5\n for <gcc-patches@gcc.gnu.org>; Fri, 13 Feb 2026 12:35:59 -0600 (CST)" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org 1A3F64BAD148", "OpenDKIM Filter v2.11.0 sourceware.org 05F434B9DB6E" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 05F434B9DB6E", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 05F434B9DB6E", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1771007761; cv=none;\n b=HK22WNccgDUWXzy4O3ACKN0LBcBf+GImJZr+aLz2/uD4fmlVv122Ajv/Rp5OrmrZOLoQpxDoV7Xz5KCku/94A8DNyMXrQzTFN7cga+KFvvSaAosr2IEIaitQzKw15gmW3aikW4YuZWsDYopMI7N8Xjmzs366+cmqbGyJCvsHTg8=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1771007761; c=relaxed/simple;\n bh=R3jp92lStcol47SKbfj2rlb6RthKvA8sFSIvIh7k47M=;\n h=From:To:Subject:Date:Message-ID:MIME-Version;\n b=p+nlQd4knCEvVmdkn2LrqhGuXreYXTssGY/mX20JE2jew3lXFSzwk7XyHsOYl4kOqLy3gYHE0JFYcjBeF1z7bXcCj7pM1cbHSom3776LHgHn1azd+d2V89pSCeiAYKVPz1qYbM0SRnaY8s20/ayqqnvSPUIyslJyfQ9hPleTBGk=", "ARC-Authentication-Results": "i=1; server2.sourceware.org", "From": "Robert Dubner <rdubner@symas.com>", "To": "<gcc-patches@gcc.gnu.org>", "Subject": "[committed] cobol: Optimized alpha-to-alpha moves. [PR119455]", "Thread-Topic": "[committed] cobol: Optimized alpha-to-alpha moves. [PR119455]", "Date": "Fri, 13 Feb 2026 12:35:59 -0600 (CST)", "Message-ID": "<066b01dc9d17$99e96250$cdbc26f0$@symas.com>", "MIME-Version": "1.0", "Content-Type": "text/plain;\n\tcharset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "X-Mailer": [ "Microsoft Outlook 16.0", "Zimbra 10.1.13_GA_4837 (Zimbra-ZCO/1949 (10.0.26200 en-US) P64c4\n T8a4 R4598)" ], "Content-Language": "en-us", "Thread-Index": "AdydF3mU6aToKsvAQQaIDqkEV/AcvQ==", "X-BeenThere": "gcc-patches@gcc.gnu.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>", "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>", "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>", "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org" }, "content": "From: Robert Dubner <rdubner@symas.com>\nDate: Fri, 13 Feb 2026 13:26:47 -0500\nSubject: [PATCH] cobol: Optimized alpha-to-alpha moves. [PR119455]\n\nCode for implementing many common scenarios of \"MOVE <literal> TO\n<alphanumeric>\" and \" MOVE <alphanumeric> to <alphanumeric> \" is created\ndirectly through GENERIC rather than by calling the general-purpose\nlibgcobol __gg__move routine.\n\ngcc/cobol/ChangeLog:\n\n\tPR cobol/119455\n\t* genapi.cc (mh_source_is_group): Formatting.\n\t(mh_source_is_literalA): Implement accelerated move.\n\t(mh_alpha_to_alpha): New function; implements accelerated move.\n\t(move_helper): Calls new mh_alpha_to_alpha.\n---\n gcc/cobol/genapi.cc | 238 +++++++++++++++++++++++++++++++++++++-------\n 1 file changed, 202 insertions(+), 36 deletions(-)\n\n && sourceref.field->codeset.encoding ==\ndestref.field->codeset.encoding\n && charmap->stride() == 1)\n@@ -15727,7 +15727,7 @@ mh_source_is_group( const cbl_refer_t &destref,\n }\n ELSE\n {\n- // There are too-few source bytes:\n+ // There are too few source bytes:\n int dest_space = charmap->mapped_character(ascii_space);\n gg_memset(tdest, build_int_cst_type(INT, dest_space), dbytes);\n gg_memcpy(tdest, tsource, sbytes);\n@@ -15861,38 +15861,91 @@ mh_source_is_literalA(const cbl_refer_t\n&destref,\n }\n }\n \n- // If the source is flagged ALL, or if we are setting the destination\nto\n- // a figurative constant, pass along the ALL bit:\n- int rounded_parameter = rounded\n- | ((sourceref.all || figconst ) ?\nREFER_ALL_BIT : 0);\n-\n- if( size_error )\n+ // Check to see if we can do a simple alphanumeric-to-alphanumeric\nmove\n+ if( ( destref.field->type == FldAlphanumeric\n+ || destref.field->type == FldGroup )\n+ && !(destref.field->attr & any_length_e)\n+ && !sourceref.all \n+ && !size_error)\n {\n- gg_assign(size_error,\n- gg_call_expr( INT,\n- \"__gg__move_literala\",\n-\ngg_get_address_of(destref.field->var_decl_node),\n- refer_offset(destref),\n- refer_size_dest(destref),\n- build_int_cst_type(INT, rounded_parameter),\n- build_string_literal(outlength,\n- buffer),\n- build_int_cst_type( SIZE_T, outlength),\n- NULL_TREE));\n+ // A simple alpha-to-alpha move is possible\n+ size_t dest_bytes = destref.field->data.capacity();\n+ // We have 'outlength' bytes in 'buffer' that need to go to\n+ // destref.field->data.capacity() bytes at destref.field->data.\n+ char *src = static_cast<char *>(xmalloc(dest_bytes));\n+ size_t src_bytes = std::min(outlength, dest_bytes);\n+ charmap_t *charmap =\n__gg__get_charmap(destref.field->codeset.encoding);\n+ charmap->memset(src, charmap->mapped_character(ascii_space),\ndest_bytes);\n+\n+ if( destref.field->attr & rjust_e )\n+ {\n+ size_t fill = 0;\n+ if( src_bytes < dest_bytes )\n+ {\n+ fill = dest_bytes - src_bytes;\n+ }\n+ memcpy(src+fill, buffer+outlength-src_bytes, src_bytes);\n+ }\n+ else\n+ {\n+ memcpy(src, buffer, src_bytes);\n+ }\n+ // src is now the desired string, space-filled if necessary on the\nright,\n+ // (or on the left, for rjust_e destinations).\n+\n+ if( refer_is_clean(destref) )\n+ {\n+ gg_memcpy(member(destref.field->var_decl_node, \"data\"),\n+ build_string_literal(dest_bytes, src),\n+ build_int_cst_type(SIZE_T, dest_bytes));\n+ }\n+ else\n+ {\n+ gg_memcpy(gg_add(member(destref.field->var_decl_node, \"data\"),\n+ refer_offset(destref)),\n+ build_string_literal(dest_bytes, src),\n+ refer_size_dest(destref));\n+ }\n+ free(src);\n }\n else\n {\n- gg_call ( INT,\n- \"__gg__move_literala\",\n-\ngg_get_address_of(destref.field->var_decl_node),\n- refer_offset(destref),\n- refer_size_dest(destref),\n- build_int_cst_type(INT, rounded_parameter),\n- build_string_literal(outlength,\n- buffer),\n- build_int_cst_type( SIZE_T, outlength),\n- NULL_TREE);\n+ // This is more complicated than a simple alpha-to-alpha move\n+\n+ // If the source is flagged ALL, or if we are setting the\ndestination to\n+ // a figurative constant, pass along the ALL bit:\n+ int rounded_parameter = rounded\n+ | ((sourceref.all || figconst ) ?\nREFER_ALL_BIT : 0);\n+\n+ if( size_error )\n+ {\n+ gg_assign(size_error,\n+ gg_call_expr( INT,\n+ \"__gg__move_literala\",\n+\ngg_get_address_of(destref.field->var_decl_node),\n+ refer_offset(destref),\n+ refer_size_dest(destref),\n+ build_int_cst_type(INT,\nrounded_parameter),\n+ build_string_literal(outlength,\n+ buffer),\n+ build_int_cst_type( SIZE_T, outlength),\n+ NULL_TREE));\n+ }\n+ else\n+ {\n+ gg_call ( INT,\n+ \"__gg__move_literala\",\n+\ngg_get_address_of(destref.field->var_decl_node),\n+ refer_offset(destref),\n+ refer_size_dest(destref),\n+ build_int_cst_type(INT,\nrounded_parameter),\n+ build_string_literal(outlength,\n+ buffer),\n+ build_int_cst_type( SIZE_T, outlength),\n+ NULL_TREE);\n+ }\n }\n+\n if( destref.refmod.from\n || destref.refmod.len )\n {\n@@ -15904,6 +15957,118 @@ mh_source_is_literalA(const cbl_refer_t\n&destref,\n return moved;\n }\n \n+static bool\n+mh_alpha_to_alpha(const cbl_refer_t &destref,\n+ const cbl_refer_t &sourceref,\n+ cbl_round_t /*rounded*/,\n+ tree size_error)\n+ {\n+ bool moved = false;\n+ // If a bunch of conditions are met, we can do a move without resorting\nto\n+ // the library.\n+ if( sourceref.field->type == FldAlphanumeric\n+ && destref.field->type == FldAlphanumeric\n+ && !size_error\n+ && sourceref.field->codeset.encoding ==\ndestref.field->codeset.encoding\n+ && !destref.refmod.from\n+ && !destref.refmod.len\n+ && !(destref.field->attr & rjust_e)\n+ && !(sourceref.field->attr & any_length_e)\n+ && !(destref.field->attr & any_length_e)\n+ && !(sourceref.field->attr & intermediate_e)\n+ && !sourceref.all\n+ )\n+ {\n+ // We are in a position to simply move bytes from the source to the\ndest.\n+ if( refer_is_clean(sourceref) && refer_is_clean(destref) )\n+ {\n+ // Source and destination are both clean\n+ if( destref.field->data.capacity() <=\nsourceref.field->data.capacity() )\n+ {\n+ // This is the simplest case of all\n+ gg_memcpy(member( destref.field->var_decl_node, \"data\"),\n+ member(sourceref.field->var_decl_node, \"data\"),\n+ build_int_cst_type(SIZE_T,\ndestref.field->data.capacity()));\n+ moved = true;\n+ }\n+ else\n+ {\n+ // This is a tad more complicated. The source is too short, so\nwe need\n+ // to copy over what we can...\n+ gg_memcpy(member( destref.field->var_decl_node, \"data\"),\n+ member(sourceref.field->var_decl_node, \"data\"),\n+ build_int_cst_type(SIZE_T,\nsourceref.field->data.capacity()));\n+ // And then space-fill the rest:\n+ size_t fill_bytes =\n+ destref.field->data.capacity() -\nsourceref.field->data.capacity();\n+\n+ // ...and then create a memory area with the fill spaces...\n+ char *spaces = static_cast<char *>(xmalloc(fill_bytes));\n+ charmap_t *charmap\n=__gg__get_charmap(destref.field->codeset.encoding);\n+ charmap->memset(spaces,\n+ charmap->mapped_character(ascii_space),\n+ fill_bytes);\n+ // ...and then copy those spaces into place.\n+ gg_memcpy(\n+ gg_add(member(destref.field->var_decl_node, \"data\"),\n+ build_int_cst_type(SIZE_T,\nsourceref.field->data.capacity())),\n+ build_string_literal(fill_bytes, spaces),\n+ build_int_cst_type(SIZE_T, fill_bytes));\n+ free(spaces);\n+ moved = true;\n+ }\n+ }\n+ else\n+ {\n+ // Either the source or the dest is a table or refmod, so we need\nto do\n+ // more work.\n+ tree source_data = gg_define_variable(UCHAR_P);\n+ tree source_len = gg_define_variable(SIZE_T);\n+\n+ tree dest_data = gg_define_variable(UCHAR_P);\n+ tree dest_len = gg_define_variable(SIZE_T);\n+\n+ gg_assign(source_data,\n+ gg_add(member(sourceref.field->var_decl_node, \"data\"),\n+ refer_offset(sourceref)));\n+ gg_assign(source_len, refer_size_source(sourceref));\n+\n+ gg_assign(dest_data,\n+ gg_add(member(destref.field->var_decl_node, \"data\"),\n+ refer_offset(destref)));\n+ gg_assign(dest_len, refer_size_dest(destref));\n+ IF( source_len, ge_op, dest_len )\n+ {\n+ // The source has enough (or more) bytes to fill the destination:\n+ gg_memcpy(dest_data, source_data, dest_len);\n+ }\n+ ELSE\n+ {\n+ // The source data is too short. We need to copy over what we\nhave...\n+ gg_memcpy(dest_data, source_data, source_len);\n+\n+ // And then right-fill the remainder with spaces. Create a buffer\nwith\n+ // more than enough spaces for our purposes:\n+ size_t fill_bytes = destref.field->data.capacity();\n+ char *spaces = static_cast<char *>(xmalloc(fill_bytes));\n+ charmap_t *charmap\n=__gg__get_charmap(destref.field->codeset.encoding);\n+ charmap->memset(spaces,\n+ charmap->mapped_character(ascii_space),\n+ fill_bytes);\n+ // And then copy enough of those spaces into place.\n+ gg_memcpy(gg_add(dest_data, source_len),\n+ build_string_literal(fill_bytes, spaces),\n+ gg_subtract(dest_len, source_len));\n+ free(spaces);\n+ }\n+ ENDIF\n+\n+ moved = true;\n+ }\n+ }\n+ return moved;\n+ }\n+\n static void\n move_helper(tree size_error, // This is an INT\n cbl_refer_t destref,\n@@ -15932,7 +16097,6 @@ move_helper(tree size_error, // This is an\nINT\n \n tree st_data = NULL_TREE;\n tree st_size = NULL_TREE;\n-\n if( restore_on_error )\n {\n // We are creating a copy of the original destination in case we\nclobber it\n@@ -15956,12 +16120,6 @@ move_helper(tree size_error, // This is an\nINT\n st_size);\n }\n \n- if( (sourceref.field->attr & (linkage_e | based_e))\n- || ( destref.field->attr & (linkage_e | based_e)) )\n- {\n- //goto dont_be_clever; this will go through to the default.\n- }\n-\n // if( !moved ) // commented out to quiet cppcheck\n {\n moved = mh_source_is_group(destref, sourceref, tsource);\n@@ -16015,6 +16173,14 @@ move_helper(tree size_error, // This is an\nINT\n size_error);\n }\n \n+ if( !moved )\n+ {\n+ moved = mh_alpha_to_alpha(destref,\n+ sourceref,\n+ rounded,\n+ size_error);\n+ }\n+\n if( !moved )\n {\n SHOW_PARSE1", "diff": "diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc\nindex 6f8ce1889bd..78122c12b16 100644\n--- a/gcc/cobol/genapi.cc\n+++ b/gcc/cobol/genapi.cc\n@@ -15705,7 +15705,7 @@ mh_source_is_group( const cbl_refer_t &destref,\n const TREEPLET &tsrc)\n {\n bool retval = false;\n- charmap_t *charmap = __gg__get_charmap(destref.field->codeset.encoding);\n+ charmap_t *charmap =\n__gg__get_charmap(destref.field->codeset.encoding);\n if( sourceref.field->type == FldGroup && !(destref.field->attr &\nrjust_e)\n", "prefixes": [ "committed" ] }