diff options
Diffstat (limited to 'Source/JavaScriptCore/b3/B3LowerMacros.cpp')
| -rw-r--r-- | Source/JavaScriptCore/b3/B3LowerMacros.cpp | 377 |
1 files changed, 0 insertions, 377 deletions
diff --git a/Source/JavaScriptCore/b3/B3LowerMacros.cpp b/Source/JavaScriptCore/b3/B3LowerMacros.cpp deleted file mode 100644 index f71ca62ab..000000000 --- a/Source/JavaScriptCore/b3/B3LowerMacros.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2015 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "B3LowerMacros.h" - -#if ENABLE(B3_JIT) - -#include "B3BasicBlockInlines.h" -#include "B3BlockInsertionSet.h" -#include "B3CCallValue.h" -#include "B3ConstPtrValue.h" -#include "B3ControlValue.h" -#include "B3InsertionSetInlines.h" -#include "B3PhaseScope.h" -#include "B3ProcedureInlines.h" -#include "B3SwitchValue.h" -#include "B3UpsilonValue.h" -#include "B3ValueInlines.h" -#include <cmath> - -namespace JSC { namespace B3 { - -namespace { - -class LowerMacros { -public: - LowerMacros(Procedure& proc) - : m_proc(proc) - , m_blockInsertionSet(proc) - , m_insertionSet(proc) - { - } - - bool run() - { - for (BasicBlock* block : m_proc) { - m_block = block; - processCurrentBlock(); - } - m_changed |= m_blockInsertionSet.execute(); - if (m_changed) { - m_proc.resetReachability(); - m_proc.invalidateCFG(); - } - return m_changed; - } - -private: - void processCurrentBlock() - { - for (m_index = 0; m_index < m_block->size(); ++m_index) { - m_value = m_block->at(m_index); - m_origin = m_value->origin(); - switch (m_value->opcode()) { - case Mod: { - double (*fmodDouble)(double, double) = fmod; - if (m_value->type() == Double) { - Value* functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, fmodDouble); - Value* result = m_insertionSet.insert<CCallValue>(m_index, Double, m_origin, - Effects::none(), - functionAddress, - m_value->child(0), - m_value->child(1)); - m_value->replaceWithIdentity(result); - m_changed = true; - } else if (m_value->type() == Float) { - Value* numeratorAsDouble = m_insertionSet.insert<Value>(m_index, FloatToDouble, m_origin, m_value->child(0)); - Value* denominatorAsDouble = m_insertionSet.insert<Value>(m_index, FloatToDouble, m_origin, m_value->child(1)); - Value* functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, fmodDouble); - Value* doubleMod = m_insertionSet.insert<CCallValue>(m_index, Double, m_origin, - Effects::none(), - functionAddress, - numeratorAsDouble, - denominatorAsDouble); - Value* result = m_insertionSet.insert<Value>(m_index, DoubleToFloat, m_origin, doubleMod); - m_value->replaceWithIdentity(result); - m_changed = true; - } else if (isARM64()) { - Value* divResult = m_insertionSet.insert<Value>(m_index, ChillDiv, m_origin, m_value->child(0), m_value->child(1)); - Value* multipliedBack = m_insertionSet.insert<Value>(m_index, Mul, m_origin, divResult, m_value->child(1)); - Value* result = m_insertionSet.insert<Value>(m_index, Sub, m_origin, m_value->child(0), multipliedBack); - m_value->replaceWithIdentity(result); - m_changed = true; - } - break; - } - case ChillDiv: { - makeDivisionChill(Div); - break; - } - - case ChillMod: { - if (isARM64()) { - BasicBlock* before = m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet); - BasicBlock* zeroDenCase = m_blockInsertionSet.insertBefore(m_block); - BasicBlock* normalModCase = m_blockInsertionSet.insertBefore(m_block); - - before->replaceLastWithNew<ControlValue>( - m_proc, Branch, m_origin, m_value->child(1), - FrequentedBlock(normalModCase, FrequencyClass::Normal), - FrequentedBlock(zeroDenCase, FrequencyClass::Rare)); - - Value* divResult = normalModCase->appendNew<Value>(m_proc, ChillDiv, m_origin, m_value->child(0), m_value->child(1)); - Value* multipliedBack = normalModCase->appendNew<Value>(m_proc, Mul, m_origin, divResult, m_value->child(1)); - Value* result = normalModCase->appendNew<Value>(m_proc, Sub, m_origin, m_value->child(0), multipliedBack); - UpsilonValue* normalResult = normalModCase->appendNew<UpsilonValue>(m_proc, m_origin, result); - normalModCase->appendNew<ControlValue>(m_proc, Jump, m_origin, FrequentedBlock(m_block)); - - UpsilonValue* zeroResult = zeroDenCase->appendNew<UpsilonValue>( - m_proc, m_origin, - zeroDenCase->appendIntConstant(m_proc, m_value, 0)); - zeroDenCase->appendNew<ControlValue>(m_proc, Jump, m_origin, FrequentedBlock(m_block)); - - Value* phi = m_insertionSet.insert<Value>(m_index, Phi, m_value->type(), m_origin); - normalResult->setPhi(phi); - zeroResult->setPhi(phi); - m_value->replaceWithIdentity(phi); - m_changed = true; - } else - makeDivisionChill(Mod); - break; - } - - case Switch: { - SwitchValue* switchValue = m_value->as<SwitchValue>(); - Vector<SwitchCase> cases; - for (const SwitchCase& switchCase : *switchValue) - cases.append(switchCase); - std::sort( - cases.begin(), cases.end(), - [] (const SwitchCase& left, const SwitchCase& right) { - return left.caseValue() < right.caseValue(); - }); - m_block->values().removeLast(); - recursivelyBuildSwitch(cases, 0, false, cases.size(), m_block); - m_proc.deleteValue(switchValue); - m_block->updatePredecessorsAfter(); - m_changed = true; - break; - } - - default: - break; - } - } - m_insertionSet.execute(m_block); - } - - void makeDivisionChill(Opcode nonChillOpcode) - { - ASSERT(nonChillOpcode == Div || nonChillOpcode == Mod); - - // ARM supports this instruction natively. - if (isARM64()) - return; - - // We implement "res = ChillDiv/ChillMod(num, den)" as follows: - // - // if (den + 1 <=_unsigned 1) { - // if (!den) { - // res = 0; - // goto done; - // } - // if (num == -2147483648) { - // res = isDiv ? num : 0; - // goto done; - // } - // } - // res = num (/ or %) dev; - // done: - m_changed = true; - - Value* num = m_value->child(0); - Value* den = m_value->child(1); - - Value* one = m_insertionSet.insertIntConstant(m_index, m_value, 1); - Value* isDenOK = m_insertionSet.insert<Value>( - m_index, Above, m_origin, - m_insertionSet.insert<Value>(m_index, Add, m_origin, den, one), - one); - - BasicBlock* before = m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet); - - BasicBlock* normalDivCase = m_blockInsertionSet.insertBefore(m_block); - BasicBlock* shadyDenCase = m_blockInsertionSet.insertBefore(m_block); - BasicBlock* zeroDenCase = m_blockInsertionSet.insertBefore(m_block); - BasicBlock* neg1DenCase = m_blockInsertionSet.insertBefore(m_block); - BasicBlock* intMinCase = m_blockInsertionSet.insertBefore(m_block); - - before->replaceLastWithNew<ControlValue>( - m_proc, Branch, m_origin, isDenOK, - FrequentedBlock(normalDivCase, FrequencyClass::Normal), - FrequentedBlock(shadyDenCase, FrequencyClass::Rare)); - - UpsilonValue* normalResult = normalDivCase->appendNew<UpsilonValue>( - m_proc, m_origin, - normalDivCase->appendNew<Value>(m_proc, nonChillOpcode, m_origin, num, den)); - normalDivCase->appendNew<ControlValue>( - m_proc, Jump, m_origin, FrequentedBlock(m_block)); - - shadyDenCase->appendNew<ControlValue>( - m_proc, Branch, m_origin, den, - FrequentedBlock(neg1DenCase, FrequencyClass::Normal), - FrequentedBlock(zeroDenCase, FrequencyClass::Rare)); - - UpsilonValue* zeroResult = zeroDenCase->appendNew<UpsilonValue>( - m_proc, m_origin, - zeroDenCase->appendIntConstant(m_proc, m_value, 0)); - zeroDenCase->appendNew<ControlValue>( - m_proc, Jump, m_origin, FrequentedBlock(m_block)); - - int64_t badNumeratorConst = 0; - switch (m_value->type()) { - case Int32: - badNumeratorConst = std::numeric_limits<int32_t>::min(); - break; - case Int64: - badNumeratorConst = std::numeric_limits<int64_t>::min(); - break; - default: - ASSERT_NOT_REACHED(); - badNumeratorConst = 0; - } - - Value* badNumerator = - neg1DenCase->appendIntConstant(m_proc, m_value, badNumeratorConst); - - neg1DenCase->appendNew<ControlValue>( - m_proc, Branch, m_origin, - neg1DenCase->appendNew<Value>( - m_proc, Equal, m_origin, num, badNumerator), - FrequentedBlock(intMinCase, FrequencyClass::Rare), - FrequentedBlock(normalDivCase, FrequencyClass::Normal)); - - Value* intMinResult = nonChillOpcode == Div ? badNumerator : intMinCase->appendIntConstant(m_proc, m_value, 0); - UpsilonValue* intMinResultUpsilon = intMinCase->appendNew<UpsilonValue>( - m_proc, m_origin, intMinResult); - intMinCase->appendNew<ControlValue>( - m_proc, Jump, m_origin, FrequentedBlock(m_block)); - - Value* phi = m_insertionSet.insert<Value>( - m_index, Phi, m_value->type(), m_origin); - normalResult->setPhi(phi); - zeroResult->setPhi(phi); - intMinResultUpsilon->setPhi(phi); - - m_value->replaceWithIdentity(phi); - before->updatePredecessorsAfter(); - } - - void recursivelyBuildSwitch( - const Vector<SwitchCase>& cases, unsigned start, bool hardStart, unsigned end, - BasicBlock* before) - { - // FIXME: Add table-based switch lowering. - // https://bugs.webkit.org/show_bug.cgi?id=151141 - - // See comments in jit/BinarySwitch.cpp for a justification of this algorithm. The only - // thing we do differently is that we don't use randomness. - - const unsigned leafThreshold = 3; - - unsigned size = end - start; - - if (size <= leafThreshold) { - bool allConsecutive = false; - - if ((hardStart || (start && cases[start - 1].caseValue() == cases[start].caseValue() - 1)) - && end < cases.size() - && cases[end - 1].caseValue() == cases[end].caseValue() - 1) { - allConsecutive = true; - for (unsigned i = 0; i < size - 1; ++i) { - if (cases[start + i].caseValue() + 1 != cases[start + i + 1].caseValue()) { - allConsecutive = false; - break; - } - } - } - - unsigned limit = allConsecutive ? size - 1 : size; - - for (unsigned i = 0; i < limit; ++i) { - BasicBlock* nextCheck = m_blockInsertionSet.insertAfter(m_block); - before->appendNew<ControlValue>( - m_proc, Branch, m_origin, - before->appendNew<Value>( - m_proc, Equal, m_origin, m_value->child(0), - before->appendIntConstant( - m_proc, m_origin, m_value->child(0)->type(), - cases[start + i].caseValue())), - cases[start + i].target(), FrequentedBlock(nextCheck)); - - before = nextCheck; - } - - if (allConsecutive) { - before->appendNew<ControlValue>( - m_proc, Jump, m_origin, cases[end - 1].target()); - } else { - before->appendNew<ControlValue>( - m_proc, Jump, m_origin, m_value->as<SwitchValue>()->fallThrough()); - } - return; - } - - unsigned medianIndex = (start + end) / 2; - - BasicBlock* left = m_blockInsertionSet.insertAfter(m_block); - BasicBlock* right = m_blockInsertionSet.insertAfter(m_block); - - before->appendNew<ControlValue>( - m_proc, Branch, m_origin, - before->appendNew<Value>( - m_proc, LessThan, m_origin, m_value->child(0), - before->appendIntConstant( - m_proc, m_origin, m_value->child(0)->type(), - cases[medianIndex].caseValue())), - FrequentedBlock(left), FrequentedBlock(right)); - - recursivelyBuildSwitch(cases, start, hardStart, medianIndex, left); - recursivelyBuildSwitch(cases, medianIndex, true, end, right); - } - - Procedure& m_proc; - BlockInsertionSet m_blockInsertionSet; - InsertionSet m_insertionSet; - BasicBlock* m_block; - unsigned m_index; - Value* m_value; - Origin m_origin; - bool m_changed { false }; -}; - -bool lowerMacrosImpl(Procedure& proc) -{ - LowerMacros lowerMacros(proc); - return lowerMacros.run(); -} - -} // anonymous namespace - -bool lowerMacros(Procedure& proc) -{ - PhaseScope phaseScope(proc, "lowerMacros"); - bool result = lowerMacrosImpl(proc); - if (shouldValidateIR()) - RELEASE_ASSERT(!lowerMacrosImpl(proc)); - return result; -} - -} } // namespace JSC::B3 - -#endif // ENABLE(B3_JIT) - |
