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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 InstructionSetEnum getInstructionSet() const { return InstructionSet; } | 187 InstructionSetEnum getInstructionSet() const { return InstructionSet; } |
188 Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister); | 188 Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister); |
189 | 189 |
190 protected: | 190 protected: |
191 const bool NeedSandboxing; | 191 const bool NeedSandboxing; |
192 | 192 |
193 explicit TargetX86Base(Cfg *Func); | 193 explicit TargetX86Base(Cfg *Func); |
194 | 194 |
195 void postLower() override; | 195 void postLower() override; |
196 | 196 |
| 197 /// Initializes the RebasePtr member variable -- if so required by |
| 198 /// SandboxingType for the concrete Target. |
| 199 void initRebasePtr() { |
| 200 assert(SandboxingType != ST_None); |
| 201 dispatchToConcrete(&Traits::ConcreteTarget::initRebasePtr); |
| 202 } |
| 203 |
| 204 /// Emit code that initializes the value of the RebasePtr near the start of |
| 205 /// the function -- if so required by SandboxingType for the concrete type. |
197 void initSandbox() { | 206 void initSandbox() { |
| 207 assert(SandboxingType != ST_None); |
198 dispatchToConcrete(&Traits::ConcreteTarget::initSandbox); | 208 dispatchToConcrete(&Traits::ConcreteTarget::initSandbox); |
199 } | 209 } |
200 | 210 |
201 void lowerAlloca(const InstAlloca *Inst) override; | 211 void lowerAlloca(const InstAlloca *Inst) override; |
202 void lowerArguments() override; | 212 void lowerArguments() override; |
203 void lowerArithmetic(const InstArithmetic *Inst) override; | 213 void lowerArithmetic(const InstArithmetic *Inst) override; |
204 void lowerAssign(const InstAssign *Inst) override; | 214 void lowerAssign(const InstAssign *Inst) override; |
205 void lowerBr(const InstBr *Inst) override; | 215 void lowerBr(const InstBr *Inst) override; |
206 void lowerCall(const InstCall *Inst) override; | 216 void lowerCall(const InstCall *Inst) override; |
207 void lowerCast(const InstCast *Inst) override; | 217 void lowerCast(const InstCast *Inst) override; |
(...skipping 10 matching lines...) Expand all Loading... |
218 void lowerStore(const InstStore *Inst) override; | 228 void lowerStore(const InstStore *Inst) override; |
219 void lowerSwitch(const InstSwitch *Inst) override; | 229 void lowerSwitch(const InstSwitch *Inst) override; |
220 void lowerUnreachable(const InstUnreachable *Inst) override; | 230 void lowerUnreachable(const InstUnreachable *Inst) override; |
221 void lowerOther(const Inst *Instr) override; | 231 void lowerOther(const Inst *Instr) override; |
222 void lowerRMW(const InstX86FakeRMW *RMW); | 232 void lowerRMW(const InstX86FakeRMW *RMW); |
223 void prelowerPhis() override; | 233 void prelowerPhis() override; |
224 uint32_t getCallStackArgumentsSizeBytes(const std::vector<Type> &ArgTypes, | 234 uint32_t getCallStackArgumentsSizeBytes(const std::vector<Type> &ArgTypes, |
225 Type ReturnType); | 235 Type ReturnType); |
226 uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override; | 236 uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override; |
227 void genTargetHelperCallFor(Inst *Instr) override; | 237 void genTargetHelperCallFor(Inst *Instr) override; |
| 238 |
| 239 /// OptAddr wraps all the possible operands that an x86 address might have. |
| 240 struct OptAddr { |
| 241 Variable *Base = nullptr; |
| 242 Variable *Index = nullptr; |
| 243 uint16_t Shift = 0; |
| 244 int32_t Offset = 0; |
| 245 ConstantRelocatable *Relocatable = nullptr; |
| 246 }; |
| 247 /// Legalizes Addr w.r.t. SandboxingType. The exact type of legalization |
| 248 /// varies for different <Target, SandboxingType> tuples. |
| 249 bool legalizeOptAddrForSandbox(OptAddr *Addr) { |
| 250 return dispatchToConcrete( |
| 251 &Traits::ConcreteTarget::legalizeOptAddrForSandbox, std::move(Addr)); |
| 252 } |
| 253 // Builds information for a canonical address expresion: |
| 254 // <Relocatable + Offset>(Base, Index, Shift) |
| 255 X86OperandMem *computeAddressOpt(const Inst *Instr, Type MemType, |
| 256 Operand *Addr); |
228 void doAddressOptLoad() override; | 257 void doAddressOptLoad() override; |
229 void doAddressOptStore() override; | 258 void doAddressOptStore() override; |
230 void doMockBoundsCheck(Operand *Opnd) override; | 259 void doMockBoundsCheck(Operand *Opnd) override; |
231 void randomlyInsertNop(float Probability, | 260 void randomlyInsertNop(float Probability, |
232 RandomNumberGenerator &RNG) override; | 261 RandomNumberGenerator &RNG) override; |
233 | 262 |
234 /// Naive lowering of cmpxchg. | 263 /// Naive lowering of cmpxchg. |
235 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, | 264 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, |
236 Operand *Desired); | 265 Operand *Desired); |
237 /// Attempt a more optimized lowering of cmpxchg. Returns true if optimized. | 266 /// Attempt a more optimized lowering of cmpxchg. Returns true if optimized. |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 /// that the Operand kind is one of those indicated by the LegalMask (a | 340 /// that the Operand kind is one of those indicated by the LegalMask (a |
312 /// bitmask of allowed kinds). If the input Operand is known to already meet | 341 /// bitmask of allowed kinds). If the input Operand is known to already meet |
313 /// the constraints, it may be simply returned as the result, without creating | 342 /// the constraints, it may be simply returned as the result, without creating |
314 /// any new instructions or operands. | 343 /// any new instructions or operands. |
315 enum OperandLegalization { | 344 enum OperandLegalization { |
316 Legal_None = 0, | 345 Legal_None = 0, |
317 Legal_Reg = 1 << 0, // physical register, not stack location | 346 Legal_Reg = 1 << 0, // physical register, not stack location |
318 Legal_Imm = 1 << 1, | 347 Legal_Imm = 1 << 1, |
319 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] | 348 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] |
320 Legal_Rematerializable = 1 << 3, | 349 Legal_Rematerializable = 1 << 3, |
321 Legal_AddrAbs = 1 << 4, // ConstantRelocatable doesn't have to add GotVar | 350 Legal_AddrAbs = 1 << 4, // ConstantRelocatable doesn't have to add RebasePtr |
322 Legal_Default = ~(Legal_Rematerializable | Legal_AddrAbs) | 351 Legal_Default = ~(Legal_Rematerializable | Legal_AddrAbs) |
323 // TODO(stichnot): Figure out whether this default works for x86-64. | 352 // TODO(stichnot): Figure out whether this default works for x86-64. |
324 }; | 353 }; |
325 using LegalMask = uint32_t; | 354 using LegalMask = uint32_t; |
326 Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default, | 355 Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default, |
327 int32_t RegNum = Variable::NoRegister); | 356 int32_t RegNum = Variable::NoRegister); |
328 Variable *legalizeToReg(Operand *From, int32_t RegNum = Variable::NoRegister); | 357 Variable *legalizeToReg(Operand *From, int32_t RegNum = Variable::NoRegister); |
329 /// Legalize the first source operand for use in the cmp instruction. | 358 /// Legalize the first source operand for use in the cmp instruction. |
330 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); | 359 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); |
331 /// Turn a pointer operand into a memory operand that can be used by a real | 360 /// 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... |
399 } | 428 } |
400 | 429 |
401 X86OperandMem **findMemoryReference() { return nullptr; } | 430 X86OperandMem **findMemoryReference() { return nullptr; } |
402 | 431 |
403 public: | 432 public: |
404 std::unique_ptr<AutoBundle> Bundler; | 433 std::unique_ptr<AutoBundle> Bundler; |
405 X86OperandMem **const MemOperand; | 434 X86OperandMem **const MemOperand; |
406 | 435 |
407 template <typename... T> | 436 template <typename... T> |
408 AutoMemorySandboxer(typename Traits::TargetLowering *Target, T... Args) | 437 AutoMemorySandboxer(typename Traits::TargetLowering *Target, T... Args) |
409 : Target(Target), | 438 : Target(Target), MemOperand(Target->SandboxingType == ST_None |
410 MemOperand( | 439 ? nullptr |
411 (!Traits::Is64Bit || !Target->Ctx->getFlags().getUseSandboxing()) | 440 : findMemoryReference(Args...)) { |
412 ? nullptr | |
413 : findMemoryReference(Args...)) { | |
414 if (MemOperand != nullptr) { | 441 if (MemOperand != nullptr) { |
415 Bundler = makeUnique<AutoBundle>(Target, BundleLockOpt); | 442 Bundler = makeUnique<AutoBundle>(Target, BundleLockOpt); |
416 *MemOperand = Target->_sandbox_mem_reference(*MemOperand); | 443 *MemOperand = Target->_sandbox_mem_reference(*MemOperand); |
417 } | 444 } |
418 } | 445 } |
419 | 446 |
420 ~AutoMemorySandboxer() {} | 447 ~AutoMemorySandboxer() {} |
421 }; | 448 }; |
422 | 449 |
423 /// The following are helpers that insert lowered x86 instructions with | 450 /// The following are helpers that insert lowered x86 instructions with |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
921 size_t SpillAreaSizeBytes = 0; | 948 size_t SpillAreaSizeBytes = 0; |
922 size_t FixedAllocaSizeBytes = 0; | 949 size_t FixedAllocaSizeBytes = 0; |
923 size_t FixedAllocaAlignBytes = 0; | 950 size_t FixedAllocaAlignBytes = 0; |
924 bool PrologEmitsFixedAllocas = false; | 951 bool PrologEmitsFixedAllocas = false; |
925 uint32_t MaxOutArgsSizeBytes = 0; | 952 uint32_t MaxOutArgsSizeBytes = 0; |
926 static std::array<llvm::SmallBitVector, RCX86_NUM> TypeToRegisterSet; | 953 static std::array<llvm::SmallBitVector, RCX86_NUM> TypeToRegisterSet; |
927 static std::array<llvm::SmallBitVector, Traits::RegisterSet::Reg_NUM> | 954 static std::array<llvm::SmallBitVector, Traits::RegisterSet::Reg_NUM> |
928 RegisterAliases; | 955 RegisterAliases; |
929 llvm::SmallBitVector RegsUsed; | 956 llvm::SmallBitVector RegsUsed; |
930 std::array<VarList, IceType_NUM> PhysicalRegisters; | 957 std::array<VarList, IceType_NUM> PhysicalRegisters; |
931 // GotVar is a Variable that holds the GlobalOffsetTable address for Non-SFI | 958 // RebasePtr is a Variable that holds the Rebasing pointer (if any) for the |
932 // mode. | 959 // current sandboxing type. |
933 Variable *GotVar = nullptr; | 960 Variable *RebasePtr = nullptr; |
934 | 961 |
935 /// Randomize a given immediate operand | 962 /// Randomize a given immediate operand |
936 Operand *randomizeOrPoolImmediate(Constant *Immediate, | 963 Operand *randomizeOrPoolImmediate(Constant *Immediate, |
937 int32_t RegNum = Variable::NoRegister); | 964 int32_t RegNum = Variable::NoRegister); |
938 X86OperandMem * | 965 X86OperandMem * |
939 randomizeOrPoolImmediate(X86OperandMem *MemOperand, | 966 randomizeOrPoolImmediate(X86OperandMem *MemOperand, |
940 int32_t RegNum = Variable::NoRegister); | 967 int32_t RegNum = Variable::NoRegister); |
941 bool RandomizationPoolingPaused = false; | 968 bool RandomizationPoolingPaused = false; |
942 | 969 |
943 private: | 970 private: |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 void lowerSelectMove(Variable *Dest, BrCond Cond, Operand *SrcT, | 1018 void lowerSelectMove(Variable *Dest, BrCond Cond, Operand *SrcT, |
992 Operand *SrcF); | 1019 Operand *SrcF); |
993 void lowerSelectIntMove(Variable *Dest, BrCond Cond, Operand *SrcT, | 1020 void lowerSelectIntMove(Variable *Dest, BrCond Cond, Operand *SrcT, |
994 Operand *SrcF); | 1021 Operand *SrcF); |
995 /// Generic helper to move an arbitrary type from Src to Dest. | 1022 /// Generic helper to move an arbitrary type from Src to Dest. |
996 void lowerMove(Variable *Dest, Operand *Src, bool IsRedefinition); | 1023 void lowerMove(Variable *Dest, Operand *Src, bool IsRedefinition); |
997 | 1024 |
998 /// Optimizations for idiom recognition. | 1025 /// Optimizations for idiom recognition. |
999 bool lowerOptimizeFcmpSelect(const InstFcmp *Fcmp, const InstSelect *Select); | 1026 bool lowerOptimizeFcmpSelect(const InstFcmp *Fcmp, const InstSelect *Select); |
1000 | 1027 |
1001 /// Emit code that initializes the value of the GotVar near the start of the | |
1002 /// function. (This code is emitted only in Non-SFI mode.) | |
1003 void initGotVarIfNeeded(); | |
1004 | |
1005 /// Complains loudly if invoked because the cpu can handle 64-bit types | 1028 /// Complains loudly if invoked because the cpu can handle 64-bit types |
1006 /// natively. | 1029 /// natively. |
1007 template <typename T = Traits> | 1030 template <typename T = Traits> |
1008 typename std::enable_if<T::Is64Bit, void>::type lowerIcmp64(const InstIcmp *, | 1031 typename std::enable_if<T::Is64Bit, void>::type lowerIcmp64(const InstIcmp *, |
1009 const Inst *) { | 1032 const Inst *) { |
1010 llvm::report_fatal_error( | 1033 llvm::report_fatal_error( |
1011 "Hey, yo! This is x86-64. Watcha doin'? (lowerIcmp64)"); | 1034 "Hey, yo! This is x86-64. Watcha doin'? (lowerIcmp64)"); |
1012 } | 1035 } |
1013 /// x86lowerIcmp64 handles 64-bit icmp lowering. | 1036 /// x86lowerIcmp64 handles 64-bit icmp lowering. |
1014 template <typename T = Traits> | 1037 template <typename T = Traits> |
1015 typename std::enable_if<!T::Is64Bit, void>::type | 1038 typename std::enable_if<!T::Is64Bit, void>::type |
1016 lowerIcmp64(const InstIcmp *Icmp, const Inst *Consumer); | 1039 lowerIcmp64(const InstIcmp *Icmp, const Inst *Consumer); |
1017 | 1040 |
1018 BoolFolding<Traits> FoldingInfo; | 1041 BoolFolding<Traits> FoldingInfo; |
1019 | 1042 |
1020 static FixupKind PcRelFixup; | 1043 static FixupKind PcRelFixup; |
1021 static FixupKind AbsFixup; | 1044 static FixupKind AbsFixup; |
1022 }; | 1045 }; |
1023 } // end of namespace X86NAMESPACE | 1046 } // end of namespace X86NAMESPACE |
1024 } // end of namespace Ice | 1047 } // end of namespace Ice |
1025 | 1048 |
1026 #include "IceTargetLoweringX86BaseImpl.h" | 1049 #include "IceTargetLoweringX86BaseImpl.h" |
1027 | 1050 |
1028 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H | 1051 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H |
OLD | NEW |