Changeset 195084 in webkit


Ignore:
Timestamp:
Jan 14, 2016 4:58:22 PM (8 years ago)
Author:
fpizlo@apple.com
Message:

Air needs a Shuffle instruction
https://bugs.webkit.org/show_bug.cgi?id=152952

Reviewed by Saam Barati.

This adds an instruction called Shuffle. Shuffle allows you to simultaneously perform
multiple moves to perform arbitrary permutations over registers and memory. We call these
rotations. It also allows you to perform "shifts", like (a => b, b => c): after the shift,
c will have b's old value, b will have a's old value, and a will be unchanged. Shifts can
use immediates as their source.

Shuffle is added as a custom instruction, since it has a variable number of arguments. It
takes any number of triplets of arguments, where each triplet describes one mapping of the
shuffle. For example, to represent (a => b, b => c), we might say:

Shuffle %a, %b, 64, %b, %c, 64

Note the "64"s, those are width arguments that describe how many bits of the register are
being moved. Each triplet is referred to as a "shuffle pair". We call it a pair because the
most relevant part of it is the pair of registers or memroy locations (i.e. %a, %b form one
of the pairs in the example). For GP arguments, the width follows ZDef semantics.

In the future, we will be able to use Shuffle for a lot of things. This patch is modest about
how to use it:

  • C calling convention argument marshalling. Previously we used move instructions. But that's problematic since it introduces artificial interference between the argument registers and the inputs. Using Shuffle removes that interference. This helps a bit.
  • Cold C calls. This is what really motivated me to write this patch. If we have a C call on a cold path, then we want it to appear to the register allocator like it doesn't clobber any registers. Only after register allocation should we handle the clobbering by simply saving all of the live volatile registers to the stack. If you imagine the saving and the argument marshalling, you can see how before the call, we want to have a Shuffle that does both of those things. This is important. If argument marshalling was separate from the saving, then we'd still appear to clobber argument registers. Doing them together as one Shuffle means that the cold call doesn't appear to even clobber the argument registers.

Unfortunately, I was wrong about cold C calls being the dominant problem with our register
allocator right now. Fixing this revealed other problems in my current tuning benchmark,
Octane/encrypt. Nonetheless, this is a small speed-up across the board, and gives us some
functionality we will need to implement other optimizations.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/AbstractMacroAssembler.h:

(JSC::isX86_64):
(JSC::isIOS):
(JSC::optimizeForARMv7IDIVSupported):

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::zeroExtend32ToPtr):
(JSC::MacroAssemblerX86Common::swap32):
(JSC::MacroAssemblerX86Common::moveConditionally32):

  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::store64WithAddressOffsetPatch):
(JSC::MacroAssemblerX86_64::swap64):
(JSC::MacroAssemblerX86_64::move64ToDouble):

  • assembler/X86Assembler.h:

(JSC::X86Assembler::xchgl_rr):
(JSC::X86Assembler::xchgl_rm):
(JSC::X86Assembler::xchgq_rr):
(JSC::X86Assembler::xchgq_rm):
(JSC::X86Assembler::movl_rr):

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

(JSC::B3::Compilation::Compilation):
(JSC::B3::Compilation::~Compilation):

  • b3/B3Compilation.h:

(JSC::B3::Compilation::code):

  • b3/B3LowerToAir.cpp:

(JSC::B3::Air::LowerToAir::run):
(JSC::B3::Air::LowerToAir::createSelect):
(JSC::B3::Air::LowerToAir::lower):
(JSC::B3::Air::LowerToAir::marshallCCallArgument): Deleted.

  • b3/B3OpaqueByproducts.h:

(JSC::B3::OpaqueByproducts::count):

  • b3/B3StackmapSpecial.cpp:

(JSC::B3::StackmapSpecial::isArgValidForValue):
(JSC::B3::StackmapSpecial::isArgValidForRep):

  • b3/air/AirArg.cpp:

(JSC::B3::Air::Arg::isStackMemory):
(JSC::B3::Air::Arg::isRepresentableAs):
(JSC::B3::Air::Arg::usesTmp):
(JSC::B3::Air::Arg::canRepresent):
(JSC::B3::Air::Arg::isCompatibleType):
(JSC::B3::Air::Arg::dump):
(WTF::printInternal):

  • b3/air/AirArg.h:

(JSC::B3::Air::Arg::forEachType):
(JSC::B3::Air::Arg::isWarmUse):
(JSC::B3::Air::Arg::cooled):
(JSC::B3::Air::Arg::isEarlyUse):
(JSC::B3::Air::Arg::imm64):
(JSC::B3::Air::Arg::immPtr):
(JSC::B3::Air::Arg::addr):
(JSC::B3::Air::Arg::special):
(JSC::B3::Air::Arg::widthArg):
(JSC::B3::Air::Arg::operator==):
(JSC::B3::Air::Arg::isImm64):
(JSC::B3::Air::Arg::isSomeImm):
(JSC::B3::Air::Arg::isAddr):
(JSC::B3::Air::Arg::isIndex):
(JSC::B3::Air::Arg::isMemory):
(JSC::B3::Air::Arg::isRelCond):
(JSC::B3::Air::Arg::isSpecial):
(JSC::B3::Air::Arg::isWidthArg):
(JSC::B3::Air::Arg::isAlive):
(JSC::B3::Air::Arg::base):
(JSC::B3::Air::Arg::hasOffset):
(JSC::B3::Air::Arg::offset):
(JSC::B3::Air::Arg::width):
(JSC::B3::Air::Arg::isGPTmp):
(JSC::B3::Air::Arg::isGP):
(JSC::B3::Air::Arg::isFP):
(JSC::B3::Air::Arg::isType):
(JSC::B3::Air::Arg::isGPR):
(JSC::B3::Air::Arg::isValidForm):
(JSC::B3::Air::Arg::forEachTmpFast):

  • b3/air/AirBasicBlock.h:

(JSC::B3::Air::BasicBlock::insts):
(JSC::B3::Air::BasicBlock::appendInst):
(JSC::B3::Air::BasicBlock::append):

  • b3/air/AirCCallingConvention.cpp: Added.

(JSC::B3::Air::computeCCallingConvention):
(JSC::B3::Air::cCallResult):
(JSC::B3::Air::buildCCall):

  • b3/air/AirCCallingConvention.h: Added.
  • b3/air/AirCode.h:

(JSC::B3::Air::Code::proc):

  • b3/air/AirCustom.cpp: Added.

(JSC::B3::Air::CCallCustom::isValidForm):
(JSC::B3::Air::CCallCustom::generate):
(JSC::B3::Air::ShuffleCustom::isValidForm):
(JSC::B3::Air::ShuffleCustom::generate):

  • b3/air/AirCustom.h:

(JSC::B3::Air::PatchCustom::forEachArg):
(JSC::B3::Air::PatchCustom::generate):
(JSC::B3::Air::CCallCustom::forEachArg):
(JSC::B3::Air::CCallCustom::isValidFormStatic):
(JSC::B3::Air::CCallCustom::admitsStack):
(JSC::B3::Air::CCallCustom::hasNonArgNonControlEffects):
(JSC::B3::Air::ColdCCallCustom::forEachArg):
(JSC::B3::Air::ShuffleCustom::forEachArg):
(JSC::B3::Air::ShuffleCustom::isValidFormStatic):
(JSC::B3::Air::ShuffleCustom::admitsStack):
(JSC::B3::Air::ShuffleCustom::hasNonArgNonControlEffects):

  • b3/air/AirEmitShuffle.cpp: Added.

(JSC::B3::Air::ShufflePair::dump):
(JSC::B3::Air::emitShuffle):

  • b3/air/AirEmitShuffle.h: Added.

(JSC::B3::Air::ShufflePair::ShufflePair):
(JSC::B3::Air::ShufflePair::src):
(JSC::B3::Air::ShufflePair::dst):
(JSC::B3::Air::ShufflePair::width):

  • b3/air/AirGenerate.cpp:

(JSC::B3::Air::prepareForGeneration):

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

(JSC::B3::Air::InsertionSet::insertInsts):
(JSC::B3::Air::InsertionSet::execute):

  • b3/air/AirInsertionSet.h:

(JSC::B3::Air::InsertionSet::insertInst):
(JSC::B3::Air::InsertionSet::insert):

  • b3/air/AirInst.h:

(JSC::B3::Air::Inst::operator bool):
(JSC::B3::Air::Inst::append):

  • b3/air/AirLowerAfterRegAlloc.cpp: Added.

(JSC::B3::Air::lowerAfterRegAlloc):

  • b3/air/AirLowerAfterRegAlloc.h: Added.
  • b3/air/AirLowerMacros.cpp: Added.

(JSC::B3::Air::lowerMacros):

  • b3/air/AirLowerMacros.h: Added.
  • b3/air/AirOpcode.opcodes:
  • b3/air/AirRegisterPriority.h:

(JSC::B3::Air::regsInPriorityOrder):

  • b3/air/testair.cpp: Added.

(hiddenTruthBecauseNoReturnIsStupid):
(usage):
(JSC::B3::Air::compile):
(JSC::B3::Air::invoke):
(JSC::B3::Air::compileAndRun):
(JSC::B3::Air::testSimple):
(JSC::B3::Air::loadConstantImpl):
(JSC::B3::Air::loadConstant):
(JSC::B3::Air::loadDoubleConstant):
(JSC::B3::Air::testShuffleSimpleSwap):
(JSC::B3::Air::testShuffleSimpleShift):
(JSC::B3::Air::testShuffleLongShift):
(JSC::B3::Air::testShuffleLongShiftBackwards):
(JSC::B3::Air::testShuffleSimpleRotate):
(JSC::B3::Air::testShuffleSimpleBroadcast):
(JSC::B3::Air::testShuffleBroadcastAllRegs):
(JSC::B3::Air::testShuffleTreeShift):
(JSC::B3::Air::testShuffleTreeShiftBackward):
(JSC::B3::Air::testShuffleTreeShiftOtherBackward):
(JSC::B3::Air::testShuffleMultipleShifts):
(JSC::B3::Air::testShuffleRotateWithFringe):
(JSC::B3::Air::testShuffleRotateWithLongFringe):
(JSC::B3::Air::testShuffleMultipleRotates):
(JSC::B3::Air::testShuffleShiftAndRotate):
(JSC::B3::Air::testShuffleShiftAllRegs):
(JSC::B3::Air::testShuffleRotateAllRegs):
(JSC::B3::Air::testShuffleSimpleSwap64):
(JSC::B3::Air::testShuffleSimpleShift64):
(JSC::B3::Air::testShuffleSwapMixedWidth):
(JSC::B3::Air::testShuffleShiftMixedWidth):
(JSC::B3::Air::testShuffleShiftMemory):
(JSC::B3::Air::testShuffleShiftMemoryLong):
(JSC::B3::Air::testShuffleShiftMemoryAllRegs):
(JSC::B3::Air::testShuffleShiftMemoryAllRegs64):
(JSC::B3::Air::combineHiLo):
(JSC::B3::Air::testShuffleShiftMemoryAllRegsMixedWidth):
(JSC::B3::Air::testShuffleRotateMemory):
(JSC::B3::Air::testShuffleRotateMemory64):
(JSC::B3::Air::testShuffleRotateMemoryMixedWidth):
(JSC::B3::Air::testShuffleRotateMemoryAllRegs64):
(JSC::B3::Air::testShuffleRotateMemoryAllRegsMixedWidth):
(JSC::B3::Air::testShuffleSwapDouble):
(JSC::B3::Air::testShuffleShiftDouble):
(JSC::B3::Air::run):
(run):
(main):

  • b3/testb3.cpp:

(JSC::B3::testCallSimple):
(JSC::B3::testCallRare):
(JSC::B3::testCallRareLive):
(JSC::B3::testCallSimplePure):
(JSC::B3::run):

Location:
trunk/Source/JavaScriptCore
Files:
10 added
30 edited

Legend:

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

    r195009 r195084  
    7474    b3/air/AirBasicBlock.cpp
    7575    b3/air/AirCCallSpecial.cpp
     76    b3/air/AirCCallingConvention.cpp
    7677    b3/air/AirCode.cpp
     78    b3/air/AirCustom.cpp
    7779    b3/air/AirEliminateDeadCode.cpp
     80    b3/air/AirEmitShuffle.cpp
    7881    b3/air/AirFixPartialRegisterStalls.cpp
    7982    b3/air/AirGenerate.cpp
     
    8386    b3/air/AirInst.cpp
    8487    b3/air/AirIteratedRegisterCoalescing.cpp
     88    b3/air/AirLowerAfterRegAlloc.cpp
     89    b3/air/AirLowerMacros.cpp
    8590    b3/air/AirOptimizeBlockOrder.cpp
    8691    b3/air/AirPhaseScope.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r195077 r195084  
     12016-01-14  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Air needs a Shuffle instruction
     4        https://bugs.webkit.org/show_bug.cgi?id=152952
     5
     6        Reviewed by Saam Barati.
     7
     8        This adds an instruction called Shuffle. Shuffle allows you to simultaneously perform
     9        multiple moves to perform arbitrary permutations over registers and memory. We call these
     10        rotations. It also allows you to perform "shifts", like (a => b, b => c): after the shift,
     11        c will have b's old value, b will have a's old value, and a will be unchanged. Shifts can
     12        use immediates as their source.
     13
     14        Shuffle is added as a custom instruction, since it has a variable number of arguments. It
     15        takes any number of triplets of arguments, where each triplet describes one mapping of the
     16        shuffle. For example, to represent (a => b, b => c), we might say:
     17
     18            Shuffle %a, %b, 64, %b, %c, 64
     19
     20        Note the "64"s, those are width arguments that describe how many bits of the register are
     21        being moved. Each triplet is referred to as a "shuffle pair". We call it a pair because the
     22        most relevant part of it is the pair of registers or memroy locations (i.e. %a, %b form one
     23        of the pairs in the example). For GP arguments, the width follows ZDef semantics.
     24
     25        In the future, we will be able to use Shuffle for a lot of things. This patch is modest about
     26        how to use it:
     27
     28        - C calling convention argument marshalling. Previously we used move instructions. But that's
     29          problematic since it introduces artificial interference between the argument registers and
     30          the inputs. Using Shuffle removes that interference. This helps a bit.
     31
     32        - Cold C calls. This is what really motivated me to write this patch. If we have a C call on
     33          a cold path, then we want it to appear to the register allocator like it doesn't clobber
     34          any registers. Only after register allocation should we handle the clobbering by simply
     35          saving all of the live volatile registers to the stack. If you imagine the saving and the
     36          argument marshalling, you can see how before the call, we want to have a Shuffle that does
     37          both of those things. This is important. If argument marshalling was separate from the
     38          saving, then we'd still appear to clobber argument registers. Doing them together as one
     39          Shuffle means that the cold call doesn't appear to even clobber the argument registers.
     40
     41        Unfortunately, I was wrong about cold C calls being the dominant problem with our register
     42        allocator right now. Fixing this revealed other problems in my current tuning benchmark,
     43        Octane/encrypt. Nonetheless, this is a small speed-up across the board, and gives us some
     44        functionality we will need to implement other optimizations.
     45
     46        * CMakeLists.txt:
     47        * JavaScriptCore.xcodeproj/project.pbxproj:
     48        * assembler/AbstractMacroAssembler.h:
     49        (JSC::isX86_64):
     50        (JSC::isIOS):
     51        (JSC::optimizeForARMv7IDIVSupported):
     52        * assembler/MacroAssemblerX86Common.h:
     53        (JSC::MacroAssemblerX86Common::zeroExtend32ToPtr):
     54        (JSC::MacroAssemblerX86Common::swap32):
     55        (JSC::MacroAssemblerX86Common::moveConditionally32):
     56        * assembler/MacroAssemblerX86_64.h:
     57        (JSC::MacroAssemblerX86_64::store64WithAddressOffsetPatch):
     58        (JSC::MacroAssemblerX86_64::swap64):
     59        (JSC::MacroAssemblerX86_64::move64ToDouble):
     60        * assembler/X86Assembler.h:
     61        (JSC::X86Assembler::xchgl_rr):
     62        (JSC::X86Assembler::xchgl_rm):
     63        (JSC::X86Assembler::xchgq_rr):
     64        (JSC::X86Assembler::xchgq_rm):
     65        (JSC::X86Assembler::movl_rr):
     66        * b3/B3CCallValue.h:
     67        * b3/B3Compilation.cpp:
     68        (JSC::B3::Compilation::Compilation):
     69        (JSC::B3::Compilation::~Compilation):
     70        * b3/B3Compilation.h:
     71        (JSC::B3::Compilation::code):
     72        * b3/B3LowerToAir.cpp:
     73        (JSC::B3::Air::LowerToAir::run):
     74        (JSC::B3::Air::LowerToAir::createSelect):
     75        (JSC::B3::Air::LowerToAir::lower):
     76        (JSC::B3::Air::LowerToAir::marshallCCallArgument): Deleted.
     77        * b3/B3OpaqueByproducts.h:
     78        (JSC::B3::OpaqueByproducts::count):
     79        * b3/B3StackmapSpecial.cpp:
     80        (JSC::B3::StackmapSpecial::isArgValidForValue):
     81        (JSC::B3::StackmapSpecial::isArgValidForRep):
     82        * b3/air/AirArg.cpp:
     83        (JSC::B3::Air::Arg::isStackMemory):
     84        (JSC::B3::Air::Arg::isRepresentableAs):
     85        (JSC::B3::Air::Arg::usesTmp):
     86        (JSC::B3::Air::Arg::canRepresent):
     87        (JSC::B3::Air::Arg::isCompatibleType):
     88        (JSC::B3::Air::Arg::dump):
     89        (WTF::printInternal):
     90        * b3/air/AirArg.h:
     91        (JSC::B3::Air::Arg::forEachType):
     92        (JSC::B3::Air::Arg::isWarmUse):
     93        (JSC::B3::Air::Arg::cooled):
     94        (JSC::B3::Air::Arg::isEarlyUse):
     95        (JSC::B3::Air::Arg::imm64):
     96        (JSC::B3::Air::Arg::immPtr):
     97        (JSC::B3::Air::Arg::addr):
     98        (JSC::B3::Air::Arg::special):
     99        (JSC::B3::Air::Arg::widthArg):
     100        (JSC::B3::Air::Arg::operator==):
     101        (JSC::B3::Air::Arg::isImm64):
     102        (JSC::B3::Air::Arg::isSomeImm):
     103        (JSC::B3::Air::Arg::isAddr):
     104        (JSC::B3::Air::Arg::isIndex):
     105        (JSC::B3::Air::Arg::isMemory):
     106        (JSC::B3::Air::Arg::isRelCond):
     107        (JSC::B3::Air::Arg::isSpecial):
     108        (JSC::B3::Air::Arg::isWidthArg):
     109        (JSC::B3::Air::Arg::isAlive):
     110        (JSC::B3::Air::Arg::base):
     111        (JSC::B3::Air::Arg::hasOffset):
     112        (JSC::B3::Air::Arg::offset):
     113        (JSC::B3::Air::Arg::width):
     114        (JSC::B3::Air::Arg::isGPTmp):
     115        (JSC::B3::Air::Arg::isGP):
     116        (JSC::B3::Air::Arg::isFP):
     117        (JSC::B3::Air::Arg::isType):
     118        (JSC::B3::Air::Arg::isGPR):
     119        (JSC::B3::Air::Arg::isValidForm):
     120        (JSC::B3::Air::Arg::forEachTmpFast):
     121        * b3/air/AirBasicBlock.h:
     122        (JSC::B3::Air::BasicBlock::insts):
     123        (JSC::B3::Air::BasicBlock::appendInst):
     124        (JSC::B3::Air::BasicBlock::append):
     125        * b3/air/AirCCallingConvention.cpp: Added.
     126        (JSC::B3::Air::computeCCallingConvention):
     127        (JSC::B3::Air::cCallResult):
     128        (JSC::B3::Air::buildCCall):
     129        * b3/air/AirCCallingConvention.h: Added.
     130        * b3/air/AirCode.h:
     131        (JSC::B3::Air::Code::proc):
     132        * b3/air/AirCustom.cpp: Added.
     133        (JSC::B3::Air::CCallCustom::isValidForm):
     134        (JSC::B3::Air::CCallCustom::generate):
     135        (JSC::B3::Air::ShuffleCustom::isValidForm):
     136        (JSC::B3::Air::ShuffleCustom::generate):
     137        * b3/air/AirCustom.h:
     138        (JSC::B3::Air::PatchCustom::forEachArg):
     139        (JSC::B3::Air::PatchCustom::generate):
     140        (JSC::B3::Air::CCallCustom::forEachArg):
     141        (JSC::B3::Air::CCallCustom::isValidFormStatic):
     142        (JSC::B3::Air::CCallCustom::admitsStack):
     143        (JSC::B3::Air::CCallCustom::hasNonArgNonControlEffects):
     144        (JSC::B3::Air::ColdCCallCustom::forEachArg):
     145        (JSC::B3::Air::ShuffleCustom::forEachArg):
     146        (JSC::B3::Air::ShuffleCustom::isValidFormStatic):
     147        (JSC::B3::Air::ShuffleCustom::admitsStack):
     148        (JSC::B3::Air::ShuffleCustom::hasNonArgNonControlEffects):
     149        * b3/air/AirEmitShuffle.cpp: Added.
     150        (JSC::B3::Air::ShufflePair::dump):
     151        (JSC::B3::Air::emitShuffle):
     152        * b3/air/AirEmitShuffle.h: Added.
     153        (JSC::B3::Air::ShufflePair::ShufflePair):
     154        (JSC::B3::Air::ShufflePair::src):
     155        (JSC::B3::Air::ShufflePair::dst):
     156        (JSC::B3::Air::ShufflePair::width):
     157        * b3/air/AirGenerate.cpp:
     158        (JSC::B3::Air::prepareForGeneration):
     159        * b3/air/AirGenerate.h:
     160        * b3/air/AirInsertionSet.cpp:
     161        (JSC::B3::Air::InsertionSet::insertInsts):
     162        (JSC::B3::Air::InsertionSet::execute):
     163        * b3/air/AirInsertionSet.h:
     164        (JSC::B3::Air::InsertionSet::insertInst):
     165        (JSC::B3::Air::InsertionSet::insert):
     166        * b3/air/AirInst.h:
     167        (JSC::B3::Air::Inst::operator bool):
     168        (JSC::B3::Air::Inst::append):
     169        * b3/air/AirLowerAfterRegAlloc.cpp: Added.
     170        (JSC::B3::Air::lowerAfterRegAlloc):
     171        * b3/air/AirLowerAfterRegAlloc.h: Added.
     172        * b3/air/AirLowerMacros.cpp: Added.
     173        (JSC::B3::Air::lowerMacros):
     174        * b3/air/AirLowerMacros.h: Added.
     175        * b3/air/AirOpcode.opcodes:
     176        * b3/air/AirRegisterPriority.h:
     177        (JSC::B3::Air::regsInPriorityOrder):
     178        * b3/air/testair.cpp: Added.
     179        (hiddenTruthBecauseNoReturnIsStupid):
     180        (usage):
     181        (JSC::B3::Air::compile):
     182        (JSC::B3::Air::invoke):
     183        (JSC::B3::Air::compileAndRun):
     184        (JSC::B3::Air::testSimple):
     185        (JSC::B3::Air::loadConstantImpl):
     186        (JSC::B3::Air::loadConstant):
     187        (JSC::B3::Air::loadDoubleConstant):
     188        (JSC::B3::Air::testShuffleSimpleSwap):
     189        (JSC::B3::Air::testShuffleSimpleShift):
     190        (JSC::B3::Air::testShuffleLongShift):
     191        (JSC::B3::Air::testShuffleLongShiftBackwards):
     192        (JSC::B3::Air::testShuffleSimpleRotate):
     193        (JSC::B3::Air::testShuffleSimpleBroadcast):
     194        (JSC::B3::Air::testShuffleBroadcastAllRegs):
     195        (JSC::B3::Air::testShuffleTreeShift):
     196        (JSC::B3::Air::testShuffleTreeShiftBackward):
     197        (JSC::B3::Air::testShuffleTreeShiftOtherBackward):
     198        (JSC::B3::Air::testShuffleMultipleShifts):
     199        (JSC::B3::Air::testShuffleRotateWithFringe):
     200        (JSC::B3::Air::testShuffleRotateWithLongFringe):
     201        (JSC::B3::Air::testShuffleMultipleRotates):
     202        (JSC::B3::Air::testShuffleShiftAndRotate):
     203        (JSC::B3::Air::testShuffleShiftAllRegs):
     204        (JSC::B3::Air::testShuffleRotateAllRegs):
     205        (JSC::B3::Air::testShuffleSimpleSwap64):
     206        (JSC::B3::Air::testShuffleSimpleShift64):
     207        (JSC::B3::Air::testShuffleSwapMixedWidth):
     208        (JSC::B3::Air::testShuffleShiftMixedWidth):
     209        (JSC::B3::Air::testShuffleShiftMemory):
     210        (JSC::B3::Air::testShuffleShiftMemoryLong):
     211        (JSC::B3::Air::testShuffleShiftMemoryAllRegs):
     212        (JSC::B3::Air::testShuffleShiftMemoryAllRegs64):
     213        (JSC::B3::Air::combineHiLo):
     214        (JSC::B3::Air::testShuffleShiftMemoryAllRegsMixedWidth):
     215        (JSC::B3::Air::testShuffleRotateMemory):
     216        (JSC::B3::Air::testShuffleRotateMemory64):
     217        (JSC::B3::Air::testShuffleRotateMemoryMixedWidth):
     218        (JSC::B3::Air::testShuffleRotateMemoryAllRegs64):
     219        (JSC::B3::Air::testShuffleRotateMemoryAllRegsMixedWidth):
     220        (JSC::B3::Air::testShuffleSwapDouble):
     221        (JSC::B3::Air::testShuffleShiftDouble):
     222        (JSC::B3::Air::run):
     223        (run):
     224        (main):
     225        * b3/testb3.cpp:
     226        (JSC::B3::testCallSimple):
     227        (JSC::B3::testCallRare):
     228        (JSC::B3::testCallRareLive):
     229        (JSC::B3::testCallSimplePure):
     230        (JSC::B3::run):
     231
    12322016-01-14  Keith Miller  <keith_miller@apple.com>
    2233
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r194976 r195084  
    2626                        );
    2727                        dependencies = (
     28                                0F6183471C45F67A0072450B /* PBXTargetDependency */,
    2829                                0F93275D1C20BF3A00CF6564 /* PBXTargetDependency */,
    2930                                0FEC85B11BDB5D8F0080FF74 /* PBXTargetDependency */,
     
    401402                0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5EF91C16878F78003E5C25 /* JITThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
    402403                0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
     404                0F6183291C45BF070072450B /* AirCCallingConvention.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183201C45BF070072450B /* AirCCallingConvention.cpp */; };
     405                0F61832A1C45BF070072450B /* AirCCallingConvention.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183211C45BF070072450B /* AirCCallingConvention.h */; };
     406                0F61832B1C45BF070072450B /* AirCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183221C45BF070072450B /* AirCustom.cpp */; };
     407                0F61832C1C45BF070072450B /* AirEmitShuffle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183231C45BF070072450B /* AirEmitShuffle.cpp */; };
     408                0F61832D1C45BF070072450B /* AirEmitShuffle.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183241C45BF070072450B /* AirEmitShuffle.h */; };
     409                0F61832E1C45BF070072450B /* AirLowerAfterRegAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183251C45BF070072450B /* AirLowerAfterRegAlloc.cpp */; };
     410                0F61832F1C45BF070072450B /* AirLowerAfterRegAlloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183261C45BF070072450B /* AirLowerAfterRegAlloc.h */; };
     411                0F6183301C45BF070072450B /* AirLowerMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183271C45BF070072450B /* AirLowerMacros.cpp */; };
     412                0F6183311C45BF070072450B /* AirLowerMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183281C45BF070072450B /* AirLowerMacros.h */; };
     413                0F6183331C45F35C0072450B /* AirOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183321C45F35C0072450B /* AirOpcode.h */; };
     414                0F6183361C45F3B60072450B /* AirOpcodeGenerated.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183341C45F3B60072450B /* AirOpcodeGenerated.h */; };
     415                0F6183371C45F3B60072450B /* AirOpcodeUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183351C45F3B60072450B /* AirOpcodeUtils.h */; };
     416                0F61833C1C45F62A0072450B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
     417                0F61833D1C45F62A0072450B /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
     418                0F6183451C45F6600072450B /* testair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183441C45F6600072450B /* testair.cpp */; };
    403419                0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */; };
    404420                0F620176143FCD3B0068B77C /* DFGBasicBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620170143FCD2F0068B77C /* DFGBasicBlock.h */; };
     
    20802096
    20812097/* Begin PBXContainerItemProxy section */
     2098                0F6183461C45F67A0072450B /* PBXContainerItemProxy */ = {
     2099                        isa = PBXContainerItemProxy;
     2100                        containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
     2101                        proxyType = 1;
     2102                        remoteGlobalIDString = 0F6183381C45F62A0072450B;
     2103                        remoteInfo = testair;
     2104                };
    20822105                0F93275C1C20BF3A00CF6564 /* PBXContainerItemProxy */ = {
    20832106                        isa = PBXContainerItemProxy;
     
    25432566                0F5EF91C16878F78003E5C25 /* JITThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITThunks.h; sourceTree = "<group>"; };
    25442567                0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnconditionalFinalizer.h; sourceTree = "<group>"; };
     2568                0F6183201C45BF070072450B /* AirCCallingConvention.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirCCallingConvention.cpp; path = b3/air/AirCCallingConvention.cpp; sourceTree = "<group>"; };
     2569                0F6183211C45BF070072450B /* AirCCallingConvention.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirCCallingConvention.h; path = b3/air/AirCCallingConvention.h; sourceTree = "<group>"; };
     2570                0F6183221C45BF070072450B /* AirCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirCustom.cpp; path = b3/air/AirCustom.cpp; sourceTree = "<group>"; };
     2571                0F6183231C45BF070072450B /* AirEmitShuffle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirEmitShuffle.cpp; path = b3/air/AirEmitShuffle.cpp; sourceTree = "<group>"; };
     2572                0F6183241C45BF070072450B /* AirEmitShuffle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirEmitShuffle.h; path = b3/air/AirEmitShuffle.h; sourceTree = "<group>"; };
     2573                0F6183251C45BF070072450B /* AirLowerAfterRegAlloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirLowerAfterRegAlloc.cpp; path = b3/air/AirLowerAfterRegAlloc.cpp; sourceTree = "<group>"; };
     2574                0F6183261C45BF070072450B /* AirLowerAfterRegAlloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirLowerAfterRegAlloc.h; path = b3/air/AirLowerAfterRegAlloc.h; sourceTree = "<group>"; };
     2575                0F6183271C45BF070072450B /* AirLowerMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirLowerMacros.cpp; path = b3/air/AirLowerMacros.cpp; sourceTree = "<group>"; };
     2576                0F6183281C45BF070072450B /* AirLowerMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirLowerMacros.h; path = b3/air/AirLowerMacros.h; sourceTree = "<group>"; };
     2577                0F6183321C45F35C0072450B /* AirOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirOpcode.h; sourceTree = "<group>"; };
     2578                0F6183341C45F3B60072450B /* AirOpcodeGenerated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirOpcodeGenerated.h; sourceTree = "<group>"; };
     2579                0F6183351C45F3B60072450B /* AirOpcodeUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirOpcodeUtils.h; sourceTree = "<group>"; };
     2580                0F6183431C45F62A0072450B /* testair */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testair; sourceTree = BUILT_PRODUCTS_DIR; };
     2581                0F6183441C45F6600072450B /* testair.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testair.cpp; path = b3/air/testair.cpp; sourceTree = "<group>"; };
    25452582                0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractValue.h; path = dfg/DFGAbstractValue.h; sourceTree = "<group>"; };
    25462583                0F620170143FCD2F0068B77C /* DFGBasicBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBasicBlock.h; path = dfg/DFGBasicBlock.h; sourceTree = "<group>"; };
     
    33733410                7035587C1C418419004BD7BF /* MapPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = MapPrototype.js; sourceTree = "<group>"; };
    33743411                7035587D1C418419004BD7BF /* SetPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SetPrototype.js; sourceTree = "<group>"; };
    3375                 7035587E1C418458004BD7BF /* MapPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MapPrototype.lut.h; path = MapPrototype.lut.h; sourceTree = "<group>"; };
    3376                 7035587F1C418458004BD7BF /* SetPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SetPrototype.lut.h; path = SetPrototype.lut.h; sourceTree = "<group>"; };
     3412                7035587E1C418458004BD7BF /* MapPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapPrototype.lut.h; sourceTree = "<group>"; };
     3413                7035587F1C418458004BD7BF /* SetPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetPrototype.lut.h; sourceTree = "<group>"; };
    33773414                704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; };
    33783415                705B41A31A6E501E00716757 /* Symbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbol.cpp; sourceTree = "<group>"; };
     
    43074344
    43084345/* Begin PBXFrameworksBuildPhase section */
     4346                0F61833B1C45F62A0072450B /* Frameworks */ = {
     4347                        isa = PBXFrameworksBuildPhase;
     4348                        buildActionMask = 2147483647;
     4349                        files = (
     4350                                0F61833C1C45F62A0072450B /* Foundation.framework in Frameworks */,
     4351                                0F61833D1C45F62A0072450B /* JavaScriptCore.framework in Frameworks */,
     4352                        );
     4353                        runOnlyForDeploymentPostprocessing = 0;
     4354                };
    43094355                0F9327511C20BCBA00CF6564 /* Frameworks */ = {
    43104356                        isa = PBXFrameworksBuildPhase;
     
    44044450                                6511230514046A4C002B101D /* testRegExp */,
    44054451                                0F9327591C20BCBA00CF6564 /* dynbench */,
     4452                                0F6183431C45F62A0072450B /* testair */,
    44064453                        );
    44074454                        name = Products;
     
    47944841                                0FEC854D1BDACDC70080FF74 /* AirBasicBlock.h */,
    47954842                                0FB3878B1BFBC44D00E3AB1E /* AirBlockWorklist.h */,
     4843                                0F6183201C45BF070072450B /* AirCCallingConvention.cpp */,
     4844                                0F6183211C45BF070072450B /* AirCCallingConvention.h */,
    47964845                                0FEC854E1BDACDC70080FF74 /* AirCCallSpecial.cpp */,
    47974846                                0FEC854F1BDACDC70080FF74 /* AirCCallSpecial.h */,
    47984847                                0FEC85501BDACDC70080FF74 /* AirCode.cpp */,
    47994848                                0FEC85511BDACDC70080FF74 /* AirCode.h */,
     4849                                0F6183221C45BF070072450B /* AirCustom.cpp */,
    48004850                                0F10F1A21C420BF0001C07D2 /* AirCustom.h */,
    48014851                                0F4570361BE44C910062A629 /* AirEliminateDeadCode.cpp */,
    48024852                                0F4570371BE44C910062A629 /* AirEliminateDeadCode.h */,
     4853                                0F6183231C45BF070072450B /* AirEmitShuffle.cpp */,
     4854                                0F6183241C45BF070072450B /* AirEmitShuffle.h */,
    48034855                                262D85B41C0D650F006ACB61 /* AirFixPartialRegisterStalls.cpp */,
    48044856                                262D85B51C0D650F006ACB61 /* AirFixPartialRegisterStalls.h */,
     
    48194871                                26718BA31BE99F780052017B /* AirIteratedRegisterCoalescing.h */,
    48204872                                2684D4371C00161C0081D663 /* AirLiveness.h */,
     4873                                0F6183251C45BF070072450B /* AirLowerAfterRegAlloc.cpp */,
     4874                                0F6183261C45BF070072450B /* AirLowerAfterRegAlloc.h */,
     4875                                0F6183271C45BF070072450B /* AirLowerMacros.cpp */,
     4876                                0F6183281C45BF070072450B /* AirLowerMacros.h */,
    48214877                                264091FA1BE2FD4100684DB2 /* AirOpcode.opcodes */,
    48224878                                0FB3878C1BFBC44D00E3AB1E /* AirOptimizeBlockOrder.cpp */,
     
    48444900                                0FEC856B1BDACDC70080FF74 /* AirValidate.cpp */,
    48454901                                0FEC856C1BDACDC70080FF74 /* AirValidate.h */,
     4902                                0F6183441C45F6600072450B /* testair.cpp */,
    48464903                        );
    48474904                        name = air;
     
    53015358                        isa = PBXGroup;
    53025359                        children = (
     5360                                0F6183321C45F35C0072450B /* AirOpcode.h */,
     5361                                0F6183341C45F3B60072450B /* AirOpcodeGenerated.h */,
     5362                                0F6183351C45F3B60072450B /* AirOpcodeUtils.h */,
    53035363                                996B73151BDA05AA00331B84 /* ArrayConstructor.lut.h */,
    53045364                                996B73161BDA05AA00331B84 /* ArrayIteratorPrototype.lut.h */,
     
    69006960                                79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */,
    69016961                                79D5CD5B1C1106A900CECA07 /* SamplingProfiler.h in Headers */,
     6962                                0F6183311C45BF070072450B /* AirLowerMacros.h in Headers */,
    69026963                                0FEC85771BDACDC70080FF74 /* AirFrequentedBlock.h in Headers */,
    69036964                                0FEC85791BDACDC70080FF74 /* AirGenerate.h in Headers */,
     
    69627023                                0FEC85C11BE167A00080FF74 /* B3Effects.h in Headers */,
    69637024                                0FEC85161BDACDAC0080FF74 /* B3FrequencyClass.h in Headers */,
     7025                                0F61832F1C45BF070072450B /* AirLowerAfterRegAlloc.h in Headers */,
    69647026                                0FEC85171BDACDAC0080FF74 /* B3FrequentedBlock.h in Headers */,
    69657027                                0FEC85191BDACDAC0080FF74 /* B3Generate.h in Headers */,
     
    71557217                                0F37308D1C0BD29100052BFA /* B3PhiChildren.h in Headers */,
    71567218                                A77A424217A0BBFD00A8DB81 /* DFGClobberSet.h in Headers */,
     7219                                0F61832D1C45BF070072450B /* AirEmitShuffle.h in Headers */,
    71577220                                0F3C1F1B1B868E7900ABB08B /* DFGClobbersExitState.h in Headers */,
    71587221                                0F04396E1B03DC0B009598B7 /* DFGCombinedLiveness.h in Headers */,
     
    72597322                                0FFC92161B94FB3E0071DD66 /* DFGPropertyTypeKey.h in Headers */,
    72607323                                0FB17663196B8F9E0091052A /* DFGPureValue.h in Headers */,
     7324                                0F6183361C45F3B60072450B /* AirOpcodeGenerated.h in Headers */,
    72617325                                0F3730911C0CD70C00052BFA /* AllowMacroScratchRegisterUsage.h in Headers */,
    72627326                                0F3A1BFA1A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h in Headers */,
     
    72757339                                0F9FB4F517FCB91700CB67F8 /* DFGStackLayoutPhase.h in Headers */,
    72767340                                0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */,
     7341                                0F6183371C45F3B60072450B /* AirOpcodeUtils.h in Headers */,
    72777342                                0F9E32641B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h in Headers */,
    72787343                                0FC20CB61852E2C600C9E954 /* DFGStrengthReductionPhase.h in Headers */,
     
    76297694                                A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */,
    76307695                                E33F50811B8429A400413856 /* JSInternalPromise.h in Headers */,
     7696                                0F61832A1C45BF070072450B /* AirCCallingConvention.h in Headers */,
    76317697                                E33F50791B84225700413856 /* JSInternalPromiseConstructor.h in Headers */,
    76327698                                E33F50871B8449EF00413856 /* JSInternalPromiseConstructor.lut.h in Headers */,
     
    80198085                                14E84F9F14EE1ACC00D6D5D4 /* WeakBlock.h in Headers */,
    80208086                                14BFCE6910CDB1FC00364CCE /* WeakGCMap.h in Headers */,
     8087                                0F6183331C45F35C0072450B /* AirOpcode.h in Headers */,
    80218088                                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */,
    80228089                                14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */,
     
    80518118
    80528119/* Begin PBXNativeTarget section */
     8120                0F6183381C45F62A0072450B /* testair */ = {
     8121                        isa = PBXNativeTarget;
     8122                        buildConfigurationList = 0F61833E1C45F62A0072450B /* Build configuration list for PBXNativeTarget "testair" */;
     8123                        buildPhases = (
     8124                                0F6183391C45F62A0072450B /* Sources */,
     8125                                0F61833B1C45F62A0072450B /* Frameworks */,
     8126                        );
     8127                        buildRules = (
     8128                        );
     8129                        dependencies = (
     8130                        );
     8131                        name = testair;
     8132                        productName = testapi;
     8133                        productReference = 0F6183431C45F62A0072450B /* testair */;
     8134                        productType = "com.apple.product-type.tool";
     8135                };
    80538136                0F93274E1C20BCBA00CF6564 /* dynbench */ = {
    80548137                        isa = PBXNativeTarget;
     
    82588341                                5D6B2A47152B9E17005231DE /* Test Tools */,
    82598342                                0F93274E1C20BCBA00CF6564 /* dynbench */,
     8343                                0F6183381C45F62A0072450B /* testair */,
    82608344                        );
    82618345                };
     
    84948578
    84958579/* Begin PBXSourcesBuildPhase section */
     8580                0F6183391C45F62A0072450B /* Sources */ = {
     8581                        isa = PBXSourcesBuildPhase;
     8582                        buildActionMask = 2147483647;
     8583                        files = (
     8584                                0F6183451C45F6600072450B /* testair.cpp in Sources */,
     8585                        );
     8586                        runOnlyForDeploymentPostprocessing = 0;
     8587                };
    84968588                0F93274F1C20BCBA00CF6564 /* Sources */ = {
    84978589                        isa = PBXSourcesBuildPhase;
     
    86988790                                0FBADF541BD1F4B800E073C1 /* CopiedBlock.cpp in Sources */,
    86998791                                C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */,
     8792                                0F6183301C45BF070072450B /* AirLowerMacros.cpp in Sources */,
    87008793                                C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */,
    87018794                                2A111245192FCE79005EE18D /* CustomGetterSetter.cpp in Sources */,
     
    87468839                                0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */,
    87478840                                A7D89CF517A0B8CC00773AD8 /* DFGCriticalEdgeBreakingPhase.cpp in Sources */,
     8841                                0F6183291C45BF070072450B /* AirCCallingConvention.cpp in Sources */,
    87488842                                0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
    87498843                                0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */,
     
    87628856                                A78A9776179738B8009DF744 /* DFGFinalizer.cpp in Sources */,
    87638857                                0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */,
     8858                                0F61832C1C45BF070072450B /* AirEmitShuffle.cpp in Sources */,
    87648859                                0F9D339617FFC4E60073C2BC /* DFGFlushedAt.cpp in Sources */,
    87658860                                A7D89CF717A0B8CC00773AD8 /* DFGFlushFormat.cpp in Sources */,
     
    90739168                                E33F50741B8421C000413856 /* JSInternalPromisePrototype.cpp in Sources */,
    90749169                                A503FA1B188E0FB000110F14 /* JSJavaScriptCallFrame.cpp in Sources */,
     9170                                0F61832E1C45BF070072450B /* AirLowerAfterRegAlloc.cpp in Sources */,
    90759171                                A503FA1D188E0FB000110F14 /* JSJavaScriptCallFramePrototype.cpp in Sources */,
    90769172                                7013CA8B1B491A9400CAE613 /* JSJob.cpp in Sources */,
     
    92159311                                0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
    92169312                                0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */,
     9313                                0F61832B1C45BF070072450B /* AirCustom.cpp in Sources */,
    92179314                                0F13912B16771C3A009CCB07 /* ProfilerProfiledBytecodes.cpp in Sources */,
    92189315                                0FD3E40D1B618B6600C80E1E /* PropertyCondition.cpp in Sources */,
     
    93679464
    93689465/* Begin PBXTargetDependency section */
     9466                0F6183471C45F67A0072450B /* PBXTargetDependency */ = {
     9467                        isa = PBXTargetDependency;
     9468                        target = 0F6183381C45F62A0072450B /* testair */;
     9469                        targetProxy = 0F6183461C45F67A0072450B /* PBXContainerItemProxy */;
     9470                };
    93699471                0F93275D1C20BF3A00CF6564 /* PBXTargetDependency */ = {
    93709472                        isa = PBXTargetDependency;
     
    94759577                        buildSettings = {
    94769578                                PRODUCT_NAME = "Derived Sources copy";
     9579                        };
     9580                        name = Production;
     9581                };
     9582                0F61833F1C45F62A0072450B /* Debug */ = {
     9583                        isa = XCBuildConfiguration;
     9584                        baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
     9585                        buildSettings = {
     9586                                CODE_SIGN_ENTITLEMENTS_ios_testair = entitlements.plist;
     9587                                PRODUCT_NAME = testair;
     9588                        };
     9589                        name = Debug;
     9590                };
     9591                0F6183401C45F62A0072450B /* Release */ = {
     9592                        isa = XCBuildConfiguration;
     9593                        baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
     9594                        buildSettings = {
     9595                                CODE_SIGN_ENTITLEMENTS_ios_testair = entitlements.plist;
     9596                                PRODUCT_NAME = testair;
     9597                        };
     9598                        name = Release;
     9599                };
     9600                0F6183411C45F62A0072450B /* Profiling */ = {
     9601                        isa = XCBuildConfiguration;
     9602                        baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
     9603                        buildSettings = {
     9604                                CODE_SIGN_ENTITLEMENTS_ios_testair = entitlements.plist;
     9605                                PRODUCT_NAME = testair;
     9606                        };
     9607                        name = Profiling;
     9608                };
     9609                0F6183421C45F62A0072450B /* Production */ = {
     9610                        isa = XCBuildConfiguration;
     9611                        baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
     9612                        buildSettings = {
     9613                                CODE_SIGN_ENTITLEMENTS_ios_testair = entitlements.plist;
     9614                                PRODUCT_NAME = testair;
    94779615                        };
    94789616                        name = Production;
     
    990710045                        defaultConfigurationName = Production;
    990810046                };
     10047                0F61833E1C45F62A0072450B /* Build configuration list for PBXNativeTarget "testair" */ = {
     10048                        isa = XCConfigurationList;
     10049                        buildConfigurations = (
     10050                                0F61833F1C45F62A0072450B /* Debug */,
     10051                                0F6183401C45F62A0072450B /* Release */,
     10052                                0F6183411C45F62A0072450B /* Profiling */,
     10053                                0F6183421C45F62A0072450B /* Production */,
     10054                        );
     10055                        defaultConfigurationIsVisible = 0;
     10056                        defaultConfigurationName = Production;
     10057                };
    990910058                0F9327541C20BCBA00CF6564 /* Build configuration list for PBXNativeTarget "dynbench" */ = {
    991010059                        isa = XCConfigurationList;
  • trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h

    r194331 r195084  
    11/*
    2  * Copyright (C) 2008, 2012, 2014, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2012, 2014-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7777}
    7878
     79inline bool isIOS()
     80{
     81#if PLATFORM(IOS)
     82    return true;
     83#else
     84    return false;
     85#endif
     86}
     87
    7988inline bool optimizeForARMv7IDIVSupported()
    8089{
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r194802 r195084  
    14111411    }
    14121412#endif
     1413
     1414    void swap32(RegisterID src, RegisterID dest)
     1415    {
     1416        m_assembler.xchgl_rr(src, dest);
     1417    }
     1418
     1419    void swap32(RegisterID src, Address dest)
     1420    {
     1421        m_assembler.xchgl_rm(src, dest.offset, dest.base);
     1422    }
    14131423
    14141424    void moveConditionally32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID src, RegisterID dest)
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r194824 r195084  
    11/*
    2  * Copyright (C) 2008, 2012, 2014, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2012, 2014-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    656656    }
    657657
     658    void swap64(RegisterID src, RegisterID dest)
     659    {
     660        m_assembler.xchgq_rr(src, dest);
     661    }
     662
     663    void swap64(RegisterID src, Address dest)
     664    {
     665        m_assembler.xchgq_rm(src, dest.offset, dest.base);
     666    }
     667
    658668    void move64ToDouble(RegisterID src, FPRegisterID dest)
    659669    {
  • trunk/Source/JavaScriptCore/assembler/X86Assembler.h

    r194635 r195084  
    11/*
    2  * Copyright (C) 2008, 2012-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2012-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    14321432    }
    14331433
     1434    void xchgl_rm(RegisterID src, int offset, RegisterID base)
     1435    {
     1436        m_formatter.oneByteOp(OP_XCHG_EvGv, src, base, offset);
     1437    }
     1438
    14341439#if CPU(X86_64)
    14351440    void xchgq_rr(RegisterID src, RegisterID dst)
     
    14411446        else
    14421447            m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
     1448    }
     1449
     1450    void xchgq_rm(RegisterID src, int offset, RegisterID base)
     1451    {
     1452        m_formatter.oneByteOp64(OP_XCHG_EvGv, src, base, offset);
    14431453    }
    14441454#endif
  • trunk/Source/JavaScriptCore/b3/B3CCallValue.h

    r193943 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4040    ~CCallValue();
    4141
    42     Effects effects;
     42    Effects effects { Effects::forCall() };
    4343
    4444private:
     
    4848    CCallValue(unsigned index, Type type, Origin origin, Arguments... arguments)
    4949        : Value(index, CheckedOpcode, CCall, type, origin, arguments...)
    50         , effects(Effects::forCall())
    5150    {
    5251        RELEASE_ASSERT(numChildren() >= 1);
  • trunk/Source/JavaScriptCore/b3/B3Compilation.cpp

    r193362 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5353}
    5454
     55Compilation::Compilation(MacroAssemblerCodeRef codeRef, std::unique_ptr<OpaqueByproducts> byproducts)
     56    : m_codeRef(codeRef)
     57    , m_byproducts(WTFMove(byproducts))
     58{
     59}
     60
    5561Compilation::~Compilation()
    5662{
  • trunk/Source/JavaScriptCore/b3/B3Compilation.h

    r192320 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5656public:
    5757    JS_EXPORT_PRIVATE Compilation(VM&, Procedure&, unsigned optLevel = 1);
     58
     59    // This constructor allows you to manually create a Compilation. It's currently only used by test
     60    // code. Probably best to keep it that way.
     61    JS_EXPORT_PRIVATE Compilation(MacroAssemblerCodeRef, std::unique_ptr<OpaqueByproducts>);
     62   
    5863    JS_EXPORT_PRIVATE ~Compilation();
    5964
  • trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp

    r194976 r195084  
    3636#include "B3ArgumentRegValue.h"
    3737#include "B3BasicBlockInlines.h"
     38#include "B3BlockWorklist.h"
    3839#include "B3CCallValue.h"
    3940#include "B3CheckSpecial.h"
     
    100101        }
    101102
     103        // Figure out which blocks are not rare.
     104        m_fastWorklist.push(m_procedure[0]);
     105        while (B3::BasicBlock* block = m_fastWorklist.pop()) {
     106            for (B3::FrequentedBlock& successor : block->successors()) {
     107                if (!successor.isRare())
     108                    m_fastWorklist.push(successor.block());
     109            }
     110        }
     111
    102112        m_procedure.resetValueOwners(); // Used by crossesInterference().
    103113
     
    108118            // Reset some state.
    109119            m_insts.resize(0);
     120
     121            m_isRare = !m_fastWorklist.saw(block);
    110122
    111123            if (verbose)
     
    15531565    }
    15541566
    1555     template<typename BankInfo>
    1556     Arg marshallCCallArgument(unsigned& argumentCount, unsigned& stackOffset, Value* child)
    1557     {
    1558         unsigned argumentIndex = argumentCount++;
    1559         if (argumentIndex < BankInfo::numberOfArgumentRegisters) {
    1560             Tmp result = Tmp(BankInfo::toArgumentRegister(argumentIndex));
    1561             append(relaxedMoveForType(child->type()), immOrTmp(child), result);
    1562             return result;
    1563         }
    1564 
    1565 #if CPU(ARM64) && PLATFORM(IOS)
    1566         // iOS does not follow the ARM64 ABI regarding function calls.
    1567         // Arguments must be packed.
    1568         unsigned slotSize = sizeofType(child->type());
    1569         stackOffset = WTF::roundUpToMultipleOf(slotSize, stackOffset);
    1570 #else
    1571         unsigned slotSize = sizeof(void*);
    1572 #endif
    1573         Arg result = Arg::callArg(stackOffset);
    1574         stackOffset += slotSize;
    1575        
    1576         // Put the code for storing the argument before anything else. This significantly eases the
    1577         // burden on the register allocator. If we could, we'd hoist these stores as far as
    1578         // possible.
    1579         // FIXME: Add a phase to hoist stores as high as possible to relieve register pressure.
    1580         // https://bugs.webkit.org/show_bug.cgi?id=151063
    1581         m_insts.last().insert(0, createStore(child, result));
    1582        
    1583         return result;
    1584     }
    1585 
    15861567    void lower()
    15871568    {
     
    19351916        }
    19361917
    1937         case CCall: {
     1918        case B3::CCall: {
    19381919            CCallValue* cCall = m_value->as<CCallValue>();
    1939             Inst inst(Patch, cCall, Arg::special(m_code.cCallSpecial()));
    1940 
    1941             // This is a bit weird - we have a super intense contract with Arg::CCallSpecial. It might
    1942             // be better if we factored Air::CCallSpecial out of the Air namespace and made it a B3
    1943             // thing.
    1944             // FIXME: https://bugs.webkit.org/show_bug.cgi?id=151045
     1920
     1921            Inst inst(m_isRare ? Air::ColdCCall : Air::CCall, cCall);
    19451922
    19461923            // We have a ton of flexibility regarding the callee argument, but currently, we don't
     
    19551932            inst.args.append(tmp(cCall->child(0)));
    19561933
    1957             // We need to tell Air what registers this defines.
    1958             inst.args.append(Tmp(GPRInfo::returnValueGPR));
    1959             inst.args.append(Tmp(GPRInfo::returnValueGPR2));
    1960             inst.args.append(Tmp(FPRInfo::returnValueFPR));
    1961 
    1962             // Now marshall the arguments. This is where we implement the C calling convention. After
    1963             // this, Air does not know what the convention is; it just takes our word for it.
    1964             unsigned gpArgumentCount = 0;
    1965             unsigned fpArgumentCount = 0;
    1966             unsigned stackOffset = 0;
    1967             for (unsigned i = 1; i < cCall->numChildren(); ++i) {
    1968                 Value* argChild = cCall->child(i);
    1969                 Arg arg;
    1970                
    1971                 switch (Arg::typeForB3Type(argChild->type())) {
    1972                 case Arg::GP:
    1973                     arg = marshallCCallArgument<GPRInfo>(gpArgumentCount, stackOffset, argChild);
    1974                     break;
    1975 
    1976                 case Arg::FP:
    1977                     arg = marshallCCallArgument<FPRInfo>(fpArgumentCount, stackOffset, argChild);
    1978                     break;
    1979                 }
    1980 
    1981                 if (arg.isTmp())
    1982                     inst.args.append(arg);
    1983             }
    1984            
     1934            if (cCall->type() != Void)
     1935                inst.args.append(tmp(cCall));
     1936
     1937            for (unsigned i = 1; i < cCall->numChildren(); ++i)
     1938                inst.args.append(immOrTmp(cCall->child(i)));
     1939
    19851940            m_insts.last().append(WTFMove(inst));
    1986 
    1987             switch (cCall->type()) {
    1988             case Void:
    1989                 break;
    1990             case Int32:
    1991             case Int64:
    1992                 append(Move, Tmp(GPRInfo::returnValueGPR), tmp(cCall));
    1993                 break;
    1994             case Float:
    1995             case Double:
    1996                 append(MoveDouble, Tmp(FPRInfo::returnValueFPR), tmp(cCall));
    1997                 break;
    1998             }
    19991941            return;
    20001942        }
     
    22882230    UseCounts m_useCounts;
    22892231    PhiChildren m_phiChildren;
     2232    BlockWorklist m_fastWorklist;
    22902233
    22912234    Vector<Vector<Inst, 4>> m_insts;
     
    22932236
    22942237    B3::BasicBlock* m_block;
     2238    bool m_isRare;
    22952239    unsigned m_index;
    22962240    Value* m_value;
  • trunk/Source/JavaScriptCore/b3/B3OpaqueByproducts.h

    r192183 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4040public:
    4141    OpaqueByproducts();
    42     ~OpaqueByproducts();
     42    JS_EXPORT_PRIVATE ~OpaqueByproducts();
    4343
    4444    size_t count() const { return m_byproducts.size(); }
  • trunk/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp

    r194850 r195084  
    201201    case Arg::Imm:
    202202    case Arg::Imm64:
    203     case Arg::Stack:
    204     case Arg::CallArg:
    205         break; // OK
    206     case Arg::Addr:
    207         if (arg.base() != Tmp(GPRInfo::callFrameRegister)
    208             && arg.base() != Tmp(MacroAssembler::stackPointerRegister))
     203        break;
     204    default:
     205        if (!arg.isStackMemory())
    209206            return false;
    210207        break;
    211     default:
    212         return false;
    213     }
    214    
    215     Arg::Type type = Arg::typeForB3Type(value->type());
    216 
    217     return arg.isType(type);
     208    }
     209
     210    return arg.canRepresent(value);
    218211}
    219212
  • trunk/Source/JavaScriptCore/b3/air/AirArg.cpp

    r194858 r195084  
    3131#include "AirSpecial.h"
    3232#include "AirStackSlot.h"
     33#include "B3Value.h"
     34#include "FPRInfo.h"
     35#include "GPRInfo.h"
    3336
    3437#if COMPILER(GCC) && ASSERT_DISABLED
     
    3841
    3942namespace JSC { namespace B3 { namespace Air {
     43
     44bool Arg::isStackMemory() const
     45{
     46    switch (kind()) {
     47    case Addr:
     48        return base() == Air::Tmp(GPRInfo::callFrameRegister)
     49            || base() == Air::Tmp(MacroAssembler::stackPointerRegister);
     50    case Stack:
     51    case CallArg:
     52        return true;
     53    default:
     54        return false;
     55    }
     56}
    4057
    4158bool Arg::isRepresentableAs(Width width, Signedness signedness) const
     
    6885}
    6986
     87bool Arg::usesTmp(Air::Tmp tmp) const
     88{
     89    bool uses = false;
     90    const_cast<Arg*>(this)->forEachTmpFast(
     91        [&] (Air::Tmp otherTmp) {
     92            if (otherTmp == tmp)
     93                uses = true;
     94        });
     95    return uses;
     96}
     97
     98bool Arg::canRepresent(Value* value) const
     99{
     100    return isType(typeForB3Type(value->type()));
     101}
     102
     103bool Arg::isCompatibleType(const Arg& other) const
     104{
     105    if (hasType())
     106        return other.isType(type());
     107    if (other.hasType())
     108        return isType(other.type());
     109    return true;
     110}
     111
    70112void Arg::dump(PrintStream& out) const
    71113{
     
    118160        out.print(pointerDump(special()));
    119161        return;
     162    case WidthArg:
     163        out.print(width());
     164        return;
    120165    }
    121166
     
    168213        out.print("Special");
    169214        return;
     215    case Arg::WidthArg:
     216        out.print("WidthArg");
     217        return;
    170218    }
    171219
     
    232280    switch (width) {
    233281    case Arg::Width8:
    234         out.print("Width8");
     282        out.print("8");
    235283        return;
    236284    case Arg::Width16:
    237         out.print("Width16");
     285        out.print("16");
    238286        return;
    239287    case Arg::Width32:
    240         out.print("Width32");
     288        out.print("32");
    241289        return;
    242290    case Arg::Width64:
    243         out.print("Width64");
     291        out.print("64");
    244292        return;
    245293    }
  • trunk/Source/JavaScriptCore/b3/air/AirArg.h

    r194858 r195084  
    3939#endif // COMPILER(GCC) && ASSERT_DISABLED
    4040
    41 namespace JSC { namespace B3 { namespace Air {
     41namespace JSC { namespace B3 {
     42
     43class Value;
     44
     45namespace Air {
    4246
    4347class Special;
     
    7579        ResCond,
    7680        DoubleCond,
    77         Special
     81        Special,
     82        WidthArg
    7883    };
    7984
     
    162167    static const unsigned numTypes = 2;
    163168
     169    template<typename Functor>
     170    static void forEachType(const Functor& functor)
     171    {
     172        functor(GP);
     173        functor(FP);
     174    }
     175
    164176    enum Width : int8_t {
    165177        Width8,
     
    226238    {
    227239        return isAnyUse(role) && !isColdUse(role);
     240    }
     241
     242    static Role cooled(Role role)
     243    {
     244        switch (role) {
     245        case ColdUse:
     246        case LateColdUse:
     247        case UseDef:
     248        case UseZDef:
     249        case Def:
     250        case ZDef:
     251        case UseAddr:
     252        case Scratch:
     253        case EarlyDef:
     254            return role;
     255        case Use:
     256            return ColdUse;
     257        case LateUse:
     258            return LateColdUse;
     259        }
    228260    }
    229261
     
    448480        result.m_offset = value;
    449481        return result;
     482    }
     483
     484    static Arg immPtr(const void* address)
     485    {
     486        return imm64(bitwise_cast<intptr_t>(address));
    450487    }
    451488
     
    564601    }
    565602
     603    static Arg widthArg(Width width)
     604    {
     605        Arg result;
     606        result.m_kind = WidthArg;
     607        result.m_offset = width;
     608        return result;
     609    }
     610
    566611    bool operator==(const Arg& other) const
    567612    {
     
    600645    }
    601646
     647    bool isSomeImm() const
     648    {
     649        return isImm() || isImm64();
     650    }
     651
    602652    bool isAddr() const
    603653    {
     
    620670    }
    621671
    622     bool isRelCond() const
    623     {
    624         return kind() == RelCond;
    625     }
    626 
    627     bool isResCond() const
    628     {
    629         return kind() == ResCond;
    630     }
    631 
    632     bool isDoubleCond() const
    633     {
    634         return kind() == DoubleCond;
    635     }
    636 
    637     bool isCondition() const
    638     {
    639         switch (kind()) {
    640         case RelCond:
    641         case ResCond:
    642         case DoubleCond:
    643             return true;
    644         default:
    645             return false;
    646         }
    647     }
    648 
    649     bool isSpecial() const
    650     {
    651         return kind() == Special;
    652     }
    653 
    654     bool isAlive() const
    655     {
    656         return isTmp() || isStack();
    657     }
    658 
    659     Air::Tmp tmp() const
    660     {
    661         ASSERT(kind() == Tmp);
    662         return m_base;
    663     }
    664 
    665     int64_t value() const
    666     {
    667         ASSERT(kind() == Imm || kind() == Imm64);
    668         return m_offset;
    669     }
    670 
    671     template<typename T>
    672     bool isRepresentableAs() const
    673     {
    674         return B3::isRepresentableAs<T>(value());
    675     }
    676 
    677     bool isRepresentableAs(Width, Signedness) const;
    678 
    679     template<typename T>
    680     T asNumber() const
    681     {
    682         return static_cast<T>(value());
    683     }
    684 
    685     void* pointerValue() const
    686     {
    687         ASSERT(kind() == Imm64);
    688         return bitwise_cast<void*>(static_cast<intptr_t>(m_offset));
    689     }
    690 
    691     Air::Tmp base() const
    692     {
    693         ASSERT(kind() == Addr || kind() == Index);
    694         return m_base;
    695     }
    696 
    697     bool hasOffset() const
     672    bool isMemory() const
    698673    {
    699674        switch (kind()) {
     
    707682        }
    708683    }
     684
     685    bool isStackMemory() const;
     686
     687    bool isRelCond() const
     688    {
     689        return kind() == RelCond;
     690    }
     691
     692    bool isResCond() const
     693    {
     694        return kind() == ResCond;
     695    }
     696
     697    bool isDoubleCond() const
     698    {
     699        return kind() == DoubleCond;
     700    }
     701
     702    bool isCondition() const
     703    {
     704        switch (kind()) {
     705        case RelCond:
     706        case ResCond:
     707        case DoubleCond:
     708            return true;
     709        default:
     710            return false;
     711        }
     712    }
     713
     714    bool isSpecial() const
     715    {
     716        return kind() == Special;
     717    }
     718
     719    bool isWidthArg() const
     720    {
     721        return kind() == WidthArg;
     722    }
     723
     724    bool isAlive() const
     725    {
     726        return isTmp() || isStack();
     727    }
     728
     729    Air::Tmp tmp() const
     730    {
     731        ASSERT(kind() == Tmp);
     732        return m_base;
     733    }
     734
     735    int64_t value() const
     736    {
     737        ASSERT(kind() == Imm || kind() == Imm64);
     738        return m_offset;
     739    }
     740
     741    template<typename T>
     742    bool isRepresentableAs() const
     743    {
     744        return B3::isRepresentableAs<T>(value());
     745    }
     746
     747    bool isRepresentableAs(Width, Signedness) const;
     748
     749    template<typename T>
     750    T asNumber() const
     751    {
     752        return static_cast<T>(value());
     753    }
     754
     755    void* pointerValue() const
     756    {
     757        ASSERT(kind() == Imm64);
     758        return bitwise_cast<void*>(static_cast<intptr_t>(m_offset));
     759    }
     760
     761    Air::Tmp base() const
     762    {
     763        ASSERT(kind() == Addr || kind() == Index);
     764        return m_base;
     765    }
     766
     767    bool hasOffset() const { return isMemory(); }
    709768   
    710769    int32_t offset() const
     
    743802        ASSERT(kind() == Special);
    744803        return bitwise_cast<Air::Special*>(m_offset);
     804    }
     805
     806    Width width() const
     807    {
     808        ASSERT(kind() == WidthArg);
     809        return static_cast<Width>(m_offset);
    745810    }
    746811
     
    769834        case DoubleCond:
    770835        case Special:
     836        case WidthArg:
    771837            return true;
    772838        case Tmp:
     
    787853        case DoubleCond:
    788854        case Special:
     855        case WidthArg:
    789856        case Invalid:
    790857            return false;
     
    829896        ASSERT_NOT_REACHED();
    830897    }
     898
     899    bool canRepresent(Value* value) const;
     900
     901    bool isCompatibleType(const Arg& other) const;
    831902
    832903    bool isGPR() const
     
    9711042        case DoubleCond:
    9721043        case Special:
     1044        case WidthArg:
    9731045            return true;
    9741046        }
     
    9921064        }
    9931065    }
     1066
     1067    bool usesTmp(Air::Tmp tmp) const;
    9941068
    9951069    // This is smart enough to know that an address arg in a Def or UseDef rule will use its
  • trunk/Source/JavaScriptCore/b3/air/AirBasicBlock.h

    r194542 r195084  
    7979
    8080    template<typename Inst>
    81     void appendInst(Inst&& inst)
     81    Inst& appendInst(Inst&& inst)
    8282    {
    8383        m_insts.append(std::forward<Inst>(inst));
     84        return m_insts.last();
    8485    }
    8586
    8687    template<typename... Arguments>
    87     void append(Arguments&&... arguments)
     88    Inst& append(Arguments&&... arguments)
    8889    {
    8990        m_insts.append(Inst(std::forward<Arguments>(arguments)...));
     91        return m_insts.last();
    9092    }
    9193
  • trunk/Source/JavaScriptCore/b3/air/AirCode.h

    r194858 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6161    Procedure& proc() { return m_proc; }
    6262
    63     BasicBlock* addBlock(double frequency = 1);
     63    JS_EXPORT_PRIVATE BasicBlock* addBlock(double frequency = 1);
    6464
    6565    // Note that you can rely on stack slots always getting indices that are larger than the index
    6666    // of any prior stack slot. In fact, all stack slots you create in the future will have an index
    6767    // that is >= stackSlots().size().
    68     StackSlot* addStackSlot(unsigned byteSize, StackSlotKind, StackSlotValue* = nullptr);
     68    JS_EXPORT_PRIVATE StackSlot* addStackSlot(
     69        unsigned byteSize, StackSlotKind, StackSlotValue* = nullptr);
    6970    StackSlot* addStackSlot(StackSlotValue*);
    7071
  • trunk/Source/JavaScriptCore/b3/air/AirCustom.h

    r194856 r195084  
    3131#include "AirInst.h"
    3232#include "AirSpecial.h"
     33#include "B3Value.h"
    3334
    3435namespace JSC { namespace B3 { namespace Air {
     
    5253// always have access to Code& even in methods that don't take a GenerationContext.
    5354
     55// Definition of Patch instruction. Patch is used to delegate the behavior of the instruction to the
     56// Special object, which will be the first argument to the instruction.
    5457struct PatchCustom {
    5558    template<typename Functor>
     
    97100};
    98101
     102// Definition of CCall instruction. CCall is used for hot path C function calls. It's lowered to a
     103// Patch with an Air CCallSpecial along with code to marshal instructions. The lowering happens
     104// before register allocation, so that the register allocator sees the clobbers.
     105struct CCallCustom {
     106    template<typename Functor>
     107    static void forEachArg(Inst& inst, const Functor& functor)
     108    {
     109        Value* value = inst.origin;
     110
     111        unsigned index = 0;
     112
     113        functor(inst.args[index++], Arg::Use, Arg::GP, Arg::pointerWidth()); // callee
     114       
     115        if (value->type() != Void) {
     116            functor(
     117                inst.args[index++], Arg::Def,
     118                Arg::typeForB3Type(value->type()),
     119                Arg::widthForB3Type(value->type()));
     120        }
     121
     122        for (unsigned i = 1; i < value->numChildren(); ++i) {
     123            Value* child = value->child(i);
     124            functor(
     125                inst.args[index++], Arg::Use,
     126                Arg::typeForB3Type(child->type()),
     127                Arg::widthForB3Type(child->type()));
     128        }
     129    }
     130
     131    template<typename... Arguments>
     132    static bool isValidFormStatic(Arguments...)
     133    {
     134        return false;
     135    }
     136
     137    static bool isValidForm(Inst&);
     138
     139    static bool admitsStack(Inst&, unsigned)
     140    {
     141        return true;
     142    }
     143
     144    static bool hasNonArgNonControlEffects(Inst&)
     145    {
     146        return true;
     147    }
     148
     149    // This just crashes, since we expect C calls to be lowered before generation.
     150    static CCallHelpers::Jump generate(Inst&, CCallHelpers&, GenerationContext&);
     151};
     152
     153struct ColdCCallCustom : CCallCustom {
     154    template<typename Functor>
     155    static void forEachArg(Inst& inst, const Functor& functor)
     156    {
     157        // This is just like a call, but uses become cold.
     158        CCallCustom::forEachArg(
     159            inst,
     160            [&] (Arg& arg, Arg::Role role, Arg::Type type, Arg::Width width) {
     161                functor(arg, Arg::cooled(role), type, width);
     162            });
     163    }
     164};
     165
     166struct ShuffleCustom {
     167    template<typename Functor>
     168    static void forEachArg(Inst& inst, const Functor& functor)
     169    {
     170        unsigned limit = inst.args.size() / 3 * 3;
     171        for (unsigned i = 0; i < limit; i += 3) {
     172            Arg& src = inst.args[i + 0];
     173            Arg& dst = inst.args[i + 1];
     174            Arg& widthArg = inst.args[i + 2];
     175            Arg::Width width = widthArg.width();
     176            Arg::Type type = src.isGP() && dst.isGP() ? Arg::GP : Arg::FP;
     177            functor(src, Arg::Use, type, width);
     178            functor(dst, Arg::Def, type, width);
     179            functor(widthArg, Arg::Use, Arg::GP, Arg::Width8);
     180        }
     181    }
     182
     183    template<typename... Arguments>
     184    static bool isValidFormStatic(Arguments...)
     185    {
     186        return false;
     187    }
     188
     189    static bool isValidForm(Inst&);
     190   
     191    static bool admitsStack(Inst&, unsigned index)
     192    {
     193        switch (index % 3) {
     194        case 0:
     195        case 1:
     196            return true;
     197        default:
     198            return false;
     199        }
     200    }
     201
     202    static bool hasNonArgNonControlEffects(Inst&)
     203    {
     204        return false;
     205    }
     206
     207    static CCallHelpers::Jump generate(Inst&, CCallHelpers&, GenerationContext&);
     208};
     209
    99210} } } // namespace JSC::B3::Air
    100211
  • trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp

    r194628 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3636#include "AirHandleCalleeSaves.h"
    3737#include "AirIteratedRegisterCoalescing.h"
     38#include "AirLowerAfterRegAlloc.h"
     39#include "AirLowerMacros.h"
    3840#include "AirOpcodeUtils.h"
    3941#include "AirOptimizeBlockOrder.h"
     
    6668    }
    6769
     70    lowerMacros(code);
     71
    6872    // This is where we run our optimizations and transformations.
    6973    // FIXME: Add Air optimizations.
     
    8084    else
    8185        iteratedRegisterCoalescing(code);
     86
     87    lowerAfterRegAlloc(code);
    8288
    8389    // Prior to this point the prologue and epilogue is implicit. This makes it explicit. It also
  • trunk/Source/JavaScriptCore/b3/air/AirGenerate.h

    r192558 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3939// This takes an Air::Code that hasn't had any stack allocation and optionally hasn't had any
    4040// register allocation and does both of those things.
    41 void prepareForGeneration(Code&);
     41JS_EXPORT_PRIVATE void prepareForGeneration(Code&);
    4242
    4343// This generates the code using the given CCallHelpers instance. Note that this may call callbacks
    4444// in the supplied code as it is generating.
    45 void generate(Code&, CCallHelpers&);
     45JS_EXPORT_PRIVATE void generate(Code&, CCallHelpers&);
    4646
    4747} } } // namespace JSC::B3::Air
  • trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.cpp

    r191960 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3434namespace JSC { namespace B3 { namespace Air {
    3535
     36void InsertionSet::insertInsts(size_t index, const Vector<Inst>& insts)
     37{
     38    for (const Inst& inst : insts)
     39        insertInst(index, inst);
     40}
     41
     42void InsertionSet::insertInsts(size_t index, Vector<Inst>&& insts)
     43{
     44    for (Inst& inst : insts)
     45        insertInst(index, WTFMove(inst));
     46}
     47
    3648void InsertionSet::execute(BasicBlock* block)
    3749{
  • trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.h

    r191705 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6060        appendInsertion(Insertion(index, std::forward<Inst>(inst)));
    6161    }
     62
     63    void insertInsts(size_t index, const Vector<Inst>&);
     64    void insertInsts(size_t index, Vector<Inst>&&);
    6265   
    6366    template<typename... Arguments>
  • trunk/Source/JavaScriptCore/b3/air/AirInst.h

    r194856 r195084  
    8585
    8686    explicit operator bool() const { return origin || opcode != Nop || args.size(); }
     87
     88    void append() { }
     89   
     90    template<typename... Arguments>
     91    void append(Arg arg, Arguments... arguments)
     92    {
     93        args.append(arg);
     94        append(arguments...);
     95    }
    8796
    8897    // Note that these functors all avoid using "const" because we want to use them for things that
  • trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes

    r194915 r195084  
    418418    x86: Imm, Addr as storePtr
    419419
     420x86: Swap32 UD:G:32, UD:G:32
     421    Tmp, Tmp
     422    Tmp, Addr
     423
     424x86_64: Swap64 UD:G:64, UD:G:64
     425    Tmp, Tmp
     426    Tmp, Addr
     427
    420428Move32 U:G:32, ZD:G:32
    421429    Tmp, Tmp as zeroExtend32ToPtr
     
    683691Oops /terminal
    684692
     693# A Shuffle is a multi-source, multi-destination move. It simultaneously does multiple moves at once.
     694# The moves are specified as triplets of src, dst, and width. For example you can request a swap this
     695# way:
     696#     Shuffle %tmp1, %tmp2, 64, %tmp2, %tmp1, 64
     697custom Shuffle
     698
    685699# Air allows for exotic behavior. A Patch's behavior is determined entirely by the Special operand,
    686700# which must be the first operand.
    687701custom Patch
    688702
     703# Instructions used for lowering C calls. These don't make it to Air generation. They get lowered to
     704# something else first. The origin Value must be a CCallValue.
     705custom CCall
     706custom ColdCCall
     707
     708
  • trunk/Source/JavaScriptCore/b3/air/AirRegisterPriority.h

    r191705 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5353}
    5454
    55 const Vector<Reg>& regsInPriorityOrder(Arg::Type);
     55JS_EXPORT_PRIVATE const Vector<Reg>& regsInPriorityOrder(Arg::Type);
    5656
    5757} } } // namespace JSC::B3::Air
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r194976 r195084  
    77747774
    77757775    CHECK(compileAndRun<int>(proc, a, b) == a + b);
     7776}
     7777
     7778void testCallRare(int a, int b)
     7779{
     7780    Procedure proc;
     7781    BasicBlock* root = proc.addBlock();
     7782    BasicBlock* common = proc.addBlock();
     7783    BasicBlock* rare = proc.addBlock();
     7784
     7785    root->appendNew<ControlValue>(
     7786        proc, Branch, Origin(),
     7787        root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
     7788        FrequentedBlock(rare, FrequencyClass::Rare),
     7789        FrequentedBlock(common));
     7790
     7791    common->appendNew<ControlValue>(
     7792        proc, Return, Origin(), common->appendNew<Const32Value>(proc, Origin(), 0));
     7793   
     7794    rare->appendNew<ControlValue>(
     7795        proc, Return, Origin(),
     7796        rare->appendNew<CCallValue>(
     7797            proc, Int32, Origin(),
     7798            rare->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
     7799            rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
     7800            rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
     7801
     7802    CHECK(compileAndRun<int>(proc, true, a, b) == a + b);
     7803}
     7804
     7805void testCallRareLive(int a, int b, int c)
     7806{
     7807    Procedure proc;
     7808    BasicBlock* root = proc.addBlock();
     7809    BasicBlock* common = proc.addBlock();
     7810    BasicBlock* rare = proc.addBlock();
     7811
     7812    root->appendNew<ControlValue>(
     7813        proc, Branch, Origin(),
     7814        root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
     7815        FrequentedBlock(rare, FrequencyClass::Rare),
     7816        FrequentedBlock(common));
     7817
     7818    common->appendNew<ControlValue>(
     7819        proc, Return, Origin(), common->appendNew<Const32Value>(proc, Origin(), 0));
     7820   
     7821    rare->appendNew<ControlValue>(
     7822        proc, Return, Origin(),
     7823        rare->appendNew<Value>(
     7824            proc, Add, Origin(),
     7825            rare->appendNew<CCallValue>(
     7826                proc, Int32, Origin(),
     7827                rare->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
     7828                rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
     7829                rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)),
     7830            rare->appendNew<Value>(
     7831                proc, Trunc, Origin(),
     7832                rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3))));
     7833
     7834    CHECK(compileAndRun<int>(proc, true, a, b, c) == a + b + c);
    77767835}
    77777836
     
    1007010129
    1007110130    RUN(testCallSimple(1, 2));
     10131    RUN(testCallRare(1, 2));
     10132    RUN(testCallRareLive(1, 2, 3));
    1007210133    RUN(testCallSimplePure(1, 2));
    1007310134    RUN(testCallFunctionWithHellaArguments());
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r194922 r195084  
    35413541                m_out.aboveOrEqual(
    35423542                    prevLength, m_out.load32(storage, m_heaps.Butterfly_vectorLength)),
    3543                 rarely(slowPath), usually(fastPath));
     3543                unsure(slowPath), unsure(fastPath));
    35443544           
    35453545            LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
     
    82268226                    FTL_NEW_BLOCK(m_out, ("PutByVal hole case"));
    82278227                   
    8228                 m_out.branch(isOutOfBounds, unsure(outOfBoundsCase), unsure(holeCase));
     8228                m_out.branch(isOutOfBounds, rarely(outOfBoundsCase), usually(holeCase));
    82298229                   
    82308230                LBasicBlock innerLastNext = m_out.appendTo(outOfBoundsCase, holeCase);
  • trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp

    r193640 r195084  
    7474    RefPtr<OSRExitHandle> handle =
    7575        prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset, isExceptionHandler);
    76     handle->emitExitThunk(jit);
     76    handle->emitExitThunk(state, jit);
    7777    return handle;
    7878}
     
    8585        prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset, isExceptionHandler);
    8686    params.addLatePath(
    87         [handle] (CCallHelpers& jit) {
    88             handle->emitExitThunk(jit);
     87        [handle, &state] (CCallHelpers& jit) {
     88            handle->emitExitThunk(state, jit);
    8989        });
    9090    return handle;
  • trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.cpp

    r194331 r195084  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030
    3131#include "FTLOSRExit.h"
     32#include "FTLState.h"
    3233#include "FTLThunks.h"
    3334#include "LinkBuffer.h"
     35#include "ProfilerCompilation.h"
    3436
    3537namespace JSC { namespace FTL {
    3638
    37 void OSRExitHandle::emitExitThunk(CCallHelpers& jit)
     39void OSRExitHandle::emitExitThunk(State& state, CCallHelpers& jit)
    3840{
    39     label = jit.label();
     41    Profiler::Compilation* compilation = state.graph.compilation();
     42    CCallHelpers::Label myLabel = jit.label();
     43    label = myLabel;
    4044    jit.pushToSaveImmediateWithoutTouchingRegisters(CCallHelpers::TrustedImm32(index));
    4145    CCallHelpers::PatchableJump jump = jit.patchableJump();
    4246    RefPtr<OSRExitHandle> self = this;
    4347    jit.addLinkTask(
    44         [self, jump] (LinkBuffer& linkBuffer) {
     48        [self, jump, myLabel, compilation] (LinkBuffer& linkBuffer) {
    4549            self->exit.m_patchableJump = CodeLocationJump(linkBuffer.locationOf(jump));
    4650
     
    4852                jump.m_jump,
    4953                CodeLocationLabel(linkBuffer.vm().getCTIStub(osrExitGenerationThunkGenerator).code()));
     54            if (compilation)
     55                compilation->addOSRExitSite({ linkBuffer.locationOf(myLabel).executableAddress() });
    5056        });
    5157}
  • trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.h

    r193362 r195084  
    3636namespace JSC { namespace FTL {
    3737
     38class State;
    3839struct OSRExit;
    3940
     
    5657
    5758    // This emits the exit thunk and populates 'label'.
    58     void emitExitThunk(CCallHelpers&);
     59    void emitExitThunk(State&, CCallHelpers&);
    5960};
    6061
Note: See TracChangeset for help on using the changeset viewer.