Changeset 194402 in webkit
- Timestamp:
- Dec 23, 2015, 4:26:04 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 10 edited
-
ChangeLog (modified) (1 diff)
-
JavaScriptCore.xcodeproj/project.pbxproj (modified) (4 diffs)
-
b3/B3LowerToAir.cpp (modified) (4 diffs)
-
b3/B3Validate.cpp (modified) (3 diffs)
-
b3/air/AirCode.h (modified) (2 diffs)
-
b3/air/AirFixSpillSlotZDef.h (added)
-
b3/air/AirGenerate.cpp (modified) (1 diff)
-
b3/air/AirIteratedRegisterCoalescing.cpp (modified) (3 diffs)
-
b3/air/AirSpillEverything.cpp (modified) (4 diffs)
-
b3/air/AirTmpWidth.cpp (modified) (1 diff)
-
runtime/Options.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r194401 r194402 1 2015-12-23 Filip Pizlo <fpizlo@apple.com> 2 3 FTL B3 should be able to run crypto-sha1 in eager mode 4 https://bugs.webkit.org/show_bug.cgi?id=152539 5 6 Reviewed by Saam Barati. 7 8 This patch contains one real bug fix and some other fixes that are primarily there for sanity 9 because I don't believe they are symptomatic. 10 11 The real fix is the instruction selector's handling of Phi. It was assuming that the correct 12 lowering of Phi is to do nothing and the correct lowering of Upsilon is to store into the tmp 13 that the Phi uses. But this fails for code patterns like: 14 15 @a = Phi() 16 Upsilon(@x, ^a) 17 use(@a) // this should see the value that @a had at the point that "@a = Phi()" executed. 18 19 This arises when we have a lot of Upsilons in a row and they are trying to perform a 20 shuffling. Prior to this change, "use(@a)" would see the new value of @a, i.e. @x. That's 21 wrong. So, this changes the lowering to make each Phi have a special shadow Tmp, and Upsilon 22 stores to it while Phi loads from it. Most of these assignments get copy-propagated by IRC, 23 so it doesn't really hurt us. I couldn't find any benchmarks that slowed down because of 24 this. In fact, I believe that the only time that this would lead to extra interference or 25 extra assignments is when it's actually needed to be correct. 26 27 This also contains other fixes, which are probably not for real bugs, but they make me feel 28 all warm and fuzzy: 29 30 - spillEverything() works again. Previously, it didn't have all of IRC's smarts for handling 31 a spill of a ZDef. I fixed this by creating a helper phase that finds all subwidth ZDefs 32 to spill slots and amends them with zero-fills of the top bits. 33 34 - IRC no longer requires precise TmpWidth analysis. Previously, if TmpWidth gave pessimistic 35 results, the subwidth ZDef bug would return. That probably means that it was never fixed 36 to begin with, since it's totally cool for just a single def or use of a tmp to cause it 37 to become pessimistic. But there may still have been some subwidth ZDefs. The way that I 38 fixed this bug is to have IRC also run the ZDef fixup code that spillEverything() uses. 39 This is abstracted behind the beautifully named Air::fixSpillSlotZDef(). 40 41 - B3::validate() does dominance checks! So, if you shoot yourself in the foot by using 42 something before defining it, validate() will tell you. 43 44 - Air::TmpWidth is now easy to "turn off" - i.e. to make it go fully conservative. It's not 45 an Option; you have to hack code. But that's better than nothing, and it's consistent with 46 what we do for other super-internal compiler options that we use rarely. 47 48 - You can now run spillEverything() without hacking code. Just use 49 Options::airSpillSeverything(). 50 51 * JavaScriptCore.xcodeproj/project.pbxproj: 52 * b3/B3LowerToAir.cpp: 53 (JSC::B3::Air::LowerToAir::LowerToAir): 54 (JSC::B3::Air::LowerToAir::run): 55 (JSC::B3::Air::LowerToAir::lower): 56 * b3/B3Validate.cpp: 57 * b3/air/AirCode.h: 58 (JSC::B3::Air::Code::specials): 59 (JSC::B3::Air::Code::forAllTmps): 60 (JSC::B3::Air::Code::isFastTmp): 61 * b3/air/AirFixSpillSlotZDef.h: Added. 62 (JSC::B3::Air::fixSpillSlotZDef): 63 * b3/air/AirGenerate.cpp: 64 (JSC::B3::Air::prepareForGeneration): 65 * b3/air/AirIteratedRegisterCoalescing.cpp: 66 * b3/air/AirSpillEverything.cpp: 67 (JSC::B3::Air::spillEverything): 68 * b3/air/AirTmpWidth.cpp: 69 (JSC::B3::Air::TmpWidth::recompute): 70 * jit/JITOperations.cpp: 71 * runtime/Options.h: 72 1 73 2015-12-23 Filip Pizlo <fpizlo@apple.com> 2 74 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r194394 r194402 375 375 0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 376 376 0F4C91661C29F4F2004341A6 /* B3OriginDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4C91651C29F4F2004341A6 /* B3OriginDump.h */; }; 377 0F4C91681C2B3D68004341A6 /* AirFixSpillSlotZDef.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4C91671C2B3D68004341A6 /* AirFixSpillSlotZDef.h */; }; 377 378 0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; }; 378 379 0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; }; … … 2509 2510 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = "<group>"; }; 2510 2511 0F4C91651C29F4F2004341A6 /* B3OriginDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3OriginDump.h; path = b3/B3OriginDump.h; sourceTree = "<group>"; }; 2512 0F4C91671C2B3D68004341A6 /* AirFixSpillSlotZDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirFixSpillSlotZDef.h; path = b3/air/AirFixSpillSlotZDef.h; sourceTree = "<group>"; }; 2511 2513 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = "<group>"; }; 2512 2514 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; }; … … 4777 4779 262D85B41C0D650F006ACB61 /* AirFixPartialRegisterStalls.cpp */, 4778 4780 262D85B51C0D650F006ACB61 /* AirFixPartialRegisterStalls.h */, 4781 0F4C91671C2B3D68004341A6 /* AirFixSpillSlotZDef.h */, 4779 4782 0FEC85521BDACDC70080FF74 /* AirFrequentedBlock.h */, 4780 4783 0FEC85531BDACDC70080FF74 /* AirGenerate.cpp */, … … 7217 7220 0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */, 7218 7221 0FFFC95E14EF90B700C72532 /* DFGPredictionPropagationPhase.h in Headers */, 7222 0F4C91681C2B3D68004341A6 /* AirFixSpillSlotZDef.h in Headers */, 7219 7223 0F3E01AB19D353A500F61B7F /* DFGPrePostNumbering.h in Headers */, 7220 7224 0F2B9CED19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h in Headers */, -
trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp
r194401 r194402 65 65 LowerToAir(Procedure& procedure) 66 66 : m_valueToTmp(procedure.values().size()) 67 , m_phiToTmp(procedure.values().size()) 67 68 , m_blockToBlock(procedure.size()) 68 69 , m_useCounts(procedure) … … 77 78 for (B3::BasicBlock* block : m_procedure) 78 79 m_blockToBlock[block] = m_code.addBlock(block->frequency()); 80 79 81 for (Value* value : m_procedure.values()) { 80 if (StackSlotValue* stackSlotValue = value->as<StackSlotValue>()) 82 switch (value->opcode()) { 83 case Phi: { 84 m_phiToTmp[value] = m_code.newTmp(Arg::typeForB3Type(value->type())); 85 break; 86 } 87 case B3::StackSlot: { 88 StackSlotValue* stackSlotValue = value->as<StackSlotValue>(); 81 89 m_stackToStack.add(stackSlotValue, m_code.addStackSlot(stackSlotValue)); 90 break; 91 } 92 default: 93 break; 94 } 82 95 } 83 96 … … 2127 2140 append( 2128 2141 relaxedMoveForType(value->type()), immOrTmp(value), 2129 tmp(m_value->as<UpsilonValue>()->phi()));2142 m_phiToTmp[m_value->as<UpsilonValue>()->phi()]); 2130 2143 return; 2131 2144 } 2132 2145 2133 2146 case Phi: { 2134 // Our semantics are determined by Upsilons, so we have nothing to do here. 2147 // Snapshot the value of the Phi. It may change under us because you could do: 2148 // a = Phi() 2149 // Upsilon(@x, ^a) 2150 // @a => this should get the value of the Phi before the Upsilon, i.e. not @x. 2151 2152 append(relaxedMoveForType(m_value->type()), m_phiToTmp[m_value], tmp(m_value)); 2135 2153 return; 2136 2154 } … … 2210 2228 IndexSet<Value> m_locked; // These are values that will have no Tmp in Air. 2211 2229 IndexMap<Value, Tmp> m_valueToTmp; // These are values that must have a Tmp in Air. We say that a Value* with a non-null Tmp is "pinned". 2230 IndexMap<Value, Tmp> m_phiToTmp; // Each Phi gets its own Tmp. 2212 2231 IndexMap<B3::BasicBlock, Air::BasicBlock*> m_blockToBlock; 2213 2232 HashMap<StackSlotValue*, Air::StackSlot*> m_stackToStack; -
trunk/Source/JavaScriptCore/b3/B3Validate.cpp
r194341 r194402 31 31 #include "B3ArgumentRegValue.h" 32 32 #include "B3BasicBlockInlines.h" 33 #include "B3Dominators.h" 33 34 #include "B3MemoryValue.h" 34 35 #include "B3Procedure.h" … … 63 64 HashSet<Value*> valueInProc; 64 65 HashMap<Value*, unsigned> valueInBlock; 66 HashMap<Value*, BasicBlock*> valueOwner; 67 HashMap<Value*, unsigned> valueIndex; 65 68 66 69 for (BasicBlock* block : m_procedure) { 67 70 blocks.add(block); 68 for (Value* value : *block) 71 for (unsigned i = 0; i < block->size(); ++i) { 72 Value* value = block->at(i); 69 73 valueInBlock.add(value, 0).iterator->value++; 74 valueOwner.add(value, block); 75 valueIndex.add(value, i); 76 } 70 77 } 71 78 … … 80 87 } 81 88 89 // Compute dominators ourselves to avoid perturbing Procedure. 90 Dominators dominators(m_procedure); 91 82 92 for (Value* value : valueInProc) { 83 93 for (Value* child : value->children()) { 84 94 VALIDATE(child, ("At ", *value)); 85 95 VALIDATE(valueInProc.contains(child), ("At ", *value, "->", pointerDump(child))); 96 if (valueOwner.get(child) == valueOwner.get(value)) 97 VALIDATE(valueIndex.get(value) > valueIndex.get(child), ("At ", *value, "->", pointerDump(child))); 98 else 99 VALIDATE(dominators.dominates(valueOwner.get(child), valueOwner.get(value)), ("at ", *value, "->", pointerDump(child))); 86 100 } 87 101 } -
trunk/Source/JavaScriptCore/b3/air/AirCode.h
r193682 r194402 58 58 BasicBlock* addBlock(double frequency = 1); 59 59 60 // Note that you can rely on stack slots always getting indices that are larger than the index 61 // of any prior stack slot. In fact, all stack slots you create in the future will have an index 62 // that is >= stackSlots().size(). 60 63 StackSlot* addStackSlot(unsigned byteSize, StackSlotKind, StackSlotValue* = nullptr); 61 64 StackSlot* addStackSlot(StackSlotValue*); … … 291 294 292 295 SpecialsCollection specials() const { return SpecialsCollection(*this); } 296 297 template<typename Callback> 298 void forAllTmps(const Callback& callback) const 299 { 300 for (unsigned i = m_numGPTmps; i--;) 301 callback(Tmp::gpTmpForIndex(i)); 302 for (unsigned i = m_numFPTmps; i--;) 303 callback(Tmp::fpTmpForIndex(i)); 304 } 293 305 294 306 void addFastTmp(Tmp); -
trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp
r192981 r194402 75 75 // 76 76 // For debugging, you can use spillEverything() to put everything to the stack between each Inst. 77 if ( false)77 if (Options::airSpillsEverything()) 78 78 spillEverything(code); 79 79 else -
trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp
r194385 r194402 30 30 31 31 #include "AirCode.h" 32 #include "AirFixSpillSlotZDef.h" 32 33 #include "AirInsertionSet.h" 33 34 #include "AirInstInlines.h" … … 1165 1166 { 1166 1167 HashMap<Tmp, StackSlot*> stackSlots; 1168 unsigned newStackSlotThreshold = m_code.stackSlots().size(); 1167 1169 for (Tmp tmp : allocator.spilledTmps()) { 1168 1170 // All the spilled values become unspillable. … … 1261 1263 } 1262 1264 } 1265 1266 fixSpillSlotZDef( 1267 m_code, 1268 [&] (StackSlot* stackSlot) -> bool { 1269 return stackSlot->index() >= newStackSlotThreshold; 1270 }); 1263 1271 } 1264 1272 -
trunk/Source/JavaScriptCore/b3/air/AirSpillEverything.cpp
r194331 r194402 30 30 31 31 #include "AirCode.h" 32 #include "AirFixSpillSlotZDef.h" 32 33 #include "AirInsertionSet.h" 33 34 #include "AirInstInlines.h" … … 87 88 // Allocate a stack slot for each tmp. 88 89 Vector<StackSlot*> allStackSlots[Arg::numTypes]; 90 unsigned newStackSlotThreshold = code.stackSlots().size(); 89 91 for (unsigned typeIndex = 0; typeIndex < Arg::numTypes; ++typeIndex) { 90 92 Vector<StackSlot*>& stackSlots = allStackSlots[typeIndex]; … … 110 112 continue; 111 113 112 if (inst.admitsStack(i)) { 114 if (inst.admitsStack(i)) { 113 115 StackSlot* stackSlot = allStackSlots[arg.type()][arg.tmpIndex()]; 114 116 arg = Arg::stack(stackSlot); … … 185 187 insertionSet.execute(block); 186 188 } 189 190 fixSpillSlotZDef( 191 code, 192 [&] (StackSlot* stackSlot) -> bool { 193 return stackSlot->index() >= newStackSlotThreshold; 194 }); 187 195 } 188 196 -
trunk/Source/JavaScriptCore/b3/air/AirTmpWidth.cpp
r194331 r194402 49 49 void TmpWidth::recompute(Code& code) 50 50 { 51 // Set this to true to cause this analysis to always return pessimistic results. 52 const bool beCareful = false; 53 51 54 m_width.clear(); 55 56 auto assumeTheWorst = [&] (Tmp tmp) { 57 Widths& widths = m_width.add(tmp, Widths()).iterator->value; 58 Arg::Type type = Arg(tmp).type(); 59 widths.use = Arg::conservativeWidth(type); 60 widths.def = Arg::conservativeWidth(type); 61 }; 52 62 53 63 // Assume the worst for registers. 54 64 RegisterSet::allRegisters().forEach( 55 65 [&] (Reg reg) { 56 Widths& widths = m_width.add(Tmp(reg), Widths()).iterator->value; 57 Arg::Type type = Arg(Tmp(reg)).type(); 58 widths.use = Arg::conservativeWidth(type); 59 widths.def = Arg::conservativeWidth(type); 66 assumeTheWorst(Tmp(reg)); 60 67 }); 61 68 69 if (beCareful) { 70 code.forAllTmps(assumeTheWorst); 71 72 // We fall through because the fixpoint that follows can only make things even more 73 // conservative. This mode isn't meant to be fast, just safe. 74 } 75 62 76 // Now really analyze everything but Move's over Tmp's, but set aside those Move's so we can find 63 77 // them quickly during the fixpoint below. Note that we can make this analysis stronger by -
trunk/Source/JavaScriptCore/runtime/Options.h
r193424 r194402 341 341 v(bool, logB3PhaseTimes, false, nullptr) \ 342 342 v(double, rareBlockPenalty, 0.001, nullptr) \ 343 v(bool, airSpillsEverything, false, nullptr) \ 343 344 \ 344 345 v(bool, useDollarVM, false, "installs the $vm debugging tool in global objects") \
Note:
See TracChangeset
for help on using the changeset viewer.