 Chromium Code Reviews
 Chromium Code Reviews Issue 2148593003:
  [Subzero][MIPS32] Implement post lower legalizer for MIPS32  (Closed) 
  Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
    
  
    Issue 2148593003:
  [Subzero][MIPS32] Implement post lower legalizer for MIPS32  (Closed) 
  Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master| OLD | NEW | 
|---|---|
| 1 // | 1 // | 
| 2 // The Subzero Code Generator | 2 // The Subzero Code Generator | 
| 3 // | 3 // | 
| 4 // This file is distributed under the University of Illinois Open Source | 4 // This file is distributed under the University of Illinois Open Source | 
| 5 // License. See LICENSE.TXT for details. | 5 // License. See LICENSE.TXT for details. | 
| 6 // | 6 // | 
| 7 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// | 
| 8 /// | 8 /// | 
| 9 /// \file | 9 /// \file | 
| 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost | 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost | 
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 Func->advancedPhiLowering(); | 288 Func->advancedPhiLowering(); | 
| 289 Func->dump("After advanced Phi lowering"); | 289 Func->dump("After advanced Phi lowering"); | 
| 290 } | 290 } | 
| 291 | 291 | 
| 292 // Stack frame mapping. | 292 // Stack frame mapping. | 
| 293 Func->genFrame(); | 293 Func->genFrame(); | 
| 294 if (Func->hasError()) | 294 if (Func->hasError()) | 
| 295 return; | 295 return; | 
| 296 Func->dump("After stack frame mapping"); | 296 Func->dump("After stack frame mapping"); | 
| 297 | 297 | 
| 298 postLowerLegalization(); | |
| 299 if (Func->hasError()) | |
| 300 return; | |
| 301 Func->dump("After postLowerLegalization"); | |
| 302 | |
| 298 Func->contractEmptyNodes(); | 303 Func->contractEmptyNodes(); | 
| 299 Func->reorderNodes(); | 304 Func->reorderNodes(); | 
| 300 | 305 | 
| 301 // Branch optimization. This needs to be done just before code emission. In | 306 // Branch optimization. This needs to be done just before code emission. In | 
| 302 // particular, no transformations that insert or reorder CfgNodes should be | 307 // particular, no transformations that insert or reorder CfgNodes should be | 
| 303 // done after branch optimization. We go ahead and do it before nop insertion | 308 // done after branch optimization. We go ahead and do it before nop insertion | 
| 304 // to reduce the amount of work needed for searching for opportunities. | 309 // to reduce the amount of work needed for searching for opportunities. | 
| 305 Func->doBranchOpt(); | 310 Func->doBranchOpt(); | 
| 306 Func->dump("After branch optimization"); | 311 Func->dump("After branch optimization"); | 
| 307 | 312 | 
| (...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 982 } | 987 } | 
| 983 } | 988 } | 
| 984 | 989 | 
| 985 if (TotalStackSizeBytes) { | 990 if (TotalStackSizeBytes) { | 
| 986 _addiu(SP, SP, TotalStackSizeBytes); | 991 _addiu(SP, SP, TotalStackSizeBytes); | 
| 987 } | 992 } | 
| 988 | 993 | 
| 989 return; | 994 return; | 
| 990 } | 995 } | 
| 991 | 996 | 
| 997 Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister( | |
| 998 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { | |
| 999 // Legalize will likely need a lui/ori combination, but if the top bits are | |
| 1000 // all 0 from negating the offset and subtracting, we could use that instead. | |
| 1001 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; | |
| 1002 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); | |
| 1003 if (ShouldSub) { | |
| 1004 Variable *OffsetVal = | |
| 1005 Target->legalizeToReg(Target->Ctx->getConstantInt32(-Offset)); | |
| 1006 Target->_sub(ScratchReg, Base, OffsetVal); | |
| 1007 } else { | |
| 1008 Target->_addiu(ScratchReg, Base, Offset); | |
| 1009 } | |
| 1010 | |
| 1011 return ScratchReg; | |
| 1012 } | |
| 1013 | |
| 1014 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { | |
| 1015 Variable *Dest = MovInstr->getDest(); | |
| 1016 assert(Dest != nullptr); | |
| 1017 const Type DestTy = Dest->getType(); | |
| 
Jim Stichnoth
2016/07/14 21:49:59
If DestTy and SrcTy have no other uses, this would
 | |
| 1018 (void)DestTy; | |
| 1019 assert(DestTy != IceType_i64); | |
| 1020 | |
| 1021 Operand *Src = MovInstr->getSrc(0); | |
| 1022 const Type SrcTy = Src->getType(); | |
| 1023 (void)SrcTy; | |
| 1024 assert(SrcTy != IceType_i64); | |
| 1025 | |
| 1026 if (MovInstr->isMultiDest() || MovInstr->isMultiSource()) | |
| 1027 return; | |
| 1028 | |
| 1029 bool Legalized = false; | |
| 1030 if (Dest->hasReg()) { | |
| 1031 if (auto *Var = llvm::dyn_cast<Variable>(Src)) { | |
| 1032 if (Var->isRematerializable()) { | |
| 1033 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). | |
| 1034 | |
| 1035 // ExtraOffset is only needed for frame-pointer based frames as we have | |
| 1036 // to account for spill storage. | |
| 1037 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg()) | |
| 1038 ? Target->getFrameFixedAllocaOffset() | |
| 1039 : 0; | |
| 1040 | |
| 1041 const int32_t Offset = Var->getStackOffset() + ExtraOffset; | |
| 1042 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); | |
| 1043 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); | |
| 1044 Target->_mov(Dest, T); | |
| 1045 Legalized = true; | |
| 1046 } else if (!Var->hasReg()) { | |
| 1047 UnimplementedError(getFlags()); | |
| 1048 return; | |
| 1049 } | |
| 1050 } | |
| 1051 } else { | |
| 1052 UnimplementedError(getFlags()); | |
| 1053 return; | |
| 1054 } | |
| 1055 | |
| 1056 if (Legalized) { | |
| 1057 if (MovInstr->isDestRedefined()) { | |
| 1058 Target->_set_dest_redefined(); | |
| 1059 } | |
| 1060 MovInstr->setDeleted(); | |
| 1061 } | |
| 1062 } | |
| 1063 | |
| 1064 void TargetMIPS32::postLowerLegalization() { | |
| 1065 Func->dump("Before postLowerLegalization"); | |
| 1066 assert(hasComputedFrame()); | |
| 1067 for (CfgNode *Node : Func->getNodes()) { | |
| 1068 Context.init(Node); | |
| 1069 PostLoweringLegalizer Legalizer(this); | |
| 1070 while (!Context.atEnd()) { | |
| 1071 PostIncrLoweringContext PostIncrement(Context); | |
| 1072 Inst *CurInstr = iteratorToInst(Context.getCur()); | |
| 1073 | |
| 1074 // TODO(sagar.thakur): Add remaining cases of legalization. | |
| 1075 | |
| 1076 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { | |
| 1077 Legalizer.legalizeMov(MovInstr); | |
| 1078 } | |
| 1079 } | |
| 1080 } | |
| 1081 } | |
| 1082 | |
| 992 Operand *TargetMIPS32::loOperand(Operand *Operand) { | 1083 Operand *TargetMIPS32::loOperand(Operand *Operand) { | 
| 993 assert(Operand->getType() == IceType_i64); | 1084 assert(Operand->getType() == IceType_i64); | 
| 994 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand)) | 1085 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand)) | 
| 995 return Var64On32->getLo(); | 1086 return Var64On32->getLo(); | 
| 996 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { | 1087 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { | 
| 997 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); | 1088 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); | 
| 998 } | 1089 } | 
| 999 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) { | 1090 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) { | 
| 1000 // Conservatively disallow memory operands with side-effects (pre/post | 1091 // Conservatively disallow memory operands with side-effects (pre/post | 
| 1001 // increment) in case of duplication. | 1092 // increment) in case of duplication. | 
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1410 } | 1501 } | 
| 1411 break; | 1502 break; | 
| 1412 case InstArithmetic::Frem: | 1503 case InstArithmetic::Frem: | 
| 1413 break; | 1504 break; | 
| 1414 } | 1505 } | 
| 1415 UnimplementedLoweringError(this, Instr); | 1506 UnimplementedLoweringError(this, Instr); | 
| 1416 } | 1507 } | 
| 1417 | 1508 | 
| 1418 void TargetMIPS32::lowerAssign(const InstAssign *Instr) { | 1509 void TargetMIPS32::lowerAssign(const InstAssign *Instr) { | 
| 1419 Variable *Dest = Instr->getDest(); | 1510 Variable *Dest = Instr->getDest(); | 
| 1511 | |
| 1512 if (Dest->isRematerializable()) { | |
| 1513 Context.insert<InstFakeDef>(Dest); | |
| 1514 return; | |
| 1515 } | |
| 1516 | |
| 1420 Operand *Src0 = Instr->getSrc(0); | 1517 Operand *Src0 = Instr->getSrc(0); | 
| 1421 assert(Dest->getType() == Src0->getType()); | 1518 assert(Dest->getType() == Src0->getType()); | 
| 1422 if (Dest->getType() == IceType_i64) { | 1519 if (Dest->getType() == IceType_i64) { | 
| 1423 Src0 = legalizeUndef(Src0); | 1520 Src0 = legalizeUndef(Src0); | 
| 1424 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); | 1521 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); | 
| 1425 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); | 1522 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); | 
| 1426 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 1523 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 
| 1427 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 1524 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 
| 1428 // Variable *T_Lo = nullptr, *T_Hi = nullptr; | 1525 // Variable *T_Lo = nullptr, *T_Hi = nullptr; | 
| 1429 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); | 1526 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); | 
| (...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2434 Str << "\t.set\t" | 2531 Str << "\t.set\t" | 
| 2435 << "nomips16\n"; | 2532 << "nomips16\n"; | 
| 2436 } | 2533 } | 
| 2437 | 2534 | 
| 2438 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 2535 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 
| 2439 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 2536 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 
| 2440 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 2537 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 
| 2441 | 2538 | 
| 2442 } // end of namespace MIPS32 | 2539 } // end of namespace MIPS32 | 
| 2443 } // end of namespace Ice | 2540 } // end of namespace Ice | 
| OLD | NEW |