diff options
| -rw-r--r-- | llvm/lib/Target/Hexagon/RDFLiveness.cpp | 33 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/RDFRegisters.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/RDFRegisters.h | 1 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Hexagon/rdf-cover-use.ll | 38 |
4 files changed, 74 insertions, 13 deletions
diff --git a/llvm/lib/Target/Hexagon/RDFLiveness.cpp b/llvm/lib/Target/Hexagon/RDFLiveness.cpp index 726b7af73b0..9d8a3881797 100644 --- a/llvm/lib/Target/Hexagon/RDFLiveness.cpp +++ b/llvm/lib/Target/Hexagon/RDFLiveness.cpp @@ -497,26 +497,33 @@ void Liveness::computePhiInfo() { // = R1:0 u6 Not reached by d1 (covered collectively // by d3 and d5), but following reached // defs and uses from d1 will lead here. - auto InPhiDefs = [&PhiDefs] (NodeAddr<DefNode*> DA) -> bool { - return PhiDefs.count(DA.Id); - }; for (auto UI = RealUses.begin(), UE = RealUses.end(); UI != UE; ) { // For each reached register UI->first, there is a set UI->second, of // uses of it. For each such use, check if it is reached by this phi, // i.e. check if the set of its reaching uses intersects the set of // this phi's defs. - NodeRefSet &Uses = UI->second; - for (auto I = Uses.begin(), E = Uses.end(); I != E; ) { - auto UA = DFG.addr<UseNode*>(I->first); + NodeRefSet Uses = UI->second; + UI->second.clear(); + for (std::pair<NodeId,LaneBitmask> I : Uses) { + 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); - NodeList RDs = getAllReachingDefs(R, UA); - // If none of the reaching defs of R are from this phi, remove this - // use of R. - I = any_of(RDs, InPhiDefs) ? std::next(I) : Uses.erase(I); + RegisterRef R(UI->first, I.second); + // Calculate the exposed part of the reached use. + RegisterAggr Covered(PRI); + for (NodeAddr<DefNode*> DA : getAllReachingDefs(R, UA)) { + if (PhiDefs.count(DA.Id)) + break; + Covered.insert(DA.Addr->getRegRef(DFG)); + } + if (RegisterRef RC = Covered.clearIn(R)) { + // We are updating the map for register UI->first, so we need + // to map RC to be expressed in terms of that register. + RegisterRef S = PRI.mapTo(RC, UI->first); + UI->second.insert({I.first, S.Mask}); + } } - UI = Uses.empty() ? RealUses.erase(UI) : std::next(UI); + UI = UI->second.empty() ? RealUses.erase(UI) : std::next(UI); } // If this phi reaches some "real" uses, add it to the queue for upward @@ -626,7 +633,7 @@ void Liveness::computePhiInfo() { const RegisterAggr &DRs = PhiDRs.at(P.first); if (!DRs.hasAliasOf(R)) continue; - R = DRs.intersectWith(R); + R = PRI.mapTo(DRs.intersectWith(R), T.first); for (std::pair<NodeId,LaneBitmask> V : T.second) { LaneBitmask M = R.Mask & V.second; if (M.none()) diff --git a/llvm/lib/Target/Hexagon/RDFRegisters.cpp b/llvm/lib/Target/Hexagon/RDFRegisters.cpp index 4224ded3418..2aabf4ee1a3 100644 --- a/llvm/lib/Target/Hexagon/RDFRegisters.cpp +++ b/llvm/lib/Target/Hexagon/RDFRegisters.cpp @@ -212,6 +212,21 @@ bool PhysicalRegisterInfo::aliasMM(RegisterRef RM, RegisterRef RN) const { return false; } +RegisterRef PhysicalRegisterInfo::mapTo(RegisterRef RR, unsigned R) const { + if (RR.Reg == R) + return RR; + if (unsigned Idx = TRI.getSubRegIndex(R, RR.Reg)) + return RegisterRef(R, TRI.composeSubRegIndexLaneMask(Idx, RR.Mask)); + if (unsigned Idx = TRI.getSubRegIndex(RR.Reg, R)) { + const RegInfo &RI = RegInfos[R]; + LaneBitmask RCM = RI.RegClass ? RI.RegClass->LaneMask + : LaneBitmask::getAll(); + LaneBitmask M = TRI.reverseComposeSubRegIndexLaneMask(Idx, RR.Mask); + return RegisterRef(R, M & RCM); + } + llvm_unreachable("Invalid arguments: unrelated registers?"); +} + bool RegisterAggr::hasAliasOf(RegisterRef RR) const { if (PhysicalRegisterInfo::isRegMaskId(RR.Reg)) diff --git a/llvm/lib/Target/Hexagon/RDFRegisters.h b/llvm/lib/Target/Hexagon/RDFRegisters.h index 314d8b5666d..09b733ce616 100644 --- a/llvm/lib/Target/Hexagon/RDFRegisters.h +++ b/llvm/lib/Target/Hexagon/RDFRegisters.h @@ -112,6 +112,7 @@ namespace rdf { const BitVector &getMaskUnits(RegisterId MaskId) const { return MaskInfos[TargetRegisterInfo::stackSlot2Index(MaskId)].Units; } + RegisterRef mapTo(RegisterRef RR, unsigned R) const; const TargetRegisterInfo &getTRI() const { return TRI; } diff --git a/llvm/test/CodeGen/Hexagon/rdf-cover-use.ll b/llvm/test/CodeGen/Hexagon/rdf-cover-use.ll new file mode 100644 index 00000000000..4f3de0868aa --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/rdf-cover-use.ll @@ -0,0 +1,38 @@ +; RUN: llc -march=hexagon -verify-machineinstrs < %s | FileCheck %s + +; Check for sane output. +; CHECK: vmpyweh + +target triple = "hexagon" + +declare i32 @llvm.hexagon.S2.clb(i32) #0 +declare i32 @llvm.hexagon.S2.asl.r.r(i32, i32) #0 +declare i32 @llvm.hexagon.S2.vrndpackwh(i64) #0 +declare i64 @llvm.hexagon.M2.mmpyl.s1(i64, i64) #0 + +define i64 @fred(i32 %a0, i32 %a1) local_unnamed_addr #1 { +b2: + br i1 undef, label %b15, label %b3 + +b3: ; preds = %b2 + %v4 = tail call i32 @llvm.hexagon.S2.clb(i32 %a1) #0 + %v5 = add nsw i32 %v4, -32 + %v6 = zext i32 %v5 to i64 + %v7 = shl nuw i64 %v6, 32 + %v8 = or i64 %v7, 0 + %v9 = tail call i32 @llvm.hexagon.S2.asl.r.r(i32 %a0, i32 0) + %v10 = tail call i32 @llvm.hexagon.S2.vrndpackwh(i64 %v8) + %v11 = sext i32 %v9 to i64 + %v12 = sext i32 %v10 to i64 + %v13 = tail call i64 @llvm.hexagon.M2.mmpyl.s1(i64 %v11, i64 %v12) + %v14 = and i64 %v13, 4294967295 + br label %b15 + +b15: ; preds = %b3, %b2 + %v16 = phi i64 [ %v14, %b3 ], [ 0, %b2 ] + %v17 = or i64 0, %v16 + ret i64 %v17 +} + +attributes #0 = { nounwind readnone } +attributes #1 = { nounwind "target-cpu"="hexagonv55" } |

