Bug 1629791 part 3 - Define CacheIR ops in a YAML file and use that to generate a header file. r=iain

For now this generates just CACHE_IR_OPS and CACHE_IR_SHARED_OPS in CacheIROpsGenerated.h
but the plan is to use this to generate parts of the IR writer and compiler/transpiler
interface. The spewer could also potentially be improved now that each operand has a name
and more precise type.

Generating the IR writer will likely happen incrementally so that will give us
another chance to double check the precise types match what's in the YAML file.

Differential Revision: https://phabricator.services.mozilla.com/D70995

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2020-04-16 05:21:38 +00:00
parent aa4f4f7fe1
commit 72d50388f6
6 changed files with 1448 additions and 383 deletions

View File

@ -64,6 +64,7 @@ included_inclnames_to_ignore = set([
'frontend/smoosh_generated.h', # generated in $OBJDIR
'gc/StatsPhasesGenerated.h', # generated in $OBJDIR
'gc/StatsPhasesGenerated.inc', # generated in $OBJDIR
'jit/CacheIROpsGenerated.h', # generated in $OBJDIR
'jit/LOpcodesGenerated.h', # generated in $OBJDIR
'jit/MOpcodesGenerated.h', # generated in $OBJDIR
'jscustomallocator.h', # provided by embedders; allowed to be missing

View File

@ -12,6 +12,7 @@
#include "NamespaceImports.h"
#include "gc/Rooting.h"
#include "jit/CacheIROpsGenerated.h"
#include "jit/CompactBuffer.h"
#include "jit/ICState.h"
#include "jit/MacroAssembler.h"
@ -198,234 +199,6 @@ enum ArgType {
extern const uint32_t ArgLengths[];
} // namespace CacheIROpFormat
#ifdef JS_SIMULATOR
# define IF_SIMULATOR(x, y) x
#else
# define IF_SIMULATOR(x, y) y
#endif
#define CACHE_IR_OPS(_) /****************************************************/ \
_(GuardToObject, Id) \
_(GuardIsObjectOrNull, Id) \
_(GuardIsNullOrUndefined, Id) \
_(GuardIsNotNullOrUndefined, Id) \
_(GuardIsNull, Id) \
_(GuardIsUndefined, Id) \
_(GuardToBoolean, Id, Id) \
_(GuardToString, Id) \
_(GuardToSymbol, Id) \
_(GuardToBigInt, Id) \
_(GuardIsNumber, Id) \
_(GuardToInt32, Id, Id) \
_(GuardToInt32Index, Id, Id) \
_(GuardToTypedArrayIndex, Id, Id) \
_(GuardToInt32ModUint32, Id, Id) \
_(GuardToUint8Clamped, Id, Id) \
_(GuardType, Id, Byte) \
_(GuardShape, Id, Field) \
_(GuardGroup, Id, Field) \
_(GuardProto, Id, Field) \
_(GuardClass, Id, Byte) /* Guard per GuardClassKind */ \
_(GuardAnyClass, Id, Field) /* Guard an arbitrary class */ \
_(GuardCompartment, Id, Field, Field) \
_(GuardIsExtensible, Id) \
_(GuardIsNativeObject, Id) \
_(GuardIsProxy, Id) \
_(GuardHasProxyHandler, Id, Field) \
_(GuardNotDOMProxy, Id) \
_(GuardSpecificObject, Id, Field) \
_(GuardSpecificAtom, Id, Field) \
_(GuardSpecificSymbol, Id, Field) \
_(GuardSpecificInt32Immediate, Id, Int32) \
_(GuardSpecificNativeFunction, Id, Word) \
_(GuardMagicValue, Id, Byte) \
_(GuardFrameHasNoArgumentsObject, None) \
_(GuardNoDenseElements, Id) \
_(GuardAndGetIndexFromString, Id, Id) \
_(GuardAndGetInt32FromString, Id, Id) \
_(GuardAndGetNumberFromString, Id, Id) \
_(GuardAndGetNumberFromBoolean, Id, Id) \
_(GuardAndGetIterator, Id, Id, Field, Field) \
_(GuardHasGetterSetter, Id, Field) \
_(GuardGroupHasUnanalyzedNewScript, Field) \
_(GuardIndexIsNonNegative, Id) \
_(GuardIndexGreaterThanArrayLength, Id, Id) \
_(GuardIndexIsValidUpdateOrAdd, Id, Id) \
_(GuardIndexGreaterThanDenseInitLength, Id, Id) \
_(GuardTagNotEqual, Id, Id) \
_(GuardXrayExpandoShapeAndDefaultProto, Id, Byte, Field) \
_(GuardFunctionPrototype, Id, Id, Field) \
_(GuardNoAllocationMetadataBuilder, None) \
_(GuardObjectGroupNotPretenured, Field) \
_(GuardFunctionHasJitEntry, Id, Byte) \
_(GuardFunctionIsNative, Id) \
_(GuardFunctionIsConstructor, Id) \
_(GuardNotClassConstructor, Id) \
_(GuardFunApply, Id, Byte) \
_(LoadObject, Id, Field) \
_(LoadProto, Id, Id) \
_(LoadEnclosingEnvironment, Id, Id) \
_(LoadWrapperTarget, Id, Id) \
_(LoadValueTag, Id, Id) \
_(LoadArgumentFixedSlot, Id, Byte) \
_(LoadArgumentDynamicSlot, Id, Id, Byte) \
\
_(TruncateDoubleToUInt32, Id, Id) \
\
_(MegamorphicLoadSlotResult, Id, Field, Byte) \
_(MegamorphicLoadSlotByValueResult, Id, Id, Byte) \
_(MegamorphicStoreSlot, Id, Field, Id, Byte) \
_(MegamorphicSetElement, Id, Id, Id, Byte) \
_(MegamorphicHasPropResult, Id, Id, Byte) \
\
/* See CacheIR.cpp 'DOM proxies' comment. */ \
_(LoadDOMExpandoValue, Id, Id) \
_(LoadDOMExpandoValueGuardGeneration, Id, Field, Field, Id) \
_(LoadDOMExpandoValueIgnoreGeneration, Id, Id) \
_(GuardDOMExpandoMissingOrGuardShape, Id, Field) \
\
_(StoreFixedSlot, Id, Field, Id) \
_(StoreDynamicSlot, Id, Field, Id) \
_(AddAndStoreFixedSlot, Id, Field, Id, Byte, Field, Field) \
_(AddAndStoreDynamicSlot, Id, Field, Id, Byte, Field, Field) \
_(AllocateAndStoreDynamicSlot, Id, Field, Id, Byte, Field, Field, Field) \
_(StoreTypedObjectReferenceProperty, Id, Field, Byte, Byte, Id) \
_(StoreTypedObjectScalarProperty, Id, Field, Byte, Byte, Id) \
_(StoreDenseElement, Id, Id, Id) \
_(StoreDenseElementHole, Id, Id, Id, Byte) \
_(ArrayPush, Id, Id) \
_(ArrayJoinResult, Id) \
_(StoreTypedElement, Id, Byte, Byte, Id, Id, Byte) \
_(CallNativeSetter, Id, Id, Field) \
_(CallScriptedSetter, Id, Field, Id, Byte) \
_(CallSetArrayLength, Id, Byte, Id) \
_(CallProxySet, Id, Id, Field, Byte) \
_(CallProxySetByValue, Id, Id, Id, Byte) \
_(CallAddOrUpdateSparseElementHelper, Id, Id, Id, Byte) \
_(CallInt32ToString, Id, Id) \
_(CallNumberToString, Id, Id) \
_(BooleanToString, Id, Id) \
_(CallScriptedFunction, Id, Id, Byte) \
_(CallNativeFunction, Id, Id, Byte, IF_SIMULATOR(Field, Byte)) \
_(CallClassHook, Id, Id, Byte, Field) \
\
/* Meta ops generate no code, but contain data for BaselineInspector */ \
_(MetaTwoByte, Byte, Field, Field) \
\
/* The *Result ops load a value into the cache's result register. */ \
_(LoadFixedSlotResult, Id, Field) \
_(LoadDynamicSlotResult, Id, Field) \
_(LoadTypedObjectResult, Id, Byte, Byte, Field) \
_(LoadDenseElementResult, Id, Id) \
_(LoadDenseElementHoleResult, Id, Id) \
_(CallGetSparseElementResult, Id, Id) \
_(LoadDenseElementExistsResult, Id, Id) \
_(LoadTypedElementExistsResult, Id, Id, Byte) \
_(LoadDenseElementHoleExistsResult, Id, Id) \
_(LoadTypedElementResult, Id, Id, Byte, Byte, Byte) \
_(LoadInt32ArrayLengthResult, Id) \
_(LoadArgumentsObjectArgResult, Id, Id) \
_(LoadArgumentsObjectLengthResult, Id) \
_(LoadFunctionLengthResult, Id) \
_(LoadStringCharResult, Id, Id) \
_(LoadStringLengthResult, Id) \
_(LoadFrameCalleeResult, None) \
_(LoadFrameNumActualArgsResult, None) \
_(LoadFrameArgumentResult, Id) \
_(LoadEnvironmentFixedSlotResult, Id, Field) \
_(LoadEnvironmentDynamicSlotResult, Id, Field) \
_(LoadObjectResult, Id) \
_(LoadInt32Result, Id) \
_(LoadDoubleResult, Id) \
_(CallScriptedGetterResult, Id, Field, Byte) \
_(CallScriptedGetterByValueResult, Id, Field, Byte) \
_(CallNativeGetterResult, Id, Field) \
_(CallNativeGetterByValueResult, Id, Field) \
_(CallProxyGetResult, Id, Field) \
_(CallProxyGetByValueResult, Id, Id) \
_(CallProxyHasPropResult, Id, Id, Byte) \
_(CallObjectHasSparseElementResult, Id, Id) \
_(CallNativeGetElementResult, Id, Id) \
_(LoadUndefinedResult, None) \
_(LoadBooleanResult, Byte) \
_(LoadStringResult, Field) \
_(LoadInstanceOfObjectResult, Id, Id) \
_(LoadTypeOfObjectResult, Id) \
_(DoubleAddResult, Id, Id) \
_(DoubleSubResult, Id, Id) \
_(DoubleMulResult, Id, Id) \
_(DoubleDivResult, Id, Id) \
_(DoubleModResult, Id, Id) \
_(DoublePowResult, Id, Id) \
_(Int32AddResult, Id, Id) \
_(Int32SubResult, Id, Id) \
_(Int32MulResult, Id, Id) \
_(Int32DivResult, Id, Id) \
_(Int32ModResult, Id, Id) \
_(Int32PowResult, Id, Id) \
_(BigIntAddResult, Id, Id) \
_(BigIntSubResult, Id, Id) \
_(BigIntMulResult, Id, Id) \
_(BigIntDivResult, Id, Id) \
_(BigIntModResult, Id, Id) \
_(BigIntPowResult, Id, Id) \
_(Int32BitOrResult, Id, Id) \
_(Int32BitXorResult, Id, Id) \
_(Int32BitAndResult, Id, Id) \
_(Int32LeftShiftResult, Id, Id) \
_(Int32RightShiftResult, Id, Id) \
_(Int32URightShiftResult, Id, Id, Byte) \
_(Int32NotResult, Id) \
_(BigIntBitOrResult, Id, Id) \
_(BigIntBitXorResult, Id, Id) \
_(BigIntBitAndResult, Id, Id) \
_(BigIntLeftShiftResult, Id, Id) \
_(BigIntRightShiftResult, Id, Id) \
_(BigIntNotResult, Id) \
_(Int32NegationResult, Id) \
_(DoubleNegationResult, Id) \
_(BigIntNegationResult, Id) \
_(Int32IncResult, Id) \
_(Int32DecResult, Id) \
_(DoubleIncResult, Id) \
_(DoubleDecResult, Id) \
_(BigIntIncResult, Id) \
_(BigIntDecResult, Id) \
_(LoadInt32TruthyResult, Id) \
_(LoadDoubleTruthyResult, Id) \
_(LoadStringTruthyResult, Id) \
_(LoadObjectTruthyResult, Id) \
_(LoadBigIntTruthyResult, Id) \
_(LoadValueResult, Field) \
_(LoadNewObjectFromTemplateResult, Field, UInt32, UInt32) \
\
_(CallStringConcatResult, Id, Id) \
_(CallStringObjectConcatResult, Id, Id) \
_(CallIsSuspendedGeneratorResult, Id) \
\
_(CompareStringResult, Id, Id, Byte) \
_(CompareObjectResult, Id, Id, Byte) \
_(CompareSymbolResult, Id, Id, Byte) \
_(CompareInt32Result, Id, Id, Byte) \
_(CompareDoubleResult, Id, Id, Byte) \
_(CompareBigIntResult, Id, Id, Byte) \
_(CompareBigIntInt32Result, Id, Id, Byte) \
_(CompareInt32BigIntResult, Id, Id, Byte) \
_(CompareBigIntNumberResult, Id, Id, Byte) \
_(CompareNumberBigIntResult, Id, Id, Byte) \
_(CompareBigIntStringResult, Id, Id, Byte) \
_(CompareStringBigIntResult, Id, Id, Byte) \
_(CompareObjectUndefinedNullResult, Id, Byte) \
\
_(CallPrintString, Word) \
_(Breakpoint, None) \
\
_(TypeMonitorResult, None) \
_(ReturnFromIC, None) \
_(WrapResult, None)
#undef IS_SIMULATOR
enum class CacheOp {
#define DEFINE_OP(op, ...) op,
CACHE_IR_OPS(DEFINE_OP)

View File

@ -19,161 +19,6 @@ namespace jit {
class BaselineCacheIRCompiler;
class IonCacheIRCompiler;
// The ops below are defined in CacheIRCompiler and codegen is shared between
// BaselineCacheIRCompiler and IonCacheIRCompiler.
#define CACHE_IR_SHARED_OPS(_) \
_(GuardToObject) \
_(GuardIsNullOrUndefined) \
_(GuardIsNotNullOrUndefined) \
_(GuardIsNull) \
_(GuardIsUndefined) \
_(GuardIsObjectOrNull) \
_(GuardToBoolean) \
_(GuardToString) \
_(GuardToSymbol) \
_(GuardToBigInt) \
_(GuardIsNumber) \
_(GuardToInt32) \
_(GuardToInt32Index) \
_(GuardToTypedArrayIndex) \
_(GuardToInt32ModUint32) \
_(GuardToUint8Clamped) \
_(GuardType) \
_(GuardClass) \
_(GuardGroupHasUnanalyzedNewScript) \
_(GuardIsExtensible) \
_(GuardFunctionIsNative) \
_(GuardFunctionIsConstructor) \
_(GuardSpecificNativeFunction) \
_(GuardFunctionPrototype) \
_(GuardIsNativeObject) \
_(GuardIsProxy) \
_(GuardNotDOMProxy) \
_(GuardSpecificInt32Immediate) \
_(GuardMagicValue) \
_(GuardNoDenseElements) \
_(GuardAndGetInt32FromString) \
_(GuardAndGetNumberFromString) \
_(GuardAndGetNumberFromBoolean) \
_(GuardAndGetIndexFromString) \
_(GuardIndexIsNonNegative) \
_(GuardIndexGreaterThanArrayLength) \
_(GuardIndexIsValidUpdateOrAdd) \
_(GuardIndexGreaterThanDenseInitLength) \
_(GuardTagNotEqual) \
_(GuardXrayExpandoShapeAndDefaultProto) \
_(GuardNoAllocationMetadataBuilder) \
_(GuardObjectGroupNotPretenured) \
_(GuardFunctionHasJitEntry) \
_(GuardNotClassConstructor) \
_(LoadObject) \
_(LoadProto) \
_(LoadEnclosingEnvironment) \
_(LoadWrapperTarget) \
_(LoadValueTag) \
_(LoadDOMExpandoValue) \
_(LoadDOMExpandoValueIgnoreGeneration) \
_(LoadUndefinedResult) \
_(LoadBooleanResult) \
_(LoadInt32ArrayLengthResult) \
_(DoubleAddResult) \
_(DoubleSubResult) \
_(DoubleMulResult) \
_(DoubleDivResult) \
_(DoubleModResult) \
_(DoublePowResult) \
_(Int32AddResult) \
_(Int32SubResult) \
_(Int32MulResult) \
_(Int32DivResult) \
_(Int32ModResult) \
_(Int32PowResult) \
_(Int32BitOrResult) \
_(Int32BitXorResult) \
_(Int32BitAndResult) \
_(Int32LeftShiftResult) \
_(Int32RightShiftResult) \
_(Int32URightShiftResult) \
_(Int32NegationResult) \
_(Int32NotResult) \
_(Int32IncResult) \
_(Int32DecResult) \
_(DoubleIncResult) \
_(DoubleDecResult) \
_(DoubleNegationResult) \
_(BigIntAddResult) \
_(BigIntSubResult) \
_(BigIntMulResult) \
_(BigIntDivResult) \
_(BigIntModResult) \
_(BigIntPowResult) \
_(BigIntBitOrResult) \
_(BigIntBitXorResult) \
_(BigIntBitAndResult) \
_(BigIntLeftShiftResult) \
_(BigIntRightShiftResult) \
_(BigIntNegationResult) \
_(BigIntNotResult) \
_(BigIntIncResult) \
_(BigIntDecResult) \
_(TruncateDoubleToUInt32) \
_(LoadArgumentsObjectLengthResult) \
_(LoadFunctionLengthResult) \
_(LoadStringLengthResult) \
_(LoadStringCharResult) \
_(LoadArgumentsObjectArgResult) \
_(LoadInstanceOfObjectResult) \
_(LoadTypedObjectResult) \
_(LoadDenseElementResult) \
_(LoadDenseElementHoleResult) \
_(LoadDenseElementExistsResult) \
_(LoadDenseElementHoleExistsResult) \
_(LoadTypedElementExistsResult) \
_(LoadTypedElementResult) \
_(LoadObjectResult) \
_(LoadInt32Result) \
_(LoadDoubleResult) \
_(LoadTypeOfObjectResult) \
_(LoadInt32TruthyResult) \
_(LoadDoubleTruthyResult) \
_(LoadStringTruthyResult) \
_(LoadObjectTruthyResult) \
_(LoadBigIntTruthyResult) \
_(LoadNewObjectFromTemplateResult) \
_(CompareObjectResult) \
_(CompareSymbolResult) \
_(CompareInt32Result) \
_(CompareDoubleResult) \
_(CompareBigIntResult) \
_(CompareBigIntInt32Result) \
_(CompareInt32BigIntResult) \
_(CompareBigIntNumberResult) \
_(CompareNumberBigIntResult) \
_(CompareBigIntStringResult) \
_(CompareStringBigIntResult) \
_(CompareObjectUndefinedNullResult) \
_(ArrayJoinResult) \
_(StoreTypedElement) \
_(StoreTypedObjectScalarProperty) \
_(CallPrintString) \
_(Breakpoint) \
_(MegamorphicLoadSlotResult) \
_(MegamorphicLoadSlotByValueResult) \
_(MegamorphicStoreSlot) \
_(MegamorphicHasPropResult) \
_(CallObjectHasSparseElementResult) \
_(CallInt32ToString) \
_(CallNumberToString) \
_(BooleanToString) \
_(CallStringConcatResult) \
_(CallIsSuspendedGeneratorResult) \
_(CallNativeGetElementResult) \
_(CallProxyHasPropResult) \
_(CallProxyGetByValueResult) \
_(CallGetSparseElementResult) \
_(MetaTwoByte) \
_(WrapResult)
// [SMDDOC] CacheIR Value Representation and Tracking
//
// While compiling an IC stub the CacheIR compiler needs to keep track of the

1288
js/src/jit/CacheIROps.yaml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,152 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# This script generates jit/CacheIROpsGenerated.h from CacheIROps.yaml
import buildconfig
import yaml
from collections import OrderedDict
from six import StringIO
from mozbuild.preprocessor import Preprocessor
HEADER_TEMPLATE = """\
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef %(includeguard)s
#define %(includeguard)s
/* This file is generated by jit/GenerateCacheIRFiles.py. Do not edit! */
%(contents)s
#endif // %(includeguard)s
"""
def generate_header(c_out, includeguard, contents):
c_out.write(HEADER_TEMPLATE % {
'includeguard': includeguard,
'contents': contents,
})
def load_yaml(yaml_path):
# First invoke preprocessor.py so that we can use #ifdef JS_SIMULATOR in
# the YAML file.
pp = Preprocessor()
pp.context.update(buildconfig.defines['ALLDEFINES'])
pp.out = StringIO()
pp.do_filter('substitution')
pp.do_include(yaml_path)
contents = pp.out.getvalue()
# Load into an OrderedDict to ensure order is preserved. Note: Python 3.7+
# also preserves ordering for normal dictionaries.
# Code based on https://stackoverflow.com/a/21912744.
class OrderedLoader(yaml.Loader):
pass
def construct_mapping(loader, node):
loader.flatten_mapping(node)
return OrderedDict(loader.construct_pairs(node))
tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG
OrderedLoader.add_constructor(tag, construct_mapping)
return yaml.load(contents, OrderedLoader)
def generate_cacheirops_header(c_out, yaml_path):
"""Generate CacheIROpsGenerated.h from CacheIROps.yaml. The generated file
has a list of CacheIR ops, like this:
#define CACHE_IR_OPS(_)\
_(GuardToObject, Id)\
_(CompareObjectUndefinedNullResult, Id, Byte)\
...
It also contains a list of "shared" ops (implemented in the CacheIRCompiler
base class):
#define CACHE_IR_SHARED_OPS(_)\
_(GuardToObject)\
_(GuardIsObjectOrNull)\
...
"""
data = load_yaml(yaml_path)
# Mapping from operand types to the less precise types expected by current
# C++ code.
mapping = {
'ValId': 'Id',
'ObjId': 'Id',
'StrId': 'Id',
'SymId': 'Id',
'Int32Id': 'Id',
'NumId': 'Id',
'BigIntId': 'Id',
'ValTagId': 'Id',
'AnyId': 'Id',
'ShapeField': 'Field',
'GroupField': 'Field',
'ObjectField': 'Field',
'StringField': 'Field',
'SymbolField': 'Field',
'RawWordField': 'Field',
'DOMExpandoGenerationField': 'Field',
'IdField': 'Field',
'ValueField': 'Field',
'FieldOffset': 'Field',
'ByteImm': 'Byte',
'BoolImm': 'Byte',
'CallFlagsImm': 'Byte',
'TypedThingLayoutImm': 'Byte',
'ReferenceTypeImm': 'Byte',
'ScalarTypeImm': 'Byte',
'MetaTwoByteKindImm': 'Byte',
'JSOpImm': 'Byte',
'ValueTypeImm': 'Byte',
'GuardClassKindImm': 'Byte',
'JSWhyMagicImm': 'Byte',
'Int32Imm': 'Int32',
'UInt32Imm': 'UInt32',
'JSNativeImm': 'Word',
'StaticStringImm': 'Word',
}
ops_items = []
ops_shared = []
for op in data:
name = op['name']
operands = op['operands']
assert operands is None or isinstance(operands, OrderedDict)
shared = op['shared']
assert isinstance(shared, bool)
if operands:
operands_str = ', '.join([mapping[v] for v in operands.values()])
else:
operands_str = 'None'
ops_items.append('_({}, {})'.format(name, operands_str))
if shared:
ops_shared.append('_({})'.format(name))
contents = '#define CACHE_IR_OPS(_)\\\n'
contents += '\\\n'.join(ops_items)
contents += '\n\n'
contents += '#define CACHE_IR_SHARED_OPS(_)\\\n'
contents += '\\\n'.join(ops_shared)
contents += '\n\n'
generate_header(c_out, 'jit_CacheIROpsGenerated_h', contents)

View File

@ -252,3 +252,9 @@ GeneratedFile('LOpcodesGenerated.h',
script='GenerateOpcodeFiles.py',
entry_point='generate_lir_header',
inputs=lir_inputs)
# Generate jit/CacheIROpsGenerated.h from jit/CacheIROps.yaml
GeneratedFile('CacheIROpsGenerated.h',
script='GenerateCacheIRFiles.py',
entry_point='generate_cacheirops_header',
inputs=['CacheIROps.yaml'])