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 // This file implements the TargetLoweringX86Base class, which | 10 // This file implements the TargetLoweringX86Base class, which |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 return nullptr; | 242 return nullptr; |
243 SizeT VarNum = Var->getIndex(); | 243 SizeT VarNum = Var->getIndex(); |
244 auto Element = Producers.find(VarNum); | 244 auto Element = Producers.find(VarNum); |
245 if (Element == Producers.end()) | 245 if (Element == Producers.end()) |
246 return nullptr; | 246 return nullptr; |
247 return Element->second.Instr; | 247 return Element->second.Instr; |
248 } | 248 } |
249 | 249 |
250 template <class MachineTraits> | 250 template <class MachineTraits> |
251 void BoolFolding<MachineTraits>::dump(const Cfg *Func) const { | 251 void BoolFolding<MachineTraits>::dump(const Cfg *Func) const { |
252 if (!ALLOW_DUMP || !Func->isVerbose(IceV_Folding)) | 252 if (!BuildDefs::dump() || !Func->isVerbose(IceV_Folding)) |
253 return; | 253 return; |
254 OstreamLocker L(Func->getContext()); | 254 OstreamLocker L(Func->getContext()); |
255 Ostream &Str = Func->getContext()->getStrDump(); | 255 Ostream &Str = Func->getContext()->getStrDump(); |
256 for (auto &I : Producers) { | 256 for (auto &I : Producers) { |
257 if (I.second.Instr == nullptr) | 257 if (I.second.Instr == nullptr) |
258 continue; | 258 continue; |
259 Str << "Found foldable producer:\n "; | 259 Str << "Found foldable producer:\n "; |
260 I.second.Instr->dump(Func); | 260 I.second.Instr->dump(Func); |
261 Str << "\n"; | 261 Str << "\n"; |
262 } | 262 } |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 Variable *Arg = Args[I]; | 835 Variable *Arg = Args[I]; |
836 Type Ty = Arg->getType(); | 836 Type Ty = Arg->getType(); |
837 if (!isVectorType(Ty)) | 837 if (!isVectorType(Ty)) |
838 continue; | 838 continue; |
839 // Replace Arg in the argument list with the home register. Then | 839 // Replace Arg in the argument list with the home register. Then |
840 // generate an instruction in the prolog to copy the home register | 840 // generate an instruction in the prolog to copy the home register |
841 // to the assigned location of Arg. | 841 // to the assigned location of Arg. |
842 int32_t RegNum = RegX8632::Reg_xmm0 + NumXmmArgs; | 842 int32_t RegNum = RegX8632::Reg_xmm0 + NumXmmArgs; |
843 ++NumXmmArgs; | 843 ++NumXmmArgs; |
844 Variable *RegisterArg = Func->makeVariable(Ty); | 844 Variable *RegisterArg = Func->makeVariable(Ty); |
845 if (ALLOW_DUMP) | 845 if (BuildDefs::dump()) |
846 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); | 846 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); |
847 RegisterArg->setRegNum(RegNum); | 847 RegisterArg->setRegNum(RegNum); |
848 RegisterArg->setIsArg(); | 848 RegisterArg->setIsArg(); |
849 Arg->setIsArg(false); | 849 Arg->setIsArg(false); |
850 | 850 |
851 Args[I] = RegisterArg; | 851 Args[I] = RegisterArg; |
852 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); | 852 Context.insert(InstAssign::create(Func, Arg, RegisterArg)); |
853 } | 853 } |
854 } | 854 } |
855 | 855 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize, | 1067 SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize, |
1068 IsEbpBasedFrame); | 1068 IsEbpBasedFrame); |
1069 // Assign stack offsets to variables that have been linked to spilled | 1069 // Assign stack offsets to variables that have been linked to spilled |
1070 // variables. | 1070 // variables. |
1071 for (Variable *Var : VariablesLinkedToSpillSlots) { | 1071 for (Variable *Var : VariablesLinkedToSpillSlots) { |
1072 Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo(); | 1072 Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo(); |
1073 Var->setStackOffset(Linked->getStackOffset()); | 1073 Var->setStackOffset(Linked->getStackOffset()); |
1074 } | 1074 } |
1075 this->HasComputedFrame = true; | 1075 this->HasComputedFrame = true; |
1076 | 1076 |
1077 if (ALLOW_DUMP && Func->isVerbose(IceV_Frame)) { | 1077 if (BuildDefs::dump() && Func->isVerbose(IceV_Frame)) { |
1078 OstreamLocker L(Func->getContext()); | 1078 OstreamLocker L(Func->getContext()); |
1079 Ostream &Str = Func->getContext()->getStrDump(); | 1079 Ostream &Str = Func->getContext()->getStrDump(); |
1080 | 1080 |
1081 Str << "Stack layout:\n"; | 1081 Str << "Stack layout:\n"; |
1082 uint32_t EspAdjustmentPaddingSize = | 1082 uint32_t EspAdjustmentPaddingSize = |
1083 SpillAreaSizeBytes - LocalsSpillAreaSize - | 1083 SpillAreaSizeBytes - LocalsSpillAreaSize - |
1084 GlobalsAndSubsequentPaddingSize - SpillAreaPaddingBytes; | 1084 GlobalsAndSubsequentPaddingSize - SpillAreaPaddingBytes; |
1085 Str << " in-args = " << InArgsSizeBytes << " bytes\n" | 1085 Str << " in-args = " << InArgsSizeBytes << " bytes\n" |
1086 << " return address = " << Traits::X86_RET_IP_SIZE_BYTES << " bytes\n" | 1086 << " return address = " << Traits::X86_RET_IP_SIZE_BYTES << " bytes\n" |
1087 << " preserved registers = " << PreservedRegsSizeBytes << " bytes\n" | 1087 << " preserved registers = " << PreservedRegsSizeBytes << " bytes\n" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 } | 1183 } |
1184 Variable *Lo = Var->getLo(); | 1184 Variable *Lo = Var->getLo(); |
1185 Variable *Hi = Var->getHi(); | 1185 Variable *Hi = Var->getHi(); |
1186 if (Lo) { | 1186 if (Lo) { |
1187 assert(Hi); | 1187 assert(Hi); |
1188 return; | 1188 return; |
1189 } | 1189 } |
1190 assert(Hi == nullptr); | 1190 assert(Hi == nullptr); |
1191 Lo = Func->makeVariable(IceType_i32); | 1191 Lo = Func->makeVariable(IceType_i32); |
1192 Hi = Func->makeVariable(IceType_i32); | 1192 Hi = Func->makeVariable(IceType_i32); |
1193 if (ALLOW_DUMP) { | 1193 if (BuildDefs::dump()) { |
1194 Lo->setName(Func, Var->getName(Func) + "__lo"); | 1194 Lo->setName(Func, Var->getName(Func) + "__lo"); |
1195 Hi->setName(Func, Var->getName(Func) + "__hi"); | 1195 Hi->setName(Func, Var->getName(Func) + "__hi"); |
1196 } | 1196 } |
1197 Var->setLoHi(Lo, Hi); | 1197 Var->setLoHi(Lo, Hi); |
1198 if (Var->getIsArg()) { | 1198 if (Var->getIsArg()) { |
1199 Lo->setIsArg(); | 1199 Lo->setIsArg(); |
1200 Hi->setIsArg(); | 1200 Hi->setIsArg(); |
1201 } | 1201 } |
1202 } | 1202 } |
1203 | 1203 |
(...skipping 2191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3395 Context.insert( | 3395 Context.insert( |
3396 InstFakeUse::create(Func, Context.getLastInserted()->getDest())); | 3396 InstFakeUse::create(Func, Context.getLastInserted()->getDest())); |
3397 return; | 3397 return; |
3398 } | 3398 } |
3399 case Intrinsics::AtomicRMW: | 3399 case Intrinsics::AtomicRMW: |
3400 if (!Intrinsics::isMemoryOrderValid( | 3400 if (!Intrinsics::isMemoryOrderValid( |
3401 ID, getConstantMemoryOrder(Instr->getArg(3)))) { | 3401 ID, getConstantMemoryOrder(Instr->getArg(3)))) { |
3402 Func->setError("Unexpected memory ordering for AtomicRMW"); | 3402 Func->setError("Unexpected memory ordering for AtomicRMW"); |
3403 return; | 3403 return; |
3404 } | 3404 } |
3405 lowerAtomicRMW(Instr->getDest(), | 3405 lowerAtomicRMW( |
3406 static_cast<uint32_t>(llvm::cast<ConstantInteger32>( | 3406 Instr->getDest(), |
3407 Instr->getArg(0))->getValue()), | 3407 static_cast<uint32_t>( |
3408 Instr->getArg(1), Instr->getArg(2)); | 3408 llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue()), |
| 3409 Instr->getArg(1), Instr->getArg(2)); |
3409 return; | 3410 return; |
3410 case Intrinsics::AtomicStore: { | 3411 case Intrinsics::AtomicStore: { |
3411 if (!Intrinsics::isMemoryOrderValid( | 3412 if (!Intrinsics::isMemoryOrderValid( |
3412 ID, getConstantMemoryOrder(Instr->getArg(2)))) { | 3413 ID, getConstantMemoryOrder(Instr->getArg(2)))) { |
3413 Func->setError("Unexpected memory ordering for AtomicStore"); | 3414 Func->setError("Unexpected memory ordering for AtomicStore"); |
3414 return; | 3415 return; |
3415 } | 3416 } |
3416 // We require the memory address to be naturally aligned. | 3417 // We require the memory address to be naturally aligned. |
3417 // Given that is the case, then normal stores are atomic. | 3418 // Given that is the case, then normal stores are atomic. |
3418 // Add a fence after the store to make it visible. | 3419 // Add a fence after the store to make it visible. |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4012 if (const InstArithmetic *Arith = | 4013 if (const InstArithmetic *Arith = |
4013 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { | 4014 llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { |
4014 return (Arith->getOp() == InstArithmetic::Add); | 4015 return (Arith->getOp() == InstArithmetic::Add); |
4015 } | 4016 } |
4016 return false; | 4017 return false; |
4017 } | 4018 } |
4018 | 4019 |
4019 void dumpAddressOpt(const Cfg *Func, const Variable *Base, | 4020 void dumpAddressOpt(const Cfg *Func, const Variable *Base, |
4020 const Variable *Index, uint16_t Shift, int32_t Offset, | 4021 const Variable *Index, uint16_t Shift, int32_t Offset, |
4021 const Inst *Reason) { | 4022 const Inst *Reason) { |
4022 if (!ALLOW_DUMP) | 4023 if (!BuildDefs::dump()) |
4023 return; | 4024 return; |
4024 if (!Func->isVerbose(IceV_AddrOpt)) | 4025 if (!Func->isVerbose(IceV_AddrOpt)) |
4025 return; | 4026 return; |
4026 OstreamLocker L(Func->getContext()); | 4027 OstreamLocker L(Func->getContext()); |
4027 Ostream &Str = Func->getContext()->getStrDump(); | 4028 Ostream &Str = Func->getContext()->getStrDump(); |
4028 Str << "Instruction: "; | 4029 Str << "Instruction: "; |
4029 Reason->dumpDecorated(Func); | 4030 Reason->dumpDecorated(Func); |
4030 Str << " results in Base="; | 4031 Str << " results in Base="; |
4031 if (Base) | 4032 if (Base) |
4032 Base->dump(Func); | 4033 Base->dump(Func); |
(...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5264 First = false; | 5265 First = false; |
5265 Str << getRegName(Register, IceType_i32); | 5266 Str << getRegName(Register, IceType_i32); |
5266 } | 5267 } |
5267 Str << "}\n"; | 5268 Str << "}\n"; |
5268 } | 5269 } |
5269 } | 5270 } |
5270 } | 5271 } |
5271 | 5272 |
5272 template <class Machine> | 5273 template <class Machine> |
5273 void TargetX86Base<Machine>::emit(const ConstantInteger32 *C) const { | 5274 void TargetX86Base<Machine>::emit(const ConstantInteger32 *C) const { |
5274 if (!ALLOW_DUMP) | 5275 if (!BuildDefs::dump()) |
5275 return; | 5276 return; |
5276 Ostream &Str = Ctx->getStrEmit(); | 5277 Ostream &Str = Ctx->getStrEmit(); |
5277 Str << getConstantPrefix() << C->getValue(); | 5278 Str << getConstantPrefix() << C->getValue(); |
5278 } | 5279 } |
5279 | 5280 |
5280 template <class Machine> | 5281 template <class Machine> |
5281 void TargetX86Base<Machine>::emit(const ConstantInteger64 *) const { | 5282 void TargetX86Base<Machine>::emit(const ConstantInteger64 *) const { |
5282 llvm::report_fatal_error("Not expecting to emit 64-bit integers"); | 5283 llvm::report_fatal_error("Not expecting to emit 64-bit integers"); |
5283 } | 5284 } |
5284 | 5285 |
5285 template <class Machine> | 5286 template <class Machine> |
5286 void TargetX86Base<Machine>::emit(const ConstantFloat *C) const { | 5287 void TargetX86Base<Machine>::emit(const ConstantFloat *C) const { |
5287 if (!ALLOW_DUMP) | 5288 if (!BuildDefs::dump()) |
5288 return; | 5289 return; |
5289 Ostream &Str = Ctx->getStrEmit(); | 5290 Ostream &Str = Ctx->getStrEmit(); |
5290 C->emitPoolLabel(Str); | 5291 C->emitPoolLabel(Str); |
5291 } | 5292 } |
5292 | 5293 |
5293 template <class Machine> | 5294 template <class Machine> |
5294 void TargetX86Base<Machine>::emit(const ConstantDouble *C) const { | 5295 void TargetX86Base<Machine>::emit(const ConstantDouble *C) const { |
5295 if (!ALLOW_DUMP) | 5296 if (!BuildDefs::dump()) |
5296 return; | 5297 return; |
5297 Ostream &Str = Ctx->getStrEmit(); | 5298 Ostream &Str = Ctx->getStrEmit(); |
5298 C->emitPoolLabel(Str); | 5299 C->emitPoolLabel(Str); |
5299 } | 5300 } |
5300 | 5301 |
5301 template <class Machine> | 5302 template <class Machine> |
5302 void TargetX86Base<Machine>::emit(const ConstantUndef *) const { | 5303 void TargetX86Base<Machine>::emit(const ConstantUndef *) const { |
5303 llvm::report_fatal_error("undef value encountered by emitter."); | 5304 llvm::report_fatal_error("undef value encountered by emitter."); |
5304 } | 5305 } |
5305 | 5306 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5403 // The offset of this mem operand should be blinded or pooled | 5404 // The offset of this mem operand should be blinded or pooled |
5404 Ctx->statsUpdateRPImms(); | 5405 Ctx->statsUpdateRPImms(); |
5405 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == | 5406 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == |
5406 RPI_Randomize) { | 5407 RPI_Randomize) { |
5407 // blind the constant offset | 5408 // blind the constant offset |
5408 // FROM: | 5409 // FROM: |
5409 // offset[base, index, shift] | 5410 // offset[base, index, shift] |
5410 // TO: | 5411 // TO: |
5411 // insert: lea offset+cookie[base], RegTemp | 5412 // insert: lea offset+cookie[base], RegTemp |
5412 // => -cookie[RegTemp, index, shift] | 5413 // => -cookie[RegTemp, index, shift] |
5413 uint32_t Value = llvm::dyn_cast<ConstantInteger32>( | 5414 uint32_t Value = |
5414 MemOperand->getOffset())->getValue(); | 5415 llvm::dyn_cast<ConstantInteger32>(MemOperand->getOffset()) |
| 5416 ->getValue(); |
5415 uint32_t Cookie = Ctx->getRandomizationCookie(); | 5417 uint32_t Cookie = Ctx->getRandomizationCookie(); |
5416 Constant *Mask1 = Ctx->getConstantInt( | 5418 Constant *Mask1 = Ctx->getConstantInt( |
5417 MemOperand->getOffset()->getType(), Cookie + Value); | 5419 MemOperand->getOffset()->getType(), Cookie + Value); |
5418 Constant *Mask2 = | 5420 Constant *Mask2 = |
5419 Ctx->getConstantInt(MemOperand->getOffset()->getType(), 0 - Cookie); | 5421 Ctx->getConstantInt(MemOperand->getOffset()->getType(), 0 - Cookie); |
5420 | 5422 |
5421 OperandX8632Mem *TempMemOperand = OperandX8632Mem::create( | 5423 OperandX8632Mem *TempMemOperand = OperandX8632Mem::create( |
5422 Func, MemOperand->getType(), MemOperand->getBase(), Mask1); | 5424 Func, MemOperand->getType(), MemOperand->getBase(), Mask1); |
5423 // If we have already assigned a physical register, we must come from | 5425 // If we have already assigned a physical register, we must come from |
5424 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse | 5426 // advancedPhiLowering()=>lowerAssign(). In this case we should reuse |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5494 } | 5496 } |
5495 // the offset is not eligible for blinding or pooling, return the original | 5497 // the offset is not eligible for blinding or pooling, return the original |
5496 // mem operand | 5498 // mem operand |
5497 return MemOperand; | 5499 return MemOperand; |
5498 } | 5500 } |
5499 | 5501 |
5500 } // end of namespace X86Internal | 5502 } // end of namespace X86Internal |
5501 } // end of namespace Ice | 5503 } // end of namespace Ice |
5502 | 5504 |
5503 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 5505 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |