mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-10 12:55:00 +00:00
[RDF] Fix liveness propagation through shadows
Each shadow only represents data flow that is restricted to its reaching def. Propagating more than that could lead to spurious register liveness, resulting in extra (incorrectly) block live-ins. llvm-svn: 283143
This commit is contained in:
parent
a827ed8891
commit
c8b6ecabd8
@ -530,7 +530,7 @@ void Liveness::computePhiInfo() {
|
||||
RegisterSet UpReached;
|
||||
for (const std::pair<RegisterRef,NodeSet> &T : RUM) {
|
||||
RegisterRef R = T.first;
|
||||
if (!isRestrictedToRef(PA, UA, R))
|
||||
if (UA.Addr->getFlags() & NodeAttrs::Shadow)
|
||||
R = getRestrictedRegRef(UA);
|
||||
if (!MidDefs.hasCoverOf(R))
|
||||
UpReached.insert(R);
|
||||
@ -648,7 +648,7 @@ void Liveness::computeLiveIns() {
|
||||
auto &LOX = PhiLOX[PrA.Addr->getCode()];
|
||||
for (auto R : RUs) {
|
||||
RegisterRef RR = R.first;
|
||||
if (!isRestrictedToRef(PA, UA, RR))
|
||||
if (UA.Addr->getFlags() & NodeAttrs::Shadow)
|
||||
RR = getRestrictedRegRef(UA);
|
||||
// The restricted ref may be different from the ref that was
|
||||
// accessed in the "real use". This means that this phi use
|
||||
@ -770,29 +770,6 @@ void Liveness::resetKills(MachineBasicBlock *B) {
|
||||
}
|
||||
|
||||
|
||||
// For shadows, determine if RR is aliased to a reaching def of any other
|
||||
// shadow associated with RA. The register ref on RA will be "larger" than
|
||||
// each individual reaching def, and to determine the data-flow between defs
|
||||
// and uses of RR it may be necessary to visit all shadows. If RR is not
|
||||
// aliased to the reaching def of any other shadow, then visiting only RA
|
||||
// is sufficient. In that sense, the data flow of RR would be restricted to
|
||||
// the reference RA.
|
||||
// For non-shadows, this function returns "true".
|
||||
bool Liveness::isRestrictedToRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
|
||||
RegisterRef RR) const {
|
||||
NodeId Start = RA.Id;
|
||||
for (NodeAddr<RefNode*> TA = DFG.getNextShadow(IA, RA);
|
||||
TA.Id != 0 && TA.Id != Start; TA = DFG.getNextShadow(IA, TA)) {
|
||||
NodeId RD = TA.Addr->getReachingDef();
|
||||
if (RD == 0)
|
||||
continue;
|
||||
if (DFG.alias(RR, DFG.addr<DefNode*>(RD).Addr->getRegRef()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
RegisterRef Liveness::getRestrictedRegRef(NodeAddr<RefNode*> RA) const {
|
||||
assert(DFG.IsRef<NodeAttrs::Use>(RA));
|
||||
if (RA.Addr->getFlags() & NodeAttrs::Shadow) {
|
||||
@ -850,12 +827,13 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
|
||||
}
|
||||
|
||||
if (Trace) {
|
||||
dbgs() << LLVM_FUNCTION_NAME << " in BB#" << B->getNumber()
|
||||
<< " after recursion into";
|
||||
dbgs() << "\n-- BB#" << B->getNumber() << ": " << LLVM_FUNCTION_NAME
|
||||
<< " after recursion into: {";
|
||||
for (auto I : *N)
|
||||
dbgs() << ' ' << I->getBlock()->getNumber();
|
||||
dbgs() << "\n LiveIn: " << Print<RefMap>(LiveIn, DFG);
|
||||
dbgs() << "\n Local: " << Print<RegisterSet>(LiveMap[B], DFG) << '\n';
|
||||
dbgs() << " }\n";
|
||||
dbgs() << " LiveIn: " << Print<RefMap>(LiveIn, DFG) << '\n';
|
||||
dbgs() << " Local: " << Print<RegisterSet>(LiveMap[B], DFG) << '\n';
|
||||
}
|
||||
|
||||
// Add phi uses that are live on exit from this block.
|
||||
|
73
llvm/test/CodeGen/Hexagon/rdf-extra-livein.ll
Normal file
73
llvm/test/CodeGen/Hexagon/rdf-extra-livein.ll
Normal file
@ -0,0 +1,73 @@
|
||||
; RUN: llc -march=hexagon -verify-machineinstrs < %s | FileCheck %s
|
||||
; Verify that the code compiles successfully.
|
||||
; CHECK: call printf
|
||||
|
||||
target triple = "hexagon"
|
||||
|
||||
%struct.0 = type { i32, i32, i32, i32, i32, i32, i32, i32, i32 }
|
||||
|
||||
@.str.13 = external unnamed_addr constant [60 x i8], align 1
|
||||
|
||||
declare void @printf(i8* nocapture readonly, ...) local_unnamed_addr #0
|
||||
|
||||
declare void @danny() local_unnamed_addr #0
|
||||
declare zeroext i8 @sammy() local_unnamed_addr #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @main() local_unnamed_addr #0 {
|
||||
entry:
|
||||
br i1 undef, label %if.then8, label %if.end10
|
||||
|
||||
if.then8: ; preds = %entry
|
||||
ret void
|
||||
|
||||
if.end10: ; preds = %entry
|
||||
br label %do.body
|
||||
|
||||
do.body: ; preds = %if.end88.do.body_crit_edge, %if.end10
|
||||
%cond = icmp eq i32 undef, 0
|
||||
br i1 %cond, label %if.end49, label %if.then124
|
||||
|
||||
if.end49: ; preds = %do.body
|
||||
br i1 undef, label %if.end55, label %if.then53
|
||||
|
||||
if.then53: ; preds = %if.end49
|
||||
call void @danny()
|
||||
br label %if.end55
|
||||
|
||||
if.end55: ; preds = %if.then53, %if.end49
|
||||
%call76 = call zeroext i8 @sammy() #0
|
||||
switch i8 %call76, label %sw.epilog79 [
|
||||
i8 0, label %sw.bb77
|
||||
i8 3, label %sw.bb77
|
||||
]
|
||||
|
||||
sw.bb77: ; preds = %if.end55, %if.end55
|
||||
unreachable
|
||||
|
||||
sw.epilog79: ; preds = %if.end55
|
||||
br i1 undef, label %if.end88, label %if.then81
|
||||
|
||||
if.then81: ; preds = %sw.epilog79
|
||||
%div87 = fdiv float 0.000000e+00, undef
|
||||
br label %if.end88
|
||||
|
||||
if.end88: ; preds = %if.then81, %sw.epilog79
|
||||
%t.1 = phi float [ undef, %sw.epilog79 ], [ %div87, %if.then81 ]
|
||||
%div89 = fdiv float 1.000000e+00, %t.1
|
||||
%mul92 = fmul float undef, %div89
|
||||
%div93 = fdiv float %mul92, 1.000000e+06
|
||||
%conv107 = fpext float %div93 to double
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @.str.13, i32 0, i32 0), double %conv107, double undef, i64 undef, i32 undef) #0
|
||||
br i1 undef, label %if.end88.do.body_crit_edge, label %if.then124
|
||||
|
||||
if.end88.do.body_crit_edge: ; preds = %if.end88
|
||||
br label %do.body
|
||||
|
||||
if.then124: ; preds = %if.end88, %do.body
|
||||
unreachable
|
||||
}
|
||||
|
||||
|
||||
attributes #0 = { nounwind }
|
||||
|
Loading…
Reference in New Issue
Block a user