Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1691193002: Subzero: Prototype to make use of RegNumT::No Register more concise (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: changes suggested by stichnot Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 bool GprSlotsRemain = true; 1469 bool GprSlotsRemain = true;
1470 1470
1471 Context.init(Func->getEntryNode()); 1471 Context.init(Func->getEntryNode());
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 RegNumT RegNum;
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
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()) {
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()).hasValue()) {
2502 RegNumT::NoRegister)) {
2503 GprArgs.emplace_back(Ty, Arg); 2501 GprArgs.emplace_back(Ty, Arg);
2504 } else { 2502 } else {
2505 // Place on stack. 2503 // Place on stack.
2506 StackArgs.push_back(Arg); 2504 StackArgs.push_back(Arg);
2507 if (isVectorType(Arg->getType())) { 2505 if (isVectorType(Arg->getType())) {
2508 ParameterAreaSizeBytes = 2506 ParameterAreaSizeBytes =
2509 Traits::applyStackAlignment(ParameterAreaSizeBytes); 2507 Traits::applyStackAlignment(ParameterAreaSizeBytes);
2510 } 2508 }
2511 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType); 2509 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType);
2512 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes); 2510 Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes);
(...skipping 4093 matching lines...) Expand 10 before | Expand all | Expand 10 after
6606 _psrl(Reg, Ctx->getConstantInt8(1)); 6604 _psrl(Reg, Ctx->getConstantInt8(1));
6607 return Reg; 6605 return Reg;
6608 } 6606 }
6609 6607
6610 template <typename TraitsType> 6608 template <typename TraitsType>
6611 typename TargetX86Base<TraitsType>::X86OperandMem * 6609 typename TargetX86Base<TraitsType>::X86OperandMem *
6612 TargetX86Base<TraitsType>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot, 6610 TargetX86Base<TraitsType>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
6613 uint32_t Offset) { 6611 uint32_t Offset) {
6614 // Ensure that Loc is a stack slot. 6612 // Ensure that Loc is a stack slot.
6615 assert(Slot->mustNotHaveReg()); 6613 assert(Slot->mustNotHaveReg());
6616 assert(Slot->getRegNum() == RegNumT::NoRegister); 6614 assert(Slot->getRegNum().hasNoValue());
6617 // Compute the location of Loc in memory. 6615 // Compute the location of Loc in memory.
6618 // TODO(wala,stichnot): lea should not 6616 // TODO(wala,stichnot): lea should not
6619 // be required. The address of the stack slot is known at compile time 6617 // be required. The address of the stack slot is known at compile time
6620 // (although not until after addProlog()). 6618 // (although not until after addProlog()).
6621 constexpr Type PointerType = IceType_i32; 6619 constexpr Type PointerType = IceType_i32;
6622 Variable *Loc = makeReg(PointerType); 6620 Variable *Loc = makeReg(PointerType);
6623 _lea(Loc, Slot); 6621 _lea(Loc, Slot);
6624 Constant *ConstantOffset = Ctx->getConstantInt32(Offset); 6622 Constant *ConstantOffset = Ctx->getConstantInt32(Offset);
6625 return X86OperandMem::create(Func, Ty, Loc, ConstantOffset); 6623 return X86OperandMem::create(Func, Ty, Loc, ConstantOffset);
6626 } 6624 }
6627 6625
6628 /// Lowering helper to copy a scalar integer source operand into some 8-bit GPR. 6626 /// Lowering helper to copy a scalar integer source operand into some 8-bit GPR.
6629 /// Src is assumed to already be legalized. If the source operand is known to 6627 /// Src is assumed to already be legalized. If the source operand is known to
6630 /// be a memory or immediate operand, a simple mov will suffice. But if the 6628 /// be a memory or immediate operand, a simple mov will suffice. But if the
6631 /// source operand can be a physical register, then it must first be copied into 6629 /// source operand can be a physical register, then it must first be copied into
6632 /// a physical register that is truncable to 8-bit, then truncated into a 6630 /// a physical register that is truncable to 8-bit, then truncated into a
6633 /// physical register that can receive a truncation, and finally copied into the 6631 /// physical register that can receive a truncation, and finally copied into the
6634 /// result 8-bit register (which in general can be any 8-bit register). For 6632 /// result 8-bit register (which in general can be any 8-bit register). For
6635 /// example, moving %ebp into %ah may be accomplished as: 6633 /// example, moving %ebp into %ah may be accomplished as:
6636 /// movl %ebp, %edx 6634 /// movl %ebp, %edx
6637 /// mov_trunc %edx, %dl // this redundant assignment is ultimately elided 6635 /// mov_trunc %edx, %dl // this redundant assignment is ultimately elided
6638 /// movb %dl, %ah 6636 /// movb %dl, %ah
6639 /// On the other hand, moving a memory or immediate operand into ah: 6637 /// On the other hand, moving a memory or immediate operand into ah:
6640 /// movb 4(%ebp), %ah 6638 /// movb 4(%ebp), %ah
6641 /// movb $my_imm, %ah 6639 /// movb $my_imm, %ah
6642 /// 6640 ///
6643 /// Note #1. On a 64-bit target, the "movb 4(%ebp), %ah" is likely not 6641 /// Note #1. On a 64-bit target, the "movb 4(%ebp), %ah" is likely not
6644 /// encodable, so RegNum=Reg_ah should NOT be given as an argument. Instead, 6642 /// encodable, so RegNum=Reg_ah should NOT be given as an argument. Instead,
6645 /// use RegNum=NoRegister and then let the caller do a separate copy into 6643 /// use RegNum=RegNumT() and then let the caller do a separate copy into
6646 /// Reg_ah. 6644 /// Reg_ah.
6647 /// 6645 ///
6648 /// Note #2. ConstantRelocatable operands are also put through this process 6646 /// Note #2. ConstantRelocatable operands are also put through this process
6649 /// (not truncated directly) because our ELF emitter does R_386_32 relocations 6647 /// (not truncated directly) because our ELF emitter does R_386_32 relocations
6650 /// but not R_386_8 relocations. 6648 /// but not R_386_8 relocations.
6651 /// 6649 ///
6652 /// Note #3. If Src is a Variable, the result will be an infinite-weight i8 6650 /// Note #3. If Src is a Variable, the result will be an infinite-weight i8
6653 /// Variable with the RCX86_IsTrunc8Rcvr register class. As such, this helper 6651 /// Variable with the RCX86_IsTrunc8Rcvr register class. As such, this helper
6654 /// is a convenient way to prevent ah/bh/ch/dh from being an (invalid) argument 6652 /// is a convenient way to prevent ah/bh/ch/dh from being an (invalid) argument
6655 /// to the pinsrb instruction. 6653 /// to the pinsrb instruction.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
6706 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); 6704 const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi();
6707 const Type Ty = From->getType(); 6705 const Type Ty = From->getType();
6708 // Assert that a physical register is allowed. To date, all calls to 6706 // 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 6707 // 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 6708 // explicitly disallowed, then new code will need to be written to force a
6711 // spill. 6709 // spill.
6712 assert(Allowed & Legal_Reg); 6710 assert(Allowed & Legal_Reg);
6713 // If we're asking for a specific physical register, make sure we're not 6711 // 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 6712 // 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.) 6713 // the shl shift amount to be either an immediate or in ecx.)
6716 assert(RegNum == RegNumT::NoRegister || Allowed == Legal_Reg); 6714 assert(RegNum.hasNoValue() || Allowed == Legal_Reg);
6717 6715
6718 // Substitute with an available infinite-weight variable if possible. Only do 6716 // 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 6717 // 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 6718 // 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 6719 // match, in order to capture the vast majority of opportunities and avoid
6722 // corner cases in the lowering. 6720 // corner cases in the lowering.
6723 if (RegNum == RegNumT::NoRegister) { 6721 if (RegNum.hasNoValue()) {
6724 if (Variable *Subst = getContext().availabilityGet(From)) { 6722 if (Variable *Subst = getContext().availabilityGet(From)) {
6725 // At this point we know there is a potential substitution available. 6723 // At this point we know there is a potential substitution available.
6726 if (Subst->mustHaveReg() && !Subst->hasReg()) { 6724 if (Subst->mustHaveReg() && !Subst->hasReg()) {
6727 // At this point we know the substitution will have a register. 6725 // At this point we know the substitution will have a register.
6728 if (From->getType() == Subst->getType()) { 6726 if (From->getType() == Subst->getType()) {
6729 // At this point we know the substitution's register is compatible. 6727 // At this point we know the substitution's register is compatible.
6730 return Subst; 6728 return Subst;
6731 } 6729 }
6732 } 6730 }
6733 } 6731 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
6774 return From; 6772 return From;
6775 Const = llvm::cast<Constant>(From); 6773 Const = llvm::cast<Constant>(From);
6776 } 6774 }
6777 // There should be no constants of vector type (other than undef). 6775 // There should be no constants of vector type (other than undef).
6778 assert(!isVectorType(Ty)); 6776 assert(!isVectorType(Ty));
6779 6777
6780 // If the operand is a 64 bit constant integer we need to legalize it to a 6778 // If the operand is a 64 bit constant integer we need to legalize it to a
6781 // register in x86-64. 6779 // register in x86-64.
6782 if (Traits::Is64Bit) { 6780 if (Traits::Is64Bit) {
6783 if (llvm::isa<ConstantInteger64>(Const)) { 6781 if (llvm::isa<ConstantInteger64>(Const)) {
6784 if (RegNum != RegNumT::NoRegister) { 6782 if (RegNum.hasValue()) {
6785 assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum); 6783 assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum);
6786 } 6784 }
6787 return copyToReg(Const, RegNum); 6785 return copyToReg(Const, RegNum);
6788 } 6786 }
6789 } 6787 }
6790 6788
6791 // If the operand is an 32 bit constant integer, we should check whether we 6789 // If the operand is an 32 bit constant integer, we should check whether we
6792 // need to randomize it or pool it. 6790 // need to randomize it or pool it.
6793 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) { 6791 if (auto *C = llvm::dyn_cast<ConstantInteger32>(Const)) {
6794 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum); 6792 Operand *NewConst = randomizeOrPoolImmediate(C, RegNum);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
6857 if (MustRematerialize) { 6855 if (MustRematerialize) {
6858 assert(Ty == IceType_i32); 6856 assert(Ty == IceType_i32);
6859 Variable *NewVar = makeReg(Ty, RegNum); 6857 Variable *NewVar = makeReg(Ty, RegNum);
6860 // Since Var is rematerializable, the offset will be added when the lea is 6858 // Since Var is rematerializable, the offset will be added when the lea is
6861 // emitted. 6859 // emitted.
6862 constexpr Constant *NoOffset = nullptr; 6860 constexpr Constant *NoOffset = nullptr;
6863 auto *Mem = X86OperandMem::create(Func, Ty, Var, NoOffset); 6861 auto *Mem = X86OperandMem::create(Func, Ty, Var, NoOffset);
6864 _lea(NewVar, Mem); 6862 _lea(NewVar, Mem);
6865 From = NewVar; 6863 From = NewVar;
6866 } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || 6864 } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
6867 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) { 6865 (RegNum.hasValue() && RegNum != Var->getRegNum())) {
6868 From = copyToReg(From, RegNum); 6866 From = copyToReg(From, RegNum);
6869 } 6867 }
6870 return From; 6868 return From;
6871 } 6869 }
6872 6870
6873 llvm::report_fatal_error("Unhandled operand kind in legalize()"); 6871 llvm::report_fatal_error("Unhandled operand kind in legalize()");
6874 return From; 6872 return From;
6875 } 6873 }
6876 6874
6877 /// Provide a trivial wrapper to legalize() for this common usage. 6875 /// Provide a trivial wrapper to legalize() for this common usage.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
6960 // randomization/pooling. 6958 // randomization/pooling.
6961 return llvm::cast<X86OperandMem>(DoLegalize ? legalize(Mem) 6959 return llvm::cast<X86OperandMem>(DoLegalize ? legalize(Mem)
6962 : randomizeOrPoolImmediate(Mem)); 6960 : randomizeOrPoolImmediate(Mem));
6963 } 6961 }
6964 6962
6965 template <typename TraitsType> 6963 template <typename TraitsType>
6966 Variable *TargetX86Base<TraitsType>::makeReg(Type Type, RegNumT RegNum) { 6964 Variable *TargetX86Base<TraitsType>::makeReg(Type Type, RegNumT RegNum) {
6967 // There aren't any 64-bit integer registers for x86-32. 6965 // There aren't any 64-bit integer registers for x86-32.
6968 assert(Traits::Is64Bit || Type != IceType_i64); 6966 assert(Traits::Is64Bit || Type != IceType_i64);
6969 Variable *Reg = Func->makeVariable(Type); 6967 Variable *Reg = Func->makeVariable(Type);
6970 if (RegNum == RegNumT::NoRegister) 6968 if (RegNum.hasValue())
6969 Reg->setRegNum(RegNum);
6970 else
6971 Reg->setMustHaveReg(); 6971 Reg->setMustHaveReg();
6972 else
6973 Reg->setRegNum(RegNum);
6974 return Reg; 6972 return Reg;
6975 } 6973 }
6976 6974
6977 template <typename TraitsType> 6975 template <typename TraitsType>
6978 const Type TargetX86Base<TraitsType>::TypeForSize[] = { 6976 const Type TargetX86Base<TraitsType>::TypeForSize[] = {
6979 IceType_i8, IceType_i16, IceType_i32, IceType_f64, IceType_v16i8}; 6977 IceType_i8, IceType_i16, IceType_i32, IceType_f64, IceType_v16i8};
6980 template <typename TraitsType> 6978 template <typename TraitsType>
6981 Type TargetX86Base<TraitsType>::largestTypeInSize(uint32_t Size, 6979 Type TargetX86Base<TraitsType>::largestTypeInSize(uint32_t Size,
6982 uint32_t MaxSize) { 6980 uint32_t MaxSize) {
6983 assert(Size != 0); 6981 assert(Size != 0);
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
7234 // TO: 7232 // TO:
7235 // insert: mov $label, RegTemp 7233 // insert: mov $label, RegTemp
7236 // insert: lea [base, RegTemp], RegTemp 7234 // insert: lea [base, RegTemp], RegTemp
7237 // =>[RegTemp, index, shift] 7235 // =>[RegTemp, index, shift]
7238 7236
7239 // Memory operand should never exist as source operands in phi lowering 7237 // Memory operand should never exist as source operands in phi lowering
7240 // assignments, so there is no need to reuse any registers here. For 7238 // assignments, so there is no need to reuse any registers here. For
7241 // phi lowering, we should not ask for new physical registers in 7239 // phi lowering, we should not ask for new physical registers in
7242 // general. However, if we do meet Memory Operand during phi lowering, 7240 // general. However, if we do meet Memory Operand during phi lowering,
7243 // we should not blind or pool the immediates for now. 7241 // we should not blind or pool the immediates for now.
7244 if (RegNum != RegNumT::NoRegister) 7242 if (RegNum.hasValue())
7245 return MemOperand; 7243 return MemOperand;
7246 Variable *RegTemp = makeReg(IceType_i32); 7244 Variable *RegTemp = makeReg(IceType_i32);
7247 IceString Label; 7245 IceString Label;
7248 llvm::raw_string_ostream Label_stream(Label); 7246 llvm::raw_string_ostream Label_stream(Label);
7249 MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx); 7247 MemOperand->getOffset()->emitPoolLabel(Label_stream, Ctx);
7250 MemOperand->getOffset()->setShouldBePooled(true); 7248 MemOperand->getOffset()->setShouldBePooled(true);
7251 constexpr RelocOffsetT SymOffset = 0; 7249 constexpr RelocOffsetT SymOffset = 0;
7252 constexpr bool SuppressMangling = true; 7250 constexpr bool SuppressMangling = true;
7253 Constant *Symbol = 7251 Constant *Symbol =
7254 Ctx->getConstantSym(SymOffset, Label_stream.str(), SuppressMangling); 7252 Ctx->getConstantSym(SymOffset, Label_stream.str(), SuppressMangling);
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
7419 emitGlobal(*Var, SectionSuffix); 7417 emitGlobal(*Var, SectionSuffix);
7420 } 7418 }
7421 } 7419 }
7422 } break; 7420 } break;
7423 } 7421 }
7424 } 7422 }
7425 } // end of namespace X86NAMESPACE 7423 } // end of namespace X86NAMESPACE
7426 } // end of namespace Ice 7424 } // end of namespace Ice
7427 7425
7428 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H 7426 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698