mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-27 14:45:50 +00:00
Throttle back tail duplication to avoid creating really ugly sequences of code.
For Transforms/TailDup/if-tail-dup.ll, f.e., it produces: _foo: movl 8(%esp), %eax movl 4(%esp), %ecx testl $1, %ecx je LBB1_2 #cond_next LBB1_1: #cond_true movl $1, (%eax) LBB1_2: #cond_next testl $2, %ecx je LBB1_4 #cond_next10 LBB1_3: #cond_true6 movl $1, 4(%eax) LBB1_4: #cond_next10 testl $4, %ecx je LBB1_6 #cond_next18 LBB1_5: #cond_true14 movl $1, 8(%eax) LBB1_6: #cond_next18 testl $8, %ecx je LBB1_8 #return LBB1_7: #cond_true22 movl $1, 12(%eax) ret LBB1_8: #return ret instead of: _foo: movl 4(%esp), %eax testl $2, %eax sete %cl movl 8(%esp), %edx testl $1, %eax je LBB1_2 #cond_next LBB1_1: #cond_true movl $1, (%edx) testb %cl, %cl jne LBB1_4 #cond_next10 jmp LBB1_3 #cond_true6 LBB1_2: #cond_next testb %cl, %cl jne LBB1_4 #cond_next10 LBB1_3: #cond_true6 movl $1, 4(%edx) testl $4, %eax je LBB1_6 #cond_next18 jmp LBB1_5 #cond_true14 LBB1_4: #cond_next10 testl $4, %eax je LBB1_6 #cond_next18 LBB1_5: #cond_true14 movl $1, 8(%edx) testl $8, %eax je LBB1_8 #return jmp LBB1_7 #cond_true22 LBB1_6: #cond_next18 testl $8, %eax je LBB1_8 #return LBB1_7: #cond_true22 movl $1, 12(%edx) ret LBB1_8: #return ret git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30158 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3d222b9ace
commit
e99c623e75
@ -127,6 +127,25 @@ bool TailDup::shouldEliminateUnconditionalBranch(TerminatorInst *TI) {
|
||||
for (; PI != PE; ++PI)
|
||||
if (TooMany-- == 0) return false;
|
||||
}
|
||||
|
||||
// Finally, if this unconditional branch is a fall-through, be careful about
|
||||
// tail duplicating it. In particular, we don't want to taildup it if the
|
||||
// original block will still be there after taildup is completed: doing so
|
||||
// would eliminate the fall-through, requiring unconditional branches.
|
||||
Function::iterator DestI = Dest;
|
||||
if (&*--DestI == BI->getParent()) {
|
||||
// The uncond branch is a fall-through. Tail duplication of the block is
|
||||
// will eliminate the fall-through-ness and end up cloning the terminator
|
||||
// at the end of the Dest block. Since the original Dest block will
|
||||
// continue to exist, this means that one or the other will not be able to
|
||||
// fall through. One typical example that this helps with is code like:
|
||||
// if (a)
|
||||
// foo();
|
||||
// if (b)
|
||||
// foo();
|
||||
// Cloning the 'if b' block into the end of the first foo block is messy.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user