[llvm-commits] [regalloc_linearscan] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp
Alkis Evlogimenos
alkis at cs.uiuc.edu
Sat Nov 15 12:34:02 PST 2003
Changes in directory llvm/lib/CodeGen:
RegAllocLinearScan.cpp updated: 1.1.2.12 -> 1.1.2.13
---
Log message:
Make register allocation more aggressive. As a result two-addr
instructions end up preventing a copy (a = b op c -> a = b, a = a op c
in the general case; we avoid a = b if this is b's last use).
When spilled defined operands are used do not load them if this is not
a use (no need to insert extra load if we are redefining the value).
---
Diffs of the changes: (+88 -74)
Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp
diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.12 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.13
--- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.12 Thu Nov 13 03:49:50 2003
+++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Sat Nov 15 12:33:33 2003
@@ -222,10 +222,6 @@
inactive_.end()));
DEBUG(printVirt2PhysMap());
- // process the active intervals (this will potentially
- // expire intervals and hence free physical registers)
- processActiveIntervals(curIndex);
-
// FIXME: holes are completely ignored for now
// processInactiveIntervals(curIndex);
@@ -238,20 +234,6 @@
reservePhysReg(physReg);
}
- // loop over operands and spill all already defined
- // physical registers
- DEBUG(std::cerr << "\t\tprocessing already allocated physical "
- "registers:\n");
- for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
- i != e; ++i) {
- MachineOperand& op = (*currentInstr_)->getOperand(i);
- if (op.isPhysicalRegister() &&
- (op.opIsDefOnly() || op.opIsDefAndUse())) {
- unsigned physReg = op.getAllocatedRegNum();
- reservePhysReg(physReg);
- }
- }
-
// assign physical registers to used operands
DEBUG(std::cerr << "\t\tprocessing used operands:\n");
for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
@@ -276,9 +258,57 @@
}
}
+ // loop over killed physical registers and clear them
+ DEBUG(std::cerr << "\t\tprocessing killed physical registers:\n");
+ for (LiveVariables::killed_iterator
+ ki = lv_->killed_begin(*currentInstr_),
+ ke = lv_->killed_end(*currentInstr_);
+ ki != ke; ++ki) {
+ unsigned reg = ki->second;
+ if (reg < MRegisterInfo::FirstVirtualRegister) {
+ clearReservedPhysReg(reg);
+ }
+ }
+
+ // loop over dead physical registers and clear them
+ DEBUG(std::cerr << "\t\tprocessing dead physical registers:\n");
+ for (LiveVariables::killed_iterator
+ ki = lv_->dead_begin(*currentInstr_),
+ ke = lv_->dead_end(*currentInstr_);
+ ki != ke; ++ki) {
+ unsigned reg = ki->second;
+ if (reg < MRegisterInfo::FirstVirtualRegister) {
+ clearReservedPhysReg(reg);
+ }
+ }
+
+
+ DEBUG(std::cerr << "\t\tclearing temporarily used operands:\n");
+ for (unsigned i = 0, e = tempUseOperands_.size(); i != e; ++i) {
+ clearVirtReg(tempUseOperands_[i]);
+ }
+
+ // this will expire intervals that are dead right after
+ // the execution of this instruction
+ processActiveIntervals(curIndex + 1);
+
processInterval(curIndex);
- // assign physical registers to used operands
+ // loop over operands and spill all already defined
+ // physical registers
+ DEBUG(std::cerr << "\t\tprocessing already allocated physical "
+ "registers:\n");
+ for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
+ i != e; ++i) {
+ MachineOperand& op = (*currentInstr_)->getOperand(i);
+ if (op.isPhysicalRegister() &&
+ (op.opIsDefOnly() || op.opIsDefAndUse())) {
+ unsigned physReg = op.getAllocatedRegNum();
+ reservePhysReg(physReg);
+ }
+ }
+
+ // assign physical registers to not allocated defined operands
DEBUG(std::cerr << "\t\tprocessing not allocated defined "
"operands:\n");
for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
@@ -297,7 +327,14 @@
physReg = getFreePhysReg(virtReg);
}
assert(physReg && "no available physical register?!");
- loadVirt2PhysReg(virtReg, physReg);
+ // load from stack only if we are going to use the value
+ if (op.opIsDefAndUse()) {
+ loadVirt2PhysReg(virtReg, physReg);
+ }
+ // otherwise just assign the mapping
+ else {
+ allocateVirt2PhysReg(virtReg, physReg);
+ }
tempDefOperands_.push_back(virtReg);
}
(*currentInstr_)->SetMachineOperandReg(i, v2pMap_[virtReg]);
@@ -321,35 +358,36 @@
}
}
- // loop over killed physical registers and clear them
- DEBUG(std::cerr << "\t\tprocessing killed physical registers:\n");
- for (LiveVariables::killed_iterator
- ki = lv_->killed_begin(*currentInstr_),
- ke = lv_->killed_end(*currentInstr_);
- ki != ke; ++ki) {
- unsigned reg = ki->second;
- if (reg < MRegisterInfo::FirstVirtualRegister) {
- clearReservedPhysReg(reg);
- }
- }
-
- // loop over dead physical registers and clear them
- DEBUG(std::cerr << "\t\tprocessing dead physical registers:\n");
- for (LiveVariables::killed_iterator
- ki = lv_->dead_begin(*currentInstr_),
- ke = lv_->dead_end(*currentInstr_);
- ki != ke; ++ki) {
- unsigned reg = ki->second;
- if (reg < MRegisterInfo::FirstVirtualRegister) {
- clearReservedPhysReg(reg);
- }
+ // if the instructions is a two address instruction:
+ //
+ //"a = b + c" but a and b must be the same register,
+ //insert "a = b" before it and make the original
+ //instruction "a = a + c")
+
+ if (tm_->getInstrInfo().isTwoAddrInstr(
+ (*currentInstr_)->getOpcode())) {
+ assert((*currentInstr_)->getOperand(1).isRegister() &&
+ (*currentInstr_)->getOperand(1).getAllocatedRegNum() &&
+ (*currentInstr_)->getOperand(1).opIsUse() &&
+ "Two address instruction invalid");
+
+ unsigned regA =
+ (*currentInstr_)->getOperand(0).getAllocatedRegNum();
+ unsigned regB =
+ (*currentInstr_)->getOperand(1).getAllocatedRegNum();
+ const TargetRegisterClass* rc = mri_->getRegClass(regA);
+
+ instrAdded_ += mri_->copyRegToReg(*currentMbb_,
+ currentInstr_,
+ regA,
+ regB,
+ rc);
+ tempUseOperands_.erase(remove(tempUseOperands_.begin(),
+ tempUseOperands_.end(),
+ regB),
+ tempUseOperands_.end());
+ (*currentInstr_)->SetMachineOperandReg(1, regA);
}
-
- DEBUG(std::cerr << "\t\tclearing temporarily used operands:\n");
- for (unsigned i = 0, e = tempUseOperands_.size(); i != e; ++i) {
- clearVirtReg(tempUseOperands_[i]);
- }
-
DEBUG(std::cerr << "\t\tspilling temporarily defined operands:\n");
for (unsigned i = 0, e = tempDefOperands_.size(); i != e; ++i) {
spillVirtReg(tempDefOperands_[i]);
@@ -379,31 +417,7 @@
currentInterval_->start() == curIndex) {
DEBUG(std::cerr << "\t\tprocessing current interval:\n");
unsigned virtReg = currentInterval_->reg;
- unsigned physReg = (unsigned) -1;
- if (tm_->getInstrInfo().isTwoAddrInstr((*currentInstr_)->getOpcode())) {
- assert((*currentInstr_)->getOperand(1).isRegister() &&
- (*currentInstr_)->getOperand(1).getAllocatedRegNum() &&
- (*currentInstr_)->getOperand(1).opIsUse() &&
- "Two address instruction invalid");
-
- physReg = (*currentInstr_)->getOperand(1).getAllocatedRegNum();
- // remove interval from active
- for (IntervalPtrs::iterator i = active_.begin(), e = active_.end();
- i != e; ++i) {
- if ((*i)->reg == p2vMap_[physReg]) {
- active_.erase(i);
- break;
- }
- }
- tempUseOperands_.erase(remove(tempUseOperands_.begin(),
- tempUseOperands_.end(),
- p2vMap_[physReg]),
- tempUseOperands_.end());
- spillVirtReg(p2vMap_[physReg]);
- }
- else {
- physReg = getFreePhysReg(virtReg);
- }
+ unsigned physReg = getFreePhysReg(virtReg);
if (!physReg) {
spillInterval();
@@ -454,7 +468,7 @@
// // remove from inactive
// i = inactive_.erase(i);
// }
-// // move re-activated intervals in active list
+// // move re-activated intervals in active list
// else if ((*i)->overlaps(curIndex)) {
// DEBUG(std::cerr << "\t\t\tinterval " << **i << " active\n");
// markReg(virtReg);
More information about the llvm-commits
mailing list