From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05on2086.outbound.protection.outlook.com [40.107.22.86]) by sourceware.org (Postfix) with ESMTPS id 8CCFF3858D1E; Wed, 17 May 2023 11:55:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8CCFF3858D1E Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=siemens.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=siemens.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kp9mC1TnSTEOEV6C/JTQ8sR75aUyxVGNk5/0BVhl0Z80oNLLZfDFITZbLb2R4z7Tqw/MM7rDKxEuvnNmTj4b+BAXNiw2kZoP7zsBeZQAcUz2TvMgO21q7XFjDSP37f45L4I8DKCIQSMqL9UCXBOknO5DCkJj/lxD6XxrB4L2SGu+7dkAlAA+fXVrokxayRZ1kgy/LcvAjRSKMhOvQ8k/f9jSSZa3vIdrKsdQEQI9KoWqU6tiqvlSnx53z8JrZ/0e9OZ40ffFLFFgh7c2rUdubNIi5PH6Msyz2W/b6bljTjtlc/aV9iDjXR2+TE2rHfv7jiXjOP03RgCSCck93nfNrQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5kcocUuC80/87jXtNVL9uKfFqwARL2+JXNcAwLgK9e4=; b=ga5EZmvWRgjvN1E0Cd2pg7/JydAUxEm3gndZvHFWMY001PnEzRPzQnDzFPoTGwhjLEg8w5eHUsYAZd/xtfkWwmlnz9n1KpJrR0nOB0Yv1V4QA0zGgIw51/te08s2jI8gJUL5JhwT/VuDYtpr01JTht4+EYDJ7z7qMb8HBefcnlxjDzYVU1Uk55VyMVbu+Gg5erzAw3UHPSgIB3AZyKMidkWKe5Z2tA8khmEIYsqxABDtNUeNl8H5E81XrpmxQmtpbDYsZ4++Y1k22xR69/fNsFBPAtODo4A2UT84u58osp1eHeXLEur4zkjs7Xx5A+FCixqBlcig1yaoN/UZn4P7zQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=siemens.com; dmarc=pass action=none header.from=siemens.com; dkim=pass header.d=siemens.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=siemens.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5kcocUuC80/87jXtNVL9uKfFqwARL2+JXNcAwLgK9e4=; b=JT/HCzFKHKF7x74qvKSnpGmvFlkwg7gdk/6JHXXgXQ/0hIxPSGrxbyDJv0RI/asrBpqvxj9PR09v9aQnVVqcfoJz0QuNd7t/GLjOXugMu6weo897o/+fl+YnlpX3oSbUuY3sZvuKE7uUmWQ9CRkyEYNB+XRgfMEM1MBde7gT4lQ4Erey777oAM94Re2pA6vtgZQNZiUxl+ZUN2OsnW9KkjjZ/8UQo39bQU2aQAyzMdZjaW0u9/XhiDiNNNvEEw/zrwmOE1afcpWCMlj3ss0kDEfBtoufJmakuVUmYr8XedPXLlHmkEqcT9D6xo6xvH4tsM5J7PmgMLTWG0g5nbRWCQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=siemens.com; Received: from AM9PR10MB4824.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:20b:413::23) by DB8PR10MB3814.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:10:16c::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6411.17; Wed, 17 May 2023 11:55:02 +0000 Received: from AM9PR10MB4824.EURPRD10.PROD.OUTLOOK.COM ([fe80::bfea:f7bc:cdf9:550]) by AM9PR10MB4824.EURPRD10.PROD.OUTLOOK.COM ([fe80::bfea:f7bc:cdf9:550%7]) with mapi id 15.20.6411.017; Wed, 17 May 2023 11:55:02 +0000 Message-ID: <8b53269a-c385-52d1-b862-8a4b904ce66d@siemens.com> Date: Wed, 17 May 2023 13:55:00 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.10.1 Subject: Re: [PATCH 0/7] openmp: OpenMP 5.1 loop transformation directives To: Jakub Jelinek Cc: Frederik Harwath , gcc-patches@gcc.gnu.org, fortran@gcc.gnu.org, tobias@codesourcery.com, joseph@codesourcery.com, jason@redhat.com References: <20230324153046.3996092-1-frederik@codesourcery.com> From: Frederik Harwath In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-ClientProxiedBy: FR2P281CA0150.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:98::11) To AM9PR10MB4824.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:20b:413::23) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM9PR10MB4824:EE_|DB8PR10MB3814:EE_ X-MS-Office365-Filtering-Correlation-Id: 4acfd557-ddd7-4c2c-f5a7-08db56cd8bf3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: mVm8QwozfZaxsy/AiA4qb7rAHCfTyeyQxuiuMx6+OEJHuDWx65OT6ROtqCcb4Tl5P7sj9+Ezh8faIM5z116oPnY0m+bU46+EjxHWWzegjQHXux4qASNzWf8JOS0m2yhC05gNXJfCMU/LqSrda2FMgVkxGhUDuFrXc1dALY2VrD2oadwevjJXRFAuBak+0d3G+Chcpf7Xbh5RUGHMwotNOp1hHst2clK8JfJecXzK+6OqJkZKPXhQcjscknvPaw4vCJN6DxjCkXJVPtq7I18Qq45eoxG9B8zqaIou5MR76Gsw5Z55wMus6lUYx0G7bIJGysg5iN5Wb4cE2mkBEXeHAIc6vpmO37E9Ay9NgfChppa1N4MKx8jn+is0LDYcQ+xQ+UnagWYAMFmOkdYRN6jx42leokyn10vbFQJ4ZJE9D0ZeIw8WCJHuoWFIW/4mP5ogrbVUtaPgpcTj7x+qTcMKafhZnfR0ljJ18WEzDWQ6QOcJH92q1ntJ4Anyrp/LcybTjwqOHzvv4MOkeiT3l6pwZfrgj4AJFsmwXU0/3qvkLis1KWoWHA8O7QuyKL18LfTjFwO07bBIpIJbaPhVVAT4QBngQPFt4GL+9vSof4NoH+6hvfWQpQTByvKkie+L5Vb51ksd8tviz7wufHdhp+p5Lw== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM9PR10MB4824.EURPRD10.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230028)(4636009)(366004)(346002)(39860400002)(396003)(136003)(376002)(451199021)(53546011)(6506007)(6512007)(83380400001)(36756003)(2616005)(86362001)(38100700002)(31696002)(82960400001)(186003)(2906002)(478600001)(4326008)(6916009)(66556008)(8676002)(66476007)(31686004)(8936002)(66946007)(316002)(5660300002)(44832011)(41300700001)(6486002)(43740500002)(45980500001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?bG5SM3FJYXhrWk5JYXRHbG9uL1pZL2FjdnRrQUxSS1p0OTBMVWNIWjJOKzBG?= =?utf-8?B?QVhmK2ZpQ2NxbFlvY24wM2tkT3ZBaDgyQUd2enhIZmpYQ2xLNitWc2E3Q0Rq?= =?utf-8?B?aEg0ZFVhaFRkYzRoMVREUkc0bHA1TkdRZ09BSXVKS1QrZytRZ0hSNDhTbWdx?= =?utf-8?B?Z2xBYVh4S3BnU0xrZFhjOHAvS2IyUDd4YWJnbmYyN2hjNWh3Sk5rVGZac1RF?= =?utf-8?B?SG0renZCdHJuQjFHaG9sUjhYb0ErUWo0VEhXMytCMDNSblpJcE1VazVuNE1Y?= =?utf-8?B?WjFSMTBBSmc4MitBdzlsVy9iRCtDN2taeTBxU0MxYmg3dUlPVWZWK2ZOZEd6?= =?utf-8?B?cGRmNWN0S1M0b1YzdjUzcGZyYTltQ0gxSE15MjVnS0dyMk40VGNEOFU5MXRr?= =?utf-8?B?eTBBYm1uWStManZoK2ViVXhFQ213SzdNRjlKTlZIM2l0Y2hJak5tbmFVQ2FQ?= =?utf-8?B?RXJRNXBjZ2h5ZldTb3d0T3h5SytBdzJvR2JzVENta1ZNeUpFSXNmZ0VmdmxT?= =?utf-8?B?akZyZHo2TFlZV2pWSThNbS9qeStCTGVpL2ZuTENKVVBsK2Vjd2tTWlhOcGFx?= =?utf-8?B?TEYzMW1hMHdxdUF4NmdNa3pNYjBBTHhXRXg2Y2FudnJ6aUQ4SzduZSt5b1Iv?= =?utf-8?B?Rll4N2F2SlhqOGQvSjBteEgvRGlzL21aQ3A2QjM4bW02NFlVU2t2emNwUURa?= =?utf-8?B?aXp6RTJSbmwwWmhWUC9iWk0vLzRBcEpReUtiUi9OV3l2UW5HM2dxUlhNdU1Z?= =?utf-8?B?VUV6b1ozVUwrZThlb21YazZOTmcrTGRpRjJtZW9IUXk5aFhhNW1ZTys5V1Bv?= =?utf-8?B?blBNcmR2bXRNT1lDZWp6ZkMrN3JDS05SSGZ0aVFQTGdQenFoblNhdUl4a0ZF?= =?utf-8?B?Q1VCdWlsVW9LZDVDbFE2dzU4eW8vU2JEQ2lUMDNod1RxVXp4M2NBdjJTRUQz?= =?utf-8?B?R3cvbHo5MlpxZWVHMi80WlVCc1VrUzZsSFhCRGFjVHRqSXNteHpUUytBWU9n?= =?utf-8?B?WldxcnN3eFdIREhlUmZVSGowcHpUYWV5UTY0cHZhK3RBTU1MVWdsVmVrNy81?= =?utf-8?B?d21UViswUDJ4bFE2b1BXMFBiMWU5Ni9ZTzFMVm5kd2M2ZnhQVll2VzZvUmZS?= =?utf-8?B?SFZrTlJERTZjb0xYMDdyY3RKRldreFJLKzNzdjZOOVQ0cDFTckdRNTNSVnd1?= =?utf-8?B?SVdkVXdZMTFTdm0yMG9ja1VKMmp4Mk1nZlFDOW9Eam44UjFPUG1jajVIY3B2?= =?utf-8?B?djBpUHQ2d2VyQVZyUElSUGR2RksxUEpPR2FDQk1sZnNRc1pmTjhjMnlsbWlB?= =?utf-8?B?VVdoeU1nZlRucWl4TzhIMkZBR3N1aC9rRXQ4VWY0N2liaHQ4Q3ZrNTJBMHRY?= =?utf-8?B?ZGErVWhINzdVa0x1dXJIVUFWdW5McWdSMjVwcXVScGpROUlBRmRnbHFyTGtk?= =?utf-8?B?cHUrbFdONitUNE0vRmlZWWo3V1ZId3hrc01BVVFNZ01OUEFNZC9mZlJmR3dO?= =?utf-8?B?UU1sRWthUUxJWmZya0s2Qk54TzVyMkhFcDkwWXVXOUZETm1tY2pMbWtsL0pw?= =?utf-8?B?TXQ3NEJ5RUxscU5PK2VsaGg1M2N2OFVEZURaSS9QWi91TWtta2tWcU9JVnhr?= =?utf-8?B?Y2ZEdWZUVElUb1VTc0QrWXIwVnB6NjhQNVdOQVM0SkJoU1BqVWJLbS80Q2sz?= =?utf-8?B?WWlRNkJYM2w4VEkwbEl1V3JKeG9LU2dWM2Y4Q0JNbGp6MEpaYjZUMWhxNlEy?= =?utf-8?B?b0NmNmJKYXlNOU5nSjRJVWJIR3FZS1dQOFpobDJrcUhiY0RwNms2d0FpcFhT?= =?utf-8?B?cG1HWUtOY3pLWDdQYW51RHkvRlN6aGpYQmVyTmkzL2w4Ujd1eTNwVmNRL2ht?= =?utf-8?B?VGpLRC9CVDdGQjNDS0ZKTGF0cnNwWG4vRnJ0MTNaZXlsNS9MRmNTRzlzMkdu?= =?utf-8?B?S0I0akVpcklTNmZhWTFCWjhIeGo0a2pmZ1F4bEFOYzJ1VVVKMytMZWxXRjhr?= =?utf-8?B?THNnK29UWG55T3llTzZMRTZGeVAwNzJGSThNUmFsaUVGN3ROQ1FWNVVSQUY4?= =?utf-8?B?bndKalVhYS8wNVhtb3dxTy8zUytKNDlya1ExYkdORnZwa1V5NUdlZ0o4Y3Jn?= =?utf-8?B?cG82Zmt3ZUNhWGNEZzhZdTk5a29HeTRyQk8zZnR4MUFpVFlFV1l3RDRvVURW?= =?utf-8?B?ZlF2WW5Ra1NhY2JKQlNMSm04RFp6SlNxUm1RMFVBYzBlSkp2cGFqVnhyeDB1?= =?utf-8?B?S1hiK053NzNaeW1tQy8wTFlTR2FnPT0=?= X-OriginatorOrg: siemens.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4acfd557-ddd7-4c2c-f5a7-08db56cd8bf3 X-MS-Exchange-CrossTenant-AuthSource: AM9PR10MB4824.EURPRD10.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 May 2023 11:55:02.0262 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 38ae3bcd-9579-4fd4-adda-b42e1495d55a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: bCfGYfabGclAlmpcuhZMDCI6iczIclo+mSsPaLa47DnNEjbTAiamoSmYlFKOPWSqHCECFcMVgBl6a9krDsKg/Ki5bTu7UQvFEaa5xiKB+T8= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB8PR10MB3814 X-Spam-Status: No, score=-5.4 required=5.0 tests=BAYES_00,DKIMWL_WL_MED,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FORGED_SPF_HELO,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi Jakub, On 16.05.23 13:00, Jakub Jelinek wrote: > On Tue, May 16, 2023 at 11:45:16AM +0200, Frederik Harwath wrote: >> The place where different compilers implement the loop transformations >> was discussed in an OpenMP loop transformation meeting last year. Two >> compilers (another one and GCC with this patch series) transformed >> the loops >> in the middle end after the handling of data sharing, one planned to >> do so. >> Yet another vendor had not yet decided where it will be implemented. >> Clang >> currently does everything in the front end, but it was mentioned that >> this >> might change in the future e.g. for code sharing with Flang. Implementing >> the loop transformations late could potentially >> complicate the implementation of transformations which require >> adjustments >> of the data sharing clauses, but this is known and consequentially, >> no such > When already in the FE we determine how many canonical loops a particular > loop transformation creates, I think the primary changes I'd like to > see is > really have OMP_UNROLL/OMP_TILE GENERIC statements (see below) and > consider > where is the best spot to lower it. I believe for data sharing it is best > done during gimplification before the containing loops are handled, it is > already shared code among all the FEs, I think will make it easier to > handle > data sharing right and gimplification is also where doacross processing is > done. While there is restriction that ordered clause is incompatible with > generated loops from tile construct, there isn't one for unroll (unless > "The ordered clause must not appear on a worksharing-loop directive if > the associated loops > include the generated loops of a tile directive." > means unroll partial implicitly because partial unroll tiles the loop, but > it doesn't say it acts as if it was a tile construct), so we'd have to > handle > #pragma omp for ordered(2) > for (int i = 0; i < 64; i++) > #pragma omp unroll partial(4) > for (int j = 0; j < 64; j++) > { > #pragma omp ordered depend (sink: i - 1, j - 2) > #pragma omp ordered depend (source) > } > and I think handling it after gimplification is going to be increasingly > harder. Of course another possibility is ask lang committee to clarify > unless it has been clarified already in 6.0 (but in TR11 it is not). I do not really expect that we will have to handle this. Questions concerning the correctness of code after applying loop transformations came up several times since I have been following the design meetings and the result was always either that nothing will be changed, because the loop transformations are not expected to ensure the correctness of enclosing directives, or that the use of the problematic construct in conjunction with loop transformations will be forbidden. Concerning the use of "ordered" on transformed loops, the latter approach was suggested for all transformations, cf. issue #3494 in the private OpenMP spec repository. I see that you have already asked for clarification on unroll. I suppose this could also be fixed after gimplification with reasonable effort. But let's just wait for the result of that discussion before we continue worrying about this. > Also, I think creating temporaries is easier to be done during > gimplification than later. This has not caused problems with the current approach. > Another option is as you implemented a separate pre-omp-lowering pass, > and another one would be do it in the omplower pass, which has actually > several subpasses internally, do it in the scan phase. Disadvantage of > a completely separate pass is that we have to walk the whole IL again, > while doing it in the scan phase means we avoid that cost. We already > do there similar transformations, scan_omp_simd transforms simd constructs > into if (...) simd else simt and then we process it with normal > scan_omp_for > on what we've created. So, if you insist doing it after gimplification > perhaps for compatibility with other non-LLVM compilers, I'd prefer to > do it there rather than in a completely separate pass. I see. This would be possible. My current approach is indeed rather wasteful because the pass is not restricted to functions that actually use loop transformations. I could add an attribute to such functions that could be used to avoid the execution of the pass and hence the gimple walk on functions that do not use transformations. >> This is necessary to represent the loop nest that is affected by the >> loop transformations by a single OMP_FOR to meet the expectations >> of all later OpenMP code transformations. This is also the major >> reason why the loop transformations are represented by clauses >> instead of representing them asĀ  "OMP_UNROLL/OMP_TILE as >> GENERIC constructs like OMP_FOR" as you suggest below. Since the > I really don't see why. We try to represent what we see in the source > as OpenMP constructs as those constructs. We already have a precedent > with composite loop constructs, where for the combined constructs which > aren't innermost we temporarily use NULL > OMP_FOR_{INIT,COND,INCR,ORIG_DECLS} > vectors to stand for this will be some loop, but the details for it aren't > known yet, to be filled up later. So, why can't we similarly represent > #pragma omp for collapse(3) > #pragma omp tile sizes (4, 2, 2) > #pragma omp tile sizes (4, 8, 16) > for (int i = 0; i < 64; ++i) > for (int j = 0; j < 64; ++j) > for (int k = 0; k < 64; ++k) > body; > as OMP_FOR with NULL OMP_FOR_{INIT,COND,INCR,ORIG_DECLS} > with the appropriate clauses on it, with > OMP_TILE (again, right clauses, NULL OMP_FOR_{INIT,COND,INCR,ORIG_DECLS}) > and another OMP_TILE, this time with all the vectors filled in in GENERIC? > > #pragma omp for collapse(2) > for (int i = 0; i < 64; ++i) > #pragma omp tile sizes (4) > for (int j = 0; j < 64; ++j) > would be represented by non-NULL vectors which would have all the inner > entries NULL (the outer loop is not generated loop, the inner one is > generated) with OMP_TILE inside of it. > > Then depending on where the loop transformation is actually performed, > we'd either need to preserve such shape from gimplification until the > loop transformations are applied, or would be solely on GENERIC and > GIMPLE would already have the transformed loops. Thanks for the explanation! I think now I understand how you would do this. > Clauses e.g. have the disadvantage that generally they aren't ordered. > If it is separate statements, it is e.g. easier to print it right in > original dump, so that people can compare the loops before the > transformation and after it. > You mean, the clauses are not ordered at the level of the specification? In the implementation they are of course ordered and the order has proved to be sufficiently stable. But perhaps you mean that you would like to avoid introducing code that relies on the ordering of the clauses? In this case, I could move the transformations to a separate chain which could be accessed e.g. by OMP_FOR_TRANSFORMS and by gimple_omp_for_transforms per level. This would also allow to print the transformations in the pretty printing functions on the corresponding levels of the loop nest. This would also be possible somehow with the present representation. But right now the transformations are just printed together with the other clauses on the directive. I considerd this to be acceptable because I suppose the dumps will be mostly read by GCC developers. There are also other clauses that are only used internally. >> You suggest to implement the loop transformations during gimplification. >> I am not sure if gimplification is actually well-suited to implement the >> depth-first evaluation of the loop transformations. I also believe that > Why not? The loop transformation constructs can't be deeply nested in the > bodies, they need to be close. > gimplify_omp_for already searches the body for the case of composite > constructs - if (OMP_FOR_INIT (for_stmt) == NULL_TREE) early in it. > So, this would just mean doing it if that condition is true also looking > for loop transformation constructs (if they are found, pass in the > containing OMP_{FOR,SIMD,LOOP,DISTRIBUTE,TASKLOOP} if any to a routine > that handles the transformation, such that it can update the containing > looping construct if any during the transformation. > That alone would handle the case where the looping construct should work > solely with the generated loop. It would need to do the same thing > also if OMP_FOR_INIT (for_stmt) is non-NULL but > TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), TREE_VEC_LENGTH (OMP_FOR_INIT > (for_stmt))) > is NULL to handle the case where generated loops are just some of the > inner > ones. > And then when gimplify_omp_for would encounter an OMP_TILE/OMP_UNROLL > loop on its own (i.e. not nested inside some other loop), it would > similarly > find further transform constructs in it like the above but then would just > normally do the loop transformation, with NULL_TREE for the containing > loop, > meaning it is a sequential stuff. Thanks for the explanation. But actually doing this would require a complete rewrite which would almost certainly imply that mainline GCC would not support the loop transformations for a long time. Best regards, Frederik