OLD | NEW |
---|---|
1 //===- subzero/src/IceTargetLoweringX86Base.h - x86 lowering ----*- C++ -*-===// | 1 //===- subzero/src/IceTargetLoweringX86Base.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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 InstructionSetEnum getInstructionSet() const { return InstructionSet; } | 185 InstructionSetEnum getInstructionSet() const { return InstructionSet; } |
186 Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister); | 186 Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister); |
187 | 187 |
188 protected: | 188 protected: |
189 const bool NeedSandboxing; | 189 const bool NeedSandboxing; |
190 | 190 |
191 explicit TargetX86Base(Cfg *Func); | 191 explicit TargetX86Base(Cfg *Func); |
192 | 192 |
193 void postLower() override; | 193 void postLower() override; |
194 | 194 |
195 /// Initializes the SandboxPtr member variable -- if so required by | |
196 /// SandboxingType for the concrete Target. | |
197 void initSandboxPtr() { | |
198 assert(SandboxingType != ST_None); | |
199 dispatchToConcrete(&Traits::ConcreteTarget::initSandboxPtr); | |
200 } | |
201 | |
202 /// Emit code that initializes the value of the SandboxPtr near the start of | |
203 /// the function -- if so required by SandboxingType for the concrete type. | |
195 void initSandbox() { | 204 void initSandbox() { |
205 assert(SandboxingType != ST_None); | |
196 dispatchToConcrete(&Traits::ConcreteTarget::initSandbox); | 206 dispatchToConcrete(&Traits::ConcreteTarget::initSandbox); |
197 } | 207 } |
198 | 208 |
199 void lowerAlloca(const InstAlloca *Inst) override; | 209 void lowerAlloca(const InstAlloca *Inst) override; |
200 void lowerArguments() override; | 210 void lowerArguments() override; |
201 void lowerArithmetic(const InstArithmetic *Inst) override; | 211 void lowerArithmetic(const InstArithmetic *Inst) override; |
202 void lowerAssign(const InstAssign *Inst) override; | 212 void lowerAssign(const InstAssign *Inst) override; |
203 void lowerBr(const InstBr *Inst) override; | 213 void lowerBr(const InstBr *Inst) override; |
204 void lowerCall(const InstCall *Inst) override; | 214 void lowerCall(const InstCall *Inst) override; |
205 void lowerCast(const InstCast *Inst) override; | 215 void lowerCast(const InstCast *Inst) override; |
(...skipping 10 matching lines...) Expand all Loading... | |
216 void lowerStore(const InstStore *Inst) override; | 226 void lowerStore(const InstStore *Inst) override; |
217 void lowerSwitch(const InstSwitch *Inst) override; | 227 void lowerSwitch(const InstSwitch *Inst) override; |
218 void lowerUnreachable(const InstUnreachable *Inst) override; | 228 void lowerUnreachable(const InstUnreachable *Inst) override; |
219 void lowerOther(const Inst *Instr) override; | 229 void lowerOther(const Inst *Instr) override; |
220 void lowerRMW(const InstX86FakeRMW *RMW); | 230 void lowerRMW(const InstX86FakeRMW *RMW); |
221 void prelowerPhis() override; | 231 void prelowerPhis() override; |
222 uint32_t getCallStackArgumentsSizeBytes(const std::vector<Type> &ArgTypes, | 232 uint32_t getCallStackArgumentsSizeBytes(const std::vector<Type> &ArgTypes, |
223 Type ReturnType); | 233 Type ReturnType); |
224 uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override; | 234 uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override; |
225 void genTargetHelperCallFor(Inst *Instr) override; | 235 void genTargetHelperCallFor(Inst *Instr) override; |
236 | |
237 /// OptAddr wraps all the possible operands that an x86 address might have. | |
238 struct OptAddr { | |
Jim Stichnoth
2016/01/22 02:44:10
For better or worse, I *think* we go ahead and cal
John
2016/01/22 02:56:21
But this has no methods, and it has a quasi-dumb,
Jim Stichnoth
2016/01/22 03:08:55
On further thought, I take this back. If you make
John
2016/01/22 04:18:07
Not really. In theory, that should be done for str
| |
239 Variable *Base = nullptr; | |
240 Variable *Index = nullptr; | |
241 uint16_t Shift = 0; | |
242 int32_t Offset = 0; | |
243 ConstantRelocatable *Relocatable = nullptr; | |
244 }; | |
245 /// Legalizes Addr w.r.t. SandboxingType. The exact type of legalization | |
246 /// varies for different <Target, SandboxingType> tuples. | |
247 bool legalizeOptAddrForSandbox(OptAddr *Addr) { | |
248 return dispatchToConcrete( | |
249 &Traits::ConcreteTarget::legalizeOptAddrForSandbox, std::move(Addr)); | |
250 } | |
251 // Builds information for a canonical address expresion: | |
252 // <Relocatable + Offset>(Base, Index, Shift) | |
253 X86OperandMem *computeAddressOpt(const Inst *Instr, Type MemType, | |
254 Operand *Addr); | |
226 void doAddressOptLoad() override; | 255 void doAddressOptLoad() override; |
227 void doAddressOptStore() override; | 256 void doAddressOptStore() override; |
228 void doMockBoundsCheck(Operand *Opnd) override; | 257 void doMockBoundsCheck(Operand *Opnd) override; |
229 void randomlyInsertNop(float Probability, | 258 void randomlyInsertNop(float Probability, |
230 RandomNumberGenerator &RNG) override; | 259 RandomNumberGenerator &RNG) override; |
231 | 260 |
232 /// Naive lowering of cmpxchg. | 261 /// Naive lowering of cmpxchg. |
233 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, | 262 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, |
234 Operand *Desired); | 263 Operand *Desired); |
235 /// Attempt a more optimized lowering of cmpxchg. Returns true if optimized. | 264 /// Attempt a more optimized lowering of cmpxchg. Returns true if optimized. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 /// that the Operand kind is one of those indicated by the LegalMask (a | 331 /// that the Operand kind is one of those indicated by the LegalMask (a |
303 /// bitmask of allowed kinds). If the input Operand is known to already meet | 332 /// bitmask of allowed kinds). If the input Operand is known to already meet |
304 /// the constraints, it may be simply returned as the result, without creating | 333 /// the constraints, it may be simply returned as the result, without creating |
305 /// any new instructions or operands. | 334 /// any new instructions or operands. |
306 enum OperandLegalization { | 335 enum OperandLegalization { |
307 Legal_None = 0, | 336 Legal_None = 0, |
308 Legal_Reg = 1 << 0, // physical register, not stack location | 337 Legal_Reg = 1 << 0, // physical register, not stack location |
309 Legal_Imm = 1 << 1, | 338 Legal_Imm = 1 << 1, |
310 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] | 339 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] |
311 Legal_Rematerializable = 1 << 3, | 340 Legal_Rematerializable = 1 << 3, |
312 Legal_AddrAbs = 1 << 4, // ConstantRelocatable doesn't have to add GotVar | 341 Legal_AddrAbs = |
342 1 << 4, // ConstantRelocatable doesn't have to add SandboxPtr | |
313 Legal_Default = ~(Legal_Rematerializable | Legal_AddrAbs) | 343 Legal_Default = ~(Legal_Rematerializable | Legal_AddrAbs) |
314 // TODO(stichnot): Figure out whether this default works for x86-64. | 344 // TODO(stichnot): Figure out whether this default works for x86-64. |
315 }; | 345 }; |
316 using LegalMask = uint32_t; | 346 using LegalMask = uint32_t; |
317 Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default, | 347 Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default, |
318 int32_t RegNum = Variable::NoRegister); | 348 int32_t RegNum = Variable::NoRegister); |
319 Variable *legalizeToReg(Operand *From, int32_t RegNum = Variable::NoRegister); | 349 Variable *legalizeToReg(Operand *From, int32_t RegNum = Variable::NoRegister); |
320 /// Legalize the first source operand for use in the cmp instruction. | 350 /// Legalize the first source operand for use in the cmp instruction. |
321 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); | 351 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); |
322 /// Turn a pointer operand into a memory operand that can be used by a real | 352 /// Turn a pointer operand into a memory operand that can be used by a real |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
390 } | 420 } |
391 | 421 |
392 X86OperandMem **findMemoryReference() { return nullptr; } | 422 X86OperandMem **findMemoryReference() { return nullptr; } |
393 | 423 |
394 public: | 424 public: |
395 std::unique_ptr<AutoBundle> Bundler; | 425 std::unique_ptr<AutoBundle> Bundler; |
396 X86OperandMem **const MemOperand; | 426 X86OperandMem **const MemOperand; |
397 | 427 |
398 template <typename... T> | 428 template <typename... T> |
399 AutoMemorySandboxer(typename Traits::TargetLowering *Target, T... Args) | 429 AutoMemorySandboxer(typename Traits::TargetLowering *Target, T... Args) |
400 : Target(Target), | 430 : Target(Target), MemOperand(Target->SandboxingType == ST_None |
401 MemOperand( | 431 ? nullptr |
402 (!Traits::Is64Bit || !Target->Ctx->getFlags().getUseSandboxing()) | 432 : findMemoryReference(Args...)) { |
403 ? nullptr | |
404 : findMemoryReference(Args...)) { | |
405 if (MemOperand != nullptr) { | 433 if (MemOperand != nullptr) { |
406 Bundler = makeUnique<AutoBundle>(Target, BundleLockOpt); | 434 Bundler = makeUnique<AutoBundle>(Target, BundleLockOpt); |
407 *MemOperand = Target->_sandbox_mem_reference(*MemOperand); | 435 *MemOperand = Target->_sandbox_mem_reference(*MemOperand); |
408 } | 436 } |
409 } | 437 } |
410 | 438 |
411 ~AutoMemorySandboxer() {} | 439 ~AutoMemorySandboxer() {} |
412 }; | 440 }; |
413 | 441 |
414 /// The following are helpers that insert lowered x86 instructions with | 442 /// The following are helpers that insert lowered x86 instructions with |
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
907 size_t SpillAreaSizeBytes = 0; | 935 size_t SpillAreaSizeBytes = 0; |
908 size_t FixedAllocaSizeBytes = 0; | 936 size_t FixedAllocaSizeBytes = 0; |
909 size_t FixedAllocaAlignBytes = 0; | 937 size_t FixedAllocaAlignBytes = 0; |
910 bool PrologEmitsFixedAllocas = false; | 938 bool PrologEmitsFixedAllocas = false; |
911 uint32_t MaxOutArgsSizeBytes = 0; | 939 uint32_t MaxOutArgsSizeBytes = 0; |
912 static std::array<llvm::SmallBitVector, RCX86_NUM> TypeToRegisterSet; | 940 static std::array<llvm::SmallBitVector, RCX86_NUM> TypeToRegisterSet; |
913 static std::array<llvm::SmallBitVector, Traits::RegisterSet::Reg_NUM> | 941 static std::array<llvm::SmallBitVector, Traits::RegisterSet::Reg_NUM> |
914 RegisterAliases; | 942 RegisterAliases; |
915 llvm::SmallBitVector RegsUsed; | 943 llvm::SmallBitVector RegsUsed; |
916 std::array<VarList, IceType_NUM> PhysicalRegisters; | 944 std::array<VarList, IceType_NUM> PhysicalRegisters; |
917 // GotVar is a Variable that holds the GlobalOffsetTable address for Non-SFI | 945 // SandboxPtr is a Variable that holds the GlobalOffsetTable address for |
Jim Stichnoth
2016/01/22 02:44:10
This comment should also reflect its use in sandbo
John
2016/01/22 04:18:07
Done.
| |
918 // mode. | 946 // Non-SFI mode. |
919 Variable *GotVar = nullptr; | 947 Variable *SandboxPtr = nullptr; |
Jim Stichnoth
2016/01/22 02:44:10
I have to say, I'm not thrilled with the various u
John
2016/01/22 02:56:21
How about RebasingPtr? RebasePtr?
| |
920 | 948 |
921 /// Randomize a given immediate operand | 949 /// Randomize a given immediate operand |
922 Operand *randomizeOrPoolImmediate(Constant *Immediate, | 950 Operand *randomizeOrPoolImmediate(Constant *Immediate, |
923 int32_t RegNum = Variable::NoRegister); | 951 int32_t RegNum = Variable::NoRegister); |
924 X86OperandMem * | 952 X86OperandMem * |
925 randomizeOrPoolImmediate(X86OperandMem *MemOperand, | 953 randomizeOrPoolImmediate(X86OperandMem *MemOperand, |
926 int32_t RegNum = Variable::NoRegister); | 954 int32_t RegNum = Variable::NoRegister); |
927 bool RandomizationPoolingPaused = false; | 955 bool RandomizationPoolingPaused = false; |
928 | 956 |
929 private: | 957 private: |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
977 void lowerSelectMove(Variable *Dest, BrCond Cond, Operand *SrcT, | 1005 void lowerSelectMove(Variable *Dest, BrCond Cond, Operand *SrcT, |
978 Operand *SrcF); | 1006 Operand *SrcF); |
979 void lowerSelectIntMove(Variable *Dest, BrCond Cond, Operand *SrcT, | 1007 void lowerSelectIntMove(Variable *Dest, BrCond Cond, Operand *SrcT, |
980 Operand *SrcF); | 1008 Operand *SrcF); |
981 /// Generic helper to move an arbitrary type from Src to Dest. | 1009 /// Generic helper to move an arbitrary type from Src to Dest. |
982 void lowerMove(Variable *Dest, Operand *Src, bool IsRedefinition); | 1010 void lowerMove(Variable *Dest, Operand *Src, bool IsRedefinition); |
983 | 1011 |
984 /// Optimizations for idiom recognition. | 1012 /// Optimizations for idiom recognition. |
985 bool lowerOptimizeFcmpSelect(const InstFcmp *Fcmp, const InstSelect *Select); | 1013 bool lowerOptimizeFcmpSelect(const InstFcmp *Fcmp, const InstSelect *Select); |
986 | 1014 |
987 /// Emit code that initializes the value of the GotVar near the start of the | |
988 /// function. (This code is emitted only in Non-SFI mode.) | |
989 void initGotVarIfNeeded(); | |
990 | |
991 /// Complains loudly if invoked because the cpu can handle 64-bit types | 1015 /// Complains loudly if invoked because the cpu can handle 64-bit types |
992 /// natively. | 1016 /// natively. |
993 template <typename T = Traits> | 1017 template <typename T = Traits> |
994 typename std::enable_if<T::Is64Bit, void>::type lowerIcmp64(const InstIcmp *, | 1018 typename std::enable_if<T::Is64Bit, void>::type lowerIcmp64(const InstIcmp *, |
995 const Inst *) { | 1019 const Inst *) { |
996 llvm::report_fatal_error( | 1020 llvm::report_fatal_error( |
997 "Hey, yo! This is x86-64. Watcha doin'? (lowerIcmp64)"); | 1021 "Hey, yo! This is x86-64. Watcha doin'? (lowerIcmp64)"); |
998 } | 1022 } |
999 /// x86lowerIcmp64 handles 64-bit icmp lowering. | 1023 /// x86lowerIcmp64 handles 64-bit icmp lowering. |
1000 template <typename T = Traits> | 1024 template <typename T = Traits> |
1001 typename std::enable_if<!T::Is64Bit, void>::type | 1025 typename std::enable_if<!T::Is64Bit, void>::type |
1002 lowerIcmp64(const InstIcmp *Icmp, const Inst *Consumer); | 1026 lowerIcmp64(const InstIcmp *Icmp, const Inst *Consumer); |
1003 | 1027 |
1004 BoolFolding<Traits> FoldingInfo; | 1028 BoolFolding<Traits> FoldingInfo; |
1005 | 1029 |
1006 static FixupKind PcRelFixup; | 1030 static FixupKind PcRelFixup; |
1007 static FixupKind AbsFixup; | 1031 static FixupKind AbsFixup; |
1008 }; | 1032 }; |
1009 } // end of namespace X86NAMESPACE | 1033 } // end of namespace X86NAMESPACE |
1010 } // end of namespace Ice | 1034 } // end of namespace Ice |
1011 | 1035 |
1012 #include "IceTargetLoweringX86BaseImpl.h" | 1036 #include "IceTargetLoweringX86BaseImpl.h" |
1013 | 1037 |
1014 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H | 1038 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H |
OLD | NEW |