Chromium Code Reviews| 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 |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 884 Str << "%" << getRegName(Var->getRegNum(), VarType); | 884 Str << "%" << getRegName(Var->getRegNum(), VarType); |
| 885 return; | 885 return; |
| 886 } | 886 } |
| 887 if (Var->mustHaveReg()) { | 887 if (Var->mustHaveReg()) { |
| 888 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + | 888 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + |
| 889 ") has no register assigned - function " + | 889 ") has no register assigned - function " + |
| 890 Func->getFunctionName()); | 890 Func->getFunctionName()); |
| 891 } | 891 } |
| 892 const int32_t Offset = Var->getStackOffset(); | 892 const int32_t Offset = Var->getStackOffset(); |
| 893 auto BaseRegNum = Var->getBaseRegNum(); | 893 auto BaseRegNum = Var->getBaseRegNum(); |
| 894 if (BaseRegNum == RegNumT::NoRegister) | 894 if (BaseRegNum.hasNoValue()) |
| 895 BaseRegNum = getFrameOrStackReg(); | 895 BaseRegNum = getFrameOrStackReg(); |
| 896 // Print in the form "Offset(%reg)", taking care that: | 896 // Print in the form "Offset(%reg)", taking care that: |
| 897 // - Offset is never printed when it is 0 | 897 // - Offset is never printed when it is 0 |
| 898 | 898 |
| 899 const bool DecorateAsm = Func->getContext()->getFlags().getDecorateAsm(); | 899 const bool DecorateAsm = Func->getContext()->getFlags().getDecorateAsm(); |
| 900 // Only print Offset when it is nonzero, regardless of DecorateAsm. | 900 // Only print Offset when it is nonzero, regardless of DecorateAsm. |
| 901 if (Offset) { | 901 if (Offset) { |
| 902 if (DecorateAsm) { | 902 if (DecorateAsm) { |
| 903 Str << Var->getSymbolicStackOffset(Func); | 903 Str << Var->getSymbolicStackOffset(Func); |
| 904 } else { | 904 } else { |
| 905 Str << Offset; | 905 Str << Offset; |
| 906 } | 906 } |
| 907 } | 907 } |
| 908 const Type FrameSPTy = Traits::WordType; | 908 const Type FrameSPTy = Traits::WordType; |
| 909 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")"; | 909 Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")"; |
| 910 } | 910 } |
| 911 | 911 |
| 912 template <typename TraitsType> | 912 template <typename TraitsType> |
| 913 typename TargetX86Base<TraitsType>::X86Address | 913 typename TargetX86Base<TraitsType>::X86Address |
| 914 TargetX86Base<TraitsType>::stackVarToAsmOperand(const Variable *Var) const { | 914 TargetX86Base<TraitsType>::stackVarToAsmOperand(const Variable *Var) const { |
| 915 if (Var->hasReg()) | 915 if (Var->hasReg()) |
| 916 llvm::report_fatal_error("Stack Variable has a register assigned"); | 916 llvm::report_fatal_error("Stack Variable has a register assigned"); |
| 917 if (Var->mustHaveReg()) { | 917 if (Var->mustHaveReg()) { |
| 918 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + | 918 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + |
| 919 ") has no register assigned - function " + | 919 ") has no register assigned - function " + |
| 920 Func->getFunctionName()); | 920 Func->getFunctionName()); |
| 921 } | 921 } |
| 922 int32_t Offset = Var->getStackOffset(); | 922 int32_t Offset = Var->getStackOffset(); |
| 923 auto BaseRegNum = Var->getBaseRegNum(); | 923 auto BaseRegNum = Var->getBaseRegNum(); |
| 924 if (Var->getBaseRegNum() == RegNumT::NoRegister) | 924 if (Var->getBaseRegNum().hasNoValue()) |
| 925 BaseRegNum = getFrameOrStackReg(); | 925 BaseRegNum = getFrameOrStackReg(); |
| 926 return X86Address(Traits::getEncodedGPR(BaseRegNum), Offset, | 926 return X86Address(Traits::getEncodedGPR(BaseRegNum), Offset, |
| 927 AssemblerFixup::NoFixup); | 927 AssemblerFixup::NoFixup); |
| 928 } | 928 } |
| 929 | 929 |
| 930 template <typename TraitsType> | 930 template <typename TraitsType> |
| 931 void TargetX86Base<TraitsType>::addProlog(CfgNode *Node) { | 931 void TargetX86Base<TraitsType>::addProlog(CfgNode *Node) { |
| 932 // Stack frame layout: | 932 // Stack frame layout: |
| 933 // | 933 // |
| 934 // +------------------------+ | 934 // +------------------------+ |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1116 | 1116 |
| 1117 emitGetIP(Node); | 1117 emitGetIP(Node); |
| 1118 | 1118 |
| 1119 const VarList &Args = Func->getArgs(); | 1119 const VarList &Args = Func->getArgs(); |
| 1120 size_t InArgsSizeBytes = 0; | 1120 size_t InArgsSizeBytes = 0; |
| 1121 unsigned NumXmmArgs = 0; | 1121 unsigned NumXmmArgs = 0; |
| 1122 unsigned NumGPRArgs = 0; | 1122 unsigned NumGPRArgs = 0; |
| 1123 for (Variable *Arg : Args) { | 1123 for (Variable *Arg : Args) { |
| 1124 // Skip arguments passed in registers. | 1124 // Skip arguments passed in registers. |
| 1125 if (isVectorType(Arg->getType())) { | 1125 if (isVectorType(Arg->getType())) { |
| 1126 if (Traits::getRegisterForXmmArgNum(NumXmmArgs) != RegNumT::NoRegister) { | 1126 if (Traits::getRegisterForXmmArgNum(NumXmmArgs).hasValue()) { |
| 1127 ++NumXmmArgs; | 1127 ++NumXmmArgs; |
| 1128 continue; | 1128 continue; |
| 1129 } | 1129 } |
| 1130 } else if (isScalarFloatingType(Arg->getType())) { | 1130 } else if (isScalarFloatingType(Arg->getType())) { |
| 1131 if (Traits::X86_PASS_SCALAR_FP_IN_XMM && | 1131 if (Traits::X86_PASS_SCALAR_FP_IN_XMM && |
| 1132 Traits::getRegisterForXmmArgNum(NumXmmArgs) != RegNumT::NoRegister) { | 1132 Traits::getRegisterForXmmArgNum(NumXmmArgs).hasValue()) { |
| 1133 ++NumXmmArgs; | 1133 ++NumXmmArgs; |
| 1134 continue; | 1134 continue; |
| 1135 } | 1135 } |
| 1136 } else { | 1136 } else { |
| 1137 assert(isScalarIntegerType(Arg->getType())); | 1137 assert(isScalarIntegerType(Arg->getType())); |
| 1138 if (Traits::getRegisterForGprArgNum(Traits::WordType, NumGPRArgs) != | 1138 if (Traits::getRegisterForGprArgNum(Traits::WordType, NumGPRArgs) |
| 1139 RegNumT::NoRegister) { | 1139 .hasValue()) { |
| 1140 ++NumGPRArgs; | 1140 ++NumGPRArgs; |
| 1141 continue; | 1141 continue; |
| 1142 } | 1142 } |
| 1143 } | 1143 } |
| 1144 // For esp-based frames where the allocas are done outside the prolog, the | 1144 // For esp-based frames where the allocas are done outside the prolog, the |
| 1145 // esp value may not stabilize to its home value until after all the | 1145 // esp value may not stabilize to its home value until after all the |
| 1146 // fixed-size alloca instructions have executed. In this case, a stack | 1146 // fixed-size alloca instructions have executed. In this case, a stack |
| 1147 // adjustment is needed when accessing in-args in order to copy them into | 1147 // adjustment is needed when accessing in-args in order to copy them into |
| 1148 // registers. | 1148 // registers. |
| 1149 size_t StackAdjBytes = 0; | 1149 size_t StackAdjBytes = 0; |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1472 Context.setInsertPoint(Context.getCur()); | 1472 Context.setInsertPoint(Context.getCur()); |
| 1473 | 1473 |
| 1474 for (SizeT i = 0, End = Args.size(); | 1474 for (SizeT i = 0, End = Args.size(); |
| 1475 i < End && (XmmSlotsRemain || GprSlotsRemain); ++i) { | 1475 i < End && (XmmSlotsRemain || GprSlotsRemain); ++i) { |
| 1476 Variable *Arg = Args[i]; | 1476 Variable *Arg = Args[i]; |
| 1477 Type Ty = Arg->getType(); | 1477 Type Ty = Arg->getType(); |
| 1478 Variable *RegisterArg = nullptr; | 1478 Variable *RegisterArg = nullptr; |
| 1479 auto RegNum = RegNumT::NoRegister; | 1479 auto RegNum = RegNumT::NoRegister; |
| 1480 if (isVectorType(Ty)) { | 1480 if (isVectorType(Ty)) { |
| 1481 RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs); | 1481 RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs); |
| 1482 if (RegNum == RegNumT::NoRegister) { | 1482 if (RegNum.hasNoValue()) { |
| 1483 XmmSlotsRemain = false; | 1483 XmmSlotsRemain = false; |
| 1484 continue; | 1484 continue; |
| 1485 } | 1485 } |
| 1486 ++NumXmmArgs; | 1486 ++NumXmmArgs; |
| 1487 RegisterArg = Func->makeVariable(Ty); | 1487 RegisterArg = Func->makeVariable(Ty); |
| 1488 } else if (isScalarFloatingType(Ty)) { | 1488 } else if (isScalarFloatingType(Ty)) { |
| 1489 if (!Traits::X86_PASS_SCALAR_FP_IN_XMM) { | 1489 if (!Traits::X86_PASS_SCALAR_FP_IN_XMM) { |
| 1490 continue; | 1490 continue; |
| 1491 } | 1491 } |
| 1492 RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs); | 1492 RegNum = Traits::getRegisterForXmmArgNum(NumXmmArgs); |
| 1493 if (RegNum == RegNumT::NoRegister) { | 1493 if (RegNum.hasNoValue()) { |
| 1494 XmmSlotsRemain = false; | 1494 XmmSlotsRemain = false; |
| 1495 continue; | 1495 continue; |
| 1496 } | 1496 } |
| 1497 ++NumXmmArgs; | 1497 ++NumXmmArgs; |
| 1498 RegisterArg = Func->makeVariable(Ty); | 1498 RegisterArg = Func->makeVariable(Ty); |
| 1499 } else if (isScalarIntegerType(Ty)) { | 1499 } else if (isScalarIntegerType(Ty)) { |
| 1500 RegNum = Traits::getRegisterForGprArgNum(Ty, NumGprArgs); | 1500 RegNum = Traits::getRegisterForGprArgNum(Ty, NumGprArgs); |
| 1501 if (RegNum == RegNumT::NoRegister) { | 1501 if (RegNum.hasNoValue()) { |
| 1502 GprSlotsRemain = false; | 1502 GprSlotsRemain = false; |
| 1503 continue; | 1503 continue; |
| 1504 } | 1504 } |
| 1505 ++NumGprArgs; | 1505 ++NumGprArgs; |
| 1506 RegisterArg = Func->makeVariable(Ty); | 1506 RegisterArg = Func->makeVariable(Ty); |
| 1507 } | 1507 } |
| 1508 assert(RegNum != RegNumT::NoRegister); | 1508 assert(RegNum.hasValue()); |
| 1509 assert(RegisterArg != nullptr); | 1509 assert(RegisterArg != nullptr); |
| 1510 // Replace Arg in the argument list with the home register. Then generate | 1510 // Replace Arg in the argument list with the home register. Then generate |
| 1511 // an instruction in the prolog to copy the home register to the assigned | 1511 // an instruction in the prolog to copy the home register to the assigned |
| 1512 // location of Arg. | 1512 // location of Arg. |
| 1513 if (BuildDefs::dump()) | 1513 if (BuildDefs::dump()) |
| 1514 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); | 1514 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); |
| 1515 RegisterArg->setRegNum(RegNum); | 1515 RegisterArg->setRegNum(RegNum); |
| 1516 RegisterArg->setIsArg(); | 1516 RegisterArg->setIsArg(); |
| 1517 Arg->setIsArg(false); | 1517 Arg->setIsArg(false); |
| 1518 | 1518 |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2483 OperandList StackArgs, StackArgLocations; | 2483 OperandList StackArgs, StackArgLocations; |
| 2484 uint32_t ParameterAreaSizeBytes = 0; | 2484 uint32_t ParameterAreaSizeBytes = 0; |
| 2485 | 2485 |
| 2486 // Classify each argument operand according to the location where the argument | 2486 // Classify each argument operand according to the location where the argument |
| 2487 // is passed. | 2487 // is passed. |
| 2488 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { | 2488 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { |
| 2489 Operand *Arg = Instr->getArg(i); | 2489 Operand *Arg = Instr->getArg(i); |
| 2490 const Type Ty = Arg->getType(); | 2490 const Type Ty = Arg->getType(); |
| 2491 // The PNaCl ABI requires the width of arguments to be at least 32 bits. | 2491 // The PNaCl ABI requires the width of arguments to be at least 32 bits. |
| 2492 assert(typeWidthInBytes(Ty) >= 4); | 2492 assert(typeWidthInBytes(Ty) >= 4); |
| 2493 if (isVectorType(Ty) && (Traits::getRegisterForXmmArgNum(XmmArgs.size()) != | 2493 if (isVectorType(Ty) && |
| 2494 RegNumT::NoRegister)) { | 2494 (Traits::getRegisterForXmmArgNum(XmmArgs.size()).hasValue())) { |
|
Jim Stichnoth
2016/02/12 18:29:54
I would remove the outer level of parentheses arou
rkotlerimgtec
2016/02/12 22:02:01
Done.
| |
| 2495 XmmArgs.push_back(Arg); | 2495 XmmArgs.push_back(Arg); |
| 2496 } else if (isScalarFloatingType(Ty) && Traits::X86_PASS_SCALAR_FP_IN_XMM && | 2496 } else if (isScalarFloatingType(Ty) && Traits::X86_PASS_SCALAR_FP_IN_XMM && |
| 2497 (Traits::getRegisterForXmmArgNum(XmmArgs.size()) != | 2497 (Traits::getRegisterForXmmArgNum(XmmArgs.size()).hasValue())) { |
| 2498 RegNumT::NoRegister)) { | |
| 2499 XmmArgs.push_back(Arg); | 2498 XmmArgs.push_back(Arg); |
| 2500 } else if (isScalarIntegerType(Ty) && | 2499 } else if (isScalarIntegerType(Ty) && |
| 2501 (Traits::getRegisterForGprArgNum(Ty, GprArgs.size()) != | 2500 (Traits::getRegisterForGprArgNum(Ty, GprArgs.size()) |
| 2502 RegNumT::NoRegister)) { | 2501 .hasValue())) { |
| 2503 GprArgs.emplace_back(Ty, Arg); | 2502 GprArgs.emplace_back(Ty, Arg); |
| 2504 } else { | 2503 } else { |
| 2505 // Place on stack. | 2504 // Place on stack. |
| 2506 StackArgs.push_back(Arg); | 2505 StackArgs.push_back(Arg); |
| 2507 if (isVectorType(Arg->getType())) { | 2506 if (isVectorType(Arg->getType())) { |
| 2508 ParameterAreaSizeBytes = | 2507 ParameterAreaSizeBytes = |
| 2509 Traits::applyStackAlignment(ParameterAreaSizeBytes); | 2508 Traits::applyStackAlignment(ParameterAreaSizeBytes); |
| 2510 } | 2509 } |
| 2511 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType); | 2510 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType); |
| 2512 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes); | 2511 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes); |
| (...skipping 4093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6606 _psrl(Reg, Ctx->getConstantInt8(1)); | 6605 _psrl(Reg, Ctx->getConstantInt8(1)); |
| 6607 return Reg; | 6606 return Reg; |
| 6608 } | 6607 } |
| 6609 | 6608 |
| 6610 template <typename TraitsType> | 6609 template <typename TraitsType> |
| 6611 typename TargetX86Base<TraitsType>::X86OperandMem * | 6610 typename TargetX86Base<TraitsType>::X86OperandMem * |
| 6612 TargetX86Base<TraitsType>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot, | 6611 TargetX86Base<TraitsType>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot, |
| 6613 uint32_t Offset) { | 6612 uint32_t Offset) { |
| 6614 // Ensure that Loc is a stack slot. | 6613 // Ensure that Loc is a stack slot. |
| 6615 assert(Slot->mustNotHaveReg()); | 6614 assert(Slot->mustNotHaveReg()); |
| 6616 assert(Slot->getRegNum() == RegNumT::NoRegister); | 6615 assert(Slot->getRegNum().hasNoValue()); |
| 6617 // Compute the location of Loc in memory. | 6616 // Compute the location of Loc in memory. |
| 6618 // TODO(wala,stichnot): lea should not | 6617 // TODO(wala,stichnot): lea should not |
| 6619 // be required. The address of the stack slot is known at compile time | 6618 // be required. The address of the stack slot is known at compile time |
| 6620 // (although not until after addProlog()). | 6619 // (although not until after addProlog()). |
| 6621 constexpr Type PointerType = IceType_i32; | 6620 constexpr Type PointerType = IceType_i32; |
| 6622 Variable *Loc = makeReg(PointerType); | 6621 Variable *Loc = makeReg(PointerType); |
| 6623 _lea(Loc, Slot); | 6622 _lea(Loc, Slot); |
| 6624 Constant *ConstantOffset = Ctx->getConstantInt32(Offset); | 6623 Constant *ConstantOffset = Ctx->getConstantInt32(Offset); |
| 6625 return X86OperandMem::create(Func, Ty, Loc, ConstantOffset); | 6624 return X86OperandMem::create(Func, Ty, Loc, ConstantOffset); |
| 6626 } | 6625 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6706 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); | 6705 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); |
| 6707 const Type Ty = From->getType(); | 6706 const Type Ty = From->getType(); |
| 6708 // Assert that a physical register is allowed. To date, all calls to | 6707 // Assert that a physical register is allowed. To date, all calls to |
| 6709 // legalize() allow a physical register. If a physical register needs to be | 6708 // legalize() allow a physical register. If a physical register needs to be |
| 6710 // explicitly disallowed, then new code will need to be written to force a | 6709 // explicitly disallowed, then new code will need to be written to force a |
| 6711 // spill. | 6710 // spill. |
| 6712 assert(Allowed & Legal_Reg); | 6711 assert(Allowed & Legal_Reg); |
| 6713 // If we're asking for a specific physical register, make sure we're not | 6712 // If we're asking for a specific physical register, make sure we're not |
| 6714 // allowing any other operand kinds. (This could be future work, e.g. allow | 6713 // allowing any other operand kinds. (This could be future work, e.g. allow |
| 6715 // the shl shift amount to be either an immediate or in ecx.) | 6714 // the shl shift amount to be either an immediate or in ecx.) |
| 6716 assert(RegNum == RegNumT::NoRegister || Allowed == Legal_Reg); | 6715 assert(RegNum.hasNoValue() || Allowed == Legal_Reg); |
| 6717 | 6716 |
| 6718 // Substitute with an available infinite-weight variable if possible. Only do | 6717 // Substitute with an available infinite-weight variable if possible. Only do |
| 6719 // this when we are not asking for a specific register, and when the | 6718 // this when we are not asking for a specific register, and when the |
| 6720 // substitution is not locked to a specific register, and when the types | 6719 // substitution is not locked to a specific register, and when the types |
| 6721 // match, in order to capture the vast majority of opportunities and avoid | 6720 // match, in order to capture the vast majority of opportunities and avoid |
| 6722 // corner cases in the lowering. | 6721 // corner cases in the lowering. |
| 6723 if (RegNum == RegNumT::NoRegister) { | 6722 if (RegNum.hasNoValue()) { |
| 6724 if (Variable *Subst = getContext().availabilityGet(From)) { | 6723 if (Variable *Subst = getContext().availabilityGet(From)) { |
| 6725 // At this point we know there is a potential substitution available. | 6724 // At this point we know there is a potential substitution available. |
| 6726 if (Subst->mustHaveReg() && !Subst->hasReg()) { | 6725 if (Subst->mustHaveReg() && !Subst->hasReg()) { |
| 6727 // At this point we know the substitution will have a register. | 6726 // At this point we know the substitution will have a register. |
| 6728 if (From->getType() == Subst->getType()) { | 6727 if (From->getType() == Subst->getType()) { |
| 6729 // At this point we know the substitution's register is compatible. | 6728 // At this point we know the substitution's register is compatible. |
| 6730 return Subst; | 6729 return Subst; |
| 6731 } | 6730 } |
| 6732 } | 6731 } |
| 6733 } | 6732 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6774 return From; | 6773 return From; |
| 6775 Const = llvm::cast<Constant>(From); | 6774 Const = llvm::cast<Constant>(From); |
| 6776 } | 6775 } |
| 6777 // There should be no constants of vector type (other than undef). | 6776 // There should be no constants of vector type (other than undef). |
| 6778 assert(!isVectorType(Ty)); | 6777 assert(!isVectorType(Ty)); |
| 6779 | 6778 |
| 6780 // If the operand is a 64 bit constant integer we need to legalize it to a | 6779 // If the operand is a 64 bit constant integer we need to legalize it to a |
| 6781 // register in x86-64. | 6780 // register in x86-64. |
| 6782 if (Traits::Is64Bit) { | 6781 if (Traits::Is64Bit) { |
| 6783 if (llvm::isa<ConstantInteger64>(Const)) { | 6782 if (llvm::isa<ConstantInteger64>(Const)) { |
| 6784 if (RegNum != RegNumT::NoRegister) { | 6783 if (RegNum.hasValue()) { |
| 6785 assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum); | 6784 assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum); |
| 6786 } | 6785 } |
| 6787 return copyToReg(Const, RegNum); | 6786 return copyToReg(Const, RegNum); |
| 6788 } | 6787 } |
| 6789 } | 6788 } |
| 6790 | 6789 |
| 6791 // If the operand is an 32 bit constant integer, we should check whether we | 6790 // If the operand is an 32 bit constant integer, we should check whether we |
| 6792 // need to randomize it or pool it. | 6791 // need to randomize it or pool it. |
| 6793 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) { | 6792 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) { |
| 6794 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); | 6793 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6857 if (MustRematerialize) { | 6856 if (MustRematerialize) { |
| 6858 assert(Ty == IceType_i32); | 6857 assert(Ty == IceType_i32); |
| 6859 Variable *NewVar = makeReg(Ty, RegNum); | 6858 Variable *NewVar = makeReg(Ty, RegNum); |
| 6860 // Since Var is rematerializable, the offset will be added when the lea is | 6859 // Since Var is rematerializable, the offset will be added when the lea is |
| 6861 // emitted. | 6860 // emitted. |
| 6862 constexpr Constant *NoOffset = nullptr; | 6861 constexpr Constant *NoOffset = nullptr; |
| 6863 auto *Mem = X86OperandMem::create(Func, Ty, Var, NoOffset); | 6862 auto *Mem = X86OperandMem::create(Func, Ty, Var, NoOffset); |
| 6864 _lea(NewVar, Mem); | 6863 _lea(NewVar, Mem); |
| 6865 From = NewVar; | 6864 From = NewVar; |
| 6866 } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 6865 } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
| 6867 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) { | 6866 (RegNum.hasValue() && RegNum != Var->getRegNum())) { |
| 6868 From = copyToReg(From, RegNum); | 6867 From = copyToReg(From, RegNum); |
| 6869 } | 6868 } |
| 6870 return From; | 6869 return From; |
| 6871 } | 6870 } |
| 6872 | 6871 |
| 6873 llvm::report_fatal_error("Unhandled operand kind in legalize()"); | 6872 llvm::report_fatal_error("Unhandled operand kind in legalize()"); |
| 6874 return From; | 6873 return From; |
| 6875 } | 6874 } |
| 6876 | 6875 |
| 6877 /// Provide a trivial wrapper to legalize() for this common usage. | 6876 /// Provide a trivial wrapper to legalize() for this common usage. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6960 // randomization/pooling. | 6959 // randomization/pooling. |
| 6961 return llvm::cast<X86OperandMem>(DoLegalize ? legalize(Mem) | 6960 return llvm::cast<X86OperandMem>(DoLegalize ? legalize(Mem) |
| 6962 : randomizeOrPoolImmediate(Mem)); | 6961 : randomizeOrPoolImmediate(Mem)); |
| 6963 } | 6962 } |
| 6964 | 6963 |
| 6965 template <typename TraitsType> | 6964 template <typename TraitsType> |
| 6966 Variable *TargetX86Base<TraitsType>::makeReg(Type Type, RegNumT RegNum) { | 6965 Variable *TargetX86Base<TraitsType>::makeReg(Type Type, RegNumT RegNum) { |
| 6967 // There aren't any 64-bit integer registers for x86-32. | 6966 // There aren't any 64-bit integer registers for x86-32. |
| 6968 assert(Traits::Is64Bit || Type != IceType_i64); | 6967 assert(Traits::Is64Bit || Type != IceType_i64); |
| 6969 Variable *Reg = Func->makeVariable(Type); | 6968 Variable *Reg = Func->makeVariable(Type); |
| 6970 if (RegNum == RegNumT::NoRegister) | 6969 if (RegNum.hasNoValue()) |
| 6971 Reg->setMustHaveReg(); | 6970 Reg->setMustHaveReg(); |
| 6972 else | 6971 else |
| 6973 Reg->setRegNum(RegNum); | 6972 Reg->setRegNum(RegNum); |
| 6974 return Reg; | 6973 return Reg; |
| 6975 } | 6974 } |
| 6976 | 6975 |
| 6977 template <typename TraitsType> | 6976 template <typename TraitsType> |
| 6978 const Type TargetX86Base<TraitsType>::TypeForSize[] = { | 6977 const Type TargetX86Base<TraitsType>::TypeForSize[] = { |
| 6979 IceType_i8, IceType_i16, IceType_i32, IceType_f64, IceType_v16i8}; | 6978 IceType_i8, IceType_i16, IceType_i32, IceType_f64, IceType_v16i8}; |
| 6980 template <typename TraitsType> | 6979 template <typename TraitsType> |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7234 // TO: | 7233 // TO: |
| 7235 // insert: mov $label, RegTemp | 7234 // insert: mov $label, RegTemp |
| 7236 // insert: lea [base, RegTemp], RegTemp | 7235 // insert: lea [base, RegTemp], RegTemp |
| 7237 // =>[RegTemp, index, shift] | 7236 // =>[RegTemp, index, shift] |
| 7238 | 7237 |
| 7239 // Memory operand should never exist as source operands in phi lowering | 7238 // Memory operand should never exist as source operands in phi lowering |
| 7240 // assignments, so there is no need to reuse any registers here. For | 7239 // assignments, so there is no need to reuse any registers here. For |
| 7241 // phi lowering, we should not ask for new physical registers in | 7240 // phi lowering, we should not ask for new physical registers in |
| 7242 // general. However, if we do meet Memory Operand during phi lowering, | 7241 // general. However, if we do meet Memory Operand during phi lowering, |
| 7243 // we should not blind or pool the immediates for now. | 7242 // we should not blind or pool the immediates for now. |
| 7244 if (RegNum != RegNumT::NoRegister) | 7243 if (RegNum.hasValue()) |
| 7245 return MemOperand; | 7244 return MemOperand; |
| 7246 Variable *RegTemp = makeReg(IceType_i32); | 7245 Variable *RegTemp = makeReg(IceType_i32); |
| 7247 IceString Label; | 7246 IceString Label; |
| 7248 llvm::raw_string_ostream Label_stream(Label); | 7247 llvm::raw_string_ostream Label_stream(Label); |
| 7249 MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx); | 7248 MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx); |
| 7250 MemOperand->getOffset()->setShouldBePooled(true); | 7249 MemOperand->getOffset()->setShouldBePooled(true); |
| 7251 constexpr RelocOffsetT SymOffset = 0; | 7250 constexpr RelocOffsetT SymOffset = 0; |
| 7252 constexpr bool SuppressMangling = true; | 7251 constexpr bool SuppressMangling = true; |
| 7253 Constant *Symbol = | 7252 Constant *Symbol = |
| 7254 Ctx->getConstantSym(SymOffset, Label_stream.str(), SuppressMangling); | 7253 Ctx->getConstantSym(SymOffset, Label_stream.str(), SuppressMangling); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7419 emitGlobal(*Var, SectionSuffix); | 7418 emitGlobal(*Var, SectionSuffix); |
| 7420 } | 7419 } |
| 7421 } | 7420 } |
| 7422 } break; | 7421 } break; |
| 7423 } | 7422 } |
| 7424 } | 7423 } |
| 7425 } // end of namespace X86NAMESPACE | 7424 } // end of namespace X86NAMESPACE |
| 7426 } // end of namespace Ice | 7425 } // end of namespace Ice |
| 7427 | 7426 |
| 7428 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 7427 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
| OLD | NEW |