Chromium Code Reviews| 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); | |
|
John
2015/11/13 21:51:20
What's the difference of pxor and xorp*?
Jim Stichnoth
2015/11/13 22:20:24
We were trying to figure that out. The Intel guys
| |
| 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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5556 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(Const)) { | 5580 if (ConstantInteger32 *C = llvm::dyn_cast<ConstantInteger32>(Const)) { |
| 5557 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); | 5581 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); |
| 5558 if (NewConst != Const) { | 5582 if (NewConst != Const) { |
| 5559 return NewConst; | 5583 return NewConst; |
| 5560 } | 5584 } |
| 5561 } | 5585 } |
| 5562 | 5586 |
| 5563 // Convert a scalar floating point constant into an explicit memory | 5587 // Convert a scalar floating point constant into an explicit memory |
| 5564 // operand. | 5588 // operand. |
| 5565 if (isScalarFloatingType(Ty)) { | 5589 if (isScalarFloatingType(Ty)) { |
| 5590 if (auto *ConstFloat = llvm::dyn_cast<ConstantFloat>(Const)) { | |
| 5591 float Value = ConstFloat->getValue(); | |
| 5592 if (Value == 0 && !signbit(Value)) | |
|
John
2015/11/13 21:51:19
Optional: This is a good candidate for a little he
Jim Stichnoth
2015/11/13 22:20:24
Nice, done.
| |
| 5593 return makeZeroedRegister(Ty, RegNum); | |
| 5594 } else if (auto *ConstDouble = llvm::dyn_cast<ConstantDouble>(Const)) { | |
| 5595 double Value = ConstDouble->getValue(); | |
| 5596 if (Value == 0 && !signbit(Value)) | |
| 5597 return makeZeroedRegister(Ty, RegNum); | |
| 5598 } | |
| 5566 Variable *Base = nullptr; | 5599 Variable *Base = nullptr; |
| 5567 std::string Buffer; | 5600 std::string Buffer; |
| 5568 llvm::raw_string_ostream StrBuf(Buffer); | 5601 llvm::raw_string_ostream StrBuf(Buffer); |
| 5569 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx); | 5602 llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx); |
| 5570 llvm::cast<Constant>(From)->setShouldBePooled(true); | 5603 llvm::cast<Constant>(From)->setShouldBePooled(true); |
| 5571 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); | 5604 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); |
| 5572 From = Traits::X86OperandMem::create(Func, Ty, Base, Offset); | 5605 From = Traits::X86OperandMem::create(Func, Ty, Base, Offset); |
| 5573 } | 5606 } |
| 5574 bool NeedsReg = false; | 5607 bool NeedsReg = false; |
| 5575 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) | 5608 if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty)) |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5978 } | 6011 } |
| 5979 // the offset is not eligible for blinding or pooling, return the original | 6012 // the offset is not eligible for blinding or pooling, return the original |
| 5980 // mem operand | 6013 // mem operand |
| 5981 return MemOperand; | 6014 return MemOperand; |
| 5982 } | 6015 } |
| 5983 | 6016 |
| 5984 } // end of namespace X86Internal | 6017 } // end of namespace X86Internal |
| 5985 } // end of namespace Ice | 6018 } // end of namespace Ice |
| 5986 | 6019 |
| 5987 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 6020 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |