Ignore:
Timestamp:
Apr 4, 2017, 12:09:03 PM (8 years ago)
Author:
[email protected]
Message:

Don't need to Air::reportUsedRegisters for wasm at -O1
https://bugs.webkit.org/show_bug.cgi?id=170459

Reviewed by Saam Barati.

Source/JavaScriptCore:

I did some refactorings to Liveness<> to try to understand its performance. Based on
this I concluded that the bigger immediate issue is just removing unnecessary phases
from -O1.

This removes Air::reportUsedRegisters() from -O1 if the user has indicated that he is
not interested in StackmapGenerationParams::usedRegisters(). The logic here is a bit
weird because of how Air does spill code generation. The register allocator's spiller
will emit spill code using identifiable spill slots, which allows subsequent phases to
register-allocate the spill slots. We do this by a forward flow CSE phase called
fixObviousSpills (which is a terrible name since there is no longer anything obvious
about some of the spills that this phase can fix!). As is most natural for CSEs over
3AC, it rewires the uses of redundant computations rather than removing the redundant
computations. This means that if a spill got "fixed", there may be either or both of
the following:

  • Dead loads from the stack.
  • Dead stores to the stack.


We know that a load from the stack is dead if the register is dead at the point of the
load. We know that a store to the stack is dead if the spill slot is dead at the point
of the store.

Unfortunately, liveness analysis - over either registers or spill slots - is expensive.

Fortunately, allocateStack() already does liveness analysis over spill slots. So, we
baked elimination of stores to the stack into that phase. That aspect of clean-up after
the spill CSE comes for free.

Also fortunately for the FTL, we have to do reportUsedRegisters() anyway. This is a
phase that enables StackmapGenerationParams::usedRegisters() to work, which then
enables the FTL's patchpoints to do crazy slow-path live range splitting. So, Air's
strategy for the load fix-up after spill CSE is to do it as part of
reportUsedRegisters().

This patch introduces the Procedure::setNeedsUsedRegisters() API. But if you set
needsUsedRegisters to false then we will still run reportUsedRegisters() at -O2 as an
optimization - it removes dead loads from the stack that are left behind from
fixObviousSpills().

This is a ~6% compile time progression at -O1.

  • b3/B3Procedure.h:

(JSC::B3::Procedure::setNeedsUsedRegisters):
(JSC::B3::Procedure::needsUsedRegisters):

  • b3/B3StackmapGenerationParams.h:
  • b3/B3VariableLiveness.cpp:

(JSC::B3::VariableLiveness::VariableLiveness):

  • b3/air/AirCode.cpp:

(JSC::B3::Air::Code::needsUsedRegisters):

  • b3/air/AirCode.h:
  • b3/air/AirGenerate.cpp:

(JSC::B3::Air::prepareForGeneration):

  • b3/air/AirLiveness.h:

(JSC::B3::Air::Liveness::Liveness):

  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::parseAndCompile):

Source/WTF:

Just moved the liveness computation into a method, which enabled me to do the profiling
that I used to write this patch.

  • wtf/Liveness.h:

(WTF::Liveness::Liveness):
(WTF::Liveness::compute):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.cpp

    r203390 r214887  
    11/*
    2  * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3939const RegisterSet& StackmapGenerationParams::usedRegisters() const
    4040{
     41    ASSERT(m_context.code->needsUsedRegisters());
     42   
    4143    return m_value->m_usedRegisters;
    4244}
Note: See TracChangeset for help on using the changeset viewer.