Lines Matching +full:op +full:- +full:tee

1 //===-- WebAssemblyRegStackify.cpp - Register Stackification --------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
13 /// such that they form single-use expression trees. Registers fitting this form
20 //===----------------------------------------------------------------------===//
42 #define DEBUG_TYPE "wasm-reg-stackify"
84 if (!MI->definesRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr)) in imposeStackOrdering()
85 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK, in imposeStackOrdering()
90 if (!MI->readsRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr)) in imposeStackOrdering()
91 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK, in imposeStackOrdering()
103 assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF); in convertImplicitDefToConstZero()
105 const auto *RegClass = MRI.getRegClass(MI->getOperand(0).getReg()); in convertImplicitDefToConstZero()
107 MI->setDesc(TII->get(WebAssembly::CONST_I32)); in convertImplicitDefToConstZero()
108 MI->addOperand(MachineOperand::CreateImm(0)); in convertImplicitDefToConstZero()
110 MI->setDesc(TII->get(WebAssembly::CONST_I64)); in convertImplicitDefToConstZero()
111 MI->addOperand(MachineOperand::CreateImm(0)); in convertImplicitDefToConstZero()
113 MI->setDesc(TII->get(WebAssembly::CONST_F32)); in convertImplicitDefToConstZero()
116 MI->addOperand(MachineOperand::CreateFPImm(Val)); in convertImplicitDefToConstZero()
118 MI->setDesc(TII->get(WebAssembly::CONST_F64)); in convertImplicitDefToConstZero()
121 MI->addOperand(MachineOperand::CreateFPImm(Val)); in convertImplicitDefToConstZero()
123 MI->setDesc(TII->get(WebAssembly::CONST_V128_I64x2)); in convertImplicitDefToConstZero()
124 MI->addOperand(MachineOperand::CreateImm(0)); in convertImplicitDefToConstZero()
125 MI->addOperand(MachineOperand::CreateImm(0)); in convertImplicitDefToConstZero()
132 // MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side
143 if (!GA->isInterposable()) in queryCallee()
144 GV = GA->getAliasee(); in queryCallee()
147 if (!F->doesNotThrow()) in queryCallee()
149 if (F->doesNotAccessMemory()) in queryCallee()
151 if (F->onlyReadsMemory()) { in queryCallee()
259 return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def); in shouldRematerialize()
275 return LIS.getInstructionFromIndex(ValNo->def); in getVRegDef()
317 const MachineInstr *DefI = Def->getParent(); in isSafeToMove()
318 const MachineInstr *UseI = Use->getParent(); in isSafeToMove()
319 assert(DefI->getParent() == Insert->getParent()); in isSafeToMove()
320 assert(UseI->getParent() == Insert->getParent()); in isSafeToMove()
333 if (Def != DefI->defs().begin()) in isSafeToMove()
341 for (const auto &SubsequentDef : drop_begin(DefI->defs())) { in isSafeToMove()
345 for (const auto &PriorUse : I->uses()) { in isSafeToMove()
355 const MachineBasicBlock *MBB = DefI->getParent(); in isSafeToMove()
357 for (auto E = MBB->end(); NextI != E && NextI->isDebugInstr(); ++NextI) in isSafeToMove()
364 if (WebAssembly::isCatch(DefI->getOpcode())) in isSafeToMove()
369 for (const MachineOperand &MO : DefI->operands()) { in isSafeToMove()
375 if (MO.isDead() && Insert->definesRegister(Reg, /*TRI=*/nullptr) && in isSafeToMove()
376 !Insert->readsRegister(Reg, /*TRI=*/nullptr)) in isSafeToMove()
409 for (--I; I != D; --I) { in isSafeToMove()
426 for (const MachineOperand &MO : I->operands()) in isSafeToMove()
464 // Actually, dominating is over-conservative. Test that the use would in oneUseDominatesOtherUses()
469 if (UseInst->getDesc().getNumDefs() == 0) in oneUseDominatesOtherUses()
471 const MachineOperand &MO = UseInst->getOperand(0); in oneUseDominatesOtherUses()
492 /// Get the appropriate tee opcode for the given register class.
521 /// A single-use def in the same block with no intervening memory or register
523 static MachineInstr *moveForSingleUse(unsigned Reg, MachineOperand &Op, in moveForSingleUse() argument
528 LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump()); in moveForSingleUse()
542 Op.setReg(NewReg); in moveForSingleUse()
551 LIS.getInstructionIndex(*Op.getParent()).getRegSlot(), in moveForSingleUse()
556 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump()); in moveForSingleUse()
564 for (auto *I = MI->getPrevNode(); I; I = I->getPrevNode()) in getPrevNonDebugInst()
565 if (!I->isDebugInstr()) in getPrevNonDebugInst()
573 unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock &MBB, in rematerializeCheapDef() argument
578 LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump()); in rematerializeCheapDef()
584 Op.setReg(NewReg); in rematerializeCheapDef()
592 LLVM_DEBUG(dbgs() << " - Cloned to "; Clone->dump()); in rematerializeCheapDef()
604 LLVM_DEBUG(dbgs() << " - Deleting original\n"); in rematerializeCheapDef()
615 /// A multiple-use def in the same block with no intervening memory or register
617 /// insert a tee to satisfy the rest of the uses. As an illustration, rewrite
636 unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, in moveAndTeeForMultiUse() argument
639 LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump()); in moveAndTeeForMultiUse()
650 // Create the Tee and attach the registers. in moveAndTeeForMultiUse()
651 MachineOperand &DefMO = Def->getOperand(0); in moveAndTeeForMultiUse()
652 MachineInstr *Tee = BuildMI(MBB, Insert, Insert->getDebugLoc(), in moveAndTeeForMultiUse() local
653 TII->get(getTeeOpcode(RegClass)), TeeReg) in moveAndTeeForMultiUse()
656 Op.setReg(TeeReg); in moveAndTeeForMultiUse()
658 SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot(); in moveAndTeeForMultiUse()
661 // Tell LiveIntervals we moved the original vreg def from Def to Tee. in moveAndTeeForMultiUse()
665 I->start = TeeIdx; in moveAndTeeForMultiUse()
666 ValNo->def = TeeIdx; in moveAndTeeForMultiUse()
675 imposeStackOrdering(Tee); in moveAndTeeForMultiUse()
677 // Even though 'TeeReg, Reg = TEE ...', has two defs, we don't need to clone in moveAndTeeForMultiUse()
683 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump()); in moveAndTeeForMultiUse()
684 LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump()); in moveAndTeeForMultiUse()
699 const iterator_range<mop_iterator> &Range = Insert->explicit_uses(); in TreeWalkerState()
708 MachineOperand &Op = *Range.begin(); in pop() local
714 return Op; in pop()
719 const iterator_range<mop_iterator> &Range(Instr->explicit_uses()); in pushOperands()
725 /// re-insert them starting from the beginning (because we've commuted them).
730 Worklist.back() = reverse(Instr->explicit_uses()); in resetTopOperands()
739 return !Range.empty() && Range.begin()->getParent() == Instr; in hasRemainingOperands()
782 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1); in maybeCommute()
788 if (TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) { in maybeCommute()
790 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1); in maybeCommute()
824 // Don't use a range-based for loop, because we modify the list as we're in runOnMachineFunction()
830 if (Insert->isInlineAsm()) in runOnMachineFunction()
834 if (Insert->isDebugValue()) in runOnMachineFunction()
862 if (DefI->isInlineAsm()) in runOnMachineFunction()
865 // Argument instructions represent live-in registers and not real in runOnMachineFunction()
867 if (WebAssembly::isArgument(DefI->getOpcode())) in runOnMachineFunction()
871 DefI->findRegisterDefOperand(Reg, /*TRI=*/nullptr); in runOnMachineFunction()
874 // Decide which strategy to take. Prefer to move a single-use value in runOnMachineFunction()
875 // over cloning it, and prefer cloning over introducing a tee. in runOnMachineFunction()
878 // supports intra-block moves) and it's MachineSink's job to catch all in runOnMachineFunction()
880 bool SameBlock = DefI->getParent() == &MBB; in runOnMachineFunction()
893 rematerializeCheapDef(Reg, Use, *DefI, MBB, Insert->getIterator(), in runOnMachineFunction()
908 // Stackifying a multivalue def may unlock in-place stackification of in runOnMachineFunction()
911 auto *SubsequentDef = Insert->defs().begin(); in runOnMachineFunction()
913 while (SubsequentDef != Insert->defs().end() && in runOnMachineFunction()
914 SubsequentUse != Use.getParent()->uses().end()) { in runOnMachineFunction()
915 if (!SubsequentDef->isReg() || !SubsequentUse->isReg()) in runOnMachineFunction()
917 Register DefReg = SubsequentDef->getReg(); in runOnMachineFunction()
918 Register UseReg = SubsequentUse->getReg(); in runOnMachineFunction()
919 // TODO: This single-use restriction could be relaxed by using tees in runOnMachineFunction()
930 if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF) in runOnMachineFunction()
949 // If we used VALUE_STACK anywhere, add it to the live-in sets everywhere so in runOnMachineFunction()
950 // that it never looks like a use-before-def. in runOnMachineFunction()