WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
the patch
blah.patch (text/plain), 99.46 KB, created by
Filip Pizlo
on 2016-09-28 21:36:18 PDT
(
hide
)
Description:
the patch
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2016-09-28 21:36:18 PDT
Size:
99.46 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 206574) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,166 @@ >+2016-09-28 Filip Pizlo <fpizlo@apple.com> >+ >+ B3 opcodes should leave room for flags >+ https://bugs.webkit.org/show_bug.cgi?id=162692 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ It used to be that the main thing that determined what a Value did was the opcode. The >+ Opcode was how you knew what subclass of Value you had. The opcode told you what the Value >+ actually did. This change replaces Opcode with Kind, which is a tuple of opcode and other >+ stuff. >+ >+ Opcodes are great, and that's how most compilers work. But opcodes are one-dimensional. Here >+ is how this manifests. Say you have an opcode, like Load. You will be happy if your IR has >+ one Load opcode. But then, you might add Load8S/Load8Z/Load16S/Load16Z opcodes, as we have >+ done in B3. B3 has one dimension of Load opcodes, which determines something like the C type >+ of the load. But in the very near future, we will want to add two more dimensions to Loads: >+ >+ - A flag to say if the load traps. >+ - A flag to say if the load has acquire semantics. >+ >+ Mapping these three dimensions (type, trap, acquire) onto the one-dimensional Opcode space >+ would create mayham: Load8S, Load8STrap, Load8SAcquire, Load8STrapAcquire, Load8Z, >+ Load8ZTrap, etc. >+ >+ This happens in other parts of the IR. For example, we have a dimension of arithmetic >+ operations: add, sub, mul, div, mod, etc. Then we have the chill flag. But since opcodes >+ are one-dimensional, that means having ChillDiv and ChillMod, and tons of places in the >+ compiler that case on both Div and ChillDiv, or case on both Mod and ChillMod, since they >+ are only interested in the kind of arithmetic being done and not the chillness. >+ >+ Though the examples all involve bits (chill or not, trapping or not, etc), I can imagine >+ other properties that behave more like small enums, like if we fill out more memory ordering >+ modes other than just "acquire? yes/no". There will eventually have to be something like a >+ std::memory_order associated with memory accesses. >+ >+ One approach to this problem is to have a Value subclass that contains fields with the meta >+ data. I don't like this for two reasons: >+ >+ - In bug 162688, I want to make trapping memory accesses have stackmaps. This means that a >+ trapping memory access would have a different Value subclass than a non-trapping memory >+ access. So, this meta-data needs to channel into ValueType::accepts(). Currently that >+ takes Opcode and nothing else. >+ >+ - Compiler IRs are all about making common tasks easy. If it becomes commonplace for opcodes >+ to require a custom Value subclass just for a bit then that's not very easy. >+ >+ This change addresses this problem by making the compiler pass around Kinds rather than >+ Opcodes. A Kind contains an Opcode as well as any number of opcode-specific bits. This >+ change demonstrates how Kind should be used by converting chillness to it. Kind has >+ hasIsChill(), isChill(), and setIsChill() methods. hasIsChill() is true only for Div and >+ Mod. setIsChill() asserts if !hasIsChill(). If you want to create a Chill Div, you say >+ chill(Div). IR dumps will print it like this: >+ >+ Int32 @38 = Div<Chill>(@36, @37, DFG:@24, ControlDependent) >+ >+ Where "Div<Chill>" is how a Kind that hasExtraBits() dumps itself. If a Kind does not >+ hasExtraBits() (the normal case) then it dumps like a normal Opcode (without the "<>"). >+ >+ I replaced many uses of Opcode with Kind. New code has to be mindful that Opcode may not be >+ the right way to summarize what a value does, and so in many cases it's better to carry >+ around a Kind instead - especially if you will use it to stamp out new Values. Opcode is no >+ longer sufficient to perform a dynamic Value cast, since that code now uses Kind. ValueKey >+ now wants a Kind instead of an Opcode. All Value constructors now take Kind instead of >+ Opcode. But most opcodes don't get any extra Kind bits, and so the code that operates on >+ those opcodes is largely unchanged. >+ >+ * CMakeLists.txt: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * b3/B3ArgumentRegValue.h: >+ * b3/B3CCallValue.h: >+ * b3/B3CheckValue.cpp: >+ (JSC::B3::CheckValue::convertToAdd): >+ (JSC::B3::CheckValue::CheckValue): >+ * b3/B3CheckValue.h: >+ (JSC::B3::CheckValue::accepts): >+ * b3/B3Const32Value.h: >+ * b3/B3Const64Value.h: >+ * b3/B3ConstDoubleValue.h: >+ * b3/B3ConstFloatValue.h: >+ * b3/B3FenceValue.h: >+ * b3/B3Kind.cpp: Added. >+ (JSC::B3::Kind::dump): >+ * b3/B3Kind.h: Added. >+ (JSC::B3::Kind::Kind): >+ (JSC::B3::Kind::opcode): >+ (JSC::B3::Kind::setOpcode): >+ (JSC::B3::Kind::hasExtraBits): >+ (JSC::B3::Kind::hasIsChill): >+ (JSC::B3::Kind::isChill): >+ (JSC::B3::Kind::setIsChill): >+ (JSC::B3::Kind::operator==): >+ (JSC::B3::Kind::operator!=): >+ (JSC::B3::Kind::operator<): >+ (JSC::B3::Kind::operator>): >+ (JSC::B3::Kind::operator<=): >+ (JSC::B3::Kind::operator>=): >+ (JSC::B3::Kind::hash): >+ (JSC::B3::Kind::isHashTableDeletedValue): >+ (JSC::B3::chill): >+ (JSC::B3::KindHash::hash): >+ (JSC::B3::KindHash::equal): >+ * b3/B3LowerMacros.cpp: >+ * b3/B3LowerToAir.cpp: >+ (JSC::B3::Air::LowerToAir::lower): >+ * b3/B3MemoryValue.h: >+ * b3/B3Opcode.cpp: >+ (WTF::printInternal): >+ * b3/B3Opcode.h: >+ * b3/B3PatchpointValue.h: >+ (JSC::B3::PatchpointValue::accepts): >+ * b3/B3ReduceStrength.cpp: >+ * b3/B3SlotBaseValue.h: >+ * b3/B3StackmapValue.cpp: >+ (JSC::B3::StackmapValue::StackmapValue): >+ * b3/B3StackmapValue.h: >+ * b3/B3SwitchValue.h: >+ (JSC::B3::SwitchValue::accepts): >+ * b3/B3UpsilonValue.h: >+ * b3/B3Validate.cpp: >+ * b3/B3Value.cpp: >+ (JSC::B3::Value::dump): >+ (JSC::B3::Value::deepDump): >+ (JSC::B3::Value::invertedCompare): >+ (JSC::B3::Value::effects): >+ (JSC::B3::Value::key): >+ (JSC::B3::Value::typeFor): >+ (JSC::B3::Value::badKind): >+ (JSC::B3::Value::badOpcode): Deleted. >+ * b3/B3Value.h: >+ * b3/B3ValueInlines.h: >+ (JSC::B3::Value::as): >+ * b3/B3ValueKey.cpp: >+ (JSC::B3::ValueKey::dump): >+ (JSC::B3::ValueKey::materialize): >+ * b3/B3ValueKey.h: >+ (JSC::B3::ValueKey::ValueKey): >+ (JSC::B3::ValueKey::kind): >+ (JSC::B3::ValueKey::opcode): >+ (JSC::B3::ValueKey::operator==): >+ (JSC::B3::ValueKey::hash): >+ * b3/B3ValueKeyInlines.h: >+ (JSC::B3::ValueKey::ValueKey): >+ * b3/B3VariableValue.cpp: >+ (JSC::B3::VariableValue::VariableValue): >+ * b3/B3VariableValue.h: >+ * b3/testb3.cpp: >+ (JSC::B3::testChillDiv): >+ (JSC::B3::testChillDivTwice): >+ (JSC::B3::testChillDiv64): >+ (JSC::B3::testChillModArg): >+ (JSC::B3::testChillModArgs): >+ (JSC::B3::testChillModImms): >+ (JSC::B3::testChillModArg32): >+ (JSC::B3::testChillModArgs32): >+ (JSC::B3::testChillModImms32): >+ (JSC::B3::testSwitchChillDiv): >+ (JSC::B3::testEntrySwitchWithCommonPaths): >+ (JSC::B3::testEntrySwitchWithCommonPathsAndNonTrivialEntrypoint): >+ * ftl/FTLOutput.cpp: >+ (JSC::FTL::Output::chillDiv): >+ (JSC::FTL::Output::chillMod): >+ > 2016-09-28 Saam Barati <sbarati@apple.com> > > stringProtoFuncRepeatCharacter will return `null` when it should not >Index: Source/JavaScriptCore/CMakeLists.txt >=================================================================== >--- Source/JavaScriptCore/CMakeLists.txt (revision 206524) >+++ Source/JavaScriptCore/CMakeLists.txt (working copy) >@@ -133,6 +133,7 @@ set(JavaScriptCore_SOURCES > b3/B3HeapRange.cpp > b3/B3InferSwitches.cpp > b3/B3InsertionSet.cpp >+ b3/B3Kind.cpp > b3/B3LegalizeMemoryOffsets.cpp > b3/B3LowerMacros.cpp > b3/B3LowerMacrosAfterOptimizations.cpp >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 206524) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -722,6 +722,8 @@ > 0FDB2CEA174896C7007B3C1B /* ConcurrentJITLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDB2CE9174896C7007B3C1B /* ConcurrentJITLock.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */; }; > 0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */; }; >+ 0FDF67D21D9C6D27001B9825 /* B3Kind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDF67D11D9C6086001B9825 /* B3Kind.h */; }; >+ 0FDF67D31D9C6D2A001B9825 /* B3Kind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDF67D01D9C6086001B9825 /* B3Kind.cpp */; }; > 0FDF70851D3F2C2200927449 /* AirLowerEntrySwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDF70831D3F2C1F00927449 /* AirLowerEntrySwitch.cpp */; }; > 0FDF70861D3F2C2500927449 /* AirLowerEntrySwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDF70841D3F2C1F00927449 /* AirLowerEntrySwitch.h */; }; > 0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -2975,6 +2977,8 @@ > 0FDB2CE9174896C7007B3C1B /* ConcurrentJITLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConcurrentJITLock.h; sourceTree = "<group>"; }; > 0FDDBFB21666EED500C55FEF /* DFGVariableAccessDataDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessDataDump.cpp; path = dfg/DFGVariableAccessDataDump.cpp; sourceTree = "<group>"; }; > 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessDataDump.h; path = dfg/DFGVariableAccessDataDump.h; sourceTree = "<group>"; }; >+ 0FDF67D01D9C6086001B9825 /* B3Kind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3Kind.cpp; path = b3/B3Kind.cpp; sourceTree = "<group>"; }; >+ 0FDF67D11D9C6086001B9825 /* B3Kind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3Kind.h; path = b3/B3Kind.h; sourceTree = "<group>"; }; > 0FDF70831D3F2C1F00927449 /* AirLowerEntrySwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirLowerEntrySwitch.cpp; path = b3/air/AirLowerEntrySwitch.cpp; sourceTree = "<group>"; }; > 0FDF70841D3F2C1F00927449 /* AirLowerEntrySwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirLowerEntrySwitch.h; path = b3/air/AirLowerEntrySwitch.h; sourceTree = "<group>"; }; > 0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentsMode.h; sourceTree = "<group>"; }; >@@ -4869,6 +4873,8 @@ > 0FEC85B41BE1462F0080FF74 /* B3InsertionSet.cpp */, > 0FEC85B51BE1462F0080FF74 /* B3InsertionSet.h */, > 0FEC85B61BE1462F0080FF74 /* B3InsertionSetInlines.h */, >+ 0FDF67D01D9C6086001B9825 /* B3Kind.cpp */, >+ 0FDF67D11D9C6086001B9825 /* B3Kind.h */, > 436E54511C468E5F00B5AF73 /* B3LegalizeMemoryOffsets.cpp */, > 436E54521C468E5F00B5AF73 /* B3LegalizeMemoryOffsets.h */, > 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */, >@@ -7728,6 +7734,7 @@ > 0F64EAF31C4ECD0600621E9B /* AirArgInlines.h in Headers */, > A5EA710519F6DE740098F5EC /* generate_objc_configuration_header.py in Headers */, > DC69B99D1D15F914002E3C00 /* B3InferSwitches.h in Headers */, >+ 0FDF67D21D9C6D27001B9825 /* B3Kind.h in Headers */, > A5EA710619F6DE760098F5EC /* generate_objc_configuration_implementation.py in Headers */, > 0F7C39FF1C90C55B00480151 /* DFGOpInfo.h in Headers */, > A5EA710719F6DE780098F5EC /* generate_objc_protocol_type_conversions_header.py in Headers */, >@@ -9080,6 +9087,7 @@ > 0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */, > 0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */, > 0F338E121BF0276C0013C88F /* B3OpaqueByproducts.cpp in Sources */, >+ 0FDF67D31D9C6D2A001B9825 /* B3Kind.cpp in Sources */, > 0F8F2B99172F04FF007DBDA5 /* DFGDesiredIdentifiers.cpp in Sources */, > C2C0F7CD17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp in Sources */, > 0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */, >Index: Source/JavaScriptCore/b3/B3ArgumentRegValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3ArgumentRegValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3ArgumentRegValue.h (working copy) >@@ -35,7 +35,7 @@ namespace JSC { namespace B3 { > > class JS_EXPORT_PRIVATE ArgumentRegValue : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == ArgumentReg; } >+ static bool accepts(Kind kind) { return kind == ArgumentReg; } > > ~ArgumentRegValue(); > >Index: Source/JavaScriptCore/b3/B3CCallValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3CCallValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3CCallValue.h (working copy) >@@ -35,7 +35,7 @@ namespace JSC { namespace B3 { > > class JS_EXPORT_PRIVATE CCallValue : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == CCall; } >+ static bool accepts(Kind kind) { return kind == CCall; } > > ~CCallValue(); > >Index: Source/JavaScriptCore/b3/B3CheckValue.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3CheckValue.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3CheckValue.cpp (working copy) >@@ -37,7 +37,7 @@ CheckValue::~CheckValue() > void CheckValue::convertToAdd() > { > RELEASE_ASSERT(opcode() == CheckAdd || opcode() == CheckSub || opcode() == CheckMul); >- m_opcode = CheckAdd; >+ m_kind = CheckAdd; > } > > Value* CheckValue::cloneImpl() const >@@ -46,21 +46,21 @@ Value* CheckValue::cloneImpl() const > } > > // Use this form for CheckAdd, CheckSub, and CheckMul. >-CheckValue::CheckValue(Opcode opcode, Origin origin, Value* left, Value* right) >- : StackmapValue(CheckedOpcode, opcode, left->type(), origin) >+CheckValue::CheckValue(Kind kind, Origin origin, Value* left, Value* right) >+ : StackmapValue(CheckedOpcode, kind, left->type(), origin) > { > ASSERT(B3::isInt(type())); > ASSERT(left->type() == right->type()); >- ASSERT(opcode == CheckAdd || opcode == CheckSub || opcode == CheckMul); >+ ASSERT(kind == CheckAdd || kind == CheckSub || kind == CheckMul); > append(ConstrainedValue(left, ValueRep::WarmAny)); > append(ConstrainedValue(right, ValueRep::WarmAny)); > } > > // Use this form for Check. >-CheckValue::CheckValue(Opcode opcode, Origin origin, Value* predicate) >- : StackmapValue(CheckedOpcode, opcode, Void, origin) >+CheckValue::CheckValue(Kind kind, Origin origin, Value* predicate) >+ : StackmapValue(CheckedOpcode, kind, Void, origin) > { >- ASSERT(opcode == Check); >+ ASSERT(kind == Check); > append(ConstrainedValue(predicate, ValueRep::WarmAny)); > } > >Index: Source/JavaScriptCore/b3/B3CheckValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3CheckValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3CheckValue.h (working copy) >@@ -34,9 +34,9 @@ namespace JSC { namespace B3 { > > class CheckValue : public StackmapValue { > public: >- static bool accepts(Opcode opcode) >+ static bool accepts(Kind kind) > { >- switch (opcode) { >+ switch (kind.opcode()) { > case CheckAdd: > case CheckSub: > case CheckMul: >@@ -58,10 +58,10 @@ private: > friend class Procedure; > > // Use this form for CheckAdd, CheckSub, and CheckMul. >- JS_EXPORT_PRIVATE CheckValue(Opcode, Origin, Value* left, Value* right); >+ JS_EXPORT_PRIVATE CheckValue(Kind, Origin, Value* left, Value* right); > > // Use this form for Check. >- JS_EXPORT_PRIVATE CheckValue(Opcode, Origin, Value* predicate); >+ JS_EXPORT_PRIVATE CheckValue(Kind, Origin, Value* predicate); > }; > > } } // namespace JSC::B3 >Index: Source/JavaScriptCore/b3/B3Const32Value.h >=================================================================== >--- Source/JavaScriptCore/b3/B3Const32Value.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3Const32Value.h (working copy) >@@ -34,7 +34,7 @@ namespace JSC { namespace B3 { > > class JS_EXPORT_PRIVATE Const32Value : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == Const32; } >+ static bool accepts(Kind kind) { return kind == Const32; } > > ~Const32Value(); > >Index: Source/JavaScriptCore/b3/B3Const64Value.h >=================================================================== >--- Source/JavaScriptCore/b3/B3Const64Value.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3Const64Value.h (working copy) >@@ -34,7 +34,7 @@ namespace JSC { namespace B3 { > > class JS_EXPORT_PRIVATE Const64Value : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == Const64; } >+ static bool accepts(Kind kind) { return kind == Const64; } > > ~Const64Value(); > >Index: Source/JavaScriptCore/b3/B3ConstDoubleValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3ConstDoubleValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3ConstDoubleValue.h (working copy) >@@ -34,7 +34,7 @@ namespace JSC { namespace B3 { > > class JS_EXPORT_PRIVATE ConstDoubleValue : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == ConstDouble; } >+ static bool accepts(Kind kind) { return kind == ConstDouble; } > > ~ConstDoubleValue(); > >Index: Source/JavaScriptCore/b3/B3ConstFloatValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3ConstFloatValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3ConstFloatValue.h (working copy) >@@ -34,7 +34,7 @@ namespace JSC { namespace B3 { > > class JS_EXPORT_PRIVATE ConstFloatValue : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == ConstFloat; } >+ static bool accepts(Kind kind) { return kind == ConstFloat; } > > ~ConstFloatValue(); > >Index: Source/JavaScriptCore/b3/B3FenceValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3FenceValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3FenceValue.h (working copy) >@@ -34,7 +34,7 @@ namespace JSC { namespace B3 { > > class JS_EXPORT_PRIVATE FenceValue : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == Fence; } >+ static bool accepts(Kind kind) { return kind == Fence; } > > ~FenceValue(); > >Index: Source/JavaScriptCore/b3/B3Kind.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3Kind.cpp (nonexistent) >+++ Source/JavaScriptCore/b3/B3Kind.cpp (working copy) >@@ -0,0 +1,51 @@ >+/* >+ * Copyright (C) 2016 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "B3Kind.h" >+ >+#if ENABLE(B3_JIT) >+ >+#include <wtf/CommaPrinter.h> >+ >+namespace JSC { namespace B3 { >+ >+void Kind::dump(PrintStream& out) const >+{ >+ out.print(m_opcode); >+ if (!hasExtraBits()) >+ return; >+ >+ CommaPrinter comma; >+ out.print("<"); >+ if (isChill()) >+ out.print(comma, "Chill"); >+ out.print(">"); >+} >+ >+} } // namespace JSC::B3 >+ >+#endif // ENABLE(B3_JIT) >+ >Index: Source/JavaScriptCore/b3/B3Kind.h >=================================================================== >--- Source/JavaScriptCore/b3/B3Kind.h (nonexistent) >+++ Source/JavaScriptCore/b3/B3Kind.h (working copy) >@@ -0,0 +1,218 @@ >+/* >+ * Copyright (C) 2016 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef B3Kind_h >+#define B3Kind_h >+ >+#if ENABLE(B3_JIT) >+ >+#include "B3Opcode.h" >+#include <wtf/HashTable.h> >+#include <wtf/PrintStream.h> >+ >+namespace JSC { namespace B3 { >+ >+// A Kind is a terse summary of what a Value does. There is a fixed number of possible >+// Kinds. Kind is a tuple of Opcode (see B3Opcode.h) and some extra bits. Most opcodes don't >+// get any extra bits, and those bits must remain zero if the Kind's opcode field is set to >+// one of those opcodes. The purpose of Kind is to be like an opcode in other IRs, but to >+// be multidimensional. For example, a Load has many dimensions of customization that we may >+// eventually implement. A Load can have different alignments, alignment failure modes, >+// temporality modes, trapping modes, ordering modes, etc. It's fine to put such flags into >+// subclasses of Value, but in some cases that would be overkill, particularly since if you >+// did that for a pure value then you'd also have to thread it through ValueKey. It's much >+// easier to put it in Kind, and then your extra bit will get carried around by everyone who >+// knows how to carry around Kinds. Most importantly, putting flags into Kind allows you to >+// use them as part of B3::Value's dynamic cast facility. For example we could have a >+// trapping Load that uses a Value subclass that has a stackmap while non-trapping Loads >+// continue to use the normal MemoryValue. >+// >+// Note that any code in the compiler that transcribes IR (like a strength reduction that >+// replaces an Add with a different Add, or even with a different opcode entirely) will >+// probably drop unknown bits by default. This is definitely not correct for many bits (like >+// isChill for Div/Mod and all of the envisioned Load/Store flags), so if you add a new bit >+// you will probably have to audit the compiler to make sure that phases that transcribe >+// your opcode do the right thing with your bit. >+ >+class Kind { >+public: >+ Kind(Opcode opcode) >+ : m_opcode(opcode) >+ { >+ u.bits = 0; >+ } >+ >+ Kind() >+ : Kind(Oops) >+ { >+ } >+ >+ Opcode opcode() const { return m_opcode; } >+ void setOpcode(Opcode opcode) { m_opcode = opcode; } >+ >+ bool hasExtraBits() const { return !!u.bits; } >+ >+ // Chill bit. This applies to division-based arithmetic ops, which may trap on some >+ // platforms or exhibit bizarre behavior when passed certain inputs. The non-chill >+ // version will behave as unpredictably as it wants. For example, it's legal to >+ // constant-fold Div(x, 0) to any value or to replace it with any effectful operation. >+ // But when it's chill, that means that the semantics when it would have trapped are >+ // the JS semantics. For example, Div<Chill>(@a, @b) means: >+ // >+ // ((a | 0) / (b | 0)) | 0 >+ // >+ // And Mod<Chill>(a, b) means: >+ // >+ // ((a | 0) % (b | 0)) | 0 >+ // >+ // Note that Div<Chill> matches exactly how ARM handles integer division. >+ bool hasIsChill() const >+ { >+ switch (m_opcode) { >+ case Div: >+ case Mod: >+ return true; >+ default: >+ return false; >+ } >+ } >+ bool isChill() const >+ { >+ return hasIsChill() && u.isChill; >+ } >+ void setIsChill(bool isChill) >+ { >+ ASSERT(hasIsChill()); >+ u.isChill = isChill; >+ } >+ >+ // Rules for adding new properties: >+ // - Put the accessors here. >+ // - hasBlah() should check if the opcode allows for your property. >+ // - blah() returns a default value if !hasBlah() >+ // - setBlah() asserts if !hasBlah() >+ // - Try not to increase the size of Kind too much. But it wouldn't be the end of the >+ // world if it bloated to 64 bits. >+ >+ bool operator==(const Kind& other) const >+ { >+ return m_opcode == other.m_opcode >+ && u.bits == other.u.bits; >+ } >+ >+ bool operator!=(const Kind& other) const >+ { >+ return !(*this == other); >+ } >+ >+ bool operator<(const Kind& other) const >+ { >+ if (m_opcode == other.m_opcode) >+ return u.bits < other.u.bits; >+ return m_opcode < other.m_opcode; >+ } >+ >+ bool operator>(const Kind& other) const >+ { >+ return other < *this; >+ } >+ >+ bool operator<=(const Kind& other) const >+ { >+ return !(*this > other); >+ } >+ >+ bool operator>=(const Kind& other) const >+ { >+ return !(*this < other); >+ } >+ >+ void dump(PrintStream&) const; >+ >+ unsigned hash() const >+ { >+ // It's almost certainly more important that this hash function is cheap to compute than >+ // anything else. We can live with some kind hash collisions. >+ return m_opcode + u.bits * 111; >+ } >+ >+ Kind(WTF::HashTableDeletedValueType) >+ : m_opcode(Oops) >+ { >+ u.bits = 1; >+ } >+ >+ bool isHashTableDeletedValue() const >+ { >+ return *this == Kind(WTF::HashTableDeletedValue); >+ } >+ >+private: >+ Opcode m_opcode; >+ union { >+ bool isChill; >+ uint16_t bits; >+ } u; >+}; >+ >+// For every flag 'foo' you add, it's customary to create a Kind B3::foo(Kind) function that makes >+// a kind with the flag set. For example, for chill, this lets us say: >+// >+// block->appendNew<Value>(m_proc, chill(Mod), Origin(), a, b); >+// >+// That looks pretty slick. Let's keep it that way. >+ >+inline Kind chill(Kind kind) >+{ >+ kind.setIsChill(true); >+ return kind; >+} >+ >+struct KindHash { >+ static unsigned hash(const Kind& key) { return key.hash(); } >+ static bool equal(const Kind& a, const Kind& b) { return a == b; } >+ static const bool safeToCompareToEmptyOrDeleted = true; >+}; >+ >+} } // namespace JSC::B3 >+ >+namespace WTF { >+ >+template<typename T> struct DefaultHash; >+template<> struct DefaultHash<JSC::B3::Kind> { >+ typedef JSC::B3::KindHash Hash; >+}; >+ >+template<typename T> struct HashTraits; >+template<> struct HashTraits<JSC::B3::Kind> : public SimpleClassHashTraits<JSC::B3::Kind> { >+ static const bool emptyValueIsZero = false; >+}; >+ >+} // namespace WTF >+ >+#endif // ENABLE(B3_JIT) >+ >+#endif // B3Kind_h >+ >Index: Source/JavaScriptCore/b3/B3LowerMacros.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3LowerMacros.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3LowerMacros.cpp (working copy) >@@ -83,6 +83,41 @@ private: > m_origin = m_value->origin(); > switch (m_value->opcode()) { > case Mod: { >+ if (m_value->isChill()) { >+ if (isARM64()) { >+ BasicBlock* before = m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet); >+ BasicBlock* zeroDenCase = m_blockInsertionSet.insertBefore(m_block); >+ BasicBlock* normalModCase = m_blockInsertionSet.insertBefore(m_block); >+ >+ before->replaceLastWithNew<Value>(m_proc, Branch, m_origin, m_value->child(1)); >+ before->setSuccessors( >+ FrequentedBlock(normalModCase, FrequencyClass::Normal), >+ FrequentedBlock(zeroDenCase, FrequencyClass::Rare)); >+ >+ Value* divResult = normalModCase->appendNew<Value>(m_proc, chill(Div), m_origin, m_value->child(0), m_value->child(1)); >+ Value* multipliedBack = normalModCase->appendNew<Value>(m_proc, Mul, m_origin, divResult, m_value->child(1)); >+ Value* result = normalModCase->appendNew<Value>(m_proc, Sub, m_origin, m_value->child(0), multipliedBack); >+ UpsilonValue* normalResult = normalModCase->appendNew<UpsilonValue>(m_proc, m_origin, result); >+ normalModCase->appendNew<Value>(m_proc, Jump, m_origin); >+ normalModCase->setSuccessors(FrequentedBlock(m_block)); >+ >+ UpsilonValue* zeroResult = zeroDenCase->appendNew<UpsilonValue>( >+ m_proc, m_origin, >+ zeroDenCase->appendIntConstant(m_proc, m_value, 0)); >+ zeroDenCase->appendNew<Value>(m_proc, Jump, m_origin); >+ zeroDenCase->setSuccessors(FrequentedBlock(m_block)); >+ >+ Value* phi = m_insertionSet.insert<Value>(m_index, Phi, m_value->type(), m_origin); >+ normalResult->setPhi(phi); >+ zeroResult->setPhi(phi); >+ m_value->replaceWithIdentity(phi); >+ before->updatePredecessorsAfter(); >+ m_changed = true; >+ } else >+ makeDivisionChill(Mod); >+ break; >+ } >+ > double (*fmodDouble)(double, double) = fmod; > if (m_value->type() == Double) { > Value* functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, fmodDouble); >@@ -106,7 +141,7 @@ private: > m_value->replaceWithIdentity(result); > m_changed = true; > } else if (isARM64()) { >- Value* divResult = m_insertionSet.insert<Value>(m_index, ChillDiv, m_origin, m_value->child(0), m_value->child(1)); >+ Value* divResult = m_insertionSet.insert<Value>(m_index, chill(Div), m_origin, m_value->child(0), m_value->child(1)); > Value* multipliedBack = m_insertionSet.insert<Value>(m_index, Mul, m_origin, divResult, m_value->child(1)); > Value* result = m_insertionSet.insert<Value>(m_index, Sub, m_origin, m_value->child(0), multipliedBack); > m_value->replaceWithIdentity(result); >@@ -114,43 +149,9 @@ private: > } > break; > } >- case ChillDiv: { >- makeDivisionChill(Div); >- break; >- } >- >- case ChillMod: { >- if (isARM64()) { >- BasicBlock* before = m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet); >- BasicBlock* zeroDenCase = m_blockInsertionSet.insertBefore(m_block); >- BasicBlock* normalModCase = m_blockInsertionSet.insertBefore(m_block); >- >- before->replaceLastWithNew<Value>(m_proc, Branch, m_origin, m_value->child(1)); >- before->setSuccessors( >- FrequentedBlock(normalModCase, FrequencyClass::Normal), >- FrequentedBlock(zeroDenCase, FrequencyClass::Rare)); >- >- Value* divResult = normalModCase->appendNew<Value>(m_proc, ChillDiv, m_origin, m_value->child(0), m_value->child(1)); >- Value* multipliedBack = normalModCase->appendNew<Value>(m_proc, Mul, m_origin, divResult, m_value->child(1)); >- Value* result = normalModCase->appendNew<Value>(m_proc, Sub, m_origin, m_value->child(0), multipliedBack); >- UpsilonValue* normalResult = normalModCase->appendNew<UpsilonValue>(m_proc, m_origin, result); >- normalModCase->appendNew<Value>(m_proc, Jump, m_origin); >- normalModCase->setSuccessors(FrequentedBlock(m_block)); >- >- UpsilonValue* zeroResult = zeroDenCase->appendNew<UpsilonValue>( >- m_proc, m_origin, >- zeroDenCase->appendIntConstant(m_proc, m_value, 0)); >- zeroDenCase->appendNew<Value>(m_proc, Jump, m_origin); >- zeroDenCase->setSuccessors(FrequentedBlock(m_block)); >- >- Value* phi = m_insertionSet.insert<Value>(m_index, Phi, m_value->type(), m_origin); >- normalResult->setPhi(phi); >- zeroResult->setPhi(phi); >- m_value->replaceWithIdentity(phi); >- before->updatePredecessorsAfter(); >- m_changed = true; >- } else >- makeDivisionChill(Mod); >+ case Div: { >+ if (m_value->isChill()) >+ makeDivisionChill(Div); > break; > } > >@@ -188,7 +189,7 @@ private: > if (isARM64()) > return; > >- // We implement "res = ChillDiv/ChillMod(num, den)" as follows: >+ // We implement "res = Div<Chill>/Mod<Chill>(num, den)" as follows: > // > // if (den + 1 <=_unsigned 1) { > // if (!den) { >Index: Source/JavaScriptCore/b3/B3LowerToAir.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3LowerToAir.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3LowerToAir.cpp (working copy) >@@ -1846,10 +1846,9 @@ private: > return; > } > >- case ChillDiv: >- RELEASE_ASSERT(isARM64()); >- FALLTHROUGH; > case Div: { >+ if (m_value->isChill()) >+ RELEASE_ASSERT(isARM64()); > #if CPU(X86) || CPU(X86_64) > if (isInt(m_value->type())) { > lowerX86Div(); >@@ -1865,6 +1864,7 @@ private: > > case Mod: { > RELEASE_ASSERT(isX86()); >+ RELEASE_ASSERT(!m_value->isChill()); > #if CPU(X86) || CPU(X86_64) > lowerX86Div(); > append(Move, Tmp(X86Registers::edx), tmp(m_value)); >Index: Source/JavaScriptCore/b3/B3MemoryValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3MemoryValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3MemoryValue.h (working copy) >@@ -38,9 +38,9 @@ namespace JSC { namespace B3 { > > class JS_EXPORT_PRIVATE MemoryValue : public Value { > public: >- static bool accepts(Opcode opcode) >+ static bool accepts(Kind kind) > { >- switch (opcode) { >+ switch (kind.opcode()) { > case Load8Z: > case Load8S: > case Load16Z: >@@ -55,9 +55,9 @@ public: > } > } > >- static bool isStore(Opcode opcode) >+ static bool isStore(Kind kind) > { >- switch (opcode) { >+ switch (kind.opcode()) { > case Store8: > case Store16: > case Store: >@@ -67,9 +67,9 @@ public: > } > } > >- static bool isLoad(Opcode opcode) >+ static bool isLoad(Kind kind) > { >- return accepts(opcode) && !isStore(opcode); >+ return accepts(kind) && !isStore(kind); > } > > ~MemoryValue(); >@@ -95,13 +95,13 @@ private: > > // Use this form for Load (but not Load8Z, Load8S, or any of the Loads that have a suffix that > // describes the returned type). >- MemoryValue(Opcode opcode, Type type, Origin origin, Value* pointer, int32_t offset = 0) >- : Value(CheckedOpcode, opcode, type, origin, pointer) >+ MemoryValue(Kind kind, Type type, Origin origin, Value* pointer, int32_t offset = 0) >+ : Value(CheckedOpcode, kind, type, origin, pointer) > , m_offset(offset) > , m_range(HeapRange::top()) > { > if (!ASSERT_DISABLED) { >- switch (opcode) { >+ switch (kind.opcode()) { > case Load: > break; > case Load8Z: >@@ -122,19 +122,19 @@ private: > } > > // Use this form for loads where the return type is implied. >- MemoryValue(Opcode opcode, Origin origin, Value* pointer, int32_t offset = 0) >- : MemoryValue(opcode, Int32, origin, pointer, offset) >+ MemoryValue(Kind kind, Origin origin, Value* pointer, int32_t offset = 0) >+ : MemoryValue(kind, Int32, origin, pointer, offset) > { > } > > // Use this form for stores. >- MemoryValue(Opcode opcode, Origin origin, Value* value, Value* pointer, int32_t offset = 0) >- : Value(CheckedOpcode, opcode, Void, origin, value, pointer) >+ MemoryValue(Kind kind, Origin origin, Value* value, Value* pointer, int32_t offset = 0) >+ : Value(CheckedOpcode, kind, Void, origin, value, pointer) > , m_offset(offset) > , m_range(HeapRange::top()) > { > if (!ASSERT_DISABLED) { >- switch (opcode) { >+ switch (kind.opcode()) { > case Store8: > case Store16: > case Store: >Index: Source/JavaScriptCore/b3/B3Opcode.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3Opcode.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3Opcode.cpp (working copy) >@@ -128,12 +128,6 @@ void printInternal(PrintStream& out, Opc > case Neg: > out.print("Neg"); > return; >- case ChillDiv: >- out.print("ChillDiv"); >- return; >- case ChillMod: >- out.print("ChillMod"); >- return; > case BitAnd: > out.print("BitAnd"); > return; >Index: Source/JavaScriptCore/b3/B3Opcode.h >=================================================================== >--- Source/JavaScriptCore/b3/B3Opcode.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3Opcode.h (working copy) >@@ -34,6 +34,9 @@ > > namespace JSC { namespace B3 { > >+// Warning: In B3, an Opcode is just one part of a Kind. Kind is used the way that an opcode >+// would be used in simple IRs. See B3Kind.h. >+ > enum Opcode : int16_t { > // A no-op that returns Void, useful for when you want to remove a value. > Nop, >@@ -84,8 +87,6 @@ enum Opcode : int16_t { > Neg, > > // Integer math. >- ChillDiv, // doesn't trap ever, behaves like JS (x/y)|0. >- ChillMod, // doesn't trap ever, behaves like JS (x%y)|0. > BitAnd, > BitOr, > BitXor, >Index: Source/JavaScriptCore/b3/B3PatchpointValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3PatchpointValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3PatchpointValue.h (working copy) >@@ -38,7 +38,7 @@ class PatchpointValue : public StackmapV > public: > typedef StackmapValue Base; > >- static bool accepts(Opcode opcode) { return opcode == Patchpoint; } >+ static bool accepts(Kind kind) { return kind == Patchpoint; } > > ~PatchpointValue(); > >Index: Source/JavaScriptCore/b3/B3ReduceStrength.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3ReduceStrength.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3ReduceStrength.cpp (working copy) >@@ -648,10 +648,9 @@ private: > break; > > case Div: >- case ChillDiv: > // Turn this: Div(constant1, constant2) > // Into this: constant1 / constant2 >- // Note that this uses ChillDiv semantics. That's fine, because the rules for Div >+ // Note that this uses Div<Chill> semantics. That's fine, because the rules for Div > // are strictly weaker: it has corner cases where it's allowed to do anything it > // likes. > if (replaceWithNewValue(m_value->child(0)->divConstant(m_proc, m_value->child(1)))) >@@ -737,10 +736,9 @@ private: > break; > > case Mod: >- case ChillMod: > // Turn this: Mod(constant1, constant2) > // Into this: constant1 / constant2 >- // Note that this uses ChillMod semantics. >+ // Note that this uses Mod<Chill> semantics. > if (replaceWithNewValue(m_value->child(0)->modConstant(m_proc, m_value->child(1)))) > break; > >@@ -774,19 +772,8 @@ private: > // = -2^31 - -2^31 > // = 0 > >- Opcode divOpcode; >- switch (m_value->opcode()) { >- case Mod: >- divOpcode = Div; >- break; >- case ChillMod: >- divOpcode = ChillDiv; >- break; >- default: >- divOpcode = Oops; >- RELEASE_ASSERT_NOT_REACHED(); >- break; >- } >+ Kind divKind = Div; >+ divKind.setIsChill(m_value->isChill()); > > replaceWithIdentity( > m_insertionSet.insert<Value>( >@@ -795,7 +782,7 @@ private: > m_insertionSet.insert<Value>( > m_index, Mul, m_value->origin(), > m_insertionSet.insert<Value>( >- m_index, divOpcode, m_value->origin(), >+ m_index, divKind, m_value->origin(), > m_value->child(0), m_value->child(1)), > m_value->child(1)))); > break; >Index: Source/JavaScriptCore/b3/B3SlotBaseValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3SlotBaseValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3SlotBaseValue.h (working copy) >@@ -36,7 +36,7 @@ class StackSlot; > > class JS_EXPORT_PRIVATE SlotBaseValue : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == SlotBase; } >+ static bool accepts(Kind kind) { return kind == SlotBase; } > > ~SlotBaseValue(); > >Index: Source/JavaScriptCore/b3/B3StackmapValue.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3StackmapValue.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3StackmapValue.cpp (working copy) >@@ -83,10 +83,10 @@ void StackmapValue::dumpMeta(CommaPrinte > ", lateClobbered = ", m_lateClobbered, ", usedRegisters = ", m_usedRegisters); > } > >-StackmapValue::StackmapValue(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin) >- : Value(CheckedOpcode, opcode, type, origin) >+StackmapValue::StackmapValue(CheckedOpcodeTag, Kind kind, Type type, Origin origin) >+ : Value(CheckedOpcode, kind, type, origin) > { >- ASSERT(accepts(opcode)); >+ ASSERT(accepts(kind)); > } > > } } // namespace JSC::B3 >Index: Source/JavaScriptCore/b3/B3StackmapValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3StackmapValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3StackmapValue.h (working copy) >@@ -44,10 +44,10 @@ typedef SharedTask<StackmapGeneratorFunc > > class JS_EXPORT_PRIVATE StackmapValue : public Value { > public: >- static bool accepts(Opcode opcode) >+ static bool accepts(Kind kind) > { > // This needs to include opcodes of all subclasses. >- switch (opcode) { >+ switch (kind.opcode()) { > case CheckAdd: > case CheckSub: > case CheckMul: >@@ -289,7 +289,7 @@ protected: > void dumpChildren(CommaPrinter&, PrintStream&) const override; > void dumpMeta(CommaPrinter&, PrintStream&) const override; > >- StackmapValue(CheckedOpcodeTag, Opcode, Type, Origin); >+ StackmapValue(CheckedOpcodeTag, Kind, Type, Origin); > > private: > friend class CheckSpecial; >Index: Source/JavaScriptCore/b3/B3SwitchValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3SwitchValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3SwitchValue.h (working copy) >@@ -36,7 +36,7 @@ namespace JSC { namespace B3 { > > class SwitchValue : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == Switch; } >+ static bool accepts(Kind kind) { return kind == Switch; } > > ~SwitchValue(); > >Index: Source/JavaScriptCore/b3/B3UpsilonValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3UpsilonValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3UpsilonValue.h (working copy) >@@ -34,7 +34,7 @@ namespace JSC { namespace B3 { > > class JS_EXPORT_PRIVATE UpsilonValue : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == Upsilon; } >+ static bool accepts(Kind kind) { return kind == Upsilon; } > > ~UpsilonValue(); > >Index: Source/JavaScriptCore/b3/B3Validate.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3Validate.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3Validate.cpp (working copy) >@@ -131,44 +131,54 @@ public: > switch (value->opcode()) { > case Nop: > case Fence: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == Void, ("At ", *value)); > break; > case Identity: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); > VALIDATE(value->type() != Void, ("At ", *value)); > break; > case Const32: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == Int32, ("At ", *value)); > break; > case Const64: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == Int64, ("At ", *value)); > break; > case ConstDouble: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == Double, ("At ", *value)); > break; > case ConstFloat: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == Float, ("At ", *value)); > break; > case Set: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->child(0)->type() == value->as<VariableValue>()->variable()->type(), ("At ", *value)); > break; > case Get: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == value->as<VariableValue>()->variable()->type(), ("At ", *value)); > break; > case SlotBase: > case FramePointer: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == pointerType(), ("At ", *value)); > break; > case ArgumentReg: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE( > (value->as<ArgumentRegValue>()->argumentReg().isGPR() ? pointerType() : Double) >@@ -181,19 +191,31 @@ public: > case Mod: > case BitAnd: > case BitXor: >+ switch (value->opcode()) { >+ case Div: >+ case Mod: >+ if (value->isChill()) { >+ VALIDATE(value->opcode() == Div || value->opcode() == Mod, ("At ", *value)); >+ VALIDATE(isInt(value->type()), ("At ", *value)); >+ } >+ break; >+ default: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); >+ break; >+ } > VALIDATE(value->numChildren() == 2, ("At ", *value)); > VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); > VALIDATE(value->type() == value->child(1)->type(), ("At ", *value)); > VALIDATE(value->type() != Void, ("At ", *value)); > break; > case Neg: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); > VALIDATE(value->type() != Void, ("At ", *value)); > break; >- case ChillDiv: >- case ChillMod: > case BitOr: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 2, ("At ", *value)); > VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); > VALIDATE(value->type() == value->child(1)->type(), ("At ", *value)); >@@ -202,12 +224,14 @@ public: > case Shl: > case SShr: > case ZShr: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 2, ("At ", *value)); > VALIDATE(value->type() == value->child(0)->type(), ("At ", *value)); > VALIDATE(value->child(1)->type() == Int32, ("At ", *value)); > VALIDATE(isInt(value->type()), ("At ", *value)); > break; > case BitwiseCast: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->type() != value->child(0)->type(), ("At ", *value)); > VALIDATE( >@@ -219,22 +243,26 @@ public: > break; > case SExt8: > case SExt16: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->child(0)->type() == Int32, ("At ", *value)); > VALIDATE(value->type() == Int32, ("At ", *value)); > break; > case SExt32: > case ZExt32: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->child(0)->type() == Int32, ("At ", *value)); > VALIDATE(value->type() == Int64, ("At ", *value)); > break; > case Clz: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); > VALIDATE(isInt(value->type()), ("At ", *value)); > break; > case Trunc: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->child(0)->type() == Int64, ("At ", *value)); > VALIDATE(value->type() == Int32, ("At ", *value)); >@@ -243,26 +271,31 @@ public: > case Ceil: > case Floor: > case Sqrt: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(isFloat(value->child(0)->type()), ("At ", *value)); > VALIDATE(isFloat(value->type()), ("At ", *value)); > break; > case IToD: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); > VALIDATE(value->type() == Double, ("At ", *value)); > break; > case IToF: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); > VALIDATE(value->type() == Float, ("At ", *value)); > break; > case FloatToDouble: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->child(0)->type() == Float, ("At ", *value)); > VALIDATE(value->type() == Double, ("At ", *value)); > break; > case DoubleToFloat: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->child(0)->type() == Double, ("At ", *value)); > VALIDATE(value->type() == Float, ("At ", *value)); >@@ -273,6 +306,7 @@ public: > case GreaterThan: > case LessEqual: > case GreaterEqual: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 2, ("At ", *value)); > VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value)); > VALIDATE(value->type() == Int32, ("At ", *value)); >@@ -281,18 +315,21 @@ public: > case Below: > case AboveEqual: > case BelowEqual: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 2, ("At ", *value)); > VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value)); > VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); > VALIDATE(value->type() == Int32, ("At ", *value)); > break; > case EqualOrUnordered: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 2, ("At ", *value)); > VALIDATE(value->child(0)->type() == value->child(1)->type(), ("At ", *value)); > VALIDATE(isFloat(value->child(0)->type()), ("At ", *value)); > VALIDATE(value->type() == Int32, ("At ", *value)); > break; > case Select: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 3, ("At ", *value)); > VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); > VALIDATE(value->type() == value->child(1)->type(), ("At ", *value)); >@@ -302,12 +339,14 @@ public: > case Load8S: > case Load16Z: > case Load16S: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value)); > VALIDATE(value->type() == Int32, ("At ", *value)); > validateStackAccess(value); > break; > case Load: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value)); > VALIDATE(value->type() != Void, ("At ", *value)); >@@ -315,6 +354,7 @@ public: > break; > case Store8: > case Store16: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 2, ("At ", *value)); > VALIDATE(value->child(0)->type() == Int32, ("At ", *value)); > VALIDATE(value->child(1)->type() == pointerType(), ("At ", *value)); >@@ -322,16 +362,19 @@ public: > validateStackAccess(value); > break; > case Store: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 2, ("At ", *value)); > VALIDATE(value->child(1)->type() == pointerType(), ("At ", *value)); > VALIDATE(value->type() == Void, ("At ", *value)); > validateStackAccess(value); > break; > case CCall: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() >= 1, ("At ", *value)); > VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value)); > break; > case Patchpoint: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > if (value->type() == Void) > VALIDATE(value->as<PatchpointValue>()->resultConstraint == ValueRep::WarmAny, ("At ", *value)); > else { >@@ -354,6 +397,7 @@ public: > case CheckAdd: > case CheckSub: > case CheckMul: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() >= 2, ("At ", *value)); > VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); > VALIDATE(isInt(value->child(1)->type()), ("At ", *value)); >@@ -362,12 +406,14 @@ public: > validateStackmap(value); > break; > case Check: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() >= 1, ("At ", *value)); > VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); > VALIDATE(value->as<StackmapValue>()->constrainedChild(0).rep() == ValueRep::WarmAny, ("At ", *value)); > validateStackmap(value); > break; > case Upsilon: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(value->as<UpsilonValue>()->phi(), ("At ", *value)); > VALIDATE(value->as<UpsilonValue>()->phi()->opcode() == Phi, ("At ", *value)); >@@ -375,31 +421,37 @@ public: > VALIDATE(valueInProc.contains(value->as<UpsilonValue>()->phi()), ("At ", *value)); > break; > case Phi: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() != Void, ("At ", *value)); > break; > case Jump: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == Void, ("At ", *value)); > VALIDATE(valueOwner.get(value)->numSuccessors() == 1, ("At ", *value)); > break; > case Oops: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == Void, ("At ", *value)); > VALIDATE(!valueOwner.get(value)->numSuccessors(), ("At ", *value)); > break; > case Return: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() <= 1, ("At ", *value)); > VALIDATE(value->type() == Void, ("At ", *value)); > VALIDATE(!valueOwner.get(value)->numSuccessors(), ("At ", *value)); > break; > case Branch: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); > VALIDATE(value->type() == Void, ("At ", *value)); > VALIDATE(valueOwner.get(value)->numSuccessors() == 2, ("At ", *value)); > break; > case Switch: { >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(value->numChildren() == 1, ("At ", *value)); > VALIDATE(isInt(value->child(0)->type()), ("At ", *value)); > VALIDATE(value->type() == Void, ("At ", *value)); >@@ -417,6 +469,7 @@ public: > break; > } > case EntrySwitch: >+ VALIDATE(!value->kind().hasExtraBits(), ("At ", *value)); > VALIDATE(!value->numChildren(), ("At ", *value)); > VALIDATE(value->type() == Void, ("At ", *value)); > VALIDATE(valueOwner.get(value)->numSuccessors() == m_procedure.numEntrypoints(), ("At ", *value)); >Index: Source/JavaScriptCore/b3/B3Value.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3Value.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3Value.cpp (working copy) >@@ -175,7 +175,7 @@ void Value::dump(PrintStream& out) const > { > bool isConstant = false; > >- switch (m_opcode) { >+ switch (opcode()) { > case Const32: > out.print("$", asInt32(), "("); > isConstant = true; >@@ -215,7 +215,7 @@ void Value::dumpChildren(CommaPrinter& c > > void Value::deepDump(const Procedure* proc, PrintStream& out) const > { >- out.print(m_type, " ", dumpPrefix, m_index, " = ", m_opcode); >+ out.print(m_type, " ", dumpPrefix, m_index, " = ", m_kind); > > out.print("("); > CommaPrinter comma; >@@ -437,8 +437,10 @@ Value* Value::invertedCompare(Procedure& > { > if (!numChildren()) > return nullptr; >- if (Optional<Opcode> invertedOpcode = B3::invertedCompare(opcode(), child(0)->type())) >+ if (Optional<Opcode> invertedOpcode = B3::invertedCompare(opcode(), child(0)->type())) { >+ ASSERT(!kind().hasExtraBits()); > return proc.add<Value>(*invertedOpcode, type(), origin(), children()); >+ } > return nullptr; > } > >@@ -532,8 +534,6 @@ Effects Value::effects() const > case Sub: > case Mul: > case Neg: >- case ChillDiv: >- case ChillMod: > case BitAnd: > case BitOr: > case BitXor: >@@ -642,7 +642,7 @@ ValueKey Value::key() const > { > switch (opcode()) { > case FramePointer: >- return ValueKey(opcode(), type()); >+ return ValueKey(kind(), type()); > case Identity: > case Abs: > case Ceil: >@@ -661,14 +661,12 @@ ValueKey Value::key() const > case Check: > case BitwiseCast: > case Neg: >- return ValueKey(opcode(), type(), child(0)); >+ return ValueKey(kind(), type(), child(0)); > case Add: > case Sub: > case Mul: > case Div: > case Mod: >- case ChillDiv: >- case ChillMod: > case BitAnd: > case BitOr: > case BitXor: >@@ -687,9 +685,9 @@ ValueKey Value::key() const > case CheckAdd: > case CheckSub: > case CheckMul: >- return ValueKey(opcode(), type(), child(0), child(1)); >+ return ValueKey(kind(), type(), child(0), child(1)); > case Select: >- return ValueKey(opcode(), type(), child(0), child(1), child(2)); >+ return ValueKey(kind(), type(), child(0), child(1), child(2)); > case Const32: > return ValueKey(Const32, type(), static_cast<int64_t>(asInt32())); > case Const64: >@@ -738,9 +736,9 @@ void Value::dumpMeta(CommaPrinter&, Prin > { > } > >-Type Value::typeFor(Opcode opcode, Value* firstChild, Value* secondChild) >+Type Value::typeFor(Kind kind, Value* firstChild, Value* secondChild) > { >- switch (opcode) { >+ switch (kind.opcode()) { > case Identity: > case Add: > case Sub: >@@ -748,8 +746,6 @@ Type Value::typeFor(Opcode opcode, Value > case Div: > case Mod: > case Neg: >- case ChillDiv: >- case ChillMod: > case BitAnd: > case BitOr: > case BitXor: >@@ -820,9 +816,9 @@ Type Value::typeFor(Opcode opcode, Value > } > } > >-void Value::badOpcode(Opcode opcode, unsigned numArgs) >+void Value::badKind(Kind kind, unsigned numArgs) > { >- dataLog("Bad opcode ", opcode, " with ", numArgs, " args.\n"); >+ dataLog("Bad kind ", kind, " with ", numArgs, " args.\n"); > RELEASE_ASSERT_NOT_REACHED(); > } > >Index: Source/JavaScriptCore/b3/B3Value.h >=================================================================== >--- Source/JavaScriptCore/b3/B3Value.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3Value.h (working copy) >@@ -31,7 +31,7 @@ > #include "AirArg.h" > #include "B3Effects.h" > #include "B3FrequentedBlock.h" >-#include "B3Opcode.h" >+#include "B3Kind.h" > #include "B3Origin.h" > #include "B3SparseCollection.h" > #include "B3Type.h" >@@ -55,15 +55,21 @@ public: > > static const char* const dumpPrefix; > >- static bool accepts(Opcode) { return true; } >+ static bool accepts(Kind) { return true; } > > virtual ~Value(); > > unsigned index() const { return m_index; } > >- // Note that the opcode is immutable, except for replacing values with: >+ // Note that the kind is immutable, except for replacing values with: > // Identity, Nop, Oops, Jump, and Phi. See below for replaceWithXXX() methods. >- Opcode opcode() const { return m_opcode; } >+ Kind kind() const { return m_kind; } >+ >+ Opcode opcode() const { return kind().opcode(); } >+ >+ // It's good practice to mirror Kind methods here, so you can say value->isBlah() >+ // instead of value->kind().isBlah(). >+ bool isChill() const { return kind().isChill(); } > > Origin origin() const { return m_origin; } > void setOrigin(Origin origin) { m_origin = origin; } >@@ -132,8 +138,8 @@ public: > // things > // } > // >- // This will return null if this opcode() != ArgumentReg. This works because this returns nullptr >- // if T::accepts(opcode()) returns false. >+ // This will return null if this kind() != ArgumentReg. This works because this returns nullptr >+ // if T::accepts(kind()) returns false. > template<typename T> > T* as(); > template<typename T> >@@ -142,7 +148,7 @@ public: > // What follows are a bunch of helpers for inspecting and modifying values. Note that we have a > // bunch of different idioms for implementing such helpers. You can use virtual methods, and > // override from the various Value subclasses. You can put the method inside Value and make it >- // non-virtual, and the implementation can switch on opcode. The method could be inline or not. >+ // non-virtual, and the implementation can switch on kind. The method could be inline or not. > // If a method is specific to some Value subclass, you could put it in the subclass, or you could > // put it on Value anyway. It's fine to pick whatever feels right, and we shouldn't restrict > // ourselves to any particular idiom. >@@ -159,8 +165,8 @@ public: > virtual Value* checkSubConstant(Procedure&, const Value* other) const; > virtual Value* checkMulConstant(Procedure&, const Value* other) const; > virtual Value* checkNegConstant(Procedure&) const; >- virtual Value* divConstant(Procedure&, const Value* other) const; // This chooses ChillDiv semantics for integers. >- virtual Value* modConstant(Procedure&, const Value* other) const; // This chooses ChillMod semantics. >+ virtual Value* divConstant(Procedure&, const Value* other) const; // This chooses Div<Chill> semantics for integers. >+ virtual Value* modConstant(Procedure&, const Value* other) const; // This chooses Mod<Chill> semantics. > virtual Value* bitAndConstant(Procedure&, const Value* other) const; > virtual Value* bitOrConstant(Procedure&, const Value* other) const; > virtual Value* bitXorConstant(Procedure&, const Value* other) const; >@@ -274,10 +280,10 @@ private: > friend class Procedure; > friend class SparseCollection<Value>; > >- // Checks that this opcode is valid for use with B3::Value. >- ALWAYS_INLINE static void checkOpcode(Opcode opcode, unsigned numArgs) >+ // Checks that this kind is valid for use with B3::Value. >+ ALWAYS_INLINE static void checkKind(Kind kind, unsigned numArgs) > { >- switch (opcode) { >+ switch (kind.opcode()) { > case FramePointer: > case Nop: > case Phi: >@@ -285,11 +291,11 @@ private: > case Oops: > case EntrySwitch: > if (UNLIKELY(numArgs)) >- badOpcode(opcode, numArgs); >+ badKind(kind, numArgs); > break; > case Return: > if (UNLIKELY(numArgs > 1)) >- badOpcode(opcode, numArgs); >+ badKind(kind, numArgs); > break; > case Identity: > case Neg: >@@ -310,15 +316,13 @@ private: > case BitwiseCast: > case Branch: > if (UNLIKELY(numArgs != 1)) >- badOpcode(opcode, numArgs); >+ badKind(kind, numArgs); > break; > case Add: > case Sub: > case Mul: > case Div: > case Mod: >- case ChillDiv: >- case ChillMod: > case BitAnd: > case BitOr: > case BitXor: >@@ -337,14 +341,14 @@ private: > case BelowEqual: > case EqualOrUnordered: > if (UNLIKELY(numArgs != 2)) >- badOpcode(opcode, numArgs); >+ badKind(kind, numArgs); > break; > case Select: > if (UNLIKELY(numArgs != 3)) >- badOpcode(opcode, numArgs); >+ badKind(kind, numArgs); > break; > default: >- badOpcode(opcode, numArgs); >+ badKind(kind, numArgs); > break; > } > } >@@ -358,56 +362,56 @@ protected: > // Instantiate values via Procedure. > // This form requires specifying the type explicitly: > template<typename... Arguments> >- explicit Value(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin, Value* firstChild, Arguments... arguments) >- : m_opcode(opcode) >+ explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin, Value* firstChild, Arguments... arguments) >+ : m_kind(kind) > , m_type(type) > , m_origin(origin) > , m_children{ firstChild, arguments... } > { > } > // This form is for specifying the type explicitly when the opcode has no children: >- explicit Value(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin) >- : m_opcode(opcode) >+ explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin) >+ : m_kind(kind) > , m_type(type) > , m_origin(origin) > { > } > // This form is for those opcodes that can infer their type from the opcode and first child: > template<typename... Arguments> >- explicit Value(CheckedOpcodeTag, Opcode opcode, Origin origin, Value* firstChild) >- : m_opcode(opcode) >- , m_type(typeFor(opcode, firstChild)) >+ explicit Value(CheckedOpcodeTag, Kind kind, Origin origin, Value* firstChild) >+ : m_kind(kind) >+ , m_type(typeFor(kind, firstChild)) > , m_origin(origin) > , m_children{ firstChild } > { > } > // This form is for those opcodes that can infer their type from the opcode and first and second child: > template<typename... Arguments> >- explicit Value(CheckedOpcodeTag, Opcode opcode, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments) >- : m_opcode(opcode) >- , m_type(typeFor(opcode, firstChild, secondChild)) >+ explicit Value(CheckedOpcodeTag, Kind kind, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments) >+ : m_kind(kind) >+ , m_type(typeFor(kind, firstChild, secondChild)) > , m_origin(origin) > , m_children{ firstChild, secondChild, arguments... } > { > } > // This form is for those opcodes that can infer their type from the opcode alone, and that don't > // take any arguments: >- explicit Value(CheckedOpcodeTag, Opcode opcode, Origin origin) >- : m_opcode(opcode) >- , m_type(typeFor(opcode, nullptr)) >+ explicit Value(CheckedOpcodeTag, Kind kind, Origin origin) >+ : m_kind(kind) >+ , m_type(typeFor(kind, nullptr)) > , m_origin(origin) > { > } > // Use this form for varargs. >- explicit Value(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin, const AdjacencyList& children) >- : m_opcode(opcode) >+ explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin, const AdjacencyList& children) >+ : m_kind(kind) > , m_type(type) > , m_origin(origin) > , m_children(children) > { > } >- explicit Value(CheckedOpcodeTag, Opcode opcode, Type type, Origin origin, AdjacencyList&& children) >- : m_opcode(opcode) >+ explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin, AdjacencyList&& children) >+ : m_kind(kind) > , m_type(type) > , m_origin(origin) > , m_children(WTFMove(children)) >@@ -417,52 +421,52 @@ protected: > // This is the constructor you end up actually calling, if you're instantiating Value > // directly. > template<typename... Arguments> >- explicit Value(Opcode opcode, Type type, Origin origin) >- : Value(CheckedOpcode, opcode, type, origin) >+ explicit Value(Kind kind, Type type, Origin origin) >+ : Value(CheckedOpcode, kind, type, origin) > { >- checkOpcode(opcode, 0); >+ checkKind(kind, 0); > } > template<typename... Arguments> >- explicit Value(Opcode opcode, Type type, Origin origin, Value* firstChild, Arguments&&... arguments) >- : Value(CheckedOpcode, opcode, type, origin, firstChild, std::forward<Arguments>(arguments)...) >+ explicit Value(Kind kind, Type type, Origin origin, Value* firstChild, Arguments&&... arguments) >+ : Value(CheckedOpcode, kind, type, origin, firstChild, std::forward<Arguments>(arguments)...) > { >- checkOpcode(opcode, 1 + sizeof...(arguments)); >+ checkKind(kind, 1 + sizeof...(arguments)); > } > template<typename... Arguments> >- explicit Value(Opcode opcode, Type type, Origin origin, const AdjacencyList& children) >- : Value(CheckedOpcode, opcode, type, origin, children) >+ explicit Value(Kind kind, Type type, Origin origin, const AdjacencyList& children) >+ : Value(CheckedOpcode, kind, type, origin, children) > { >- checkOpcode(opcode, children.size()); >+ checkKind(kind, children.size()); > } > template<typename... Arguments> >- explicit Value(Opcode opcode, Type type, Origin origin, AdjacencyList&& children) >- : Value(CheckedOpcode, opcode, type, origin, WTFMove(children)) >+ explicit Value(Kind kind, Type type, Origin origin, AdjacencyList&& children) >+ : Value(CheckedOpcode, kind, type, origin, WTFMove(children)) > { >- checkOpcode(opcode, m_children.size()); >+ checkKind(kind, m_children.size()); > } > template<typename... Arguments> >- explicit Value(Opcode opcode, Origin origin, Arguments&&... arguments) >- : Value(CheckedOpcode, opcode, origin, std::forward<Arguments>(arguments)...) >+ explicit Value(Kind kind, Origin origin, Arguments&&... arguments) >+ : Value(CheckedOpcode, kind, origin, std::forward<Arguments>(arguments)...) > { >- checkOpcode(opcode, sizeof...(arguments)); >+ checkKind(kind, sizeof...(arguments)); > } > > private: >- friend class CheckValue; // CheckValue::convertToAdd() modifies m_opcode. >+ friend class CheckValue; // CheckValue::convertToAdd() modifies m_kind. > >- static Type typeFor(Opcode, Value* firstChild, Value* secondChild = nullptr); >+ static Type typeFor(Kind, Value* firstChild, Value* secondChild = nullptr); > > // This group of fields is arranged to fit in 64 bits. > protected: > unsigned m_index { UINT_MAX }; > private: >- Opcode m_opcode; >+ Kind m_kind; > Type m_type; > > Origin m_origin; > AdjacencyList m_children; > >- JS_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH static void badOpcode(Opcode, unsigned); >+ JS_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH static void badKind(Kind, unsigned); > > public: > BasicBlock* owner { nullptr }; // computed by Procedure::resetValueOwners(). >Index: Source/JavaScriptCore/b3/B3ValueInlines.h >=================================================================== >--- Source/JavaScriptCore/b3/B3ValueInlines.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3ValueInlines.h (working copy) >@@ -58,7 +58,7 @@ void Value::replaceWithBottom(const Bott > template<typename T> > inline T* Value::as() > { >- if (T::accepts(opcode())) >+ if (T::accepts(kind())) > return static_cast<T*>(this); > return nullptr; > } >Index: Source/JavaScriptCore/b3/B3ValueKey.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3ValueKey.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3ValueKey.cpp (working copy) >@@ -51,14 +51,14 @@ ValueKey ValueKey::intConstant(Type type > > void ValueKey::dump(PrintStream& out) const > { >- out.print(m_type, " ", m_opcode, "(", u.indices[0], ", ", u.indices[1], ", ", u.indices[2], ")"); >+ out.print(m_type, " ", m_kind, "(", u.indices[0], ", ", u.indices[1], ", ", u.indices[2], ")"); > } > > Value* ValueKey::materialize(Procedure& proc, Origin origin) const > { > switch (opcode()) { > case FramePointer: >- return proc.add<Value>(opcode(), type(), origin); >+ return proc.add<Value>(kind(), type(), origin); > case Identity: > case Sqrt: > case SExt8: >@@ -72,11 +72,10 @@ Value* ValueKey::materialize(Procedure& > case FloatToDouble: > case DoubleToFloat: > case Check: >- return proc.add<Value>(opcode(), type(), origin, child(proc, 0)); >+ return proc.add<Value>(kind(), type(), origin, child(proc, 0)); > case Add: > case Sub: > case Mul: >- case ChillDiv: > case Mod: > case BitAnd: > case BitOr: >@@ -93,9 +92,9 @@ Value* ValueKey::materialize(Procedure& > case AboveEqual: > case BelowEqual: > case Div: >- return proc.add<Value>(opcode(), type(), origin, child(proc, 0), child(proc, 1)); >+ return proc.add<Value>(kind(), type(), origin, child(proc, 0), child(proc, 1)); > case Select: >- return proc.add<Value>(opcode(), type(), origin, child(proc, 0), child(proc, 1), child(proc, 2)); >+ return proc.add<Value>(kind(), type(), origin, child(proc, 0), child(proc, 1), child(proc, 2)); > case Const32: > return proc.add<Const32Value>(origin, static_cast<int32_t>(value())); > case Const64: >Index: Source/JavaScriptCore/b3/B3ValueKey.h >=================================================================== >--- Source/JavaScriptCore/b3/B3ValueKey.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3ValueKey.h (working copy) >@@ -29,7 +29,7 @@ > #if ENABLE(B3_JIT) > > #include "B3HeapRange.h" >-#include "B3Opcode.h" >+#include "B3Kind.h" > #include "B3Origin.h" > #include "B3Type.h" > #include <wtf/HashTable.h> >@@ -51,34 +51,34 @@ public: > { > } > >- ValueKey(Opcode opcode, Type type) >- : m_opcode(opcode) >+ ValueKey(Kind kind, Type type) >+ : m_kind(kind) > , m_type(type) > { > } > >- ValueKey(Opcode, Type, Value* child); >+ ValueKey(Kind, Type, Value* child); > >- ValueKey(Opcode, Type, Value* left, Value* right); >+ ValueKey(Kind, Type, Value* left, Value* right); > >- ValueKey(Opcode, Type, Value* a, Value* b, Value* c); >+ ValueKey(Kind, Type, Value* a, Value* b, Value* c); > >- ValueKey(Opcode opcode, Type type, int64_t value) >- : m_opcode(opcode) >+ ValueKey(Kind kind, Type type, int64_t value) >+ : m_kind(kind) > , m_type(type) > { > u.value = value; > } > >- ValueKey(Opcode opcode, Type type, double value) >- : m_opcode(opcode) >+ ValueKey(Kind kind, Type type, double value) >+ : m_kind(kind) > , m_type(type) > { > u.doubleValue = value; > } > >- ValueKey(Opcode opcode, Type type, float value) >- : m_opcode(opcode) >+ ValueKey(Kind kind, Type type, float value) >+ : m_kind(kind) > , m_type(type) > { > u.floatValue = value; >@@ -86,7 +86,8 @@ public: > > static ValueKey intConstant(Type type, int64_t value); > >- Opcode opcode() const { return m_opcode; } >+ Kind kind() const { return m_kind; } >+ Opcode opcode() const { return kind().opcode(); } > Type type() const { return m_type; } > unsigned childIndex(unsigned index) const { return u.indices[index]; } > Value* child(Procedure&, unsigned index) const; >@@ -96,7 +97,7 @@ public: > > bool operator==(const ValueKey& other) const > { >- return m_opcode == other.m_opcode >+ return m_kind == other.m_kind > && m_type == other.m_type > && u == other.u; > } >@@ -108,7 +109,7 @@ public: > > unsigned hash() const > { >- return m_opcode + m_type + WTF::IntHash<int32_t>::hash(u.indices[0]) + u.indices[1] + u.indices[2]; >+ return m_kind.hash() + m_type + WTF::IntHash<int32_t>::hash(u.indices[0]) + u.indices[1] + u.indices[2]; > } > > explicit operator bool() const { return *this != ValueKey(); } >@@ -150,7 +151,7 @@ public: > } > > private: >- Opcode m_opcode { Oops }; >+ Kind m_kind; > Type m_type { Void }; > union U { > unsigned indices[3]; >Index: Source/JavaScriptCore/b3/B3ValueKeyInlines.h >=================================================================== >--- Source/JavaScriptCore/b3/B3ValueKeyInlines.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3ValueKeyInlines.h (working copy) >@@ -34,23 +34,23 @@ > > namespace JSC { namespace B3 { > >-inline ValueKey::ValueKey(Opcode opcode, Type type, Value* child) >- : m_opcode(opcode) >+inline ValueKey::ValueKey(Kind kind, Type type, Value* child) >+ : m_kind(kind) > , m_type(type) > { > u.indices[0] = child->index(); > } > >-inline ValueKey::ValueKey(Opcode opcode, Type type, Value* left, Value* right) >- : m_opcode(opcode) >+inline ValueKey::ValueKey(Kind kind, Type type, Value* left, Value* right) >+ : m_kind(kind) > , m_type(type) > { > u.indices[0] = left->index(); > u.indices[1] = right->index(); > } > >-inline ValueKey::ValueKey(Opcode opcode, Type type, Value* a, Value* b, Value* c) >- : m_opcode(opcode) >+inline ValueKey::ValueKey(Kind kind, Type type, Value* a, Value* b, Value* c) >+ : m_kind(kind) > , m_type(type) > { > u.indices[0] = a->index(); >Index: Source/JavaScriptCore/b3/B3VariableValue.cpp >=================================================================== >--- Source/JavaScriptCore/b3/B3VariableValue.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/B3VariableValue.cpp (working copy) >@@ -46,18 +46,18 @@ Value* VariableValue::cloneImpl() const > return new VariableValue(*this); > } > >-VariableValue::VariableValue(Opcode opcode, Origin origin, Variable* variable, Value* value) >- : Value(CheckedOpcode, opcode, Void, origin, value) >+VariableValue::VariableValue(Kind kind, Origin origin, Variable* variable, Value* value) >+ : Value(CheckedOpcode, kind, Void, origin, value) > , m_variable(variable) > { >- ASSERT(opcode == Set); >+ ASSERT(kind == Set); > } > >-VariableValue::VariableValue(Opcode opcode, Origin origin, Variable* variable) >- : Value(CheckedOpcode, opcode, variable->type(), origin) >+VariableValue::VariableValue(Kind kind, Origin origin, Variable* variable) >+ : Value(CheckedOpcode, kind, variable->type(), origin) > , m_variable(variable) > { >- ASSERT(opcode == Get); >+ ASSERT(kind == Get); > } > > } } // namespace JSC::B3 >Index: Source/JavaScriptCore/b3/B3VariableValue.h >=================================================================== >--- Source/JavaScriptCore/b3/B3VariableValue.h (revision 206524) >+++ Source/JavaScriptCore/b3/B3VariableValue.h (working copy) >@@ -36,7 +36,7 @@ class Variable; > > class JS_EXPORT_PRIVATE VariableValue : public Value { > public: >- static bool accepts(Opcode opcode) { return opcode == Get || opcode == Set; } >+ static bool accepts(Kind kind) { return kind == Get || kind == Set; } > > ~VariableValue(); > >@@ -51,10 +51,10 @@ private: > friend class Procedure; > > // Use this for Set. >- VariableValue(Opcode, Origin, Variable*, Value*); >+ VariableValue(Kind, Origin, Variable*, Value*); > > // Use this for Get. >- VariableValue(Opcode, Origin, Variable*); >+ VariableValue(Kind, Origin, Variable*); > > Variable* m_variable; > }; >Index: Source/JavaScriptCore/b3/testb3.cpp >=================================================================== >--- Source/JavaScriptCore/b3/testb3.cpp (revision 206524) >+++ Source/JavaScriptCore/b3/testb3.cpp (working copy) >@@ -9976,7 +9976,7 @@ void testChillDiv(int num, int den, int > root->appendNewControlValue( > proc, Return, Origin(), > root->appendNew<Value>( >- proc, ChillDiv, Origin(), >+ proc, chill(Div), Origin(), > root->appendNew<Value>( > proc, Trunc, Origin(), > root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)), >@@ -9995,7 +9995,7 @@ void testChillDiv(int num, int den, int > root->appendNewControlValue( > proc, Return, Origin(), > root->appendNew<Value>( >- proc, ChillDiv, Origin(), >+ proc, chill(Div), Origin(), > root->appendNew<Const32Value>(proc, Origin(), num), > root->appendNew<Const32Value>(proc, Origin(), den))); > >@@ -10013,7 +10013,7 @@ void testChillDivTwice(int num1, int den > root->appendNew<Value>( > proc, Add, Origin(), > root->appendNew<Value>( >- proc, ChillDiv, Origin(), >+ proc, chill(Div), Origin(), > root->appendNew<Value>( > proc, Trunc, Origin(), > root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)), >@@ -10021,7 +10021,7 @@ void testChillDivTwice(int num1, int den > proc, Trunc, Origin(), > root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))), > root->appendNew<Value>( >- proc, ChillDiv, Origin(), >+ proc, chill(Div), Origin(), > root->appendNew<Value>( > proc, Trunc, Origin(), > root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)), >@@ -10045,7 +10045,7 @@ void testChillDiv64(int64_t num, int64_t > root->appendNewControlValue( > proc, Return, Origin(), > root->appendNew<Value>( >- proc, ChillDiv, Origin(), >+ proc, chill(Div), Origin(), > root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0), > root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))); > >@@ -10060,7 +10060,7 @@ void testChillDiv64(int64_t num, int64_t > root->appendNewControlValue( > proc, Return, Origin(), > root->appendNew<Value>( >- proc, ChillDiv, Origin(), >+ proc, chill(Div), Origin(), > root->appendNew<Const64Value>(proc, Origin(), num), > root->appendNew<Const64Value>(proc, Origin(), den))); > >@@ -10179,7 +10179,7 @@ void testChillModArg(int64_t value) > BasicBlock* root = proc.addBlock(); > > Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0); >- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument, argument); >+ Value* result = root->appendNew<Value>(proc, chill(Mod), Origin(), argument, argument); > root->appendNewControlValue(proc, Return, Origin(), result); > > CHECK(!compileAndRun<int64_t>(proc, value)); >@@ -10192,7 +10192,7 @@ void testChillModArgs(int64_t numerator, > > Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0); > Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1); >- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2); >+ Value* result = root->appendNew<Value>(proc, chill(Mod), Origin(), argument1, argument2); > root->appendNewControlValue(proc, Return, Origin(), result); > > CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == chillMod(numerator, denominator)); >@@ -10205,7 +10205,7 @@ void testChillModImms(int64_t numerator, > > Value* argument1 = root->appendNew<Const64Value>(proc, Origin(), numerator); > Value* argument2 = root->appendNew<Const64Value>(proc, Origin(), denominator); >- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2); >+ Value* result = root->appendNew<Value>(proc, chill(Mod), Origin(), argument1, argument2); > root->appendNewControlValue(proc, Return, Origin(), result); > > CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == chillMod(numerator, denominator)); >@@ -10218,7 +10218,7 @@ void testChillModArg32(int32_t value) > > Value* argument = root->appendNew<Value>(proc, Trunc, Origin(), > root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); >- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument, argument); >+ Value* result = root->appendNew<Value>(proc, chill(Mod), Origin(), argument, argument); > root->appendNewControlValue(proc, Return, Origin(), result); > > CHECK(!compileAndRun<int32_t>(proc, value)); >@@ -10233,7 +10233,7 @@ void testChillModArgs32(int32_t numerato > root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); > Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(), > root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)); >- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2); >+ Value* result = root->appendNew<Value>(proc, chill(Mod), Origin(), argument1, argument2); > root->appendNewControlValue(proc, Return, Origin(), result); > > CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == chillMod(numerator, denominator)); >@@ -10246,7 +10246,7 @@ void testChillModImms32(int32_t numerato > > Value* argument1 = root->appendNew<Const32Value>(proc, Origin(), numerator); > Value* argument2 = root->appendNew<Const32Value>(proc, Origin(), denominator); >- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2); >+ Value* result = root->appendNew<Value>(proc, chill(Mod), Origin(), argument1, argument2); > root->appendNewControlValue(proc, Return, Origin(), result); > > CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == chillMod(numerator, denominator)); >@@ -10313,7 +10313,7 @@ void testSwitchChillDiv(unsigned degree, > newBlock->appendNewControlValue( > proc, Return, Origin(), > newBlock->appendNew<Value>( >- proc, ChillDiv, Origin(), (i & 1) ? right : left, (i & 1) ? left : right)); >+ proc, chill(Div), Origin(), (i & 1) ? right : left, (i & 1) ? left : right)); > > switchValue->appendCase(SwitchCase(gap * i, FrequentedBlock(newBlock))); > } >@@ -12674,7 +12674,7 @@ void testEntrySwitchWithCommonPaths() > end->appendNew<Value>( > proc, Return, Origin(), > end->appendNew<Value>( >- proc, ChillMod, Origin(), >+ proc, chill(Mod), Origin(), > phi, end->appendNew<Value>( > proc, Trunc, Origin(), > end->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)))); >@@ -12791,7 +12791,7 @@ void testEntrySwitchWithCommonPathsAndNo > end->appendNew<Value>( > proc, Return, Origin(), > end->appendNew<Value>( >- proc, ChillMod, Origin(), >+ proc, chill(Mod), Origin(), > phi, end->appendNew<Value>( > proc, Trunc, Origin(), > end->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)))); >Index: Source/JavaScriptCore/ftl/FTLOutput.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLOutput.cpp (revision 206524) >+++ Source/JavaScriptCore/ftl/FTLOutput.cpp (working copy) >@@ -151,7 +151,7 @@ LValue Output::div(LValue left, LValue r > > LValue Output::chillDiv(LValue left, LValue right) > { >- return m_block->appendNew<B3::Value>(m_proc, B3::ChillDiv, origin(), left, right); >+ return m_block->appendNew<B3::Value>(m_proc, chill(B3::Div), origin(), left, right); > } > > LValue Output::mod(LValue left, LValue right) >@@ -161,7 +161,7 @@ LValue Output::mod(LValue left, LValue r > > LValue Output::chillMod(LValue left, LValue right) > { >- return m_block->appendNew<B3::Value>(m_proc, B3::ChillMod, origin(), left, right); >+ return m_block->appendNew<B3::Value>(m_proc, chill(B3::Mod), origin(), left, right); > } > > LValue Output::neg(LValue value) >Index: Websites/webkit.org/ChangeLog >=================================================================== >--- Websites/webkit.org/ChangeLog (revision 206524) >+++ Websites/webkit.org/ChangeLog (working copy) >@@ -1,3 +1,15 @@ >+2016-09-28 Filip Pizlo <fpizlo@apple.com> >+ >+ B3 opcodes should leave room for flags >+ https://bugs.webkit.org/show_bug.cgi?id=162692 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Updated the documentation to talk about Kind and the isChill bit, and to remove >+ ChillDiv/ChillMod. >+ >+ * docs/b3/intermediate-representation.html: >+ > 2016-09-27 Joseph Pecoraro <pecoraro@apple.com> > > Update style guide for #pragma once >Index: Websites/webkit.org/docs/b3/intermediate-representation.html >=================================================================== >--- Websites/webkit.org/docs/b3/intermediate-representation.html (revision 206524) >+++ Websites/webkit.org/docs/b3/intermediate-representation.html (working copy) >@@ -78,9 +78,14 @@ > <h2>Values</h2> > > <p>Variables, and the instructions that define them, are represented using the Value object. >- The Value object has a return type, an opcode, and zero or more children. Children are >+ The Value object has a return type, a kind, and zero or more children. Children are > references to other Values. Those values are used as input to the instruction that > computes this value.</p> >+ >+ <p>The value kind is a combination of an opcode and optional flags. The flags allow a single >+ opcode to have many variants. For example, Div and Mod may have the Chill flag set to indicate >+ that they should not trap on corner cases.</p> >+ > <p>Values also have a unique 32-bit index that is used as the name.</p> > > <p>Example:</p> >@@ -231,31 +236,36 @@ > according to the IEEE 854 spec.</dd> > > <dt>T Div(T, T)</dt> >- <dd>Works with any type except Void. For integer types, this represents signed division >- with round-to-zero. Its behavior is undefined for x/0 or -2<sup>31</sup>/-1. For floating >- point types, this represents division according to the IEEE 854 spec.</dd> >+ <dd> >+ <p>Works with any type except Void. For integer types, this represents signed >+ division with round-to-zero. By default, its behavior is undefined for x/0 or >+ -2<sup>31</sup>/-1. For floating point types, this represents division according >+ to the IEEE 854 spec.</p> >+ <p>Integer Div may have the Chill flag set. You can create a Chill Div by saying >+ <code>chill(Div)</code> instead of <code>Div</code>; the former creates a Kind >+ that has Div as the opcode and has the Chill bit set. An operation is said to be >+ chill if it returns a sensible value whenever its non-chill form would have had >+ undefined behavior. Chill Div turns x/0 into 0 and -2<sup>31</sup>/-1 into >+ -2<sup>31</sup>. We recognize this in IR because it's exactly the semantics of >+ division on ARM64, and it's also exactly the semantics that JavaScript wants for >+ "(x/y)|0".</p> >+ </dd> > > <dt>T Mod(T, T)</dt> >- <dd>Works with any type except Void. For integer types, this represents signed modulo. >- Its behavior is undefined for x%0 or -2<sup>31</sup>%-1. For floating point types, this >- represents modulo according to "fmod()".</dd> >+ <dd> >+ <p>Works with any type except Void. For integer types, this represents signed >+ modulo. By default, its behavior is undefined for x%0 or -2<sup>31</sup>%-1. For >+ floating point types, this represents modulo according to "fmod()".</p> >+ <p>Integer Mod may have the Chill flag set. You can create a Chill Mod by saying >+ <code>chill(Mod)</code>. Chill Mod turns x%0 into 0 and -2<sup>31</sup>%-1 into >+ 0.</p> >+ </dd> > > <dt>T Neg(T)</dt> > <dd>Works with any type except Void. For integer types, this represents twos-complement > negation. For floating point types, this represents negation according to the IEEE > spec.</dd> > >- <dt>T ChillDiv(T, T)</dt> >- <dd>Chill division. Valid for Int32 and Int64. An operation is said to be chill if it >- returns a sensible value whenever its non-chill form would have had undefined behavior. >- ChillDiv turns x/0 into 0 and -2<sup>31</sup>/-1 into -2<sup>31</sup>. This is a separate opcode >- because it's exactly the semantics of division on ARM64, and it's also exactly the >- semantics that JavaScript wants for "(x/y)|0".</dd> >- >- <dt>T ChillMod(T, T)</dt> >- <dd>Chill modulo. Valid for Int32 and Int64. ChllMod turns x%0 into 0 and >- -2<sup>31</sup>%-1 into 0.</dd> >- > <dt>T BitAnd(T, T)</dt> > <dd>Bitwise and. Valid for Int32 and Int64.</dd> >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
keith_miller
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 162692
:
290105
|
290123
|
290162
| 290176