| 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 |