From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg1-f174.google.com (mail-pg1-f174.google.com [209.85.215.174]) by sourceware.org (Postfix) with ESMTPS id 906BA3858293 for ; Thu, 14 Jul 2022 12:34:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 906BA3858293 Received: by mail-pg1-f174.google.com with SMTP id s206so1429241pgs.3 for ; Thu, 14 Jul 2022 05:34:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=SZc7X22g36DSuW7GGdQqElBJjWWi2e/kaFZDTM29TBE=; b=bnSb3WtAaRMIOAcwO8lTrGDnlO4kApZ0igY/yBLFUmOySM9SvK2o7LKI/rUaWBtiGB 49FT9Z/raKE+dlmDmiBNKyqwh2YZ06mhCJndZVrLiZlNFC7AW9qj+RM/S2hAL0Wxdjh2 bnWoGXxLujVr8J+0euN7n4AYwzj3D3pe7BxT+bHcnyHLaq23/5uFqqAuPunqDjfHVOyr 4wU0Mq+dvVe29CnzeGa5cgytNFAXtqbtB7iBUKqDi8bROOCSASR/6UOwYTznw/HsUOcb q+H5caRbuIU16hKsp6exmlwSthqyIgTRBCwBOnmROWPHxCr5JSfFi6Ivo+YqFYbTdR1j 80QQ== X-Gm-Message-State: AJIora8hclWkMMu7Db+ueFnaF2Sbk/4BMetPyTolyPWOvm/DHszKQhWH KgZsEieC7/1a4yVt188sGafncy+58BI+SA== X-Google-Smtp-Source: AGRyM1sq3XR5Anpr918oYiHW8EUDwUVY86oStqtis+rRFhFYWBUDJYvaEV3+XPx+hC7N5PvO7vjF0w== X-Received: by 2002:a05:6a00:22cb:b0:525:ba83:559a with SMTP id f11-20020a056a0022cb00b00525ba83559amr8430930pfj.54.1657802081248; Thu, 14 Jul 2022 05:34:41 -0700 (PDT) Received: from mail-pj1-f44.google.com (mail-pj1-f44.google.com. [209.85.216.44]) by smtp.gmail.com with ESMTPSA id j126-20020a62c584000000b0052878f66f8asm1520677pfg.132.2022.07.14.05.34.41 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 14 Jul 2022 05:34:41 -0700 (PDT) Received: by mail-pj1-f44.google.com with SMTP id fz10so2762584pjb.2 for ; Thu, 14 Jul 2022 05:34:41 -0700 (PDT) X-Received: by 2002:a17:902:b7c9:b0:16c:354:a029 with SMTP id v9-20020a170902b7c900b0016c0354a029mr8392714plz.58.1657802080748; Thu, 14 Jul 2022 05:34:40 -0700 (PDT) MIME-Version: 1.0 From: Erick Ochoa Date: Thu, 14 Jul 2022 14:38:42 +0200 X-Gmail-Original-Message-ID: Message-ID: Subject: Creating a wrapper around a function at compile time To: gcc@gcc.gnu.org X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, HTML_MESSAGE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jul 2022 12:34:44 -0000 Hello, I'm looking for some help in how to create a new function at compile time / link time. The idea is an alternative form of constant propagation. The current implementation of ipa-cp, may specialize functions for which arguments may be known at compile time. Call graph edges from the caller to the new specialized functions will replace the old call graph edges from the caller to the original functions. Call graph edges which have no known compile time constants will still point to the original unspecialized function. I would like to explore a different approach to function specialization. Instead of only specializing functions which are guaranteed to have a compile time constant, I would like to also attempt to specialize the edges which do not have compile time constants with a parameter test. In other words, for call graph edges with non-constant arguments at compile time, create a wrapper function around the original function and do a switch statement around parameters. For example, let's say we have a function mul, which multiplies two integers. int mul (int a, int b) { return a * b; } Function mul is called from three different callsites in the whole program: A: mul (a, 2); B: mul (b, 4); C: mul (c, d); At the moment, ipa-cp might specialize mul into 3 different versions: // unoptimized original mul int mul (int a, int b) { return a * b; } // optimized for b = 2; int mul.constprop1 (int a) { // DEBUG b => 2 return a << 1; } // optimized for b = 4; int mul.constprop2 (int a) { // DEBUG b => 4 return a << 2; } and change the callsites to: A: mul.constprop1 (a); B: mul.constprop2 (b); C: mul (c, d); I would like instead to do the following: Create a function mul_test_param int mul_test_param (int a, int b) { switch (b) { case 2: return mul.constprop1 (a); break; case 4: return mul.constprop2 (a); break; default: return mul (a, b); break; } } The function mul_test_param will test each parameter and then call the specialized function. The callsites can either be changed to: A: mul.constprop1 (a); B: mul.constprop2 (b); C: mul_test_param (c, d); or A: mul_test_param (a, 2); B: mul_test_param (b, 4); C: mul_test_param (c, d); The idea is that there exist some class of functions for which the parameter test and the specialized version is less expensive than the original function version. And if, at runtime, d might be a quasi-constant with a good likelihood of being either 2 or 4, then it makes sense to have this parameter test. This is very similar to function tests for making direct to indirect functions and to what could be done in value profiling. I already know how to achieve most of this, but I have never created a function from scratch. That is the bit that is challenging to me at the moment. Any help is appreciated. Thanks! -Erick