| 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 // This file declares the TargetLoweringX86 template class, which | 10 // This file declares the TargetLoweringX86 template class, which |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 void emit(const ConstantUndef *C) const final; | 131 void emit(const ConstantUndef *C) const final; |
| 132 void emit(const ConstantInteger32 *C) const final; | 132 void emit(const ConstantInteger32 *C) const final; |
| 133 void emit(const ConstantInteger64 *C) const final; | 133 void emit(const ConstantInteger64 *C) const final; |
| 134 void emit(const ConstantFloat *C) const final; | 134 void emit(const ConstantFloat *C) const final; |
| 135 void emit(const ConstantDouble *C) const final; | 135 void emit(const ConstantDouble *C) const final; |
| 136 | 136 |
| 137 void lowerArguments() override; | 137 void lowerArguments() override; |
| 138 void initNodeForLowering(CfgNode *Node) override; | 138 void initNodeForLowering(CfgNode *Node) override; |
| 139 void addProlog(CfgNode *Node) override; | 139 void addProlog(CfgNode *Node) override; |
| 140 void addEpilog(CfgNode *Node) override; | 140 void addEpilog(CfgNode *Node) override; |
| 141 // Ensure that a 64-bit Variable has been split into 2 32-bit | 141 /// Ensure that a 64-bit Variable has been split into 2 32-bit |
| 142 // Variables, creating them if necessary. This is needed for all | 142 /// Variables, creating them if necessary. This is needed for all |
| 143 // I64 operations, and it is needed for pushing F64 arguments for | 143 /// I64 operations, and it is needed for pushing F64 arguments for |
| 144 // function calls using the 32-bit push instruction (though the | 144 /// function calls using the 32-bit push instruction (though the |
| 145 // latter could be done by directly writing to the stack). | 145 /// latter could be done by directly writing to the stack). |
| 146 void split64(Variable *Var); | 146 void split64(Variable *Var); |
| 147 Operand *loOperand(Operand *Operand); | 147 Operand *loOperand(Operand *Operand); |
| 148 Operand *hiOperand(Operand *Operand); | 148 Operand *hiOperand(Operand *Operand); |
| 149 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, | 149 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, |
| 150 size_t BasicFrameOffset, size_t &InArgsSizeBytes); | 150 size_t BasicFrameOffset, size_t &InArgsSizeBytes); |
| 151 X8632::Address stackVarToAsmOperand(const Variable *Var) const final; | 151 X8632::Address stackVarToAsmOperand(const Variable *Var) const final; |
| 152 | 152 |
| 153 typename Traits::InstructionSet getInstructionSet() const final { | 153 typename Traits::InstructionSet getInstructionSet() const final { |
| 154 return InstructionSet; | 154 return InstructionSet; |
| 155 } | 155 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 179 void lowerUnreachable(const InstUnreachable *Inst) override; | 179 void lowerUnreachable(const InstUnreachable *Inst) override; |
| 180 void lowerOther(const Inst *Instr) override; | 180 void lowerOther(const Inst *Instr) override; |
| 181 void lowerRMW(const InstX8632FakeRMW *RMW); | 181 void lowerRMW(const InstX8632FakeRMW *RMW); |
| 182 void prelowerPhis() override; | 182 void prelowerPhis() override; |
| 183 void lowerPhiAssignments(CfgNode *Node, | 183 void lowerPhiAssignments(CfgNode *Node, |
| 184 const AssignList &Assignments) override; | 184 const AssignList &Assignments) override; |
| 185 void doAddressOptLoad() override; | 185 void doAddressOptLoad() override; |
| 186 void doAddressOptStore() override; | 186 void doAddressOptStore() override; |
| 187 void randomlyInsertNop(float Probability) override; | 187 void randomlyInsertNop(float Probability) override; |
| 188 | 188 |
| 189 // Naive lowering of cmpxchg. | 189 /// Naive lowering of cmpxchg. |
| 190 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, | 190 void lowerAtomicCmpxchg(Variable *DestPrev, Operand *Ptr, Operand *Expected, |
| 191 Operand *Desired); | 191 Operand *Desired); |
| 192 // Attempt a more optimized lowering of cmpxchg. Returns true if optimized. | 192 /// Attempt a more optimized lowering of cmpxchg. Returns true if optimized. |
| 193 bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr, | 193 bool tryOptimizedCmpxchgCmpBr(Variable *DestPrev, Operand *Ptr, |
| 194 Operand *Expected, Operand *Desired); | 194 Operand *Expected, Operand *Desired); |
| 195 void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr, | 195 void lowerAtomicRMW(Variable *Dest, uint32_t Operation, Operand *Ptr, |
| 196 Operand *Val); | 196 Operand *Val); |
| 197 void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal, | 197 void lowerCountZeros(bool Cttz, Type Ty, Variable *Dest, Operand *FirstVal, |
| 198 Operand *SecondVal); | 198 Operand *SecondVal); |
| 199 | 199 |
| 200 typedef void (TargetX86Base::*LowerBinOp)(Variable *, Operand *); | 200 typedef void (TargetX86Base::*LowerBinOp)(Variable *, Operand *); |
| 201 void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi, | 201 void expandAtomicRMWAsCmpxchg(LowerBinOp op_lo, LowerBinOp op_hi, |
| 202 Variable *Dest, Operand *Ptr, Operand *Val); | 202 Variable *Dest, Operand *Ptr, Operand *Val); |
| 203 | 203 |
| 204 void eliminateNextVectorSextInstruction(Variable *SignExtendedResult); | 204 void eliminateNextVectorSextInstruction(Variable *SignExtendedResult); |
| 205 | 205 |
| 206 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest, | 206 void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest, |
| 207 Operand *Src0, Operand *Src1); | 207 Operand *Src0, Operand *Src1); |
| 208 | 208 |
| 209 // Operand legalization helpers. To deal with address mode | 209 /// Operand legalization helpers. To deal with address mode |
| 210 // constraints, the helpers will create a new Operand and emit | 210 /// constraints, the helpers will create a new Operand and emit |
| 211 // instructions that guarantee that the Operand kind is one of those | 211 /// instructions that guarantee that the Operand kind is one of those |
| 212 // indicated by the LegalMask (a bitmask of allowed kinds). If the | 212 /// indicated by the LegalMask (a bitmask of allowed kinds). If the |
| 213 // input Operand is known to already meet the constraints, it may be | 213 /// input Operand is known to already meet the constraints, it may be |
| 214 // simply returned as the result, without creating any new | 214 /// simply returned as the result, without creating any new |
| 215 // instructions or operands. | 215 /// instructions or operands. |
| 216 enum OperandLegalization { | 216 enum OperandLegalization { |
| 217 Legal_None = 0, | 217 Legal_None = 0, |
| 218 Legal_Reg = 1 << 0, // physical register, not stack location | 218 Legal_Reg = 1 << 0, // physical register, not stack location |
| 219 Legal_Imm = 1 << 1, | 219 Legal_Imm = 1 << 1, |
| 220 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] | 220 Legal_Mem = 1 << 2, // includes [eax+4*ecx] as well as [esp+12] |
| 221 Legal_All = ~Legal_None | 221 Legal_All = ~Legal_None |
| 222 }; | 222 }; |
| 223 typedef uint32_t LegalMask; | 223 typedef uint32_t LegalMask; |
| 224 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | 224 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
| 225 int32_t RegNum = Variable::NoRegister); | 225 int32_t RegNum = Variable::NoRegister); |
| 226 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); | 226 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); |
| 227 // Legalize the first source operand for use in the cmp instruction. | 227 /// Legalize the first source operand for use in the cmp instruction. |
| 228 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); | 228 Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1); |
| 229 // Turn a pointer operand into a memory operand that can be | 229 /// Turn a pointer operand into a memory operand that can be |
| 230 // used by a real load/store operation. Legalizes the operand as well. | 230 /// used by a real load/store operation. Legalizes the operand as well. |
| 231 // This is a nop if the operand is already a legal memory operand. | 231 /// This is a nop if the operand is already a legal memory operand. |
| 232 OperandX8632Mem *formMemoryOperand(Operand *Ptr, Type Ty, | 232 OperandX8632Mem *formMemoryOperand(Operand *Ptr, Type Ty, |
| 233 bool DoLegalize = true); | 233 bool DoLegalize = true); |
| 234 | 234 |
| 235 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 235 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 236 static Type stackSlotType(); | 236 static Type stackSlotType(); |
| 237 | 237 |
| 238 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); | 238 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); |
| 239 | 239 |
| 240 // Returns a vector in a register with the given constant entries. | 240 /// Returns a vector in a register with the given constant entries. |
| 241 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); | 241 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 242 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister); | 242 Variable *makeVectorOfOnes(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 243 Variable *makeVectorOfMinusOnes(Type Ty, | 243 Variable *makeVectorOfMinusOnes(Type Ty, |
| 244 int32_t RegNum = Variable::NoRegister); | 244 int32_t RegNum = Variable::NoRegister); |
| 245 Variable *makeVectorOfHighOrderBits(Type Ty, | 245 Variable *makeVectorOfHighOrderBits(Type Ty, |
| 246 int32_t RegNum = Variable::NoRegister); | 246 int32_t RegNum = Variable::NoRegister); |
| 247 Variable *makeVectorOfFabsMask(Type Ty, | 247 Variable *makeVectorOfFabsMask(Type Ty, |
| 248 int32_t RegNum = Variable::NoRegister); | 248 int32_t RegNum = Variable::NoRegister); |
| 249 | 249 |
| 250 // Return a memory operand corresponding to a stack allocated Variable. | 250 /// Return a memory operand corresponding to a stack allocated Variable. |
| 251 OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot, | 251 OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot, |
| 252 uint32_t Offset = 0); | 252 uint32_t Offset = 0); |
| 253 | 253 |
| 254 void makeRandomRegisterPermutation( | 254 void makeRandomRegisterPermutation( |
| 255 llvm::SmallVectorImpl<int32_t> &Permutation, | 255 llvm::SmallVectorImpl<int32_t> &Permutation, |
| 256 const llvm::SmallBitVector &ExcludeRegisters) const override; | 256 const llvm::SmallBitVector &ExcludeRegisters) const override; |
| 257 | 257 |
| 258 // The following are helpers that insert lowered x86 instructions | 258 /// The following are helpers that insert lowered x86 instructions |
| 259 // with minimal syntactic overhead, so that the lowering code can | 259 /// with minimal syntactic overhead, so that the lowering code can |
| 260 // look as close to assembly as practical. | 260 /// look as close to assembly as practical. |
| 261 void _adc(Variable *Dest, Operand *Src0) { | 261 void _adc(Variable *Dest, Operand *Src0) { |
| 262 Context.insert(InstX8632Adc::create(Func, Dest, Src0)); | 262 Context.insert(InstX8632Adc::create(Func, Dest, Src0)); |
| 263 } | 263 } |
| 264 void _adc_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 264 void _adc_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { |
| 265 Context.insert(InstX8632AdcRMW::create(Func, DestSrc0, Src1)); | 265 Context.insert(InstX8632AdcRMW::create(Func, DestSrc0, Src1)); |
| 266 } | 266 } |
| 267 void _add(Variable *Dest, Operand *Src0) { | 267 void _add(Variable *Dest, Operand *Src0) { |
| 268 Context.insert(InstX8632Add::create(Func, Dest, Src0)); | 268 Context.insert(InstX8632Add::create(Func, Dest, Src0)); |
| 269 } | 269 } |
| 270 void _add_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { | 270 void _add_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { | 371 void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { |
| 372 Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1)); | 372 Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1)); |
| 373 } | 373 } |
| 374 void _jmp(Operand *Target) { | 374 void _jmp(Operand *Target) { |
| 375 Context.insert(InstX8632Jmp::create(Func, Target)); | 375 Context.insert(InstX8632Jmp::create(Func, Target)); |
| 376 } | 376 } |
| 377 void _lea(Variable *Dest, Operand *Src0) { | 377 void _lea(Variable *Dest, Operand *Src0) { |
| 378 Context.insert(InstX8632Lea::create(Func, Dest, Src0)); | 378 Context.insert(InstX8632Lea::create(Func, Dest, Src0)); |
| 379 } | 379 } |
| 380 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); } | 380 void _mfence() { Context.insert(InstX8632Mfence::create(Func)); } |
| 381 // If Dest=nullptr is passed in, then a new variable is created, | 381 /// If Dest=nullptr is passed in, then a new variable is created, |
| 382 // marked as infinite register allocation weight, and returned | 382 /// marked as infinite register allocation weight, and returned |
| 383 // through the in/out Dest argument. | 383 /// through the in/out Dest argument. |
| 384 void _mov(Variable *&Dest, Operand *Src0, | 384 void _mov(Variable *&Dest, Operand *Src0, |
| 385 int32_t RegNum = Variable::NoRegister) { | 385 int32_t RegNum = Variable::NoRegister) { |
| 386 if (Dest == nullptr) | 386 if (Dest == nullptr) |
| 387 Dest = makeReg(Src0->getType(), RegNum); | 387 Dest = makeReg(Src0->getType(), RegNum); |
| 388 Context.insert(InstX8632Mov::create(Func, Dest, Src0)); | 388 Context.insert(InstX8632Mov::create(Func, Dest, Src0)); |
| 389 } | 389 } |
| 390 void _mov_nonkillable(Variable *Dest, Operand *Src0) { | 390 void _mov_nonkillable(Variable *Dest, Operand *Src0) { |
| 391 Inst *NewInst = InstX8632Mov::create(Func, Dest, Src0); | 391 Inst *NewInst = InstX8632Mov::create(Func, Dest, Src0); |
| 392 NewInst->setDestNonKillable(); | 392 NewInst->setDestNonKillable(); |
| 393 Context.insert(NewInst); | 393 Context.insert(NewInst); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 Traits::InstructionSet::Begin; | 587 Traits::InstructionSet::Begin; |
| 588 bool IsEbpBasedFrame = false; | 588 bool IsEbpBasedFrame = false; |
| 589 bool NeedsStackAlignment = false; | 589 bool NeedsStackAlignment = false; |
| 590 size_t SpillAreaSizeBytes = 0; | 590 size_t SpillAreaSizeBytes = 0; |
| 591 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 591 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
| 592 llvm::SmallBitVector ScratchRegs; | 592 llvm::SmallBitVector ScratchRegs; |
| 593 llvm::SmallBitVector RegsUsed; | 593 llvm::SmallBitVector RegsUsed; |
| 594 VarList PhysicalRegisters[IceType_NUM]; | 594 VarList PhysicalRegisters[IceType_NUM]; |
| 595 static IceString RegNames[]; | 595 static IceString RegNames[]; |
| 596 | 596 |
| 597 // Randomize a given immediate operand | 597 /// Randomize a given immediate operand |
| 598 Operand *randomizeOrPoolImmediate(Constant *Immediate, | 598 Operand *randomizeOrPoolImmediate(Constant *Immediate, |
| 599 int32_t RegNum = Variable::NoRegister); | 599 int32_t RegNum = Variable::NoRegister); |
| 600 OperandX8632Mem * | 600 OperandX8632Mem * |
| 601 randomizeOrPoolImmediate(OperandX8632Mem *MemOperand, | 601 randomizeOrPoolImmediate(OperandX8632Mem *MemOperand, |
| 602 int32_t RegNum = Variable::NoRegister); | 602 int32_t RegNum = Variable::NoRegister); |
| 603 bool RandomizationPoolingPaused = false; | 603 bool RandomizationPoolingPaused = false; |
| 604 | 604 |
| 605 private: | 605 private: |
| 606 ~TargetX86Base() override {} | 606 ~TargetX86Base() override {} |
| 607 BoolFolding FoldingInfo; | 607 BoolFolding FoldingInfo; |
| 608 }; | 608 }; |
| 609 } // end of namespace X86Internal | 609 } // end of namespace X86Internal |
| 610 } // end of namespace Ice | 610 } // end of namespace Ice |
| 611 | 611 |
| 612 #include "IceTargetLoweringX86BaseImpl.h" | 612 #include "IceTargetLoweringX86BaseImpl.h" |
| 613 | 613 |
| 614 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H | 614 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASE_H |
| OLD | NEW |