From: Jakob Stoklund Olesen Date: Wed, 12 May 2010 18:46:03 +0000 (+0000) Subject: Make sure to add kill flags to the last use of a virtreg when it is redefined. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=804291e31658d46fb1db5ecaf42b31950c02a6f2;p=oota-llvm.git Make sure to add kill flags to the last use of a virtreg when it is redefined. The X86 floating point stack pass and others depend on good kill flags. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103635 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/RegAllocFast.cpp b/lib/CodeGen/RegAllocFast.cpp index a481f787dcb..eac8407fff3 100644 --- a/lib/CodeGen/RegAllocFast.cpp +++ b/lib/CodeGen/RegAllocFast.cpp @@ -121,8 +121,9 @@ namespace { bool runOnMachineFunction(MachineFunction &Fn); void AllocateBasicBlock(MachineBasicBlock &MBB); int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC); - void killVirtReg(unsigned VirtReg); + void addKillFlag(LiveRegMap::iterator i); void killVirtReg(LiveRegMap::iterator i); + void killVirtReg(unsigned VirtReg); void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned VirtReg, bool isKill); void killPhysReg(unsigned PhysReg); @@ -161,20 +162,27 @@ int RAFast::getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC) { return FrameIdx; } -/// killVirtReg - Mark virtreg as no longer available. -void RAFast::killVirtReg(LiveRegMap::iterator i) { - assert(i != LiveVirtRegs.end() && "Killing unmapped virtual register"); - unsigned VirtReg = i->first; - const LiveReg &LR = i->second; - assert(PhysRegState[LR.PhysReg] == VirtReg && "Broken RegState mapping"); - PhysRegState[LR.PhysReg] = regFree; +/// addKillFlag - Set kill flags on last use of a virtual register. +void RAFast::addKillFlag(LiveRegMap::iterator lri) { + assert(lri != LiveVirtRegs.end() && "Killing unmapped virtual register"); + const LiveReg &LR = lri->second; if (LR.LastUse) { MachineOperand &MO = LR.LastUse->getOperand(LR.LastOpNum); - if (MO.isUse()) MO.setIsKill(); - else MO.setIsDead(); - DEBUG(dbgs() << " - last seen here: " << *LR.LastUse); + if (MO.isDef()) + MO.setIsDead(); + else if (!LR.LastUse->isRegTiedToDefOperand(LR.LastOpNum)) + MO.setIsKill(); + DEBUG(dbgs() << " %reg" << lri->first << " killed: " << *LR.LastUse); } - LiveVirtRegs.erase(i); +} + +/// killVirtReg - Mark virtreg as no longer available. +void RAFast::killVirtReg(LiveRegMap::iterator lri) { + addKillFlag(lri); + const LiveReg &LR = lri->second; + assert(PhysRegState[LR.PhysReg] == lri->first && "Broken RegState mapping"); + PhysRegState[LR.PhysReg] = regFree; + LiveVirtRegs.erase(lri); } /// killVirtReg - Mark virtreg as no longer available. @@ -445,6 +453,8 @@ unsigned RAFast::defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg); if (lri == LiveVirtRegs.end()) lri = allocVirtReg(MBB, MI, VirtReg); + else + addKillFlag(lri); // Kill before redefine. LiveReg &LR = lri->second; LR.LastUse = MI; LR.LastOpNum = OpNum; diff --git a/test/CodeGen/X86/2010-05-12-FastAllocKills.ll b/test/CodeGen/X86/2010-05-12-FastAllocKills.ll new file mode 100644 index 00000000000..36a99d6f90e --- /dev/null +++ b/test/CodeGen/X86/2010-05-12-FastAllocKills.ll @@ -0,0 +1,59 @@ +; RUN: llc -regalloc=fast -verify-machineinstrs < %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin" + +; This test causes a virtual FP register to be redefined while it is live: +;BB#5: derived from LLVM BB %bb10 +; Predecessors according to CFG: BB#4 BB#5 +; %reg1024 = MOV_Fp8080 %reg1034 +; %reg1025 = MUL_Fp80m32 %reg1024, %RIP, 1, %reg0, , %reg0; mem:LD4[ConstantPool] +; %reg1034 = MOV_Fp8080 %reg1025 +; FP_REG_KILL %FP0, %FP1, %FP2, %FP3, %FP4, %FP5, %FP6 +; JMP_4 +; Successors according to CFG: BB#5 +; +; The X86FP pass needs good kill flags, like on %FP0 representing %reg1034: +;BB#5: derived from LLVM BB %bb10 +; Predecessors according to CFG: BB#4 BB#5 +; %FP0 = LD_Fp80m , 1, %reg0, 0, %reg0; mem:LD10[FixedStack3](align=4) +; %FP1 = MOV_Fp8080 %FP0 +; %FP2 = MUL_Fp80m32 %FP1, %RIP, 1, %reg0, , %reg0; mem:LD4[ConstantPool] +; %FP0 = MOV_Fp8080 %FP2 +; ST_FpP80m , 1, %reg0, 0, %reg0, %FP0; mem:ST10[FixedStack3](align=4) +; ST_FpP80m , 1, %reg0, 0, %reg0, %FP1; mem:ST10[FixedStack4](align=4) +; ST_FpP80m , 1, %reg0, 0, %reg0, %FP2; mem:ST10[FixedStack5](align=4) +; FP_REG_KILL %FP0, %FP1, %FP2, %FP3, %FP4, %FP5, %FP6 +; JMP_4 +; Successors according to CFG: BB#5 + +define fastcc i32 @sqlite3AtoF(i8* %z, double* nocapture %pResult) nounwind ssp { +entry: + br i1 undef, label %bb2, label %bb1.i.i + +bb1.i.i: ; preds = %entry + unreachable + +bb2: ; preds = %entry + br i1 undef, label %isdigit339.exit11.preheader, label %bb13 + +isdigit339.exit11.preheader: ; preds = %bb2 + br i1 undef, label %bb12, label %bb10 + +bb10: ; preds = %bb10, %isdigit339.exit11.preheader + %divisor.041 = phi x86_fp80 [ %0, %bb10 ], [ 0xK3FFF8000000000000000, %isdigit339.exit11.preheader ] ; [#uses=1] + %0 = fmul x86_fp80 %divisor.041, 0xK4002A000000000000000 ; [#uses=2] + br i1 false, label %bb12, label %bb10 + +bb12: ; preds = %bb10, %isdigit339.exit11.preheader + %divisor.0.lcssa = phi x86_fp80 [ 0xK3FFF8000000000000000, %isdigit339.exit11.preheader ], [ %0, %bb10 ] ; [#uses=0] + br label %bb13 + +bb13: ; preds = %bb12, %bb2 + br i1 undef, label %bb34, label %bb36 + +bb34: ; preds = %bb13 + br label %bb36 + +bb36: ; preds = %bb34, %bb13 + ret i32 undef +}