1/* 2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef DFGArgumentPosition_h 27#define DFGArgumentPosition_h 28 29#include "DFGDoubleFormatState.h" 30#include "DFGVariableAccessData.h" 31#include "DFGVariableAccessDataDump.h" 32#include "SpeculatedType.h" 33 34namespace JSC { namespace DFG { 35 36class ArgumentPosition { 37public: 38 ArgumentPosition() 39 : m_prediction(SpecNone) 40 , m_doubleFormatState(EmptyDoubleFormatState) 41 , m_isProfitableToUnbox(false) 42 , m_shouldNeverUnbox(false) 43 { 44 } 45 46 void addVariable(VariableAccessData* variable) 47 { 48 m_variables.append(variable); 49 } 50 51 VariableAccessData* someVariable() const 52 { 53 if (m_variables.isEmpty()) 54 return 0; 55 return m_variables[0]->find(); 56 } 57 58 FlushFormat flushFormat() const 59 { 60 if (VariableAccessData* variable = someVariable()) 61 return variable->flushFormat(); 62 return DeadFlush; 63 } 64 65 bool mergeShouldNeverUnbox(bool shouldNeverUnbox) 66 { 67 return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | shouldNeverUnbox); 68 } 69 70 bool mergeArgumentPredictionAwareness() 71 { 72 bool changed = false; 73 for (unsigned i = 0; i < m_variables.size(); ++i) { 74 VariableAccessData* variable = m_variables[i]->find(); 75 changed |= mergeSpeculation(m_prediction, variable->argumentAwarePrediction()); 76 changed |= mergeDoubleFormatState(m_doubleFormatState, variable->doubleFormatState()); 77 changed |= mergeShouldNeverUnbox(variable->shouldNeverUnbox()); 78 } 79 if (!changed) 80 return false; 81 changed = false; 82 for (unsigned i = 0; i < m_variables.size(); ++i) { 83 VariableAccessData* variable = m_variables[i]->find(); 84 changed |= variable->mergeArgumentAwarePrediction(m_prediction); 85 changed |= variable->mergeDoubleFormatState(m_doubleFormatState); 86 changed |= variable->mergeShouldNeverUnbox(m_shouldNeverUnbox); 87 } 88 return changed; 89 } 90 91 bool mergeArgumentUnboxingAwareness() 92 { 93 bool changed = false; 94 for (unsigned i = 0; i < m_variables.size(); ++i) { 95 VariableAccessData* variable = m_variables[i]->find(); 96 changed |= checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | variable->isProfitableToUnbox()); 97 } 98 if (!changed) 99 return false; 100 changed = false; 101 for (unsigned i = 0; i < m_variables.size(); ++i) { 102 VariableAccessData* variable = m_variables[i]->find(); 103 changed |= variable->mergeIsProfitableToUnbox(m_isProfitableToUnbox); 104 } 105 return changed; 106 } 107 108 bool shouldUnboxIfPossible() const { return m_isProfitableToUnbox && !m_shouldNeverUnbox; } 109 110 SpeculatedType prediction() const { return m_prediction; } 111 DoubleFormatState doubleFormatState() const { return m_doubleFormatState; } 112 bool shouldUseDoubleFormat() const 113 { 114 return doubleFormatState() == UsingDoubleFormat && shouldUnboxIfPossible(); 115 } 116 117 void dump(PrintStream& out, Graph* graph) 118 { 119 for (unsigned i = 0; i < m_variables.size(); ++i) { 120 VariableAccessData* variable = m_variables[i]->find(); 121 VirtualRegister operand = variable->local(); 122 123 if (i) 124 out.print(" "); 125 126 if (operand.isArgument()) 127 out.print("arg", operand.toArgument(), "(", VariableAccessDataDump(*graph, variable), ")"); 128 else 129 out.print("r", operand.toLocal(), "(", VariableAccessDataDump(*graph, variable), ")"); 130 } 131 out.print("\n"); 132 } 133 134private: 135 SpeculatedType m_prediction; 136 DoubleFormatState m_doubleFormatState; 137 bool m_isProfitableToUnbox; 138 bool m_shouldNeverUnbox; 139 140 Vector<VariableAccessData*, 2> m_variables; 141}; 142 143} } // namespace JSC::DFG 144 145#endif // DFGArgumentPosition_h 146 147