Commit 69660557 by Jim Stichnoth

Subzero: Fix a couple of debugging tools.

1. Regalloc dump output was displaying status updates for the wrong variable in some cases. 2. getPhysicalRegister() creates a variable for referring to a specific physical register for low-level purposes, such as the stack pointer, or the frame pointer, or a pushed/popped callee-save register. We change its behavior so that all such physical registers do not have their liveness tracked/validated, not just the stack pointer. For #2, the original behavior was causing a liveness validation failure if a function had a single basic block and used callee-save registers, and the -asm-verbose flag was used. This is because -asm-verbose runs a final liveness pass after the prolog/epilog are generated, and the initial callee-save register pushes would make it look like single-basic-block variables are live coming into a basic block, which is a hallmark of a liveness problem. BUG= none R=jpp@chromium.org Review URL: https://codereview.chromium.org/1353923004 .
parent 6d47bcdc
......@@ -520,7 +520,7 @@ protected:
bool IsImplicitArgument = false;
/// IgnoreLiveness means that the variable should be ignored when constructing
/// and validating live ranges. This is usually reserved for the stack
/// pointer.
/// pointer and other physical registers specifically referenced by name.
bool IgnoreLiveness = false;
RegRequirement RegRequirement = RR_MayHaveRegister;
/// RegNum is the allocated register, or NoRegister if it isn't
......
......@@ -339,12 +339,12 @@ void LinearScan::handleActiveRangeExpiredOrInactive(const Variable *Cur) {
bool Moved = false;
if (Item->rangeEndsBefore(Cur)) {
// Move Item from Active to Handled list.
dumpLiveRangeTrace("Expiring ", Cur);
dumpLiveRangeTrace("Expiring ", Item);
moveItem(Active, Index, Handled);
Moved = true;
} else if (!Item->rangeOverlapsStart(Cur)) {
// Move Item from Active to Inactive list.
dumpLiveRangeTrace("Inactivating ", Cur);
dumpLiveRangeTrace("Inactivating ", Item);
moveItem(Active, Index, Inactive);
Moved = true;
}
......@@ -368,11 +368,11 @@ void LinearScan::handleInactiveRangeExpiredOrReactivated(const Variable *Cur) {
Item->trimLiveRange(Cur->getLiveRange().getStart());
if (Item->rangeEndsBefore(Cur)) {
// Move Item from Inactive to Handled list.
dumpLiveRangeTrace("Expiring ", Cur);
dumpLiveRangeTrace("Expiring ", Item);
moveItem(Inactive, Index, Handled);
} else if (Item->rangeOverlapsStart(Cur)) {
// Move Item from Inactive to Active list.
dumpLiveRangeTrace("Reactivating ", Cur);
dumpLiveRangeTrace("Reactivating ", Item);
moveItem(Inactive, Index, Active);
// Increment Item in RegUses[].
assert(Item->hasRegTmp());
......
......@@ -389,12 +389,12 @@ Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) {
Reg = Func->makeVariable(Ty);
Reg->setRegNum(RegNum);
PhysicalRegisters[Ty][RegNum] = Reg;
// Specially mark SP and LR as an "argument" so that it is considered live
// upon function entry.
if (RegNum == RegARM32::Reg_sp || RegNum == RegARM32::Reg_lr) {
Func->addImplicitArg(Reg);
Reg->setIgnoreLiveness();
}
// Specially mark a named physical register as an "argument" so that it is
// considered live upon function entry. Otherwise it's possible to get
// liveness validation errors for saving callee-save registers.
Func->addImplicitArg(Reg);
// Don't bother tracking the live range of a named physical register.
Reg->setIgnoreLiveness();
}
return Reg;
}
......
......@@ -243,12 +243,12 @@ Variable *TargetMIPS32::getPhysicalRegister(SizeT RegNum, Type Ty) {
Reg = Func->makeVariable(Ty);
Reg->setRegNum(RegNum);
PhysicalRegisters[Ty][RegNum] = Reg;
// Specially mark SP as an "argument" so that it is considered live upon
// function entry.
if (RegNum == RegMIPS32::Reg_SP || RegNum == RegMIPS32::Reg_RA) {
Func->addImplicitArg(Reg);
Reg->setIgnoreLiveness();
}
// Specially mark a named physical register as an "argument" so that it is
// considered live upon function entry. Otherwise it's possible to get
// liveness validation errors for saving callee-save registers.
Func->addImplicitArg(Reg);
// Don't bother tracking the live range of a named physical register.
Reg->setIgnoreLiveness();
}
return Reg;
}
......
......@@ -720,12 +720,12 @@ Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) {
Reg = Func->makeVariable(Ty);
Reg->setRegNum(RegNum);
PhysicalRegisters[Ty][RegNum] = Reg;
// Specially mark esp as an "argument" so that it is considered live upon
// function entry.
if (RegNum == Traits::RegisterSet::Reg_esp) {
Func->addImplicitArg(Reg);
Reg->setIgnoreLiveness();
}
// Specially mark a named physical register as an "argument" so that it is
// considered live upon function entry. Otherwise it's possible to get
// liveness validation errors for saving callee-save registers.
Func->addImplicitArg(Reg);
// Don't bother tracking the live range of a named physical register.
Reg->setIgnoreLiveness();
}
return Reg;
}
......
; Tests that -asm-verbose doesn't fail liveness validation because of
; callee-save pushes/pops in a single-basic-block function.
; REQUIRES: allow_dump
; RUN: %p2i --target x8632 -i %s --filetype=asm --args -O2 -asm-verbose \
; RUN: | FileCheck %s
; TODO(stichnot,jpp): Enable for x8664 and arm32.
; RUIN: %p2i --target x8664 -i %s --filetype=asm --args -O2 -asm-verbose \
; RUIN: | FileCheck %s
; RUIN: %p2i --target arm32 -i %s --filetype=asm --args -O2 -asm-verbose \
; RUIN: | FileCheck %s
define i32 @single_bb(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) {
b1:
%t1 = add i32 %arg0, %arg1
%t2 = add i32 %t1, %arg2
%t3 = add i32 %t2, %arg3
%t4 = add i32 %t3, %arg4
%t5 = add i32 %t4, %arg5
%t6 = add i32 %t5, %arg6
%t7 = add i32 %t6, %arg7
ret i32 %t7
}
; CHECK-LABEL: single_bb
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment