From 3f91ad7ba72777e338a657900ce5536d4a0a68e3 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 15 Dec 2002 20:48:03 +0000 Subject: [PATCH] Fix a problem that occurs when PHI nodes have multiple entries for the same predecessor git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5055 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/RegAllocSimple.cpp | 77 +++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/lib/CodeGen/RegAllocSimple.cpp b/lib/CodeGen/RegAllocSimple.cpp index a6bda33722e..97b42b0307a 100644 --- a/lib/CodeGen/RegAllocSimple.cpp +++ b/lib/CodeGen/RegAllocSimple.cpp @@ -283,43 +283,60 @@ void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) { const TargetRegisterClass* regClass = PhysRegClasses[physReg]; assert(regClass && "Target register class not found!"); unsigned dataSize = regClass->getDataSize(); - + for (int i = MI->getNumOperands() - 1; i >= 2; i-=2) { MachineOperand &opVal = MI->getOperand(i-1); // Get the MachineBasicBlock equivalent of the BasicBlock that is the // source path the phi MachineBasicBlock &opBlock = *MI->getOperand(i).getMachineBasicBlock(); - MachineBasicBlock::iterator opI = opBlock.end(); - MachineInstr *opMI = *--opI; - - // must backtrack over ALL the branches in the previous block, until no - // more - while (MII.isBranch(opMI->getOpcode()) && opI != opBlock.begin()) - opMI = *--opI; - - // move back to the first branch instruction so new instructions - // are inserted right in front of it and not in front of a non-branch - if (!MII.isBranch(opMI->getOpcode())) - ++opI; - - // Retrieve the constant value from this op, move it to target - // register of the phi - if (opVal.isImmediate()) { - opI = RegInfo->moveImm2Reg(opBlock, opI, physReg, - (unsigned) opVal.getImmedValue(), - dataSize); - saveVirtRegToStack(opBlock, opI, virtualReg, physReg); - } else { - // Allocate a physical register and add a move in the BB - unsigned opVirtualReg = (unsigned) opVal.getAllocatedRegNum(); - unsigned opPhysReg; - opI = moveUseToReg(opBlock, opI, opVirtualReg, physReg); - - // Save that register value to the stack of the TARGET REG - saveVirtRegToStack(opBlock, opI, virtualReg, physReg); + + // Check to make sure we haven't already emitted the copy for this block. + // This can happen because PHI nodes may have multiple entries for the + // same basic block. It doesn't matter which entry we use though, because + // all incoming values are guaranteed to be the same for a particular bb. + // + // Note that this is N^2 in the number of phi node entries, but since the + // # of entries is tiny, this is not a problem. + // + bool HaveNotEmitted = true; + for (int op = MI->getNumOperands() - 1; op != i; op -= 2) + if (&opBlock == MI->getOperand(op).getMachineBasicBlock()) { + HaveNotEmitted = false; + break; + } + + if (HaveNotEmitted) { + MachineBasicBlock::iterator opI = opBlock.end(); + MachineInstr *opMI = *--opI; + + // must backtrack over ALL the branches in the previous block + while (MII.isBranch(opMI->getOpcode()) && opI != opBlock.begin()) + opMI = *--opI; + + // move back to the first branch instruction so new instructions + // are inserted right in front of it and not in front of a non-branch + if (!MII.isBranch(opMI->getOpcode())) + ++opI; + + // Retrieve the constant value from this op, move it to target + // register of the phi + if (opVal.isImmediate()) { + opI = RegInfo->moveImm2Reg(opBlock, opI, physReg, + (unsigned) opVal.getImmedValue(), + dataSize); + saveVirtRegToStack(opBlock, opI, virtualReg, physReg); + } else { + // Allocate a physical register and add a move in the BB + unsigned opVirtualReg = (unsigned) opVal.getAllocatedRegNum(); + unsigned opPhysReg; + opI = moveUseToReg(opBlock, opI, opVirtualReg, physReg); + + // Save that register value to the stack of the TARGET REG + saveVirtRegToStack(opBlock, opI, virtualReg, physReg); + } } - + // make regs available to other instructions clearAllRegs(); } -- 2.34.1