Changeset 214836 in webkit


Ignore:
Timestamp:
Apr 3, 2017 1:50:33 PM (7 years ago)
Author:
fpizlo@apple.com
Message:

WTF::Liveness should have an API that focuses on actions at instruction boundaries
https://bugs.webkit.org/show_bug.cgi?id=170407

Reviewed by Keith Miller.

Source/JavaScriptCore:

Adopt changes to the WTF::Liveness<> API. Instead of having separate functions for the
early/late versions of uses and defs, we now have just a use/def API. Those
automatically take care of eary/late issues as needed.

This reduces the API surface between WTF::Liveness<> and its clients, which makes it
easier to implement some other optimizations I'm thinking about.

  • b3/B3VariableLiveness.h:

(JSC::B3::VariableLivenessAdapter::forEachUse):
(JSC::B3::VariableLivenessAdapter::forEachDef):
(JSC::B3::VariableLivenessAdapter::forEachEarlyUse): Deleted.
(JSC::B3::VariableLivenessAdapter::forEachLateUse): Deleted.
(JSC::B3::VariableLivenessAdapter::forEachEarlyDef): Deleted.
(JSC::B3::VariableLivenessAdapter::forEachLateDef): Deleted.

  • b3/air/AirLiveness.h:

(JSC::B3::Air::LivenessAdapter::blockSize):
(JSC::B3::Air::LivenessAdapter::forEachUse):
(JSC::B3::Air::LivenessAdapter::forEachDef):
(JSC::B3::Air::LivenessAdapter::forEachEarlyUse): Deleted.
(JSC::B3::Air::LivenessAdapter::forEachLateUse): Deleted.
(JSC::B3::Air::LivenessAdapter::forEachEarlyDef): Deleted.
(JSC::B3::Air::LivenessAdapter::forEachLateDef): Deleted.

Source/WTF:

Change the Liveness<> API to handle early and late things in one lump inside forEachUse
and forEachDef functions. This reduces the amount of different functions that Liveness<>
expects from its adaptor. This makes it easier to implement optimizations that cache the
use/def behavior of each instruction boundary.

  • wtf/Liveness.h:

(WTF::Liveness::Liveness):
(WTF::Liveness::LocalCalc::execute):

Location:
trunk/Source
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r214827 r214836  
     12017-04-03  Filip Pizlo  <fpizlo@apple.com>
     2
     3        WTF::Liveness should have an API that focuses on actions at instruction boundaries
     4        https://bugs.webkit.org/show_bug.cgi?id=170407
     5
     6        Reviewed by Keith Miller.
     7       
     8        Adopt changes to the WTF::Liveness<> API. Instead of having separate functions for the
     9        early/late versions of uses and defs, we now have just a use/def API. Those
     10        automatically take care of eary/late issues as needed.
     11       
     12        This reduces the API surface between WTF::Liveness<> and its clients, which makes it
     13        easier to implement some other optimizations I'm thinking about.
     14
     15        * b3/B3VariableLiveness.h:
     16        (JSC::B3::VariableLivenessAdapter::forEachUse):
     17        (JSC::B3::VariableLivenessAdapter::forEachDef):
     18        (JSC::B3::VariableLivenessAdapter::forEachEarlyUse): Deleted.
     19        (JSC::B3::VariableLivenessAdapter::forEachLateUse): Deleted.
     20        (JSC::B3::VariableLivenessAdapter::forEachEarlyDef): Deleted.
     21        (JSC::B3::VariableLivenessAdapter::forEachLateDef): Deleted.
     22        * b3/air/AirLiveness.h:
     23        (JSC::B3::Air::LivenessAdapter::blockSize):
     24        (JSC::B3::Air::LivenessAdapter::forEachUse):
     25        (JSC::B3::Air::LivenessAdapter::forEachDef):
     26        (JSC::B3::Air::LivenessAdapter::forEachEarlyUse): Deleted.
     27        (JSC::B3::Air::LivenessAdapter::forEachLateUse): Deleted.
     28        (JSC::B3::Air::LivenessAdapter::forEachEarlyDef): Deleted.
     29        (JSC::B3::Air::LivenessAdapter::forEachLateDef): Deleted.
     30
    1312017-04-03  Filip Pizlo  <fpizlo@apple.com>
    232
  • trunk/Source/JavaScriptCore/b3/B3VariableLiveness.h

    r214410 r214836  
    6262   
    6363    template<typename Func>
    64     void forEachEarlyUse(BasicBlock* block, unsigned valueIndex, const Func& func)
     64    void forEachUse(BasicBlock* block, unsigned valueBoundaryIndex, const Func& func)
    6565    {
    66         Value* value = block->get(valueIndex);
     66        // We want all of the uses that happen between valueBoundaryIndex-1 and
     67        // valueBoundaryIndex. Since the Get opcode is the only value that has a use and since
     68        // this is an early use, we only care about block[valueBoundaryIndex].
     69        Value* value = block->get(valueBoundaryIndex);
    6770        if (!value)
    6871            return;
     
    7376   
    7477    template<typename Func>
    75     void forEachLateUse(BasicBlock*, unsigned, const Func&)
     78    void forEachDef(BasicBlock* block, unsigned valueBoundaryIndex, const Func& func)
    7679    {
    77     }
    78    
    79     template<typename Func>
    80     void forEachEarlyDef(BasicBlock*, unsigned, const Func&)
    81     {
    82     }
    83    
    84     template<typename Func>
    85     void forEachLateDef(BasicBlock* block, unsigned valueIndex, const Func& func)
    86     {
    87         Value* value = block->get(valueIndex);
     80        // We want all of the defs that happen between valueBoundaryIndex-1 and
     81        // valueBoundaryIndex. Since the Set opcode is the only value that has a def and since
     82        // this is an late def, we only care about block[valueBoundaryIndex - 1].
     83        Value* value = block->get(valueBoundaryIndex - 1);
    8884        if (!value)
    8985            return;
  • trunk/Source/JavaScriptCore/b3/air/AirLiveness.h

    r214410 r214836  
    5151        return block->size();
    5252    }
    53 
     53   
    5454    template<typename Func>
    55     void forEachEarlyUse(BasicBlock* block, unsigned instIndex, const Func& func)
     55    void forEachUse(BasicBlock* block, size_t instBoundaryIndex, const Func& func)
    5656    {
    57         Inst* inst = block->get(instIndex);
    58         if (!inst)
    59             return;
    60         inst->forEach<typename Adapter::Thing>(
    61             [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
    62                 if (Arg::isEarlyUse(role)
    63                     && Adapter::acceptsBank(bank)
    64                     && Adapter::acceptsRole(role))
    65                     func(Adapter::valueToIndex(thing));
    66             });
     57        if (Inst* prevInst = block->get(instBoundaryIndex - 1)) {
     58            prevInst->forEach<typename Adapter::Thing>(
     59                [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
     60                    if (Arg::isLateUse(role)
     61                        && Adapter::acceptsBank(bank)
     62                        && Adapter::acceptsRole(role))
     63                        func(Adapter::valueToIndex(thing));
     64                });
     65        }
     66       
     67        if (Inst* nextInst = block->get(instBoundaryIndex)) {
     68            nextInst->forEach<typename Adapter::Thing>(
     69                [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
     70                    if (Arg::isEarlyUse(role)
     71                        && Adapter::acceptsBank(bank)
     72                        && Adapter::acceptsRole(role))
     73                        func(Adapter::valueToIndex(thing));
     74                });
     75        }
    6776    }
    6877   
    6978    template<typename Func>
    70     void forEachLateUse(BasicBlock* block, unsigned instIndex, const Func& func)
     79    void forEachDef(BasicBlock* block, size_t instBoundaryIndex, const Func& func)
    7180    {
    72         Inst* inst = block->get(instIndex);
    73         if (!inst)
    74             return;
    75         inst->forEach<typename Adapter::Thing>(
    76             [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
    77                 if (Arg::isLateUse(role)
    78                     && Adapter::acceptsBank(bank)
    79                     && Adapter::acceptsRole(role))
    80                     func(Adapter::valueToIndex(thing));
    81             });
     81        if (Inst* prevInst = block->get(instBoundaryIndex - 1)) {
     82            prevInst->forEach<typename Adapter::Thing>(
     83                [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
     84                    if (Arg::isLateDef(role)
     85                        && Adapter::acceptsBank(bank)
     86                        && Adapter::acceptsRole(role))
     87                        func(Adapter::valueToIndex(thing));
     88                });
     89        }
     90       
     91        if (Inst* nextInst = block->get(instBoundaryIndex)) {
     92            nextInst->forEach<typename Adapter::Thing>(
     93                [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
     94                    if (Arg::isEarlyDef(role)
     95                        && Adapter::acceptsBank(bank)
     96                        && Adapter::acceptsRole(role))
     97                        func(Adapter::valueToIndex(thing));
     98                });
     99        }
    82100    }
    83    
    84     template<typename Func>
    85     void forEachEarlyDef(BasicBlock* block, unsigned instIndex, const Func& func)
    86     {
    87         Inst* inst = block->get(instIndex);
    88         if (!inst)
    89             return;
    90         inst->forEach<typename Adapter::Thing>(
    91             [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
    92                 if (Arg::isEarlyDef(role)
    93                     && Adapter::acceptsBank(bank)
    94                     && Adapter::acceptsRole(role))
    95                     func(Adapter::valueToIndex(thing));
    96             });
    97     }
    98    
    99     template<typename Func>
    100     void forEachLateDef(BasicBlock* block, unsigned instIndex, const Func& func)
    101     {
    102         Inst* inst = block->get(instIndex);
    103         if (!inst)
    104             return;
    105         inst->forEach<typename Adapter::Thing>(
    106             [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
    107                 if (Arg::isLateDef(role)
    108                     && Adapter::acceptsBank(bank)
    109                     && Adapter::acceptsRole(role))
    110                     func(Adapter::valueToIndex(thing));
    111             });
    112     }
    113    
     101
    114102    Code& code;
    115103};
  • trunk/Source/WTF/ChangeLog

    r214716 r214836  
     12017-04-03  Filip Pizlo  <fpizlo@apple.com>
     2
     3        WTF::Liveness should have an API that focuses on actions at instruction boundaries
     4        https://bugs.webkit.org/show_bug.cgi?id=170407
     5
     6        Reviewed by Keith Miller.
     7       
     8        Change the Liveness<> API to handle early and late things in one lump inside forEachUse
     9        and forEachDef functions. This reduces the amount of different functions that Liveness<>
     10        expects from its adaptor. This makes it easier to implement optimizations that cache the
     11        use/def behavior of each instruction boundary.
     12
     13        * wtf/Liveness.h:
     14        (WTF::Liveness::Liveness):
     15        (WTF::Liveness::LocalCalc::execute):
     16
    1172017-04-01  Csaba Osztrogonác  <ossy@webkit.org>
    218
  • trunk/Source/WTF/wtf/Liveness.h

    r214410 r214836  
    5858            IndexVector& liveAtTail = m_liveAtTail[block];
    5959
    60             Adapter::forEachLateUse(
    61                 block, Adapter::blockSize(block) - 1,
     60            Adapter::forEachUse(
     61                block, Adapter::blockSize(block),
    6262                [&] (unsigned index) {
    6363                    liveAtTail.append(index);
     
    9292
    9393                // Handle the early def's of the first instruction.
    94                 Adapter::forEachEarlyDef(
     94                Adapter::forEachDef(
    9595                    block, 0,
    9696                    [&] (unsigned index) {
     
    221221            auto& workset = m_liveness.m_workset;
    222222
    223             // First handle the early def's of the next instruction.
    224             m_liveness.forEachEarlyDef(
     223            // Want an easy example to help you visualize how this works?
     224            // Check out B3VariableLiveness.h.
     225            //
     226            // Want a hard example to help you understand the hard cases?
     227            // Check out AirLiveness.h.
     228           
     229            m_liveness.forEachDef(
    225230                m_block, instIndex + 1,
    226231                [&] (unsigned index) {
     
    228233                });
    229234           
    230             // Then handle def's.
    231             m_liveness.forEachLateDef(
     235            m_liveness.forEachUse(
    232236                m_block, instIndex,
    233                 [&] (unsigned index) {
    234                     workset.remove(index);
    235                 });
    236 
    237             // Then handle use's.
    238             m_liveness.forEachEarlyUse(
    239                 m_block, instIndex,
    240                 [&] (unsigned index) {
    241                     workset.add(index);
    242                 });
    243 
    244             // And finally, handle the late use's of the previous instruction.
    245             m_liveness.forEachLateUse(
    246                 m_block, instIndex - 1,
    247237                [&] (unsigned index) {
    248238                    workset.add(index);
Note: See TracChangeset for help on using the changeset viewer.