Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/89706/?format=api
{ "id": 89706, "url": "http://patchwork.ozlabs.org/api/patches/89706/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/CE36BD26828FA5408B9F87E4DD2ACB0B92B7726494@MBXVS01.HMC.local/", "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": "<CE36BD26828FA5408B9F87E4DD2ACB0B92B7726494@MBXVS01.HMC.local>", "list_archive_url": null, "date": "2011-04-04T20:20:56", "name": "ARM generate constants for non load scheduling arch patch", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "c00870464a1f30b5dee6a82154490f169fd7cc6b", "submitter": { "id": 7587, "url": "http://patchwork.ozlabs.org/api/people/7587/?format=api", "name": "sarah@hederstierna.com", "email": "fredrik@hederstierna.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/CE36BD26828FA5408B9F87E4DD2ACB0B92B7726494@MBXVS01.HMC.local/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/89706/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/89706/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-return-288657-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "mailing list gcc-patches@gcc.gnu.org" ], "Received": [ "from sourceware.org (server1.sourceware.org [209.132.180.131])\n\tby ozlabs.org (Postfix) with SMTP id 8C852B6FBE\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 5 Apr 2011 06:22:48 +1000 (EST)", "(qmail 17340 invoked by alias); 4 Apr 2011 20:22:44 -0000", "(qmail 17005 invoked by uid 22791); 4 Apr 2011 20:22:39 -0000", "from hubext01.fsdata.se (HELO smtp04.fsdata.se) (195.35.82.70) by\n\tsourceware.org (qpsmtpd/0.43rc1) with ESMTP;\n\tMon, 04 Apr 2011 20:22:31 +0000", "from MBXVS01.HMC.local ([192.168.46.111]) by hubext01.HMC.local\n\t([192.168.46.130]) with mapi; Mon, 4 Apr 2011 22:22:28 +0200" ], "X-SWARE-Spam-Status": "No, hits=-2.4 required=5.0\ttests=AWL, BAYES_00,\n\tRCVD_IN_DNSWL_LOW, TW_XF", "X-Spam-Check-By": "sourceware.org", "From": "\"sarah@hederstierna.com\" <fredrik@hederstierna.com>", "To": "\"gcc-patches@gcc.gnu.org\" <gcc-patches@gcc.gnu.org>", "Date": "Mon, 4 Apr 2011 22:20:56 +0200", "Subject": "ARM generate constants for non load scheduling arch patch", "Message-ID": "<CE36BD26828FA5408B9F87E4DD2ACB0B92B7726494@MBXVS01.HMC.local>", "Content-Type": "multipart/mixed;\n\tboundary=\"_002_CE36BD26828FA5408B9F87E4DD2ACB0B92B7726494MBXVS01HMCloc_\"", "MIME-Version": "1.0", "Mailing-List": "contact gcc-patches-help@gcc.gnu.org; run by ezmlm", "Precedence": "bulk", "List-Id": "<gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<mailto:gcc-patches-unsubscribe-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "List-Archive": "<http://gcc.gnu.org/ml/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-help@gcc.gnu.org>", "Sender": "gcc-patches-owner@gcc.gnu.org" }, "content": "Hi!\n\nI was recently cleaning my old sources attic, and I found this old GCC-patch for ARM that never was contributed. First I was thinking to just delete it, but then I thought that maybe someone can make use it, or be inspired to do something with it.\n\nThe patch is 5-6 years old so I really think it needs checking again for correctness by some ARM maintainer.\n\nThe idea is that when generating constants for ARM, then on architectures where LDR is very expensive and optimizing for speed, it can be faster to allow adding some more instructions to avoid LDR-instructions.\n\nFor example ARM7TDMI-S core without load scheduling support, when optimizing with -O3 we could allow some more instructions to get better pipeline efficiency and faster code without LDR.\n(Also some instructions like shifts could potentially be merged into the following intructions.)\n\nPlease check to patch if you are interested, it contains first a section where I added a check for non-load-scheduling target, then three new separated different constant-generating algorithms that could be added stand-alone.\n\nAnd again, the patches are very old I cannot guarantee its 100% up to date.\nCheck it out if your are interested and use with care :)\n\nThanks and Best Regards,\n\nFredrik Hederstierna\nSecuritas Direct AB\nMalmoe SWEDEN", "diff": "Index: gcc/config/arm/arm.c\n===================================================================\n*** gcc/config/arm/arm.c\t(revision 171910)\n--- gcc/config/arm/arm.c\t(working copy)\n*************** arm_split_constant (enum rtx_code code, \n*** 2535,2576 ****\n \t Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c\n */\n if (!after_arm_reorg\n! \t && !cond\n! \t && (arm_gen_constant (code, mode, NULL_RTX, val, target, source,\n! \t\t\t\t1, 0)\n! \t > (arm_constant_limit (optimize_function_for_size_p (cfun))\n! \t\t + (code != SET))))\n! \t{\n! \t if (code == SET)\n! \t {\n! \t /* Currently SET is the only monadic value for CODE, all\n! \t\t the rest are diadic. */\n! \t if (TARGET_USE_MOVT)\n! \t\tarm_emit_movpair (target, GEN_INT (val));\n! \t else\n! \t\temit_set_insn (target, GEN_INT (val));\n! \n! \t return 1;\n! \t }\n! \t else\n! \t {\n! \t rtx temp = subtargets ? gen_reg_rtx (mode) : target;\n! \n! \t if (TARGET_USE_MOVT)\n! \t\tarm_emit_movpair (temp, GEN_INT (val));\n! \t else\n! \t\temit_set_insn (temp, GEN_INT (val));\n \n! \t /* For MINUS, the value is subtracted from, since we never\n! \t\t have subtraction of a constant. */\n! \t if (code == MINUS)\n! \t\temit_set_insn (target, gen_rtx_MINUS (mode, temp, source));\n! \t else\n! \t\temit_set_insn (target,\n! \t\t\t gen_rtx_fmt_ee (code, mode, source, temp));\n! \t return 2;\n! \t }\n! \t}\n }\n \n return arm_gen_constant (code, mode, cond, val, target, source, subtargets,\n--- 2535,2589 ----\n \t Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c\n */\n if (!after_arm_reorg\n! \t && !cond)\n! {\n! bool size_p = optimize_function_for_size_p (cfun);\n! int constant_insn_limit = arm_constant_limit (size_p) + (code != SET);\n! \n! /* If not optimize for size and set constant code,\n! then allow two extra insn if not load scheduling supported */\n! if ((!size_p) && (optimize > 2)\n! && (code == SET)\n! && (constant_insn_limit == 1)\n! && !arm_ld_sched)\n! {\n! constant_insn_limit += 2;\n! }\n \n! \t if (arm_gen_constant (code, mode, NULL_RTX, val, target, source,\n! \t\t\t\t1, 0) > constant_insn_limit)\n! {\n! if (code == SET)\n! {\n! /* Currently SET is the only monadic value for CODE, all\n! the rest are diadic. */\n! if (TARGET_USE_MOVT)\n! arm_emit_movpair (target, GEN_INT (val));\n! else\n! emit_set_insn (target, GEN_INT (val));\n! \n! return 1;\n! }\n! else\n! {\n! rtx temp = subtargets ? gen_reg_rtx (mode) : target;\n! \n! if (TARGET_USE_MOVT)\n! arm_emit_movpair (temp, GEN_INT (val));\n! else\n! emit_set_insn (temp, GEN_INT (val));\n! \n! /* For MINUS, the value is subtracted from, since we never\n! have subtraction of a constant. */\n! if (code == MINUS)\n! emit_set_insn (target, gen_rtx_MINUS (mode, temp, source));\n! else\n! emit_set_insn (target,\n! gen_rtx_fmt_ee (code, mode, source, temp));\n! return 2;\n! }\n! }\n! }\n }\n \n return arm_gen_constant (code, mode, cond, val, target, source, subtargets,\n*************** arm_gen_constant (enum rtx_code code, en\n*** 2884,2889 ****\n--- 2897,2929 ----\n \t return 1;\n \t}\n \n+ /* See of we can generate this by set 8 bits and then shift. */\n+ \n+ /* For ARM we can generate 8 bit value with even number of\n+ shift steps, but we have a special case where we must need\n+ an odd number of steps, example 0x7f800000 or 0x40800000.\n+ Constants of the form eg. (0x00FF0000 >> 1).\n+ Also the shift may well merge into a subsequent insn. */\n+ \n+ /* If odd number leading zeros and 8 bit constant */\n+ if ((clear_sign_bit_copies & 1) &&\n+ ((clear_sign_bit_copies + clear_zero_bit_copies) == 24))\n+ {\n+ temp1 = ARM_SIGN_EXTEND (remainder << clear_sign_bit_copies);\n+ \n+ if (generate)\n+ {\n+ rtx new_src = subtargets ? gen_reg_rtx (mode) : target;\n+ emit_constant_insn (cond,\n+ gen_rtx_SET (VOIDmode, new_src,\n+ GEN_INT (temp1)));\n+ emit_constant_insn (cond,\n+ gen_lshrsi3 (target, new_src,\n+ GEN_INT (clear_sign_bit_copies)));\n+ }\n+ return 2; \n+ }\n+ \n /* See if we can do this by sign_extending a constant that is known\n \t to be negative. This is a good, way of doing it, since the shift\n \t may well merge into a subsequent insn. */\n*************** arm_gen_constant (enum rtx_code code, en\n*** 2959,2964 ****\n--- 2999,3152 ----\n \t }\n \t}\n \n+ /* See of we can generate constant by set 8 bits and then shift in zeros\n+ from left or right.\n+ Eg. 0xfffefdf8 (using lsl) or 0x1ffefdff (using lsr)\n+ */\n+ \n+ /* If any leading zeros */\n+ if (clear_sign_bit_copies > 0)\n+ {\n+ /* Shift up leading zeros */\n+ temp1 = remainder << clear_sign_bit_copies;\n+ /* Set lowest bits */\n+ temp2 = (1 << clear_sign_bit_copies) - 1;\n+ temp1 |= temp2;\n+ \n+ /* Try negate and check if value can be loaded into 8 bits */\n+ temp2 = ~temp1;\n+ /* Count and shift down trailing zeros */\n+ for (i = 0; i <= 31; i++)\n+ {\n+ if (temp2 & 1)\n+ break;\n+ else\n+ temp2 >>= 1;\n+ }\n+ \n+ if ((temp2 < 256) || (((temp2 & 0xffff0000) == 0) &&\n+ (temp2 & 0x8000)))\n+ {\n+ \t if (generate)\n+ \t\t{\n+ \t\t rtx new_src = subtargets ? gen_reg_rtx (mode) : target;\n+ \n+ \t\t insns = arm_gen_constant (code, /* SET */\n+ mode,\n+ cond,\n+ \t\t\t\t\t temp1,\n+ \t\t\t\t\t new_src,\n+ source,\n+ subtargets,\n+ 1);\n+ \t\t source = new_src;\n+ \t\t}\n+ \t else\n+ \t\t{\n+ \t\t rtx new_src = subtargets ? NULL_RTX : target;\n+ \n+ \t\t insns = arm_gen_constant (code, /* SET */\n+ mode,\n+ cond,\n+ \t\t\t\t\t temp1,\n+ \t\t\t\t\t new_src,\n+ source,\n+ subtargets,\n+ 0);\n+ \t\t source = new_src;\n+ \t\t}\n+ \n+ if (generate)\n+ {\n+ /* rtx new_src = subtargets ? gen_reg_rtx (mode) : target; */\n+ rtx shift = GEN_INT (clear_sign_bit_copies);\n+ \n+ \n+ emit_constant_insn (cond,\n+ gen_rtx_SET (VOIDmode,\n+ target,\n+ gen_rtx_LSHIFTRT (mode,\n+ source,\n+ shift)));\n+ \n+ /* emit_constant_insn (cond, gen_lshrsi3 (target, new_src, shift)); */\n+ }\n+ \n+ return insns + 1;\n+ }\n+ }\n+ \n+ /* If any trailing zeros */\n+ if (clear_zero_bit_copies > 0)\n+ {\n+ /* Shift down trailing zeros */\n+ temp1 = remainder >> clear_zero_bit_copies;\n+ /* Set highest bits */\n+ temp2 = (1 << clear_zero_bit_copies) - 1;\n+ temp1 |= (temp2 << (32 - clear_zero_bit_copies));\n+ \n+ /* Try negate and check if value can be loaded into 8 bits */\n+ temp2 = ~temp1;\n+ /* Count and shift down trailing zeros */\n+ for (i = 0; i <= 31; i++)\n+ {\n+ if (temp2 & 1)\n+ break;\n+ else\n+ temp2 >>= 1;\n+ }\n+ \n+ if ((temp2 < 256) || (((temp2 & 0xffff0000) == 0) &&\n+ (temp2 & 0x8000)))\n+ {\n+ \t if (generate)\n+ \t\t{\n+ \t\t rtx new_src = subtargets ? gen_reg_rtx (mode) : target;\n+ \n+ \t\t insns = arm_gen_constant (code, /* SET */\n+ mode,\n+ cond,\n+ \t\t\t\t\t temp1,\n+ \t\t\t\t\t new_src,\n+ source,\n+ subtargets,\n+ 1);\n+ \t\t source = new_src;\n+ \t\t}\n+ \t else\n+ \t\t{\n+ \t\t rtx new_src = subtargets ? NULL_RTX : target;\n+ \n+ \t\t insns = arm_gen_constant (code, /* SET */\n+ mode,\n+ cond,\n+ \t\t\t\t\t temp1,\n+ \t\t\t\t\t new_src,\n+ source,\n+ subtargets,\n+ 0);\n+ \t\t source = new_src;\n+ \t\t}\n+ \n+ if (generate)\n+ {\n+ /* rtx new_src = subtargets ? gen_reg_rtx (mode) : target; */\n+ rtx shift = GEN_INT (clear_zero_bit_copies);\n+ \n+ emit_constant_insn (cond,\n+ gen_rtx_SET (VOIDmode,\n+ target,\n+ gen_rtx_ASHIFT (mode,\n+ source,\n+ shift)));\n+ \n+ /* emit_constant_insn (cond, gen_lshrsi3 (target, new_src, shift)); */\n+ }\n+ \n+ return insns + 1;\n+ }\n+ }\n+ \n /* See if we can generate this by setting the bottom (or the top)\n \t 16 bits, and then shifting these into the other half of the\n \t word. We only look for the simplest cases, to do more would cost\n*************** arm_gen_constant (enum rtx_code code, en\n*** 2991,2998 ****\n \t\t\t\t\t\t GEN_INT (i)),\n \t\t\t\t source)));\n \t\t return insns + 1;\n! \t\t}\n! \t }\n \n \t /* Don't duplicate cases already considered. */\n \t for (i = 17; i < 24; i++)\n--- 3179,3211 ----\n \t\t\t\t\t\t GEN_INT (i)),\n \t\t\t\t source)));\n \t\t return insns + 1;\n! \t\t}\t \n! \n! /* Also check cases where we could generate constant using XOR.\n! eg. (0x11110000 + ~0xffff1111) */\n! else if (((((temp2 | 0xffff0000) ^ ((temp2 | 0xffff0000) << i))\n! & 0xffffffff) == remainder)\n! && !const_ok_for_arm (temp2 | 0xffff0000))\n! {\n! rtx new_src = (subtargets\n! ? (generate ? gen_reg_rtx (mode) : NULL_RTX)\n! : target);\n! insns = arm_gen_constant (code, mode, cond,\n! (temp2 | 0xffff0000), new_src,\n! source, subtargets, generate);\n! source = new_src;\n! if (generate)\n! emit_constant_insn\n! (cond,\n! gen_rtx_SET\n! (VOIDmode, target,\n! gen_rtx_XOR (mode,\n! gen_rtx_ASHIFT (mode, source,\n! GEN_INT (i)),\n! source)));\n! return insns + 1;\n! } \n! }\n \n \t /* Don't duplicate cases already considered. */\n \t for (i = 17; i < 24; i++)\n", "prefixes": [] }