diff --git a/lib/CodeGen/RegAllocSimple.cpp b/lib/CodeGen/RegAllocSimple.cpp index 978e927c36e..c7348d51654 100644 --- a/lib/CodeGen/RegAllocSimple.cpp +++ b/lib/CodeGen/RegAllocSimple.cpp @@ -60,10 +60,8 @@ namespace { std::map RegsUsed; std::map RegClassIdx; - RegAllocSimple(TargetMachine &tm) : TM(tm), - RegInfo(tm.getRegisterInfo()), - PhysRegClasses(RegInfo) - { + RegAllocSimple(TargetMachine &tm) + : TM(tm), RegInfo(tm.getRegisterInfo()), PhysRegClasses(RegInfo) { RegsUsed[RegInfo->getFramePointer()] = 1; RegsUsed[RegInfo->getStackPointer()] = 1; @@ -75,7 +73,8 @@ namespace { return RegsUsed.find(Reg) == RegsUsed.end(); } - /// + /// allocateStackSpaceFor - This allocates space for the specified virtual + /// register to be held on the stack. unsigned allocateStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *regClass); @@ -85,7 +84,7 @@ namespace { /// Returns all `borrowed' registers back to the free pool void clearAllRegs() { - RegClassIdx.clear(); + RegClassIdx.clear(); } /// Invalidates any references, real or implicit, to physical registers @@ -106,23 +105,23 @@ namespace { void cleanupAfterFunction() { VirtReg2OffsetMap.clear(); SSA2PhysRegMap.clear(); - NumBytesAllocated = 4; /* FIXME: This is X86 specific */ + NumBytesAllocated = 4; // FIXME: This is X86 specific } /// Moves value from memory into that register MachineBasicBlock::iterator - moveUseToReg (MachineBasicBlock *MBB, + moveUseToReg (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned VirtReg, unsigned &PhysReg); /// Saves reg value on the stack (maps virtual register to stack value) MachineBasicBlock::iterator - saveVirtRegToStack (MachineBasicBlock *MBB, + saveVirtRegToStack (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned VirtReg, unsigned PhysReg); MachineBasicBlock::iterator - savePhysRegToStack (MachineBasicBlock *MBB, + savePhysRegToStack (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned PhysReg); /// runOnFunction - Top level implementation of instruction selection for @@ -130,6 +129,13 @@ namespace { /// bool runOnMachineFunction(MachineFunction &Fn); + /// AllocateBasicBlock - Register allocate the specified basic block. + void AllocateBasicBlock(MachineBasicBlock &MBB); + + /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions + /// in predecessor basic blocks. + void EliminatePHINodes(MachineBasicBlock &MBB); + bool runOnFunction(Function &Fn) { return runOnMachineFunction(MachineFunction::get(&Fn)); } @@ -137,6 +143,8 @@ namespace { } +/// allocateStackSpaceFor - This allocates space for the specified virtual +/// register to be held on the stack. unsigned RegAllocSimple::allocateStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *regClass) { @@ -180,7 +188,7 @@ unsigned RegAllocSimple::getFreeReg(unsigned virtualReg) { } MachineBasicBlock::iterator -RegAllocSimple::moveUseToReg (MachineBasicBlock *MBB, +RegAllocSimple::moveUseToReg (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned VirtReg, unsigned &PhysReg) { @@ -191,13 +199,13 @@ RegAllocSimple::moveUseToReg (MachineBasicBlock *MBB, PhysReg = getFreeReg(VirtReg); // Add move instruction(s) - return RegInfo->loadRegOffset2Reg(MBB, I, PhysReg, + return RegInfo->loadRegOffset2Reg(&MBB, I, PhysReg, RegInfo->getFramePointer(), -stackOffset, regClass->getDataSize()); } MachineBasicBlock::iterator -RegAllocSimple::saveVirtRegToStack (MachineBasicBlock *MBB, +RegAllocSimple::saveVirtRegToStack (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned VirtReg, unsigned PhysReg) { @@ -207,13 +215,13 @@ RegAllocSimple::saveVirtRegToStack (MachineBasicBlock *MBB, unsigned stackOffset = allocateStackSpaceFor(VirtReg, regClass); // Add move instruction(s) - return RegInfo->storeReg2RegOffset(MBB, I, PhysReg, + return RegInfo->storeReg2RegOffset(&MBB, I, PhysReg, RegInfo->getFramePointer(), -stackOffset, regClass->getDataSize()); } MachineBasicBlock::iterator -RegAllocSimple::savePhysRegToStack (MachineBasicBlock *MBB, +RegAllocSimple::savePhysRegToStack (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned PhysReg) { @@ -223,157 +231,157 @@ RegAllocSimple::savePhysRegToStack (MachineBasicBlock *MBB, unsigned offset = allocateStackSpaceFor(PhysReg, regClass); // Add move instruction(s) - return RegInfo->storeReg2RegOffset(MBB, I, PhysReg, + return RegInfo->storeReg2RegOffset(&MBB, I, PhysReg, RegInfo->getFramePointer(), offset, regClass->getDataSize()); } -bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) { - cleanupAfterFunction(); +/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in +/// predecessor basic blocks. +void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) { + while (MBB.front()->getOpcode() == 0) { + MachineInstr *MI = MBB.front(); + // get rid of the phi + MBB.erase(MBB.begin()); + + // a preliminary pass that will invalidate any registers that + // are used by the instruction (including implicit uses) + invalidatePhysRegs(MI); + + DEBUG(std::cerr << "num invalid regs: " << RegsUsed.size() << "\n"); + + DEBUG(std::cerr << "num ops: " << MI->getNumOperands() << "\n"); + MachineOperand &targetReg = MI->getOperand(0); + + // If it's a virtual register, allocate a physical one + // otherwise, just use whatever register is there now + // note: it MUST be a register -- we're assigning to it + unsigned virtualReg = (unsigned) targetReg.getAllocatedRegNum(); + unsigned physReg; + if (targetReg.isVirtualRegister()) { + physReg = getFreeReg(virtualReg); + } else { + physReg = virtualReg; + } + + // Find the register class of the target register: should be the + // same as the values we're trying to store there + 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; + const MachineInstrInfo &MII = TM.getInstrInfo(); - unsigned virtualReg, physReg; + // 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; // = getFreeReg(opVirtualReg); + opI = moveUseToReg(opBlock, opI, opVirtualReg, physReg); + //opI = RegInfo->moveReg2Reg(opBlock, opI, physReg, opPhysReg, + // dataSize); + // Save that register value to the stack of the TARGET REG + saveVirtRegToStack(opBlock, opI, virtualReg, physReg); + } + + // make regs available to other instructions + clearAllRegs(); + } + + // really delete the instruction + delete MI; + } +} + + +void RegAllocSimple::AllocateBasicBlock(MachineBasicBlock &MBB) { + // Handle PHI instructions specially: add moves to each pred block + EliminatePHINodes(MBB); + + //loop over each basic block + for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) { + MachineInstr *MI = *I; + + // a preliminary pass that will invalidate any registers that + // are used by the instruction (including implicit uses) + invalidatePhysRegs(MI); + + // Loop over uses, move from memory into registers + for (int i = MI->getNumOperands() - 1; i >= 0; --i) { + MachineOperand &op = MI->getOperand(i); + + if (op.isImmediate()) { + DEBUG(std::cerr << "const\n"); + } else if (op.isVirtualRegister()) { + unsigned virtualReg = (unsigned) op.getAllocatedRegNum(); + DEBUG(std::cerr << "op: " << op << "\n"); + DEBUG(std::cerr << "\t inst[" << i << "]: "; + MI->print(std::cerr, TM)); + + // make sure the same virtual register maps to the same physical + // register in any given instruction + unsigned physReg; + if (VirtReg2PhysRegMap.find(virtualReg) != VirtReg2PhysRegMap.end()) { + physReg = VirtReg2PhysRegMap[virtualReg]; + } else { + if (op.opIsDef()) { + if (TM.getInstrInfo().isTwoAddrInstr(MI->getOpcode()) && i == 0) { + // must be same register number as the first operand + // This maps a = b + c into b += c, and saves b into a's spot + physReg = (unsigned) MI->getOperand(1).getAllocatedRegNum(); + } else { + physReg = getFreeReg(virtualReg); + } + MachineBasicBlock::iterator J = I; + J = saveVirtRegToStack(MBB, ++J, virtualReg, physReg); + I = --J; + } else { + I = moveUseToReg(MBB, I, virtualReg, physReg); + } + VirtReg2PhysRegMap[virtualReg] = physReg; + } + MI->SetMachineOperandReg(i, physReg); + DEBUG(std::cerr << "virt: " << virtualReg << + ", phys: " << op.getAllocatedRegNum() << "\n"); + } + } + + clearAllRegs(); + VirtReg2PhysRegMap.clear(); + } +} + +bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) { DEBUG(std::cerr << "Machine Function " << "\n"); MF = &Fn; for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); MBB != MBBe; ++MBB) - { - MachineBasicBlock *CurrMBB = &(*MBB); - - // Handle PHI instructions specially: add moves to each pred block - while (MBB->front()->getOpcode() == 0) { - MachineInstr *MI = MBB->front(); - // get rid of the phi - MBB->erase(MBB->begin()); - - // a preliminary pass that will invalidate any registers that - // are used by the instruction (including implicit uses) - invalidatePhysRegs(MI); - - DEBUG(std::cerr << "num invalid regs: " << RegsUsed.size() << "\n"); - - DEBUG(std::cerr << "num ops: " << MI->getNumOperands() << "\n"); - MachineOperand &targetReg = MI->getOperand(0); - - // If it's a virtual register, allocate a physical one - // otherwise, just use whatever register is there now - // note: it MUST be a register -- we're assigning to it - virtualReg = (unsigned) targetReg.getAllocatedRegNum(); - if (targetReg.isVirtualRegister()) { - physReg = getFreeReg(virtualReg); - } else { - physReg = virtualReg; - } - - // Find the register class of the target register: should be the - // same as the values we're trying to store there - 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); - const MachineInstrInfo &MII = TM.getInstrInfo(); - // must backtrack over ALL the branches in the previous block, until no more - while ((MII.isBranch(opMI->getOpcode()) || MII.isReturn(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 - ++opI; - - - // Retrieve the constant value from this op, move it to target - // register of the phi - if (opVal.getType() == MachineOperand::MO_SignExtendedImmed || - opVal.getType() == MachineOperand::MO_UnextendedImmed) - { - 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; // = getFreeReg(opVirtualReg); - opI = moveUseToReg(opBlock, opI, opVirtualReg, physReg); - //opI = RegInfo->moveReg2Reg(opBlock, opI, physReg, opPhysReg, - // dataSize); - // Save that register value to the stack of the TARGET REG - saveVirtRegToStack(opBlock, opI, virtualReg, physReg); - } - - // make regs available to other instructions - clearAllRegs(); - } - - // really delete the instruction - delete MI; - } - - //loop over each basic block - for (MachineBasicBlock::iterator I = MBB->begin(); I != MBB->end(); ++I) - { - MachineInstr *MI = *I; - - // a preliminary pass that will invalidate any registers that - // are used by the instruction (including implicit uses) - invalidatePhysRegs(MI); - - // Loop over uses, move from memory into registers - for (int i = MI->getNumOperands() - 1; i >= 0; --i) { - MachineOperand &op = MI->getOperand(i); - - if (op.getType() == MachineOperand::MO_SignExtendedImmed || - op.getType() == MachineOperand::MO_UnextendedImmed) - { - DEBUG(std::cerr << "const\n"); - } else if (op.isVirtualRegister()) { - virtualReg = (unsigned) op.getAllocatedRegNum(); - DEBUG(std::cerr << "op: " << op << "\n"); - DEBUG(std::cerr << "\t inst[" << i << "]: "; - MI->print(std::cerr, TM)); - - // make sure the same virtual register maps to the same physical - // register in any given instruction - if (VirtReg2PhysRegMap.find(virtualReg) != VirtReg2PhysRegMap.end()) { - physReg = VirtReg2PhysRegMap[virtualReg]; - } else { - if (op.opIsDef()) { - if (TM.getInstrInfo().isTwoAddrInstr(MI->getOpcode()) && i == 0) { - // must be same register number as the first operand - // This maps a = b + c into b += c, and saves b into a's spot - physReg = (unsigned) MI->getOperand(1).getAllocatedRegNum(); - } else { - physReg = getFreeReg(virtualReg); - } - MachineBasicBlock::iterator J = I; - J = saveVirtRegToStack(CurrMBB, ++J, virtualReg, physReg); - I = --J; - } else { - I = moveUseToReg(CurrMBB, I, virtualReg, physReg); - } - VirtReg2PhysRegMap[virtualReg] = physReg; - } - MI->SetMachineOperandReg(i, physReg); - DEBUG(std::cerr << "virt: " << virtualReg << - ", phys: " << op.getAllocatedRegNum() << "\n"); - } - } - - clearAllRegs(); - VirtReg2PhysRegMap.clear(); - } - - } + AllocateBasicBlock(*MBB); // add prologue we should preserve callee-save registers... MachineFunction::iterator Fi = Fn.begin(); @@ -381,21 +389,22 @@ bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) { MachineBasicBlock::iterator MBBi = MBB->begin(); RegInfo->emitPrologue(MBB, MBBi, NumBytesAllocated); + const MachineInstrInfo &MII = TM.getInstrInfo(); + // add epilogue to restore the callee-save registers // loop over the basic block for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); - MBB != MBBe; ++MBB) - { + MBB != MBBe; ++MBB) { // check if last instruction is a RET - MachineBasicBlock::iterator I = (*MBB).end(); - MachineInstr *MI = *(--I); - const MachineInstrInfo &MII = TM.getInstrInfo(); + MachineBasicBlock::iterator I = MBB->end(); + MachineInstr *MI = *--I; if (MII.isReturn(MI->getOpcode())) { // this block has a return instruction, add epilogue RegInfo->emitEpilogue(MBB, I, NumBytesAllocated); } } + cleanupAfterFunction(); return false; // We never modify the LLVM itself. }