Changeset 242569 in webkit
- Timestamp:
- Mar 6, 2019, 2:57:08 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 6 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/optional-def-arg-width-should-be-both-early-and-late-use.js (added)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/b3/air/AirPadInterference.h (modified) (1 diff)
-
Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/b3/testb3.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r242568 r242569 1 2019-03-06 Saam Barati <sbarati@apple.com> 2 3 Air::reportUsedRegisters must padInterference 4 https://bugs.webkit.org/show_bug.cgi?id=195303 5 <rdar://problem/48270343> 6 7 Reviewed by Keith Miller. 8 9 * stress/optional-def-arg-width-should-be-both-early-and-late-use.js: Added. 10 1 11 2019-03-06 Yusuke Suzuki <ysuzuki@apple.com> 2 12 -
trunk/Source/JavaScriptCore/ChangeLog
r242568 r242569 1 2019-03-06 Saam Barati <sbarati@apple.com> 2 3 Air::reportUsedRegisters must padInterference 4 https://bugs.webkit.org/show_bug.cgi?id=195303 5 <rdar://problem/48270343> 6 7 Reviewed by Keith Miller. 8 9 reportUsedRegisters uses reg liveness to eliminate loads/moves into dead 10 registers. However, liveness can report incorrect results in certain 11 scenarios when considering liveness at instruction boundaries. For example, 12 it can go wrong when an Inst has a LateUse of a register and the following 13 Inst has an EarlyDef of that same register. Such a scenario could lead us 14 to incorrectly say the register is not live-in to the first Inst. Pad 15 interference inserts Nops between such instruction boundaries that cause 16 this issue. 17 18 The test with this patch fixes the issue in reportUsedRegisters. This patch 19 also conservatively makes it so that lowerAfterRegAlloc calls padInterference 20 since it also reasons about liveness. 21 22 * b3/air/AirLowerAfterRegAlloc.cpp: 23 (JSC::B3::Air::lowerAfterRegAlloc): 24 * b3/air/AirPadInterference.h: 25 * b3/air/AirReportUsedRegisters.cpp: 26 (JSC::B3::Air::reportUsedRegisters): 27 * b3/testb3.cpp: 28 (JSC::B3::testReportUsedRegistersLateUseNotDead): 29 (JSC::B3::run): 30 1 31 2019-03-06 Yusuke Suzuki <ysuzuki@apple.com> 2 32 -
trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp
r221954 r242569 35 35 #include "AirInsertionSet.h" 36 36 #include "AirInstInlines.h" 37 #include "AirPadInterference.h" 37 38 #include "AirRegLiveness.h" 38 39 #include "AirPhaseScope.h" … … 77 78 if (!haveAnyRelevant) 78 79 return; 80 81 padInterference(code); 79 82 80 83 HashMap<Inst*, RegisterSet> usedRegisters; -
trunk/Source/JavaScriptCore/b3/air/AirPadInterference.h
r207434 r242569 33 33 34 34 // This isn't a phase - it's meant to be a utility that other phases use. Air reasons about liveness by 35 // reasoning about interference at boundaries between instructions. This can go wrong - for example, a 35 // reasoning about interference at boundaries between instructions. This is convenient because it works 36 // great in the most common case: early uses and late defs. However, this can go wrong - for example, a 36 37 // late use in one instruction doesn't actually interfere with an early def of the next instruction, but 37 // Air thinks that it does. This is convenient because it works great in the most common case: early uses 38 // and late defs. In practice, only the register allocators need to use this, since only they need to be 39 // able to color the interference graph using a bounded number of colors. 38 // Air thinks that it does. It can also go wrong by having liveness incorrectly report that something is 39 // dead when it isn't. 40 40 // 41 41 // See https://bugs.webkit.org/show_bug.cgi?id=163548#c2 for more info. -
trunk/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp
r225893 r242569 32 32 #include "AirCode.h" 33 33 #include "AirInstInlines.h" 34 #include "AirPadInterference.h" 34 35 #include "AirRegLiveness.h" 35 36 #include "AirPhaseScope.h" … … 42 43 43 44 static constexpr bool verbose = false; 45 46 padInterference(code); 44 47 45 48 if (verbose) -
trunk/Source/JavaScriptCore/b3/testb3.cpp
r242100 r242569 16722 16722 demoteValues(proc, valuesToDemote); 16723 16723 validate(proc); 16724 } 16725 16726 void testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead() 16727 { 16728 Procedure proc; 16729 if (proc.optLevel() < 2) 16730 return; 16731 BasicBlock* root = proc.addBlock(); 16732 16733 RegisterSet allRegs = RegisterSet::allGPRs(); 16734 allRegs.exclude(RegisterSet::stackRegisters()); 16735 allRegs.exclude(RegisterSet::reservedHardwareRegisters()); 16736 16737 { 16738 // Make every reg 42 (just needs to be a value other than 10). 16739 PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin()); 16740 Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42); 16741 for (Reg reg : allRegs) 16742 patchpoint->append(const42, ValueRep::reg(reg)); 16743 patchpoint->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { }); 16744 } 16745 16746 { 16747 PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin()); 16748 Value* const10 = root->appendNew<Const32Value>(proc, Origin(), 10); 16749 for (Reg reg : allRegs) 16750 patchpoint->append(const10, ValueRep::lateReg(reg)); 16751 patchpoint->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { 16752 for (Reg reg : allRegs) { 16753 auto done = jit.branch32(CCallHelpers::Equal, reg.gpr(), CCallHelpers::TrustedImm32(10)); 16754 jit.breakpoint(); 16755 done.link(&jit); 16756 } 16757 }); 16758 } 16759 16760 { 16761 PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin()); 16762 patchpoint->resultConstraint = ValueRep::SomeEarlyRegister; 16763 patchpoint->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams& params) { 16764 RELEASE_ASSERT(allRegs.contains(params[0].gpr())); 16765 }); 16766 } 16767 16768 root->appendNewControlValue(proc, Return, Origin()); 16769 16770 compileAndRun<void>(proc); 16724 16771 } 16725 16772 … … 18350 18397 } 18351 18398 18399 RUN(testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead()); 18400 18352 18401 if (tasks.isEmpty()) 18353 18402 usage();
Note:
See TracChangeset
for help on using the changeset viewer.