Changeset 242857 in webkit
- Timestamp:
- Mar 13, 2019, 1:24:38 AM (7 years ago)
- Location:
- branches/safari-607-branch
- 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
-
branches/safari-607-branch/JSTests/ChangeLog
r242855 r242857 1 2019-03-13 Babak Shafiei <bshafiei@apple.com> 2 3 Cherry-pick r242569. rdar://problem/48839273 4 5 Air::reportUsedRegisters must padInterference 6 https://bugs.webkit.org/show_bug.cgi?id=195303 7 <rdar://problem/48270343> 8 9 Reviewed by Keith Miller. 10 11 JSTests: 12 13 * stress/optional-def-arg-width-should-be-both-early-and-late-use.js: Added. 14 15 Source/JavaScriptCore: 16 17 reportUsedRegisters uses reg liveness to eliminate loads/moves into dead 18 registers. However, liveness can report incorrect results in certain 19 scenarios when considering liveness at instruction boundaries. For example, 20 it can go wrong when an Inst has a LateUse of a register and the following 21 Inst has an EarlyDef of that same register. Such a scenario could lead us 22 to incorrectly say the register is not live-in to the first Inst. Pad 23 interference inserts Nops between such instruction boundaries that cause 24 this issue. 25 26 The test with this patch fixes the issue in reportUsedRegisters. This patch 27 also conservatively makes it so that lowerAfterRegAlloc calls padInterference 28 since it also reasons about liveness. 29 30 * b3/air/AirLowerAfterRegAlloc.cpp: 31 (JSC::B3::Air::lowerAfterRegAlloc): 32 * b3/air/AirPadInterference.h: 33 * b3/air/AirReportUsedRegisters.cpp: 34 (JSC::B3::Air::reportUsedRegisters): 35 * b3/testb3.cpp: 36 (JSC::B3::testReportUsedRegistersLateUseNotDead): 37 (JSC::B3::run): 38 39 40 git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242569 268f45cc-cd09-0410-ab3c-d52691b4dbfc 41 42 2019-03-06 Saam Barati <sbarati@apple.com> 43 44 Air::reportUsedRegisters must padInterference 45 https://bugs.webkit.org/show_bug.cgi?id=195303 46 <rdar://problem/48270343> 47 48 Reviewed by Keith Miller. 49 50 * stress/optional-def-arg-width-should-be-both-early-and-late-use.js: Added. 51 1 52 2019-03-13 Babak Shafiei <bshafiei@apple.com> 2 53 -
branches/safari-607-branch/Source/JavaScriptCore/ChangeLog
r242855 r242857 1 2019-03-13 Babak Shafiei <bshafiei@apple.com> 2 3 Cherry-pick r242569. rdar://problem/48839273 4 5 Air::reportUsedRegisters must padInterference 6 https://bugs.webkit.org/show_bug.cgi?id=195303 7 <rdar://problem/48270343> 8 9 Reviewed by Keith Miller. 10 11 JSTests: 12 13 * stress/optional-def-arg-width-should-be-both-early-and-late-use.js: Added. 14 15 Source/JavaScriptCore: 16 17 reportUsedRegisters uses reg liveness to eliminate loads/moves into dead 18 registers. However, liveness can report incorrect results in certain 19 scenarios when considering liveness at instruction boundaries. For example, 20 it can go wrong when an Inst has a LateUse of a register and the following 21 Inst has an EarlyDef of that same register. Such a scenario could lead us 22 to incorrectly say the register is not live-in to the first Inst. Pad 23 interference inserts Nops between such instruction boundaries that cause 24 this issue. 25 26 The test with this patch fixes the issue in reportUsedRegisters. This patch 27 also conservatively makes it so that lowerAfterRegAlloc calls padInterference 28 since it also reasons about liveness. 29 30 * b3/air/AirLowerAfterRegAlloc.cpp: 31 (JSC::B3::Air::lowerAfterRegAlloc): 32 * b3/air/AirPadInterference.h: 33 * b3/air/AirReportUsedRegisters.cpp: 34 (JSC::B3::Air::reportUsedRegisters): 35 * b3/testb3.cpp: 36 (JSC::B3::testReportUsedRegistersLateUseNotDead): 37 (JSC::B3::run): 38 39 40 git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242569 268f45cc-cd09-0410-ab3c-d52691b4dbfc 41 42 2019-03-06 Saam Barati <sbarati@apple.com> 43 44 Air::reportUsedRegisters must padInterference 45 https://bugs.webkit.org/show_bug.cgi?id=195303 46 <rdar://problem/48270343> 47 48 Reviewed by Keith Miller. 49 50 reportUsedRegisters uses reg liveness to eliminate loads/moves into dead 51 registers. However, liveness can report incorrect results in certain 52 scenarios when considering liveness at instruction boundaries. For example, 53 it can go wrong when an Inst has a LateUse of a register and the following 54 Inst has an EarlyDef of that same register. Such a scenario could lead us 55 to incorrectly say the register is not live-in to the first Inst. Pad 56 interference inserts Nops between such instruction boundaries that cause 57 this issue. 58 59 The test with this patch fixes the issue in reportUsedRegisters. This patch 60 also conservatively makes it so that lowerAfterRegAlloc calls padInterference 61 since it also reasons about liveness. 62 63 * b3/air/AirLowerAfterRegAlloc.cpp: 64 (JSC::B3::Air::lowerAfterRegAlloc): 65 * b3/air/AirPadInterference.h: 66 * b3/air/AirReportUsedRegisters.cpp: 67 (JSC::B3::Air::reportUsedRegisters): 68 * b3/testb3.cpp: 69 (JSC::B3::testReportUsedRegistersLateUseNotDead): 70 (JSC::B3::run): 71 1 72 2019-03-13 Babak Shafiei <bshafiei@apple.com> 2 73 -
branches/safari-607-branch/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp
r221954 r242857 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; -
branches/safari-607-branch/Source/JavaScriptCore/b3/air/AirPadInterference.h
r207434 r242857 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. -
branches/safari-607-branch/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp
r225893 r242857 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) -
branches/safari-607-branch/Source/JavaScriptCore/b3/testb3.cpp
r239187 r242857 16279 16279 demoteValues(proc, valuesToDemote); 16280 16280 validate(proc); 16281 } 16282 16283 void testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead() 16284 { 16285 Procedure proc; 16286 if (proc.optLevel() < 2) 16287 return; 16288 BasicBlock* root = proc.addBlock(); 16289 16290 RegisterSet allRegs = RegisterSet::allGPRs(); 16291 allRegs.exclude(RegisterSet::stackRegisters()); 16292 allRegs.exclude(RegisterSet::reservedHardwareRegisters()); 16293 16294 { 16295 // Make every reg 42 (just needs to be a value other than 10). 16296 PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin()); 16297 Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42); 16298 for (Reg reg : allRegs) 16299 patchpoint->append(const42, ValueRep::reg(reg)); 16300 patchpoint->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { }); 16301 } 16302 16303 { 16304 PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin()); 16305 Value* const10 = root->appendNew<Const32Value>(proc, Origin(), 10); 16306 for (Reg reg : allRegs) 16307 patchpoint->append(const10, ValueRep::lateReg(reg)); 16308 patchpoint->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { 16309 for (Reg reg : allRegs) { 16310 auto done = jit.branch32(CCallHelpers::Equal, reg.gpr(), CCallHelpers::TrustedImm32(10)); 16311 jit.breakpoint(); 16312 done.link(&jit); 16313 } 16314 }); 16315 } 16316 16317 { 16318 PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin()); 16319 patchpoint->resultConstraint = ValueRep::SomeEarlyRegister; 16320 patchpoint->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams& params) { 16321 RELEASE_ASSERT(allRegs.contains(params[0].gpr())); 16322 }); 16323 } 16324 16325 root->appendNewControlValue(proc, Return, Origin()); 16326 16327 compileAndRun<void>(proc); 16281 16328 } 16282 16329 … … 17876 17923 } 17877 17924 17925 RUN(testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead()); 17926 17878 17927 if (tasks.isEmpty()) 17879 17928 usage();
Note:
See TracChangeset
for help on using the changeset viewer.