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 /// \file | 10 /// \file |
11 /// \brief Implements the TargetLoweringX86Base class, which consists almost | 11 /// \brief Implements the TargetLoweringX86Base class, which consists almost |
12 /// entirely of the lowering sequence for each high-level instruction. | 12 /// entirely of the lowering sequence for each high-level instruction. |
13 /// | 13 /// |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 | 15 |
16 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 16 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
17 #define SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 17 #define SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
18 | 18 |
19 #include "IceCfg.h" | 19 #include "IceCfg.h" |
20 #include "IceCfgNode.h" | 20 #include "IceCfgNode.h" |
21 #include "IceClFlags.h" | 21 #include "IceClFlags.h" |
22 #include "IceDefs.h" | 22 #include "IceDefs.h" |
23 #include "IceELFObjectWriter.h" | 23 #include "IceELFObjectWriter.h" |
24 #include "IceGlobalInits.h" | 24 #include "IceGlobalInits.h" |
25 #include "IceInstVarIter.h" | 25 #include "IceInstVarIter.h" |
| 26 #include "IceInstX86Base.h" |
26 #include "IceLiveness.h" | 27 #include "IceLiveness.h" |
27 #include "IceOperand.h" | 28 #include "IceOperand.h" |
28 #include "IcePhiLoweringImpl.h" | 29 #include "IcePhiLoweringImpl.h" |
29 #include "IceUtils.h" | 30 #include "IceUtils.h" |
30 #include "IceInstX86Base.h" | 31 #include "IceVariableSplitting.h" |
| 32 |
31 #include "llvm/Support/MathExtras.h" | 33 #include "llvm/Support/MathExtras.h" |
32 | 34 |
33 #include <stack> | 35 #include <stack> |
34 | 36 |
35 namespace Ice { | 37 namespace Ice { |
36 namespace X86 { | 38 namespace X86 { |
37 template <typename T> struct PoolTypeConverter {}; | 39 template <typename T> struct PoolTypeConverter {}; |
38 | 40 |
39 template <> struct PoolTypeConverter<float> { | 41 template <> struct PoolTypeConverter<float> { |
40 using PrimitiveIntType = uint32_t; | 42 using PrimitiveIntType = uint32_t; |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 BoolFlagSaver B(RandomizationPoolingPaused, true); | 516 BoolFlagSaver B(RandomizationPoolingPaused, true); |
515 doLoadOpt(); | 517 doLoadOpt(); |
516 } | 518 } |
517 Func->genCode(); | 519 Func->genCode(); |
518 if (Func->hasError()) | 520 if (Func->hasError()) |
519 return; | 521 return; |
520 if (SandboxingType != ST_None) { | 522 if (SandboxingType != ST_None) { |
521 initSandbox(); | 523 initSandbox(); |
522 } | 524 } |
523 Func->dump("After x86 codegen"); | 525 Func->dump("After x86 codegen"); |
| 526 splitBlockLocalVariables(Func); |
524 | 527 |
525 // Register allocation. This requires instruction renumbering and full | 528 // Register allocation. This requires instruction renumbering and full |
526 // liveness analysis. Loops must be identified before liveness so variable | 529 // liveness analysis. Loops must be identified before liveness so variable |
527 // use weights are correct. | 530 // use weights are correct. |
528 Func->renumberInstructions(); | 531 Func->renumberInstructions(); |
529 if (Func->hasError()) | 532 if (Func->hasError()) |
530 return; | 533 return; |
531 Func->liveness(Liveness_Intervals); | 534 Func->liveness(Liveness_Intervals); |
532 if (Func->hasError()) | 535 if (Func->hasError()) |
533 return; | 536 return; |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 SpillAreaSizeBytes = 0; | 1038 SpillAreaSizeBytes = 0; |
1036 // If there is a separate locals area, this specifies the alignment for it. | 1039 // If there is a separate locals area, this specifies the alignment for it. |
1037 uint32_t LocalsSlotsAlignmentBytes = 0; | 1040 uint32_t LocalsSlotsAlignmentBytes = 0; |
1038 // The entire spill locations area gets aligned to largest natural alignment | 1041 // The entire spill locations area gets aligned to largest natural alignment |
1039 // of the variables that have a spill slot. | 1042 // of the variables that have a spill slot. |
1040 uint32_t SpillAreaAlignmentBytes = 0; | 1043 uint32_t SpillAreaAlignmentBytes = 0; |
1041 // A spill slot linked to a variable with a stack slot should reuse that | 1044 // A spill slot linked to a variable with a stack slot should reuse that |
1042 // stack slot. | 1045 // stack slot. |
1043 std::function<bool(Variable *)> TargetVarHook = | 1046 std::function<bool(Variable *)> TargetVarHook = |
1044 [&VariablesLinkedToSpillSlots](Variable *Var) { | 1047 [&VariablesLinkedToSpillSlots](Variable *Var) { |
1045 if (Var->getLinkedTo() != nullptr) { | 1048 // TODO(stichnot): Refactor this into the base class. |
1046 // TODO(stichnot): This assert won't necessarily be true in the | 1049 Variable *Root = Var->getLinkedToStackRoot(); |
1047 // future. | 1050 if (Root != nullptr) { |
1048 assert(Var->mustNotHaveReg()); | 1051 assert(!Root->hasReg()); |
1049 if (!Var->getLinkedTo()->hasReg()) { | 1052 if (!Root->hasReg()) { |
1050 VariablesLinkedToSpillSlots.push_back(Var); | 1053 VariablesLinkedToSpillSlots.push_back(Var); |
1051 return true; | 1054 return true; |
1052 } | 1055 } |
1053 } | 1056 } |
1054 return false; | 1057 return false; |
1055 }; | 1058 }; |
1056 | 1059 |
1057 // Compute the list of spilled variables and bounds for GlobalsSize, etc. | 1060 // Compute the list of spilled variables and bounds for GlobalsSize, etc. |
1058 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize, | 1061 getVarStackSlotParams(SortedSpilledVariables, RegsUsed, &GlobalsSize, |
1059 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes, | 1062 &SpillAreaSizeBytes, &SpillAreaAlignmentBytes, |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 InArgsSizeBytes); | 1206 InArgsSizeBytes); |
1204 } | 1207 } |
1205 | 1208 |
1206 // Fill in stack offsets for locals. | 1209 // Fill in stack offsets for locals. |
1207 assignVarStackSlots(SortedSpilledVariables, SpillAreaPaddingBytes, | 1210 assignVarStackSlots(SortedSpilledVariables, SpillAreaPaddingBytes, |
1208 SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize, | 1211 SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize, |
1209 IsEbpBasedFrame); | 1212 IsEbpBasedFrame); |
1210 // Assign stack offsets to variables that have been linked to spilled | 1213 // Assign stack offsets to variables that have been linked to spilled |
1211 // variables. | 1214 // variables. |
1212 for (Variable *Var : VariablesLinkedToSpillSlots) { | 1215 for (Variable *Var : VariablesLinkedToSpillSlots) { |
1213 const Variable *Root = Var->getLinkedToRoot(); | 1216 const Variable *Root = Var->getLinkedToStackRoot(); |
1214 assert(Root != nullptr); | 1217 assert(Root != nullptr); |
1215 Var->setStackOffset(Root->getStackOffset()); | 1218 Var->setStackOffset(Root->getStackOffset()); |
1216 } | 1219 } |
1217 this->HasComputedFrame = true; | 1220 this->HasComputedFrame = true; |
1218 | 1221 |
1219 if (BuildDefs::dump() && Func->isVerbose(IceV_Frame)) { | 1222 if (BuildDefs::dump() && Func->isVerbose(IceV_Frame)) { |
1220 OstreamLocker L(Func->getContext()); | 1223 OstreamLocker L(Func->getContext()); |
1221 Ostream &Str = Func->getContext()->getStrDump(); | 1224 Ostream &Str = Func->getContext()->getStrDump(); |
1222 | 1225 |
1223 Str << "Stack layout:\n"; | 1226 Str << "Stack layout:\n"; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1343 return; | 1346 return; |
1344 } | 1347 } |
1345 emitSandboxedReturn(); | 1348 emitSandboxedReturn(); |
1346 if (RI->getSrcSize()) { | 1349 if (RI->getSrcSize()) { |
1347 auto *RetValue = llvm::cast<Variable>(RI->getSrc(0)); | 1350 auto *RetValue = llvm::cast<Variable>(RI->getSrc(0)); |
1348 Context.insert<InstFakeUse>(RetValue); | 1351 Context.insert<InstFakeUse>(RetValue); |
1349 } | 1352 } |
1350 RI->setDeleted(); | 1353 RI->setDeleted(); |
1351 } | 1354 } |
1352 | 1355 |
| 1356 template <typename TraitsType> |
| 1357 Inst *TargetX86Base<TraitsType>::createLoweredMove(Variable *Dest, |
| 1358 Variable *SrcVar) { |
| 1359 if (isVectorType(Dest->getType())) { |
| 1360 return Traits::Insts::Movp::create(Func, Dest, SrcVar); |
| 1361 } |
| 1362 return Traits::Insts::Mov::create(Func, Dest, SrcVar); |
| 1363 } |
| 1364 |
1353 template <typename TraitsType> Type TargetX86Base<TraitsType>::stackSlotType() { | 1365 template <typename TraitsType> Type TargetX86Base<TraitsType>::stackSlotType() { |
1354 return Traits::WordType; | 1366 return Traits::WordType; |
1355 } | 1367 } |
1356 | 1368 |
1357 template <typename TraitsType> | 1369 template <typename TraitsType> |
1358 template <typename T> | 1370 template <typename T> |
1359 typename std::enable_if<!T::Is64Bit, Operand>::type * | 1371 typename std::enable_if<!T::Is64Bit, Operand>::type * |
1360 TargetX86Base<TraitsType>::loOperand(Operand *Operand) { | 1372 TargetX86Base<TraitsType>::loOperand(Operand *Operand) { |
1361 assert(Operand->getType() == IceType_i64 || | 1373 assert(Operand->getType() == IceType_i64 || |
1362 Operand->getType() == IceType_f64); | 1374 Operand->getType() == IceType_f64); |
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3117 case IceType_f64: { | 3129 case IceType_f64: { |
3118 assert(Src0->getType() == IceType_i64); | 3130 assert(Src0->getType() == IceType_i64); |
3119 if (Traits::Is64Bit) { | 3131 if (Traits::Is64Bit) { |
3120 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 3132 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
3121 Variable *T = makeReg(IceType_f64); | 3133 Variable *T = makeReg(IceType_f64); |
3122 _movd(T, Src0RM); | 3134 _movd(T, Src0RM); |
3123 _mov(Dest, T); | 3135 _mov(Dest, T); |
3124 } else { | 3136 } else { |
3125 Src0 = legalize(Src0); | 3137 Src0 = legalize(Src0); |
3126 if (llvm::isa<X86OperandMem>(Src0)) { | 3138 if (llvm::isa<X86OperandMem>(Src0)) { |
3127 Variable *T = Func->makeVariable(DestTy); | 3139 Variable *T = makeReg(DestTy); |
3128 _movq(T, Src0); | 3140 _movq(T, Src0); |
3129 _movq(Dest, T); | 3141 _movq(Dest, T); |
3130 break; | 3142 break; |
3131 } | 3143 } |
3132 // a.f64 = bitcast b.i64 ==> | 3144 // a.f64 = bitcast b.i64 ==> |
3133 // t_lo.i32 = b_lo.i32 | 3145 // t_lo.i32 = b_lo.i32 |
3134 // FakeDef(s.f64) | 3146 // FakeDef(s.f64) |
3135 // lo(s.f64) = t_lo.i32 | 3147 // lo(s.f64) = t_lo.i32 |
3136 // t_hi.i32 = b_hi.i32 | 3148 // t_hi.i32 = b_hi.i32 |
3137 // hi(s.f64) = t_hi.i32 | 3149 // hi(s.f64) = t_hi.i32 |
(...skipping 4933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8071 emitGlobal(*Var, SectionSuffix); | 8083 emitGlobal(*Var, SectionSuffix); |
8072 } | 8084 } |
8073 } | 8085 } |
8074 } break; | 8086 } break; |
8075 } | 8087 } |
8076 } | 8088 } |
8077 } // end of namespace X86NAMESPACE | 8089 } // end of namespace X86NAMESPACE |
8078 } // end of namespace Ice | 8090 } // end of namespace Ice |
8079 | 8091 |
8080 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 8092 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |