| 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 5052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5063 | 5063 |
| 5064 inline const Inst *matchAssign(Variable **Var, | 5064 inline const Inst *matchAssign(Variable **Var, |
| 5065 ConstantRelocatable **Relocatable, | 5065 ConstantRelocatable **Relocatable, |
| 5066 int32_t *Offset); | 5066 int32_t *Offset); |
| 5067 | 5067 |
| 5068 inline const Inst *matchCombinedBaseIndex(Variable **Base, Variable **Index, | 5068 inline const Inst *matchCombinedBaseIndex(Variable **Base, Variable **Index, |
| 5069 uint16_t *Shift); | 5069 uint16_t *Shift); |
| 5070 | 5070 |
| 5071 inline const Inst *matchShiftedIndex(Variable **Index, uint16_t *Shift); | 5071 inline const Inst *matchShiftedIndex(Variable **Index, uint16_t *Shift); |
| 5072 | 5072 |
| 5073 inline const Inst *matchOffsetBase(Variable **Base, | 5073 inline const Inst *matchOffsetIndexOrBase(Variable **IndexOrBase, |
| 5074 ConstantRelocatable **Relocatable, | 5074 const uint16_t Shift, |
| 5075 int32_t *Offset); | 5075 ConstantRelocatable **Relocatable, |
| 5076 int32_t *Offset); |
| 5076 | 5077 |
| 5077 private: | 5078 private: |
| 5078 const Cfg *const Func; | 5079 const Cfg *const Func; |
| 5079 const VariablesMetadata *const VMetadata; | 5080 const VariablesMetadata *const VMetadata; |
| 5080 | 5081 |
| 5081 static bool isAdd(const Inst *Instr) { | 5082 static bool isAdd(const Inst *Instr) { |
| 5082 if (auto *Arith = llvm::dyn_cast_or_null<const InstArithmetic>(Instr)) { | 5083 if (auto *Arith = llvm::dyn_cast_or_null<const InstArithmetic>(Instr)) { |
| 5083 return (Arith->getOp() == InstArithmetic::Add); | 5084 return (Arith->getOp() == InstArithmetic::Add); |
| 5084 } | 5085 } |
| 5085 return false; | 5086 return false; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5249 return IndexInst; | 5250 return IndexInst; |
| 5250 } | 5251 } |
| 5251 } | 5252 } |
| 5252 } | 5253 } |
| 5253 } | 5254 } |
| 5254 } | 5255 } |
| 5255 } | 5256 } |
| 5256 return nullptr; | 5257 return nullptr; |
| 5257 } | 5258 } |
| 5258 | 5259 |
| 5259 const Inst *AddressOptimizer::matchOffsetBase(Variable **Base, | 5260 const Inst *AddressOptimizer::matchOffsetIndexOrBase( |
| 5260 ConstantRelocatable **Relocatable, | 5261 Variable **IndexOrBase, const uint16_t Shift, |
| 5261 int32_t *Offset) { | 5262 ConstantRelocatable **Relocatable, int32_t *Offset) { |
| 5262 // Base is Base=Var+Const || Base is Base=Const+Var ==> | 5263 // Base is Base=Var+Const || Base is Base=Const+Var ==> |
| 5263 // set Base=Var, Offset+=Const | 5264 // set Base=Var, Offset+=Const |
| 5264 // Base is Base=Var-Const ==> | 5265 // Base is Base=Var-Const ==> |
| 5265 // set Base=Var, Offset-=Const | 5266 // set Base=Var, Offset-=Const |
| 5266 if (*Base == nullptr) { | 5267 // Index is Index=Var+Const ==> |
| 5268 // set Index=Var, Offset+=(Const<<Shift) |
| 5269 // Index is Index=Const+Var ==> |
| 5270 // set Index=Var, Offset+=(Const<<Shift) |
| 5271 // Index is Index=Var-Const ==> |
| 5272 // set Index=Var, Offset-=(Const<<Shift) |
| 5273 |
| 5274 if (*IndexOrBase == nullptr) { |
| 5267 return nullptr; | 5275 return nullptr; |
| 5268 } | 5276 } |
| 5269 const Inst *BaseInst = VMetadata->getSingleDefinition(*Base); | 5277 const Inst *Definition = VMetadata->getSingleDefinition(*IndexOrBase); |
| 5270 if (BaseInst == nullptr) { | 5278 if (Definition == nullptr) { |
| 5271 return nullptr; | 5279 return nullptr; |
| 5272 } | 5280 } |
| 5273 assert(!VMetadata->isMultiDef(*Base)); | 5281 assert(!VMetadata->isMultiDef(*IndexOrBase)); |
| 5274 if (auto *ArithInst = llvm::dyn_cast<const InstArithmetic>(BaseInst)) { | 5282 if (auto *ArithInst = llvm::dyn_cast<const InstArithmetic>(Definition)) { |
| 5275 if (ArithInst->getOp() != InstArithmetic::Add && | 5283 if (ArithInst->getOp() != InstArithmetic::Add && |
| 5276 ArithInst->getOp() != InstArithmetic::Sub) | 5284 ArithInst->getOp() != InstArithmetic::Sub) |
| 5277 return nullptr; | 5285 return nullptr; |
| 5278 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add; | 5286 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add; |
| 5279 Operand *Src0 = ArithInst->getSrc(0); | 5287 Operand *Src0 = ArithInst->getSrc(0); |
| 5280 Operand *Src1 = ArithInst->getSrc(1); | 5288 Operand *Src1 = ArithInst->getSrc(1); |
| 5281 auto *Var0 = llvm::dyn_cast<Variable>(Src0); | 5289 auto *Var0 = llvm::dyn_cast<Variable>(Src0); |
| 5282 auto *Var1 = llvm::dyn_cast<Variable>(Src1); | 5290 auto *Var1 = llvm::dyn_cast<Variable>(Src1); |
| 5283 auto *Const0 = llvm::dyn_cast<ConstantInteger32>(Src0); | 5291 auto *Const0 = llvm::dyn_cast<ConstantInteger32>(Src0); |
| 5284 auto *Const1 = llvm::dyn_cast<ConstantInteger32>(Src1); | 5292 auto *Const1 = llvm::dyn_cast<ConstantInteger32>(Src1); |
| 5285 auto *Reloc0 = llvm::dyn_cast<ConstantRelocatable>(Src0); | 5293 auto *Reloc0 = llvm::dyn_cast<ConstantRelocatable>(Src0); |
| 5286 auto *Reloc1 = llvm::dyn_cast<ConstantRelocatable>(Src1); | 5294 auto *Reloc1 = llvm::dyn_cast<ConstantRelocatable>(Src1); |
| 5287 Variable *NewBase = nullptr; | 5295 Variable *NewIndexOrBase = nullptr; |
| 5288 int32_t NewOffset = *Offset; | 5296 int32_t NewOffset = 0; |
| 5289 ConstantRelocatable *NewRelocatable = *Relocatable; | 5297 ConstantRelocatable *NewRelocatable = *Relocatable; |
| 5290 if (Var0 && Var1) | 5298 if (Var0 && Var1) |
| 5291 // TODO(sehr): merge base/index splitting into here. | 5299 // TODO(sehr): merge base/index splitting into here. |
| 5292 return nullptr; | 5300 return nullptr; |
| 5293 if (!IsAdd && Var1) | 5301 if (!IsAdd && Var1) |
| 5294 return nullptr; | 5302 return nullptr; |
| 5295 if (Var0) | 5303 if (Var0) |
| 5296 NewBase = Var0; | 5304 NewIndexOrBase = Var0; |
| 5297 else if (Var1) | 5305 else if (Var1) |
| 5298 NewBase = Var1; | 5306 NewIndexOrBase = Var1; |
| 5299 // Don't know how to add/subtract two relocatables. | 5307 // Don't know how to add/subtract two relocatables. |
| 5300 if ((*Relocatable && (Reloc0 || Reloc1)) || (Reloc0 && Reloc1)) | 5308 if ((*Relocatable && (Reloc0 || Reloc1)) || (Reloc0 && Reloc1)) |
| 5301 return nullptr; | 5309 return nullptr; |
| 5302 // Don't know how to subtract a relocatable. | 5310 // Don't know how to subtract a relocatable. |
| 5303 if (!IsAdd && Reloc1) | 5311 if (!IsAdd && Reloc1) |
| 5304 return nullptr; | 5312 return nullptr; |
| 5305 // Incorporate ConstantRelocatables. | 5313 // Incorporate ConstantRelocatables. |
| 5306 if (Reloc0) | 5314 if (Reloc0) |
| 5307 NewRelocatable = Reloc0; | 5315 NewRelocatable = Reloc0; |
| 5308 else if (Reloc1) | 5316 else if (Reloc1) |
| 5309 NewRelocatable = Reloc1; | 5317 NewRelocatable = Reloc1; |
| 5310 // Compute the updated constant offset. | 5318 // Compute the updated constant offset. |
| 5311 if (Const0) { | 5319 if (Const0) { |
| 5312 const int32_t MoreOffset = | 5320 const int32_t MoreOffset = |
| 5313 IsAdd ? Const0->getValue() : -Const0->getValue(); | 5321 IsAdd ? Const0->getValue() : -Const0->getValue(); |
| 5314 if (Utils::WouldOverflowAdd(NewOffset, MoreOffset)) | 5322 if (Utils::WouldOverflowAdd(*Offset + NewOffset, MoreOffset)) |
| 5315 return nullptr; | 5323 return nullptr; |
| 5316 NewOffset += MoreOffset; | 5324 NewOffset += MoreOffset; |
| 5317 } | 5325 } |
| 5318 if (Const1) { | 5326 if (Const1) { |
| 5319 const int32_t MoreOffset = | 5327 const int32_t MoreOffset = |
| 5320 IsAdd ? Const1->getValue() : -Const1->getValue(); | 5328 IsAdd ? Const1->getValue() : -Const1->getValue(); |
| 5321 if (Utils::WouldOverflowAdd(NewOffset, MoreOffset)) | 5329 if (Utils::WouldOverflowAdd(*Offset + NewOffset, MoreOffset)) |
| 5322 return nullptr; | 5330 return nullptr; |
| 5323 NewOffset += MoreOffset; | 5331 NewOffset += MoreOffset; |
| 5324 } | 5332 } |
| 5325 *Base = NewBase; | 5333 if (Utils::WouldOverflowAdd(*Offset, NewOffset << Shift)) |
| 5326 *Offset = NewOffset; | 5334 return nullptr; |
| 5335 *IndexOrBase = NewIndexOrBase; |
| 5336 *Offset += (NewOffset << Shift); |
| 5337 // Shift is always zero if this is called with the base |
| 5327 *Relocatable = NewRelocatable; | 5338 *Relocatable = NewRelocatable; |
| 5328 return BaseInst; | 5339 return Definition; |
| 5329 } | 5340 } |
| 5330 return nullptr; | 5341 return nullptr; |
| 5331 } | 5342 } |
| 5332 | 5343 |
| 5333 template <typename TypeTraits> | 5344 template <typename TypeTraits> |
| 5334 typename TargetX86Base<TypeTraits>::X86OperandMem * | 5345 typename TargetX86Base<TypeTraits>::X86OperandMem * |
| 5335 TargetX86Base<TypeTraits>::computeAddressOpt(const Inst *Instr, Type MemType, | 5346 TargetX86Base<TypeTraits>::computeAddressOpt(const Inst *Instr, Type MemType, |
| 5336 Operand *Addr) { | 5347 Operand *Addr) { |
| 5337 Func->resetCurrentNode(); | 5348 Func->resetCurrentNode(); |
| 5338 if (Func->isVerbose(IceV_AddrOpt)) { | 5349 if (Func->isVerbose(IceV_AddrOpt)) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5453 if (NewAddr.Shift == 0 && | 5464 if (NewAddr.Shift == 0 && |
| 5454 (Reason = AddrOpt.matchShiftedIndex(&NewAddr.Base, &NewAddr.Shift))) { | 5465 (Reason = AddrOpt.matchShiftedIndex(&NewAddr.Base, &NewAddr.Shift))) { |
| 5455 std::swap(NewAddr.Base, NewAddr.Index); | 5466 std::swap(NewAddr.Base, NewAddr.Index); |
| 5456 continue; | 5467 continue; |
| 5457 } | 5468 } |
| 5458 } | 5469 } |
| 5459 | 5470 |
| 5460 // Update Offset to reflect additions/subtractions with constants and | 5471 // Update Offset to reflect additions/subtractions with constants and |
| 5461 // relocatables. | 5472 // relocatables. |
| 5462 // TODO: consider overflow issues with respect to Offset. | 5473 // TODO: consider overflow issues with respect to Offset. |
| 5463 if (!Skip.OffsetFromBase && | 5474 if (!Skip.OffsetFromBase && (Reason = AddrOpt.matchOffsetIndexOrBase( |
| 5464 (Reason = AddrOpt.matchOffsetBase(&NewAddr.Base, &NewAddr.Relocatable, | 5475 &NewAddr.Base, /*Shift =*/0, |
| 5465 &NewAddr.Offset))) { | 5476 &NewAddr.Relocatable, &NewAddr.Offset))) { |
| 5466 SkipLastFolding = &Skip.OffsetFromBase; | 5477 SkipLastFolding = &Skip.OffsetFromBase; |
| 5467 continue; | 5478 continue; |
| 5468 } | 5479 } |
| 5469 if (NewAddr.Shift == 0 && !Skip.OffsetFromIndex && | 5480 if (!Skip.OffsetFromIndex && (Reason = AddrOpt.matchOffsetIndexOrBase( |
| 5470 (Reason = AddrOpt.matchOffsetBase(&NewAddr.Index, &NewAddr.Relocatable, | 5481 &NewAddr.Index, NewAddr.Shift, |
| 5471 &NewAddr.Offset))) { | 5482 &NewAddr.Relocatable, &NewAddr.Offset))) { |
| 5472 SkipLastFolding = &Skip.OffsetFromIndex; | 5483 SkipLastFolding = &Skip.OffsetFromIndex; |
| 5473 continue; | 5484 continue; |
| 5474 } | 5485 } |
| 5475 | 5486 |
| 5476 // TODO(sehr, stichnot): Handle updates of Index with Shift != 0. | |
| 5477 // Index is Index=Var+Const ==> | |
| 5478 // set Index=Var, Offset+=(Const<<Shift) | |
| 5479 // Index is Index=Const+Var ==> | |
| 5480 // set Index=Var, Offset+=(Const<<Shift) | |
| 5481 // Index is Index=Var-Const ==> | |
| 5482 // set Index=Var, Offset-=(Const<<Shift) | |
| 5483 break; | 5487 break; |
| 5484 } while (Reason); | 5488 } while (Reason); |
| 5485 | 5489 |
| 5486 if (!AddressWasOptimized) { | 5490 if (!AddressWasOptimized) { |
| 5487 return nullptr; | 5491 return nullptr; |
| 5488 } | 5492 } |
| 5489 | 5493 |
| 5490 // Undo any addition of RebasePtr. It will be added back when the mem | 5494 // Undo any addition of RebasePtr. It will be added back when the mem |
| 5491 // operand is sandboxed. | 5495 // operand is sandboxed. |
| 5492 if (NewAddr.Base == RebasePtr) { | 5496 if (NewAddr.Base == RebasePtr) { |
| (...skipping 2477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7970 emitGlobal(*Var, SectionSuffix); | 7974 emitGlobal(*Var, SectionSuffix); |
| 7971 } | 7975 } |
| 7972 } | 7976 } |
| 7973 } break; | 7977 } break; |
| 7974 } | 7978 } |
| 7975 } | 7979 } |
| 7976 } // end of namespace X86NAMESPACE | 7980 } // end of namespace X86NAMESPACE |
| 7977 } // end of namespace Ice | 7981 } // end of namespace Ice |
| 7978 | 7982 |
| 7979 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 7983 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |