Changeset 192295 in webkit


Ignore:
Timestamp:
Nov 10, 2015 11:21:23 PM (8 years ago)
Author:
fpizlo@apple.com
Message:

B3 should be able to compile a program with ChillDiv
https://bugs.webkit.org/show_bug.cgi?id=151114

Reviewed by Benjamin Poulain.

Source/JavaScriptCore:

This change is about a lot more than ChillDiv. I picked that as the next thing to lower
because I knew that it would force me to come up with a sensible idiom for doing
stepwise lowerings that require breaking basic blocks. The idea is that you want to
write a loop that iterates forward over the program, which turns some operations that
currently are just single Values into an entire little sub-CFGs. That requires splitting
the block that contained the original Value. That's tricky if you then want to keep
iterating: the index of the Value you were last looking at has now changed and your
InsertionSets are now invalid.

This introduces an idiom that handles this. It's BlockInsertionSet::splitBefore(). The
idea is that it uses the current block before the split as the continuation after the
split. When you call splitBefore(), you pass it your loop index and your InsertionSet
(if applicable). It makes sure that it changes those auxiliary things in such a way that
you can keep looping.

This uncovered some bugs, since this is the first time that we're compiling cross edges.

Because ChillDiv is really a division, I also had to write a bunch of code to support
the ordinary B3 Div. While doing that, I realized that there was asymmetry to that
constness of the Value constant folding methods, so I fixed that as well.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::mul32):
(JSC::MacroAssemblerX86Common::x86ConvertToDoubleWord32):
(JSC::MacroAssemblerX86Common::x86Div32):
(JSC::MacroAssemblerX86Common::neg32):

  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::mul64):
(JSC::MacroAssemblerX86_64::x86ConvertToQuadWord64):
(JSC::MacroAssemblerX86_64::x86Div64):
(JSC::MacroAssemblerX86_64::neg64):

  • assembler/X86Assembler.h:

(JSC::X86Assembler::idivl_r):
(JSC::X86Assembler::idivq_r):
(JSC::X86Assembler::cmpl_rr):
(JSC::X86Assembler::cdq):
(JSC::X86Assembler::cdqq):
(JSC::X86Assembler::fstps):

  • b3/B3BasicBlock.cpp:

(JSC::B3::BasicBlock::append):
(JSC::B3::BasicBlock::replaceLast):
(JSC::B3::BasicBlock::appendIntConstant):
(JSC::B3::BasicBlock::replaceSuccessor):
(JSC::B3::BasicBlock::addPredecessor):
(JSC::B3::BasicBlock::replacePredecessor):
(JSC::B3::BasicBlock::updatePredecessors):
(JSC::B3::BasicBlock::dump):

  • b3/B3BasicBlock.h:

(JSC::B3::BasicBlock::values):
(JSC::B3::BasicBlock::numPredecessors):
(JSC::B3::BasicBlock::predecessor):
(JSC::B3::BasicBlock::frequency):

  • b3/B3BasicBlockInlines.h:

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

  • b3/B3BasicBlockUtils.h:

(JSC::B3::replacePredecessor):
(JSC::B3::updatePredecessors):
(JSC::B3::resetReachability):

  • b3/B3BlockInsertionSet.cpp: Added.

(JSC::B3::BlockInsertionSet::BlockInsertionSet):
(JSC::B3::BlockInsertionSet::~BlockInsertionSet):
(JSC::B3::BlockInsertionSet::insert):
(JSC::B3::BlockInsertionSet::insertBefore):
(JSC::B3::BlockInsertionSet::splitForward):
(JSC::B3::BlockInsertionSet::execute):

  • b3/B3BlockInsertionSet.h: Added.
  • b3/B3Common.h:

(JSC::B3::isRepresentableAs):
(JSC::B3::chillDiv):

  • b3/B3Const32Value.cpp:

(JSC::B3::Const32Value::addConstant):
(JSC::B3::Const32Value::subConstant):
(JSC::B3::Const32Value::divConstant):
(JSC::B3::Const32Value::bitAndConstant):
(JSC::B3::Const32Value::bitOrConstant):
(JSC::B3::Const32Value::bitXorConstant):
(JSC::B3::Const32Value::shlConstant):
(JSC::B3::Const32Value::sShrConstant):
(JSC::B3::Const32Value::zShrConstant):
(JSC::B3::Const32Value::equalConstant):
(JSC::B3::Const32Value::notEqualConstant):
(JSC::B3::Const32Value::lessThanConstant):
(JSC::B3::Const32Value::greaterThanConstant):
(JSC::B3::Const32Value::lessEqualConstant):
(JSC::B3::Const32Value::greaterEqualConstant):
(JSC::B3::Const32Value::aboveConstant):
(JSC::B3::Const32Value::belowConstant):
(JSC::B3::Const32Value::aboveEqualConstant):
(JSC::B3::Const32Value::belowEqualConstant):

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

(JSC::B3::Const64Value::addConstant):
(JSC::B3::Const64Value::subConstant):
(JSC::B3::Const64Value::divConstant):
(JSC::B3::Const64Value::bitAndConstant):
(JSC::B3::Const64Value::bitOrConstant):
(JSC::B3::Const64Value::bitXorConstant):
(JSC::B3::Const64Value::shlConstant):
(JSC::B3::Const64Value::sShrConstant):
(JSC::B3::Const64Value::zShrConstant):
(JSC::B3::Const64Value::equalConstant):
(JSC::B3::Const64Value::notEqualConstant):
(JSC::B3::Const64Value::lessThanConstant):
(JSC::B3::Const64Value::greaterThanConstant):
(JSC::B3::Const64Value::lessEqualConstant):
(JSC::B3::Const64Value::greaterEqualConstant):
(JSC::B3::Const64Value::aboveConstant):
(JSC::B3::Const64Value::belowConstant):
(JSC::B3::Const64Value::aboveEqualConstant):
(JSC::B3::Const64Value::belowEqualConstant):

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

(JSC::B3::ConstDoubleValue::addConstant):
(JSC::B3::ConstDoubleValue::subConstant):
(JSC::B3::ConstDoubleValue::divConstant):
(JSC::B3::ConstDoubleValue::equalConstant):
(JSC::B3::ConstDoubleValue::notEqualConstant):
(JSC::B3::ConstDoubleValue::lessThanConstant):
(JSC::B3::ConstDoubleValue::greaterThanConstant):
(JSC::B3::ConstDoubleValue::lessEqualConstant):
(JSC::B3::ConstDoubleValue::greaterEqualConstant):

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

(JSC::B3::ControlValue::~ControlValue):
(JSC::B3::ControlValue::replaceSuccessor):
(JSC::B3::ControlValue::convertToJump):

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

(JSC::B3::generateToAir):

  • b3/B3GenericFrequentedBlock.h:

(JSC::B3::GenericFrequentedBlock::block):
(JSC::B3::GenericFrequentedBlock::frequency):
(JSC::B3::GenericFrequentedBlock::dump):

  • b3/B3InsertionSet.cpp:

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

  • b3/B3InsertionSet.h:
  • b3/B3LowerMacros.cpp: Added.

(JSC::B3::lowerMacros):

  • b3/B3LowerMacros.h: Added.
  • b3/B3LowerToAir.cpp:

(JSC::B3::Air::LowerToAir::lower):

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

(JSC::B3::Procedure::addBlock):
(JSC::B3::Procedure::addIntConstant):
(JSC::B3::Procedure::addBoolConstant):
(JSC::B3::Procedure::resetValueOwners):

  • b3/B3Procedure.h:

(JSC::B3::Procedure::takeByproducts):

  • b3/B3ReduceStrength.cpp:
  • b3/B3Validate.cpp:
  • b3/B3Value.cpp:

(JSC::B3::Value::addConstant):
(JSC::B3::Value::subConstant):
(JSC::B3::Value::divConstant):
(JSC::B3::Value::bitAndConstant):
(JSC::B3::Value::bitOrConstant):
(JSC::B3::Value::bitXorConstant):
(JSC::B3::Value::shlConstant):
(JSC::B3::Value::sShrConstant):
(JSC::B3::Value::zShrConstant):
(JSC::B3::Value::equalConstant):
(JSC::B3::Value::notEqualConstant):
(JSC::B3::Value::lessThanConstant):
(JSC::B3::Value::greaterThanConstant):
(JSC::B3::Value::lessEqualConstant):
(JSC::B3::Value::greaterEqualConstant):
(JSC::B3::Value::aboveConstant):
(JSC::B3::Value::belowConstant):
(JSC::B3::Value::aboveEqualConstant):
(JSC::B3::Value::belowEqualConstant):

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

(JSC::B3::Air::generate):

  • b3/air/AirInstInlines.h:

(JSC::B3::Air::isUrshift64Valid):
(JSC::B3::Air::isX86DivHelperValid):
(JSC::B3::Air::isX86ConvertToDoubleWord32Valid):
(JSC::B3::Air::isX86ConvertToDoubleWord64Valid):
(JSC::B3::Air::isX86Div32Valid):
(JSC::B3::Air::isX86Div64Valid):

  • b3/air/AirOpcode.opcodes:
  • b3/air/AirSimplifyCFG.cpp:

(JSC::B3::Air::simplifyCFG):

  • b3/testb3.cpp:

(JSC::B3::testCallFunctionWithHellaDoubleArguments):
(JSC::B3::testChillDiv):
(JSC::B3::testChillDivTwice):
(JSC::B3::testChillDiv64):
(JSC::B3::run):

  • dfg/DFGBlockInsertionSet.h:
  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileArithDiv):
(JSC::DFG::SpeculativeJIT::compileArithMod):

  • jit/JITArithmetic.cpp:

(JSC::JIT::emit_op_mod):

  • jit/JITArithmetic32_64.cpp:

(JSC::JIT::emit_op_mod):

  • wasm/WASMFunctionCompiler.h:

(JSC::WASMFunctionCompiler::buildBinaryI32):

Source/WTF:

Needed to beef up some compiler algorithms. All of the hardening was about making them
work with objects that have move semantics but not copy semantics. This arises in B3
basic block insertion sets.

  • wtf/BubbleSort.h:

(WTF::bubbleSort):

  • wtf/Insertion.h:

(WTF::Insertion::Insertion):
(WTF::Insertion::index):
(WTF::Insertion::element):
(WTF::Insertion::operator<):
(WTF::executeInsertions):

Location:
trunk/Source
Files:
3 added
43 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r192292 r192295  
     12015-11-10  Filip Pizlo  <fpizlo@apple.com>
     2
     3        B3 should be able to compile a program with ChillDiv
     4        https://bugs.webkit.org/show_bug.cgi?id=151114
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        This change is about a lot more than ChillDiv. I picked that as the next thing to lower
     9        because I knew that it would force me to come up with a sensible idiom for doing
     10        stepwise lowerings that require breaking basic blocks. The idea is that you want to
     11        write a loop that iterates forward over the program, which turns some operations that
     12        currently are just single Values into an entire little sub-CFGs. That requires splitting
     13        the block that contained the original Value. That's tricky if you then want to keep
     14        iterating: the index of the Value you were last looking at has now changed and your
     15        InsertionSets are now invalid.
     16
     17        This introduces an idiom that handles this. It's BlockInsertionSet::splitBefore(). The
     18        idea is that it uses the current block before the split as the continuation after the
     19        split. When you call splitBefore(), you pass it your loop index and your InsertionSet
     20        (if applicable). It makes sure that it changes those auxiliary things in such a way that
     21        you can keep looping.
     22
     23        This uncovered some bugs, since this is the first time that we're compiling cross edges.
     24
     25        Because ChillDiv is really a division, I also had to write a bunch of code to support
     26        the ordinary B3 Div. While doing that, I realized that there was asymmetry to that
     27        constness of the Value constant folding methods, so I fixed that as well.
     28
     29        * JavaScriptCore.xcodeproj/project.pbxproj:
     30        * assembler/MacroAssemblerX86Common.h:
     31        (JSC::MacroAssemblerX86Common::mul32):
     32        (JSC::MacroAssemblerX86Common::x86ConvertToDoubleWord32):
     33        (JSC::MacroAssemblerX86Common::x86Div32):
     34        (JSC::MacroAssemblerX86Common::neg32):
     35        * assembler/MacroAssemblerX86_64.h:
     36        (JSC::MacroAssemblerX86_64::mul64):
     37        (JSC::MacroAssemblerX86_64::x86ConvertToQuadWord64):
     38        (JSC::MacroAssemblerX86_64::x86Div64):
     39        (JSC::MacroAssemblerX86_64::neg64):
     40        * assembler/X86Assembler.h:
     41        (JSC::X86Assembler::idivl_r):
     42        (JSC::X86Assembler::idivq_r):
     43        (JSC::X86Assembler::cmpl_rr):
     44        (JSC::X86Assembler::cdq):
     45        (JSC::X86Assembler::cdqq):
     46        (JSC::X86Assembler::fstps):
     47        * b3/B3BasicBlock.cpp:
     48        (JSC::B3::BasicBlock::append):
     49        (JSC::B3::BasicBlock::replaceLast):
     50        (JSC::B3::BasicBlock::appendIntConstant):
     51        (JSC::B3::BasicBlock::replaceSuccessor):
     52        (JSC::B3::BasicBlock::addPredecessor):
     53        (JSC::B3::BasicBlock::replacePredecessor):
     54        (JSC::B3::BasicBlock::updatePredecessors):
     55        (JSC::B3::BasicBlock::dump):
     56        * b3/B3BasicBlock.h:
     57        (JSC::B3::BasicBlock::values):
     58        (JSC::B3::BasicBlock::numPredecessors):
     59        (JSC::B3::BasicBlock::predecessor):
     60        (JSC::B3::BasicBlock::frequency):
     61        * b3/B3BasicBlockInlines.h:
     62        (JSC::B3::BasicBlock::appendNew):
     63        (JSC::B3::BasicBlock::replaceLastWithNew):
     64        (JSC::B3::BasicBlock::numSuccessors):
     65        * b3/B3BasicBlockUtils.h:
     66        (JSC::B3::replacePredecessor):
     67        (JSC::B3::updatePredecessors):
     68        (JSC::B3::resetReachability):
     69        * b3/B3BlockInsertionSet.cpp: Added.
     70        (JSC::B3::BlockInsertionSet::BlockInsertionSet):
     71        (JSC::B3::BlockInsertionSet::~BlockInsertionSet):
     72        (JSC::B3::BlockInsertionSet::insert):
     73        (JSC::B3::BlockInsertionSet::insertBefore):
     74        (JSC::B3::BlockInsertionSet::splitForward):
     75        (JSC::B3::BlockInsertionSet::execute):
     76        * b3/B3BlockInsertionSet.h: Added.
     77        * b3/B3Common.h:
     78        (JSC::B3::isRepresentableAs):
     79        (JSC::B3::chillDiv):
     80        * b3/B3Const32Value.cpp:
     81        (JSC::B3::Const32Value::addConstant):
     82        (JSC::B3::Const32Value::subConstant):
     83        (JSC::B3::Const32Value::divConstant):
     84        (JSC::B3::Const32Value::bitAndConstant):
     85        (JSC::B3::Const32Value::bitOrConstant):
     86        (JSC::B3::Const32Value::bitXorConstant):
     87        (JSC::B3::Const32Value::shlConstant):
     88        (JSC::B3::Const32Value::sShrConstant):
     89        (JSC::B3::Const32Value::zShrConstant):
     90        (JSC::B3::Const32Value::equalConstant):
     91        (JSC::B3::Const32Value::notEqualConstant):
     92        (JSC::B3::Const32Value::lessThanConstant):
     93        (JSC::B3::Const32Value::greaterThanConstant):
     94        (JSC::B3::Const32Value::lessEqualConstant):
     95        (JSC::B3::Const32Value::greaterEqualConstant):
     96        (JSC::B3::Const32Value::aboveConstant):
     97        (JSC::B3::Const32Value::belowConstant):
     98        (JSC::B3::Const32Value::aboveEqualConstant):
     99        (JSC::B3::Const32Value::belowEqualConstant):
     100        * b3/B3Const32Value.h:
     101        * b3/B3Const64Value.cpp:
     102        (JSC::B3::Const64Value::addConstant):
     103        (JSC::B3::Const64Value::subConstant):
     104        (JSC::B3::Const64Value::divConstant):
     105        (JSC::B3::Const64Value::bitAndConstant):
     106        (JSC::B3::Const64Value::bitOrConstant):
     107        (JSC::B3::Const64Value::bitXorConstant):
     108        (JSC::B3::Const64Value::shlConstant):
     109        (JSC::B3::Const64Value::sShrConstant):
     110        (JSC::B3::Const64Value::zShrConstant):
     111        (JSC::B3::Const64Value::equalConstant):
     112        (JSC::B3::Const64Value::notEqualConstant):
     113        (JSC::B3::Const64Value::lessThanConstant):
     114        (JSC::B3::Const64Value::greaterThanConstant):
     115        (JSC::B3::Const64Value::lessEqualConstant):
     116        (JSC::B3::Const64Value::greaterEqualConstant):
     117        (JSC::B3::Const64Value::aboveConstant):
     118        (JSC::B3::Const64Value::belowConstant):
     119        (JSC::B3::Const64Value::aboveEqualConstant):
     120        (JSC::B3::Const64Value::belowEqualConstant):
     121        * b3/B3Const64Value.h:
     122        * b3/B3ConstDoubleValue.cpp:
     123        (JSC::B3::ConstDoubleValue::addConstant):
     124        (JSC::B3::ConstDoubleValue::subConstant):
     125        (JSC::B3::ConstDoubleValue::divConstant):
     126        (JSC::B3::ConstDoubleValue::equalConstant):
     127        (JSC::B3::ConstDoubleValue::notEqualConstant):
     128        (JSC::B3::ConstDoubleValue::lessThanConstant):
     129        (JSC::B3::ConstDoubleValue::greaterThanConstant):
     130        (JSC::B3::ConstDoubleValue::lessEqualConstant):
     131        (JSC::B3::ConstDoubleValue::greaterEqualConstant):
     132        * b3/B3ConstDoubleValue.h:
     133        * b3/B3ControlValue.cpp:
     134        (JSC::B3::ControlValue::~ControlValue):
     135        (JSC::B3::ControlValue::replaceSuccessor):
     136        (JSC::B3::ControlValue::convertToJump):
     137        * b3/B3ControlValue.h:
     138        * b3/B3Generate.cpp:
     139        (JSC::B3::generateToAir):
     140        * b3/B3GenericFrequentedBlock.h:
     141        (JSC::B3::GenericFrequentedBlock::block):
     142        (JSC::B3::GenericFrequentedBlock::frequency):
     143        (JSC::B3::GenericFrequentedBlock::dump):
     144        * b3/B3InsertionSet.cpp:
     145        (JSC::B3::InsertionSet::insertIntConstant):
     146        (JSC::B3::InsertionSet::execute):
     147        * b3/B3InsertionSet.h:
     148        * b3/B3LowerMacros.cpp: Added.
     149        (JSC::B3::lowerMacros):
     150        * b3/B3LowerMacros.h: Added.
     151        * b3/B3LowerToAir.cpp:
     152        (JSC::B3::Air::LowerToAir::lower):
     153        * b3/B3Opcode.h:
     154        * b3/B3Procedure.cpp:
     155        (JSC::B3::Procedure::addBlock):
     156        (JSC::B3::Procedure::addIntConstant):
     157        (JSC::B3::Procedure::addBoolConstant):
     158        (JSC::B3::Procedure::resetValueOwners):
     159        * b3/B3Procedure.h:
     160        (JSC::B3::Procedure::takeByproducts):
     161        * b3/B3ReduceStrength.cpp:
     162        * b3/B3Validate.cpp:
     163        * b3/B3Value.cpp:
     164        (JSC::B3::Value::addConstant):
     165        (JSC::B3::Value::subConstant):
     166        (JSC::B3::Value::divConstant):
     167        (JSC::B3::Value::bitAndConstant):
     168        (JSC::B3::Value::bitOrConstant):
     169        (JSC::B3::Value::bitXorConstant):
     170        (JSC::B3::Value::shlConstant):
     171        (JSC::B3::Value::sShrConstant):
     172        (JSC::B3::Value::zShrConstant):
     173        (JSC::B3::Value::equalConstant):
     174        (JSC::B3::Value::notEqualConstant):
     175        (JSC::B3::Value::lessThanConstant):
     176        (JSC::B3::Value::greaterThanConstant):
     177        (JSC::B3::Value::lessEqualConstant):
     178        (JSC::B3::Value::greaterEqualConstant):
     179        (JSC::B3::Value::aboveConstant):
     180        (JSC::B3::Value::belowConstant):
     181        (JSC::B3::Value::aboveEqualConstant):
     182        (JSC::B3::Value::belowEqualConstant):
     183        * b3/B3Value.h:
     184        * b3/air/AirGenerate.cpp:
     185        (JSC::B3::Air::generate):
     186        * b3/air/AirInstInlines.h:
     187        (JSC::B3::Air::isUrshift64Valid):
     188        (JSC::B3::Air::isX86DivHelperValid):
     189        (JSC::B3::Air::isX86ConvertToDoubleWord32Valid):
     190        (JSC::B3::Air::isX86ConvertToDoubleWord64Valid):
     191        (JSC::B3::Air::isX86Div32Valid):
     192        (JSC::B3::Air::isX86Div64Valid):
     193        * b3/air/AirOpcode.opcodes:
     194        * b3/air/AirSimplifyCFG.cpp:
     195        (JSC::B3::Air::simplifyCFG):
     196        * b3/testb3.cpp:
     197        (JSC::B3::testCallFunctionWithHellaDoubleArguments):
     198        (JSC::B3::testChillDiv):
     199        (JSC::B3::testChillDivTwice):
     200        (JSC::B3::testChillDiv64):
     201        (JSC::B3::run):
     202        * dfg/DFGBlockInsertionSet.h:
     203        * dfg/DFGSpeculativeJIT.cpp:
     204        (JSC::DFG::SpeculativeJIT::compileArithDiv):
     205        (JSC::DFG::SpeculativeJIT::compileArithMod):
     206        * jit/JITArithmetic.cpp:
     207        (JSC::JIT::emit_op_mod):
     208        * jit/JITArithmetic32_64.cpp:
     209        (JSC::JIT::emit_op_mod):
     210        * wasm/WASMFunctionCompiler.h:
     211        (JSC::WASMFunctionCompiler::buildBinaryI32):
     212
    12132015-11-10  Benjamin Poulain  <bpoulain@apple.com>
    2214
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r192292 r192295  
    301301                0F338E151BF0276C0013C88F /* B3ValueKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E091BF0276C0013C88F /* B3ValueKey.h */; };
    302302                0F338E161BF0276C0013C88F /* B3ValueKeyInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E0A1BF0276C0013C88F /* B3ValueKeyInlines.h */; };
     303                0F338E1B1BF286EA0013C88F /* B3BlockInsertionSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */; };
     304                0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */; };
     305                0F338E1D1BF286EA0013C88F /* B3LowerMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */; };
     306                0F338E1E1BF286EA0013C88F /* B3LowerMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */; };
    303307                0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
    304308                0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; };
     
    23442348                0F338E091BF0276C0013C88F /* B3ValueKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ValueKey.h; path = b3/B3ValueKey.h; sourceTree = "<group>"; };
    23452349                0F338E0A1BF0276C0013C88F /* B3ValueKeyInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ValueKeyInlines.h; path = b3/B3ValueKeyInlines.h; sourceTree = "<group>"; };
     2350                0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3BlockInsertionSet.cpp; path = b3/B3BlockInsertionSet.cpp; sourceTree = "<group>"; };
     2351                0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3BlockInsertionSet.h; path = b3/B3BlockInsertionSet.h; sourceTree = "<group>"; };
     2352                0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3LowerMacros.cpp; path = b3/B3LowerMacros.cpp; sourceTree = "<group>"; };
     2353                0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3LowerMacros.h; path = b3/B3LowerMacros.h; sourceTree = "<group>"; };
    23462354                0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = "<group>"; };
    23472355                0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = "<group>"; };
     
    44434451                                0FEC84B81BDACDAC0080FF74 /* B3BasicBlockInlines.h */,
    44444452                                0FEC84B91BDACDAC0080FF74 /* B3BasicBlockUtils.h */,
     4453                                0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */,
     4454                                0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */,
    44454455                                0FEC84BA1BDACDAC0080FF74 /* B3BlockWorklist.h */,
    44464456                                0F338DF71BE96AA80013C88F /* B3CCallValue.cpp */,
     
    44844494                                0FEC85B51BE1462F0080FF74 /* B3InsertionSet.h */,
    44854495                                0FEC85B61BE1462F0080FF74 /* B3InsertionSetInlines.h */,
     4496                                0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */,
     4497                                0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */,
    44864498                                0FEC84D31BDACDAC0080FF74 /* B3LowerToAir.cpp */,
    44874499                                0FEC84D41BDACDAC0080FF74 /* B3LowerToAir.h */,
     
    66816693                                0FEC853A1BDACDAC0080FF74 /* B3SwitchValue.h in Headers */,
    66826694                                0F4570411BE584CA0062A629 /* B3TimingScope.h in Headers */,
     6695                                0F338E1E1BF286EA0013C88F /* B3LowerMacros.h in Headers */,
    66836696                                0FEC853C1BDACDAC0080FF74 /* B3Type.h in Headers */,
    66846697                                0FEC853E1BDACDAC0080FF74 /* B3UpsilonValue.h in Headers */,
     
    67806793                                C218D1401655CFD50062BB81 /* CopyWorkList.h in Headers */,
    67816794                                C4F4B6F41A05C944005CAB76 /* cpp_generator.py in Headers */,
     6795                                0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */,
    67826796                                C4F4B6F31A05C944005CAB76 /* cpp_generator_templates.py in Headers */,
    67836797                                5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
     
    83258339                                14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */,
    83268340                                149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
     8341                                0F338E1D1BF286EA0013C88F /* B3LowerMacros.cpp in Sources */,
    83278342                                0F2D4DDD19832D34007D4B19 /* DebuggerScope.cpp in Sources */,
    83288343                                2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */,
     
    84978512                                0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
    84988513                                0FEA0A09170513DB00BB722C /* FTLCapabilities.cpp in Sources */,
     8514                                0F338E1B1BF286EA0013C88F /* B3BlockInsertionSet.cpp in Sources */,
    84998515                                0FEA0A271709623B00BB722C /* FTLCommonValues.cpp in Sources */,
    85008516                                0FEA0A0B170513DB00BB722C /* FTLCompile.cpp in Sources */,
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r192183 r192295  
    248248    }
    249249
     250    void x86ConvertToDoubleWord32()
     251    {
     252        m_assembler.cdq();
     253    }
     254
     255    void x86ConvertToDoubleWord32(RegisterID eax, RegisterID edx)
     256    {
     257        ASSERT_UNUSED(eax, eax == X86Registers::eax);
     258        ASSERT_UNUSED(edx, edx == X86Registers::edx);
     259        x86ConvertToDoubleWord32();
     260    }
     261
     262    void x86Div32(RegisterID denominator)
     263    {
     264        m_assembler.idivl_r(denominator);
     265    }
     266
     267    void x86Div32(RegisterID eax, RegisterID edx, RegisterID denominator)
     268    {
     269        ASSERT_UNUSED(eax, eax == X86Registers::eax);
     270        ASSERT_UNUSED(edx, edx == X86Registers::edx);
     271        x86Div32(denominator);
     272    }
     273
    250274    void neg32(RegisterID srcDest)
    251275    {
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r192267 r192295  
    387387    }
    388388   
     389    void x86ConvertToQuadWord64()
     390    {
     391        m_assembler.cqo();
     392    }
     393
     394    void x86ConvertToQuadWord64(RegisterID rax, RegisterID rdx)
     395    {
     396        ASSERT_UNUSED(rax, rax == X86Registers::eax);
     397        ASSERT_UNUSED(rdx, rdx == X86Registers::edx);
     398        x86ConvertToQuadWord64();
     399    }
     400
     401    void x86Div64(RegisterID denominator)
     402    {
     403        m_assembler.idivq_r(denominator);
     404    }
     405
     406    void x86Div64(RegisterID rax, RegisterID rdx, RegisterID denominator)
     407    {
     408        ASSERT_UNUSED(rax, rax == X86Registers::eax);
     409        ASSERT_UNUSED(rdx, rdx == X86Registers::edx);
     410        x86Div64(denominator);
     411    }
     412
    389413    void neg64(RegisterID dest)
    390414    {
  • trunk/Source/JavaScriptCore/assembler/X86Assembler.h

    r192267 r192295  
    963963    }
    964964
     965#if CPU(X86_64)
     966    void idivq_r(RegisterID dst)
     967    {
     968        m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
     969    }
     970#endif // CPU(X86_64)
     971
    965972    // Comparisons:
    966973
     
    12941301        m_formatter.oneByteOp(OP_CDQ);
    12951302    }
     1303
     1304#if CPU(X86_64)
     1305    void cqo()
     1306    {
     1307        m_formatter.oneByteOp64(OP_CDQ);
     1308    }
     1309#endif
    12961310
    12971311    void fstps(int offset, RegisterID base)
  • trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp

    r191865 r192295  
    2929#if ENABLE(B3_JIT)
    3030
     31#include "B3BasicBlockInlines.h"
    3132#include "B3BasicBlockUtils.h"
     33#include "B3ControlValue.h"
    3234#include "B3Procedure.h"
    33 #include "B3Value.h"
     35#include "B3ValueInlines.h"
    3436#include <wtf/ListDump.h>
    3537
     
    5355}
    5456
     57void BasicBlock::replaceLast(Procedure& proc, Value* value)
     58{
     59    proc.deleteValue(last());
     60    last() = value;
     61}
     62
     63Value* BasicBlock::appendIntConstant(Procedure& proc, Origin origin, Type type, int64_t value)
     64{
     65    Value* result = proc.addIntConstant(origin, type, value);
     66    append(result);
     67    return result;
     68}
     69
     70Value* BasicBlock::appendIntConstant(Procedure& proc, Value* likeValue, int64_t value)
     71{
     72    return appendIntConstant(proc, likeValue->origin(), likeValue->type(), value);
     73}
     74
     75bool BasicBlock::replaceSuccessor(BasicBlock* from, BasicBlock* to)
     76{
     77    return last()->as<ControlValue>()->replaceSuccessor(from, to);
     78}
     79
    5580bool BasicBlock::addPredecessor(BasicBlock* block)
    5681{
     
    6691{
    6792    return B3::replacePredecessor(this, from, to);
     93}
     94
     95void BasicBlock::updatePredecessorsAfter()
     96{
     97    B3::updatePredecessorsAfter(this);
    6898}
    6999
  • trunk/Source/JavaScriptCore/b3/B3BasicBlock.h

    r192121 r192295  
    3030
    3131#include "B3FrequentedBlock.h"
     32#include "B3Origin.h"
    3233#include "B3SuccessorCollection.h"
     34#include "B3Type.h"
    3335#include <wtf/Vector.h>
    3436
    3537namespace JSC { namespace B3 {
    3638
     39class BlockInsertionSet;
    3740class InsertionSet;
    3841class Procedure;
     
    6972
    7073    JS_EXPORT_PRIVATE void append(Value*);
     74    JS_EXPORT_PRIVATE void replaceLast(Procedure&, Value*);
    7175
    7276    template<typename ValueType, typename... Arguments>
    7377    ValueType* appendNew(Procedure&, Arguments...);
     78
     79    Value* appendIntConstant(Procedure&, Origin, Type, int64_t value);
     80    Value* appendIntConstant(Procedure&, Value* likeValue, int64_t value);
     81   
     82    template<typename ValueType, typename... Arguments>
     83    ValueType* replaceLastWithNew(Procedure&, Arguments...);
    7484
    7585    unsigned numSuccessors() const;
     
    8494    SuccessorCollection<const BasicBlock, const SuccessorList> successorBlocks() const;
    8595
     96    bool replaceSuccessor(BasicBlock* from, BasicBlock* to);
     97
    8698    unsigned numPredecessors() const { return m_predecessors.size(); }
    8799    BasicBlock* predecessor(unsigned index) const { return m_predecessors[index]; }
     
    95107    bool replacePredecessor(BasicBlock* from, BasicBlock* to);
    96108
     109    // Update predecessors starting with the successors of this block.
     110    void updatePredecessorsAfter();
     111
    97112    double frequency() const { return m_frequency; }
    98113
     
    101116
    102117private:
     118    friend class BlockInsertionSet;
    103119    friend class InsertionSet;
    104120    friend class Procedure;
  • trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h

    r191705 r192295  
    4040    ValueType* result = procedure.add<ValueType>(arguments...);
    4141    append(result);
     42    return result;
     43}
     44
     45template<typename ValueType, typename... Arguments>
     46ValueType* BasicBlock::replaceLastWithNew(Procedure& procedure, Arguments... arguments)
     47{
     48    ValueType* result = procedure.add<ValueType>(arguments...);
     49    replaceLast(procedure, result);
    4250    return result;
    4351}
  • trunk/Source/JavaScriptCore/b3/B3BasicBlockUtils.h

    r192121 r192295  
    7272}
    7373
     74template<typename BasicBlock>
     75void updatePredecessorsAfter(BasicBlock* root)
     76{
     77    Vector<BasicBlock*, 16> worklist;
     78    worklist.append(root);
     79    while (!worklist.isEmpty()) {
     80        BasicBlock* block = worklist.takeLast();
     81        for (BasicBlock* successor : block->successorBlocks()) {
     82            if (addPredecessor(successor, block))
     83                worklist.append(successor);
     84        }
     85    }
     86}
     87
    7488// This recomputes predecessors and removes blocks that aren't reachable.
    7589template<typename BasicBlock, typename DeleteFunctor>
     
    8397    }
    8498
    85     GraphNodeWorklist<BasicBlock*, IndexSet<BasicBlock>> worklist;
    86     worklist.push(blocks[0].get());
    87     while (BasicBlock* block = worklist.pop()) {
    88         for (BasicBlock* successor : block->successorBlocks()) {
    89             addPredecessor(successor, block);
    90             worklist.push(successor);
    91         }
    92     }
     99    updatePredecessorsAfter(blocks[0].get());
    93100
    94101    for (unsigned i = 1; i < blocks.size(); ++i) {
  • trunk/Source/JavaScriptCore/b3/B3Common.h

    r192183 r192295  
    9595}
    9696
     97inline int32_t chillDiv(int32_t num, int32_t den)
     98{
     99    if (!den)
     100        return 0;
     101    if (den == -1 && num == std::numeric_limits<int32_t>::min())
     102        return num;
     103    return num / den;
     104}
     105
     106inline int64_t chillDiv(int64_t num, int64_t den)
     107{
     108    if (!den)
     109        return 0;
     110    if (den == -1 && num == std::numeric_limits<int64_t>::min())
     111        return num;
     112    return num / den;
     113}
     114
    97115} } // namespace JSC::B3
    98116
  • trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp

    r192072 r192295  
    4848}
    4949
    50 Value* Const32Value::addConstant(Procedure& proc, Value* other) const
     50Value* Const32Value::addConstant(Procedure& proc, const Value* other) const
    5151{
    5252    if (!other->hasInt32())
     
    5555}
    5656
    57 Value* Const32Value::subConstant(Procedure& proc, Value* other) const
     57Value* Const32Value::subConstant(Procedure& proc, const Value* other) const
    5858{
    5959    if (!other->hasInt32())
     
    6262}
    6363
    64 Value* Const32Value::bitAndConstant(Procedure& proc, Value* other) const
     64Value* Const32Value::divConstant(Procedure& proc, const Value* other) const
     65{
     66    if (!other->hasInt32())
     67        return nullptr;
     68    return proc.add<Const32Value>(origin(), chillDiv(m_value, other->asInt32()));
     69}
     70
     71Value* Const32Value::bitAndConstant(Procedure& proc, const Value* other) const
    6572{
    6673    if (!other->hasInt32())
     
    6976}
    7077
    71 Value* Const32Value::bitOrConstant(Procedure& proc, Value* other) const
     78Value* Const32Value::bitOrConstant(Procedure& proc, const Value* other) const
    7279{
    7380    if (!other->hasInt32())
     
    7683}
    7784
    78 Value* Const32Value::bitXorConstant(Procedure& proc, Value* other) const
     85Value* Const32Value::bitXorConstant(Procedure& proc, const Value* other) const
    7986{
    8087    if (!other->hasInt32())
     
    8390}
    8491
    85 Value* Const32Value::shlConstant(Procedure& proc, Value* other) const
     92Value* Const32Value::shlConstant(Procedure& proc, const Value* other) const
    8693{
    8794    if (!other->hasInt32())
     
    9097}
    9198
    92 Value* Const32Value::sShrConstant(Procedure& proc, Value* other) const
     99Value* Const32Value::sShrConstant(Procedure& proc, const Value* other) const
    93100{
    94101    if (!other->hasInt32())
     
    97104}
    98105
    99 Value* Const32Value::zShrConstant(Procedure& proc, Value* other) const
     106Value* Const32Value::zShrConstant(Procedure& proc, const Value* other) const
    100107{
    101108    if (!other->hasInt32())
     
    104111}
    105112
    106 TriState Const32Value::equalConstant(Value* other) const
     113TriState Const32Value::equalConstant(const Value* other) const
    107114{
    108115    if (!other->hasInt32())
     
    111118}
    112119
    113 TriState Const32Value::notEqualConstant(Value* other) const
     120TriState Const32Value::notEqualConstant(const Value* other) const
    114121{
    115122    if (!other->hasInt32())
     
    118125}
    119126
    120 TriState Const32Value::lessThanConstant(Value* other) const
     127TriState Const32Value::lessThanConstant(const Value* other) const
    121128{
    122129    if (!other->hasInt32())
     
    125132}
    126133
    127 TriState Const32Value::greaterThanConstant(Value* other) const
     134TriState Const32Value::greaterThanConstant(const Value* other) const
    128135{
    129136    if (!other->hasInt32())
     
    132139}
    133140
    134 TriState Const32Value::lessEqualConstant(Value* other) const
     141TriState Const32Value::lessEqualConstant(const Value* other) const
    135142{
    136143    if (!other->hasInt32())
     
    139146}
    140147
    141 TriState Const32Value::greaterEqualConstant(Value* other) const
     148TriState Const32Value::greaterEqualConstant(const Value* other) const
    142149{
    143150    if (!other->hasInt32())
     
    146153}
    147154
    148 TriState Const32Value::aboveConstant(Value* other) const
     155TriState Const32Value::aboveConstant(const Value* other) const
    149156{
    150157    if (!other->hasInt32())
     
    153160}
    154161
    155 TriState Const32Value::belowConstant(Value* other) const
     162TriState Const32Value::belowConstant(const Value* other) const
    156163{
    157164    if (!other->hasInt32())
     
    160167}
    161168
    162 TriState Const32Value::aboveEqualConstant(Value* other) const
     169TriState Const32Value::aboveEqualConstant(const Value* other) const
    163170{
    164171    if (!other->hasInt32())
     
    167174}
    168175
    169 TriState Const32Value::belowEqualConstant(Value* other) const
     176TriState Const32Value::belowEqualConstant(const Value* other) const
    170177{
    171178    if (!other->hasInt32())
  • trunk/Source/JavaScriptCore/b3/B3Const32Value.h

    r192072 r192295  
    4343    Value* negConstant(Procedure&) const override;
    4444    Value* addConstant(Procedure&, int32_t other) const override;
    45     Value* addConstant(Procedure&, Value* other) const override;
    46     Value* subConstant(Procedure&, Value* other) const override;
    47     Value* bitAndConstant(Procedure&, Value* other) const override;
    48     Value* bitOrConstant(Procedure&, Value* other) const override;
    49     Value* bitXorConstant(Procedure&, Value* other) const override;
    50     Value* shlConstant(Procedure&, Value* other) const override;
    51     Value* sShrConstant(Procedure&, Value* other) const override;
    52     Value* zShrConstant(Procedure&, Value* other) const override;
     45    Value* addConstant(Procedure&, const Value* other) const override;
     46    Value* subConstant(Procedure&, const Value* other) const override;
     47    Value* divConstant(Procedure&, const Value* other) const override;
     48    Value* bitAndConstant(Procedure&, const Value* other) const override;
     49    Value* bitOrConstant(Procedure&, const Value* other) const override;
     50    Value* bitXorConstant(Procedure&, const Value* other) const override;
     51    Value* shlConstant(Procedure&, const Value* other) const override;
     52    Value* sShrConstant(Procedure&, const Value* other) const override;
     53    Value* zShrConstant(Procedure&, const Value* other) const override;
    5354
    54     TriState equalConstant(Value* other) const override;
    55     TriState notEqualConstant(Value* other) const override;
    56     TriState lessThanConstant(Value* other) const override;
    57     TriState greaterThanConstant(Value* other) const override;
    58     TriState lessEqualConstant(Value* other) const override;
    59     TriState greaterEqualConstant(Value* other) const override;
    60     TriState aboveConstant(Value* other) const override;
    61     TriState belowConstant(Value* other) const override;
    62     TriState aboveEqualConstant(Value* other) const override;
    63     TriState belowEqualConstant(Value* other) const override;
     55    TriState equalConstant(const Value* other) const override;
     56    TriState notEqualConstant(const Value* other) const override;
     57    TriState lessThanConstant(const Value* other) const override;
     58    TriState greaterThanConstant(const Value* other) const override;
     59    TriState lessEqualConstant(const Value* other) const override;
     60    TriState greaterEqualConstant(const Value* other) const override;
     61    TriState aboveConstant(const Value* other) const override;
     62    TriState belowConstant(const Value* other) const override;
     63    TriState aboveEqualConstant(const Value* other) const override;
     64    TriState belowEqualConstant(const Value* other) const override;
    6465
    6566protected:
  • trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp

    r192072 r192295  
    4848}
    4949
    50 Value* Const64Value::addConstant(Procedure& proc, Value* other) const
     50Value* Const64Value::addConstant(Procedure& proc, const Value* other) const
    5151{
    5252    if (!other->hasInt64())
     
    5555}
    5656
    57 Value* Const64Value::subConstant(Procedure& proc, Value* other) const
     57Value* Const64Value::subConstant(Procedure& proc, const Value* other) const
    5858{
    5959    if (!other->hasInt64())
     
    6262}
    6363
    64 Value* Const64Value::bitAndConstant(Procedure& proc, Value* other) const
     64Value* Const64Value::divConstant(Procedure& proc, const Value* other) const
     65{
     66    if (!other->hasInt64())
     67        return nullptr;
     68    return proc.add<Const64Value>(origin(), chillDiv(m_value, other->asInt64()));
     69}
     70
     71Value* Const64Value::bitAndConstant(Procedure& proc, const Value* other) const
    6572{
    6673    if (!other->hasInt64())
     
    6976}
    7077
    71 Value* Const64Value::bitOrConstant(Procedure& proc, Value* other) const
     78Value* Const64Value::bitOrConstant(Procedure& proc, const Value* other) const
    7279{
    7380    if (!other->hasInt64())
     
    7683}
    7784
    78 Value* Const64Value::bitXorConstant(Procedure& proc, Value* other) const
     85Value* Const64Value::bitXorConstant(Procedure& proc, const Value* other) const
    7986{
    8087    if (!other->hasInt64())
     
    8390}
    8491
    85 Value* Const64Value::shlConstant(Procedure& proc, Value* other) const
     92Value* Const64Value::shlConstant(Procedure& proc, const Value* other) const
    8693{
    8794    if (!other->hasInt32())
     
    9097}
    9198
    92 Value* Const64Value::sShrConstant(Procedure& proc, Value* other) const
     99Value* Const64Value::sShrConstant(Procedure& proc, const Value* other) const
    93100{
    94101    if (!other->hasInt32())
     
    97104}
    98105
    99 Value* Const64Value::zShrConstant(Procedure& proc, Value* other) const
     106Value* Const64Value::zShrConstant(Procedure& proc, const Value* other) const
    100107{
    101108    if (!other->hasInt32())
     
    104111}
    105112
    106 TriState Const64Value::equalConstant(Value* other) const
     113TriState Const64Value::equalConstant(const Value* other) const
    107114{
    108115    if (!other->hasInt64())
     
    111118}
    112119
    113 TriState Const64Value::notEqualConstant(Value* other) const
     120TriState Const64Value::notEqualConstant(const Value* other) const
    114121{
    115122    if (!other->hasInt64())
     
    118125}
    119126
    120 TriState Const64Value::lessThanConstant(Value* other) const
     127TriState Const64Value::lessThanConstant(const Value* other) const
    121128{
    122129    if (!other->hasInt64())
     
    125132}
    126133
    127 TriState Const64Value::greaterThanConstant(Value* other) const
     134TriState Const64Value::greaterThanConstant(const Value* other) const
    128135{
    129136    if (!other->hasInt64())
     
    132139}
    133140
    134 TriState Const64Value::lessEqualConstant(Value* other) const
     141TriState Const64Value::lessEqualConstant(const Value* other) const
    135142{
    136143    if (!other->hasInt64())
     
    139146}
    140147
    141 TriState Const64Value::greaterEqualConstant(Value* other) const
     148TriState Const64Value::greaterEqualConstant(const Value* other) const
    142149{
    143150    if (!other->hasInt64())
     
    146153}
    147154
    148 TriState Const64Value::aboveConstant(Value* other) const
     155TriState Const64Value::aboveConstant(const Value* other) const
    149156{
    150157    if (!other->hasInt64())
     
    153160}
    154161
    155 TriState Const64Value::belowConstant(Value* other) const
     162TriState Const64Value::belowConstant(const Value* other) const
    156163{
    157164    if (!other->hasInt64())
     
    160167}
    161168
    162 TriState Const64Value::aboveEqualConstant(Value* other) const
     169TriState Const64Value::aboveEqualConstant(const Value* other) const
    163170{
    164171    if (!other->hasInt64())
     
    167174}
    168175
    169 TriState Const64Value::belowEqualConstant(Value* other) const
     176TriState Const64Value::belowEqualConstant(const Value* other) const
    170177{
    171178    if (!other->hasInt64())
  • trunk/Source/JavaScriptCore/b3/B3Const64Value.h

    r192072 r192295  
    4343    Value* negConstant(Procedure&) const override;
    4444    Value* addConstant(Procedure&, int32_t other) const override;
    45     Value* addConstant(Procedure&, Value* other) const override;
    46     Value* subConstant(Procedure&, Value* other) const override;
    47     Value* bitAndConstant(Procedure&, Value* other) const override;
    48     Value* bitOrConstant(Procedure&, Value* other) const override;
    49     Value* bitXorConstant(Procedure&, Value* other) const override;
    50     Value* shlConstant(Procedure&, Value* other) const override;
    51     Value* sShrConstant(Procedure&, Value* other) const override;
    52     Value* zShrConstant(Procedure&, Value* other) const override;
     45    Value* addConstant(Procedure&, const Value* other) const override;
     46    Value* subConstant(Procedure&, const Value* other) const override;
     47    Value* divConstant(Procedure&, const Value* other) const override;
     48    Value* bitAndConstant(Procedure&, const Value* other) const override;
     49    Value* bitOrConstant(Procedure&, const Value* other) const override;
     50    Value* bitXorConstant(Procedure&, const Value* other) const override;
     51    Value* shlConstant(Procedure&, const Value* other) const override;
     52    Value* sShrConstant(Procedure&, const Value* other) const override;
     53    Value* zShrConstant(Procedure&, const Value* other) const override;
    5354
    54     TriState equalConstant(Value* other) const override;
    55     TriState notEqualConstant(Value* other) const override;
    56     TriState lessThanConstant(Value* other) const override;
    57     TriState greaterThanConstant(Value* other) const override;
    58     TriState lessEqualConstant(Value* other) const override;
    59     TriState greaterEqualConstant(Value* other) const override;
    60     TriState aboveConstant(Value* other) const override;
    61     TriState belowConstant(Value* other) const override;
    62     TriState aboveEqualConstant(Value* other) const override;
    63     TriState belowEqualConstant(Value* other) const override;
     55    TriState equalConstant(const Value* other) const override;
     56    TriState notEqualConstant(const Value* other) const override;
     57    TriState lessThanConstant(const Value* other) const override;
     58    TriState greaterThanConstant(const Value* other) const override;
     59    TriState lessEqualConstant(const Value* other) const override;
     60    TriState greaterEqualConstant(const Value* other) const override;
     61    TriState aboveConstant(const Value* other) const override;
     62    TriState belowConstant(const Value* other) const override;
     63    TriState aboveEqualConstant(const Value* other) const override;
     64    TriState belowEqualConstant(const Value* other) const override;
    6465
    6566protected:
  • trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp

    r192072 r192295  
    4848}
    4949
    50 Value* ConstDoubleValue::addConstant(Procedure& proc, Value* other) const
     50Value* ConstDoubleValue::addConstant(Procedure& proc, const Value* other) const
    5151{
    5252    if (!other->hasDouble())
     
    5555}
    5656
    57 Value* ConstDoubleValue::subConstant(Procedure& proc, Value* other) const
     57Value* ConstDoubleValue::subConstant(Procedure& proc, const Value* other) const
    5858{
    5959    if (!other->hasDouble())
     
    6262}
    6363
    64 TriState ConstDoubleValue::equalConstant(Value* other) const
     64Value* ConstDoubleValue::divConstant(Procedure& proc, const Value* other) const
     65{
     66    if (!other->hasDouble())
     67        return nullptr;
     68    return proc.add<ConstDoubleValue>(origin(), m_value / other->asDouble());
     69}
     70
     71TriState ConstDoubleValue::equalConstant(const Value* other) const
    6572{
    6673    if (!other->hasDouble())
     
    6976}
    7077
    71 TriState ConstDoubleValue::notEqualConstant(Value* other) const
     78TriState ConstDoubleValue::notEqualConstant(const Value* other) const
    7279{
    7380    if (!other->hasDouble())
     
    7683}
    7784
    78 TriState ConstDoubleValue::lessThanConstant(Value* other) const
     85TriState ConstDoubleValue::lessThanConstant(const Value* other) const
    7986{
    8087    if (!other->hasDouble())
     
    8390}
    8491
    85 TriState ConstDoubleValue::greaterThanConstant(Value* other) const
     92TriState ConstDoubleValue::greaterThanConstant(const Value* other) const
    8693{
    8794    if (!other->hasDouble())
     
    9097}
    9198
    92 TriState ConstDoubleValue::lessEqualConstant(Value* other) const
     99TriState ConstDoubleValue::lessEqualConstant(const Value* other) const
    93100{
    94101    if (!other->hasDouble())
     
    97104}
    98105
    99 TriState ConstDoubleValue::greaterEqualConstant(Value* other) const
     106TriState ConstDoubleValue::greaterEqualConstant(const Value* other) const
    100107{
    101108    if (!other->hasDouble())
  • trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h

    r192183 r192295  
    4141    double value() const { return m_value; }
    4242
    43     Value* negConstant(Procedure& proc) const override;
    44     Value* addConstant(Procedure& proc, int32_t other) const override;
    45     Value* addConstant(Procedure& proc, Value* other) const override;
    46     Value* subConstant(Procedure& proc, Value* other) const override;
     43    Value* negConstant(Procedure&) const override;
     44    Value* addConstant(Procedure&, int32_t other) const override;
     45    Value* addConstant(Procedure&, const Value* other) const override;
     46    Value* subConstant(Procedure&, const Value* other) const override;
     47    Value* divConstant(Procedure&, const Value* other) const override;
    4748
    48     TriState equalConstant(Value* other) const override;
    49     TriState notEqualConstant(Value* other) const override;
    50     TriState lessThanConstant(Value* other) const override;
    51     TriState greaterThanConstant(Value* other) const override;
    52     TriState lessEqualConstant(Value* other) const override;
    53     TriState greaterEqualConstant(Value* other) const override;
     49    TriState equalConstant(const Value* other) const override;
     50    TriState notEqualConstant(const Value* other) const override;
     51    TriState lessThanConstant(const Value* other) const override;
     52    TriState greaterThanConstant(const Value* other) const override;
     53    TriState lessEqualConstant(const Value* other) const override;
     54    TriState greaterEqualConstant(const Value* other) const override;
    5455
    5556protected:
  • trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp

    r191993 r192295  
    3737}
    3838
    39 void ControlValue::convertToJump(const FrequentedBlock& destination)
     39bool ControlValue::replaceSuccessor(BasicBlock* from, BasicBlock* to)
     40{
     41    bool result = false;
     42    for (FrequentedBlock& successor : m_successors) {
     43        if (successor.block() == from) {
     44            successor.block() = to;
     45            result = true;
     46
     47            // Keep looping because it's valid for a successor to be mentioned multiple times,
     48            // like if multiple switch cases have the same target.
     49        }
     50    }
     51    return result;
     52}
     53
     54void ControlValue::convertToJump(BasicBlock* destination)
    4055{
    4156    unsigned index = this->index();
     
    4560    this->ControlValue::~ControlValue();
    4661
    47     new (this) ControlValue(index, Jump, origin, destination);
     62    new (this) ControlValue(index, Jump, origin, FrequentedBlock(destination));
    4863
    4964    this->owner = owner;
  • trunk/Source/JavaScriptCore/b3/B3ControlValue.h

    r191994 r192295  
    6565    SuccessorList& successors() { return m_successors; }
    6666
     67    bool replaceSuccessor(BasicBlock* from, BasicBlock* to);
     68
    6769    const FrequentedBlock& taken() const
    6870    {
     
    8688    }
    8789
    88     void convertToJump(const FrequentedBlock& destination);
     90    void convertToJump(BasicBlock* destination);
    8991
    9092protected:
  • trunk/Source/JavaScriptCore/b3/B3Generate.cpp

    r192183 r192295  
    3333#include "AirInstInlines.h"
    3434#include "B3Common.h"
     35#include "B3LowerMacros.h"
    3536#include "B3LowerToAir.h"
    3637#include "B3MoveConstants.h"
     
    6768    }
    6869
     70    lowerMacros(procedure);
     71
    6972    reduceStrength(procedure);
    7073   
  • trunk/Source/JavaScriptCore/b3/B3GenericFrequentedBlock.h

    r191705 r192295  
    6666    BasicBlock*& block() { return m_block; }
    6767    FrequencyClass frequency() const { return m_frequency; }
     68    FrequencyClass& frequency() { return m_frequency; }
    6869
    6970    void dump(PrintStream& out) const
  • trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp

    r191960 r192295  
    3030
    3131#include "B3BasicBlock.h"
     32#include "B3ProcedureInlines.h"
     33#include "B3ValueInlines.h"
    3234#include <wtf/BubbleSort.h>
    3335
    3436namespace JSC { namespace B3 {
     37
     38Value* InsertionSet::insertIntConstant(size_t index, Origin origin, Type type, int64_t value)
     39{
     40    return insertValue(index, m_procedure.addIntConstant(origin, type, value));
     41}
     42
     43Value* InsertionSet::insertIntConstant(size_t index, Value* likeValue, int64_t value)
     44{
     45    return insertIntConstant(index, likeValue->origin(), likeValue->type(), value);
     46}
    3547
    3648void InsertionSet::execute(BasicBlock* block)
  • trunk/Source/JavaScriptCore/b3/B3InsertionSet.h

    r191705 r192295  
    2929#if ENABLE(B3_JIT)
    3030
     31#include "B3Origin.h"
     32#include "B3Type.h"
    3133#include <wtf/Insertion.h>
    3234#include <wtf/Vector.h>
     
    6365    Value* insert(size_t index, Arguments... arguments);
    6466
     67    Value* insertIntConstant(size_t index, Origin, Type, int64_t value);
     68    Value* insertIntConstant(size_t index, Value* likeValue, int64_t value);
     69
    6570    void execute(BasicBlock*);
    6671
  • trunk/Source/JavaScriptCore/b3/B3LowerMacros.h

    r192294 r192295  
    2424 */
    2525
    26 #include "config.h"
    27 #include "B3InsertionSet.h"
     26#ifndef B3LowerMacros_h
     27#define B3LowerMacros_h
    2828
    2929#if ENABLE(B3_JIT)
    3030
    31 #include "B3BasicBlock.h"
    32 #include <wtf/BubbleSort.h>
    33 
    3431namespace JSC { namespace B3 {
    3532
    36 void InsertionSet::execute(BasicBlock* block)
    37 {
    38     bubbleSort(m_insertions.begin(), m_insertions.end());
    39     executeInsertions(block->m_values, m_insertions);
    40 }
     33class Procedure;
     34
     35// Lowers high-level operations that it's easier to deal with once they are broken up. Currently
     36// this includes Switch and ChillDiv.
     37
     38bool lowerMacros(Procedure&);
    4139
    4240} } // namespace JSC::B3
     
    4442#endif // ENABLE(B3_JIT)
    4543
     44#endif // B3LowerMacros_h
     45
  • trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp

    r192255 r192295  
    12341234        }
    12351235
     1236        case Div: {
     1237            if (isInt(m_value->type())) {
     1238                Tmp eax = Tmp(X86Registers::eax);
     1239                Tmp edx = Tmp(X86Registers::edx);
     1240
     1241                Air::Opcode convertToDoubleWord;
     1242                Air::Opcode div;
     1243                switch (m_value->type()) {
     1244                case Int32:
     1245                    convertToDoubleWord = X86ConvertToDoubleWord32;
     1246                    div = X86Div32;
     1247                    break;
     1248                case Int64:
     1249                    convertToDoubleWord = X86ConvertToQuadWord64;
     1250                    div = X86Div64;
     1251                    break;
     1252                default:
     1253                    RELEASE_ASSERT_NOT_REACHED();
     1254                    return;
     1255                }
     1256               
     1257                append(Move, tmp(m_value->child(0)), eax);
     1258                append(convertToDoubleWord, eax, edx);
     1259                append(div, eax, edx, tmp(m_value->child(1)));
     1260                append(Move, eax, tmp(m_value));
     1261                return;
     1262            }
     1263
     1264            // FIXME: Support doubles.
     1265            // https://bugs.webkit.org/show_bug.cgi?id=150991
     1266            RELEASE_ASSERT_NOT_REACHED();
     1267            return;
     1268        }
     1269
    12361270        case BitAnd: {
    12371271            appendBinOp<And32, And64, Air::Oops, Commutative>(
  • trunk/Source/JavaScriptCore/b3/B3Opcode.h

    r192187 r192295  
    7070    Sub,
    7171    Mul,
    72     Div,
     72    Div, // All bets are off as to what will happen when you execute this for -2^31/-1 and x/0.
    7373
    7474    // Integer math.
  • trunk/Source/JavaScriptCore/b3/B3Procedure.cpp

    r192183 r192295  
    5656}
    5757
    58 Value* Procedure::addIntConstant(Type type, int64_t value)
     58Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
    5959{
    6060    switch (type) {
    6161    case Int32:
    62         return add<Const32Value>(Origin(), static_cast<int32_t>(value));
     62        return add<Const32Value>(origin, static_cast<int32_t>(value));
    6363    case Int64:
    64         return add<Const64Value>(Origin(), value);
     64        return add<Const64Value>(origin, value);
    6565    case Double:
    66         return add<ConstDoubleValue>(Origin(), static_cast<double>(value));
     66        return add<ConstDoubleValue>(origin, static_cast<double>(value));
    6767    default:
    6868        RELEASE_ASSERT_NOT_REACHED();
     
    7171}
    7272
    73 Value* Procedure::addBoolConstant(TriState triState)
     73Value* Procedure::addIntConstant(Value* likeValue, int64_t value)
     74{
     75    return addIntConstant(likeValue->origin(), likeValue->type(), value);
     76}
     77
     78Value* Procedure::addBoolConstant(Origin origin, TriState triState)
    7479{
    7580    int32_t value = 0;
     
    8590    }
    8691
    87     return addIntConstant(Int32, value);
     92    return addIntConstant(origin, Int32, value);
    8893}
    8994
  • trunk/Source/JavaScriptCore/b3/B3Procedure.h

    r192183 r192295  
    2929#if ENABLE(B3_JIT)
    3030
     31#include "B3Origin.h"
    3132#include "B3Type.h"
    3233#include "PureNaN.h"
     
    4142
    4243class BasicBlock;
     44class BlockInsertionSet;
    4345class OpaqueByproducts;
    4446class Value;
     
    5759    ValueType* add(Arguments...);
    5860
    59     Value* addIntConstant(Type, int64_t value);
     61    Value* addIntConstant(Origin, Type, int64_t value);
     62    Value* addIntConstant(Value*, int64_t value);
    6063
    6164    // Returns null for MixedTriState.
    62     Value* addBoolConstant(TriState);
     65    Value* addBoolConstant(Origin, TriState);
    6366
    6467    void resetValueOwners();
     
    217220
    218221private:
     222    friend class BlockInsertionSet;
     223   
    219224    JS_EXPORT_PRIVATE size_t addValueIndex();
    220225   
  • trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp

    r192121 r192295  
    187187            break;
    188188
     189        case Div:
     190        case ChillDiv:
     191            // Turn this: Div(constant1, constant2)
     192            // Into this: constant1 / constant2
     193            // Note that this uses ChillDiv semantics. That's fine, because the rules for Div
     194            // are strictly weaker: it has corner cases where it's allowed to do anything it
     195            // likes.
     196            replaceWithNewValue(m_value->child(0)->divConstant(m_proc, m_value->child(1)));
     197            break;
     198
    189199        case BitAnd:
    190200            handleCommutativity();
     
    319329            // Into this: zero-constant.
    320330            if (m_value->child(0) == m_value->child(1)) {
    321                 replaceWithNewValue(m_proc.addIntConstant(m_value->type(), 0));
     331                replaceWithNewValue(m_proc.addIntConstant(m_value, 0));
    322332                break;
    323333            }
     
    447457            // Into this: const1 == const2
    448458            replaceWithNewValue(
    449                 m_proc.addBoolConstant(m_value->child(0)->equalConstant(m_value->child(1))));
     459                m_proc.addBoolConstant(
     460                    m_value->origin(),
     461                    m_value->child(0)->equalConstant(m_value->child(1))));
    450462            break;
    451463           
     
    474486            // Into this: const1 != const2
    475487            replaceWithNewValue(
    476                 m_proc.addBoolConstant(m_value->child(0)->notEqualConstant(m_value->child(1))));
     488                m_proc.addBoolConstant(
     489                    m_value->origin(),
     490                    m_value->child(0)->notEqualConstant(m_value->child(1))));
    477491            break;
    478492
     
    482496
    483497            replaceWithNewValue(
    484                 m_proc.addBoolConstant(m_value->child(0)->lessThanConstant(m_value->child(1))));
     498                m_proc.addBoolConstant(
     499                    m_value->origin(),
     500                    m_value->child(0)->lessThanConstant(m_value->child(1))));
    485501            break;
    486502
    487503        case GreaterThan:
    488504            replaceWithNewValue(
    489                 m_proc.addBoolConstant(m_value->child(0)->greaterThanConstant(m_value->child(1))));
     505                m_proc.addBoolConstant(
     506                    m_value->origin(),
     507                    m_value->child(0)->greaterThanConstant(m_value->child(1))));
    490508            break;
    491509
    492510        case LessEqual:
    493511            replaceWithNewValue(
    494                 m_proc.addBoolConstant(m_value->child(0)->lessEqualConstant(m_value->child(1))));
     512                m_proc.addBoolConstant(
     513                    m_value->origin(),
     514                    m_value->child(0)->lessEqualConstant(m_value->child(1))));
    495515            break;
    496516
    497517        case GreaterEqual:
    498518            replaceWithNewValue(
    499                 m_proc.addBoolConstant(m_value->child(0)->greaterEqualConstant(m_value->child(1))));
     519                m_proc.addBoolConstant(
     520                    m_value->origin(),
     521                    m_value->child(0)->greaterEqualConstant(m_value->child(1))));
    500522            break;
    501523
    502524        case Above:
    503525            replaceWithNewValue(
    504                 m_proc.addBoolConstant(m_value->child(0)->aboveConstant(m_value->child(1))));
     526                m_proc.addBoolConstant(
     527                    m_value->origin(),
     528                    m_value->child(0)->aboveConstant(m_value->child(1))));
    505529            break;
    506530
    507531        case Below:
    508532            replaceWithNewValue(
    509                 m_proc.addBoolConstant(m_value->child(0)->belowConstant(m_value->child(1))));
     533                m_proc.addBoolConstant(
     534                    m_value->origin(),
     535                    m_value->child(0)->belowConstant(m_value->child(1))));
    510536            break;
    511537
    512538        case AboveEqual:
    513539            replaceWithNewValue(
    514                 m_proc.addBoolConstant(m_value->child(0)->aboveEqualConstant(m_value->child(1))));
     540                m_proc.addBoolConstant(
     541                    m_value->origin(),
     542                    m_value->child(0)->aboveEqualConstant(m_value->child(1))));
    515543            break;
    516544
    517545        case BelowEqual:
    518546            replaceWithNewValue(
    519                 m_proc.addBoolConstant(m_value->child(0)->belowEqualConstant(m_value->child(1))));
     547                m_proc.addBoolConstant(
     548                    m_value->origin(),
     549                    m_value->child(0)->belowEqualConstant(m_value->child(1))));
    520550            break;
    521551
     
    554584            if (triState == FalseTriState) {
    555585                branch->taken().block()->removePredecessor(m_block);
    556                 branch->convertToJump(branch->notTaken());
     586                branch->convertToJump(branch->notTaken().block());
    557587                m_changedCFG = true;
    558588                break;
     
    563593            if (triState == TrueTriState) {
    564594                branch->notTaken().block()->removePredecessor(m_block);
    565                 branch->convertToJump(branch->taken());
     595                branch->convertToJump(branch->taken().block());
    566596                m_changedCFG = true;
    567597                break;
     
    632662    void simplifyCFG()
    633663    {
     664        if (verbose) {
     665            dataLog("Before simplifyCFG:\n");
     666            dataLog(m_proc);
     667        }
     668       
    634669        // We have three easy simplification rules:
    635670        //
     
    652687
    653688        for (BasicBlock* block : m_proc) {
     689            if (verbose)
     690                dataLog("Considering block ", *block, ":\n");
     691
    654692            checkPredecessorValidity();
    655693
     
    665703                    BasicBlock* newSuccessor = successor->successorBlock(0);
    666704                    if (newSuccessor != successor) {
    667                         newSuccessor->replacePredecessor(successor, block);
     705                        if (verbose) {
     706                            dataLog(
     707                                "Replacing ", pointerDump(block), "->", pointerDump(successor),
     708                                " with ", pointerDump(block), "->", pointerDump(newSuccessor),
     709                                "\n");
     710                        }
     711                        // Note that we do not do replacePredecessor() because the block we're
     712                        // skipping will still have newSuccessor as its successor.
     713                        newSuccessor->addPredecessor(block);
    668714                        successor = newSuccessor;
    669715                        m_changedCFG = true;
     
    680726                    // All of the successors must be the same.
    681727                    bool allSame = true;
    682                     FrequentedBlock firstSuccessor = block->successor(0);
     728                    BasicBlock* firstSuccessor = block->successorBlock(0);
    683729                    for (unsigned i = 1; i < block->numSuccessors(); ++i) {
    684                         if (block->successorBlock(i) != firstSuccessor.block()) {
     730                        if (block->successorBlock(i) != firstSuccessor) {
    685731                            allSame = false;
    686732                            break;
     
    688734                    }
    689735                    if (allSame) {
     736                        if (verbose) {
     737                            dataLog(
     738                                "Changing ", pointerDump(block), "'s terminal to a Jump.\n");
     739                        }
    690740                        block->last()->as<ControlValue>()->convertToJump(firstSuccessor);
    691741                        m_changedCFG = true;
     
    720770                    for (BasicBlock* newSuccessor : block->successorBlocks())
    721771                        newSuccessor->replacePredecessor(successor, block);
     772
     773                    if (verbose) {
     774                        dataLog(
     775                            "Merged ", pointerDump(block), "->", pointerDump(successor), "\n");
     776                    }
     777                   
    722778                    m_changedCFG = true;
    723779                }
  • trunk/Source/JavaScriptCore/b3/B3Validate.cpp

    r192072 r192295  
    8181
    8282        for (Value* value : valueInProc) {
    83             for (Value* child : value->children())
     83            for (Value* child : value->children()) {
     84                VALIDATE(child, ("At ", *value));
    8485                VALIDATE(valueInProc.contains(child), ("At ", *value, "->", pointerDump(child)));
     86            }
    8587        }
    8688
  • trunk/Source/JavaScriptCore/b3/B3Value.cpp

    r192183 r192295  
    125125}
    126126
    127 Value* Value::addConstant(Procedure&, Value*) const
    128 {
    129     return nullptr;
    130 }
    131 
    132 Value* Value::subConstant(Procedure&, Value*) const
    133 {
    134     return nullptr;
    135 }
    136 
    137 Value* Value::bitAndConstant(Procedure&, Value*) const
    138 {
    139     return nullptr;
    140 }
    141 
    142 Value* Value::bitOrConstant(Procedure&, Value*) const
    143 {
    144     return nullptr;
    145 }
    146 
    147 Value* Value::bitXorConstant(Procedure&, Value*) const
    148 {
    149     return nullptr;
    150 }
    151 
    152 Value* Value::shlConstant(Procedure&, Value*) const
    153 {
    154     return nullptr;
    155 }
    156 
    157 Value* Value::sShrConstant(Procedure&, Value*) const
    158 {
    159     return nullptr;
    160 }
    161 
    162 Value* Value::zShrConstant(Procedure&, Value*) const
    163 {
    164     return nullptr;
    165 }
    166 
    167 TriState Value::equalConstant(Value*) const
    168 {
    169     return MixedTriState;
    170 }
    171 
    172 TriState Value::notEqualConstant(Value*) const
    173 {
    174     return MixedTriState;
    175 }
    176 
    177 TriState Value::lessThanConstant(Value*) const
    178 {
    179     return MixedTriState;
    180 }
    181 
    182 TriState Value::greaterThanConstant(Value*) const
    183 {
    184     return MixedTriState;
    185 }
    186 
    187 TriState Value::lessEqualConstant(Value*) const
    188 {
    189     return MixedTriState;
    190 }
    191 
    192 TriState Value::greaterEqualConstant(Value*) const
    193 {
    194     return MixedTriState;
    195 }
    196 
    197 TriState Value::aboveConstant(Value*) const
    198 {
    199     return MixedTriState;
    200 }
    201 
    202 TriState Value::belowConstant(Value*) const
    203 {
    204     return MixedTriState;
    205 }
    206 
    207 TriState Value::aboveEqualConstant(Value*) const
    208 {
    209     return MixedTriState;
    210 }
    211 
    212 TriState Value::belowEqualConstant(Value*) const
     127Value* Value::addConstant(Procedure&, const Value*) const
     128{
     129    return nullptr;
     130}
     131
     132Value* Value::subConstant(Procedure&, const Value*) const
     133{
     134    return nullptr;
     135}
     136
     137Value* Value::divConstant(Procedure&, const Value*) const
     138{
     139    return nullptr;
     140}
     141
     142Value* Value::bitAndConstant(Procedure&, const Value*) const
     143{
     144    return nullptr;
     145}
     146
     147Value* Value::bitOrConstant(Procedure&, const Value*) const
     148{
     149    return nullptr;
     150}
     151
     152Value* Value::bitXorConstant(Procedure&, const Value*) const
     153{
     154    return nullptr;
     155}
     156
     157Value* Value::shlConstant(Procedure&, const Value*) const
     158{
     159    return nullptr;
     160}
     161
     162Value* Value::sShrConstant(Procedure&, const Value*) const
     163{
     164    return nullptr;
     165}
     166
     167Value* Value::zShrConstant(Procedure&, const Value*) const
     168{
     169    return nullptr;
     170}
     171
     172TriState Value::equalConstant(const Value*) const
     173{
     174    return MixedTriState;
     175}
     176
     177TriState Value::notEqualConstant(const Value*) const
     178{
     179    return MixedTriState;
     180}
     181
     182TriState Value::lessThanConstant(const Value*) const
     183{
     184    return MixedTriState;
     185}
     186
     187TriState Value::greaterThanConstant(const Value*) const
     188{
     189    return MixedTriState;
     190}
     191
     192TriState Value::lessEqualConstant(const Value*) const
     193{
     194    return MixedTriState;
     195}
     196
     197TriState Value::greaterEqualConstant(const Value*) const
     198{
     199    return MixedTriState;
     200}
     201
     202TriState Value::aboveConstant(const Value*) const
     203{
     204    return MixedTriState;
     205}
     206
     207TriState Value::belowConstant(const Value*) const
     208{
     209    return MixedTriState;
     210}
     211
     212TriState Value::aboveEqualConstant(const Value*) const
     213{
     214    return MixedTriState;
     215}
     216
     217TriState Value::belowEqualConstant(const Value*) const
    213218{
    214219    return MixedTriState;
  • trunk/Source/JavaScriptCore/b3/B3Value.h

    r192183 r192295  
    112112    virtual Value* negConstant(Procedure&) const;
    113113    virtual Value* addConstant(Procedure&, int32_t other) const;
    114     virtual Value* addConstant(Procedure&, Value* other) const;
    115     virtual Value* subConstant(Procedure&, Value* other) const;
    116     virtual Value* bitAndConstant(Procedure&, Value* other) const;
    117     virtual Value* bitOrConstant(Procedure&, Value* other) const;
    118     virtual Value* bitXorConstant(Procedure&, Value* other) const;
    119     virtual Value* shlConstant(Procedure&, Value* other) const;
    120     virtual Value* sShrConstant(Procedure&, Value* other) const;
    121     virtual Value* zShrConstant(Procedure&, Value* other) const;
    122    
    123     virtual TriState equalConstant(Value* other) const;
    124     virtual TriState notEqualConstant(Value* other) const;
    125     virtual TriState lessThanConstant(Value* other) const;
    126     virtual TriState greaterThanConstant(Value* other) const;
    127     virtual TriState lessEqualConstant(Value* other) const;
    128     virtual TriState greaterEqualConstant(Value* other) const;
    129     virtual TriState aboveConstant(Value* other) const;
    130     virtual TriState belowConstant(Value* other) const;
    131     virtual TriState aboveEqualConstant(Value* other) const;
    132     virtual TriState belowEqualConstant(Value* other) const;
     114    virtual Value* addConstant(Procedure&, const Value* other) const;
     115    virtual Value* subConstant(Procedure&, const Value* other) const;
     116    virtual Value* divConstant(Procedure&, const Value* other) const; // This chooses ChillDiv semantics for integers.
     117    virtual Value* bitAndConstant(Procedure&, const Value* other) const;
     118    virtual Value* bitOrConstant(Procedure&, const Value* other) const;
     119    virtual Value* bitXorConstant(Procedure&, const Value* other) const;
     120    virtual Value* shlConstant(Procedure&, const Value* other) const;
     121    virtual Value* sShrConstant(Procedure&, const Value* other) const;
     122    virtual Value* zShrConstant(Procedure&, const Value* other) const;
     123   
     124    virtual TriState equalConstant(const Value* other) const;
     125    virtual TriState notEqualConstant(const Value* other) const;
     126    virtual TriState lessThanConstant(const Value* other) const;
     127    virtual TriState greaterThanConstant(const Value* other) const;
     128    virtual TriState lessEqualConstant(const Value* other) const;
     129    virtual TriState greaterEqualConstant(const Value* other) const;
     130    virtual TriState aboveConstant(const Value* other) const;
     131    virtual TriState belowConstant(const Value* other) const;
     132    virtual TriState aboveEqualConstant(const Value* other) const;
     133    virtual TriState belowEqualConstant(const Value* other) const;
    133134
    134135    // If the value is a comparison then this returns the inverted form of that comparison, if
  • trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp

    r192292 r192295  
    122122    for (BasicBlock* block : code) {
    123123        blockJumps[block].link(&jit);
     124        blockLabels[block] = jit.label();
    124125        ASSERT(block->size() >= 1);
    125126        for (unsigned i = 0; i < block->size() - 1; ++i) {
     
    141142       
    142143        CCallHelpers::Jump jump = block->last().generate(jit, context);
    143         for (Inst& inst : *block)
    144             jump = inst.generate(jit, context);
    145144        switch (block->numSuccessors()) {
    146145        case 0:
  • trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h

    r192292 r192295  
    136136}
    137137
     138inline bool isX86DivHelperValid(const Inst& inst)
     139{
     140#if CPU(X86) || CPU(X86_64)
     141    return inst.args[0] == Tmp(X86Registers::eax)
     142        && inst.args[1] == Tmp(X86Registers::edx);
     143#else
     144    return false;
     145#endif
     146}
     147
     148inline bool isX86ConvertToDoubleWord32Valid(const Inst& inst)
     149{
     150    return isX86DivHelperValid(inst);
     151}
     152
     153inline bool isX86ConvertToQuadWord64Valid(const Inst& inst)
     154{
     155    return isX86DivHelperValid(inst);
     156}
     157
     158inline bool isX86Div32Valid(const Inst& inst)
     159{
     160    return isX86DivHelperValid(inst);
     161}
     162
     163inline bool isX86Div64Valid(const Inst& inst)
     164{
     165    return isX86DivHelperValid(inst);
     166}
     167
    138168} } } // namespace JSC::B3::Air
    139169
  • trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes

    r192183 r192295  
    9797    Tmp
    9898
     99Mul32 U:G, UD:G
     100    Tmp, Tmp
     101    Addr, Tmp
     102
     103X86ConvertToDoubleWord32 U:G, D:G
     104    Tmp*, Tmp*
     105
     106X86ConvertToQuadWord64 U:G, D:G
     107    Tmp*, Tmp*
     108
     109X86Div32 UD:G, UD:G, U:G
     110    Tmp*, Tmp*, Tmp
     111
     112X86Div64 UD:G, UD:G, U:G
     113    Tmp*, Tmp*, Tmp
     114
    99115Lea UA:G, D:G
    100116    Addr, Tmp
     
    157173    Tmp, Addr
    158174    Imm, Tmp
    159 
    160 Mul32 U:G, UD:G
    161     Tmp, Tmp
    162     Addr, Tmp
    163175
    164176# Note that Move operates over the full register size, which is either 32-bit or 64-bit depending on
  • trunk/Source/JavaScriptCore/b3/air/AirSimplifyCFG.cpp

    r192121 r192295  
    8787                                " with ", pointerDump(block), "->", pointerDump(newSuccessor), "\n");
    8888                        }
    89                         newSuccessor->replacePredecessor(successor, block);
     89                        // Note that we do not do replacePredecessor() because the block we're
     90                        // skipping will still have newSuccessor as its successor.
     91                        newSuccessor->addPredecessor(block);
    9092                        successor = newSuccessor;
    9193                        changed = true;
     
    113115                        block->last() = Inst(Jump, block->last().origin);
    114116                        block->successors().resize(1);
     117                        block->successors()[0].frequency() = FrequencyClass::Normal;
    115118                        changed = true;
    116119                    }
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r192292 r192295  
    28582858
    28592859    CHECK(compileAndRun<double>(proc) == functionWithHellaDoubleArguments(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26));
     2860}
     2861
     2862void testChillDiv(int num, int den, int res)
     2863{
     2864    // Test non-constant.
     2865    {
     2866        Procedure proc;
     2867        BasicBlock* root = proc.addBlock();
     2868       
     2869        root->appendNew<ControlValue>(
     2870            proc, Return, Origin(),
     2871            root->appendNew<Value>(
     2872                proc, ChillDiv, Origin(),
     2873                root->appendNew<Value>(
     2874                    proc, Trunc, Origin(),
     2875                    root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
     2876                root->appendNew<Value>(
     2877                    proc, Trunc, Origin(),
     2878                    root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
     2879
     2880        CHECK(compileAndRun<int>(proc, num, den) == res);
     2881    }
     2882
     2883    // Test constant.
     2884    {
     2885        Procedure proc;
     2886        BasicBlock* root = proc.addBlock();
     2887       
     2888        root->appendNew<ControlValue>(
     2889            proc, Return, Origin(),
     2890            root->appendNew<Value>(
     2891                proc, ChillDiv, Origin(),
     2892                root->appendNew<Const32Value>(proc, Origin(), num),
     2893                root->appendNew<Const32Value>(proc, Origin(), den)));
     2894       
     2895        CHECK(compileAndRun<int>(proc) == res);
     2896    }
     2897}
     2898
     2899void testChillDivTwice(int num1, int den1, int num2, int den2, int res)
     2900{
     2901    Procedure proc;
     2902    BasicBlock* root = proc.addBlock();
     2903
     2904    root->appendNew<ControlValue>(
     2905        proc, Return, Origin(),
     2906        root->appendNew<Value>(
     2907            proc, Add, Origin(),
     2908            root->appendNew<Value>(
     2909                proc, ChillDiv, Origin(),
     2910                root->appendNew<Value>(
     2911                    proc, Trunc, Origin(),
     2912                    root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
     2913                root->appendNew<Value>(
     2914                    proc, Trunc, Origin(),
     2915                    root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))),
     2916            root->appendNew<Value>(
     2917                proc, ChillDiv, Origin(),
     2918                root->appendNew<Value>(
     2919                    proc, Trunc, Origin(),
     2920                    root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)),
     2921                root->appendNew<Value>(
     2922                    proc, Trunc, Origin(),
     2923                    root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)))));
     2924   
     2925    CHECK(compileAndRun<int>(proc, num1, den1, num2, den2) == res);
     2926}
     2927
     2928void testChillDiv64(int64_t num, int64_t den, int64_t res)
     2929{
     2930    if (!is64Bit())
     2931        return;
     2932
     2933    // Test non-constant.
     2934    {
     2935        Procedure proc;
     2936        BasicBlock* root = proc.addBlock();
     2937       
     2938        root->appendNew<ControlValue>(
     2939            proc, Return, Origin(),
     2940            root->appendNew<Value>(
     2941                proc, ChillDiv, Origin(),
     2942                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
     2943                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
     2944       
     2945        CHECK(compileAndRun<int64_t>(proc, num, den) == res);
     2946    }
     2947
     2948    // Test constant.
     2949    {
     2950        Procedure proc;
     2951        BasicBlock* root = proc.addBlock();
     2952       
     2953        root->appendNew<ControlValue>(
     2954            proc, Return, Origin(),
     2955            root->appendNew<Value>(
     2956                proc, ChillDiv, Origin(),
     2957                root->appendNew<Const64Value>(proc, Origin(), num),
     2958                root->appendNew<Const64Value>(proc, Origin(), den)));
     2959       
     2960        CHECK(compileAndRun<int64_t>(proc) == res);
     2961    }
    28602962}
    28612963
     
    33383440    RUN(testCallFunctionWithHellaDoubleArguments());
    33393441
     3442    RUN(testChillDiv(4, 2, 2));
     3443    RUN(testChillDiv(1, 0, 0));
     3444    RUN(testChillDiv(0, 0, 0));
     3445    RUN(testChillDiv(1, -1, -1));
     3446    RUN(testChillDiv(-2147483647 - 1, 0, 0));
     3447    RUN(testChillDiv(-2147483647 - 1, 1, -2147483647 - 1));
     3448    RUN(testChillDiv(-2147483647 - 1, -1, -2147483647 - 1));
     3449    RUN(testChillDiv(-2147483647 - 1, 2, -1073741824));
     3450    RUN(testChillDiv64(4, 2, 2));
     3451    RUN(testChillDiv64(1, 0, 0));
     3452    RUN(testChillDiv64(0, 0, 0));
     3453    RUN(testChillDiv64(1, -1, -1));
     3454    RUN(testChillDiv64(-9223372036854775807ll - 1, 0, 0));
     3455    RUN(testChillDiv64(-9223372036854775807ll - 1, 1, -9223372036854775807ll - 1));
     3456    RUN(testChillDiv64(-9223372036854775807ll - 1, -1, -9223372036854775807ll - 1));
     3457    RUN(testChillDiv64(-9223372036854775807ll - 1, 2, -4611686018427387904));
     3458    RUN(testChillDivTwice(4, 2, 6, 2, 5));
     3459    RUN(testChillDivTwice(4, 0, 6, 2, 3));
     3460    RUN(testChillDivTwice(4, 2, 6, 0, 2));
     3461
    33403462    if (tasks.isEmpty())
    33413463        usage();
  • trunk/Source/JavaScriptCore/dfg/DFGBlockInsertionSet.h

    r169040 r192295  
    4646    BasicBlock* insert(size_t index, float executionCount);
    4747    BasicBlock* insertBefore(BasicBlock* before, float executionCount);
    48    
     48
    4949    bool execute();
    5050
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r192072 r192295  
    34003400           
    34013401        m_jit.move(op1GPR, eax.gpr());
    3402         m_jit.assembler().cdq();
    3403         m_jit.assembler().idivl_r(op2GPR);
     3402        m_jit.x86ConvertToDoubleWord32();
     3403        m_jit.x86Div32(op2GPR);
    34043404           
    34053405        if (op2TempGPR != InvalidGPRReg)
     
    35563556                m_jit.move(op1Gpr, eax.gpr());
    35573557                m_jit.move(TrustedImm32(divisor), scratchGPR);
    3558                 m_jit.assembler().cdq();
    3559                 m_jit.assembler().idivl_r(scratchGPR);
     3558                m_jit.x86ConvertToDoubleWord32();
     3559                m_jit.x86Div32(scratchGPR);
    35603560                if (shouldCheckNegativeZero(node->arithMode())) {
    35613561                    JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
     
    36473647           
    36483648        m_jit.move(op1GPR, eax.gpr());
    3649         m_jit.assembler().cdq();
    3650         m_jit.assembler().idivl_r(op2GPR);
     3649        m_jit.x86ConvertToDoubleWord32();
     3650        m_jit.x86Div32(op2GPR);
    36513651           
    36523652        if (op2TempGPR != InvalidGPRReg)
  • trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp

    r191978 r192295  
    624624    addSlowCase(branch32(Equal, regT0, TrustedImm32(-2147483647-1)));
    625625    denominatorNotNeg1.link(this);
    626     m_assembler.cdq();
    627     m_assembler.idivl_r(ecx);
     626    x86ConvertToDoubleWord32();
     627    x86Div32(ecx);
    628628    Jump numeratorPositive = branch32(GreaterThanOrEqual, regT4, TrustedImm32(0));
    629629    addSlowCase(branchTest32(Zero, edx));
  • trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp

    r191905 r192295  
    859859    addSlowCase(branch32(Equal, regT0, TrustedImm32(-2147483647-1)));
    860860    denominatorNotNeg1.link(this);
    861     m_assembler.cdq();
    862     m_assembler.idivl_r(regT2);
     861    x86ConvertToDoubleWord32();
     862    x86Div32(regT2);
    863863    Jump numeratorPositive = branch32(GreaterThanOrEqual, regT3, TrustedImm32(0));
    864864    addSlowCase(branchTest32(Zero, regT1));
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h

    r190722 r192295  
    764764            move(GPRInfo::regT1, X86Registers::ecx);
    765765            if (op == WASMOpExpressionI32::SDiv || op == WASMOpExpressionI32::SMod) {
    766                 m_assembler.cdq();
    767                 m_assembler.idivl_r(X86Registers::ecx);
     766                x86ConvertToDoubleWord32();
     767                x86Div32(X86Registers::ecx);
    768768            } else {
    769769                ASSERT(op == WASMOpExpressionI32::UDiv || op == WASMOpExpressionI32::UMod);
  • trunk/Source/WTF/ChangeLog

    r192247 r192295  
     12015-11-10  Filip Pizlo  <fpizlo@apple.com>
     2
     3        B3 should be able to compile a program with ChillDiv
     4        https://bugs.webkit.org/show_bug.cgi?id=151114
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        Needed to beef up some compiler algorithms. All of the hardening was about making them
     9        work with objects that have move semantics but not copy semantics. This arises in B3
     10        basic block insertion sets.
     11
     12        * wtf/BubbleSort.h:
     13        (WTF::bubbleSort):
     14        * wtf/Insertion.h:
     15        (WTF::Insertion::Insertion):
     16        (WTF::Insertion::index):
     17        (WTF::Insertion::element):
     18        (WTF::Insertion::operator<):
     19        (WTF::executeInsertions):
     20
    1212015-11-10  Carlos Garcia Campos  <cgarcia@igalia.com>
    222
  • trunk/Source/WTF/wtf/BubbleSort.h

    r191960 r192295  
    9090    bubbleSort(
    9191        begin, end,
    92         [] (typename std::iterator_traits<IteratorType>::value_type left,
    93             typename std::iterator_traits<IteratorType>::value_type right) -> bool {
     92        [] (const typename std::iterator_traits<IteratorType>::value_type& left,
     93            const typename std::iterator_traits<IteratorType>::value_type& right) -> bool {
    9494            return left < right;
    9595        });
  • trunk/Source/WTF/wtf/Insertion.h

    r188979 r192295  
    3333public:
    3434    Insertion() { }
    35    
    36     Insertion(size_t index, T element)
     35
     36    template<typename U>
     37    Insertion(size_t index, U&& element)
    3738        : m_index(index)
    38         , m_element(element)
     39        , m_element(std::forward<U>(element))
    3940    {
    4041    }
    4142   
    4243    size_t index() const { return m_index; }
    43     T element() const { return m_element; }
     44    const T& element() const { return m_element; }
     45    T& element() { return m_element; }
    4446   
    4547    bool operator<(const Insertion& other) const
     
    6769        size_t indexOffset = indexInInsertions + 1;
    6870        for (size_t i = lastIndex; --i > firstIndex;)
    69             target[i] = target[i - indexOffset];
    70         target[firstIndex] = insertions[indexInInsertions].element();
     71            target[i] = WTF::move(target[i - indexOffset]);
     72        target[firstIndex] = WTF::move(insertions[indexInInsertions].element());
    7173        lastIndex = firstIndex;
    7274    }
Note: See TracChangeset for help on using the changeset viewer.