js/src/jit/IonOptimizationLevels.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/jit/IonOptimizationLevels.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,152 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99:
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "jit/IonOptimizationLevels.h"
    1.11 +
    1.12 +#include "jsanalyze.h"
    1.13 +#include "jsscript.h"
    1.14 +
    1.15 +using namespace js;
    1.16 +using namespace js::jit;
    1.17 +
    1.18 +namespace js {
    1.19 +namespace jit {
    1.20 +
    1.21 +OptimizationInfos js_IonOptimizations;
    1.22 +
    1.23 +void
    1.24 +OptimizationInfo::initNormalOptimizationInfo()
    1.25 +{
    1.26 +    level_ = Optimization_Normal;
    1.27 +
    1.28 +    eaa_ = true;
    1.29 +    edgeCaseAnalysis_ = true;
    1.30 +    eliminateRedundantChecks_ = true;
    1.31 +    inlineInterpreted_ = true;
    1.32 +    inlineNative_ = true;
    1.33 +    gvn_ = true;
    1.34 +    gvnKind_ = GVN_Optimistic;
    1.35 +    licm_ = true;
    1.36 +    uce_ = true;
    1.37 +    rangeAnalysis_ = true;
    1.38 +    registerAllocator_ = RegisterAllocator_LSRA;
    1.39 +
    1.40 +    inlineMaxTotalBytecodeLength_ = 1000;
    1.41 +    inliningMaxCallerBytecodeLength_ = 10000;
    1.42 +    maxInlineDepth_ = 3;
    1.43 +    smallFunctionMaxInlineDepth_ = 10;
    1.44 +    usesBeforeCompile_ = 1000;
    1.45 +    usesBeforeInliningFactor_ = 0.125;
    1.46 +}
    1.47 +
    1.48 +void
    1.49 +OptimizationInfo::initAsmjsOptimizationInfo()
    1.50 +{
    1.51 +    // The AsmJS optimization level
    1.52 +    // Disables some passes that don't work well with asmjs.
    1.53 +
    1.54 +    // Take normal option values for not specified values.
    1.55 +    initNormalOptimizationInfo();
    1.56 +
    1.57 +    level_ = Optimization_AsmJS;
    1.58 +    edgeCaseAnalysis_ = false;
    1.59 +    eliminateRedundantChecks_ = false;
    1.60 +    registerAllocator_ = RegisterAllocator_Backtracking;
    1.61 +}
    1.62 +
    1.63 +uint32_t
    1.64 +OptimizationInfo::usesBeforeCompile(JSScript *script, jsbytecode *pc) const
    1.65 +{
    1.66 +    JS_ASSERT(pc == nullptr || pc == script->code() || JSOp(*pc) == JSOP_LOOPENTRY);
    1.67 +
    1.68 +    if (pc == script->code())
    1.69 +        pc = nullptr;
    1.70 +
    1.71 +    uint32_t minUses = usesBeforeCompile_;
    1.72 +    if (js_JitOptions.forceDefaultIonUsesBeforeCompile)
    1.73 +        minUses = js_JitOptions.forcedDefaultIonUsesBeforeCompile;
    1.74 +
    1.75 +    // If the script is too large to compile on the main thread, we can still
    1.76 +    // compile it off thread. In these cases, increase the use count threshold
    1.77 +    // to improve the compilation's type information and hopefully avoid later
    1.78 +    // recompilation.
    1.79 +
    1.80 +    if (script->length() > MAX_MAIN_THREAD_SCRIPT_SIZE)
    1.81 +        minUses = minUses * (script->length() / (double) MAX_MAIN_THREAD_SCRIPT_SIZE);
    1.82 +
    1.83 +    uint32_t numLocalsAndArgs = analyze::TotalSlots(script);
    1.84 +    if (numLocalsAndArgs > MAX_MAIN_THREAD_LOCALS_AND_ARGS)
    1.85 +        minUses = minUses * (numLocalsAndArgs / (double) MAX_MAIN_THREAD_LOCALS_AND_ARGS);
    1.86 +
    1.87 +    if (!pc || js_JitOptions.eagerCompilation)
    1.88 +        return minUses;
    1.89 +
    1.90 +    // It's more efficient to enter outer loops, rather than inner loops, via OSR.
    1.91 +    // To accomplish this, we use a slightly higher threshold for inner loops.
    1.92 +    // Note that the loop depth is always > 0 so we will prefer non-OSR over OSR.
    1.93 +    uint32_t loopDepth = LoopEntryDepthHint(pc);
    1.94 +    JS_ASSERT(loopDepth > 0);
    1.95 +    return minUses + loopDepth * 100;
    1.96 +}
    1.97 +
    1.98 +OptimizationInfos::OptimizationInfos()
    1.99 +{
   1.100 +    infos_[Optimization_Normal - 1].initNormalOptimizationInfo();
   1.101 +    infos_[Optimization_AsmJS - 1].initAsmjsOptimizationInfo();
   1.102 +
   1.103 +#ifdef DEBUG
   1.104 +    OptimizationLevel level = firstLevel();
   1.105 +    while (!isLastLevel(level)) {
   1.106 +        OptimizationLevel next = nextLevel(level);
   1.107 +        JS_ASSERT(level < next);
   1.108 +        level = next;
   1.109 +    }
   1.110 +#endif
   1.111 +}
   1.112 +
   1.113 +OptimizationLevel
   1.114 +OptimizationInfos::nextLevel(OptimizationLevel level) const
   1.115 +{
   1.116 +    JS_ASSERT(!isLastLevel(level));
   1.117 +    switch (level) {
   1.118 +      case Optimization_DontCompile:
   1.119 +        return Optimization_Normal;
   1.120 +      default:
   1.121 +        MOZ_ASSUME_UNREACHABLE("Unknown optimization level.");
   1.122 +    }
   1.123 +}
   1.124 +
   1.125 +OptimizationLevel
   1.126 +OptimizationInfos::firstLevel() const
   1.127 +{
   1.128 +    return nextLevel(Optimization_DontCompile);
   1.129 +}
   1.130 +
   1.131 +bool
   1.132 +OptimizationInfos::isLastLevel(OptimizationLevel level) const
   1.133 +{
   1.134 +    return level == Optimization_Normal;
   1.135 +}
   1.136 +
   1.137 +OptimizationLevel
   1.138 +OptimizationInfos::levelForScript(JSScript *script, jsbytecode *pc) const
   1.139 +{
   1.140 +    OptimizationLevel prev = Optimization_DontCompile;
   1.141 +
   1.142 +    while (!isLastLevel(prev)) {
   1.143 +        OptimizationLevel level = nextLevel(prev);
   1.144 +        const OptimizationInfo *info = get(level);
   1.145 +        if (script->getUseCount() < info->usesBeforeCompile(script, pc))
   1.146 +            return prev;
   1.147 +
   1.148 +        prev = level;
   1.149 +    }
   1.150 +
   1.151 +    return prev;
   1.152 +}
   1.153 +
   1.154 +} // namespace jit
   1.155 +} // namespace js

mercurial