On Wed, Sep 9, 2015 at 11:07 PM, Jeff Law <l...@redhat.com> wrote:
> On 08/31/2015 05:30 AM, Richard Biener wrote:
>>
>> On Mon, Aug 31, 2015 at 7:49 AM, Mikhail Maltsev <malts...@gmail.com>
>> wrote:
>>>
>>> Hi, all!
>>>
>>> This patch removes some conditional compilation from GCC. In this patch I
>>> define
>>> a macro CHECKING_P, which is equal to 1 when ENABLE_CHECKING is defined
>>> and 0
>>> otherwise. The reason for using a new name is the following: currently in
>>> GCC
>>> there are many places where ENABLE_CHECKING is checked using #ifdef, and
>>> it is a
>>> common way to do such checks (though #if would also work and is used in
>>> several
>>> places). If we change it in such way that it is always defined,
>>> accidentally
>>> using "#ifdef" instead of "#if" will lead to subtle errors: some
>>> expensive
>>> checks intended only for development stage will be enabled in release
>>> build and
>>> cause performance degradation.
>>>
>>> This patch removes all uses of ENABLE_CHECKING (I also tried poisoning
>>> this
>>> identifier in system.h, and the build succeeded, but I don't know how
>>> will this
>>> affect, e.g. merging feature branches, so I think such decisions should
>>> be made
>>> by maintainers).
>>
>>
>> I think we want to keep ENABLE_CHECKING for macro use and for some
>> selected
>> cases.
>
> Can you outline which cases you want to keep?  My general feeling is to
> avoid conditionally compiled code as much as we can.

I guess I was merely looking for the patch to be split up to see the motivation
of a always-defined CHECKING_P macro.  With the suggestion to have
a runtime flag_checking variable I wonder if there is any real code that
is guarded by ENABLE_CHECKING now that can't use flag_checking
(yes, tree checking macros and gcc_checking_assert, but those already
work with ENABLE_CHECKING just fine and are in macro context anyway).

Richard.

>>
>>> As for conditional compilation, I tried to remove it and replace #ifdef-s
>>> with
>>> if-s where possible, but, of course, avoided changing data structures
>>> layout. I
>>> also avoided reindenting large blocks of code. I changed some functions
>>> (and a
>>> couple of global variables) that were only used in "checking" build so
>>> that now
>>> they are always defined/compiled and have a DEBUG_FUNCTION (i.e. "used")
>>> attribute. I'll try to handle them in a more clean way: move CHECKING_P
>>> check
>>> inside their definitions - that will slightly reduce "visual noise" from
>>> conditions like
>
> We'll eventually want to do the reindentations as well, but for an RFC,
> that's fine.
>
>
>>>
>>> While working on this patch I noticed some issues worth mentioning. In
>>> sese.h:bb_in_region we have a check (enabled only in "checking" build):
>>>
>>>        /* Check that there are no edges coming in the region: all the
>>>           predecessors of EXIT are dominated by ENTRY.  */
>>>        FOR_EACH_EDGE (e, ei, exit->preds)
>>>          dominated_by_p (CDI_DOMINATORS, e->src, entry);
>>>
>>> IIUC, dominated_by_p has no side effects, so it's useless. Changing it to
>>> "gcc_assert (dominated_by_p (...));" causes regressions. I disabled it in
>>> the
>>> patch and added a comment.
>>
>>
>> You should open a bugreport.
>
> Agreed.  Looks like a simple bug.
>
>>
>>> In lra.c we have:
>>>
>>> #ifdef ENABLE_CHECKING
>>>
>>>   /* Function checks RTL for correctness. If FINAL_P is true, it is
>>>      done at the end of LRA and the check is more rigorous.  */
>>>   static void
>>>   check_rtl (bool final_p)
>>> ...
>>> #ifdef ENABLED_CHECKING
>>>              extract_constrain_insn (insn);
>>> #endif
>>> ...
>>> #endif /* #ifdef ENABLE_CHECKING */
>>>
>>> The comment for extract_constrain_insn says:
>>> /* Do uncached extract_insn, constrain_operands and complain about
>>> failures.
>>>     This should be used when extracting a pre-existing constrained
>>> instruction
>>>     if the caller wants to know which alternative was chosen.  */
>>>
>>> So, as I understand, this additional check can be useful. This patch
>>> removes
>>> "#ifdef ENABLED_CHECKING" (without regressions).
>
> No strong opinions here.  There's other things that would catch this later.
> The check merely catches it closer to the point where things go wrong.  So
> I'd tend to want it to be conditional.
>
>>>
>>> The third issue is that some gcc_checking_assert-s were guarded by #ifdef
>>> like:
>>> #ifdef ENABLE_CHECKING
>>>     gcc_checking_assert (!is_deleted (*slot));
>>> #endif
>>> (is_deleted is defined unconditionally).
>>>
>>> Probably that is because it is not obvious from the "release" definition
>>> #define gcc_checking_assert(EXPR) ((void)(0 && (EXPR)))
>>> that EXPR is not evaluated.
>>>
>>> At least, I first decided to change it to something like
>>> "do { if (0) (void)(EXPR); } while(0)"
>>> and only then realized that the effect of "0 &&" is exactly the same. I
>>> added a
>>> comment to make it more obvious.
>
> Sounds reasonable.
>
>>>
>>> I tested the patch on x86_64-pc-linux-gnu with --enable-checking=yes and
>>> "release". Likewise, built config-list.mk in both configurations. There
>>> we some
>>> minor changes since that check, but I'll need to rebase the patch anyway,
>>> so I
>>> will repeat the full check.
>>>
>>> Please review the patch.
>>
>>
>> Erm.  Ok so if you are here...  I've long wanted the heavier parts of
>> checking
>> (like IL checking) to be controlled by a command-line switch (-fchecking
>> or
>> even -fchecking[=...]) rather than being compile-time controlled.
>> Obviously
>> that's not sth we want (or easily can get) for things like tree-checking
>> or
>> asserts.
>>
>> Just a suggestion which might eventually remove a whole bunch of
>> ENABLE_CHECKING #ifs before tackling the rest.
>
> Seems like a reasonable thing to me.
>
> jeff
>

Reply via email to