Message ID | 201102111049.05138.ebotcazou@adacore.com |
---|---|
State | New |
Headers | show |
On Fri, Feb 11, 2011 at 10:49 AM, Eric Botcazou <ebotcazou@adacore.com> wrote: > Hi, > > this is an ICE at -O2 on i686-pc-mingw32 caused by partial inlining. > > We start with: > > <L0>: > MEM[(struct sfTextCtrlBase *)this_1(D)].D.1899.D.1763._vptr.fooControlBase = > &_ZTV14sfTextCtrlBase[2]; > MEM[(struct sfTextCtrlBase *)this_1(D)].D.1900._vptr.sfTextAreaBase = > &_ZTV14sfTextCtrlBase[6]; > MEM[(struct sfTextCtrlBase *)this_1(D)].D.1901.D.1826._vptr.sfTextEntryBase > = &_ZTV14sfTextCtrlBase[10]; > D.2174_11 = this_1(D) + 8; > MEM[(struct sfTextEntry *)this_1(D) + 8B].D.1826._vptr.sfTextEntryBase = > &_ZTV11sfTextEntry[2]; > sfTextEntryBase::~sfTextEntryBase (D.2174_11); > > [...] > > <L5>: > MEM[(struct sfTextAreaBase *)this_1(D) + 4B]._vptr.sfTextAreaBase = > &_ZTV14sfTextAreaBase[2]; > > <L6>: > resx 5 > > <L7>: > MEM[(struct fooControl *)this_1(D)].D.1763._vptr.fooControlBase = > &_ZTV10fooControl[2]; > fooControlBase::~fooControlBase (this_1(D)); > > <L8>: > resx 4 > > > L5/L6 is the cleanup of the L0 block. Partial inlining splits at L5: > > <L0>: > MEM[(struct sfTextCtrlBase *)this_1(D)].D.1899.D.1763._vptr.fooControlBase = > &_ZTV14sfTextCtrlBase[2]; > MEM[(struct sfTextCtrlBase *)this_1(D)].D.1900._vptr.sfTextAreaBase = > &_ZTV14sfTextCtrlBase[6]; > MEM[(struct sfTextCtrlBase *)this_1(D)].D.1901.D.1826._vptr.sfTextEntryBase > = &_ZTV14sfTextCtrlBase[10]; > D.2174_11 = this_1(D) + 8; > MEM[(struct sfTextEntry *)this_1(D) + 8B].D.1826._vptr.sfTextEntryBase = > &_ZTV11sfTextEntry[2]; > sfTextEntryBase::~sfTextEntryBase (D.2174_11); > > [...] > > <L5>: > sfTextCtrl::sfTextCtrl (this_1(D)); > > > with the split up part: > > sfTextCtrl::sfTextCtrl() (struct sfTextCtrl * const this) > { > struct sfTextCtrlBase * D.2188; > struct sfTextEntry * D.2187; > void * parent; > > <bb 6>: > > <L0>: > MEM[(struct sfTextAreaBase *)this_1(D) + 4B]._vptr.sfTextAreaBase = > &_ZTV14sfTextAreaBase[2]; > > Invalid sum of outgoing probabilities 0.0% > <L1>: > resx 3 > > <L2>: > MEM[(struct fooControl *)this_1(D)].D.1763._vptr.fooControlBase = > &_ZTV10fooControl[2]; > fooControlBase::~fooControlBase (this_1(D)); > > <L3>: > resx 2 > > } > > > Then the split up part is inlined back into the original function: > > <L2>: > MEM[(struct sfTextCtrlBase *)D.2028_1].D.1899.D.1763._vptr.fooControlBase = > &_ZTV14sfTextCtrlBase[2]; > MEM[(struct sfTextCtrlBase *)D.2028_1].D.1900._vptr.sfTextAreaBase = > &_ZTV14sfTextCtrlBase[6]; > MEM[(struct sfTextCtrlBase *)D.2028_1].D.1901.D.1826._vptr.sfTextEntryBase = > &_ZTV14sfTextCtrlBase[10]; > D.2245_8 = D.2028_1 + 8; > MEM[(struct sfTextEntry *)D.2028_1 + 8B].D.1826._vptr.sfTextEntryBase = > &_ZTV11sfTextEntry[2]; > sfTextEntryBase::~sfTextEntryBase (D.2245_8); > > [...] > > <L5>: > MEM[(struct sfTextAreaBase *)D.2028_1 + 4B]._vptr.sfTextAreaBase = > &_ZTV14sfTextAreaBase[2]; > > Invalid sum of outgoing probabilities 0.0% > <L9>: > resx 12 > > <L10>: > MEM[(struct fooControl *)D.2028_1].D.1763._vptr.fooControlBase = > &_ZTV10fooControl[2]; > fooControlBase::~fooControlBase (D.2028_1); > > <L11>: > resx 11 > > > The problem is that the new EH regions created by inlining (11 and 12) aren't > connected with the landing pads; the landing pad of the throwing statement: > > sfTextEntryBase::~sfTextEntryBase (D.2245_8); > > is still connected to the original region 5. So remove_unreachable_handlers > computes that region 12 is unreachable and turns resx 12 into a trap, which > is caught by an assertion because the successor L10 isn't reachable any more. > > Partial inlining already punts on external RESXs: > > /* FIXME: We can split regions containing EH. We can not however > split RESX, EH_DISPATCH and EH_POINTER referring to same region > into different partitions. This would require tracking of > EH regions and checking in consider_split_point if they > are not used elsewhere. */ > if (gimple_code (stmt) == GIMPLE_RESX > && stmt_can_throw_external (stmt)) > { > if (dump_file && (dump_flags & TDF_DETAILS)) > fprintf (dump_file, "Cannot split: external resx.\n"); > can_split = false; > } > > but it seems to me that the "external" is bogus here, hence the proposed fix. > > Tested on i586-suse-linux, OK for the mainline? Ok. Thanks, Richard. > > 2011-02-11 Eric Botcazou <ebotcazou@adacore.com> > > PR tree-optimization/47420 > * ipa-split.c (visit_bb): Put on any kind of GIMPLE_RESX. > > > 2011-02-11 Eric Botcazou <ebotcazou@adacore.com> > > * g++.dg/opt/inline17.C: New test. > > > -- > Eric Botcazou >
Index: ipa-split.c =================================================================== --- ipa-split.c (revision 169914) +++ ipa-split.c (working copy) @@ -643,11 +643,10 @@ visit_bb (basic_block bb, basic_block re into different partitions. This would require tracking of EH regions and checking in consider_split_point if they are not used elsewhere. */ - if (gimple_code (stmt) == GIMPLE_RESX - && stmt_can_throw_external (stmt)) + if (gimple_code (stmt) == GIMPLE_RESX) { if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Cannot split: external resx.\n"); + fprintf (dump_file, "Cannot split: resx.\n"); can_split = false; } if (gimple_code (stmt) == GIMPLE_EH_DISPATCH)