diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachineCopyPropagation.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineCopyPropagation.cpp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp index 10b74f5..2d9ada5 100644 --- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -414,6 +414,31 @@ bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy, if (!UseI.isCopy()) return false; + const TargetRegisterClass *CopySrcRC = + TRI->getMinimalPhysRegClass(CopySrcReg); + const TargetRegisterClass *UseDstRC = + TRI->getMinimalPhysRegClass(UseI.getOperand(0).getReg()); + const TargetRegisterClass *CrossCopyRC = TRI->getCrossCopyRegClass(CopySrcRC); + + // If cross copy register class is not the same as copy source register class + // then it is not possible to copy the register directly and requires a cross + // register class copy. Fowarding this copy without checking register class of + // UseDst may create additional cross register copies when expanding the copy + // instruction in later passes. + if (CopySrcRC != CrossCopyRC) { + const TargetRegisterClass *CopyDstRC = + TRI->getMinimalPhysRegClass(Copy.getOperand(0).getReg()); + + // Check if UseDstRC matches the necessary register class to copy from + // CopySrc's register class. If so then forwarding the copy will not + // introduce any cross-class copys. Else if CopyDstRC matches then keep the + // copy and do not forward. If neither UseDstRC or CopyDstRC matches then + // we may need a cross register copy later but we do not worry about it + // here. + if (UseDstRC != CrossCopyRC && CopyDstRC == CrossCopyRC) + return false; + } + /// COPYs don't have register class constraints, so if the user instruction /// is a COPY, we just try to avoid introducing additional cross-class /// COPYs. For example: @@ -430,9 +455,6 @@ bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy, /// /// so we have reduced the number of cross-class COPYs and potentially /// introduced a nop COPY that can be removed. - const TargetRegisterClass *UseDstRC = - TRI->getMinimalPhysRegClass(UseI.getOperand(0).getReg()); - const TargetRegisterClass *SuperRC = UseDstRC; for (TargetRegisterClass::sc_iterator SuperRCI = UseDstRC->getSuperClasses(); SuperRC; SuperRC = *SuperRCI++) |