mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 04:09:45 +00:00
Fix physical register liveness calculations:
+ Take account of clobbers + Give outputs priority over inputs since they happen later. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168360 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4fe5405bdd
commit
310f248c22
@ -149,16 +149,13 @@ public:
|
||||
/// PhysRegInfo - Information about a physical register used by a set of
|
||||
/// operands.
|
||||
struct PhysRegInfo {
|
||||
/// Clobbers - Reg or an overlapping register is defined, or a regmask
|
||||
/// Clobbers - Reg or an overlapping register is defined, or a regmask
|
||||
/// clobbers Reg.
|
||||
bool Clobbers;
|
||||
|
||||
/// Defines - Reg or a super-register is defined.
|
||||
bool Defines;
|
||||
|
||||
/// DefinesOverlap - Reg or an overlapping register is defined.
|
||||
bool DefinesOverlap;
|
||||
|
||||
/// Reads - Read or a super-register is read.
|
||||
bool Reads;
|
||||
|
||||
|
@ -982,7 +982,6 @@ MachineBasicBlock::LivenessQueryResult
|
||||
MachineBasicBlock::computeRegisterLiveness(const TargetRegisterInfo *TRI,
|
||||
unsigned Reg, MachineInstr *MI,
|
||||
unsigned Neighborhood) {
|
||||
|
||||
unsigned N = Neighborhood;
|
||||
MachineBasicBlock *MBB = MI->getParent();
|
||||
|
||||
@ -997,14 +996,18 @@ MachineBasicBlock::computeRegisterLiveness(const TargetRegisterInfo *TRI,
|
||||
MachineOperandIteratorBase::PhysRegInfo Analysis =
|
||||
MIOperands(I).analyzePhysReg(Reg, TRI);
|
||||
|
||||
if (Analysis.Kills)
|
||||
if (Analysis.Defines)
|
||||
// Outputs happen after inputs so they take precedence if both are
|
||||
// present.
|
||||
return Analysis.DefinesDead ? LQR_Dead : LQR_Live;
|
||||
|
||||
if (Analysis.Kills || Analysis.Clobbers)
|
||||
// Register killed, so isn't live.
|
||||
return LQR_Dead;
|
||||
|
||||
else if (Analysis.DefinesOverlap || Analysis.ReadsOverlap)
|
||||
else if (Analysis.ReadsOverlap)
|
||||
// Defined or read without a previous kill - live.
|
||||
return (Analysis.Defines || Analysis.Reads) ?
|
||||
LQR_Live : LQR_OverlappingLive;
|
||||
return Analysis.Reads ? LQR_Live : LQR_OverlappingLive;
|
||||
|
||||
} while (I != MBB->begin() && --N > 0);
|
||||
}
|
||||
@ -1036,7 +1039,7 @@ MachineBasicBlock::computeRegisterLiveness(const TargetRegisterInfo *TRI,
|
||||
return (Analysis.Reads) ?
|
||||
LQR_Live : LQR_OverlappingLive;
|
||||
|
||||
else if (Analysis.DefinesOverlap)
|
||||
else if (Analysis.Clobbers || Analysis.Defines)
|
||||
// Defined (but not read) therefore cannot have been live.
|
||||
return LQR_Dead;
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ MachineOperandIteratorBase::PhysRegInfo
|
||||
MachineOperandIteratorBase::analyzePhysReg(unsigned Reg,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
bool AllDefsDead = true;
|
||||
PhysRegInfo PRI = {false, false, false, false, false, false, false};
|
||||
PhysRegInfo PRI = {false, false, false, false, false, false};
|
||||
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
|
||||
"analyzePhysReg not given a physical register!");
|
||||
@ -305,7 +305,9 @@ MachineOperandIteratorBase::analyzePhysReg(unsigned Reg,
|
||||
// Reg or a super-reg is read, and perhaps killed also.
|
||||
PRI.Reads = true;
|
||||
PRI.Kills = MO.isKill();
|
||||
} if (IsRegOrOverlapping && MO.readsReg()) {
|
||||
}
|
||||
|
||||
if (IsRegOrOverlapping && MO.readsReg()) {
|
||||
PRI.ReadsOverlap = true;// Reg or an overlapping register is read.
|
||||
}
|
||||
|
||||
|
@ -98,3 +98,23 @@ define i32 @test_vmovs_no_sreg(i32 %in) {
|
||||
|
||||
ret i32 %resi
|
||||
}
|
||||
|
||||
|
||||
; The point of this test is:
|
||||
; + Make sure s1 is live before the BL
|
||||
; + Make sure s1 is clobbered by the BL
|
||||
; + Convince LLVM to emit a VMOV to S0
|
||||
; + Convince LLVM to domain-convert this.
|
||||
|
||||
; When all of those are satisfied, LLVM should *not* mark s1 as an implicit-use
|
||||
; because it's dead.
|
||||
|
||||
declare float @clobbers_s1(float, float)
|
||||
|
||||
define <2 x float> @test_clobbers_recognised(<2 x float> %invec, float %val) {
|
||||
%elt = call float @clobbers_s1(float %val, float %val)
|
||||
|
||||
%vec = insertelement <2 x float> %invec, float %elt, i32 0
|
||||
%res = fadd <2 x float> %vec, %vec
|
||||
ret <2 x float> %res
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user