Changeset 195395 in webkit


Ignore:
Timestamp:
Jan 20, 2016 7:12:55 PM (8 years ago)
Author:
fpizlo@apple.com
Message:

B3 should have basic path specialization
https://bugs.webkit.org/show_bug.cgi?id=153200

Reviewed by Benjamin Poulain.

Source/JavaScriptCore:

This adds two different kind of path specializations:

  • Check(Select) where the Select results are constants is specialized into a Branch instead of a Select and duplicated paths where the results of the Select are folded.
  • Tail duplication. A jump to a small block causes the block's contents to be copied over the Jump.

Both optimizations required being able to clone Values. We can now do that using
proc.clone(value).

Check(Select) specialization needed some utilities for walking graphs of Values.

Tail duplication needed SSA fixup, so I added a way to demote values to anonymous stack
slots (B3's equivalent of non-SSA variables) and a way to "fix SSA", i.e. to allocate
anonymous stack slots to SSA values along with an optimal Phi graph.

This is a big speed-up on Octane/deltablue. It's a 2.2% speed-up on Octane overall.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • b3/B3ArgumentRegValue.cpp:

(JSC::B3::ArgumentRegValue::dumpMeta):
(JSC::B3::ArgumentRegValue::cloneImpl):

  • b3/B3ArgumentRegValue.h:
  • b3/B3BasicBlock.cpp:

(JSC::B3::BasicBlock::append):
(JSC::B3::BasicBlock::appendNonTerminal):
(JSC::B3::BasicBlock::removeLast):

  • b3/B3BasicBlock.h:

(JSC::B3::BasicBlock::values):

  • b3/B3BasicBlockInlines.h:

(JSC::B3::BasicBlock::appendNew):
(JSC::B3::BasicBlock::appendNewNonTerminal):
(JSC::B3::BasicBlock::replaceLastWithNew):

  • b3/B3BlockInsertionSet.h:
  • b3/B3BreakCriticalEdges.cpp: Added.

(JSC::B3::breakCriticalEdges):

  • b3/B3BreakCriticalEdges.h: Added.
  • b3/B3CCallValue.cpp:

(JSC::B3::CCallValue::~CCallValue):
(JSC::B3::CCallValue::cloneImpl):

  • b3/B3CCallValue.h:
  • b3/B3CheckValue.cpp:

(JSC::B3::CheckValue::convertToAdd):
(JSC::B3::CheckValue::cloneImpl):
(JSC::B3::CheckValue::CheckValue):

  • b3/B3CheckValue.h:
  • b3/B3Const32Value.cpp:

(JSC::B3::Const32Value::dumpMeta):
(JSC::B3::Const32Value::cloneImpl):

  • b3/B3Const32Value.h:
  • b3/B3Const64Value.cpp:

(JSC::B3::Const64Value::dumpMeta):
(JSC::B3::Const64Value::cloneImpl):

  • b3/B3Const64Value.h:
  • b3/B3ConstDoubleValue.cpp:

(JSC::B3::ConstDoubleValue::dumpMeta):
(JSC::B3::ConstDoubleValue::cloneImpl):

  • b3/B3ConstDoubleValue.h:
  • b3/B3ConstFloatValue.cpp:

(JSC::B3::ConstFloatValue::dumpMeta):
(JSC::B3::ConstFloatValue::cloneImpl):

  • b3/B3ConstFloatValue.h:
  • b3/B3ControlValue.cpp:

(JSC::B3::ControlValue::dumpMeta):
(JSC::B3::ControlValue::cloneImpl):

  • b3/B3ControlValue.h:
  • b3/B3DuplicateTails.cpp: Added.

(JSC::B3::duplicateTails):

  • b3/B3DuplicateTails.h: Added.
  • b3/B3FixSSA.cpp: Added.

(JSC::B3::demoteValues):
(JSC::B3::fixSSA):

  • b3/B3FixSSA.h: Added.
  • b3/B3Generate.cpp:

(JSC::B3::generateToAir):

  • b3/B3IndexSet.h:

(JSC::B3::IndexSet::Iterable::Iterable):
(JSC::B3::IndexSet::values):
(JSC::B3::IndexSet::indices):

  • b3/B3InsertionSet.cpp:

(JSC::B3::InsertionSet::insertIntConstant):
(JSC::B3::InsertionSet::insertBottom):
(JSC::B3::InsertionSet::execute):

  • b3/B3InsertionSet.h:
  • b3/B3LowerToAir.cpp:

(JSC::B3::Air::LowerToAir::run):
(JSC::B3::Air::LowerToAir::tmp):

  • b3/B3MemoryValue.cpp:

(JSC::B3::MemoryValue::dumpMeta):
(JSC::B3::MemoryValue::cloneImpl):

  • b3/B3MemoryValue.h:
  • b3/B3OriginDump.cpp: Added.

(JSC::B3::OriginDump::dump):

  • b3/B3OriginDump.h:

(JSC::B3::OriginDump::OriginDump):
(JSC::B3::OriginDump::dump): Deleted.

  • b3/B3PatchpointValue.cpp:

(JSC::B3::PatchpointValue::dumpMeta):
(JSC::B3::PatchpointValue::cloneImpl):
(JSC::B3::PatchpointValue::PatchpointValue):

  • b3/B3PatchpointValue.h:
  • b3/B3Procedure.cpp:

(JSC::B3::Procedure::addBlock):
(JSC::B3::Procedure::clone):
(JSC::B3::Procedure::addIntConstant):
(JSC::B3::Procedure::addBottom):
(JSC::B3::Procedure::addBoolConstant):
(JSC::B3::Procedure::deleteValue):

  • b3/B3Procedure.h:
  • b3/B3ReduceStrength.cpp:
  • b3/B3SSACalculator.cpp: Added.

(JSC::B3::SSACalculator::Variable::dump):
(JSC::B3::SSACalculator::Variable::dumpVerbose):
(JSC::B3::SSACalculator::Def::dump):
(JSC::B3::SSACalculator::SSACalculator):
(JSC::B3::SSACalculator::~SSACalculator):
(JSC::B3::SSACalculator::reset):
(JSC::B3::SSACalculator::newVariable):
(JSC::B3::SSACalculator::newDef):
(JSC::B3::SSACalculator::nonLocalReachingDef):
(JSC::B3::SSACalculator::reachingDefAtTail):
(JSC::B3::SSACalculator::dump):

  • b3/B3SSACalculator.h: Added.

(JSC::B3::SSACalculator::Variable::index):
(JSC::B3::SSACalculator::Variable::Variable):
(JSC::B3::SSACalculator::Def::variable):
(JSC::B3::SSACalculator::Def::block):
(JSC::B3::SSACalculator::Def::value):
(JSC::B3::SSACalculator::Def::Def):
(JSC::B3::SSACalculator::variable):
(JSC::B3::SSACalculator::computePhis):
(JSC::B3::SSACalculator::phisForBlock):
(JSC::B3::SSACalculator::reachingDefAtHead):

  • b3/B3StackSlotKind.h:
  • b3/B3StackSlotValue.cpp:

(JSC::B3::StackSlotValue::dumpMeta):
(JSC::B3::StackSlotValue::cloneImpl):

  • b3/B3StackSlotValue.h:
  • b3/B3SwitchValue.cpp:

(JSC::B3::SwitchValue::dumpMeta):
(JSC::B3::SwitchValue::cloneImpl):
(JSC::B3::SwitchValue::SwitchValue):

  • b3/B3SwitchValue.h:
  • b3/B3UpsilonValue.cpp:

(JSC::B3::UpsilonValue::dumpMeta):
(JSC::B3::UpsilonValue::cloneImpl):

  • b3/B3UpsilonValue.h:
  • b3/B3Validate.cpp:
  • b3/B3Value.cpp:

(JSC::B3::Value::replaceWithNop):
(JSC::B3::Value::replaceWithPhi):
(JSC::B3::Value::dump):
(JSC::B3::Value::cloneImpl):
(JSC::B3::Value::dumpChildren):
(JSC::B3::Value::deepDump):

  • b3/B3Value.h:

(JSC::B3::DeepValueDump::DeepValueDump):
(JSC::B3::DeepValueDump::dump):
(JSC::B3::deepDump):

  • b3/B3ValueInlines.h:

(JSC::B3::Value::asNumber):
(JSC::B3::Value::walk):

  • b3/B3ValueKey.cpp:

(JSC::B3::ValueKey::intConstant):
(JSC::B3::ValueKey::dump):

  • b3/B3ValueKey.h:

(JSC::B3::ValueKey::ValueKey):
(JSC::B3::ValueKey::opcode):
(JSC::B3::ValueKey::type):
(JSC::B3::ValueKey::childIndex):

  • b3/air/AirCode.h:

(JSC::B3::Air::Code::forAllTmps):
(JSC::B3::Air::Code::isFastTmp):

  • b3/air/AirIteratedRegisterCoalescing.cpp:
  • b3/air/AirUseCounts.h:

(JSC::B3::Air::UseCounts::UseCounts):
(JSC::B3::Air::UseCounts::operator[]):
(JSC::B3::Air::UseCounts::dump):

  • b3/testb3.cpp:

(JSC::B3::testSelectInvert):
(JSC::B3::testCheckSelect):
(JSC::B3::testCheckSelectCheckSelect):
(JSC::B3::testPowDoubleByIntegerLoop):
(JSC::B3::run):

  • runtime/Options.h:

Source/WTF:

  • wtf/GraphNodeWorklist.h:

(WTF::GraphNodeWorklist::push):
(WTF::GraphNodeWorklist::pushAll):
(WTF::GraphNodeWorklist::isEmpty):
(WTF::GraphNodeWorklist::notEmpty):

Location:
trunk
Files:
11 added
57 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r195313 r195395  
    105105    b3/B3BasicBlock.cpp
    106106    b3/B3BlockInsertionSet.cpp
     107    b3/B3BreakCriticalEdges.cpp
    107108    b3/B3CCallValue.cpp
    108109    b3/B3CheckSpecial.cpp
     
    118119    b3/B3ControlValue.cpp
    119120    b3/B3DataSection.cpp
     121    b3/B3DuplicateTails.cpp
    120122    b3/B3Effects.cpp
     123    b3/B3FixSSA.cpp
    121124    b3/B3FrequencyClass.cpp
    122125    b3/B3Generate.cpp
     
    133136    b3/B3Opcode.cpp
    134137    b3/B3Origin.cpp
     138    b3/B3OriginDump.cpp
    135139    b3/B3PatchpointSpecial.cpp
    136140    b3/B3PatchpointValue.cpp
     
    140144    b3/B3ReduceDoubleToFloat.cpp
    141145    b3/B3ReduceStrength.cpp
     146    b3/B3SSACalculator.cpp
    142147    b3/B3StackmapGenerationParams.cpp
    143148    b3/B3StackmapSpecial.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r195388 r195395  
     12016-01-19  Filip Pizlo  <fpizlo@apple.com>
     2
     3        B3 should have basic path specialization
     4        https://bugs.webkit.org/show_bug.cgi?id=153200
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        This adds two different kind of path specializations:
     9
     10        - Check(Select) where the Select results are constants is specialized into a Branch
     11          instead of a Select and duplicated paths where the results of the Select are folded.
     12
     13        - Tail duplication. A jump to a small block causes the block's contents to be copied over
     14          the Jump.
     15
     16        Both optimizations required being able to clone Values. We can now do that using
     17        proc.clone(value).
     18
     19        Check(Select) specialization needed some utilities for walking graphs of Values.
     20
     21        Tail duplication needed SSA fixup, so I added a way to demote values to anonymous stack
     22        slots (B3's equivalent of non-SSA variables) and a way to "fix SSA", i.e. to allocate
     23        anonymous stack slots to SSA values along with an optimal Phi graph.
     24
     25        This is a big speed-up on Octane/deltablue. It's a 2.2% speed-up on Octane overall.
     26
     27        * CMakeLists.txt:
     28        * JavaScriptCore.xcodeproj/project.pbxproj:
     29        * b3/B3ArgumentRegValue.cpp:
     30        (JSC::B3::ArgumentRegValue::dumpMeta):
     31        (JSC::B3::ArgumentRegValue::cloneImpl):
     32        * b3/B3ArgumentRegValue.h:
     33        * b3/B3BasicBlock.cpp:
     34        (JSC::B3::BasicBlock::append):
     35        (JSC::B3::BasicBlock::appendNonTerminal):
     36        (JSC::B3::BasicBlock::removeLast):
     37        * b3/B3BasicBlock.h:
     38        (JSC::B3::BasicBlock::values):
     39        * b3/B3BasicBlockInlines.h:
     40        (JSC::B3::BasicBlock::appendNew):
     41        (JSC::B3::BasicBlock::appendNewNonTerminal):
     42        (JSC::B3::BasicBlock::replaceLastWithNew):
     43        * b3/B3BlockInsertionSet.h:
     44        * b3/B3BreakCriticalEdges.cpp: Added.
     45        (JSC::B3::breakCriticalEdges):
     46        * b3/B3BreakCriticalEdges.h: Added.
     47        * b3/B3CCallValue.cpp:
     48        (JSC::B3::CCallValue::~CCallValue):
     49        (JSC::B3::CCallValue::cloneImpl):
     50        * b3/B3CCallValue.h:
     51        * b3/B3CheckValue.cpp:
     52        (JSC::B3::CheckValue::convertToAdd):
     53        (JSC::B3::CheckValue::cloneImpl):
     54        (JSC::B3::CheckValue::CheckValue):
     55        * b3/B3CheckValue.h:
     56        * b3/B3Const32Value.cpp:
     57        (JSC::B3::Const32Value::dumpMeta):
     58        (JSC::B3::Const32Value::cloneImpl):
     59        * b3/B3Const32Value.h:
     60        * b3/B3Const64Value.cpp:
     61        (JSC::B3::Const64Value::dumpMeta):
     62        (JSC::B3::Const64Value::cloneImpl):
     63        * b3/B3Const64Value.h:
     64        * b3/B3ConstDoubleValue.cpp:
     65        (JSC::B3::ConstDoubleValue::dumpMeta):
     66        (JSC::B3::ConstDoubleValue::cloneImpl):
     67        * b3/B3ConstDoubleValue.h:
     68        * b3/B3ConstFloatValue.cpp:
     69        (JSC::B3::ConstFloatValue::dumpMeta):
     70        (JSC::B3::ConstFloatValue::cloneImpl):
     71        * b3/B3ConstFloatValue.h:
     72        * b3/B3ControlValue.cpp:
     73        (JSC::B3::ControlValue::dumpMeta):
     74        (JSC::B3::ControlValue::cloneImpl):
     75        * b3/B3ControlValue.h:
     76        * b3/B3DuplicateTails.cpp: Added.
     77        (JSC::B3::duplicateTails):
     78        * b3/B3DuplicateTails.h: Added.
     79        * b3/B3FixSSA.cpp: Added.
     80        (JSC::B3::demoteValues):
     81        (JSC::B3::fixSSA):
     82        * b3/B3FixSSA.h: Added.
     83        * b3/B3Generate.cpp:
     84        (JSC::B3::generateToAir):
     85        * b3/B3IndexSet.h:
     86        (JSC::B3::IndexSet::Iterable::Iterable):
     87        (JSC::B3::IndexSet::values):
     88        (JSC::B3::IndexSet::indices):
     89        * b3/B3InsertionSet.cpp:
     90        (JSC::B3::InsertionSet::insertIntConstant):
     91        (JSC::B3::InsertionSet::insertBottom):
     92        (JSC::B3::InsertionSet::execute):
     93        * b3/B3InsertionSet.h:
     94        * b3/B3LowerToAir.cpp:
     95        (JSC::B3::Air::LowerToAir::run):
     96        (JSC::B3::Air::LowerToAir::tmp):
     97        * b3/B3MemoryValue.cpp:
     98        (JSC::B3::MemoryValue::dumpMeta):
     99        (JSC::B3::MemoryValue::cloneImpl):
     100        * b3/B3MemoryValue.h:
     101        * b3/B3OriginDump.cpp: Added.
     102        (JSC::B3::OriginDump::dump):
     103        * b3/B3OriginDump.h:
     104        (JSC::B3::OriginDump::OriginDump):
     105        (JSC::B3::OriginDump::dump): Deleted.
     106        * b3/B3PatchpointValue.cpp:
     107        (JSC::B3::PatchpointValue::dumpMeta):
     108        (JSC::B3::PatchpointValue::cloneImpl):
     109        (JSC::B3::PatchpointValue::PatchpointValue):
     110        * b3/B3PatchpointValue.h:
     111        * b3/B3Procedure.cpp:
     112        (JSC::B3::Procedure::addBlock):
     113        (JSC::B3::Procedure::clone):
     114        (JSC::B3::Procedure::addIntConstant):
     115        (JSC::B3::Procedure::addBottom):
     116        (JSC::B3::Procedure::addBoolConstant):
     117        (JSC::B3::Procedure::deleteValue):
     118        * b3/B3Procedure.h:
     119        * b3/B3ReduceStrength.cpp:
     120        * b3/B3SSACalculator.cpp: Added.
     121        (JSC::B3::SSACalculator::Variable::dump):
     122        (JSC::B3::SSACalculator::Variable::dumpVerbose):
     123        (JSC::B3::SSACalculator::Def::dump):
     124        (JSC::B3::SSACalculator::SSACalculator):
     125        (JSC::B3::SSACalculator::~SSACalculator):
     126        (JSC::B3::SSACalculator::reset):
     127        (JSC::B3::SSACalculator::newVariable):
     128        (JSC::B3::SSACalculator::newDef):
     129        (JSC::B3::SSACalculator::nonLocalReachingDef):
     130        (JSC::B3::SSACalculator::reachingDefAtTail):
     131        (JSC::B3::SSACalculator::dump):
     132        * b3/B3SSACalculator.h: Added.
     133        (JSC::B3::SSACalculator::Variable::index):
     134        (JSC::B3::SSACalculator::Variable::Variable):
     135        (JSC::B3::SSACalculator::Def::variable):
     136        (JSC::B3::SSACalculator::Def::block):
     137        (JSC::B3::SSACalculator::Def::value):
     138        (JSC::B3::SSACalculator::Def::Def):
     139        (JSC::B3::SSACalculator::variable):
     140        (JSC::B3::SSACalculator::computePhis):
     141        (JSC::B3::SSACalculator::phisForBlock):
     142        (JSC::B3::SSACalculator::reachingDefAtHead):
     143        * b3/B3StackSlotKind.h:
     144        * b3/B3StackSlotValue.cpp:
     145        (JSC::B3::StackSlotValue::dumpMeta):
     146        (JSC::B3::StackSlotValue::cloneImpl):
     147        * b3/B3StackSlotValue.h:
     148        * b3/B3SwitchValue.cpp:
     149        (JSC::B3::SwitchValue::dumpMeta):
     150        (JSC::B3::SwitchValue::cloneImpl):
     151        (JSC::B3::SwitchValue::SwitchValue):
     152        * b3/B3SwitchValue.h:
     153        * b3/B3UpsilonValue.cpp:
     154        (JSC::B3::UpsilonValue::dumpMeta):
     155        (JSC::B3::UpsilonValue::cloneImpl):
     156        * b3/B3UpsilonValue.h:
     157        * b3/B3Validate.cpp:
     158        * b3/B3Value.cpp:
     159        (JSC::B3::Value::replaceWithNop):
     160        (JSC::B3::Value::replaceWithPhi):
     161        (JSC::B3::Value::dump):
     162        (JSC::B3::Value::cloneImpl):
     163        (JSC::B3::Value::dumpChildren):
     164        (JSC::B3::Value::deepDump):
     165        * b3/B3Value.h:
     166        (JSC::B3::DeepValueDump::DeepValueDump):
     167        (JSC::B3::DeepValueDump::dump):
     168        (JSC::B3::deepDump):
     169        * b3/B3ValueInlines.h:
     170        (JSC::B3::Value::asNumber):
     171        (JSC::B3::Value::walk):
     172        * b3/B3ValueKey.cpp:
     173        (JSC::B3::ValueKey::intConstant):
     174        (JSC::B3::ValueKey::dump):
     175        * b3/B3ValueKey.h:
     176        (JSC::B3::ValueKey::ValueKey):
     177        (JSC::B3::ValueKey::opcode):
     178        (JSC::B3::ValueKey::type):
     179        (JSC::B3::ValueKey::childIndex):
     180        * b3/air/AirCode.h:
     181        (JSC::B3::Air::Code::forAllTmps):
     182        (JSC::B3::Air::Code::isFastTmp):
     183        * b3/air/AirIteratedRegisterCoalescing.cpp:
     184        * b3/air/AirUseCounts.h:
     185        (JSC::B3::Air::UseCounts::UseCounts):
     186        (JSC::B3::Air::UseCounts::operator[]):
     187        (JSC::B3::Air::UseCounts::dump):
     188        * b3/testb3.cpp:
     189        (JSC::B3::testSelectInvert):
     190        (JSC::B3::testCheckSelect):
     191        (JSC::B3::testCheckSelectCheckSelect):
     192        (JSC::B3::testPowDoubleByIntegerLoop):
     193        (JSC::B3::run):
     194        * runtime/Options.h:
     195
    11962016-01-20  Benjamin Poulain  <bpoulain@apple.com>
    2197
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r195307 r195395  
    382382                0F4DE1CE1C4C1B54004D6C11 /* AirFixObviousSpills.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4DE1CC1C4C1B54004D6C11 /* AirFixObviousSpills.cpp */; };
    383383                0F4DE1CF1C4C1B54004D6C11 /* AirFixObviousSpills.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4DE1CD1C4C1B54004D6C11 /* AirFixObviousSpills.h */; };
     384                0F4DE1D11C4D764B004D6C11 /* B3OriginDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */; };
    384385                0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
    385386                0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; };
     
    450451                0F6B1CC51862C47800845D97 /* FTLUnwindInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CC11862C47800845D97 /* FTLUnwindInfo.cpp */; };
    451452                0F6B1CC61862C47800845D97 /* FTLUnwindInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
     453                0F6B8AD81C4EDDA200969052 /* B3DuplicateTails.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B8AD61C4EDDA200969052 /* B3DuplicateTails.cpp */; };
     454                0F6B8AD91C4EDDA200969052 /* B3DuplicateTails.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B8AD71C4EDDA200969052 /* B3DuplicateTails.h */; };
     455                0F6B8ADC1C4EFAC300969052 /* B3SSACalculator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B8ADA1C4EFAC300969052 /* B3SSACalculator.cpp */; };
     456                0F6B8ADD1C4EFAC300969052 /* B3SSACalculator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B8ADB1C4EFAC300969052 /* B3SSACalculator.h */; };
     457                0F6B8AE21C4EFE1700969052 /* B3BreakCriticalEdges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */; };
     458                0F6B8AE31C4EFE1700969052 /* B3BreakCriticalEdges.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */; };
     459                0F6B8AE41C4EFE1700969052 /* B3FixSSA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B8AE01C4EFE1700969052 /* B3FixSSA.cpp */; };
     460                0F6B8AE51C4EFE1700969052 /* B3FixSSA.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B8AE11C4EFE1700969052 /* B3FixSSA.h */; };
    452461                0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */; };
    453462                0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    459468                0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */; };
    460469                0F714CA516EA92F200F3EBEB /* DFGBackwardsPropagationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */; };
     470                0F725CAF1C506D3B00AD943A /* B3FoldPathConstants.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F725CAD1C506D3B00AD943A /* B3FoldPathConstants.cpp */; };
     471                0F725CB01C506D3B00AD943A /* B3FoldPathConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F725CAE1C506D3B00AD943A /* B3FoldPathConstants.h */; };
    461472                0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 652A3A201651C66100A80AFE /* ARM64Disassembler.cpp */; };
    462473                0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */; };
     
    25492560                0F4DE1CC1C4C1B54004D6C11 /* AirFixObviousSpills.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirFixObviousSpills.cpp; path = b3/air/AirFixObviousSpills.cpp; sourceTree = "<group>"; };
    25502561                0F4DE1CD1C4C1B54004D6C11 /* AirFixObviousSpills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirFixObviousSpills.h; path = b3/air/AirFixObviousSpills.h; sourceTree = "<group>"; };
     2562                0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3OriginDump.cpp; path = b3/B3OriginDump.cpp; sourceTree = "<group>"; };
    25512563                0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = "<group>"; };
    25522564                0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; };
     
    26192631                0F6B1CC11862C47800845D97 /* FTLUnwindInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLUnwindInfo.cpp; path = ftl/FTLUnwindInfo.cpp; sourceTree = "<group>"; };
    26202632                0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLUnwindInfo.h; path = ftl/FTLUnwindInfo.h; sourceTree = "<group>"; };
     2633                0F6B8AD61C4EDDA200969052 /* B3DuplicateTails.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3DuplicateTails.cpp; path = b3/B3DuplicateTails.cpp; sourceTree = "<group>"; };
     2634                0F6B8AD71C4EDDA200969052 /* B3DuplicateTails.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3DuplicateTails.h; path = b3/B3DuplicateTails.h; sourceTree = "<group>"; };
     2635                0F6B8ADA1C4EFAC300969052 /* B3SSACalculator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3SSACalculator.cpp; path = b3/B3SSACalculator.cpp; sourceTree = "<group>"; };
     2636                0F6B8ADB1C4EFAC300969052 /* B3SSACalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3SSACalculator.h; path = b3/B3SSACalculator.h; sourceTree = "<group>"; };
     2637                0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3BreakCriticalEdges.cpp; path = b3/B3BreakCriticalEdges.cpp; sourceTree = "<group>"; };
     2638                0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3BreakCriticalEdges.h; path = b3/B3BreakCriticalEdges.h; sourceTree = "<group>"; };
     2639                0F6B8AE01C4EFE1700969052 /* B3FixSSA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3FixSSA.cpp; path = b3/B3FixSSA.cpp; sourceTree = "<group>"; };
     2640                0F6B8AE11C4EFE1700969052 /* B3FixSSA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3FixSSA.h; path = b3/B3FixSSA.h; sourceTree = "<group>"; };
    26212641                0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableWriteFireDetail.cpp; sourceTree = "<group>"; };
    26222642                0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWriteFireDetail.h; sourceTree = "<group>"; };
     
    26282648                0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBackwardsPropagationPhase.cpp; path = dfg/DFGBackwardsPropagationPhase.cpp; sourceTree = "<group>"; };
    26292649                0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBackwardsPropagationPhase.h; path = dfg/DFGBackwardsPropagationPhase.h; sourceTree = "<group>"; };
     2650                0F725CAD1C506D3B00AD943A /* B3FoldPathConstants.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3FoldPathConstants.cpp; path = b3/B3FoldPathConstants.cpp; sourceTree = "<group>"; };
     2651                0F725CAE1C506D3B00AD943A /* B3FoldPathConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3FoldPathConstants.h; path = b3/B3FoldPathConstants.h; sourceTree = "<group>"; };
    26302652                0F766D1C15A5028D008F363E /* JITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutine.h; sourceTree = "<group>"; };
    26312653                0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubRoutine.cpp; sourceTree = "<group>"; };
     
    47274749                                0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */,
    47284750                                0FEC84BA1BDACDAC0080FF74 /* B3BlockWorklist.h */,
     4751                                0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */,
     4752                                0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */,
    47294753                                0F338DF71BE96AA80013C88F /* B3CCallValue.cpp */,
    47304754                                0F338DF81BE96AA80013C88F /* B3CCallValue.h */,
     
    47564780                                0F338E021BF0276C0013C88F /* B3DataSection.h */,
    47574781                                0F33FCFA1C1625BE00323F67 /* B3Dominators.h */,
     4782                                0F6B8AD61C4EDDA200969052 /* B3DuplicateTails.cpp */,
     4783                                0F6B8AD71C4EDDA200969052 /* B3DuplicateTails.h */,
    47584784                                0FEC85C41BE16F5A0080FF74 /* B3Effects.cpp */,
    47594785                                0FEC85BE1BE167A00080FF74 /* B3Effects.h */,
     4786                                0F6B8AE01C4EFE1700969052 /* B3FixSSA.cpp */,
     4787                                0F6B8AE11C4EFE1700969052 /* B3FixSSA.h */,
     4788                                0F725CAD1C506D3B00AD943A /* B3FoldPathConstants.cpp */,
     4789                                0F725CAE1C506D3B00AD943A /* B3FoldPathConstants.h */,
    47604790                                0FEC84CB1BDACDAC0080FF74 /* B3FrequencyClass.cpp */,
    47614791                                0FEC84CC1BDACDAC0080FF74 /* B3FrequencyClass.h */,
     
    47924822                                0FEC84D91BDACDAC0080FF74 /* B3Origin.cpp */,
    47934823                                0FEC84DA1BDACDAC0080FF74 /* B3Origin.h */,
     4824                                0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */,
    47944825                                0F4C91651C29F4F2004341A6 /* B3OriginDump.h */,
    47954826                                0FEC84DB1BDACDAC0080FF74 /* B3PatchpointSpecial.cpp */,
     
    48084839                                0FEC85B71BE1462F0080FF74 /* B3ReduceStrength.cpp */,
    48094840                                0FEC85B81BE1462F0080FF74 /* B3ReduceStrength.h */,
     4841                                0F6B8ADA1C4EFAC300969052 /* B3SSACalculator.cpp */,
     4842                                0F6B8ADB1C4EFAC300969052 /* B3SSACalculator.h */,
    48104843                                0F33FCF51C136E2500323F67 /* B3StackmapGenerationParams.cpp */,
    48114844                                0F33FCF61C136E2500323F67 /* B3StackmapGenerationParams.h */,
     
    71297162                                0F1C3DDA1BBCE09E00E523E4 /* CellState.h in Headers */,
    71307163                                BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
     7164                                0F6B8AD91C4EDDA200969052 /* B3DuplicateTails.h in Headers */,
    71317165                                0FE050261AA9095600D33B33 /* ClonedArguments.h in Headers */,
    71327166                                969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */,
     
    72427276                                0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */,
    72437277                                0FEA0A32170D40BF00BB722C /* DFGCommonData.h in Headers */,
     7278                                0F725CB01C506D3B00AD943A /* B3FoldPathConstants.h in Headers */,
    72447279                                0F38B01817CFE75500B144D3 /* DFGCompilationKey.h in Headers */,
    72457280                                0F9D4C111C3E2C74006CD984 /* FTLPatchpointExceptionHandle.h in Headers */,
     
    73047339                                0F5874EE194FEB1200AAB2C1 /* DFGMayExit.h in Headers */,
    73057340                                0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */,
     7341                                0F6B8AE31C4EFE1700969052 /* B3BreakCriticalEdges.h in Headers */,
    73067342                                0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */,
    73077343                                0F2BDC461522802000CD8910 /* DFGMinifiedNode.h in Headers */,
     
    74247460                                0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */,
    74257461                                0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */,
     7462                                0F6B8AE51C4EFE1700969052 /* B3FixSSA.h in Headers */,
    74267463                                0FEA0A0A170513DB00BB722C /* FTLCapabilities.h in Headers */,
    74277464                                0FEA0A231709606900BB722C /* FTLCommonValues.h in Headers */,
     
    81018138                                7B8329BF1BB21FE300649A6E /* WASMFunctionLLVMIRGenerator.h in Headers */,
    81028139                                7B0247571B8682E400542440 /* WASMFunctionParser.h in Headers */,
     8140                                0F6B8ADD1C4EFAC300969052 /* B3SSACalculator.h in Headers */,
    81038141                                7B0247591B868EB700542440 /* WASMFunctionSyntaxChecker.h in Headers */,
    81048142                                7B39F76E1B62DE3200360FB4 /* WASMModuleParser.h in Headers */,
     
    87848822                                0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
    87858823                                0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
     8824                                0F6B8ADC1C4EFAC300969052 /* B3SSACalculator.cpp in Sources */,
    87868825                                627673231B680C1E00FD9F2E /* CallMode.cpp in Sources */,
    87878826                                0F3B7E2A19A11B8000D9BC56 /* CallVariant.cpp in Sources */,
     
    89288967                                0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */,
    89298968                                0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
     8969                                0F4DE1D11C4D764B004D6C11 /* B3OriginDump.cpp in Sources */,
    89308970                                FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */,
    89318971                                0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */,
     
    90249064                                0FEA0A281709623B00BB722C /* FTLIntrinsicRepository.cpp in Sources */,
    90259065                                0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
     9066                                0F6B8AE21C4EFE1700969052 /* B3BreakCriticalEdges.cpp in Sources */,
    90269067                                A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,
    90279068                                0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
    90289069                                0FD1202F1A8AED12000F5280 /* FTLJSCallBase.cpp in Sources */,
     9070                                0F725CAF1C506D3B00AD943A /* B3FoldPathConstants.cpp in Sources */,
    90299071                                0FD120331A8C85BD000F5280 /* FTLJSCallVarargs.cpp in Sources */,
    90309072                                62774DAA1B8D4B190006F05A /* FTLJSTailCall.cpp in Sources */,
     
    93679409                                A5BA15EE182340B400A82E69 /* RemoteInspectorXPCConnection.mm in Sources */,
    93689410                                0F24E55017EE274900ABB217 /* Repatch.cpp in Sources */,
     9411                                0F6B8AD81C4EDDA200969052 /* B3DuplicateTails.cpp in Sources */,
    93699412                                527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */,
    93709413                                0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */,
     
    94309473                                0F2D4DEB19832DC4007D4B19 /* TypeProfilerLog.cpp in Sources */,
    94319474                                0F2D4DEF19832DD3007D4B19 /* TypeSet.cpp in Sources */,
     9475                                0F6B8AE41C4EFE1700969052 /* B3FixSSA.cpp in Sources */,
    94329476                                0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
    94339477                                0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */,
  • trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp

    r191993 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4040}
    4141
     42Value* ArgumentRegValue::cloneImpl() const
     43{
     44    return new ArgumentRegValue(*this);
     45}
     46
    4247} } // namespace JSC::B3
    4348
  • trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h

    r191994 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4545    void dumpMeta(CommaPrinter&, PrintStream&) const override;
    4646
     47    Value* cloneImpl() const override;
     48
    4749private:
    4850    friend class Procedure;
  • trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp

    r194372 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5353{
    5454    m_values.append(value);
     55}
     56
     57void BasicBlock::appendNonTerminal(Value* value)
     58{
     59    m_values.append(m_values.last());
     60    m_values[m_values.size() - 1] = value;
    5561}
    5662
  • trunk/Source/JavaScriptCore/b3/B3BasicBlock.h

    r194915 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7272
    7373    JS_EXPORT_PRIVATE void append(Value*);
     74    JS_EXPORT_PRIVATE void appendNonTerminal(Value*);
    7475    JS_EXPORT_PRIVATE void replaceLast(Procedure&, Value*);
    7576
    7677    template<typename ValueType, typename... Arguments>
    7778    ValueType* appendNew(Procedure&, Arguments...);
     79    template<typename ValueType, typename... Arguments>
     80    ValueType* appendNewNonTerminal(Procedure&, Arguments...);
    7881
    7982    JS_EXPORT_PRIVATE Value* appendIntConstant(Procedure&, Origin, Type, int64_t value);
  • trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h

    r192295 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4040    ValueType* result = procedure.add<ValueType>(arguments...);
    4141    append(result);
     42    return result;
     43}
     44
     45template<typename ValueType, typename... Arguments>
     46ValueType* BasicBlock::appendNewNonTerminal(Procedure& procedure, Arguments... arguments)
     47{
     48    ValueType* result = procedure.add<ValueType>(arguments...);
     49    appendNonTerminal(result);
    4250    return result;
    4351}
  • trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.h

    r192346 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6262    // executed on the newly created block - this makes sense if you had previously inserted
    6363    // things into the original block, since the newly created block will be indexed identically
    64     // to hold this block was indexed for all values prior to valueIndex. After this runs, it
    65     // sets valueIndex to zero. This allows you to use this method for things like:
     64    // to how this block was indexed for all values prior to valueIndex. After this runs, it sets
     65    // valueIndex to zero. This allows you to use this method for things like:
    6666    //
    6767    // for (unsigned valueIndex = 0; valueIndex < block->size(); ++valueIndex) {
  • trunk/Source/JavaScriptCore/b3/B3CCallValue.cpp

    r191994 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535}
    3636
     37Value* CCallValue::cloneImpl() const
     38{
     39    return new CCallValue(*this);
     40}
     41
    3742} } // namespace JSC::B3
    3843
  • trunk/Source/JavaScriptCore/b3/B3CCallValue.h

    r195139 r195395  
    4242    Effects effects { Effects::forCall() };
    4343
     44protected:
     45    Value* cloneImpl() const override;
     46   
    4447private:
    4548    friend class Procedure;
  • trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp

    r193393 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4141}
    4242
     43Value* CheckValue::cloneImpl() const
     44{
     45    return new CheckValue(*this);
     46}
     47
    4348// Use this form for CheckAdd, CheckSub, and CheckMul.
    4449CheckValue::CheckValue(unsigned index, Opcode opcode, Origin origin, Value* left, Value* right)
  • trunk/Source/JavaScriptCore/b3/B3CheckValue.h

    r192540 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5252    void convertToAdd();
    5353
     54protected:
     55    Value* cloneImpl() const override;
     56   
    5457private:
    5558    friend class Procedure;
  • trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp

    r193933 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    242242}
    243243
     244Value* Const32Value::cloneImpl() const
     245{
     246    return new Const32Value(*this);
     247}
     248
    244249} } // namespace JSC::B3
    245250
  • trunk/Source/JavaScriptCore/b3/B3Const32Value.h

    r195362 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7474    void dumpMeta(CommaPrinter&, PrintStream&) const override;
    7575
     76    Value* cloneImpl() const override;
     77
    7678    friend class Procedure;
    7779
  • trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp

    r193933 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    242242}
    243243
     244Value* Const64Value::cloneImpl() const
     245{
     246    return new Const64Value(*this);
     247}
     248
    244249} } // namespace JSC::B3
    245250
  • trunk/Source/JavaScriptCore/b3/B3Const64Value.h

    r193933 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7474    void dumpMeta(CommaPrinter&, PrintStream&) const override;
    7575
     76    Value* cloneImpl() const override;
     77
    7678    friend class Procedure;
    7779
  • trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp

    r194314 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    176176}
    177177
     178Value* ConstDoubleValue::cloneImpl() const
     179{
     180    return new ConstDoubleValue(*this);
     181}
     182
    178183} } // namespace JSC::B3
    179184
  • trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h

    r194314 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6666    void dumpMeta(CommaPrinter&, PrintStream&) const override;
    6767
     68    Value* cloneImpl() const override;
     69
    6870private:
    6971    friend class Procedure;
  • trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp

    r194062 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    158158}
    159159
     160Value* ConstFloatValue::cloneImpl() const
     161{
     162    return new ConstFloatValue(*this);
     163}
     164
    160165} } // namespace JSC::B3
    161166
  • trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h

    r194062 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6464    void dumpMeta(CommaPrinter&, PrintStream&) const override;
    6565
     66    Value* cloneImpl() const override;
     67
    6668private:
    6769    friend class Procedure;
  • trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp

    r194855 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    8484}
    8585
     86Value* ControlValue::cloneImpl() const
     87{
     88    return new ControlValue(*this);
     89}
     90
    8691} } // namespace JSC::B3
    8792
  • trunk/Source/JavaScriptCore/b3/B3ControlValue.h

    r195362 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030
    3131#include "B3FrequentedBlock.h"
     32#include "B3SuccessorCollection.h"
    3233#include "B3Value.h"
    3334
     
    6566    SuccessorList& successors() { return m_successors; }
    6667
     68    BasicBlock* successorBlock(unsigned index) const { return successor(index).block(); }
     69    BasicBlock*& successorBlock(unsigned index) { return successor(index).block(); }
     70    SuccessorCollection<BasicBlock, SuccessorList> successorBlocks()
     71    {
     72        return SuccessorCollection<BasicBlock, SuccessorList>(successors());
     73    }
     74    SuccessorCollection<const BasicBlock, const SuccessorList> successorBlocks() const
     75    {
     76        return SuccessorCollection<const BasicBlock, const SuccessorList>(successors());
     77    }
     78
    6779    bool replaceSuccessor(BasicBlock* from, BasicBlock* to);
    6880
     
    93105protected:
    94106    void dumpMeta(CommaPrinter&, PrintStream&) const override;
     107
     108    Value* cloneImpl() const override;
    95109
    96110    // Use this for subclasses.
  • trunk/Source/JavaScriptCore/b3/B3Generate.cpp

    r195159 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3333#include "AirInstInlines.h"
    3434#include "B3Common.h"
     35#include "B3DuplicateTails.h"
     36#include "B3FoldPathConstants.h"
    3537#include "B3LegalizeMemoryOffsets.h"
    3638#include "B3LowerMacros.h"
     
    7476        validate(procedure);
    7577
     78    if (optLevel >= 1) {
     79        reduceDoubleToFloat(procedure);
     80        reduceStrength(procedure);
     81        duplicateTails(procedure);
     82        foldPathConstants(procedure);
     83       
     84        // FIXME: Add more optimizations here.
     85        // https://bugs.webkit.org/show_bug.cgi?id=150507
     86    }
     87
    7688    lowerMacros(procedure);
    7789
    7890    if (optLevel >= 1) {
    79         reduceDoubleToFloat(procedure);
    80 
    8191        reduceStrength(procedure);
    8292       
     
    8696
    8797    lowerMacrosAfterOptimizations(procedure);
    88 
    8998    legalizeMemoryOffsets(procedure);
    90 
    9199    moveConstants(procedure);
    92100
  • trunk/Source/JavaScriptCore/b3/B3IndexSet.h

    r194834 r195395  
    7373    class Iterable {
    7474    public:
    75         Iterable(const CollectionType& collection, const IndexSet& set)
     75        Iterable(const CollectionType& collection, const BitVector& set)
    7676            : m_collection(collection)
    7777            , m_set(set)
     
    123123    private:
    124124        const CollectionType& m_collection;
    125         const IndexSet& m_set;
     125        const BitVector& m_set;
    126126    };
    127127
     
    134134    Iterable<CollectionType> values(const CollectionType& collection) const
    135135    {
    136         return Iterable<CollectionType>(collection);
     136        return Iterable<CollectionType>(collection, indices());
    137137    }
    138138
  • trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp

    r192295 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4646}
    4747
     48Value* InsertionSet::insertBottom(size_t index, Origin origin, Type type)
     49{
     50    return insertValue(index, m_procedure.addBottom(origin, type));
     51}
     52
     53Value* InsertionSet::insertBottom(size_t index, Value* likeValue)
     54{
     55    return insertBottom(index, likeValue->origin(), likeValue->type());
     56}
     57
    4858void InsertionSet::execute(BasicBlock* block)
    4959{
  • trunk/Source/JavaScriptCore/b3/B3InsertionSet.h

    r194855 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6868    Value* insertIntConstant(size_t index, Value* likeValue, int64_t value);
    6969
     70    Value* insertBottom(size_t index, Origin, Type);
     71    Value* insertBottom(size_t index, Value*);
     72
    7073    void execute(BasicBlock*);
    7174
  • trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp

    r195298 r195395  
    8989            case Phi: {
    9090                m_phiToTmp[value] = m_code.newTmp(Arg::typeForB3Type(value->type()));
     91                if (verbose)
     92                    dataLog("Phi tmp for ", *value, ": ", m_phiToTmp[value], "\n");
    9193                break;
    9294            }
     
    307309                if (m_procedure.isFastConstant(value->key()))
    308310                    m_code.addFastTmp(realTmp);
     311                if (verbose)
     312                    dataLog("Tmp for ", *value, ": ", realTmp, "\n");
    309313            }
    310314            tmp = realTmp;
  • trunk/Source/JavaScriptCore/b3/B3MemoryValue.cpp

    r193683 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6262}
    6363
     64Value* MemoryValue::cloneImpl() const
     65{
     66    return new MemoryValue(*this);
     67}
     68
    6469} } // namespace JSC::B3
    6570
  • trunk/Source/JavaScriptCore/b3/B3MemoryValue.h

    r193989 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6565protected:
    6666    void dumpMeta(CommaPrinter& comma, PrintStream&) const override;
     67
     68    Value* cloneImpl() const override;
    6769
    6870private:
  • trunk/Source/JavaScriptCore/b3/B3OriginDump.h

    r194372 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030
    3131#include "B3Origin.h"
    32 #include "B3Procedure.h"
    3332
    3433namespace JSC { namespace B3 {
    3534
     35class Procedure;
     36
    3637class OriginDump {
    3738public:
    38     OriginDump(const Procedure& proc, Origin origin)
     39    OriginDump(const Procedure* proc, Origin origin)
    3940        : m_proc(proc)
    4041        , m_origin(origin)
     
    4243    }
    4344
    44     void dump(PrintStream& out) const
    45     {
    46         m_proc.printOrigin(out, m_origin);
    47     }
     45    void dump(PrintStream& out) const;
    4846
    4947private:
    50     const Procedure& m_proc;
     48    const Procedure* m_proc;
    5149    Origin m_origin;
    5250};
  • trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp

    r194542 r195395  
    4545}
    4646
     47Value* PatchpointValue::cloneImpl() const
     48{
     49    return new PatchpointValue(*this);
     50}
     51
    4752PatchpointValue::PatchpointValue(unsigned index, Type type, Origin origin)
    4853    : Base(index, CheckedOpcode, Patchpoint, type, origin)
  • trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h

    r194542 r195395  
    6666    void dumpMeta(CommaPrinter&, PrintStream&) const override;
    6767
     68    Value* cloneImpl() const override;
     69
    6870private:
    6971    friend class Procedure;
  • trunk/Source/JavaScriptCore/b3/B3Procedure.cpp

    r194608 r195395  
    6969}
    7070
     71Value* Procedure::clone(Value* value)
     72{
     73    std::unique_ptr<Value> clone(value->cloneImpl());
     74    Value* result = clone.get();
     75    clone->m_index = addValueIndex();
     76    clone->owner = nullptr;
     77    m_values[clone->m_index] = WTFMove(clone);
     78    return result;
     79}
     80
    7181Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
    7282{
     
    91101}
    92102
     103Value* Procedure::addBottom(Origin origin, Type type)
     104{
     105    return addIntConstant(origin, type, 0);
     106}
     107
     108Value* Procedure::addBottom(Value* value)
     109{
     110    return addBottom(value->origin(), value->type());
     111}
     112
    93113Value* Procedure::addBoolConstant(Origin origin, TriState triState)
    94114{
     
    166186void Procedure::deleteValue(Value* value)
    167187{
    168     ASSERT(m_values[value->index()].get() == value);
     188    RELEASE_ASSERT(m_values[value->index()].get() == value);
    169189    m_valueIndexFreeList.append(value->index());
    170190    m_values[value->index()] = nullptr;
  • trunk/Source/JavaScriptCore/b3/B3Procedure.h

    r194608 r195395  
    7777    ValueType* add(Arguments...);
    7878
     79    Value* clone(Value*);
     80
    7981    Value* addIntConstant(Origin, Type, int64_t value);
    8082    Value* addIntConstant(Value*, int64_t value);
     83
     84    Value* addBottom(Origin, Type);
     85    Value* addBottom(Value*);
    8186
    8287    // Returns null for MixedTriState.
  • trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp

    r195314 r195395  
    3030
    3131#include "B3BasicBlockInlines.h"
     32#include "B3BlockInsertionSet.h"
    3233#include "B3ControlValue.h"
    3334#include "B3Dominators.h"
     
    259260        : m_proc(proc)
    260261        , m_insertionSet(proc)
     262        , m_blockInsertionSet(proc)
    261263    {
    262264    }
     
    287289               
    288290                for (m_index = 0; m_index < block->size(); ++m_index) {
     291                    if (verbose) {
     292                        dataLog(
     293                            "Looking at ", *block, " #", m_index, ": ",
     294                            deepDump(m_proc, block->at(m_index)), "\n");
     295                    }
    289296                    m_value = m_block->at(m_index);
    290297                    m_value->performSubstitution();
     
    296303            }
    297304
     305            if (m_blockInsertionSet.execute()) {
     306                m_proc.resetReachability();
     307                m_proc.invalidateCFG();
     308                m_dominators = &m_proc.dominators(); // Recompute if necessary.
     309                m_changedCFG = true;
     310            }
     311           
    298312            simplifyCFG();
    299313
     
    13881402                checkValue->child(0) = checkValue->child(0)->child(0);
    13891403                m_changed = true;
     1404            }
     1405
     1406            // If we are checking some bounded-size SSA expression that leads to a Select that
     1407            // has a constant as one of its results, then turn the Select into a Branch and split
     1408            // the code between the Check and the Branch. For example, this:
     1409            //
     1410            //     @a = Select(@p, @x, 42)
     1411            //     @b = Add(@a, 35)
     1412            //     Check(@b)
     1413            //
     1414            // becomes this:
     1415            //
     1416            //     Branch(@p, #truecase, #falsecase)
     1417            //
     1418            //   BB#truecase:
     1419            //     @b_truecase = Add(@x, 35)
     1420            //     Check(@b_truecase)
     1421            //     Upsilon(@x, ^a)
     1422            //     Upsilon(@b_truecase, ^b)
     1423            //     Jump(#continuation)
     1424            //
     1425            //   BB#falsecase:
     1426            //     @b_falsecase = Add(42, 35)
     1427            //     Check(@b_falsecase)
     1428            //     Upsilon(42, ^a)
     1429            //     Upsilon(@b_falsecase, ^b)
     1430            //     Jump(#continuation)
     1431            //
     1432            //   BB#continuation:
     1433            //     @a = Phi()
     1434            //     @b = Phi()
     1435            //
     1436            // The goal of this optimization is to kill a lot of code in one of those basic
     1437            // blocks. This is pretty much guaranteed since one of those blocks will replace all
     1438            // uses of the Select with a constant, and that constant will be transitively used
     1439            // from the check.
     1440            static const unsigned selectSpecializationBound = 3;
     1441            Value* select = findRecentNodeMatching(
     1442                m_value->child(0), selectSpecializationBound,
     1443                [&] (Value* value) -> bool {
     1444                    return value->opcode() == Select
     1445                        && (value->child(1)->isConstant() && value->child(2)->isConstant());
     1446                });
     1447            if (select) {
     1448                specializeSelect(select);
    13901449                break;
    13911450            }
     
    14571516            break;
    14581517        }
     1518    }
     1519
     1520    // Find a node that:
     1521    //     - functor(node) returns true.
     1522    //     - it's reachable from the given node via children.
     1523    //     - it's in the last "bound" slots in the current basic block.
     1524    // This algorithm is optimized under the assumption that the bound is small.
     1525    template<typename Functor>
     1526    Value* findRecentNodeMatching(Value* start, unsigned bound, const Functor& functor)
     1527    {
     1528        unsigned startIndex = bound < m_index ? m_index - bound : 0;
     1529        Value* result = nullptr;
     1530        start->walk(
     1531            [&] (Value* value) -> Value::WalkStatus {
     1532                bool found = false;
     1533                for (unsigned i = startIndex; i <= m_index; ++i) {
     1534                    if (m_block->at(i) == value)
     1535                        found = true;
     1536                }
     1537                if (!found)
     1538                    return Value::IgnoreChildren;
     1539
     1540                if (functor(value)) {
     1541                    result = value;
     1542                    return Value::Stop;
     1543                }
     1544
     1545                return Value::Continue;
     1546            });
     1547        return result;
     1548    }
     1549
     1550    // This specializes a sequence of code up to a Select. This doesn't work when we're at a
     1551    // terminal. It would be cool to fix that eventually. The main problem is that instead of
     1552    // splitting the block, we should just insert the then/else blocks. We'll have to create
     1553    // double the Phis and double the Upsilons. It'll probably be the sort of optimization that
     1554    // we want to do only after we've done loop optimizations, since this will *definitely*
     1555    // obscure things. In fact, even this simpler form of select specialization will possibly
     1556    // obscure other optimizations. It would be great to have two modes of strength reduction,
     1557    // one that does obscuring optimizations and runs late, and another that does not do
     1558    // obscuring optimizations and runs early.
     1559    // FIXME: Make select specialization handle branches.
     1560    // FIXME: Have a form of strength reduction that does no obscuring optimizations and runs
     1561    // early.
     1562    void specializeSelect(Value* source)
     1563    {
     1564        if (verbose)
     1565            dataLog("Specializing select: ", deepDump(m_proc, source), "\n");
     1566
     1567        // This mutates startIndex to account for the fact that m_block got the front of it
     1568        // chopped off.
     1569        BasicBlock* predecessor =
     1570            m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet);
     1571
     1572        // Splitting will commit the insertion set, which changes the exact position of the
     1573        // source. That's why we do the search after splitting.
     1574        unsigned startIndex = UINT_MAX;
     1575        for (unsigned i = predecessor->size(); i--;) {
     1576            if (predecessor->at(i) == source) {
     1577                startIndex = i;
     1578                break;
     1579            }
     1580        }
     1581       
     1582        RELEASE_ASSERT(startIndex != UINT_MAX);
     1583
     1584        // By BasicBlock convention, caseIndex == 0 => then, caseIndex == 1 => else.
     1585        static const unsigned numCases = 2;
     1586        BasicBlock* cases[numCases];
     1587        for (unsigned i = 0; i < numCases; ++i)
     1588            cases[i] = m_blockInsertionSet.insertBefore(m_block);
     1589
     1590        HashMap<Value*, Value*> mappings[2];
     1591
     1592        // Save things we want to know about the source.
     1593        Value* predicate = source->child(0);
     1594
     1595        for (unsigned i = 0; i < numCases; ++i)
     1596            mappings[i].add(source, source->child(1 + i));
     1597
     1598        auto cloneValue = [&] (Value* value) {
     1599            ASSERT(value != source);
     1600
     1601            for (unsigned i = 0; i < numCases; ++i) {
     1602                Value* clone = m_proc.clone(value);
     1603                for (Value*& child : clone->children()) {
     1604                    if (Value* newChild = mappings[i].get(child))
     1605                        child = newChild;
     1606                }
     1607                if (value->type() != Void)
     1608                    mappings[i].add(value, clone);
     1609
     1610                cases[i]->append(clone);
     1611                if (value->type() != Void)
     1612                    cases[i]->appendNew<UpsilonValue>(m_proc, value->origin(), clone, value);
     1613            }
     1614
     1615            value->replaceWithPhi();
     1616        };
     1617
     1618        // The jump that the splitter inserted is of no use to us.
     1619        predecessor->removeLast(m_proc);
     1620
     1621        // Hance the source, it's special.
     1622        for (unsigned i = 0; i < numCases; ++i) {
     1623            cases[i]->appendNew<UpsilonValue>(
     1624                m_proc, source->origin(), source->child(1 + i), source);
     1625        }
     1626        source->replaceWithPhi();
     1627        m_insertionSet.insertValue(m_index, source);
     1628
     1629        // Now handle all values between the source and the check.
     1630        for (unsigned i = startIndex + 1; i < predecessor->size(); ++i) {
     1631            Value* value = predecessor->at(i);
     1632            value->owner = nullptr;
     1633
     1634            cloneValue(value);
     1635
     1636            if (value->type() != Void)
     1637                m_insertionSet.insertValue(m_index, value);
     1638            else
     1639                m_proc.deleteValue(value);
     1640        }
     1641
     1642        // Finally, deal with the check.
     1643        cloneValue(m_value);
     1644
     1645        // Remove the values from the predecessor.
     1646        predecessor->values().resize(startIndex);
     1647       
     1648        predecessor->appendNew<ControlValue>(
     1649            m_proc, Branch, source->origin(), predicate,
     1650            FrequentedBlock(cases[0]), FrequentedBlock(cases[1]));
     1651
     1652        for (unsigned i = 0; i < numCases; ++i) {
     1653            cases[i]->appendNew<ControlValue>(
     1654                m_proc, Jump, m_value->origin(), FrequentedBlock(m_block));
     1655        }
     1656
     1657        m_changed = true;
     1658
     1659        predecessor->updatePredecessorsAfter();
    14591660    }
    14601661
     
    18372038    Procedure& m_proc;
    18382039    InsertionSet m_insertionSet;
     2040    BlockInsertionSet m_blockInsertionSet;
    18392041    BasicBlock* m_block { nullptr };
    18402042    unsigned m_index { 0 };
  • trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h

    r191705 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3737    Locked,
    3838
    39     // These stack slots could share space with other stack slots, provided that they aren't live
    40     // at the same time. The compiler still has to do escape analysis, since these can be escaped
    41     // explicitly in IR.
     39    // These stack slots behave like variables. Undefined behavior happens if you store less than
     40    // the width of the slot.
    4241    Anonymous
    4342
  • trunk/Source/JavaScriptCore/b3/B3StackSlotValue.cpp

    r191993 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4040}
    4141
     42Value* StackSlotValue::cloneImpl() const
     43{
     44    return new StackSlotValue(*this);
     45}
     46
    4247} } // namespace JSC::B3
    4348
  • trunk/Source/JavaScriptCore/b3/B3StackSlotValue.h

    r191994 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6060    void dumpMeta(CommaPrinter&, PrintStream&) const override;
    6161
     62    Value* cloneImpl() const override;
     63
    6264private:
    6365    friend class Air::StackSlot;
  • trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp

    r192346 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6464}
    6565
     66Value* SwitchValue::cloneImpl() const
     67{
     68    return new SwitchValue(*this);
     69}
     70
    6671SwitchValue::SwitchValue(
    6772    unsigned index, Origin origin, Value* child, const FrequentedBlock& fallThrough)
  • trunk/Source/JavaScriptCore/b3/B3SwitchValue.h

    r192346 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    117117    void dumpMeta(CommaPrinter&, PrintStream&) const override;
    118118
     119    Value* cloneImpl() const override;
     120
    119121private:
    120122    friend class Procedure;
  • trunk/Source/JavaScriptCore/b3/B3UpsilonValue.cpp

    r191993 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4646}
    4747
     48Value* UpsilonValue::cloneImpl() const
     49{
     50    return new UpsilonValue(*this);
     51}
     52
    4853} } // namespace JSC::B3
    4954
  • trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h

    r191994 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5050    void dumpMeta(CommaPrinter&, PrintStream&) const override;
    5151
     52    Value* cloneImpl() const override;
     53
    5254private:
    5355    friend class Procedure;
     
    6062        , m_phi(phi)
    6163    {
    62         if (phi) {
     64        if (phi)
    6365            ASSERT(value->type() == phi->type());
    64             ASSERT(phi->opcode() == Phi);
    65         }
    6666    }
    6767
  • trunk/Source/JavaScriptCore/b3/B3Validate.cpp

    r194802 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    353353                VALIDATE(value->numChildren() == 1, ("At ", *value));
    354354                VALIDATE(value->as<UpsilonValue>()->phi(), ("At ", *value));
     355                VALIDATE(value->as<UpsilonValue>()->phi()->opcode() == Phi, ("At ", *value));
    355356                VALIDATE(value->child(0)->type() == value->as<UpsilonValue>()->phi()->type(), ("At ", *value));
    356357                VALIDATE(valueInProc.contains(value->as<UpsilonValue>()->phi()), ("At ", *value));
  • trunk/Source/JavaScriptCore/b3/B3Value.cpp

    r194802 r195395  
    9090}
    9191
     92void Value::replaceWithPhi()
     93{
     94    if (m_type == Void) {
     95        replaceWithNop();
     96        return;
     97    }
     98   
     99    unsigned index = m_index;
     100    Origin origin = m_origin;
     101    BasicBlock* owner = this->owner;
     102    Type type = m_type;
     103
     104    this->Value::~Value();
     105
     106    new (this) Value(index, Phi, type, origin);
     107
     108    this->owner = owner;
     109}
     110
    92111void Value::dump(PrintStream& out) const
    93112{
    94113    out.print(dumpPrefix, m_index);
     114}
     115
     116Value* Value::cloneImpl() const
     117{
     118    return new Value(*this);
    95119}
    96120
     
    101125}
    102126
    103 void Value::deepDump(const Procedure& proc, PrintStream& out) const
     127void Value::deepDump(const Procedure* proc, PrintStream& out) const
    104128{
    105129    out.print(m_type, " ", *this, " = ", m_opcode);
  • trunk/Source/JavaScriptCore/b3/B3Value.h

    r194855 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343class BasicBlock;
    4444class CheckValue;
     45class PhiChildren;
    4546class Procedure;
    4647
    4748class JS_EXPORT_PRIVATE Value {
    48     WTF_MAKE_NONCOPYABLE(Value);
    4949    WTF_MAKE_FAST_ALLOCATED;
    5050public:
     
    8585    void replaceWithIdentity(Value*);
    8686    void replaceWithNop();
     87    void replaceWithPhi();
    8788
    8889    void dump(PrintStream&) const;
    89     void deepDump(const Procedure&, PrintStream&) const;
     90    void deepDump(const Procedure*, PrintStream&) const;
    9091
    9192    // This is how you cast Values. For example, if you want to do something provided that we have a
     
    205206    void performSubstitution();
    206207
     208    // Walk the ancestors of this value (i.e. the graph of things it transitively uses). This
     209    // either walks phis or not, depending on whether PhiChildren is null. Your callback gets
     210    // called with the signature:
     211    //
     212    //     (Value*) -> WalkStatus
     213    enum WalkStatus {
     214        Continue,
     215        IgnoreChildren,
     216        Stop
     217    };
     218    template<typename Functor>
     219    void walk(const Functor& functor, PhiChildren* = nullptr);
     220
    207221protected:
     222    virtual Value* cloneImpl() const;
     223   
    208224    virtual void dumpChildren(CommaPrinter&, PrintStream&) const;
    209225    virtual void dumpMeta(CommaPrinter&, PrintStream&) const;
     
    221237protected:
    222238    enum CheckedOpcodeTag { CheckedOpcode };
     239
     240    Value(const Value&) = default;
     241    Value& operator=(const Value&) = default;
    223242   
    224243    // Instantiate values via Procedure.
     
    316335class DeepValueDump {
    317336public:
    318     DeepValueDump(const Procedure& proc, const Value* value)
     337    DeepValueDump(const Procedure* proc, const Value* value)
    319338        : m_proc(proc)
    320339        , m_value(value)
     
    331350
    332351private:
    333     const Procedure& m_proc;
     352    const Procedure* m_proc;
    334353    const Value* m_value;
    335354};
     
    337356inline DeepValueDump deepDump(const Procedure& proc, const Value* value)
    338357{
    339     return DeepValueDump(proc, value);
     358    return DeepValueDump(&proc, value);
    340359}
     360inline DeepValueDump deepDump(const Value* value)
     361{
     362    return DeepValueDump(nullptr, value);
     363}
    341364
    342365} } // namespace JSC::B3
  • trunk/Source/JavaScriptCore/b3/B3ValueInlines.h

    r193683 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535#include "B3ConstFloatValue.h"
    3636#include "B3PatchpointValue.h"
     37#include "B3PhiChildren.h"
    3738#include "B3Procedure.h"
    3839#include "B3Value.h"
     40#include <wtf/GraphNodeWorklist.h>
    3941
    4042namespace JSC { namespace B3 {
     
    205207}
    206208
     209template<typename Functor>
     210void Value::walk(const Functor& functor, PhiChildren* phiChildren)
     211{
     212    GraphNodeWorklist<Value*> worklist;
     213    worklist.push(this);
     214    while (Value* value = worklist.pop()) {
     215        WalkStatus status = functor(value);
     216        switch (status) {
     217        case Continue:
     218            if (value->opcode() == Phi) {
     219                if (phiChildren)
     220                    worklist.pushAll(phiChildren->at(value).values());
     221            } else
     222                worklist.pushAll(value->children());
     223            break;
     224        case IgnoreChildren:
     225            break;
     226        case Stop:
     227            return;
     228        }
     229    }
     230}
     231
    207232} } // namespace JSC::B3
    208233
  • trunk/Source/JavaScriptCore/b3/B3ValueKey.cpp

    r194341 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535
    3636namespace JSC { namespace B3 {
     37
     38ValueKey ValueKey::intConstant(Type type, int64_t value)
     39{
     40    switch (type) {
     41    case Int32:
     42        return ValueKey(Const32, Int32, value);
     43    case Int64:
     44        return ValueKey(Const64, Int64, value);
     45    default:
     46        RELEASE_ASSERT_NOT_REACHED();
     47        return ValueKey();
     48    }
     49}
    3750
    3851void ValueKey::dump(PrintStream& out) const
  • trunk/Source/JavaScriptCore/b3/B3ValueKey.h

    r193683 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    8686    }
    8787
     88    static ValueKey intConstant(Type type, int64_t value);
     89
    8890    Opcode opcode() const { return m_opcode; }
    8991    Type type() const { return m_type; }
  • trunk/Source/JavaScriptCore/b3/air/AirCode.h

    r195298 r195395  
    2929#if ENABLE(B3_JIT)
    3030
     31#include "AirArg.h"
    3132#include "AirBasicBlock.h"
    3233#include "AirSpecial.h"
  • trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp

    r195387 r195395  
    5454class AbstractColoringAllocator {
    5555public:
    56     AbstractColoringAllocator(const Vector<Reg>& regsInPriorityOrder, IndexType lastPrecoloredRegisterIndex, unsigned tmpArraySize)
     56    AbstractColoringAllocator(const Vector<Reg>& regsInPriorityOrder, IndexType lastPrecoloredRegisterIndex, unsigned tmpArraySize, const HashSet<unsigned>& unspillableTmp)
    5757        : m_regsInPriorityOrder(regsInPriorityOrder)
    5858        , m_lastPrecoloredRegisterIndex(lastPrecoloredRegisterIndex)
     59        , m_unspillableTmps(unspillableTmp)
    5960    {
    6061        initializeDegrees(tmpArraySize);
     
    9192
    9293            if (degree >= m_regsInPriorityOrder.size())
    93                 m_spillWorklist.add(i);
     94                addToSpill(i);
    9495            else if (!m_moveList[i].isEmpty())
    9596                m_freezeWorklist.add(i);
     
    9798                m_simplifyWorklist.append(i);
    9899        }
     100    }
     101
     102    void addToSpill(unsigned toSpill)
     103    {
     104        if (m_unspillableTmps.contains(toSpill))
     105            return;
     106
     107        m_spillWorklist.add(toSpill);
    99108    }
    100109
     
    362371
    363372        if (m_degrees[u] >= m_regsInPriorityOrder.size() && m_freezeWorklist.remove(u))
    364             m_spillWorklist.add(u);
     373            addToSpill(u);
    365374    }
    366375
     
    626635    // The mapping of Tmp to their alias for Moves that are always coalescing regardless of spilling.
    627636    Vector<IndexType, 0, UnsafeVectorOverflow> m_coalescedTmpsAtSpill;
     637   
     638    const HashSet<unsigned>& m_unspillableTmps;
    628639};
    629640
     
    633644public:
    634645    ColoringAllocator(Code& code, TmpWidth& tmpWidth, const UseCounts<Tmp>& useCounts, const HashSet<unsigned>& unspillableTmp)
    635         : AbstractColoringAllocator<unsigned>(regsInPriorityOrder(type), AbsoluteTmpMapper<type>::lastMachineRegisterIndex(), tmpArraySize(code))
     646        : AbstractColoringAllocator<unsigned>(regsInPriorityOrder(type), AbsoluteTmpMapper<type>::lastMachineRegisterIndex(), tmpArraySize(code), unspillableTmp)
    636647        , m_code(code)
    637648        , m_tmpWidth(tmpWidth)
    638649        , m_useCounts(useCounts)
    639         , m_unspillableTmps(unspillableTmp)
    640650    {
    641651        initializePrecoloredTmp();
     
    928938        auto iterator = m_spillWorklist.begin();
    929939
    930         while (iterator != m_spillWorklist.end() && m_unspillableTmps.contains(*iterator))
    931             ++iterator;
    932 
    933         RELEASE_ASSERT_WITH_MESSAGE(iterator != m_spillWorklist.end(), "It is not possible to color the Air graph with the number of available registers.");
     940        RELEASE_ASSERT_WITH_MESSAGE(iterator != m_spillWorklist.end(), "selectSpill() called when there was no spill.");
     941        RELEASE_ASSERT_WITH_MESSAGE(!m_unspillableTmps.contains(*iterator), "trying to spill unspillable tmp");
    934942
    935943        // Higher score means more desirable to spill. Lower scores maximize the likelihood that a tmp
     
    946954            // All else being equal, the score should be inversely related to the number of warm uses and
    947955            // defs.
    948             const UseCounts<Tmp>::Counts& counts = m_useCounts[tmp];
    949             double uses = counts.numWarmUses + counts.numDefs;
     956            const UseCounts<Tmp>::Counts* counts = m_useCounts[tmp];
     957            if (!counts)
     958                return std::numeric_limits<double>::infinity();
     959           
     960            double uses = counts->numWarmUses + counts->numDefs;
    950961
    951962            // If it's a constant, then it's not as bad to spill. We can rematerialize it in many
    952963            // cases.
    953             if (counts.numConstDefs == counts.numDefs)
     964            if (counts->numConstDefs == counts->numDefs)
    954965                uses /= 2;
    955966
     
    962973        ++iterator;
    963974        for (;iterator != m_spillWorklist.end(); ++iterator) {
    964             if (m_unspillableTmps.contains(*iterator))
    965                 continue;
    966 
    967975            double tmpScore = score(AbsoluteTmpMapper<type>::tmpFromAbsoluteIndex(*iterator));
    968976            if (tmpScore > maxScore) {
     977                ASSERT(!m_unspillableTmps.contains(*iterator));
    969978                victimIterator = iterator;
    970979                maxScore = tmpScore;
     
    10591068    // FIXME: spilling should not type specific. It is only a side effect of using UseCounts.
    10601069    const UseCounts<Tmp>& m_useCounts;
    1061     const HashSet<unsigned>& m_unspillableTmps;
    10621070};
    10631071
  • trunk/Source/JavaScriptCore/b3/air/AirUseCounts.h

    r195387 r195395  
    9898    }
    9999
    100     const Counts& operator[](const Thing& arg) const
     100    const Counts* operator[](const Thing& arg) const
    101101    {
    102         auto iterator = m_counts.find(arg);
    103         ASSERT(iterator != m_counts.end());
    104         return iterator->value;
     102        auto iter = m_counts.find(arg);
     103        if (iter == m_counts.end())
     104            return nullptr;
     105        return &iter->value;
    105106    }
    106107
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r195159 r195395  
    90649064    CHECK(invoke<intptr_t>(*code, 43, 1, 2) == 2);
    90659065    CHECK(invoke<intptr_t>(*code, 43, 642462, 32533) == 32533);
     9066}
     9067
     9068void testCheckSelect()
     9069{
     9070    Procedure proc;
     9071    BasicBlock* root = proc.addBlock();
     9072
     9073    CheckValue* check = root->appendNew<CheckValue>(
     9074        proc, Check, Origin(),
     9075        root->appendNew<Value>(
     9076            proc, Add, Origin(),
     9077            root->appendNew<Value>(
     9078                proc, Select, Origin(),
     9079                root->appendNew<Value>(
     9080                    proc, BitAnd, Origin(),
     9081                    root->appendNew<Value>(
     9082                        proc, Trunc, Origin(),
     9083                        root->appendNew<ArgumentRegValue>(
     9084                            proc, Origin(), GPRInfo::argumentGPR0)),
     9085                    root->appendNew<Const32Value>(proc, Origin(), 0xff)),
     9086                root->appendNew<ConstPtrValue>(proc, Origin(), -42),
     9087                root->appendNew<ConstPtrValue>(proc, Origin(), 35)),
     9088            root->appendNew<ConstPtrValue>(proc, Origin(), 42)));
     9089    unsigned generationCount = 0;
     9090    check->setGenerator(
     9091        [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
     9092            AllowMacroScratchRegisterUsage allowScratch(jit);
     9093
     9094            generationCount++;
     9095            jit.move(CCallHelpers::TrustedImm32(666), GPRInfo::returnValueGPR);
     9096            jit.emitFunctionEpilogue();
     9097            jit.ret();
     9098        });
     9099   
     9100    root->appendNew<ControlValue>(
     9101        proc, Return, Origin(),
     9102        root->appendNew<Const32Value>(proc, Origin(), 0));
     9103
     9104    auto code = compile(proc);
     9105    CHECK(generationCount == 1);
     9106    CHECK(invoke<int>(*code, true) == 0);
     9107    CHECK(invoke<int>(*code, false) == 666);
     9108}
     9109
     9110void testCheckSelectCheckSelect()
     9111{
     9112    Procedure proc;
     9113    BasicBlock* root = proc.addBlock();
     9114
     9115    CheckValue* check = root->appendNew<CheckValue>(
     9116        proc, Check, Origin(),
     9117        root->appendNew<Value>(
     9118            proc, Add, Origin(),
     9119            root->appendNew<Value>(
     9120                proc, Select, Origin(),
     9121                root->appendNew<Value>(
     9122                    proc, BitAnd, Origin(),
     9123                    root->appendNew<Value>(
     9124                        proc, Trunc, Origin(),
     9125                        root->appendNew<ArgumentRegValue>(
     9126                            proc, Origin(), GPRInfo::argumentGPR0)),
     9127                    root->appendNew<Const32Value>(proc, Origin(), 0xff)),
     9128                root->appendNew<ConstPtrValue>(proc, Origin(), -42),
     9129                root->appendNew<ConstPtrValue>(proc, Origin(), 35)),
     9130            root->appendNew<ConstPtrValue>(proc, Origin(), 42)));
     9131
     9132    unsigned generationCount = 0;
     9133    check->setGenerator(
     9134        [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
     9135            AllowMacroScratchRegisterUsage allowScratch(jit);
     9136
     9137            generationCount++;
     9138            jit.move(CCallHelpers::TrustedImm32(666), GPRInfo::returnValueGPR);
     9139            jit.emitFunctionEpilogue();
     9140            jit.ret();
     9141        });
     9142   
     9143    CheckValue* check2 = root->appendNew<CheckValue>(
     9144        proc, Check, Origin(),
     9145        root->appendNew<Value>(
     9146            proc, Add, Origin(),
     9147            root->appendNew<Value>(
     9148                proc, Select, Origin(),
     9149                root->appendNew<Value>(
     9150                    proc, BitAnd, Origin(),
     9151                    root->appendNew<Value>(
     9152                        proc, Trunc, Origin(),
     9153                        root->appendNew<ArgumentRegValue>(
     9154                            proc, Origin(), GPRInfo::argumentGPR1)),
     9155                    root->appendNew<Const32Value>(proc, Origin(), 0xff)),
     9156                root->appendNew<ConstPtrValue>(proc, Origin(), -43),
     9157                root->appendNew<ConstPtrValue>(proc, Origin(), 36)),
     9158            root->appendNew<ConstPtrValue>(proc, Origin(), 43)));
     9159
     9160    unsigned generationCount2 = 0;
     9161    check2->setGenerator(
     9162        [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
     9163            AllowMacroScratchRegisterUsage allowScratch(jit);
     9164
     9165            generationCount2++;
     9166            jit.move(CCallHelpers::TrustedImm32(667), GPRInfo::returnValueGPR);
     9167            jit.emitFunctionEpilogue();
     9168            jit.ret();
     9169        });
     9170   
     9171    root->appendNew<ControlValue>(
     9172        proc, Return, Origin(),
     9173        root->appendNew<Const32Value>(proc, Origin(), 0));
     9174
     9175    auto code = compile(proc);
     9176    CHECK(generationCount == 1);
     9177    CHECK(generationCount2 == 1);
     9178    CHECK(invoke<int>(*code, true, true) == 0);
     9179    CHECK(invoke<int>(*code, false, true) == 666);
     9180    CHECK(invoke<int>(*code, true, false) == 667);
    90669181}
    90679182
     
    1007510190
    1007610191    RUN(testComplex(64, 128));
    10077     RUN(testComplex(64, 256));
    10078     RUN(testComplex(64, 384));
    1007910192    RUN(testComplex(4, 128));
    1008010193    RUN(testComplex(4, 256));
     
    1052510638    RUN(testSelectFold(43));
    1052610639    RUN(testSelectInvert());
     10640    RUN(testCheckSelect());
     10641    RUN(testCheckSelectCheckSelect());
    1052710642    RUN_BINARY(testPowDoubleByIntegerLoop, floatingPointOperands<double>(), int64Operands());
    1052810643
  • trunk/Source/JavaScriptCore/runtime/Options.h

    r195298 r195395  
    11/*
    2  * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    345345    v(bool, airSpillsEverything, false, nullptr) \
    346346    v(bool, logAirRegisterPressure, false, nullptr) \
     347    v(unsigned, maxB3TailDupBlockSize, 3, nullptr) \
     348    v(unsigned, maxB3TailDupBlockSuccessors, 3, nullptr) \
    347349    \
    348350    v(bool, useDollarVM, false, "installs the $vm debugging tool in global objects") \
  • trunk/Source/WTF/ChangeLog

    r195356 r195395  
     12016-01-19  Filip Pizlo  <fpizlo@apple.com>
     2
     3        B3 should have basic path specialization
     4        https://bugs.webkit.org/show_bug.cgi?id=153200
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        * wtf/GraphNodeWorklist.h:
     9        (WTF::GraphNodeWorklist::push):
     10        (WTF::GraphNodeWorklist::pushAll):
     11        (WTF::GraphNodeWorklist::isEmpty):
     12        (WTF::GraphNodeWorklist::notEmpty):
     13
    1142016-01-20  Said Abou-Hallawa  <sabouhallawa@apple.com>
    215
  • trunk/Source/WTF/wtf/GraphNodeWorklist.h

    r192539 r195395  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4646    }
    4747
     48    template<typename Iterable>
     49    void pushAll(const Iterable& iterable)
     50    {
     51        for (Node node : iterable)
     52            push(node);
     53    }
     54
    4855    bool isEmpty() const { return m_stack.isEmpty(); }
    4956    bool notEmpty() const { return !m_stack.isEmpty(); }
  • trunk/Tools/Scripts/display-profiler-output

    r172129 r195395  
    536536end
    537537
    538 def summary(mode)
     538def summary(mode, order)
    539539    remaining = screenWidth
    540540   
     
    619619    $bytecodes.sort {
    620620        | a, b |
    621         b.totalMaxTopExecutionCount <=> a.totalMaxTopExecutionCount
     621        case order
     622        when :bytecode
     623            b.totalMaxTopExecutionCount <=> a.totalMaxTopExecutionCount
     624        when :machine
     625            b.totalMaxBottomExecutionCount <=> a.totalMaxBottomExecutionCount
     626        else
     627            raise
     628        end
    622629    }.each {
    623630        | bytecode |
     
    739746        exit 0
    740747    when "summary", "s"
    741         summary(:summary)
     748        summary(:summary, :bytecode)
    742749    when "full", "f"
    743         summary(:full)
     750        if args[0] and (args[0] == "m" or args[0] == "machine")
     751            summary(:full, :machine)
     752        else
     753            summary(:full, :bytecode)
     754        end
    744755    when "source"
    745756        if args.length != 1
Note: See TracChangeset for help on using the changeset viewer.