mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-23 19:59:57 +00:00
[RDF] Add initial support for lane masks in the DFG
Use lane masks for calculating covering and aliasing of register references. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282194 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a9c167e82e
commit
319d69e0f2
@ -16,7 +16,8 @@
|
||||
using namespace llvm;
|
||||
using namespace rdf;
|
||||
|
||||
bool HexagonRegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB) const {
|
||||
bool HexagonRegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB,
|
||||
const DataFlowGraph &DFG) const {
|
||||
if (RA == RB)
|
||||
return true;
|
||||
|
||||
@ -31,30 +32,33 @@ bool HexagonRegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB) const {
|
||||
}
|
||||
}
|
||||
|
||||
return RegisterAliasInfo::covers(RA, RB);
|
||||
return RegisterAliasInfo::covers(RA, RB, DFG);
|
||||
}
|
||||
|
||||
bool HexagonRegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR)
|
||||
const {
|
||||
bool HexagonRegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR,
|
||||
const DataFlowGraph &DFG) const {
|
||||
if (RRs.count(RR))
|
||||
return true;
|
||||
|
||||
if (!TargetRegisterInfo::isPhysicalRegister(RR.Reg)) {
|
||||
assert(TargetRegisterInfo::isVirtualRegister(RR.Reg));
|
||||
// Check if both covering subregisters are present.
|
||||
// The exact reference RR is not in the set.
|
||||
|
||||
if (TargetRegisterInfo::isVirtualRegister(RR.Reg)) {
|
||||
// Check if the there are references in RRs of the same register,
|
||||
// with both covering subregisters.
|
||||
bool HasLo = RRs.count({RR.Reg, Hexagon::subreg_loreg});
|
||||
bool HasHi = RRs.count({RR.Reg, Hexagon::subreg_hireg});
|
||||
if (HasLo && HasHi)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (RR.Sub == 0) {
|
||||
// Check if both covering subregisters are present.
|
||||
if (TargetRegisterInfo::isPhysicalRegister(RR.Reg)) {
|
||||
// Check if both covering subregisters are present with full
|
||||
// lane masks.
|
||||
unsigned Lo = TRI.getSubReg(RR.Reg, Hexagon::subreg_loreg);
|
||||
unsigned Hi = TRI.getSubReg(RR.Reg, Hexagon::subreg_hireg);
|
||||
if (RRs.count({Lo, 0}) && RRs.count({Hi, 0}))
|
||||
return true;
|
||||
}
|
||||
|
||||
return RegisterAliasInfo::covers(RRs, RR);
|
||||
return RegisterAliasInfo::covers(RRs, RR, DFG);
|
||||
}
|
||||
|
@ -18,8 +18,10 @@ namespace rdf {
|
||||
struct HexagonRegisterAliasInfo : public RegisterAliasInfo {
|
||||
HexagonRegisterAliasInfo(const TargetRegisterInfo &TRI)
|
||||
: RegisterAliasInfo(TRI) {}
|
||||
bool covers(RegisterRef RA, RegisterRef RR) const override;
|
||||
bool covers(const RegisterSet &RRs, RegisterRef RR) const override;
|
||||
bool covers(RegisterRef RA, RegisterRef RR,
|
||||
const DataFlowGraph &DFG) const override;
|
||||
bool covers(const RegisterSet &RRs, RegisterRef RR,
|
||||
const DataFlowGraph &DFG) const override;
|
||||
};
|
||||
} // namespace rdf
|
||||
} // namespace llvm
|
||||
|
@ -580,14 +580,47 @@ NodeAddr<BlockNode*> FuncNode::getEntryBlock(const DataFlowGraph &G) {
|
||||
|
||||
// Register aliasing information.
|
||||
//
|
||||
// In theory, the lane information could be used to determine register
|
||||
// covering (and aliasing), but depending on the sub-register structure,
|
||||
// the lane mask information may be missing. The covering information
|
||||
// must be available for this framework to work, so relying solely on
|
||||
// the lane data is not sufficient.
|
||||
|
||||
LaneBitmask RegisterAliasInfo::getLaneMask(RegisterRef RR,
|
||||
const DataFlowGraph &DFG) const {
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(RR.Reg));
|
||||
const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(RR.Reg);
|
||||
return (RR.Sub != 0) ? DFG.getLaneMaskForIndex(RR.Sub) : RC->LaneMask;
|
||||
}
|
||||
|
||||
RegisterAliasInfo::CommonRegister::CommonRegister(
|
||||
unsigned RegA, LaneBitmask LA, unsigned RegB, LaneBitmask LB,
|
||||
const TargetRegisterInfo &TRI) {
|
||||
if (RegA == RegB) {
|
||||
SuperReg = RegA;
|
||||
MaskA = LA;
|
||||
MaskB = LB;
|
||||
return;
|
||||
}
|
||||
|
||||
// Find a common super-register.
|
||||
SuperReg = 0;
|
||||
for (MCSuperRegIterator SA(RegA, &TRI, true); SA.isValid(); ++SA) {
|
||||
if (!TRI.isSubRegisterEq(*SA, RegB))
|
||||
continue;
|
||||
SuperReg = *SA;
|
||||
break;
|
||||
}
|
||||
if (SuperReg == 0)
|
||||
return;
|
||||
|
||||
if (unsigned SubA = TRI.getSubRegIndex(SuperReg, RegA))
|
||||
LA = TRI.composeSubRegIndexLaneMask(SubA, LA);
|
||||
if (unsigned SubB = TRI.getSubRegIndex(SuperReg, RegB))
|
||||
LB = TRI.composeSubRegIndexLaneMask(SubB, LB);
|
||||
|
||||
MaskA = LA;
|
||||
MaskB = LB;
|
||||
}
|
||||
|
||||
// Determine whether RA covers RB.
|
||||
bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB) const {
|
||||
bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB,
|
||||
const DataFlowGraph &DFG) const {
|
||||
if (RA == RB)
|
||||
return true;
|
||||
if (TargetRegisterInfo::isVirtualRegister(RA.Reg)) {
|
||||
@ -601,13 +634,17 @@ bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB) const {
|
||||
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg) &&
|
||||
TargetRegisterInfo::isPhysicalRegister(RB.Reg));
|
||||
uint32_t A = RA.Sub != 0 ? TRI.getSubReg(RA.Reg, RA.Sub) : RA.Reg;
|
||||
uint32_t B = RB.Sub != 0 ? TRI.getSubReg(RB.Reg, RB.Sub) : RB.Reg;
|
||||
return TRI.isSubRegister(A, B);
|
||||
|
||||
CommonRegister CR(RA.Reg, getLaneMask(RA, DFG),
|
||||
RB.Reg, getLaneMask(RB, DFG), TRI);
|
||||
if (CR.SuperReg == 0)
|
||||
return false;
|
||||
return (CR.MaskA & CR.MaskB) == CR.MaskB;
|
||||
}
|
||||
|
||||
// Determine whether RR is covered by the set of references RRs.
|
||||
bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR) const {
|
||||
bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR,
|
||||
const DataFlowGraph &DFG) const {
|
||||
if (RRs.count(RR))
|
||||
return true;
|
||||
|
||||
@ -630,7 +667,7 @@ bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the list of references aliased to RR.
|
||||
// Get the list of references aliased to RR. Lane masks are ignored.
|
||||
std::vector<RegisterRef> RegisterAliasInfo::getAliasSet(RegisterRef RR) const {
|
||||
// Do not include RR in the alias set. For virtual registers return an
|
||||
// empty set.
|
||||
@ -648,16 +685,17 @@ std::vector<RegisterRef> RegisterAliasInfo::getAliasSet(RegisterRef RR) const {
|
||||
}
|
||||
|
||||
// Check whether RA and RB are aliased.
|
||||
bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB) const {
|
||||
bool VirtA = TargetRegisterInfo::isVirtualRegister(RA.Reg);
|
||||
bool VirtB = TargetRegisterInfo::isVirtualRegister(RB.Reg);
|
||||
bool PhysA = TargetRegisterInfo::isPhysicalRegister(RA.Reg);
|
||||
bool PhysB = TargetRegisterInfo::isPhysicalRegister(RB.Reg);
|
||||
bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB,
|
||||
const DataFlowGraph &DFG) const {
|
||||
bool IsVirtA = TargetRegisterInfo::isVirtualRegister(RA.Reg);
|
||||
bool IsVirtB = TargetRegisterInfo::isVirtualRegister(RB.Reg);
|
||||
bool IsPhysA = TargetRegisterInfo::isPhysicalRegister(RA.Reg);
|
||||
bool IsPhysB = TargetRegisterInfo::isPhysicalRegister(RB.Reg);
|
||||
|
||||
if (VirtA != VirtB)
|
||||
if (IsVirtA != IsVirtB)
|
||||
return false;
|
||||
|
||||
if (VirtA) {
|
||||
if (IsVirtA) {
|
||||
if (RA.Reg != RB.Reg)
|
||||
return false;
|
||||
// RA and RB refer to the same register. If any of them refer to the
|
||||
@ -675,14 +713,14 @@ bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(PhysA && PhysB);
|
||||
(void)PhysA, (void)PhysB;
|
||||
uint32_t A = RA.Sub ? TRI.getSubReg(RA.Reg, RA.Sub) : RA.Reg;
|
||||
uint32_t B = RB.Sub ? TRI.getSubReg(RB.Reg, RB.Sub) : RB.Reg;
|
||||
for (MCRegAliasIterator I(A, &TRI, true); I.isValid(); ++I)
|
||||
if (B == *I)
|
||||
return true;
|
||||
return false;
|
||||
assert(IsPhysA && IsPhysB);
|
||||
(void)IsPhysA, (void)IsPhysB;
|
||||
|
||||
CommonRegister CR(RA.Reg, getLaneMask(RA, DFG),
|
||||
RB.Reg, getLaneMask(RB, DFG), TRI);
|
||||
if (CR.SuperReg == 0)
|
||||
return false;
|
||||
return (CR.MaskA & CR.MaskB) != 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1213,7 +1251,7 @@ void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
|
||||
if (!UseOp.isReg() || !UseOp.isUse() || UseOp.isUndef())
|
||||
continue;
|
||||
RegisterRef UR = { UseOp.getReg(), UseOp.getSubReg() };
|
||||
if (RAI.alias(DR, UR))
|
||||
if (RAI.alias(DR, UR, *this))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -1398,7 +1436,7 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, BlockRefsMap &RefM,
|
||||
|
||||
auto MaxCoverIn = [this] (RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
|
||||
for (auto I : RRs)
|
||||
if (I != RR && RAI.covers(I, RR))
|
||||
if (I != RR && RAI.covers(I, RR, *this))
|
||||
RR = I;
|
||||
return RR;
|
||||
};
|
||||
@ -1425,7 +1463,7 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, BlockRefsMap &RefM,
|
||||
auto Aliased = [this,&MaxRefs](RegisterRef RR,
|
||||
std::vector<unsigned> &Closure) -> bool {
|
||||
for (auto I : Closure)
|
||||
if (RAI.alias(RR, MaxRefs[I]))
|
||||
if (RAI.alias(RR, MaxRefs[I], *this))
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
@ -1544,9 +1582,9 @@ void DataFlowGraph::linkRefUp(NodeAddr<InstrNode*> IA, NodeAddr<T> TA,
|
||||
for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
|
||||
RegisterRef QR = I->Addr->getRegRef();
|
||||
auto AliasQR = [QR,this] (RegisterRef RR) -> bool {
|
||||
return RAI.alias(QR, RR);
|
||||
return RAI.alias(QR, RR, *this);
|
||||
};
|
||||
bool PrecUp = RAI.covers(QR, RR);
|
||||
bool PrecUp = RAI.covers(QR, RR, *this);
|
||||
// Skip all defs that are aliased to any of the defs that we have already
|
||||
// seen. If we encounter a covering def, stop the stack traversal early.
|
||||
if (any_of(Defs, AliasQR)) {
|
||||
|
@ -221,6 +221,7 @@
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
@ -236,11 +237,12 @@ namespace llvm {
|
||||
class MachineDominanceFrontier;
|
||||
class MachineDominatorTree;
|
||||
class TargetInstrInfo;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
namespace rdf {
|
||||
typedef uint32_t NodeId;
|
||||
|
||||
struct DataFlowGraph;
|
||||
|
||||
struct NodeAttrs {
|
||||
enum : uint16_t {
|
||||
None = 0x0000, // Nothing
|
||||
@ -384,6 +386,15 @@ namespace rdf {
|
||||
};
|
||||
|
||||
struct RegisterRef {
|
||||
// For virtual registers, Reg and Sub have the usual meanings.
|
||||
//
|
||||
// Physical registers are assumed not to have any subregisters, and for
|
||||
// them, Sub is the key of the LaneBitmask in the lane mask map in DFG.
|
||||
// The case of Sub = 0 is treated as 'all lanes', i.e. lane mask of ~0.
|
||||
// Use an key/map to access lane masks, since we only have uint32_t
|
||||
// for it, and the LaneBitmask type can grow in the future.
|
||||
//
|
||||
// The case when Reg = 0 and Sub = 0 is reserved to mean "no register".
|
||||
uint32_t Reg, Sub;
|
||||
|
||||
// No non-trivial constructors, since this will be a member of a union.
|
||||
@ -407,11 +418,25 @@ namespace rdf {
|
||||
virtual ~RegisterAliasInfo() {}
|
||||
|
||||
virtual std::vector<RegisterRef> getAliasSet(RegisterRef RR) const;
|
||||
virtual bool alias(RegisterRef RA, RegisterRef RB) const;
|
||||
virtual bool covers(RegisterRef RA, RegisterRef RB) const;
|
||||
virtual bool covers(const RegisterSet &RRs, RegisterRef RR) const;
|
||||
virtual bool alias(RegisterRef RA, RegisterRef RB,
|
||||
const DataFlowGraph &DFG) const;
|
||||
virtual bool covers(RegisterRef RA, RegisterRef RB,
|
||||
const DataFlowGraph &DFG) const;
|
||||
virtual bool covers(const RegisterSet &RRs, RegisterRef RR,
|
||||
const DataFlowGraph &DFG) const;
|
||||
|
||||
const TargetRegisterInfo &TRI;
|
||||
|
||||
protected:
|
||||
LaneBitmask getLaneMask(RegisterRef RR, const DataFlowGraph &DFG) const;
|
||||
|
||||
struct CommonRegister {
|
||||
CommonRegister(unsigned RegA, LaneBitmask LA,
|
||||
unsigned RegB, LaneBitmask LB,
|
||||
const TargetRegisterInfo &TRI);
|
||||
unsigned SuperReg;
|
||||
LaneBitmask MaskA, MaskB;
|
||||
};
|
||||
};
|
||||
|
||||
struct TargetOperandInfo {
|
||||
@ -424,8 +449,31 @@ namespace rdf {
|
||||
const TargetInstrInfo &TII;
|
||||
};
|
||||
|
||||
// Template class for a map translating uint32_t into arbitrary types.
|
||||
// The map will act like an indexed set: upon insertion of a new object,
|
||||
// it will automatically assign a new index to it. Index of 0 is treated
|
||||
// as invalid and is never allocated.
|
||||
template <typename T, unsigned N = 32>
|
||||
struct IndexedSet {
|
||||
IndexedSet() : Map(N) {}
|
||||
const T get(uint32_t Idx) const {
|
||||
// Index Idx corresponds to Map[Idx-1].
|
||||
assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size());
|
||||
return Map[Idx-1];
|
||||
}
|
||||
uint32_t insert(T Val) {
|
||||
// Linear search.
|
||||
auto F = find(Map, Val);
|
||||
if (F != Map.end())
|
||||
return *F;
|
||||
Map.push_back(Val);
|
||||
return Map.size(); // Return actual_index + 1.
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T> Map;
|
||||
};
|
||||
|
||||
struct DataFlowGraph;
|
||||
|
||||
struct NodeBase {
|
||||
public:
|
||||
@ -648,6 +696,13 @@ namespace rdf {
|
||||
return RAI;
|
||||
}
|
||||
|
||||
LaneBitmask getLaneMaskForIndex(uint32_t K) const {
|
||||
return LMMap.get(K);
|
||||
}
|
||||
uint32_t getIndexForLaneMask(LaneBitmask LM) {
|
||||
return LMMap.insert(LM);
|
||||
}
|
||||
|
||||
struct DefStack {
|
||||
DefStack() = default;
|
||||
bool empty() const { return Stack.empty() || top() == bottom(); }
|
||||
@ -820,6 +875,8 @@ namespace rdf {
|
||||
NodeAllocator Memory;
|
||||
// Local map: MachineBasicBlock -> NodeAddr<BlockNode*>
|
||||
std::map<MachineBasicBlock*,NodeAddr<BlockNode*>> BlockNodes;
|
||||
// Lane mask map.
|
||||
IndexedSet<LaneBitmask> LMMap;
|
||||
|
||||
MachineFunction &MF;
|
||||
const TargetInstrInfo &TII;
|
||||
|
@ -109,7 +109,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
|
||||
continue;
|
||||
// Stop at the covering/overwriting def of the initial register reference.
|
||||
RegisterRef RR = TA.Addr->getRegRef();
|
||||
if (!DFG.IsPreservingDef(TA) && RAI.covers(RR, RefRR))
|
||||
if (!DFG.IsPreservingDef(TA) && RAI.covers(RR, RefRR, DFG))
|
||||
continue;
|
||||
// Get the next level of reaching defs. This will include multiple
|
||||
// reaching defs for shadows.
|
||||
@ -124,7 +124,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
|
||||
for (auto N : DefQ) {
|
||||
auto TA = DFG.addr<DefNode*>(N);
|
||||
bool IsPhi = TA.Addr->getFlags() & NodeAttrs::PhiRef;
|
||||
if (!IsPhi && !RAI.alias(RefRR, TA.Addr->getRegRef()))
|
||||
if (!IsPhi && !RAI.alias(RefRR, TA.Addr->getRegRef(), DFG))
|
||||
continue;
|
||||
Defs.insert(TA.Id);
|
||||
Owners.insert(TA.Addr->getOwner(DFG).Id);
|
||||
@ -194,7 +194,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
|
||||
Defs.count(TA.Id);
|
||||
};
|
||||
for (auto T : Tmp) {
|
||||
if (!FullChain && RAI.covers(RRs, RefRR))
|
||||
if (!FullChain && RAI.covers(RRs, RefRR, DFG))
|
||||
break;
|
||||
auto TA = DFG.addr<InstrNode*>(T);
|
||||
bool IsPhi = DFG.IsCode<NodeAttrs::Phi>(TA);
|
||||
@ -209,7 +209,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
|
||||
// phi d1<R3>(,d2,), ... Phi def d1 is covered by d2.
|
||||
// d2<R3>(d1,,u3), ...
|
||||
// ..., u3<D1>(d2) This use needs to be live on entry.
|
||||
if (FullChain || IsPhi || !RAI.covers(RRs, QR))
|
||||
if (FullChain || IsPhi || !RAI.covers(RRs, QR, DFG))
|
||||
Ds.push_back(DA);
|
||||
}
|
||||
RDefs.insert(RDefs.end(), Ds.begin(), Ds.end());
|
||||
@ -281,7 +281,7 @@ NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
|
||||
|
||||
// If the original register is already covered by all the intervening
|
||||
// defs, no more uses can be reached.
|
||||
if (RAI.covers(DefRRs, RefRR))
|
||||
if (RAI.covers(DefRRs, RefRR, DFG))
|
||||
return Uses;
|
||||
|
||||
// Add all directly reached uses.
|
||||
@ -290,7 +290,7 @@ NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
|
||||
auto UA = DFG.addr<UseNode*>(U);
|
||||
if (!(UA.Addr->getFlags() & NodeAttrs::Undef)) {
|
||||
auto UR = UA.Addr->getRegRef();
|
||||
if (RAI.alias(RefRR, UR) && !RAI.covers(DefRRs, UR))
|
||||
if (RAI.alias(RefRR, UR, DFG) && !RAI.covers(DefRRs, UR, DFG))
|
||||
Uses.insert(U);
|
||||
}
|
||||
U = UA.Addr->getSibling();
|
||||
@ -303,7 +303,7 @@ NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
|
||||
auto DR = DA.Addr->getRegRef();
|
||||
// If this def is already covered, it cannot reach anything new.
|
||||
// Similarly, skip it if it is not aliased to the interesting register.
|
||||
if (RAI.covers(DefRRs, DR) || !RAI.alias(RefRR, DR))
|
||||
if (RAI.covers(DefRRs, DR, DFG) || !RAI.alias(RefRR, DR, DFG))
|
||||
continue;
|
||||
NodeSet T;
|
||||
if (DFG.IsPreservingDef(DA)) {
|
||||
@ -514,7 +514,7 @@ void Liveness::computePhiInfo() {
|
||||
RegisterRef R = T.first;
|
||||
if (!isRestrictedToRef(PA, UA, R))
|
||||
R = getRestrictedRegRef(UA);
|
||||
if (!RAI.covers(MidDefs, R))
|
||||
if (!RAI.covers(MidDefs, R, DFG))
|
||||
UpReached.insert(R);
|
||||
}
|
||||
if (UpReached.empty())
|
||||
@ -635,7 +635,7 @@ void Liveness::computeLiveIns() {
|
||||
// The restricted ref may be different from the ref that was
|
||||
// accessed in the "real use". This means that this phi use
|
||||
// is not the one that carries this reference, so skip it.
|
||||
if (!RAI.alias(R.first, RR))
|
||||
if (!RAI.alias(R.first, RR, DFG))
|
||||
continue;
|
||||
for (auto D : getAllReachingDefs(RR, UA))
|
||||
LOX[RR].insert(D.Id);
|
||||
@ -768,7 +768,7 @@ bool Liveness::isRestrictedToRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
|
||||
NodeId RD = TA.Addr->getReachingDef();
|
||||
if (RD == 0)
|
||||
continue;
|
||||
if (RAI.alias(RR, DFG.addr<DefNode*>(RD).Addr->getRegRef()))
|
||||
if (RAI.alias(RR, DFG.addr<DefNode*>(RD).Addr->getRegRef(), DFG))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -880,13 +880,13 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
|
||||
else {
|
||||
bool IsPreserving = DFG.IsPreservingDef(DA);
|
||||
if (IA.Addr->getKind() != NodeAttrs::Phi && !IsPreserving) {
|
||||
bool Covering = RAI.covers(DDR, I.first);
|
||||
bool Covering = RAI.covers(DDR, I.first, DFG);
|
||||
NodeId U = DA.Addr->getReachedUse();
|
||||
while (U && Covering) {
|
||||
auto DUA = DFG.addr<UseNode*>(U);
|
||||
if (!(DUA.Addr->getFlags() & NodeAttrs::Undef)) {
|
||||
RegisterRef Q = DUA.Addr->getRegRef();
|
||||
Covering = RAI.covers(DA.Addr->getRegRef(), Q);
|
||||
Covering = RAI.covers(DA.Addr->getRegRef(), Q, DFG);
|
||||
}
|
||||
U = DUA.Addr->getSibling();
|
||||
}
|
||||
@ -909,7 +909,7 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
|
||||
RRs.insert(TA.Addr->getRegRef());
|
||||
if (BA.Addr->getCode() == B)
|
||||
continue;
|
||||
if (RAI.covers(RRs, DRR))
|
||||
if (RAI.covers(RRs, DRR, DFG))
|
||||
break;
|
||||
Defs.insert(TA.Id);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user