2 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "DFGDriver.h"
35 #include "DFGArgumentsSimplificationPhase.h"
36 #include "DFGBackwardsPropagationPhase.h"
37 #include "DFGByteCodeParser.h"
38 #include "DFGCFAPhase.h"
39 #include "DFGCFGSimplificationPhase.h"
40 #include "DFGCPSRethreadingPhase.h"
41 #include "DFGCSEPhase.h"
42 #include "DFGConstantFoldingPhase.h"
43 #include "DFGDCEPhase.h"
44 #include "DFGFixupPhase.h"
45 #include "DFGJITCompiler.h"
46 #include "DFGPredictionInjectionPhase.h"
47 #include "DFGPredictionPropagationPhase.h"
48 #include "DFGTypeCheckHoistingPhase.h"
49 #include "DFGUnificationPhase.h"
50 #include "DFGValidate.h"
51 #include "DFGVirtualRegisterAllocationPhase.h"
52 #include "Operations.h"
55 namespace JSC
{ namespace DFG
{
57 static unsigned numCompilations
;
59 unsigned getNumCompilations()
61 return numCompilations
;
64 enum CompileMode
{ CompileFunction
, CompileOther
};
65 inline bool compile(CompileMode compileMode
, ExecState
* exec
, CodeBlock
* codeBlock
, JITCode
& jitCode
, MacroAssemblerCodePtr
* jitCodeWithArityCheck
, unsigned osrEntryBytecodeIndex
)
67 SamplingRegion
samplingRegion("DFG Compilation (Driver)");
72 ASSERT(codeBlock
->alternative());
73 ASSERT(codeBlock
->alternative()->getJITType() == JITCode::BaselineJIT
);
75 ASSERT(osrEntryBytecodeIndex
!= UINT_MAX
);
77 if (!Options::useDFGJIT())
80 if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock
->instructionCount()))
83 if (logCompilationChanges())
84 dataLog("DFG compiling ", *codeBlock
, ", number of instructions = ", codeBlock
->instructionCount(), "\n");
86 // Derive our set of must-handle values. The compilation must be at least conservative
87 // enough to allow for OSR entry with these values.
88 unsigned numVarsWithValues
;
89 if (osrEntryBytecodeIndex
)
90 numVarsWithValues
= codeBlock
->m_numVars
;
92 numVarsWithValues
= 0;
93 Operands
<JSValue
> mustHandleValues(codeBlock
->numParameters(), numVarsWithValues
);
94 for (size_t i
= 0; i
< mustHandleValues
.size(); ++i
) {
95 int operand
= mustHandleValues
.operandForIndex(i
);
96 if (operandIsArgument(operand
)
97 && !operandToArgument(operand
)
98 && compileMode
== CompileFunction
99 && codeBlock
->specializationKind() == CodeForConstruct
) {
100 // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
101 // also never be used. It doesn't matter what we put into the value for this,
102 // but it has to be an actual value that can be grokked by subsequent DFG passes,
103 // so we sanitize it here by turning it into Undefined.
104 mustHandleValues
[i
] = jsUndefined();
106 mustHandleValues
[i
] = exec
->uncheckedR(operand
).jsValue();
109 Graph
dfg(exec
->vm(), codeBlock
, osrEntryBytecodeIndex
, mustHandleValues
);
110 if (!parse(exec
, dfg
))
113 // By this point the DFG bytecode parser will have potentially mutated various tables
114 // in the CodeBlock. This is a good time to perform an early shrink, which is more
115 // powerful than a late one. It's safe to do so because we haven't generated any code
116 // that references any of the tables directly, yet.
117 codeBlock
->shrinkToFit(CodeBlock::EarlyShrink
);
119 if (validationEnabled())
122 performCPSRethreading(dfg
);
123 performUnification(dfg
);
124 performPredictionInjection(dfg
);
126 if (validationEnabled())
129 performBackwardsPropagation(dfg
);
130 performPredictionPropagation(dfg
);
132 performTypeCheckHoisting(dfg
);
134 dfg
.m_fixpointState
= FixpointNotConverged
;
137 performArgumentsSimplification(dfg
);
138 performCPSRethreading(dfg
); // This should usually be a no-op since CSE rarely dethreads, and arguments simplification rarely does anything.
140 performConstantFolding(dfg
);
141 performCFGSimplification(dfg
);
143 dfg
.m_fixpointState
= FixpointConverged
;
145 performStoreElimination(dfg
);
146 performCPSRethreading(dfg
);
148 performVirtualRegisterAllocation(dfg
);
150 GraphDumpMode modeForFinalValidate
= DumpGraph
;
151 if (verboseCompilationEnabled()) {
152 dataLogF("Graph after optimization:\n");
154 modeForFinalValidate
= DontDumpGraph
;
156 if (validationEnabled())
157 validate(dfg
, modeForFinalValidate
);
159 JITCompiler
dataFlowJIT(dfg
);
161 if (compileMode
== CompileFunction
) {
162 ASSERT(jitCodeWithArityCheck
);
164 result
= dataFlowJIT
.compileFunction(jitCode
, *jitCodeWithArityCheck
);
166 ASSERT(compileMode
== CompileOther
);
167 ASSERT(!jitCodeWithArityCheck
);
169 result
= dataFlowJIT
.compile(jitCode
);
175 bool tryCompile(ExecState
* exec
, CodeBlock
* codeBlock
, JITCode
& jitCode
, unsigned bytecodeIndex
)
177 return compile(CompileOther
, exec
, codeBlock
, jitCode
, 0, bytecodeIndex
);
180 bool tryCompileFunction(ExecState
* exec
, CodeBlock
* codeBlock
, JITCode
& jitCode
, MacroAssemblerCodePtr
& jitCodeWithArityCheck
, unsigned bytecodeIndex
)
182 return compile(CompileFunction
, exec
, codeBlock
, jitCode
, &jitCodeWithArityCheck
, bytecodeIndex
);
185 } } // namespace JSC::DFG
187 #endif // ENABLE(DFG_JIT)