Ignore:
Timestamp:
Apr 6, 2017, 1:58:34 PM (8 years ago)
Author:
[email protected]
Message:

B3 -O1 should generate better code than -O0
https://bugs.webkit.org/show_bug.cgi?id=170563

Reviewed by Michael Saboff.

Prior to this change, code generated by -O1 ran slower than code generated by -O0. This turned
out to be because of reduceStrength optimizations that increase live ranges and create register
pressure, which then creates problems for linear scan.

It seemed obvious that canonicalizations that help isel, constant folding, and one-for-one
strength reductions should stay. It also seemed obvious that SSA and CFG simplification are fast
and harmless. So, I focused on removing:

  • CSE, which increases live ranges. This is a risky optimization when we know that we've chosen to use a bad register allocator.


  • Sophisticated strength reductions that create more code, like the insane division optimization.


  • Anything that inserts basic blocks.


CSE appeared to be the cause of half of the throughput regression of -O1 but none of the compile
time. This change also reduces the running time of reduceStrength by making it not a fixpoint at
optLevel<2.

This makes wasm -O1 compile 17% faster. This makes wasm -O1 run 19% faster. This makes -O1 code
run 3% faster than -O0, and compile about 4% slower than -O0. We may yet end up choosing to use
-O0, but at least now -O1 isn't totally useless.

  • b3/B3ReduceStrength.cpp:
File:
1 edited

Legend:

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

    r214636 r215057  
    443443            simplifySSA();
    444444           
    445             m_proc.resetValueOwners();
    446             m_dominators = &m_proc.dominators(); // Recompute if necessary.
    447             m_pureCSE.clear();
     445            if (m_proc.optLevel() >= 2) {
     446                m_proc.resetValueOwners();
     447                m_dominators = &m_proc.dominators(); // Recompute if necessary.
     448                m_pureCSE.clear();
     449            }
    448450
    449451            for (BasicBlock* block : m_proc.blocksInPreOrder()) {
     
    458460                    m_value = m_block->at(m_index);
    459461                    m_value->performSubstitution();
    460                    
    461462                    reduceValueStrength();
    462                     replaceIfRedundant();
     463                    if (m_proc.optLevel() >= 2)
     464                        replaceIfRedundant();
    463465                }
    464466                m_insertionSet.execute(m_block);
     
    466468
    467469            m_changedCFG |= m_blockInsertionSet.execute();
    468             if (m_changedCFG) {
    469                 m_proc.resetReachability();
    470                 m_proc.invalidateCFG();
    471                 m_dominators = nullptr; // Dominators are not valid anymore, and we don't need them yet.
    472                 m_changed = true;
    473             }
     470            handleChangedCFGIfNecessary();
    474471           
    475472            result |= m_changed;
    476         } while (m_changed);
     473        } while (m_changed && m_proc.optLevel() >= 2);
     474       
     475        if (m_proc.optLevel() < 2) {
     476            m_changedCFG = false;
     477            simplifyCFG();
     478            handleChangedCFGIfNecessary();
     479        }
     480       
    477481        return result;
    478482    }
     
    726730
    727731                    if (m_value->type() != Int32)
     732                        break;
     733                   
     734                    if (m_proc.optLevel() < 2)
    728735                        break;
    729736
     
    822829
    823830                default:
     831                    if (m_proc.optLevel() < 2)
     832                        break;
     833                   
    824834                    // Turn this: Mod(N, D)
    825835                    // Into this: Sub(N, Mul(Div(N, D), D))
     
    18421852                m_changed = true;
    18431853            }
     1854           
     1855            if (m_proc.optLevel() < 2)
     1856                break;
    18441857
    18451858            // If we are checking some bounded-size SSA expression that leads to a Select that
     
    19481961            }
    19491962
    1950             // If a check for the same property dominates us, we can kill the branch. This sort
    1951             // of makes sense here because it's cheap, but hacks like this show that we're going
    1952             // to need SCCP.
    1953             Value* check = m_pureCSE.findMatch(
    1954                 ValueKey(Check, Void, m_value->child(0)), m_block, *m_dominators);
    1955             if (check) {
    1956                 // The Check would have side-exited if child(0) was non-zero. So, it must be
    1957                 // zero here.
    1958                 m_block->taken().block()->removePredecessor(m_block);
    1959                 m_value->replaceWithJump(m_block, m_block->notTaken());
    1960                 m_changedCFG = true;
     1963            if (m_proc.optLevel() >= 2) {
     1964                // If a check for the same property dominates us, we can kill the branch. This sort
     1965                // of makes sense here because it's cheap, but hacks like this show that we're going
     1966                // to need SCCP.
     1967                Value* check = m_pureCSE.findMatch(
     1968                    ValueKey(Check, Void, m_value->child(0)), m_block, *m_dominators);
     1969                if (check) {
     1970                    // The Check would have side-exited if child(0) was non-zero. So, it must be
     1971                    // zero here.
     1972                    m_block->taken().block()->removePredecessor(m_block);
     1973                    m_value->replaceWithJump(m_block, m_block->notTaken());
     1974                    m_changedCFG = true;
     1975                }
    19611976            }
    19621977            break;
     
    23792394        }
    23802395    }
     2396   
     2397    void handleChangedCFGIfNecessary()
     2398    {
     2399        if (m_changedCFG) {
     2400            m_proc.resetReachability();
     2401            m_proc.invalidateCFG();
     2402            m_dominators = nullptr; // Dominators are not valid anymore, and we don't need them yet.
     2403            m_changed = true;
     2404        }
     2405    }
    23812406
    23822407    void checkPredecessorValidity()
Note: See TracChangeset for help on using the changeset viewer.