| 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 11 matching lines...) Expand all Loading... |
| 22 #include "IceDefs.h" | 22 #include "IceDefs.h" |
| 23 #include "IceELFObjectWriter.h" | 23 #include "IceELFObjectWriter.h" |
| 24 #include "IceGlobalInits.h" | 24 #include "IceGlobalInits.h" |
| 25 #include "IceInstVarIter.h" | 25 #include "IceInstVarIter.h" |
| 26 #include "IceLiveness.h" | 26 #include "IceLiveness.h" |
| 27 #include "IceOperand.h" | 27 #include "IceOperand.h" |
| 28 #include "IcePhiLoweringImpl.h" | 28 #include "IcePhiLoweringImpl.h" |
| 29 #include "IceUtils.h" | 29 #include "IceUtils.h" |
| 30 #include "llvm/Support/MathExtras.h" | 30 #include "llvm/Support/MathExtras.h" |
| 31 | 31 |
| 32 #include <cmath> // signbit() |
| 32 #include <stack> | 33 #include <stack> |
| 33 | 34 |
| 34 namespace Ice { | 35 namespace Ice { |
| 35 namespace X86Internal { | 36 namespace X86Internal { |
| 36 | 37 |
| 37 /// A helper class to ease the settings of RandomizationPoolingPause to disable | 38 /// A helper class to ease the settings of RandomizationPoolingPause to disable |
| 38 /// constant blinding or pooling for some translation phases. | 39 /// constant blinding or pooling for some translation phases. |
| 39 class BoolFlagSaver { | 40 class BoolFlagSaver { |
| 40 BoolFlagSaver() = delete; | 41 BoolFlagSaver() = delete; |
| 41 BoolFlagSaver(const BoolFlagSaver &) = delete; | 42 BoolFlagSaver(const BoolFlagSaver &) = delete; |
| (...skipping 1867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 _mov(T_Lo, Src0Lo); | 1910 _mov(T_Lo, Src0Lo); |
| 1910 _mov(DestLo, T_Lo); | 1911 _mov(DestLo, T_Lo); |
| 1911 _mov(T_Hi, Src0Hi); | 1912 _mov(T_Hi, Src0Hi); |
| 1912 _mov(DestHi, T_Hi); | 1913 _mov(DestHi, T_Hi); |
| 1913 } else { | 1914 } else { |
| 1914 Operand *Src0Legal; | 1915 Operand *Src0Legal; |
| 1915 if (Dest->hasReg()) { | 1916 if (Dest->hasReg()) { |
| 1916 // If Dest already has a physical register, then only basic legalization | 1917 // If Dest already has a physical register, then only basic legalization |
| 1917 // is needed, as the source operand can be a register, immediate, or | 1918 // is needed, as the source operand can be a register, immediate, or |
| 1918 // memory. | 1919 // memory. |
| 1919 Src0Legal = legalize(Src0); | 1920 Src0Legal = legalize(Src0, Legal_Reg, Dest->getRegNum()); |
| 1920 } else { | 1921 } else { |
| 1921 // If Dest could be a stack operand, then RI must be a physical register | 1922 // If Dest could be a stack operand, then RI must be a physical register |
| 1922 // or a scalar integer immediate. | 1923 // or a scalar integer immediate. |
| 1923 Src0Legal = legalize(Src0, Legal_Reg | Legal_Imm); | 1924 Src0Legal = legalize(Src0, Legal_Reg | Legal_Imm); |
| 1924 } | 1925 } |
| 1925 if (isVectorType(Dest->getType())) | 1926 if (isVectorType(Dest->getType())) |
| 1926 _movp(Dest, Src0Legal); | 1927 _movp(Dest, Src0Legal); |
| 1927 else | 1928 else |
| 1928 _mov(Dest, Src0Legal); | 1929 _mov(Dest, Src0Legal); |
| 1929 } | 1930 } |
| (...skipping 3370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5300 return; | 5301 return; |
| 5301 } | 5302 } |
| 5302 | 5303 |
| 5303 // Pause constant blinding or pooling, blinding or pooling will be done later | 5304 // Pause constant blinding or pooling, blinding or pooling will be done later |
| 5304 // during phi lowering assignments | 5305 // during phi lowering assignments |
| 5305 BoolFlagSaver B(RandomizationPoolingPaused, true); | 5306 BoolFlagSaver B(RandomizationPoolingPaused, true); |
| 5306 PhiLowering::prelowerPhis32Bit<TargetX86Base<Machine>>( | 5307 PhiLowering::prelowerPhis32Bit<TargetX86Base<Machine>>( |
| 5307 this, Context.getNode(), Func); | 5308 this, Context.getNode(), Func); |
| 5308 } | 5309 } |
| 5309 | 5310 |
| 5311 template <class Machine> |
| 5312 Variable *TargetX86Base<Machine>::makeZeroedRegister(Type Ty, int32_t RegNum) { |
| 5313 Variable *Reg = makeReg(Ty, RegNum); |
| 5314 switch (Ty) { |
| 5315 case IceType_i1: |
| 5316 case IceType_i8: |
| 5317 case IceType_i16: |
| 5318 case IceType_i32: |
| 5319 case IceType_i64: |
| 5320 // Conservatively do "mov reg, 0" to avoid modifying FLAGS. |
| 5321 _mov(Reg, Ctx->getConstantZero(Ty)); |
| 5322 break; |
| 5323 case IceType_f32: |
| 5324 case IceType_f64: |
| 5325 Context.insert(InstFakeDef::create(Func, Reg)); |
| 5326 // TODO(stichnot): Use xorps/xorpd instead of pxor. |
| 5327 _pxor(Reg, Reg); |
| 5328 break; |
| 5329 default: |
| 5330 // All vector types use the same pxor instruction. |
| 5331 assert(isVectorType(Ty)); |
| 5332 Context.insert(InstFakeDef::create(Func, Reg)); |
| 5333 _pxor(Reg, Reg); |
| 5334 break; |
| 5335 } |
| 5336 return Reg; |
| 5337 } |
| 5338 |
| 5310 // There is no support for loading or emitting vector constants, so the vector | 5339 // There is no support for loading or emitting vector constants, so the vector |
| 5311 // values returned from makeVectorOfZeros, makeVectorOfOnes, etc. are | 5340 // values returned from makeVectorOfZeros, makeVectorOfOnes, etc. are |
| 5312 // initialized with register operations. | 5341 // initialized with register operations. |
| 5313 // | 5342 // |
| 5314 // TODO(wala): Add limited support for vector constants so that complex | 5343 // TODO(wala): Add limited support for vector constants so that complex |
| 5315 // initialization in registers is unnecessary. | 5344 // initialization in registers is unnecessary. |
| 5316 | 5345 |
| 5317 template <class Machine> | 5346 template <class Machine> |
| 5318 Variable *TargetX86Base<Machine>::makeVectorOfZeros(Type Ty, int32_t RegNum) { | 5347 Variable *TargetX86Base<Machine>::makeVectorOfZeros(Type Ty, int32_t RegNum) { |
| 5319 Variable *Reg = makeReg(Ty, RegNum); | 5348 return makeZeroedRegister(Ty, RegNum); |
| 5320 // Insert a FakeDef, since otherwise the live range of Reg might be | |
| 5321 // overestimated. | |
| 5322 Context.insert(InstFakeDef::create(Func, Reg)); | |
| 5323 _pxor(Reg, Reg); | |
| 5324 return Reg; | |
| 5325 } | 5349 } |
| 5326 | 5350 |
| 5327 template <class Machine> | 5351 template <class Machine> |
| 5328 Variable *TargetX86Base<Machine>::makeVectorOfMinusOnes(Type Ty, | 5352 Variable *TargetX86Base<Machine>::makeVectorOfMinusOnes(Type Ty, |
| 5329 int32_t RegNum) { | 5353 int32_t RegNum) { |
| 5330 Variable *MinusOnes = makeReg(Ty, RegNum); | 5354 Variable *MinusOnes = makeReg(Ty, RegNum); |
| 5331 // Insert a FakeDef so the live range of MinusOnes is not overestimated. | 5355 // Insert a FakeDef so the live range of MinusOnes is not overestimated. |
| 5332 Context.insert(InstFakeDef::create(Func, MinusOnes)); | 5356 Context.insert(InstFakeDef::create(Func, MinusOnes)); |
| 5333 _pcmpeq(MinusOnes, MinusOnes); | 5357 _pcmpeq(MinusOnes, MinusOnes); |
| 5334 return MinusOnes; | 5358 return MinusOnes; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5464 Type Ty = Src->getType(); | 5488 Type Ty = Src->getType(); |
| 5465 Variable *Reg = makeReg(Ty, RegNum); | 5489 Variable *Reg = makeReg(Ty, RegNum); |
| 5466 if (isVectorType(Ty)) { | 5490 if (isVectorType(Ty)) { |
| 5467 _movp(Reg, Src); | 5491 _movp(Reg, Src); |
| 5468 } else { | 5492 } else { |
| 5469 _mov(Reg, Src); | 5493 _mov(Reg, Src); |
| 5470 } | 5494 } |
| 5471 return Reg; | 5495 return Reg; |
| 5472 } | 5496 } |
| 5473 | 5497 |
| 5498 namespace { |
| 5499 |
| 5500 template <typename T> bool isPositiveZero(T Val) { |
| 5501 static_assert(std::is_floating_point<T>::value, |
| 5502 "Input type must be floating point"); |
| 5503 return Val == 0 && !signbit(Val); |
| 5504 } |
| 5505 |
| 5506 } // end of anonymous namespace |
| 5507 |
| 5474 template <class Machine> | 5508 template <class Machine> |
| 5475 Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed, | 5509 Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed, |
| 5476 int32_t RegNum) { | 5510 int32_t RegNum) { |
| 5477 Type Ty = From->getType(); | 5511 Type Ty = From->getType(); |
| 5478 // Assert that a physical register is allowed. To date, all calls to | 5512 // Assert that a physical register is allowed. To date, all calls to |
| 5479 // legalize() allow a physical register. If a physical register needs to be | 5513 // legalize() allow a physical register. If a physical register needs to be |
| 5480 // explicitly disallowed, then new code will need to be written to force a | 5514 // explicitly disallowed, then new code will need to be written to force a |
| 5481 // spill. | 5515 // spill. |
| 5482 assert(Allowed & Legal_Reg); | 5516 assert(Allowed & Legal_Reg); |
| 5483 // If we're asking for a specific physical register, make sure we're not | 5517 // If we're asking for a specific physical register, make sure we're not |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5556 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(Const)) { | 5590 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(Const)) { |
| 5557 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); | 5591 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); |
| 5558 if (NewConst != Const) { | 5592 if (NewConst != Const) { |
| 5559 return NewConst; | 5593 return NewConst; |
| 5560 } | 5594 } |
| 5561 } | 5595 } |
| 5562 | 5596 |
| 5563 // Convert a scalar floating point constant into an explicit memory | 5597 // Convert a scalar floating point constant into an explicit memory |
| 5564 // operand. | 5598 // operand. |
| 5565 if (isScalarFloatingType(Ty)) { | 5599 if (isScalarFloatingType(Ty)) { |
| 5600 if (auto *ConstFloat = llvm::dyn_cast<ConstantFloat>(Const)) { |
| 5601 if (isPositiveZero(ConstFloat->getValue())) |
| 5602 return makeZeroedRegister(Ty, RegNum); |
| 5603 } else if (auto *ConstDouble = llvm::dyn_cast<ConstantDouble>(Const)) { |
| 5604 if (isPositiveZero(ConstDouble->getValue())) |
| 5605 return makeZeroedRegister(Ty, RegNum); |
| 5606 } |
| 5566 Variable *Base = nullptr; | 5607 Variable *Base = nullptr; |
| 5567 std::string Buffer; | 5608 std::string Buffer; |
| 5568 llvm::raw_string_ostream StrBuf(Buffer); | 5609 llvm::raw_string_ostream StrBuf(Buffer); |
| 5569 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx); | 5610 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx); |
| 5570 llvm::cast<Constant>(From)->setShouldBePooled(true); | 5611 llvm::cast<Constant>(From)->setShouldBePooled(true); |
| 5571 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); | 5612 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); |
| 5572 From = Traits::X86OperandMem::create(Func, Ty, Base, Offset); | 5613 From = Traits::X86OperandMem::create(Func, Ty, Base, Offset); |
| 5573 } | 5614 } |
| 5574 bool NeedsReg = false; | 5615 bool NeedsReg = false; |
| 5575 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) | 5616 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5978 } | 6019 } |
| 5979 // the offset is not eligible for blinding or pooling, return the original | 6020 // the offset is not eligible for blinding or pooling, return the original |
| 5980 // mem operand | 6021 // mem operand |
| 5981 return MemOperand; | 6022 return MemOperand; |
| 5982 } | 6023 } |
| 5983 | 6024 |
| 5984 } // end of namespace X86Internal | 6025 } // end of namespace X86Internal |
| 5985 } // end of namespace Ice | 6026 } // end of namespace Ice |
| 5986 | 6027 |
| 5987 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 6028 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |