From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out203-205-221-240.mail.qq.com (out203-205-221-240.mail.qq.com [203.205.221.240]) by sourceware.org (Postfix) with UTF8SMTPS id CDB143858D1E for ; Wed, 8 May 2024 02:46:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CDB143858D1E Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=qq.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=qq.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CDB143858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=203.205.221.240 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715136417; cv=none; b=c/cdj91i2gGuJghpQh52+NZEJ8bL4MZAwskdkp86HUuszg1NPRQLw+MRNK9QY9WWo9Mpeo5BFR2snHJfn+Xp9jn5sX6Egqnis9JLmaKH/+SAJTiIz8EQDy9AYsRvGiF/xyHCDcq0XCUBsQji6sZKVq1o4NoXAXKMS1feGtJua3Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715136417; c=relaxed/simple; bh=cTNQ8oOaUWCt5lOdQer3DhCqaaDTpFqvp3pR63cOfT0=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=B04VMXRpDpnk8VjfgcUbqLaHpBZZu/bpm+h1sDklmRZnTMBUaRuF+9P85+v9cn6N++vbr6WB7x5cRgHaXcCAERD9NIsF4+fZwnrnr/a8clMtlj/8X1qB4rn936ycd8HXTXH2n24G7OfTc05edtZlnOZRd4mBeRVhsQye6FRAesw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512; t=1715136411; bh=cWb/Gocvv6fXsqTEG9jgvKwt8sAyH6sjbvk9NgjDltQ=; h=Date:Subject:To:Cc:References:From:In-Reply-To; b=Lx3iKU8kd1vdt0sWsLYBwuLMo/1s3zrvAQhXpMsvp+A6XR8G0FXBQlirsASZOdzre rd5AcZmOxzHSFhzmELZrXIMLVbdlsnuhZQ3YpFtw7bQFEfoOceLDUMKEAHYBPW56ce qsj06MvgdEIpCFyqlFXWbIq/U0TlXV5EkHTyNXUQ= Received: from [192.168.255.10] ([113.108.77.72]) by newxmesmtplogicsvrszc5-2.qq.com (NewEsmtp) with SMTP id B9CBDC46; Wed, 08 May 2024 10:46:28 +0800 X-QQ-mid: xmsmtpt1715136388ta9ldh7zv Message-ID: X-QQ-XMAILINFO: OPIY/Y5G02yjtKdc8fyt5/W6OqrFrYbMr3hKIVGmEdNPyhIkO7BKi+882CT9QN D41s2f3McwDDemb1UQyYkKmrQcpV1W7D3LDBmlpUmqcmDnZbzXFEREOhloxXCQEjSMwXHgFvDwqF Me3jw83AsNlx0YHelatV7WhiZeKn08rMod2jKpUsMlSsIrgZc4UZkFTY+AxYoyWn5EuE4fpklsBX fXT1OLpRvpnprlpLGe1AtNPdjlPvMvPcZ85i3f3N0HgfmJ6C4mGU8h5Od20GiFc9IB1fKTke4Dsk D2BalFJLiQYFRPMLUP7q3xguOXnkcxcbzu+9NHRwPm7JZFEhCK6nD+j6zerNi4E0AwtA2xgHMh2j 4yEnonqXrkaWlwD64LjyS1Tp+3TNa6M3knM/sFEoRGVOi7HvMA0tnMNichuRdIGZ0F8SqST0OjxW WPm1h3IxRg6YDEZzoXo8VuEpBYQNAQiCTmJ/b9siuECtDnbVJy60JFdRBuHX71yC4VYWcpOACJik JAKuZnGwgHbGPy0PsJtLgLgO+j1CITdZgDu0DGReCx3Po8jGjdXRPY83h5JRW2Tx+qrmICM4xIEO FoX3yzrLI6K+/DDXCYGNIT6wbLpw5w21gRSHM1LsN34U9cC7nSQ2rbdCQJ0DcBsFAVCgtTLBblWK 8QU3PdSMoM/87t2Hod9LspOSCUZnHKjJcBJvliEdnPfTMttU5nk9R+de7v+vSRPuPf00gICUaXaj NMQTfjui5oQNKoFFYN61thp02KTms3TSkZhbPsmiafsgoe43mb2sIVmxppZPvGus+tJ6WwQSDxTj G1fFsQ8MUyQs9zHzAUrTL5NSjVec7/DIQzikFkFm9fsa5n1MhGMd2GEj6m1vnHilt4MLMoC5mRIA UQt/upsQocjaFqoVB/jDE9eKG0/JJj4sE+cdSd3SscJ9no0VPoHhK1BZGp7wFCh1snQIwVpMtbpU xLeME6xTcG6r5Nce8Z0P1F6izMg0KF84juxMwADC/8VDUIricLJzytuhGy7EESc3yWtMWTBbQoNz rBy8XSnLiFmtcocwM7 X-QQ-XMRINFO: Nq+8W0+stu50PRdwbJxPCL0= X-OQ-MSGID: <41b7d120-051d-4f43-afb8-de4f0d39be1c@qq.com> Date: Wed, 8 May 2024 10:46:28 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH 2/4] df: Add DF_LIVE_SUBREG problem To: Dimitar Dimitrov Cc: gcc-patches@gcc.gnu.org, juzhe.zhong@rivai.ai, shuo.chen@rivai.ai, jin.xia@rivai.ai, vmakarov@redhat.com, richard.sandiford@arm.com References: <20240424100505.1301-1-lehua.ding@rivai.ai> <20240424100505.1301-3-lehua.ding@rivai.ai> Content-Language: en-US From: Lehua Ding In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FORGED_MUA_MOZILLA,FREEMAIL_FROM,GIT_PATCH_0,HELO_DYNAMIC_IPADDR,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,RDNS_DYNAMIC,SPF_HELO_NONE,SPF_PASS,TXREP 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 Dimitar, Thanks for helping to review the code! I will send V3 patch which address these comments. Best, Lehua On 2024/4/26 04:56, Dimitar Dimitrov wrote: > On Wed, Apr 24, 2024 at 06:05:03PM +0800, Lehua Ding wrote: >> This patch add a new DF problem, named DF_LIVE_SUBREG. This problem >> is extended from the DF_LR problem and support track the subreg liveness >> of multireg pseudo if these pseudo satisfy the following conditions: >> >> 1. the mode size greater than it's REGMODE_NATURAL_SIZE. >> 2. the reg is used in insns via subreg pattern. >> >> The main methods are as follows: >> >> 1. split bitmap in/out/def/use fileds to full_in/out/def/use and >> partial_in/out/def/use. If a pseudo need to be tracked it's subreg >> liveness, then it is recorded in partial_in/out/def/use fileds. >> Meantimes, there are range_in/out/def/use fileds which records the live >> range of the tracked pseudo. >> 2. in the df_live_subreg_finalize function, we move the tracked pseudo from >> the partial_in/out/def/use to full_in/out/def/use if the pseudo's live >> range is full. > Hi Lehua, > > I'm not familiar with LRA, so my comments bellow could be totally off > point. Please treat them as mild suggestions. > >> gcc/ChangeLog: >> >> * Makefile.in: Add subreg-live-range object file. >> * df-problems.cc (struct df_live_subreg_problem_data): Private struct >> for DF_LIVE_SUBREG problem. >> (df_live_subreg_get_bb_info): getting bb regs in/out data. >> (get_live_subreg_local_bb_info): getting bb regs use/def data. >> (multireg_p): checking is the regno a pseudo multireg. >> (need_track_subreg_p): checking is the regno need to be tracked. >> (init_range): getting the range of subreg rtx. >> (remove_subreg_range): removing use data for the reg/subreg rtx. >> (add_subreg_range): adding def/use data for the reg/subreg rtx. >> (df_live_subreg_free_bb_info): Free basic block df data. >> (df_live_subreg_alloc): Allocate and init df data. >> (df_live_subreg_reset): Reset the live in/out df data. >> (df_live_subreg_bb_local_compute): Compute basic block df data. >> (df_live_subreg_local_compute): Compute all basic blocks df data. >> (df_live_subreg_init): Init the in/out df data. >> (df_live_subreg_check_result): Assert the full and partial df data. >> (df_live_subreg_confluence_0): Confluence function for infinite loops. >> (df_live_subreg_confluence_n): Confluence function for normal edge. >> (df_live_subreg_transfer_function): Transfer function. >> (df_live_subreg_finalize): Finalize the all_in/all_out df data. >> (df_live_subreg_free): Free the df data. >> (df_live_subreg_top_dump): Dump top df data. >> (df_live_subreg_bottom_dump): Dump bottom df data. >> (df_live_subreg_add_problem): Add the DF_LIVE_SUBREG problem. >> * df.h (enum df_problem_id): Add DF_LIVE_SUBREG. >> (class subregs_live): Simple decalare. >> (class df_live_subreg_local_bb_info): New class for full/partial def/use >> df data. >> (class df_live_subreg_bb_info): New class for full/partial in/out >> df data. >> (df_live_subreg): getting the df_live_subreg data. >> (df_live_subreg_add_problem): Exported. >> (df_live_subreg_finalize): Ditto. >> (df_live_subreg_check_result): Ditto. >> (multireg_p): Ditto. >> (init_range): Ditto. >> (add_subreg_range): Ditto. >> (remove_subreg_range): Ditto. >> (df_get_subreg_live_in): Accessor the all_in df data. >> (df_get_subreg_live_out): Accessor the all_out df data. >> (df_get_subreg_live_full_in): Accessor the full_in df data. >> (df_get_subreg_live_full_out): Accessor the full_out df data. >> (df_get_subreg_live_partial_in): Accessor the partial_in df data. >> (df_get_subreg_live_partial_out): Accessor the partial_out df data. >> (df_get_subreg_live_range_in): Accessor the range_in df data. >> (df_get_subreg_live_range_out): Accessor the range_out df data. >> * regs.h (get_nblocks): Get the blocks of mode. >> * sbitmap.cc (bitmap_full_p): sbitmap predicator. >> (bitmap_same_p): sbitmap predicator. >> (test_full): test bitmap_full_p. >> (test_same): test bitmap_same_p. >> (sbitmap_cc_tests): Add test_full and test_same. >> * sbitmap.h (bitmap_full_p): Exported. >> (bitmap_same_p): Ditto. >> * timevar.def (TV_DF_LIVE_SUBREG): add DF_LIVE_SUBREG timevar. >> * subreg-live-range.cc: New file. >> * subreg-live-range.h: New file. >> --- >> gcc/Makefile.in | 1 + >> gcc/df-problems.cc | 855 ++++++++++++++++++++++++++++++++++++++- >> gcc/df.h | 155 +++++++ >> gcc/regs.h | 5 + >> gcc/sbitmap.cc | 98 +++++ >> gcc/sbitmap.h | 2 + >> gcc/subreg-live-range.cc | 53 +++ >> gcc/subreg-live-range.h | 206 ++++++++++ >> gcc/timevar.def | 1 + >> 9 files changed, 1375 insertions(+), 1 deletion(-) >> create mode 100644 gcc/subreg-live-range.cc >> create mode 100644 gcc/subreg-live-range.h >> >> diff --git a/gcc/Makefile.in b/gcc/Makefile.in >> index a74761b7ab3..e195238f6ab 100644 >> --- a/gcc/Makefile.in >> +++ b/gcc/Makefile.in >> @@ -1684,6 +1684,7 @@ OBJS = \ >> store-motion.o \ >> streamer-hooks.o \ >> stringpool.o \ >> + subreg-live-range.o \ >> substring-locations.o \ >> target-globals.o \ >> targhooks.o \ >> diff --git a/gcc/df-problems.cc b/gcc/df-problems.cc >> index 88ee0dd67fc..93c5b52146c 100644 >> --- a/gcc/df-problems.cc >> +++ b/gcc/df-problems.cc >> @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see >> #include "target.h" >> #include "rtl.h" >> #include "df.h" >> +#include "subreg-live-range.h" >> #include "memmodel.h" >> #include "tm_p.h" >> #include "insn-config.h" >> @@ -1344,8 +1345,860 @@ df_lr_verify_transfer_functions (void) >> bitmap_clear (&all_blocks); >> } >> >> +/*---------------------------------------------------------------------------- >> + REGISTER AND SUBREGS LIVES >> + Like DF_LR, but include tracking subreg liveness. Currently used to provide > Nit: Should have two spaces after the dot, per GNU coding style. I'd suggest > to run the contrib/check_GNU_style.py script on your patches. > >> + subreg liveness related information to the register allocator. The subreg >> + information is currently tracked for registers that satisfy the following >> + conditions: >> + 1. REG is a pseudo register >> + 2. MODE_SIZE > UNIT_SIZE >> + 3. MODE_SIZE is a multiple of UNIT_SIZE >> + 4. REG is used via subreg pattern >> + Assuming: MODE = the machine mode of the REG >> + MODE_SIZE = GET_MODE_SIZE (MODE) >> + UNIT_SIZE = REGMODE_NATURAL_SIZE (MODE) >> + Condition 3 is currently strict, maybe it can be removed in the future, but >> + for now it is sufficient. >> + ----------------------------------------------------------------------------*/ >> + >> +/* These two empty data are used as default data in case the user does not turn >> + * on the track-subreg-liveness feature. */ >> +bitmap_head empty_bitmap; >> +subregs_live empty_live; > These names seem a bit too short for global variables. Perhaps tuck > them in a namespace? > > Also, since these must remain empty, shouldn't they be declared as const? > > namespace df { > const bitmap_head empty_bitmap; > const subregs_live empty_live; > } > > >> + >> +/* Private data for live_subreg problem. */ >> +struct df_live_subreg_problem_data >> +{ >> + /* Record registers that need to track subreg liveness. */ >> + bitmap_head tracked_regs; >> + /* An obstack for the bitmaps we need for this problem. */ >> + bitmap_obstack live_subreg_bitmaps; >> +}; >> + >> +/* Helper functions */ >> + >> +static df_live_subreg_bb_info * >> +df_live_subreg_get_bb_info (unsigned int index) >> +{ >> + if (index < df_live_subreg->block_info_size) >> + return &( >> + (class df_live_subreg_bb_info *) df_live_subreg->block_info)[index]; > Please consider using C++ instead: > return &static_cast(df_live_subreg->block_info)[index]; > >> + else >> + return NULL; > Use nullptr instead? > >> +} >> + >> +static df_live_subreg_local_bb_info * >> +get_live_subreg_local_bb_info (unsigned int bb_index) >> +{ >> + return df_live_subreg_get_bb_info (bb_index); >> +} >> + >> +/* Return true if regno is a multireg. */ >> +bool >> +multireg_p (int regno) >> +{ >> + if (regno < FIRST_PSEUDO_REGISTER) >> + return false; >> + rtx regno_rtx = regno_reg_rtx[regno]; >> + machine_mode reg_mode = GET_MODE (regno_rtx); >> + poly_int64 total_size = GET_MODE_SIZE (reg_mode); >> + poly_int64 natural_size = REGMODE_NATURAL_SIZE (reg_mode); >> + return maybe_gt (total_size, natural_size) >> + && multiple_p (total_size, natural_size); >> +} >> + >> +/* Return true if the REGNO need be track with subreg liveness. */ >> + >> +static bool >> +need_track_subreg_p (unsigned regno) >> +{ >> + struct df_live_subreg_problem_data *problem_data >> + = (struct df_live_subreg_problem_data *) df_live_subreg->problem_data; > Here auto could be used: > > auto problem_data = (struct df_live_subreg_problem_data *) df_live_subreg->problem_data; > >> + return bitmap_bit_p (&problem_data->tracked_regs, regno); >> +} >> + >> +/* Return the subreg_range of REF. */ > Is this comment valid? I see neither a REF parameter, nor a returned > value. Did you perhaps mean: > /* Fill RANGE with the subreg range for OP in REGMODE_NATURAL_SIZE > granularity. */ > >> +void >> +init_range (rtx op, sbitmap range) >> +{ >> + rtx reg = SUBREG_P (op) ? SUBREG_REG (op) : op; >> + machine_mode reg_mode = GET_MODE (reg); >> + >> + if (!read_modify_subreg_p (op)) >> + { >> + bitmap_set_range (range, 0, get_nblocks (reg_mode)); >> + return; >> + } >> + >> + rtx subreg = op; >> + machine_mode subreg_mode = GET_MODE (subreg); >> + poly_int64 offset = SUBREG_BYTE (subreg); >> + int nblocks = get_nblocks (reg_mode); >> + poly_int64 unit_size = REGMODE_NATURAL_SIZE (reg_mode); >> + poly_int64 subreg_size = GET_MODE_SIZE (subreg_mode); >> + poly_int64 left = offset + subreg_size; >> + >> + int subreg_start = -1; >> + int subreg_nblocks = -1; >> + for (int i = 0; i < nblocks; i += 1) >> + { >> + poly_int64 right = unit_size * (i + 1); >> + if (subreg_start < 0 && maybe_lt (offset, right)) >> + subreg_start = i; >> + if (subreg_nblocks < 0 && maybe_le (left, right)) >> + { >> + subreg_nblocks = i + 1 - subreg_start; >> + break; >> + } >> + } >> + gcc_assert (subreg_start >= 0 && subreg_nblocks > 0); >> + >> + bitmap_set_range (range, subreg_start, subreg_nblocks); >> +} >> + >> +/* Remove RANGE from BB_INFO's use data. */ >> +void >> +remove_subreg_range (df_live_subreg_local_bb_info *bb_info, unsigned int regno, >> + const_sbitmap range) >> +{ >> + bitmap partial = &bb_info->partial_use; >> + >> + bb_info->range_use->remove_range (regno, range); >> + if (bb_info->range_use->empty_p (regno)) >> + bitmap_clear_bit (partial, regno); >> +} >> + >> +/* Remove RANGE of REF from BB_INFO's use data. */ >> +static void >> +remove_subreg_range (df_live_subreg_local_bb_info *bb_info, df_ref ref) >> +{ >> + unsigned int regno = DF_REF_REGNO (ref); >> + machine_mode reg_mode = GET_MODE (DF_REF_REAL_REG (ref)); >> + >> + if (need_track_subreg_p (regno)) >> + { >> + auto_sbitmap range (get_nblocks (reg_mode)); >> + init_range (DF_REF_REG (ref), range); >> + remove_subreg_range (bb_info, regno, range); >> + } >> + else >> + { >> + bitmap_clear_bit (&bb_info->full_use, regno); >> + gcc_assert (!bitmap_bit_p (&bb_info->partial_use, regno)); >> + gcc_assert (!bitmap_bit_p (&bb_info->partial_def, regno)); >> + } >> +} >> + >> +/* add RANGE to BB_INFO's def/use. If is_def is true, means for BB_INFO's def, >> + otherwise for BB_INFO's use. */ >> +void >> +add_subreg_range (df_live_subreg_local_bb_info *bb_info, unsigned int regno, >> + const_sbitmap range, bool is_def) > Would it be more clear to split into two separate functions > instead of using a boolean flag? E.g.: > add_subreg_range_to_def (df_live_subreg_local_bb_info *bb_info, unsigned int regno, > const_sbitmap range) > add_subreg_range_to_use (df_live_subreg_local_bb_info *bb_info, unsigned int regno, > const_sbitmap range) > >> +{ >> + bitmap partial = is_def ? &bb_info->partial_def : &bb_info->partial_use; >> + subregs_live *range_live = is_def ? bb_info->range_def : bb_info->range_use; >> + >> + bitmap_set_bit (partial, regno); >> + range_live->add_range (regno, range); >> +} >> + >> +/* add RANGE of REF to BB_INFO def/use. If is_def is true, means for BB_INFO's >> + def, otherwise for BB_INFO's use. */ >> +static void >> +add_subreg_range (df_live_subreg_local_bb_info *bb_info, df_ref ref, >> + bool is_def) >> +{ >> + unsigned int regno = DF_REF_REGNO (ref); >> + machine_mode reg_mode = GET_MODE (DF_REF_REAL_REG (ref)); >> + >> + if (need_track_subreg_p (regno)) >> + { >> + auto_sbitmap range (get_nblocks (reg_mode)); >> + init_range (DF_REF_REG (ref), range); >> + add_subreg_range (bb_info, regno, range, is_def); >> + } >> + else >> + { >> + bitmap full = is_def ? &bb_info->full_def : &bb_info->full_use; >> + bitmap partial = is_def ? &bb_info->partial_def : &bb_info->partial_use; >> + bitmap_set_bit (full, regno); >> + gcc_assert (!bitmap_bit_p (partial, regno)); >> + } >> +} >> + >> +/* Free basic block info. */ >> + >> +static void >> +df_live_subreg_free_bb_info (basic_block bb ATTRIBUTE_UNUSED, void *vbb_info) >> +{ >> + df_live_subreg_bb_info *bb_info = (df_live_subreg_bb_info *) vbb_info; > Perhaps: > auto bb_info = static_cast vbb_info; > >> + if (bb_info) >> + { >> + delete bb_info->range_in; >> + bb_info->range_in = NULL; >> + delete bb_info->range_out; >> + bb_info->range_out = NULL; >> + >> + bitmap_clear (&bb_info->all_in); >> + bitmap_clear (&bb_info->full_in); >> + bitmap_clear (&bb_info->partial_in); >> + bitmap_clear (&bb_info->all_out); >> + bitmap_clear (&bb_info->full_out); >> + bitmap_clear (&bb_info->partial_out); >> + } >> +} >> + >> +/* Allocate or reset bitmaps for DF_LIVE_SUBREG blocks. The solution bits are >> + not touched unless the block is new. */ >> + >> +static void >> +df_live_subreg_alloc (bitmap all_blocks ATTRIBUTE_UNUSED) >> +{ >> + struct df_live_subreg_problem_data *problem_data; >> + df_grow_bb_info (df_live_subreg); >> + if (df_live_subreg->problem_data) >> + problem_data >> + = (struct df_live_subreg_problem_data *) df_live_subreg->problem_data; >> + else >> + { >> + problem_data = XNEW (struct df_live_subreg_problem_data); >> + df_live_subreg->problem_data = problem_data; >> + >> + bitmap_obstack_initialize (&problem_data->live_subreg_bitmaps); >> + bitmap_initialize (&problem_data->tracked_regs, >> + &problem_data->live_subreg_bitmaps); >> + } >> + >> + bitmap_clear (&problem_data->tracked_regs); >> + >> + basic_block bb; >> + FOR_EACH_BB_FN (bb, cfun) >> + bitmap_set_bit (df_live_subreg->out_of_date_transfer_functions, bb->index); >> + >> + bitmap_set_bit (df_live_subreg->out_of_date_transfer_functions, ENTRY_BLOCK); >> + bitmap_set_bit (df_live_subreg->out_of_date_transfer_functions, EXIT_BLOCK); >> + >> + unsigned int bb_index; >> + bitmap_iterator bi; >> + EXECUTE_IF_SET_IN_BITMAP (df_live_subreg->out_of_date_transfer_functions, 0, >> + bb_index, bi) >> + { >> + /* Find the regs which we need to track it's subreg liveness. */ >> + rtx_insn *insn; >> + df_ref use; >> + FOR_BB_INSNS (bb, insn) >> + { >> + if (!NONDEBUG_INSN_P (insn)) >> + continue; >> + >> + df_insn_info *insn_info = DF_INSN_INFO_GET (insn); >> + >> + FOR_EACH_INSN_INFO_USE (use, insn_info) >> + { >> + unsigned int regno = DF_REF_REGNO (use); >> + /* A multireg which is used via subreg pattern. */ >> + if (multireg_p (regno) >> + && DF_REF_FLAGS (use) & (DF_REF_SUBREG)) >> + bitmap_set_bit (&problem_data->tracked_regs, regno); >> + } >> + } >> + } >> + >> + if (dump_file) >> + { >> + fprintf (dump_file, ";; regs need to be tracked subreg liveness: "); >> + df_print_regset (dump_file, &problem_data->tracked_regs); >> + } >> + >> + size_t n = bitmap_count_bits (&problem_data->tracked_regs); >> + >> + EXECUTE_IF_SET_IN_BITMAP (df_live_subreg->out_of_date_transfer_functions, 0, >> + bb_index, bi) >> + { >> + /* Clean global infos. */ >> + df_live_subreg_bb_info *bb_info = df_live_subreg_get_bb_info (bb_index); > Here and for the rest of the call sites, I think auto is allowed to be used: > auto bb_info = df_live_subreg_get_bb_info (bb_index); > > > Regards, > Dimitar