| OLD | NEW | 
|---|
| 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 
| 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 TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which | 
| (...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 890   this->FrameSizeLocals = NextStackOffset - SpillAreaPaddingBytes; | 890   this->FrameSizeLocals = NextStackOffset - SpillAreaPaddingBytes; | 
| 891   this->HasComputedFrame = true; | 891   this->HasComputedFrame = true; | 
| 892 | 892 | 
| 893   // Assign stack offsets to variables that have been linked to spilled | 893   // Assign stack offsets to variables that have been linked to spilled | 
| 894   // variables. | 894   // variables. | 
| 895   for (Variable *Var : VariablesLinkedToSpillSlots) { | 895   for (Variable *Var : VariablesLinkedToSpillSlots) { | 
| 896     Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo(); | 896     Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo(); | 
| 897     Var->setStackOffset(Linked->getStackOffset()); | 897     Var->setStackOffset(Linked->getStackOffset()); | 
| 898   } | 898   } | 
| 899 | 899 | 
| 900   if (ALLOW_DUMP && Func->getContext()->isVerbose(IceV_Frame)) { | 900   if (ALLOW_DUMP && Func->isVerbose(IceV_Frame)) { | 
| 901     OstreamLocker L(Func->getContext()); | 901     OstreamLocker L(Func->getContext()); | 
| 902     Ostream &Str = Func->getContext()->getStrDump(); | 902     Ostream &Str = Func->getContext()->getStrDump(); | 
| 903 | 903 | 
| 904     Str << "Stack layout:\n"; | 904     Str << "Stack layout:\n"; | 
| 905     uint32_t EspAdjustmentPaddingSize = | 905     uint32_t EspAdjustmentPaddingSize = | 
| 906         SpillAreaSizeBytes - LocalsSpillAreaSize - | 906         SpillAreaSizeBytes - LocalsSpillAreaSize - | 
| 907         GlobalsAndSubsequentPaddingSize - SpillAreaPaddingBytes; | 907         GlobalsAndSubsequentPaddingSize - SpillAreaPaddingBytes; | 
| 908     Str << " in-args = " << InArgsSizeBytes << " bytes\n" | 908     Str << " in-args = " << InArgsSizeBytes << " bytes\n" | 
| 909         << " return address = " << X86_RET_IP_SIZE_BYTES << " bytes\n" | 909         << " return address = " << X86_RET_IP_SIZE_BYTES << " bytes\n" | 
| 910         << " preserved registers = " << PreservedRegsSizeBytes << " bytes\n" | 910         << " preserved registers = " << PreservedRegsSizeBytes << " bytes\n" | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 985   typedef ConstantDouble IceType; | 985   typedef ConstantDouble IceType; | 
| 986   static const Type Ty = IceType_f64; | 986   static const Type Ty = IceType_f64; | 
| 987   static const char *TypeName; | 987   static const char *TypeName; | 
| 988   static const char *AsmTag; | 988   static const char *AsmTag; | 
| 989   static const char *PrintfString; | 989   static const char *PrintfString; | 
| 990 }; | 990 }; | 
| 991 const char *PoolTypeConverter<double>::TypeName = "double"; | 991 const char *PoolTypeConverter<double>::TypeName = "double"; | 
| 992 const char *PoolTypeConverter<double>::AsmTag = ".quad"; | 992 const char *PoolTypeConverter<double>::AsmTag = ".quad"; | 
| 993 const char *PoolTypeConverter<double>::PrintfString = "0x%llx"; | 993 const char *PoolTypeConverter<double>::PrintfString = "0x%llx"; | 
| 994 | 994 | 
| 995 template <typename T> void TargetX8632::emitConstantPool() const { | 995 template <typename T> void TargetX8632::emitConstantPool(GlobalContext *Ctx) { | 
| 996   // Note: Still used by emit IAS. | 996   // Note: Still used by emit IAS. | 
| 997   Ostream &Str = Ctx->getStrEmit(); | 997   Ostream &Str = Ctx->getStrEmit(); | 
| 998   Type Ty = T::Ty; | 998   Type Ty = T::Ty; | 
| 999   SizeT Align = typeAlignInBytes(Ty); | 999   SizeT Align = typeAlignInBytes(Ty); | 
| 1000   ConstantList Pool = Ctx->getConstantPool(Ty); | 1000   ConstantList Pool = Ctx->getConstantPool(Ty); | 
| 1001 | 1001 | 
| 1002   Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align | 1002   Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align | 
| 1003       << "\n"; | 1003       << "\n"; | 
| 1004   Str << "\t.align\t" << Align << "\n"; | 1004   Str << "\t.align\t" << Align << "\n"; | 
| 1005   for (Constant *C : Pool) { | 1005   for (Constant *C : Pool) { | 
| 1006     typename T::IceType *Const = llvm::cast<typename T::IceType>(C); | 1006     typename T::IceType *Const = llvm::cast<typename T::IceType>(C); | 
| 1007     typename T::IceType::PrimType Value = Const->getValue(); | 1007     typename T::IceType::PrimType Value = Const->getValue(); | 
| 1008     // Use memcpy() to copy bits from Value into RawValue in a way | 1008     // Use memcpy() to copy bits from Value into RawValue in a way | 
| 1009     // that avoids breaking strict-aliasing rules. | 1009     // that avoids breaking strict-aliasing rules. | 
| 1010     typename T::PrimitiveIntType RawValue; | 1010     typename T::PrimitiveIntType RawValue; | 
| 1011     memcpy(&RawValue, &Value, sizeof(Value)); | 1011     memcpy(&RawValue, &Value, sizeof(Value)); | 
| 1012     char buf[30]; | 1012     char buf[30]; | 
| 1013     int CharsPrinted = | 1013     int CharsPrinted = | 
| 1014         snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); | 1014         snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); | 
| 1015     assert(CharsPrinted >= 0 && | 1015     assert(CharsPrinted >= 0 && | 
| 1016            (size_t)CharsPrinted < llvm::array_lengthof(buf)); | 1016            (size_t)CharsPrinted < llvm::array_lengthof(buf)); | 
| 1017     (void)CharsPrinted; // avoid warnings if asserts are disabled | 1017     (void)CharsPrinted; // avoid warnings if asserts are disabled | 
| 1018     Const->emitPoolLabel(Str); | 1018     Const->emitPoolLabel(Str); | 
| 1019     Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " | 1019     Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " | 
| 1020         << Value << "\n"; | 1020         << Value << "\n"; | 
| 1021   } | 1021   } | 
| 1022 } | 1022 } | 
| 1023 | 1023 | 
| 1024 void TargetX8632::emitConstants() const { | 1024 void TargetX8632::emitConstants(GlobalContext *Ctx) { | 
| 1025   // No need to emit constants from the int pool since (for x86) they | 1025   // No need to emit constants from the int pool since (for x86) they | 
| 1026   // are embedded as immediates in the instructions, just emit float/double. | 1026   // are embedded as immediates in the instructions, just emit float/double. | 
| 1027   if (Ctx->getFlags().UseELFWriter) { | 1027   if (Ctx->getFlags().UseELFWriter) { | 
| 1028     ELFObjectWriter *Writer = Ctx->getObjectWriter(); | 1028     ELFObjectWriter *Writer = Ctx->getObjectWriter(); | 
| 1029     Writer->writeConstantPool<ConstantFloat>(IceType_f32); | 1029     Writer->writeConstantPool<ConstantFloat>(IceType_f32); | 
| 1030     Writer->writeConstantPool<ConstantDouble>(IceType_f64); | 1030     Writer->writeConstantPool<ConstantDouble>(IceType_f64); | 
| 1031   } else { | 1031   } else { | 
| 1032     OstreamLocker L(Ctx); | 1032     OstreamLocker L(Ctx); | 
| 1033     emitConstantPool<PoolTypeConverter<float>>(); | 1033     emitConstantPool<PoolTypeConverter<float>>(Ctx); | 
| 1034     emitConstantPool<PoolTypeConverter<double>>(); | 1034     emitConstantPool<PoolTypeConverter<double>>(Ctx); | 
| 1035   } | 1035   } | 
| 1036 } | 1036 } | 
| 1037 | 1037 | 
| 1038 void TargetX8632::split64(Variable *Var) { | 1038 void TargetX8632::split64(Variable *Var) { | 
| 1039   switch (Var->getType()) { | 1039   switch (Var->getType()) { | 
| 1040   default: | 1040   default: | 
| 1041     return; | 1041     return; | 
| 1042   case IceType_i64: | 1042   case IceType_i64: | 
| 1043   // TODO: Only consider F64 if we need to push each half when | 1043   // TODO: Only consider F64 if we need to push each half when | 
| 1044   // passing as an argument to a function call.  Note that each half | 1044   // passing as an argument to a function call.  Note that each half | 
| (...skipping 2515 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3560     return (Arith->getOp() == InstArithmetic::Add); | 3560     return (Arith->getOp() == InstArithmetic::Add); | 
| 3561   } | 3561   } | 
| 3562   return false; | 3562   return false; | 
| 3563 } | 3563 } | 
| 3564 | 3564 | 
| 3565 void dumpAddressOpt(const Cfg *Func, const Variable *Base, | 3565 void dumpAddressOpt(const Cfg *Func, const Variable *Base, | 
| 3566                     const Variable *Index, uint16_t Shift, int32_t Offset, | 3566                     const Variable *Index, uint16_t Shift, int32_t Offset, | 
| 3567                     const Inst *Reason) { | 3567                     const Inst *Reason) { | 
| 3568   if (!ALLOW_DUMP) | 3568   if (!ALLOW_DUMP) | 
| 3569     return; | 3569     return; | 
| 3570   if (!Func->getContext()->isVerbose(IceV_AddrOpt)) | 3570   if (!Func->isVerbose(IceV_AddrOpt)) | 
| 3571     return; | 3571     return; | 
| 3572   OstreamLocker L(Func->getContext()); | 3572   OstreamLocker L(Func->getContext()); | 
| 3573   Ostream &Str = Func->getContext()->getStrDump(); | 3573   Ostream &Str = Func->getContext()->getStrDump(); | 
| 3574   Str << "Instruction: "; | 3574   Str << "Instruction: "; | 
| 3575   Reason->dumpDecorated(Func); | 3575   Reason->dumpDecorated(Func); | 
| 3576   Str << "  results in Base="; | 3576   Str << "  results in Base="; | 
| 3577   if (Base) | 3577   if (Base) | 
| 3578     Base->dump(Func); | 3578     Base->dump(Func); | 
| 3579   else | 3579   else | 
| 3580     Str << "<null>"; | 3580     Str << "<null>"; | 
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3733     Offset += MoreOffset; | 3733     Offset += MoreOffset; | 
| 3734     Reason = BaseInst; | 3734     Reason = BaseInst; | 
| 3735     return true; | 3735     return true; | 
| 3736   } | 3736   } | 
| 3737   return false; | 3737   return false; | 
| 3738 } | 3738 } | 
| 3739 | 3739 | 
| 3740 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, | 3740 void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base, | 
| 3741                        Variable *&Index, uint16_t &Shift, int32_t &Offset) { | 3741                        Variable *&Index, uint16_t &Shift, int32_t &Offset) { | 
| 3742   Func->resetCurrentNode(); | 3742   Func->resetCurrentNode(); | 
| 3743   if (Func->getContext()->isVerbose(IceV_AddrOpt)) { | 3743   if (Func->isVerbose(IceV_AddrOpt)) { | 
| 3744     OstreamLocker L(Func->getContext()); | 3744     OstreamLocker L(Func->getContext()); | 
| 3745     Ostream &Str = Func->getContext()->getStrDump(); | 3745     Ostream &Str = Func->getContext()->getStrDump(); | 
| 3746     Str << "\nStarting computeAddressOpt for instruction:\n  "; | 3746     Str << "\nStarting computeAddressOpt for instruction:\n  "; | 
| 3747     Instr->dumpDecorated(Func); | 3747     Instr->dumpDecorated(Func); | 
| 3748   } | 3748   } | 
| 3749   (void)Offset; // TODO: pattern-match for non-zero offsets. | 3749   (void)Offset; // TODO: pattern-match for non-zero offsets. | 
| 3750   if (Base == nullptr) | 3750   if (Base == nullptr) | 
| 3751     return; | 3751     return; | 
| 3752   // If the Base has more than one use or is live across multiple | 3752   // If the Base has more than one use or is live across multiple | 
| 3753   // blocks, then don't go further.  Alternatively (?), never consider | 3753   // blocks, then don't go further.  Alternatively (?), never consider | 
| (...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4575     RegisterList Shuffled(List); | 4575     RegisterList Shuffled(List); | 
| 4576     std::random_shuffle(Shuffled.begin(), Shuffled.end(), RNG); | 4576     std::random_shuffle(Shuffled.begin(), Shuffled.end(), RNG); | 
| 4577     for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { | 4577     for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { | 
| 4578       Permutation[List[SI]] = Shuffled[SI]; | 4578       Permutation[List[SI]] = Shuffled[SI]; | 
| 4579       ++NumShuffled; | 4579       ++NumShuffled; | 
| 4580     } | 4580     } | 
| 4581   } | 4581   } | 
| 4582 | 4582 | 
| 4583   assert(NumShuffled + NumPreserved == RegX8632::Reg_NUM); | 4583   assert(NumShuffled + NumPreserved == RegX8632::Reg_NUM); | 
| 4584 | 4584 | 
| 4585   if (Func->getContext()->isVerbose(IceV_Random)) { | 4585   if (Func->isVerbose(IceV_Random)) { | 
| 4586     OstreamLocker L(Func->getContext()); | 4586     OstreamLocker L(Func->getContext()); | 
| 4587     Ostream &Str = Func->getContext()->getStrDump(); | 4587     Ostream &Str = Func->getContext()->getStrDump(); | 
| 4588     Str << "Register equivalence classes:\n"; | 4588     Str << "Register equivalence classes:\n"; | 
| 4589     for (auto I : EquivalenceClasses) { | 4589     for (auto I : EquivalenceClasses) { | 
| 4590       Str << "{"; | 4590       Str << "{"; | 
| 4591       const RegisterList &List = I.second; | 4591       const RegisterList &List = I.second; | 
| 4592       bool First = true; | 4592       bool First = true; | 
| 4593       for (int32_t Register : List) { | 4593       for (int32_t Register : List) { | 
| 4594         if (!First) | 4594         if (!First) | 
| 4595           Str << " "; | 4595           Str << " "; | 
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4723   } else if (IsConstant || IsExternal) | 4723   } else if (IsConstant || IsExternal) | 
| 4724     Str << "\t.zero\t" << Size << "\n"; | 4724     Str << "\t.zero\t" << Size << "\n"; | 
| 4725   // Size is part of .comm. | 4725   // Size is part of .comm. | 
| 4726 | 4726 | 
| 4727   if (IsConstant || HasNonzeroInitializer || IsExternal) | 4727   if (IsConstant || HasNonzeroInitializer || IsExternal) | 
| 4728     Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4728     Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 
| 4729   // Size is part of .comm. | 4729   // Size is part of .comm. | 
| 4730 } | 4730 } | 
| 4731 | 4731 | 
| 4732 } // end of namespace Ice | 4732 } // end of namespace Ice | 
| OLD | NEW | 
|---|