[llvm] c6ddd04 - [RDF] Create individual phi for each indivisible register
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 8 11:08:32 PDT 2023
Author: Krzysztof Parzyszek
Date: 2023-06-08T11:07:57-07:00
New Revision: c6ddd04d73c31d970176df3e52edfd7a58e91d86
URL: https://github.com/llvm/llvm-project/commit/c6ddd04d73c31d970176df3e52edfd7a58e91d86
DIFF: https://github.com/llvm/llvm-project/commit/c6ddd04d73c31d970176df3e52edfd7a58e91d86.diff
LOG: [RDF] Create individual phi for each indivisible register
This isn't quite using register units, but it's getting close. The phi
generation is driven by register units, but each phi still contains a
reference to a register, potentially with a mask that amounts to a unit.
In cases of explicit register aliasing this may still create phis with
references that are aliased, whereas separate phis would ideally contain
disjoint references (this is all within a single basic block).
Previously phis used maximal registers, now they use minimal. This is a
step towards both, using register units directly, and a simpler liveness
calculation algorithm. The idea is that a phi cannot reach a reference
to anything smaller than the phi itself represents. Before there could
be a phi for R1_R0, now there will be two for this case (assuming R0 and
R1 have one unit each).
Added:
Modified:
llvm/lib/CodeGen/RDFGraph.cpp
llvm/lib/CodeGen/RDFLiveness.cpp
llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
llvm/test/CodeGen/Hexagon/newify-crash.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/RDFGraph.cpp b/llvm/lib/CodeGen/RDFGraph.cpp
index 14f9c1167bb43..801113479852e 100644
--- a/llvm/lib/CodeGen/RDFGraph.cpp
+++ b/llvm/lib/CodeGen/RDFGraph.cpp
@@ -1433,87 +1433,24 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, RegisterSet &AllRefs,
if (HasDF == PhiM.end() || HasDF->second.empty())
return;
- // First, remove all R in Refs in such that there exists T in Refs
- // such that T covers R. In other words, only leave those refs that
- // are not covered by another ref (i.e. maximal with respect to covering).
-
- auto MaxCoverIn = [this](RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
- for (RegisterRef I : RRs)
- if (I != RR && RegisterAggr::isCoverOf(I, RR, PRI))
- RR = I;
- return RR;
- };
-
- RegisterSet MaxDF, DefsDF;
- for (auto I = HasDF->second.rr_begin(), E = HasDF->second.rr_end(); I != E;
- ++I) {
- DefsDF.insert(*I);
- }
- for (RegisterRef I : DefsDF)
- MaxDF.insert(MaxCoverIn(I, DefsDF));
-
- std::vector<RegisterRef> MaxRefs;
- for (RegisterRef I : MaxDF)
- MaxRefs.push_back(MaxCoverIn(I, AllRefs));
-
- // Now, for each R in MaxRefs, get the alias closure of R. If the closure
- // only has R in it, create a phi a def for R. Otherwise, create a phi,
- // and add a def for each S in the closure.
-
- // Sort the refs so that the phis will be created in a deterministic order.
- llvm::sort(MaxRefs);
- // Remove duplicates.
- auto NewEnd = std::unique(MaxRefs.begin(), MaxRefs.end());
- MaxRefs.erase(NewEnd, MaxRefs.end());
-
- auto Aliased = [this, &MaxRefs](RegisterRef RR,
- std::vector<unsigned> &Closure) -> bool {
- for (unsigned I : Closure)
- if (PRI.alias(RR, MaxRefs[I]))
- return true;
- return false;
- };
-
// Prepare a list of NodeIds of the block's predecessors.
NodeList Preds;
const MachineBasicBlock *MBB = BA.Addr->getCode();
for (MachineBasicBlock *PB : MBB->predecessors())
Preds.push_back(findBlock(PB));
- while (!MaxRefs.empty()) {
- // Put the first element in the closure, and then add all subsequent
- // elements from MaxRefs to it, if they alias at least one element
- // already in the closure.
- // ClosureIdx: vector of indices in MaxRefs of members of the closure.
- std::vector<unsigned> ClosureIdx = {0};
- for (unsigned i = 1; i != MaxRefs.size(); ++i)
- if (Aliased(MaxRefs[i], ClosureIdx))
- ClosureIdx.push_back(i);
-
- // Build a phi for the closure.
- unsigned CS = ClosureIdx.size();
+ const RegisterAggr &Defs = PhiM[BA.Id];
+ uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
+
+ for (auto I = Defs.rr_begin(), E = Defs.rr_end(); I != E; ++I) {
+ RegisterRef RR = *I;
NodeAddr<PhiNode *> PA = newPhi(BA);
+ PA.Addr->addMember(newDef(PA, RR, PhiFlags), *this);
- // Add defs.
- for (unsigned X = 0; X != CS; ++X) {
- RegisterRef RR = MaxRefs[ClosureIdx[X]];
- uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
- NodeAddr<DefNode *> DA = newDef(PA, RR, PhiFlags);
- PA.Addr->addMember(DA, *this);
- }
// Add phi uses.
for (NodeAddr<BlockNode *> PBA : Preds) {
- for (unsigned X = 0; X != CS; ++X) {
- RegisterRef RR = MaxRefs[ClosureIdx[X]];
- NodeAddr<PhiUseNode *> PUA = newPhiUse(PA, RR, PBA);
- PA.Addr->addMember(PUA, *this);
- }
+ PA.Addr->addMember(newPhiUse(PA, RR, PBA), *this);
}
-
- // Erase from MaxRefs all elements in the closure.
- auto Begin = MaxRefs.begin();
- for (unsigned Idx : llvm::reverse(ClosureIdx))
- MaxRefs.erase(Begin + Idx);
}
}
diff --git a/llvm/lib/CodeGen/RDFLiveness.cpp b/llvm/lib/CodeGen/RDFLiveness.cpp
index 484ab6e5739e5..c3ef9ed23be08 100644
--- a/llvm/lib/CodeGen/RDFLiveness.cpp
+++ b/llvm/lib/CodeGen/RDFLiveness.cpp
@@ -560,7 +560,11 @@ void Liveness::computePhiInfo() {
auto UA = DFG.addr<UseNode *>(I.first);
// Undef flag is checked above.
assert((UA.Addr->getFlags() & NodeAttrs::Undef) == 0);
- RegisterRef R(UI->first, I.second);
+ RegisterRef UseR(UI->first, I.second); // Ref from Uses
+ // R = intersection of the ref from the phi and the ref from Uses
+ RegisterRef R = PhiDRs.at(PhiA.Id).intersectWith(UseR);
+ if (!R)
+ continue;
// Calculate the exposed part of the reached use.
RegisterAggr Covered(PRI);
for (NodeAddr<DefNode *> DA : getAllReachingDefs(R, UA)) {
@@ -781,9 +785,10 @@ void Liveness::computeLiveIns() {
for (NodeAddr<BlockNode *> BA : Blocks) {
MachineBasicBlock *MB = BA.Addr->getCode();
RefMap &LON = PhiLON[MB];
- for (auto P : BA.Addr->members_if(DFG.IsCode<NodeAttrs::Phi>, DFG))
+ for (auto P : BA.Addr->members_if(DFG.IsCode<NodeAttrs::Phi>, DFG)) {
for (const RefMap::value_type &S : RealUseMap[P.Id])
LON[S.first].insert(S.second.begin(), S.second.end());
+ }
}
if (Trace) {
diff --git a/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp b/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
index 99aaf1c1b592c..418cb3cbe0897 100644
--- a/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
@@ -320,8 +320,10 @@ bool HexagonRDFOpt::runOnMachineFunction(MachineFunction &MF) {
Changed |= DCE.run();
if (Changed) {
- if (RDFDump)
- dbgs() << "Starting liveness recomputation on: " << MF.getName() << '\n';
+ if (RDFDump) {
+ dbgs() << "Starting liveness recomputation on: " << MF.getName() << '\n'
+ << PrintNode<FuncNode*>(G.getFunc(), G) << '\n';
+ }
Liveness LV(*MRI, G);
LV.trace(RDFDump);
LV.computeLiveIns();
diff --git a/llvm/test/CodeGen/Hexagon/newify-crash.ll b/llvm/test/CodeGen/Hexagon/newify-crash.ll
index bb29954291271..2454a38b0388c 100644
--- a/llvm/test/CodeGen/Hexagon/newify-crash.ll
+++ b/llvm/test/CodeGen/Hexagon/newify-crash.ll
@@ -1,7 +1,7 @@
; RUN: llc -march=hexagon < %s | FileCheck %s
;
; Check that this testcase doesn't crash.
-; CHECK: vadd
+; CHECK: jump f0
target triple = "hexagon"
More information about the llvm-commits
mailing list