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