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()) |
| 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. The IsLiveOut field is |
| 352 /// initialized to true, and BoolFolding::init() sets IsLiveOut to false when it |
| 353 /// sees the variable's definitive last use (indicating the variable is not in |
| 354 /// the node's live-out set). Thus if we see here that IsLiveOut is false, we |
| 355 /// know that there can be no consumers after the store, and therefore we know |
| 356 /// the folding is safe despite the store instruction. |
| 357 template <typename Traits> |
| 358 void BoolFolding<Traits>::invalidateProducersOnStore(const Inst *Instr) { |
| 359 if (!Instr->isMemoryWrite()) |
| 360 return; |
| 361 for (auto &ProducerPair : Producers) { |
| 362 if (!ProducerPair.second.IsLiveOut) |
| 363 continue; |
| 364 Inst *PInst = ProducerPair.second.Instr; |
| 365 if (PInst == nullptr) |
| 366 continue; |
| 367 bool HasMemOperand = false; |
| 368 const SizeT SrcSize = PInst->getSrcSize(); |
| 369 for (SizeT I = 0; I < SrcSize; ++I) { |
| 370 if (llvm::isa<typename Traits::X86OperandMem>(PInst->getSrc(I))) { |
| 371 HasMemOperand = true; |
| 372 break; |
| 373 } |
| 374 } |
| 375 if (!HasMemOperand) |
| 376 continue; |
| 377 setInvalid(ProducerPair.first); |
| 378 } |
| 379 } |
| 380 |
341 template <typename TraitsType> | 381 template <typename TraitsType> |
342 void TargetX86Base<TraitsType>::initNodeForLowering(CfgNode *Node) { | 382 void TargetX86Base<TraitsType>::initNodeForLowering(CfgNode *Node) { |
343 FoldingInfo.init(Node); | 383 FoldingInfo.init(Node); |
344 FoldingInfo.dump(Func); | 384 FoldingInfo.dump(Func); |
345 } | 385 } |
346 | 386 |
347 template <typename TraitsType> | 387 template <typename TraitsType> |
348 TargetX86Base<TraitsType>::TargetX86Base(Cfg *Func) | 388 TargetX86Base<TraitsType>::TargetX86Base(Cfg *Func) |
349 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl) { | 389 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl) { |
350 static_assert( | 390 static_assert( |
(...skipping 7088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7439 emitGlobal(*Var, SectionSuffix); | 7479 emitGlobal(*Var, SectionSuffix); |
7440 } | 7480 } |
7441 } | 7481 } |
7442 } break; | 7482 } break; |
7443 } | 7483 } |
7444 } | 7484 } |
7445 } // end of namespace X86NAMESPACE | 7485 } // end of namespace X86NAMESPACE |
7446 } // end of namespace Ice | 7486 } // end of namespace Ice |
7447 | 7487 |
7448 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 7488 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |