From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-il1-x129.google.com (mail-il1-x129.google.com [IPv6:2607:f8b0:4864:20::129]) by sourceware.org (Postfix) with ESMTPS id A957E3858406 for ; Mon, 17 Jan 2022 20:49:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A957E3858406 Received: by mail-il1-x129.google.com with SMTP id u5so11531943ilq.9 for ; Mon, 17 Jan 2022 12:49:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=QCwb3NrO85rABhKmBD1JBqgELntI9YtHNVeS1rffESo=; b=4o5kUGtB9e5VvDgdir+J+RqWIr/g26Ea0YdnNe8xMrC/l7AaZLejsqvEDkxzJY3O5a 4CfOQ+BzhBLZBwi7m3LtPCA2+Pp2j+rhTERBSiSRGbAOMf9EcScwfTPBscntShrtwGK0 lD/+dWwLajxBRYSDAFYLS+2OFWZyZPyqAhwvQa/l6IfCVVRb1Qg7/zRdNoqw7p/NUlsQ 3xE3kKeXLkrGq5CgcG5h6zrddbDzHywhtDxNGlzDxXU1n6Erh13x5+g6Uieuhq0F0r19 w7RJAZtPjOdL+edGv4Iro6nuJvNzbL7uvCwfjBhEZPvFKsDrzraYIAKGM4XaS3cnX5/v 17Rw== X-Gm-Message-State: AOAM530r9SuDU4Xu/SuTOWs0ZZy373bWupCIjfPIBmHO0PppSdCFYtxE 6vXhPYN9dX3aryajb134TxQ= X-Google-Smtp-Source: ABdhPJxlKJVIYtEI9xs8IWENko++sYSMIyWb6Lr/XSYfegl0H+WUzJqKcCGIxWUsEazJkk5ayts6cQ== X-Received: by 2002:a05:6e02:1d86:: with SMTP id h6mr12008849ila.265.1642452591993; Mon, 17 Jan 2022 12:49:51 -0800 (PST) Received: from [192.168.0.41] (97-118-100-142.hlrn.qwest.net. [97.118.100.142]) by smtp.gmail.com with ESMTPSA id o25sm9137363ioa.41.2022.01.17.12.49.51 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 17 Jan 2022 12:49:51 -0800 (PST) Message-ID: Date: Mon, 17 Jan 2022 13:49:50 -0700 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.4.0 Subject: Re: Accessing const parameter of GIMPLE_CALL Content-Language: en-US To: Shubham Narlawar , Richard Biener Cc: GCC Development References: From: Martin Sebor In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, NICE_REPLY_A, 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: Mon, 17 Jan 2022 20:49:55 -0000 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 (); 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 >>>