js/src/jit/TypePolicy.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/jit/TypePolicy.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,348 @@
     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 +#ifndef jit_TypePolicy_h
    1.11 +#define jit_TypePolicy_h
    1.12 +
    1.13 +#include "jit/IonAllocPolicy.h"
    1.14 +#include "jit/IonTypes.h"
    1.15 +
    1.16 +namespace js {
    1.17 +namespace jit {
    1.18 +
    1.19 +class MInstruction;
    1.20 +class MDefinition;
    1.21 +
    1.22 +// A type policy directs the type analysis phases, which insert conversion,
    1.23 +// boxing, unboxing, and type changes as necessary.
    1.24 +class TypePolicy
    1.25 +{
    1.26 +  public:
    1.27 +    // Analyze the inputs of the instruction and perform one of the following
    1.28 +    // actions for each input:
    1.29 +    //  * Nothing; the input already type-checks.
    1.30 +    //  * If untyped, optionally ask the input to try and specialize its value.
    1.31 +    //  * Replace the operand with a conversion instruction.
    1.32 +    //  * Insert an unconditional deoptimization (no conversion possible).
    1.33 +    virtual bool adjustInputs(TempAllocator &alloc, MInstruction *def) = 0;
    1.34 +};
    1.35 +
    1.36 +class BoxInputsPolicy : public TypePolicy
    1.37 +{
    1.38 +  protected:
    1.39 +    static MDefinition *boxAt(TempAllocator &alloc, MInstruction *at, MDefinition *operand);
    1.40 +
    1.41 +  public:
    1.42 +    static MDefinition *alwaysBoxAt(TempAllocator &alloc, MInstruction *at, MDefinition *operand);
    1.43 +    virtual bool adjustInputs(TempAllocator &alloc, MInstruction *def);
    1.44 +};
    1.45 +
    1.46 +class ArithPolicy : public BoxInputsPolicy
    1.47 +{
    1.48 +  protected:
    1.49 +    // Specifies three levels of specialization:
    1.50 +    //  - < Value. This input is expected and required.
    1.51 +    //  - == Any. Inputs are probably primitive.
    1.52 +    //  - == None. This op should not be specialized.
    1.53 +    MIRType specialization_;
    1.54 +
    1.55 +  public:
    1.56 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def);
    1.57 +};
    1.58 +
    1.59 +class BitwisePolicy : public BoxInputsPolicy
    1.60 +{
    1.61 +  protected:
    1.62 +    // Specifies three levels of specialization:
    1.63 +    //  - < Value. This input is expected and required.
    1.64 +    //  - == Any. Inputs are probably primitive.
    1.65 +    //  - == None. This op should not be specialized.
    1.66 +    MIRType specialization_;
    1.67 +
    1.68 +  public:
    1.69 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def);
    1.70 +
    1.71 +    MIRType specialization() const {
    1.72 +        return specialization_;
    1.73 +    }
    1.74 +};
    1.75 +
    1.76 +class ComparePolicy : public BoxInputsPolicy
    1.77 +{
    1.78 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def);
    1.79 +};
    1.80 +
    1.81 +// Policy for MTest instructions.
    1.82 +class TestPolicy : public BoxInputsPolicy
    1.83 +{
    1.84 +  public:
    1.85 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
    1.86 +};
    1.87 +
    1.88 +class TypeBarrierPolicy : public BoxInputsPolicy
    1.89 +{
    1.90 +  public:
    1.91 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
    1.92 +};
    1.93 +
    1.94 +class CallPolicy : public BoxInputsPolicy
    1.95 +{
    1.96 +  public:
    1.97 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def);
    1.98 +};
    1.99 +
   1.100 +// Policy for MPow. First operand Double; second Double or Int32.
   1.101 +class PowPolicy : public BoxInputsPolicy
   1.102 +{
   1.103 +    MIRType specialization_;
   1.104 +
   1.105 +  public:
   1.106 +    PowPolicy(MIRType specialization)
   1.107 +      : specialization_(specialization)
   1.108 +    { }
   1.109 +
   1.110 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
   1.111 +};
   1.112 +
   1.113 +// Expect a string for operand Op. If the input is a Value, it is unboxed.
   1.114 +template <unsigned Op>
   1.115 +class StringPolicy : public BoxInputsPolicy
   1.116 +{
   1.117 +  public:
   1.118 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
   1.119 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.120 +        return staticAdjustInputs(alloc, def);
   1.121 +    }
   1.122 +};
   1.123 +
   1.124 +// Expect a string for operand Op. Else a ToString instruction is inserted.
   1.125 +template <unsigned Op>
   1.126 +class ConvertToStringPolicy : public BoxInputsPolicy
   1.127 +{
   1.128 +  public:
   1.129 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
   1.130 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.131 +        return staticAdjustInputs(alloc, def);
   1.132 +    }
   1.133 +};
   1.134 +
   1.135 +// Expect an Int for operand Op. If the input is a Value, it is unboxed.
   1.136 +template <unsigned Op>
   1.137 +class IntPolicy : public BoxInputsPolicy
   1.138 +{
   1.139 +  public:
   1.140 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
   1.141 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.142 +        return staticAdjustInputs(alloc, def);
   1.143 +    }
   1.144 +};
   1.145 +
   1.146 +// Expect an Int for operand Op. Else a ToInt32 instruction is inserted.
   1.147 +template <unsigned Op>
   1.148 +class ConvertToInt32Policy : public BoxInputsPolicy
   1.149 +{
   1.150 +  public:
   1.151 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
   1.152 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.153 +        return staticAdjustInputs(alloc, def);
   1.154 +    }
   1.155 +};
   1.156 +
   1.157 +// Expect a double for operand Op. If the input is a Value, it is unboxed.
   1.158 +template <unsigned Op>
   1.159 +class DoublePolicy : public BoxInputsPolicy
   1.160 +{
   1.161 +  public:
   1.162 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
   1.163 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.164 +        return staticAdjustInputs(alloc, def);
   1.165 +    }
   1.166 +};
   1.167 +
   1.168 +// Expect a float32 for operand Op. If the input is a Value, it is unboxed.
   1.169 +template <unsigned Op>
   1.170 +class Float32Policy : public BoxInputsPolicy
   1.171 +{
   1.172 +  public:
   1.173 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
   1.174 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.175 +        return staticAdjustInputs(alloc, def);
   1.176 +    }
   1.177 +};
   1.178 +
   1.179 +// Expect a float32 OR a double for operand Op, but will prioritize Float32
   1.180 +// if the result type is set as such. If the input is a Value, it is unboxed.
   1.181 +template <unsigned Op>
   1.182 +class FloatingPointPolicy : public TypePolicy
   1.183 +{
   1.184 +    MIRType policyType_;
   1.185 +
   1.186 +  public:
   1.187 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.188 +        if (policyType_ == MIRType_Double)
   1.189 +            return DoublePolicy<Op>::staticAdjustInputs(alloc, def);
   1.190 +        return Float32Policy<Op>::staticAdjustInputs(alloc, def);
   1.191 +    }
   1.192 +    void setPolicyType(MIRType type) {
   1.193 +        policyType_ = type;
   1.194 +    }
   1.195 +};
   1.196 +
   1.197 +template <unsigned Op>
   1.198 +class NoFloatPolicy : public TypePolicy
   1.199 +{
   1.200 +  public:
   1.201 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
   1.202 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.203 +        return staticAdjustInputs(alloc, def);
   1.204 +    }
   1.205 +};
   1.206 +
   1.207 +// Box objects or strings as an input to a ToDouble instruction.
   1.208 +class ToDoublePolicy : public BoxInputsPolicy
   1.209 +{
   1.210 +  public:
   1.211 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
   1.212 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.213 +        return staticAdjustInputs(alloc, def);
   1.214 +    }
   1.215 +};
   1.216 +
   1.217 +// Box objects, strings and undefined as input to a ToInt32 instruction.
   1.218 +class ToInt32Policy : public BoxInputsPolicy
   1.219 +{
   1.220 +  public:
   1.221 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
   1.222 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
   1.223 +        return staticAdjustInputs(alloc, def);
   1.224 +    }
   1.225 +};
   1.226 +
   1.227 +template <unsigned Op>
   1.228 +class ObjectPolicy : public BoxInputsPolicy
   1.229 +{
   1.230 +  public:
   1.231 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
   1.232 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
   1.233 +        return staticAdjustInputs(alloc, ins);
   1.234 +    }
   1.235 +};
   1.236 +
   1.237 +// Single-object input. If the input is a Value, it is unboxed. If it is
   1.238 +// a primitive, we use ValueToNonNullObject.
   1.239 +class SingleObjectPolicy : public ObjectPolicy<0>
   1.240 +{ };
   1.241 +
   1.242 +template <unsigned Op>
   1.243 +class BoxPolicy : public BoxInputsPolicy
   1.244 +{
   1.245 +  public:
   1.246 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
   1.247 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
   1.248 +        return staticAdjustInputs(alloc, ins);
   1.249 +    }
   1.250 +};
   1.251 +
   1.252 +// Boxes everything except inputs of type Type.
   1.253 +template <unsigned Op, MIRType Type>
   1.254 +class BoxExceptPolicy : public TypePolicy
   1.255 +{
   1.256 +  public:
   1.257 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
   1.258 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
   1.259 +        return staticAdjustInputs(alloc, ins);
   1.260 +    }
   1.261 +};
   1.262 +
   1.263 +// Combine multiple policies.
   1.264 +template <class Lhs, class Rhs>
   1.265 +class MixPolicy : public TypePolicy
   1.266 +{
   1.267 +  public:
   1.268 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins) {
   1.269 +        return Lhs::staticAdjustInputs(alloc, ins) && Rhs::staticAdjustInputs(alloc, ins);
   1.270 +    }
   1.271 +    virtual bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
   1.272 +        return staticAdjustInputs(alloc, ins);
   1.273 +    }
   1.274 +};
   1.275 +
   1.276 +// Combine three policies.
   1.277 +template <class Policy1, class Policy2, class Policy3>
   1.278 +class Mix3Policy : public TypePolicy
   1.279 +{
   1.280 +  public:
   1.281 +    static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins) {
   1.282 +        return Policy1::staticAdjustInputs(alloc, ins) &&
   1.283 +               Policy2::staticAdjustInputs(alloc, ins) &&
   1.284 +               Policy3::staticAdjustInputs(alloc, ins);
   1.285 +    }
   1.286 +    virtual bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
   1.287 +        return staticAdjustInputs(alloc, ins);
   1.288 +    }
   1.289 +};
   1.290 +
   1.291 +class CallSetElementPolicy : public SingleObjectPolicy
   1.292 +{
   1.293 +  public:
   1.294 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def);
   1.295 +};
   1.296 +
   1.297 +// First operand will be boxed to a Value (except for an object)
   1.298 +// Second operand (if specified) will forcefully be unboxed to an object
   1.299 +class InstanceOfPolicy : public TypePolicy
   1.300 +{
   1.301 +  public:
   1.302 +    bool adjustInputs(TempAllocator &alloc, MInstruction *def);
   1.303 +};
   1.304 +
   1.305 +class StoreTypedArrayPolicy : public BoxInputsPolicy
   1.306 +{
   1.307 +  protected:
   1.308 +    bool adjustValueInput(TempAllocator &alloc, MInstruction *ins, int arrayType, MDefinition *value, int valueOperand);
   1.309 +
   1.310 +  public:
   1.311 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
   1.312 +};
   1.313 +
   1.314 +class StoreTypedArrayHolePolicy : public StoreTypedArrayPolicy
   1.315 +{
   1.316 +  public:
   1.317 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
   1.318 +};
   1.319 +
   1.320 +class StoreTypedArrayElementStaticPolicy : public StoreTypedArrayPolicy
   1.321 +{
   1.322 +  public:
   1.323 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
   1.324 +};
   1.325 +
   1.326 +// Accepts integers and doubles. Everything else is boxed.
   1.327 +class ClampPolicy : public BoxInputsPolicy
   1.328 +{
   1.329 +  public:
   1.330 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
   1.331 +};
   1.332 +
   1.333 +class FilterTypeSetPolicy : public BoxInputsPolicy
   1.334 +{
   1.335 +  public:
   1.336 +    bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
   1.337 +};
   1.338 +
   1.339 +static inline bool
   1.340 +CoercesToDouble(MIRType type)
   1.341 +{
   1.342 +    if (type == MIRType_Undefined || IsFloatingPointType(type))
   1.343 +        return true;
   1.344 +    return false;
   1.345 +}
   1.346 +
   1.347 +
   1.348 +} // namespace jit
   1.349 +} // namespace js
   1.350 +
   1.351 +#endif /* jit_TypePolicy_h */

mercurial