Changeset 263116 in webkit
- Timestamp:
- Jun 16, 2020 2:17:04 PM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r263108 r263116 1 2020-06-16 Robin Morisset <rmorisset@apple.com> 2 3 Optimize Air::TmpWidth analysis in IRC 4 https://bugs.webkit.org/show_bug.cgi?id=152478 5 6 Reviewed by Filip Pizlo. 7 8 AirTmpWidth currently uses a HashMap to map tmps to their width. 9 Since tmps have consecutive indices, we can instead use vectors (one for GP and one for FP tmps). 10 As a bonus, we can just compute the width of the tmps of the bank the register allocator is currently looking at. 11 This cuts the time spent in the register allocator in JetStream2 by about 100ms out of 3.4s 12 (or sometimes 80ms out of 2.4, the bimodality of the time spent is due to a huge function in tagcloud-SP which usually but not always reach the FTL, I'll check later if it can be fixed by tweaking the inliner). 13 14 * b3/air/AirAllocateRegistersByGraphColoring.cpp: 15 (JSC::B3::Air::allocateRegistersByGraphColoring): 16 * b3/air/AirTmpWidth.cpp: 17 (JSC::B3::Air::TmpWidth::TmpWidth): 18 (JSC::B3::Air::TmpWidth::recompute): 19 * b3/air/AirTmpWidth.h: 20 (JSC::B3::Air::TmpWidth::width const): 21 (JSC::B3::Air::TmpWidth::requiredWidth): 22 (JSC::B3::Air::TmpWidth::defWidth const): 23 (JSC::B3::Air::TmpWidth::useWidth const): 24 (JSC::B3::Air::TmpWidth::Widths::Widths): 25 (JSC::B3::Air::TmpWidth::widths): 26 (JSC::B3::Air::TmpWidth::widths const): 27 (JSC::B3::Air::TmpWidth::addWidths): 28 (JSC::B3::Air::TmpWidth::widthsVector): 29 1 30 2020-06-16 Fujii Hironori <Hironori.Fujii@sony.com> 2 31 -
trunk/Source/JavaScriptCore/b3/air/AirAllocateRegistersByGraphColoring.cpp
r262040 r263116 1840 1840 // recomputation, in which case speeding up the lookup would be a bigger win. 1841 1841 // https://bugs.webkit.org/show_bug.cgi?id=152478 1842 m_tmpWidth.recompute (m_code);1842 m_tmpWidth.recompute<bank>(m_code); 1843 1843 1844 1844 auto doAllocation = [&] (auto& allocator) -> bool { … … 2205 2205 PhaseScope phaseScope(code, "allocateRegistersByGraphColoring"); 2206 2206 2207 if ( false)2207 if (traceDebug) 2208 2208 dataLog("Code before graph coloring:\n", code); 2209 2209 -
trunk/Source/JavaScriptCore/b3/air/AirTmpWidth.cpp
r262040 r263116 41 41 TmpWidth::TmpWidth(Code& code) 42 42 { 43 recompute(code); 43 recompute<GP>(code); 44 recompute<FP>(code); 44 45 } 45 46 … … 48 49 } 49 50 51 template <Bank bank> 50 52 void TmpWidth::recompute(Code& code) 51 53 { 52 54 // Set this to true to cause this analysis to always return pessimistic results. 53 const bool beCareful = false; 54 55 constexpr bool beCareful = false; 55 56 constexpr bool verbose = false; 56 57 57 58 if (verbose) { 58 dataLog ("Code before TmpWidth:\n");59 dataLogLn("Code before TmpWidth:"); 59 60 dataLog(code); 60 61 } 61 62 m_width.clear(); 62 63 auto& bankWidthsVector = widthsVector(bank); 64 bankWidthsVector.resize(AbsoluteTmpMapper<bank>::absoluteIndex(code.numTmps(bank))); 65 for (unsigned i = 0; i < bankWidthsVector.size(); ++i) 66 bankWidthsVector[i] = Widths(bank); 63 67 64 68 auto assumeTheWorst = [&] (Tmp tmp) { 65 Widths& widths = m_width.add(tmp, Widths()).iterator->value;66 Bank bank = Arg(tmp).bank();67 widths.use = conservativeWidth(bank);68 widths.def = conservativeWidth(bank);69 if (bank == Arg(tmp).bank()) { 70 Width conservative = conservativeWidth(bank); 71 addWidths(tmp, { conservative, conservative }); 72 } 69 73 }; 70 74 … … 90 94 for (Inst& inst : *block) { 91 95 if (inst.kind.opcode == Move && inst.args[1].isTmp()) { 96 if (Arg(inst.args[1]).bank() != bank) 97 continue; 98 92 99 if (inst.args[0].isTmp()) { 93 // Make sure that both sides of the Move have a width already initialized. The94 // fixpoint below assumes that it never has to add things to the HashMap.95 m_width.add(inst.args[0].tmp(), Widths(GP));96 m_width.add(inst.args[1].tmp(), Widths(GP));97 98 100 moves.append(&inst); 99 101 continue; 100 102 } 101 if (inst.args[0].isImm() 102 && inst.args[0].value() >= 0) { 103 if (inst.args[0].isImm() && inst.args[0].value() >= 0) { 103 104 Tmp tmp = inst.args[1].tmp(); 104 Widths& widths = m_width.add(tmp, Widths(GP)).iterator->value;105 105 Widths& tmpWidths = widths(tmp); 106 Width maxWidth = Width64; 106 107 if (inst.args[0].value() <= std::numeric_limits<int8_t>::max()) 107 widths.def = std::max(widths.def, Width8);108 maxWidth = Width8; 108 109 else if (inst.args[0].value() <= std::numeric_limits<int16_t>::max()) 109 widths.def = std::max(widths.def, Width16);110 maxWidth = Width16; 110 111 else if (inst.args[0].value() <= std::numeric_limits<int32_t>::max()) 111 widths.def = std::max(widths.def, Width32);112 else 113 widths.def = std::max(widths.def, Width64);112 maxWidth = Width32; 113 114 tmpWidths.def = std::max(tmpWidths.def, maxWidth); 114 115 115 116 continue; … … 117 118 } 118 119 inst.forEachTmp( 119 [&] (Tmp& tmp, Arg::Role role, Bank bank, Width width) { 120 Widths& widths = m_width.add(tmp, Widths(bank)).iterator->value; 121 120 [&] (Tmp& tmp, Arg::Role role, Bank tmpBank, Width width) { 121 if (Arg(tmp).bank() != bank) 122 return; 123 124 Widths& tmpWidths = widths(tmp); 122 125 if (Arg::isAnyUse(role)) 123 widths.use = std::max(widths.use, width);126 tmpWidths.use = std::max(tmpWidths.use, width); 124 127 125 128 if (Arg::isZDef(role)) 126 widths.def = std::max(widths.def, width);129 tmpWidths.def = std::max(tmpWidths.def, width); 127 130 else if (Arg::isAnyDef(role)) 128 widths.def = conservativeWidth(bank);131 tmpWidths.def = conservativeWidth(tmpBank); 129 132 }); 130 133 } … … 140 143 ASSERT(move->args[1].isTmp()); 141 144 142 // We already ensure that both tmps are added to the width map. That's important 143 // because you cannot add both tmps here while simultaneously getting a reference to 144 // their values, since the second add would invalidate the reference returned by the 145 // first one. 146 Widths& srcWidths = m_width.find(move->args[0].tmp())->value; 147 Widths& dstWidths = m_width.find(move->args[1].tmp())->value; 145 Widths& srcWidths = widths(move->args[0].tmp()); 146 Widths& dstWidths = widths(move->args[1].tmp()); 148 147 149 148 // Legend: … … 169 168 } 170 169 171 if (verbose) 172 dataLog("width: ", mapDump(m_width), "\n"); 170 if (verbose) { 171 dataLogLn("bank: ", bank, ", widthsVector: "); 172 for (unsigned i = 0; i < bankWidthsVector.size(); ++i) 173 dataLogLn("\t", i, " : ", bankWidthsVector[i]); 174 } 173 175 } 174 176 -
trunk/Source/JavaScriptCore/b3/air/AirTmpWidth.h
r212970 r263116 40 40 ~TmpWidth(); 41 41 42 template <Bank bank> 42 43 void recompute(Code&); 43 44 … … 53 54 Width width(Tmp tmp) const 54 55 { 55 auto iter = m_width.find(tmp); 56 if (iter == m_width.end()) 57 return minimumWidth(Arg(tmp).bank()); 58 return std::min(iter->value.use, iter->value.def); 56 Widths tmpWidths = widths(tmp); 57 return std::min(tmpWidths.use, tmpWidths.def); 59 58 } 60 59 … … 62 61 Width requiredWidth(Tmp tmp) 63 62 { 64 auto iter = m_width.find(tmp); 65 if (iter == m_width.end()) 66 return minimumWidth(Arg(tmp).bank()); 67 return std::max(iter->value.use, iter->value.def); 63 Widths tmpWidths = widths(tmp); 64 return std::max(tmpWidths.use, tmpWidths.def); 68 65 } 69 66 … … 76 73 Width defWidth(Tmp tmp) const 77 74 { 78 auto iter = m_width.find(tmp); 79 if (iter == m_width.end()) 80 return minimumWidth(Arg(tmp).bank()); 81 return iter->value.def; 75 return widths(tmp).def; 82 76 } 83 77 … … 85 79 Width useWidth(Tmp tmp) const 86 80 { 87 auto iter = m_width.find(tmp); 88 if (iter == m_width.end()) 89 return minimumWidth(Arg(tmp).bank()); 90 return iter->value.use; 81 return widths(tmp).use; 91 82 } 92 83 … … 96 87 97 88 Widths(Bank bank) 89 : use(minimumWidth(bank)) 90 , def(minimumWidth(bank)) 98 91 { 99 use = minimumWidth(bank); 100 def = minimumWidth(bank); 92 } 93 94 Widths(Width useArg, Width defArg) 95 : use(useArg) 96 , def(defArg) 97 { 101 98 } 102 99 … … 106 103 Width def; 107 104 }; 108 109 HashMap<Tmp, Widths> m_width; 105 106 Widths& widths(Tmp tmp) 107 { 108 if (tmp.isGP()) { 109 unsigned index = AbsoluteTmpMapper<GP>::absoluteIndex(tmp); 110 ASSERT(index < m_widthGP.size()); 111 return m_widthGP[index]; 112 } 113 unsigned index = AbsoluteTmpMapper<FP>::absoluteIndex(tmp); 114 ASSERT(index < m_widthFP.size()); 115 return m_widthFP[index]; 116 } 117 const Widths& widths(Tmp tmp) const 118 { 119 return const_cast<TmpWidth*>(this)->widths(tmp); 120 } 121 122 void addWidths(Tmp tmp, Widths tmpWidths) 123 { 124 widths(tmp) = tmpWidths; 125 } 126 127 Vector<Widths>& widthsVector(Bank bank) 128 { 129 return bank == GP ? m_widthGP : m_widthFP; 130 } 131 132 // These are initialized at the beginning of recompute<bank>, which is called in the constructor for both values of bank. 133 Vector<Widths> m_widthGP; 134 Vector<Widths> m_widthFP; 110 135 }; 111 136
Note: See TracChangeset
for help on using the changeset viewer.