⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 278390 in webkit


Ignore:
Timestamp:
Jun 2, 2021, 6:07:45 PM (5 years ago)
Author:
rmorisset@apple.com
Message:

B3MoveConstants should filter directly on Values, and only create ValueKeys when useful
​https://bugs.webkit.org/show_bug.cgi?id=226420

Reviewed by Phil Pizlo.

I did a few runs of JetStream2 to measure results, the time spent in B3MoveConstants goes from 160-180ms to 100-110ms.
The total time spent in B3+Air is in the 6 to 8s range, so this is approximately a 1% speedup.

  • b3/B3MoveConstants.cpp:
Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r278381 r278390  
     12021-06-02  Robin Morisset  <rmorisset@apple.com>
     2
     3        B3MoveConstants should filter directly on Values, and only create ValueKeys when useful
     4        https://bugs.webkit.org/show_bug.cgi?id=226420
     5
     6        Reviewed by Phil Pizlo.
     7
     8        I did a few runs of JetStream2 to measure results, the time spent in B3MoveConstants goes from 160-180ms to 100-110ms.
     9        The total time spent in B3+Air is in the 6 to 8s range, so this is approximately a 1% speedup.
     10
     11        * b3/B3MoveConstants.cpp:
     12
    1132021-06-02  Robin Morisset  <rmorisset@apple.com>
    214
  • trunk/Source/JavaScriptCore/b3/B3MoveConstants.cpp

    r261755 r278390  
    5252    {
    5353        hoistConstants(
    54             [&] (const ValueKey& key) -> bool {
    55                 return key.opcode() == ConstFloat || key.opcode() == ConstDouble;
     54            [&] (const Value* value) -> bool {
     55                return value->opcode() == ConstFloat || value->opcode() == ConstDouble;
    5656            });
    5757
    … …  
    5959       
    6060        hoistConstants(
    61             [&] (const ValueKey& key) -> bool {
    62                 return key.opcode() == Const32 || key.opcode() == Const64 || key.opcode() == ArgumentReg;
     61            [&] (const Value* value) -> bool {
     62                return value->opcode() == Const32 || value->opcode() == Const64 || value->opcode() == ArgumentReg;
    6363            });
    6464    }
    … …  
    7676            for (Value* value : *block) {
    7777                for (Value*& child : value->children()) {
     78                    if (!filter(child))
     79                        continue;
     80
    7881                    ValueKey key = child->key();
    79                     if (!filter(key))
    80                         continue;
    81 
    8282                    auto result = valueForConstant.add(key, child);
    8383                    if (result.isNewEntry) {
    … …  
    116116        for (BasicBlock* block : m_proc) {
    117117            for (Value*& value : *block) {
     118                if (!filter(value))
     119                    continue;
     120
    118121                ValueKey key = value->key();
    119                 if (!filter(key))
    120                     continue;
    121 
    122122                if (valueForConstant.get(key) == value)
    123123                    value = m_proc.add<Value>(Nop, value->origin());
    … …  
    154154                // haven't inserted it yet. This inserts the constant if necessary.
    155155                auto materialize = [&] (Value* child) {
    156                     ValueKey key = child->key();
    157                     if (!filter(key))
     156                    if (!filter(child))
    158157                        return;
    159158
    160159                    // If we encounter a fast constant, then it must be canonical, since we already
    161160                    // got rid of the non-canonical ones.
    162                     ASSERT(valueForConstant.get(key) == child);
     161                    ASSERT(valueForConstant.get(child->key()) == child);
    163162
    164163                    if (child->owner != block) {
    … …  
    176175                if (MemoryValue* memoryValue = value->as<MemoryValue>()) {
    177176                    Value* pointer = memoryValue->lastChild();
    178                     if (pointer->hasIntPtr() && filter(pointer->key())) {
     177                    if (pointer->hasIntPtr() && filter(pointer)) {
    179178                        auto desiredOffset = [&] (Value* otherPointer) -> intptr_t {
    180179                            // We would turn this:
    … …  
    214213                    case Sub: {
    215214                        Value* addend = value->child(1);
    216                         if (!addend->hasInt() || !filter(addend->key()))
     215                        if (!addend->hasInt() || !filter(addend))
    217216                            break;
    218217                        int64_t addendConst = addend->asInt();
    … …  
    262261    {
    263262        for (Value* value : m_proc.values()) {
     263            if (!goesInTable(value))
     264                continue;
    264265            ValueKey key = value->key();
    265             if (goesInTable(key))
    266                 m_constTable.add(key, m_constTable.size());
     266            m_constTable.add(key, m_constTable.size());
    267267        }
    268268       
    … …  
    283283                   
    284284                    Value*& child = value->child(childIndex);
     285                    if (!goesInTable(child))
     286                        continue;
     287
    285288                    ValueKey key = child->key();
    286                     if (!goesInTable(key))
    287                         continue;
    288 
    289289                    child = m_insertionSet.insertValue(
    290290                        valueIndex, key.materialize(m_proc, value->origin()));
    … …  
    299299            for (unsigned valueIndex = 0; valueIndex < block->size(); ++valueIndex) {
    300300                Value* value = block->at(valueIndex);
     301                if (!goesInTable(value))
     302                    continue;
     303                if (offLimits.contains(value))
     304                    continue;
     305
    301306                ValueKey key = value->key();
    302                 if (!goesInTable(key))
    303                     continue;
    304                 if (offLimits.contains(value))
    305                     continue;
    306 
    307307                auto offset = sizeof(int64_t) * m_constTable.get(key);
    308308                if (!isRepresentableAs<Value::OffsetType>(offset))
    … …  
    322322    }
    323323
    324     bool goesInTable(const ValueKey& key)
    325     {
    326         return (key.opcode() == ConstDouble && key != doubleZero())
    327             || (key.opcode() == ConstFloat && key != floatZero());
    328     }
    329 
    330     static ValueKey doubleZero()
    331     {
    332         return ValueKey(ConstDouble, Double, 0.0);
    333     }
    334 
    335     static ValueKey floatZero()
    336     {
    337         return ValueKey(ConstFloat, Float, 0.0);
     324    bool goesInTable(const Value* value)
     325    {
     326        switch (value->opcode()) {
     327        case ConstDouble: {
     328            double doubleZero = 0.0;
     329            return bitwise_cast<uint64_t>(value->asDouble()) != bitwise_cast<uint64_t>(doubleZero);
     330        }
     331        case ConstFloat: {
     332            float floatZero = 0.0;
     333            return bitwise_cast<uint32_t>(value->asFloat()) != bitwise_cast<uint32_t>(floatZero);
     334        }
     335        default:
     336            break;
     337        }
     338        return false;
    338339    }
    339340
Note: See TracChangeset for help on using the changeset viewer.