forked from OSchip/llvm-project
RegisterPressure: Fix default lanemask for missing regunit intervals
In case of missing live intervals for a physical registers getLanesWithProperty() would report 0 which was not a safe default in all situations. Add a parameter to pass in a safe default. No testcase because in-tree targets do not skip computing register unit live intervals. Also cleanup the getXXX() functions to not perform the RequireLiveIntervals checks anymore so we do not even need to return safe defaults. llvm-svn: 267977
This commit is contained in:
parent
5e4ac856d6
commit
f3619b8212
|
@ -382,7 +382,7 @@ static void removeRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
|
||||||
|
|
||||||
static LaneBitmask getLanesWithProperty(const LiveIntervals &LIS,
|
static LaneBitmask getLanesWithProperty(const LiveIntervals &LIS,
|
||||||
const MachineRegisterInfo &MRI, bool TrackLaneMasks, unsigned RegUnit,
|
const MachineRegisterInfo &MRI, bool TrackLaneMasks, unsigned RegUnit,
|
||||||
SlotIndex Pos,
|
SlotIndex Pos, LaneBitmask SafeDefault,
|
||||||
bool(*Property)(const LiveRange &LR, SlotIndex Pos)) {
|
bool(*Property)(const LiveRange &LR, SlotIndex Pos)) {
|
||||||
if (TargetRegisterInfo::isVirtualRegister(RegUnit)) {
|
if (TargetRegisterInfo::isVirtualRegister(RegUnit)) {
|
||||||
const LiveInterval &LI = LIS.getInterval(RegUnit);
|
const LiveInterval &LI = LIS.getInterval(RegUnit);
|
||||||
|
@ -402,7 +402,7 @@ static LaneBitmask getLanesWithProperty(const LiveIntervals &LIS,
|
||||||
// Be prepared for missing liveranges: We usually do not compute liveranges
|
// Be prepared for missing liveranges: We usually do not compute liveranges
|
||||||
// for physical registers on targets with many registers (GPUs).
|
// for physical registers on targets with many registers (GPUs).
|
||||||
if (LR == nullptr)
|
if (LR == nullptr)
|
||||||
return 0;
|
return SafeDefault;
|
||||||
return Property(*LR, Pos) ? ~0u : 0;
|
return Property(*LR, Pos) ? ~0u : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,7 @@ static LaneBitmask getLiveLanesAt(const LiveIntervals &LIS,
|
||||||
const MachineRegisterInfo &MRI,
|
const MachineRegisterInfo &MRI,
|
||||||
bool TrackLaneMasks, unsigned RegUnit,
|
bool TrackLaneMasks, unsigned RegUnit,
|
||||||
SlotIndex Pos) {
|
SlotIndex Pos) {
|
||||||
return getLanesWithProperty(LIS, MRI, TrackLaneMasks, RegUnit, Pos,
|
return getLanesWithProperty(LIS, MRI, TrackLaneMasks, RegUnit, Pos, ~0u,
|
||||||
[](const LiveRange &LR, SlotIndex Pos) {
|
[](const LiveRange &LR, SlotIndex Pos) {
|
||||||
return LR.liveAt(Pos);
|
return LR.liveAt(Pos);
|
||||||
});
|
});
|
||||||
|
@ -570,11 +570,11 @@ void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
|
||||||
AddFlagsMI != nullptr && (LiveAfter & ~I->LaneMask) == 0)
|
AddFlagsMI != nullptr && (LiveAfter & ~I->LaneMask) == 0)
|
||||||
AddFlagsMI->setRegisterDefReadUndef(RegUnit);
|
AddFlagsMI->setRegisterDefReadUndef(RegUnit);
|
||||||
|
|
||||||
LaneBitmask LaneMask = I->LaneMask & LiveAfter;
|
LaneBitmask ActualDef = I->LaneMask & LiveAfter;
|
||||||
if (LaneMask == 0) {
|
if (ActualDef == 0) {
|
||||||
I = Defs.erase(I);
|
I = Defs.erase(I);
|
||||||
} else {
|
} else {
|
||||||
I->LaneMask = LaneMask;
|
I->LaneMask = ActualDef;
|
||||||
++I;
|
++I;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -790,10 +790,12 @@ void RegPressureTracker::recede(const RegisterOperands &RegOpers,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discover live outs if this may be the first occurance of this register.
|
// Discover live outs if this may be the first occurance of this register.
|
||||||
|
if (RequireIntervals) {
|
||||||
LaneBitmask LiveOut = getLiveThroughAt(Reg, SlotIdx);
|
LaneBitmask LiveOut = getLiveThroughAt(Reg, SlotIdx);
|
||||||
if (LiveOut != 0)
|
if (LiveOut != 0)
|
||||||
discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
|
discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
increaseRegPressure(Reg, PreviousMask, NewMask);
|
increaseRegPressure(Reg, PreviousMask, NewMask);
|
||||||
}
|
}
|
||||||
|
@ -875,12 +877,14 @@ void RegPressureTracker::advance(const RegisterOperands &RegOpers) {
|
||||||
LiveRegs.insert(RegisterMaskPair(Reg, LiveIn));
|
LiveRegs.insert(RegisterMaskPair(Reg, LiveIn));
|
||||||
}
|
}
|
||||||
// Kill liveness at last uses.
|
// Kill liveness at last uses.
|
||||||
|
if (RequireIntervals) {
|
||||||
LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
|
LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
|
||||||
if (LastUseMask != 0) {
|
if (LastUseMask != 0) {
|
||||||
LiveRegs.erase(RegisterMaskPair(Reg, LastUseMask));
|
LiveRegs.erase(RegisterMaskPair(Reg, LastUseMask));
|
||||||
decreaseRegPressure(Reg, LiveMask, LiveMask & ~LastUseMask);
|
decreaseRegPressure(Reg, LiveMask, LiveMask & ~LastUseMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generate liveness for defs.
|
// Generate liveness for defs.
|
||||||
for (const RegisterMaskPair &Def : RegOpers.Defs) {
|
for (const RegisterMaskPair &Def : RegOpers.Defs) {
|
||||||
|
@ -1197,10 +1201,8 @@ static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
|
||||||
|
|
||||||
LaneBitmask RegPressureTracker::getLiveLanesAt(unsigned RegUnit,
|
LaneBitmask RegPressureTracker::getLiveLanesAt(unsigned RegUnit,
|
||||||
SlotIndex Pos) const {
|
SlotIndex Pos) const {
|
||||||
if (!RequireIntervals)
|
assert(RequireIntervals);
|
||||||
return 0;
|
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos, ~0u,
|
||||||
|
|
||||||
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
|
|
||||||
[](const LiveRange &LR, SlotIndex Pos) {
|
[](const LiveRange &LR, SlotIndex Pos) {
|
||||||
return LR.liveAt(Pos);
|
return LR.liveAt(Pos);
|
||||||
});
|
});
|
||||||
|
@ -1208,11 +1210,9 @@ LaneBitmask RegPressureTracker::getLiveLanesAt(unsigned RegUnit,
|
||||||
|
|
||||||
LaneBitmask RegPressureTracker::getLastUsedLanes(unsigned RegUnit,
|
LaneBitmask RegPressureTracker::getLastUsedLanes(unsigned RegUnit,
|
||||||
SlotIndex Pos) const {
|
SlotIndex Pos) const {
|
||||||
if (!RequireIntervals)
|
assert(RequireIntervals);
|
||||||
return 0;
|
|
||||||
|
|
||||||
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit,
|
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit,
|
||||||
Pos.getBaseIndex(),
|
Pos.getBaseIndex(), 0,
|
||||||
[](const LiveRange &LR, SlotIndex Pos) {
|
[](const LiveRange &LR, SlotIndex Pos) {
|
||||||
const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
|
const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
|
||||||
return S != nullptr && S->end == Pos.getRegSlot();
|
return S != nullptr && S->end == Pos.getRegSlot();
|
||||||
|
@ -1221,10 +1221,8 @@ LaneBitmask RegPressureTracker::getLastUsedLanes(unsigned RegUnit,
|
||||||
|
|
||||||
LaneBitmask RegPressureTracker::getLiveThroughAt(unsigned RegUnit,
|
LaneBitmask RegPressureTracker::getLiveThroughAt(unsigned RegUnit,
|
||||||
SlotIndex Pos) const {
|
SlotIndex Pos) const {
|
||||||
if (!RequireIntervals)
|
assert(RequireIntervals);
|
||||||
return 0;
|
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos, 0u,
|
||||||
|
|
||||||
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
|
|
||||||
[](const LiveRange &LR, SlotIndex Pos) {
|
[](const LiveRange &LR, SlotIndex Pos) {
|
||||||
const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
|
const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
|
||||||
return S != nullptr && S->start < Pos.getRegSlot(true) &&
|
return S != nullptr && S->start < Pos.getRegSlot(true) &&
|
||||||
|
@ -1251,12 +1249,12 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
|
||||||
if (TrackLaneMasks)
|
if (TrackLaneMasks)
|
||||||
RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
|
RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
|
||||||
|
|
||||||
|
if (RequireIntervals) {
|
||||||
for (const RegisterMaskPair &Use : RegOpers.Uses) {
|
for (const RegisterMaskPair &Use : RegOpers.Uses) {
|
||||||
unsigned Reg = Use.RegUnit;
|
unsigned Reg = Use.RegUnit;
|
||||||
LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
|
LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
|
||||||
if (LastUseMask == 0)
|
if (LastUseMask == 0)
|
||||||
continue;
|
continue;
|
||||||
if (RequireIntervals) {
|
|
||||||
// The LastUseMask is queried from the liveness information of instruction
|
// The LastUseMask is queried from the liveness information of instruction
|
||||||
// which may be further down the schedule. Some lanes may actually not be
|
// which may be further down the schedule. Some lanes may actually not be
|
||||||
// last uses for the current position.
|
// last uses for the current position.
|
||||||
|
@ -1267,12 +1265,12 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
|
||||||
= findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, LIS);
|
= findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, LIS);
|
||||||
if (LastUseMask == 0)
|
if (LastUseMask == 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
LaneBitmask LiveMask = LiveRegs.contains(Reg);
|
LaneBitmask LiveMask = LiveRegs.contains(Reg);
|
||||||
LaneBitmask NewMask = LiveMask & ~LastUseMask;
|
LaneBitmask NewMask = LiveMask & ~LastUseMask;
|
||||||
decreaseRegPressure(Reg, LiveMask, NewMask);
|
decreaseRegPressure(Reg, LiveMask, NewMask);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generate liveness for defs.
|
// Generate liveness for defs.
|
||||||
for (const RegisterMaskPair &Def : RegOpers.Defs) {
|
for (const RegisterMaskPair &Def : RegOpers.Defs) {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
; RUN: llc -march=amdgcn -mattr=-promote-alloca -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
|
; RUN: llc -march=amdgcn -mattr=-promote-alloca -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
|
||||||
|
|
||||||
; GCN-LABEL: {{^}}stored_fi_to_lds:
|
; GCN-LABEL: {{^}}stored_fi_to_lds:
|
||||||
; GCN-DAG: s_load_dword [[LDSPTR:s[0-9]+]]
|
; GCN: s_load_dword [[LDSPTR:s[0-9]+]]
|
||||||
; GCN-DAG: v_mov_b32_e32 [[ZERO1:v[0-9]+]], 0{{$}}
|
|
||||||
; GCN-DAG: buffer_store_dword v{{[0-9]+}}, [[ZERO1]]
|
|
||||||
; GCN: v_mov_b32_e32 [[ZERO0:v[0-9]+]], 0{{$}}
|
; GCN: v_mov_b32_e32 [[ZERO0:v[0-9]+]], 0{{$}}
|
||||||
|
; GCN: v_mov_b32_e32 [[ZERO1:v[0-9]+]], 0{{$}}
|
||||||
|
; GCN: buffer_store_dword v{{[0-9]+}}, [[ZERO1]]
|
||||||
; GCN: v_mov_b32_e32 [[VLDSPTR:v[0-9]+]], [[LDSPTR]]
|
; GCN: v_mov_b32_e32 [[VLDSPTR:v[0-9]+]], [[LDSPTR]]
|
||||||
; GCN: ds_write_b32 [[VLDSPTR]], [[ZERO0]]
|
; GCN: ds_write_b32 [[VLDSPTR]], [[ZERO0]]
|
||||||
define void @stored_fi_to_lds(float* addrspace(3)* %ptr) #0 {
|
define void @stored_fi_to_lds(float* addrspace(3)* %ptr) #0 {
|
||||||
|
|
|
@ -137,7 +137,7 @@ exit:
|
||||||
|
|
||||||
; SI: BB#4:
|
; SI: BB#4:
|
||||||
; SI: buffer_store_dword
|
; SI: buffer_store_dword
|
||||||
; SI: v_cmp_ge_i64_e64 [[CMP:s\[[0-9]+:[0-9]+\]]]
|
; SI: v_cmp_ge_i64_e32 [[CMP:s\[[0-9]+:[0-9]+\]|vcc]]
|
||||||
; SI: s_or_b64 [[TMP:s\[[0-9]+:[0-9]+\]]], [[CMP]], [[COND_STATE]]
|
; SI: s_or_b64 [[TMP:s\[[0-9]+:[0-9]+\]]], [[CMP]], [[COND_STATE]]
|
||||||
|
|
||||||
; SI: BB3_5:
|
; SI: BB3_5:
|
||||||
|
|
Loading…
Reference in New Issue