Index: lib/CodeGen/MIRCanonicalizerPass.cpp =================================================================== --- lib/CodeGen/MIRCanonicalizerPass.cpp +++ lib/CodeGen/MIRCanonicalizerPass.cpp @@ -311,6 +311,47 @@ return Changed; } +bool propagateLocalCopies(MachineBasicBlock *MBB) { + bool Changed = false; + MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); + + std::vector copies; + for (auto II = MBB->begin(), IE = MBB->end(); II != IE; ++II) { + if (II->isCopy()) + copies.push_back(&*II); + } + + for (auto MI : copies) { + + if (!MI->getOperand(0).isReg()) + continue; + if (!MI->getOperand(1).isReg()) + continue; + + const unsigned Dst = MI->getOperand(0).getReg(); + const unsigned Src = MI->getOperand(1).getReg(); + + if (!TargetRegisterInfo::isVirtualRegister(Dst)) + continue; + if (!TargetRegisterInfo::isVirtualRegister(Src)) + continue; + + std::vector RenameMOs; + for (auto UI = MRI.use_begin(Dst); UI != MRI.use_end(); ++UI) { + RenameMOs.push_back(&*UI); + } + + for (auto *MO : RenameMOs) { + Changed = true; + MO->setReg(Src); + } + + MI->eraseFromParent(); + } + + return Changed; +} + /// Here we find our candidates. What makes an interesting candidate? /// An candidate for a canonicalization tree root is normally any kind of /// instruction that causes side effects such as a store to memory or a copy to @@ -619,6 +660,10 @@ bbNames.push_back(MBB->getName()); DEBUG(dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << "\n\n";); + DEBUG(dbgs() << "MBB Before Canonical Copy Propagation:\n"; MBB->dump();); + Changed |= propagateLocalCopies(MBB); + DEBUG(dbgs() << "MBB After Canonical Copy Propagation:\n"; MBB->dump();); + DEBUG(dbgs() << "MBB Before Scheduling:\n"; MBB->dump();); unsigned IdempotentInstCount = 0; Changed |= rescheduleCanonically(IdempotentInstCount, MBB); Index: test/CodeGen/MIR/AArch64/mirCanonCopyCopyProp.mir =================================================================== --- /dev/null +++ test/CodeGen/MIR/AArch64/mirCanonCopyCopyProp.mir @@ -0,0 +1,119 @@ +# RUN: llc -mtriple=arm64-apple-ios11.0.0 -o - -run-pass mir-canonicalizer %s | FileCheck %s + +... +--- +name: Proc8 +stack: + - { id: 0, type: default, offset: 0, size: 4, alignment: 4, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -4, di-variable: '', di-expression: '', di-location: '' } + - { id: 1, type: default, offset: 0, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -16, di-variable: '', di-expression: '', di-location: '' } + - { id: 2, type: default, offset: 0, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -24, di-variable: '', di-expression: '', di-location: '' } + - { id: 3, type: default, offset: 0, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -32, di-variable: '', di-expression: '', di-location: '' } + - { id: 4, type: default, offset: 0, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -40, di-variable: '', di-expression: '', di-location: '' } + - { id: 5, type: default, offset: 0, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -48, di-variable: '', di-expression: '', di-location: '' } + - { id: 6, type: default, offset: 0, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '', callee-saved-restored: true, + local-offset: -56, di-variable: '', di-expression: '', di-location: '' } +constants: +body: | + bb.0: + liveins: $x0, $x1, $d0, $d1 + + %3:fpr64 = COPY $d1 + %2:fpr64 = COPY $d0 + %1:gpr64 = COPY $x1 + %0:gpr64common = COPY $x0 + STRXui %0, %stack.1, 0 :: (store 8) + STRXui %1, %stack.2, 0 :: (store 8) + STRDui %2, %stack.3, 0 :: (store 8) + STRDui %3, %stack.4, 0 :: (store 8) + + %4:fpr64 = FMOVDi 20 + %5:fpr64 = FADDDrr %2, killed %4 + STRDui %5, %stack.5, 0 :: (store 8) + + %6:gpr32 = FCVTZSUWDr %5 + STRDroW %3, %0, killed %6, 1, 1 + + %7:gpr64common = LDRXui %stack.1, 0 :: (dereferenceable load 8) + %8:fpr64 = LDRDui %stack.5, 0 :: (dereferenceable load 8) + + %9:gpr32common = FCVTZSUWDr killed %8 + %10:fpr64 = LDRDroW %7, %9, 1, 1 + + %11:gpr32common = ADDWri %9, 1, 0 + STRDroW killed %10, %7, killed %11, 1, 1 + + %12:fpr64 = LDRDui %stack.5, 0 :: (dereferenceable load 8) + %13:gpr64common = LDRXui %stack.1, 0 :: (dereferenceable load 8) + + %14:gpr32common = FCVTZSUWDr %12 + %15:gpr32common = ADDWri killed %14, 30, 0 + STRDroW %12, killed %13, killed %15, 1, 1 + + %16:fpr64 = LDRDui %stack.5, 0 :: (dereferenceable load 8) + STRDui killed %16, %stack.6, 0 :: (store 8) + + %19:fpr64 = FMOVDi 112 + %46:gpr32 = MOVi32imm 408 + %43:fpr64 = LDRDui %stack.5, 0 :: (dereferenceable load 8) + %44:gpr64 = LDRXui %stack.2, 0 :: (dereferenceable load 8) + + %45:gpr32 = FCVTZSUWDr %43 + %47:gpr64common = SMADDLrrr killed %45, %46, killed %44 + %48:fpr64 = LDRDui %stack.6, 0 :: (dereferenceable load 8) + + %49:gpr32 = FCVTZSUWDr killed %48 + STRDroW %43, killed %47, killed %49, 1, 1 + + %21:gpr64 = LDRXui %stack.2, 0 :: (dereferenceable load 8) + %22:fpr64 = LDRDui %stack.5, 0 :: (dereferenceable load 8) + + %23:gpr32 = FCVTZSUWDr killed %22 + %24:gpr32 = MOVi32imm 408 + %25:gpr64common = SMADDLrrr %23, %24, killed %21 + %26:gpr64sp = ADDXrx killed %25, %23, 51 + %27:fpr64 = LDURDi %26, -8 + %29:fpr64 = FADDDrr killed %27, %19 + STURDi killed %29, %26, -8 + + %30:gpr64common = LDRXui %stack.1, 0 :: (dereferenceable load 8) + %31:fpr64 = LDRDui %stack.5, 0 :: (dereferenceable load 8) + + %32:gpr32common = FCVTZSUWDr killed %31 + %34:gpr64all = IMPLICIT_DEF + %33:gpr64 = INSERT_SUBREG %34, %32, %subreg.sub_32 + %35:gpr64 = SBFMXri killed %33, 61, 31 + %36:fpr64 = LDRDroX killed %30, %35, 0, 0 + %37:gpr64 = LDRXui %stack.2, 0 :: (dereferenceable load 8) + + %38:gpr32common = ADDWri %32, 20, 0 + %39:gpr64common = SMADDLrrr killed %38, %24, killed %37 + STRDroX killed %36, killed %39, %35, 0, 0 + + %40:gpr64 = MOVi64imm 4617315517961601024 + + %42:gpr32 = LDRWui %stack.0, 0 :: (dereferenceable load 8) + + ;CHECK: %namedVReg1418:gpr32 = LDRWui %stack.0, 0 :: (dereferenceable load 8) + ;CHECK: $w0 = COPY %namedVReg1418 + ;CHECK: RET_ReallyLR implicit $w0 + + %vreg1234:gpr32 = COPY %42 + %vreg1235:gpr32 = COPY %vreg1234 + %vreg1236:gpr32 = COPY %vreg1235 + $w0 = COPY %vreg1236 + RET_ReallyLR implicit $w0 + +...