Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Side by Side Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1904233002: Subzero: Fix over-aggressive bool folding. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 const Inst *getProducerFor(const Operand *Opnd) const; 144 const Inst *getProducerFor(const Operand *Opnd) const;
145 void dump(const Cfg *Func) const; 145 void dump(const Cfg *Func) const;
146 146
147 private: 147 private:
148 /// Returns true if Producers contains a valid entry for the given VarNum. 148 /// Returns true if Producers contains a valid entry for the given VarNum.
149 bool containsValid(SizeT VarNum) const { 149 bool containsValid(SizeT VarNum) const {
150 auto Element = Producers.find(VarNum); 150 auto Element = Producers.find(VarNum);
151 return Element != Producers.end() && Element->second.Instr != nullptr; 151 return Element != Producers.end() && Element->second.Instr != nullptr;
152 } 152 }
153 void setInvalid(SizeT VarNum) { Producers[VarNum].Instr = nullptr; } 153 void setInvalid(SizeT VarNum) { Producers[VarNum].Instr = nullptr; }
154 void invalidateProducersOnStore(const Inst *Instr);
154 /// Producers maps Variable::Number to a BoolFoldingEntry. 155 /// Producers maps Variable::Number to a BoolFoldingEntry.
155 CfgUnorderedMap<SizeT, BoolFoldingEntry<Traits>> Producers; 156 CfgUnorderedMap<SizeT, BoolFoldingEntry<Traits>> Producers;
156 }; 157 };
157 158
158 template <typename Traits> 159 template <typename Traits>
159 BoolFoldingEntry<Traits>::BoolFoldingEntry(Inst *I) 160 BoolFoldingEntry<Traits>::BoolFoldingEntry(Inst *I)
160 : Instr(I), IsComplex(BoolFolding<Traits>::hasComplexLowering(I)) {} 161 : Instr(I), IsComplex(BoolFolding<Traits>::hasComplexLowering(I)) {}
161 162
162 template <typename Traits> 163 template <typename Traits>
163 typename BoolFolding<Traits>::BoolFoldingProducerKind 164 typename BoolFolding<Traits>::BoolFoldingProducerKind
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 case PK_Fcmp: 246 case PK_Fcmp:
246 return (ConsumerKind == CK_Br) || (ConsumerKind == CK_Select); 247 return (ConsumerKind == CK_Br) || (ConsumerKind == CK_Select);
247 case PK_Arith: 248 case PK_Arith:
248 return ConsumerKind == CK_Br; 249 return ConsumerKind == CK_Br;
249 } 250 }
250 } 251 }
251 252
252 template <typename Traits> void BoolFolding<Traits>::init(CfgNode *Node) { 253 template <typename Traits> void BoolFolding<Traits>::init(CfgNode *Node) {
253 Producers.clear(); 254 Producers.clear();
254 for (Inst &Instr : Node->getInsts()) { 255 for (Inst &Instr : Node->getInsts()) {
256 if (Instr.isDeleted())
Eric Holk 2016/04/21 22:09:43 As a future CL, it would probably be nice to add a
Jim Stichnoth 2016/04/21 22:50:29 That's a great idea.
257 continue;
258 invalidateProducersOnStore(&Instr);
255 // Check whether Instr is a valid producer. 259 // Check whether Instr is a valid producer.
256 Variable *Var = Instr.getDest(); 260 Variable *Var = Instr.getDest();
257 if (!Instr.isDeleted() // only consider non-deleted instructions 261 if (Var // only consider instructions with an actual dest var
258 && Var // only instructions with an actual dest var
259 && Var->getType() == IceType_i1 // only bool-type dest vars 262 && Var->getType() == IceType_i1 // only bool-type dest vars
260 && getProducerKind(&Instr) != PK_None) { // white-listed instructions 263 && getProducerKind(&Instr) != PK_None) { // white-listed instructions
261 Producers[Var->getIndex()] = BoolFoldingEntry<Traits>(&Instr); 264 Producers[Var->getIndex()] = BoolFoldingEntry<Traits>(&Instr);
262 } 265 }
263 // Check each src variable against the map. 266 // Check each src variable against the map.
264 FOREACH_VAR_IN_INST(Var, Instr) { 267 FOREACH_VAR_IN_INST(Var, Instr) {
265 SizeT VarNum = Var->getIndex(); 268 SizeT VarNum = Var->getIndex();
266 if (!containsValid(VarNum)) 269 if (!containsValid(VarNum))
267 continue; 270 continue;
268 // All valid consumers use Var as the first source operand 271 // All valid consumers use Var as the first source operand
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 Ostream &Str = Func->getContext()->getStrDump(); 334 Ostream &Str = Func->getContext()->getStrDump();
332 for (auto &I : Producers) { 335 for (auto &I : Producers) {
333 if (I.second.Instr == nullptr) 336 if (I.second.Instr == nullptr)
334 continue; 337 continue;
335 Str << "Found foldable producer:\n "; 338 Str << "Found foldable producer:\n ";
336 I.second.Instr->dump(Func); 339 I.second.Instr->dump(Func);
337 Str << "\n"; 340 Str << "\n";
338 } 341 }
339 } 342 }
340 343
344 /// If the given instruction has potential memory side effects (e.g. store, rmw,
345 /// or a call instruction with potential memory side effects), then we must not
346 /// allow a pre-store Producer instruction with memory operands to be folded
347 /// into a post-store Consumer instruction. If this is detected, the Producer
348 /// is invalidated.
349 ///
350 /// We use the Producer's IsLiveOut field to determine whether any potential
351 /// Consumers come after this store instruction. If IsLiveOut has already been
352 /// set to false, then we know the folding is safe from the store instruction.
John 2016/04/21 22:50:02 "If IsLiveOut has already been set to false, then
Jim Stichnoth 2016/04/21 23:31:35 Done, hopefully it's more explanatory now.
353 template <typename Traits>
354 void BoolFolding<Traits>::invalidateProducersOnStore(const Inst *Instr) {
355 if (!Instr->isMemoryWrite())
356 return;
357 for (auto &ProducerPair : Producers) {
358 if (!ProducerPair.second.IsLiveOut)
359 continue;
360 Inst *PInst = ProducerPair.second.Instr;
361 if (PInst == nullptr)
362 continue;
363 bool HasMemOperand = false;
364 const SizeT SrcSize = PInst->getSrcSize();
365 for (SizeT I = 0; !HasMemOperand && I < SrcSize; ++I) {
John 2016/04/21 22:50:02 why not breaking instead? I would expect llvm to e
Jim Stichnoth 2016/04/21 23:31:35 Done.
366 if (llvm::isa<typename Traits::X86OperandMem>(PInst->getSrc(I))) {
367 HasMemOperand = true;
368 }
369 }
370 if (!HasMemOperand)
371 continue;
372 setInvalid(ProducerPair.first);
373 }
374 }
375
341 template <typename TraitsType> 376 template <typename TraitsType>
342 void TargetX86Base<TraitsType>::initNodeForLowering(CfgNode *Node) { 377 void TargetX86Base<TraitsType>::initNodeForLowering(CfgNode *Node) {
343 FoldingInfo.init(Node); 378 FoldingInfo.init(Node);
344 FoldingInfo.dump(Func); 379 FoldingInfo.dump(Func);
345 } 380 }
346 381
347 template <typename TraitsType> 382 template <typename TraitsType>
348 TargetX86Base<TraitsType>::TargetX86Base(Cfg *Func) 383 TargetX86Base<TraitsType>::TargetX86Base(Cfg *Func)
349 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl) { 384 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl) {
350 static_assert( 385 static_assert(
(...skipping 7088 matching lines...) Expand 10 before | Expand all | Expand 10 after
7439 emitGlobal(*Var, SectionSuffix); 7474 emitGlobal(*Var, SectionSuffix);
7440 } 7475 }
7441 } 7476 }
7442 } break; 7477 } break;
7443 } 7478 }
7444 } 7479 }
7445 } // end of namespace X86NAMESPACE 7480 } // end of namespace X86NAMESPACE
7446 } // end of namespace Ice 7481 } // end of namespace Ice
7447 7482
7448 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H 7483 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698