OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |