| 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 |