Skip to content

Commit

Permalink
Do not remove implicit defs in BranchFolder
Browse files Browse the repository at this point in the history
Branch folder removes implicit defs if they are the only non-branching
instructions in a block, and the branches do not use the defined registers.
The problem is that in some cases these implicit defs are required for
the liveness information to be correct.

Differential Revision: https://reviews.llvm.org/D25478

llvm-svn: 284036
  • Loading branch information
Krzysztof Parzyszek committed Oct 12, 2016
1 parent 105a3ce commit 8271be9
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 55 deletions.
54 changes: 0 additions & 54 deletions llvm/lib/CodeGen/BranchFolding.cpp
Expand Up @@ -145,59 +145,6 @@ void BranchFolder::RemoveDeadBlock(MachineBasicBlock *MBB) {
MLI->removeBlock(MBB);
}

/// OptimizeImpDefsBlock - If a basic block is just a bunch of implicit_def
/// followed by terminators, and if the implicitly defined registers are not
/// used by the terminators, remove those implicit_def's. e.g.
/// BB1:
/// r0 = implicit_def
/// r1 = implicit_def
/// br
/// This block can be optimized away later if the implicit instructions are
/// removed.
bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) {
SmallSet<unsigned, 4> ImpDefRegs;
MachineBasicBlock::iterator I = MBB->begin();
while (I != MBB->end()) {
if (!I->isImplicitDef())
break;
unsigned Reg = I->getOperand(0).getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
ImpDefRegs.insert(*SubRegs);
} else {
ImpDefRegs.insert(Reg);
}
++I;
}
if (ImpDefRegs.empty())
return false;

MachineBasicBlock::iterator FirstTerm = I;
while (I != MBB->end()) {
if (!TII->isUnpredicatedTerminator(*I))
return false;
// See if it uses any of the implicitly defined registers.
for (const MachineOperand &MO : I->operands()) {
if (!MO.isReg() || !MO.isUse())
continue;
unsigned Reg = MO.getReg();
if (ImpDefRegs.count(Reg))
return false;
}
++I;
}

I = MBB->begin();
while (I != FirstTerm) {
MachineInstr *ImpDefMI = &*I;
++I;
MBB->erase(ImpDefMI);
}

return true;
}

/// OptimizeFunction - Perhaps branch folding, tail merging and other
/// CFG optimizations on the given function. Block placement changes the layout
/// and may create new tail merging opportunities.
Expand Down Expand Up @@ -228,7 +175,6 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
SmallVector<MachineOperand, 4> Cond;
if (!TII->analyzeBranch(MBB, TBB, FBB, Cond, true))
MadeChange |= MBB.CorrectExtraCFGEdges(TBB, FBB, !Cond.empty());
MadeChange |= OptimizeImpDefsBlock(&MBB);
}

// Recalculate funclet membership.
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/CodeGen/BranchFolding.h
Expand Up @@ -156,7 +156,6 @@ namespace llvm {
bool OptimizeBranches(MachineFunction &MF);
bool OptimizeBlock(MachineBasicBlock *MBB);
void RemoveDeadBlock(MachineBasicBlock *MBB);
bool OptimizeImpDefsBlock(MachineBasicBlock *MBB);

bool HoistCommonCode(MachineFunction &MF);
bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB);
Expand Down
29 changes: 29 additions & 0 deletions llvm/test/CodeGen/Hexagon/branchfolder-keep-impdef.ll
@@ -0,0 +1,29 @@
; RUN: llc -march=hexagon -verify-machineinstrs < %s | FileCheck %s
;
; Check that the testcase compiles successfully. Expect that if-conversion
; took place.
; CHECK-LABEL: fred:
; CHECK: if (!p0) r1 = memw(r0 + #0)

target triple = "hexagon"

define void @fred(i32 %p0) local_unnamed_addr align 2 {
b0:
br i1 undef, label %b1, label %b2

b1: ; preds = %b0
%t0 = load i8*, i8** undef, align 4
br label %b2

b2: ; preds = %b1, %b0
%t1 = phi i8* [ %t0, %b1 ], [ undef, %b0 ]
%t2 = getelementptr inbounds i8, i8* %t1, i32 %p0
tail call void @llvm.memmove.p0i8.p0i8.i32(i8* undef, i8* %t2, i32 undef, i32 1, i1 false) #1
unreachable
}

declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #0

attributes #0 = { argmemonly nounwind }
attributes #1 = { nounwind }

Expand Up @@ -100,6 +100,7 @@ while.end: ; preds = %entry
; CHECK-NEXT: in Loop: Header
; CHECK-NEXT: incq
; CHECK-NEXT: %for.body3.us.i
; CHECK-NEXT: Parent Loop
; CHECK-NEXT: Inner Loop
; CHECK: testb
; CHECK: je
Expand Down

0 comments on commit 8271be9

Please sign in to comment.