llvm.org GIT mirror llvm / 79a0c1e
Correctly determine whether a argument load can be folded into its uses. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47545 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 12 years ago
2 changed file(s) with 56 addition(s) and 49 deletion(s). Raw diff Collapse all Expand all
347347 /// canFoldMemoryOperand - Return true if the specified load / store
348348 /// folding is possible.
349349 bool canFoldMemoryOperand(MachineInstr *MI,
350 SmallVector &Ops) const;
351 bool canFoldMemoryOperand(MachineInstr *MI, unsigned Reg) const;
350 SmallVector &Ops,
351 bool ReMatLoadSS) const;
352352
353353 /// anyKillInMBBAfterIdx - Returns true if there is a kill of the specified
354354 /// VNInfo that's after the specified index but is within the basic block.
646646 int FrameIdx = 0;
647647 if (tii_->isLoadFromStackSlot(MI, FrameIdx) &&
648648 mf_->getFrameInfo()->isImmutableObjectIndex(FrameIdx))
649 // FIXME: Let target specific isReallyTriviallyReMaterializable determines
650 // this but remember this is not safe to fold into a two-address
651 // instruction.
649652 // This is a load from fixed stack slot. It can be rematerialized.
650653 return true;
651654
694697 return true;
695698 }
696699
700 /// FilterFoldedOps - Filter out two-address use operands. Return
701 /// true if it finds any issue with the operands that ought to prevent
702 /// folding.
703 static bool FilterFoldedOps(MachineInstr *MI,
704 SmallVector &Ops,
705 unsigned &MRInfo,
706 SmallVector &FoldOps) {
707 const TargetInstrDesc &TID = MI->getDesc();
708
709 MRInfo = 0;
710 for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
711 unsigned OpIdx = Ops[i];
712 MachineOperand &MO = MI->getOperand(OpIdx);
713 // FIXME: fold subreg use.
714 if (MO.getSubReg())
715 return true;
716 if (MO.isDef())
717 MRInfo |= (unsigned)VirtRegMap::isMod;
718 else {
719 // Filter out two-address use operand(s).
720 if (!MO.isImplicit() &&
721 TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) {
722 MRInfo = VirtRegMap::isModRef;
723 continue;
724 }
725 MRInfo |= (unsigned)VirtRegMap::isRef;
726 }
727 FoldOps.push_back(OpIdx);
728 }
729 return false;
730 }
731
732
697733 /// tryFoldMemoryOperand - Attempts to fold either a spill / restore from
698734 /// slot / to reg or any rematerialized load into ith operand of specified
699735 /// MI. If it is successul, MI is updated with the newly created MI and
703739 unsigned InstrIdx,
704740 SmallVector &Ops,
705741 bool isSS, int Slot, unsigned Reg) {
706 unsigned MRInfo = 0;
707742 const TargetInstrDesc &TID = MI->getDesc();
708743 // If it is an implicit def instruction, just delete it.
709744 if (TID.isImplicitDef()) {
714749 return true;
715750 }
716751
752 // Filter the list of operand indexes that are to be folded. Abort if
753 // any operand will prevent folding.
754 unsigned MRInfo = 0;
717755 SmallVector FoldOps;
718 for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
719 unsigned OpIdx = Ops[i];
720 MachineOperand &MO = MI->getOperand(OpIdx);
721 // FIXME: fold subreg use.
722 if (MO.getSubReg())
723 return false;
724 if (MO.isDef())
725 MRInfo |= (unsigned)VirtRegMap::isMod;
726 else {
727 // Filter out two-address use operand(s).
728 if (!MO.isImplicit() &&
729 TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1) {
730 MRInfo = VirtRegMap::isModRef;
731 continue;
732 }
733 MRInfo |= (unsigned)VirtRegMap::isRef;
734 }
735 FoldOps.push_back(OpIdx);
736 }
756 if (FilterFoldedOps(MI, Ops, MRInfo, FoldOps))
757 return false;
737758
738759 // Can't fold a load from fixed stack slot into a two address instruction.
739760 if (isSS && DefMI && (MRInfo & VirtRegMap::isMod))
766787 /// canFoldMemoryOperand - Returns true if the specified load / store
767788 /// folding is possible.
768789 bool LiveIntervals::canFoldMemoryOperand(MachineInstr *MI,
769 SmallVector &Ops) const {
790 SmallVector &Ops,
791 bool ReMatLoadSS) const {
792 // Filter the list of operand indexes that are to be folded. Abort if
793 // any operand will prevent folding.
794 unsigned MRInfo = 0;
770795 SmallVector FoldOps;
771 for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
772 unsigned OpIdx = Ops[i];
773 // FIXME: fold subreg use.
774 if (MI->getOperand(OpIdx).getSubReg())
775 return false;
776 FoldOps.push_back(OpIdx);
777 }
778
779 return tii_->canFoldMemoryOperand(MI, FoldOps);
780 }
781
782 bool LiveIntervals::canFoldMemoryOperand(MachineInstr *MI, unsigned Reg) const {
783 SmallVector FoldOps;
784 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
785 MachineOperand& mop = MI->getOperand(i);
786 if (!mop.isRegister())
787 continue;
788 unsigned UseReg = mop.getReg();
789 if (UseReg != Reg)
790 continue;
791 // FIXME: fold subreg use.
792 if (mop.getSubReg())
793 return false;
794 FoldOps.push_back(i);
795 }
796 if (FilterFoldedOps(MI, Ops, MRInfo, FoldOps))
797 return false;
798
799 // Can't fold a load from fixed stack slot into a two address instruction.
800 if (ReMatLoadSS && (MRInfo & VirtRegMap::isMod))
801 return false;
802
796803 return tii_->canFoldMemoryOperand(MI, FoldOps);
797804 }
798805
943950 goto RestartInstruction;
944951 }
945952 } else {
946 CanFold = canFoldMemoryOperand(MI, Ops);
953 CanFold = canFoldMemoryOperand(MI, Ops, DefIsReMat && isLoadSS);
947954 }
948955 } else
949956 CanFold = false;