llvm.org GIT mirror llvm / d1303d2
Fix the handling of partial redefines in the fast register allocator. A partial redefine needs to be treated like a tied operand, and the register must be reloaded while processing use operands. This fixes a bug where partially redefined registers were processed as normal defs with a reload added. The reload could clobber another use operand if it was a kill that allowed register reuse. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107193 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 9 years ago
2 changed file(s) with 61 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
514514 bool New;
515515 tie(LRI, New) = LiveVirtRegs.insert(std::make_pair(VirtReg, LiveReg()));
516516 LiveReg &LR = LRI->second;
517 bool PartialRedef = MI->getOperand(OpNum).getSubReg();
518517 if (New) {
519518 // If there is no hint, peek at the only use of this register.
520519 if ((!Hint || !TargetRegisterInfo::isPhysicalRegister(Hint)) &&
526525 Hint = DstReg;
527526 }
528527 allocVirtReg(MI, *LRI, Hint);
529 // If this is only a partial redefinition, we must reload the other parts.
530 if (PartialRedef && MI->readsVirtualRegister(VirtReg)) {
531 const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
532 int FI = getStackSpaceFor(VirtReg, RC);
533 DEBUG(dbgs() << "Reloading for partial redef: %reg" << VirtReg << "\n");
534 TII->loadRegFromStackSlot(*MBB, MI, LR.PhysReg, FI, RC, TRI);
535 ++NumLoads;
536 }
537 } else if (LR.LastUse && !PartialRedef) {
528 } else if (LR.LastUse) {
538529 // Redefining a live register - kill at the last use, unless it is this
539530 // instruction defining VirtReg multiple times.
540531 if (LR.LastUse != MI || LR.LastUse->getOperand(LR.LastOpNum).isUse())
570561 } else if (LR.Dirty) {
571562 if (isLastUseOfLocalReg(MO)) {
572563 DEBUG(dbgs() << "Killing last use: " << MO << "\n");
573 MO.setIsKill();
564 if (MO.isUse())
565 MO.setIsKill();
566 else
567 MO.setIsDead();
574568 } else if (MO.isKill()) {
575569 DEBUG(dbgs() << "Clearing dubious kill: " << MO << "\n");
576570 MO.setIsKill(false);
571 } else if (MO.isDead()) {
572 DEBUG(dbgs() << "Clearing dubious dead: " << MO << "\n");
573 MO.setIsDead(false);
577574 }
578575 } else if (MO.isKill()) {
579576 // We must remove kill flags from uses of reloaded registers because the
582579 // This would cause a second reload of %x into a different register.
583580 DEBUG(dbgs() << "Clearing clean kill: " << MO << "\n");
584581 MO.setIsKill(false);
582 } else if (MO.isDead()) {
583 DEBUG(dbgs() << "Clearing clean dead: " << MO << "\n");
584 MO.setIsDead(false);
585585 }
586586 assert(LR.PhysReg && "Register not assigned");
587587 LR.LastUse = MI;
624624 if (!MO.isReg()) continue;
625625 unsigned Reg = MO.getReg();
626626 if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
627 if (MO.isEarlyClobber() || MI->isRegTiedToDefOperand(i)) {
627 if (MO.isEarlyClobber() || MI->isRegTiedToDefOperand(i) ||
628 (MO.getSubReg() && MI->readsVirtualRegister(Reg))) {
628629 if (ThroughRegs.insert(Reg))
629630 DEBUG(dbgs() << " %reg" << Reg);
630631 }
648649 }
649650 }
650651
652 SmallVector PartialDefs;
651653 DEBUG(dbgs() << "Allocating tied uses and early clobbers.\n");
652654 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
653655 MachineOperand &MO = MI->getOperand(i);
662664 LiveRegMap::iterator LRI = reloadVirtReg(MI, i, Reg, 0);
663665 unsigned PhysReg = LRI->second.PhysReg;
664666 setPhysReg(MI, i, PhysReg);
667 // Note: we don't update the def operand yet. That would cause the normal
668 // def-scan to attempt spilling.
669 } else if (MO.getSubReg() && MI->readsVirtualRegister(Reg)) {
670 DEBUG(dbgs() << "Partial redefine: " << MO << "\n");
671 // Reload the register, but don't assign to the operand just yet.
672 // That would confuse the later phys-def processing pass.
673 LiveRegMap::iterator LRI = reloadVirtReg(MI, i, Reg, 0);
674 PartialDefs.push_back(LRI->second.PhysReg);
665675 } else if (MO.isEarlyClobber()) {
666676 // Note: defineVirtReg may invalidate MO.
667677 LiveRegMap::iterator LRI = defineVirtReg(MI, i, Reg, 0);
682692 for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)
683693 UsedInInstr.set(*AS);
684694 }
695
696 // Also mark PartialDefs as used to avoid reallocation.
697 for (unsigned i = 0, e = PartialDefs.size(); i != e; ++i)
698 UsedInInstr.set(PartialDefs[i]);
685699 }
686700
687701 void RAFast::AllocateBasicBlock() {
766780 // Mark physreg uses and early clobbers as used.
767781 // Find the end of the virtreg operands
768782 unsigned VirtOpEnd = 0;
769 bool hasTiedOps = false, hasEarlyClobbers = false, hasPhysDefs = false;
783 bool hasTiedOps = false;
784 bool hasEarlyClobbers = false;
785 bool hasPartialRedefs = false;
786 bool hasPhysDefs = false;
770787 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
771788 MachineOperand &MO = MI->getOperand(i);
772789 if (!MO.isReg()) continue;
774791 if (!Reg) continue;
775792 if (TargetRegisterInfo::isVirtualRegister(Reg)) {
776793 VirtOpEnd = i+1;
777 if (MO.isUse())
794 if (MO.isUse()) {
778795 hasTiedOps = hasTiedOps ||
779796 TID.getOperandConstraint(i, TOI::TIED_TO) != -1;
780 else if (MO.isEarlyClobber())
781 hasEarlyClobbers = true;
797 } else {
798 if (MO.isEarlyClobber())
799 hasEarlyClobbers = true;
800 if (MO.getSubReg() && MI->readsVirtualRegister(Reg))
801 hasPartialRedefs = true;
802 }
782803 continue;
783804 }
784805 if (!Allocatable.test(Reg)) continue;
799820 // operands.
800821 // We didn't detect inline asm tied operands above, so just make this extra
801822 // pass for all inline asm.
802 if (MI->isInlineAsm() || hasEarlyClobbers || (hasTiedOps && hasPhysDefs)) {
823 if (MI->isInlineAsm() || hasEarlyClobbers || hasPartialRedefs ||
824 (hasTiedOps && hasPhysDefs)) {
803825 handleThroughOperands(MI, VirtDead);
804826 // Don't attempt coalescing when we have funny stuff going on.
805827 CopyDst = 0;
0 ; RUN: llc < %s -O0 -mcpu=cortex-a8 | FileCheck %s
1 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
2 target triple = "thumbv7-apple-darwin10"
3
4 ; This tests the fast register allocator's handling of partial redefines:
5 ;
6 ; %reg1026 = VMOVv16i8 0, pred:14, pred:%reg0
7 ; %reg1028:dsub_1 = EXTRACT_SUBREG %reg1026, 1
8 ;
9 ; %reg1026 gets allocated %Q0, and if %reg1028 is reloaded for the partial redef,
10 ; it cannot also get %Q0.
11
12 ; CHECK: vmov.i8 q0, #0x0
13 ; CHECK-NOT: vld1.64 {d0,d1}
14 ; CHECK: vmov.f64 d3, d0
15
16 define i32 @main(i32 %argc, i8** %argv) nounwind {
17 entry:
18 %0 = shufflevector <2 x i64> undef, <2 x i64> zeroinitializer, <2 x i32> ; <<2 x i64>> [#uses=1]
19 store <2 x i64> %0, <2 x i64>* undef, align 16
20 ret i32 undef
21 }