From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by sourceware.org (Postfix) with ESMTPS id 958BF385803B for ; Tue, 18 Jan 2022 18:45:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 958BF385803B Received: by mail-wm1-x332.google.com with SMTP id i187-20020a1c3bc4000000b0034d2ed1be2aso6673710wma.1 for ; Tue, 18 Jan 2022 10:45:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=UCdNvEcY24OnMBr/Ct2smBMXSTIJ6u7upq91f/awKLI=; b=cCGXPnZVpxRzajOkD/qe6UELU/BPtbuk6hn+CG59QdoXACZs0S3f+SNHI29qjUYRiF 3a1Othl2RX4UueqViiBbltSbzXaBDj8VjJsXzbF10YtevDZUVXYDf8m77cvffHDpRFOb 2bQ0STgQDztCpbKSEZ+Ye2j1edy5Eol8xsf0NSe32X3maiK2m29vQ6QawKmKQgH+d6Wg S6vXxeqen7uOJ3Pq6aqOEjccqt7WHlsOS0SAh1ACeb/8gJRPj5c/JBu1c4XKBEqWjO5m ls7B4ZZnJmjKI02PvOFY6aEjfYUjVOcER6OG2VwM5km6y01MIilP219VA0pcHTfFvVwK FMsA== X-Gm-Message-State: AOAM532T2yi4ekv+r5HOTYivNE0Mb7YZ1Hht+odi/1mo5HKwXvs2YRvD N1J8auq3qzjK/L1jPWLjyUv08m6M0ogYevfjBZs= X-Google-Smtp-Source: ABdhPJw4b8FcSTQnIklW8vY5+eJxKoWx3OBBQU08eXfnqPAySKIOFGmOOnSyhExqHoqsgeoFw0B3PkDBNDGVDWZLOFU= X-Received: by 2002:a7b:c401:: with SMTP id k1mr26321965wmi.67.1642531525250; Tue, 18 Jan 2022 10:45:25 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Shubham Narlawar Date: Wed, 19 Jan 2022 00:15:13 +0530 Message-ID: Subject: Re: Accessing const parameter of GIMPLE_CALL To: Martin Sebor Cc: Richard Biener , GCC Development Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org 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: Tue, 18 Jan 2022 18:45:28 -0000 On Tue, Jan 18, 2022 at 2:19 AM Martin Sebor wrote: > > On 1/17/22 12:18, Shubham Narlawar via Gcc wrote: > > On Mon, Jan 17, 2022 at 1:55 PM Richard Biener > > wrote: > >> > >> On Mon, Jan 17, 2022 at 12:54 AM David Malcolm via Gcc wrote: > >>> > >>> On Sun, 2022-01-16 at 18:52 +0530, Shubham Narlawar via Gcc wrote: > >>>> Hello, > >>> > >>> Hi; various notes inline below... > >>> > >>>> > >>>> My aim is to iterate over gimple call stmt parameters and check > >>>> whether it is constant or constant expression and mark/store them for > >>>> some gimple transformation. > >>>> > >>>> I have an intrinsic function call of the following - > >>>> > >>>> __builtin_xyz(void*, 7, addr + 10); > >>>> > >>>> I want to find its parameters which are either constant or constant > >>>> expression i.e. 7 and addr + 10 from above case. > >>> > >>> Gimple "flattens" all tree-like operations into a sequence of simple > >>> operations, so I would expect the gimple for this to look something > >>> like this: > >>> > >>> _tmp = addr + 10; > >>> __builtin_xyx (7, _tmp); > >>> > >>> Your email doesn't specify *when* your code runs. > >>> > >>> The IR for a function goes through several stages: > >>> > >>> - an initial gimple IR without a CFG > >>> - gimple with a CFG, but not in SSA > >>> - gimple-SSA with a CFG > >>> (most of the gimple optimization passes operate in this form of the > >>> IR) > >>> - gimple with a CFG, but no longer in CFG form, immediately before > >>> conversion to RTL-with-CFG form > >>> - RTL-with-CFG > >>> - RTL-without a CFG > >>> - assembler > >>> > >>> Are you doing it as part of a plugin, or modifying an existing pass? > >>> In either case, it's a good idea to dump the gimple and see what the > >>> code has been turned into. You'll probably find the following options > >>> useful: > >>> -fdump-tree-all -fdump-gimple-all > >>> > >>> or alternatively just turn it on for the pass that you're working on. > >>> > >>>> > >>>> [1] I tried below macro but there is very less usage in the entire > >>>> source code - > >>>> > >>>> tree fn_ptr = gimple_call_fn (dyn_cast (stmt)); //stmt > >>> > >>> gimple_call_fn returns the function that will be called, a pointer. > >>> This is very general, for handling things like jumps through function > >>> pointers, but here you have the common case of a callsite that calls a > >>> specific function, so "fn_ptr" here is: > >>> &__builtin_xyx > >>> i.e. an ADDR_EXPR where operand 0 is the FUNCTION_DECL for the builtin. > >>> > >>>> = gimple_call > >>>> function_args_iterator iter; > >>>> tree argtype; > >>>> > >>>> if (TREE_CODE (fn_ptr) == ADDR_EXPR) > >>>> { > >>>> FOREACH_FUNCTION_ARGS (fn_ptr, argtype, iter) > >>> > >>> Looking in tree.h, FOREACH_FUNCTION_ARGS takes a FUNCTION_TYPE as its > >>> first argument, but the code above is passing it the ADDR_EXPR wrapping > >>> the FUNCTION_DECL. > >>> > >>> Unfortunately, because these things are all of type "tree", this kind > >>> of type mismatch doesn't get caught - unless you build gcc from source > >>> (with --enable-checking=debug) in which case all these accesses are > >>> checked at the compiler's run time (which is probably a good thing to > >>> do if you're hoping to work on gcc for GSoC). > >>> > >>> You can get the FUNCTION_TYPE of a FUNCTION_DECL via TREE_TYPE > >>> (fndecl), or alternatively, gimple_call_fntype (call) will get the type > >>> of the function expected at the call stmt (useful if there was a type > >>> mismatch). > >>> > >>> That said, FOREACH_FUNCTION_ARGS iterates through the types of the > >>> params of the FUNCTION_TYPE, but it sounds like you want to be > >>> iterating through the arguments at this particular *callsite*. > >>> > >>> For that you can use > >>> gimple_call_num_args (call); > >>> and > >>> gimple_call_arg (call, idx); > >>> > >>>> { > >>>> if (TREE_CONSTANT (argtype)) > >>>> // Found a constant expression parameter > >>>> } > >>>> } > >>>> > >>>> The problem is I am getting only one parameter tree but there are 2 > >>>> constants in the above function call. Even if "addr + 10" is treated > >>>> differently, I want to mark it for the transformation. > >>> > >>> I think you're seeing the function pointer being called, ather than the > >>> params. > >> > >> I think you are iterating over the functions formal argument types > >> rather than a specific call parameters. To look at the actual > >> parameters use sth like > >> > >> for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i) > >> { > >> tree arg = gimple_call_arg (stmt, i); > >> if (CONSTANT_CLASS_P (arg)) > >> ... > >> } > >> > >> and replace CONSTANT_CLASS_P with is_gimple_ip_invariant () > >> if you also want to handle symbolic constants like &global_var > >> as constant. > > > > Understood. I was iterating on formal parameters. But the above solves > > the problem. CONSTANT_CLASS_P() and is_gimple_ip_invariant() are > > helpful on integer constant. > > > > In below gimple dump w.r.t code snippet shared by you from above - > > > > def_stmt _14 = (unsigned int) _13; > > __builtin_xyz(instrn_buffer.3_11, 12, _14); > > > > Here, all actual parameters are represented by tree whose classes are - > > > > instrn_buffer.3_11 - tcc_exceptional > > 12 - tcc_constant > > _14 - tcc_exceptional > > > > The 1st and 3rd parameters are denoted by tcc_exceptional which fits > > no category of tree, but I want to collect such 3rd parameter i.e. to > > identify it whether it is variable or expression. Is it possible to do > > it? > > > > I want to mark _14 for gimple transformation if - > > a. it is a variable like above _14 representing a constant. > > b. it is a expression _14 + 7 i.e. again at gimple level, it is case (a) > > c. it is a phi node which represents constant when there is a case of > > ternary operator usage. > > > > How to identify such an actual parameter of gimple call? > > > > The aim of the above scenario is to identify such > > variables/expressions and then apply constant folding and propagation. > > If constant folding and propagation are not happening on actual > > parameters of intrinsic call, then I need to write some plugin to do > > it. My plugin is placed just after "pass_build_cgraph_edges" i.e. > > Callgraph Construction. > > I use the following code. It runs after pass_build_ssa, so a bit > later than pass_build_cgraph_edges: > > /* Use the range query to determine constant values in the absence > of constant proppagation (such as at -O0). */ > value_range rng; > if (!get_range_query (cfun)->range_of_expr (rng, ord, stmt) > || !rng.constant_p () > || !rng.singleton_p (&ord)) > return false; > > wide_int lob = rng.lower_bound (); > if (!wi::fits_uhwi_p (lob)) > return false; > > val = lob.to_shwi (); Understood. This is helpful. Thanks for sharing. > > Martin > > > > > Thanks for the helpful suggestions. > > > > Regards, > > Shubham > > > > > >> > >> Richard. > >> > >>>> > >>>> a. Is the above correct method to iterate over function call > >>>> parameters? > >>> > >>> As noted above, it depends on whether you want to iterate over the > >>> types of the parameters in the function's decl, or over the expressions > >>> of the arguments at the callsite. I believe the above explains how to > >>> do each of these. > >>> > >>>> b. Is there a different way to achieve the above goal? > >>> > >>> If you're looking to get familiar with GCC's insides, I recommend > >>> stepping through it in the debugger, rather than relying on injecting > >>> print statements and recompiling, since the former makes it much easier > >>> to spot mistakes like the one above (which we all make). > >>> > >>> I've written a guide to debugging GCC here: > >>> > >>> https://dmalcolm.fedorapeople.org/gcc/newbies-guide/debugging.html > >>> > >>> > >>> Hope this is helpful > >>> Dave > >>> >