From a71e05acdd7c6a8e815db46b5fb6dc1d87826aab Mon Sep 17 00:00:00 2001 From: Alkis Evlogimenos Date: Thu, 18 Dec 2003 13:15:02 +0000 Subject: [PATCH] Modify linear scan register allocator to use the two-address instruction pass. This also fixes all remaining bugs for this new allocator to pass all tests under test/Programs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10515 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveIntervalAnalysis.cpp | 2 + lib/CodeGen/RegAllocLinearScan.cpp | 113 +++++++++------------------ 2 files changed, 39 insertions(+), 76 deletions(-) diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index e5171ad5c48..d818d0b7b01 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -24,6 +24,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SSARegMap.h" +#include "llvm/CodeGen/TwoAddressInstructionPass.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -49,6 +50,7 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const AU.addRequired(); AU.addPreservedID(PHIEliminationID); AU.addRequiredID(PHIEliminationID); + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index 53fb1da606d..89c239678ef 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -84,6 +84,11 @@ namespace { /// runOnMachineFunction - register allocate the whole function bool runOnMachineFunction(MachineFunction&); + /// verifyIntervals - verify that we have no inconsistencies + /// in the register assignments we have in active and inactive + /// lists + bool verifyIntervals(); + /// processActiveIntervals - expire old intervals and move /// non-overlapping ones to the incative list void processActiveIntervals(Intervals::const_iterator cur); @@ -245,6 +250,8 @@ bool RA::runOnMachineFunction(MachineFunction &fn) { DEBUG(printIntervals("\tactive", active_.begin(), active_.end())); DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end())); + assert(verifyIntervals()); + processActiveIntervals(i); // processInactiveIntervals(i); @@ -321,7 +328,7 @@ bool RA::runOnMachineFunction(MachineFunction &fn) { for (unsigned i = 0, e = (*currentInstr_)->getNumOperands(); i != e; ++i) { MachineOperand& op = (*currentInstr_)->getOperand(i); - if (op.isVirtualRegister() && op.isUse()) { + if (op.isVirtualRegister() && op.isUse() && !op.isDef()) { unsigned virtReg = op.getAllocatedRegNum(); unsigned physReg = v2pMap_[virtReg]; if (!physReg) { @@ -361,81 +368,6 @@ bool RA::runOnMachineFunction(MachineFunction &fn) { } } - - // if the instruction is a two address instruction and the - // source operands are not identical we need to insert - // extra instructions. - - unsigned opcode = (*currentInstr_)->getOpcode(); - if (tm_->getInstrInfo().isTwoAddrInstr(opcode) && - (*currentInstr_)->getOperand(0).getAllocatedRegNum() != - (*currentInstr_)->getOperand(1).getAllocatedRegNum()) { - assert((*currentInstr_)->getOperand(1).isRegister() && - (*currentInstr_)->getOperand(1).getAllocatedRegNum() && - (*currentInstr_)->getOperand(1).isUse() && - "Two address instruction invalid"); - - unsigned regA = - (*currentInstr_)->getOperand(0).getAllocatedRegNum(); - unsigned regB = - (*currentInstr_)->getOperand(1).getAllocatedRegNum(); - unsigned regC = - ((*currentInstr_)->getNumOperands() > 2 && - (*currentInstr_)->getOperand(2).isRegister()) ? - (*currentInstr_)->getOperand(2).getAllocatedRegNum() : - 0; - - const TargetRegisterClass* rc = mri_->getRegClass(regA); - - // special case: "a = b op a". If b is a temporary - // reserved register rewrite as: "b = b op a; a = b" - // otherwise use a temporary reserved register t and - // rewrite as: "t = b; t = t op a; a = t" - if (regC && regA == regC) { - // b is a temp reserved register - if (find(reserved_.begin(), reserved_.end(), - regB) != reserved_.end()) { - (*currentInstr_)->SetMachineOperandReg(0, regB); - ++currentInstr_; - instrAdded_ += mri_->copyRegToReg(*currentMbb_, - currentInstr_, - regA, - regB, - rc); - --currentInstr_; - } - // b is just a normal register - else { - unsigned tempReg = getFreeTempPhysReg(rc); - assert (tempReg && - "no free temp reserved physical register?"); - instrAdded_ += mri_->copyRegToReg(*currentMbb_, - currentInstr_, - tempReg, - regB, - rc); - (*currentInstr_)->SetMachineOperandReg(0, tempReg); - (*currentInstr_)->SetMachineOperandReg(1, tempReg); - ++currentInstr_; - instrAdded_ += mri_->copyRegToReg(*currentMbb_, - currentInstr_, - regA, - tempReg, - rc); - --currentInstr_; - } - } - // "a = b op c" gets rewritten to "a = b; a = a op c" - else { - instrAdded_ += mri_->copyRegToReg(*currentMbb_, - currentInstr_, - regA, - regB, - rc); - (*currentInstr_)->SetMachineOperandReg(1, regA); - } - } - DEBUG(std::cerr << "\t\tspilling temporarily defined operands " "of this instruction:\n"); ++currentInstr_; // we want to insert after this instruction @@ -455,6 +387,35 @@ bool RA::runOnMachineFunction(MachineFunction &fn) { return true; } +bool RA::verifyIntervals() +{ + std::set assignedRegisters; + for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) { + if ((*i)->reg >= MRegisterInfo::FirstVirtualRegister) { + unsigned reg = v2pMap_.find((*i)->reg)->second; + + bool inserted = assignedRegisters.insert(reg).second; + assert(inserted && "registers in active list conflict"); + } + } + + for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) { + unsigned reg = (*i)->reg; + if (reg >= MRegisterInfo::FirstVirtualRegister) { + reg = v2pMap_.find((*i)->reg)->second; + } + + for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as) { + assert(assignedRegisters.find(*as) == assignedRegisters.end() && + "registers in active list alias each other"); + } + } + + // TODO: add checks between active and inactive and make sure we + // do not overlap anywhere + return true; +} + void RA::processActiveIntervals(Intervals::const_iterator cur) { DEBUG(std::cerr << "\tprocessing active intervals:\n");