1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[X86] Allow x86 call frame optimization to fold more loads into pushes

This abstracts away the test for "when can we fold across a MachineInstruction"
into the the MI interface, and changes call-frame optimization use the same test
the peephole optimizer users.

Differential Revision: http://reviews.llvm.org/D11945

llvm-svn: 244729
This commit is contained in:
Michael Kuperstein 2015-08-12 10:14:58 +00:00
parent ac50a3d981
commit 8c8a758faa
5 changed files with 36 additions and 9 deletions

View File

@ -1100,6 +1100,9 @@ public:
///
bool hasUnmodeledSideEffects() const;
/// Returns true if it is illegal to fold a load across this instruction.
bool isLoadFoldBarrier() const;
/// Return true if all the defs of this instruction are dead.
bool allDefsAreDead() const;

View File

@ -1503,6 +1503,10 @@ bool MachineInstr::hasUnmodeledSideEffects() const {
return false;
}
bool MachineInstr::isLoadFoldBarrier() const {
return mayStore() || isCall() || hasUnmodeledSideEffects();
}
/// allDefsAreDead - Return true if all the defs of this instruction are dead.
///
bool MachineInstr::allDefsAreDead() const {

View File

@ -1234,9 +1234,9 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
if (MI->isDebugValue())
continue;
// If there exists an instruction which belongs to the following
// categories, we will discard the load candidates.
if (MI->mayStore() || MI->isCall() || MI->hasUnmodeledSideEffects())
// If we run into an instruction we can't fold across, discard
// the load candidates.
if (MI->isLoadFoldBarrier())
FoldAsLoadDefCandidates.clear();
if (MI->isPosition() || MI->isPHI() || MI->isImplicitDef() ||

View File

@ -528,13 +528,10 @@ MachineInstr *X86CallFrameOptimization::canFoldIntoRegPush(
DefMI->getParent() != FrameSetup->getParent())
return nullptr;
// Now, make sure everything else up until the ADJCALLSTACK is a sequence
// of MOVs. To be less conservative would require duplicating a lot of the
// logic from PeepholeOptimizer.
// FIXME: A possibly better approach would be to teach the PeepholeOptimizer
// to be smarter about folding into pushes.
// Make sure we don't have any instructions between DefMI and the
// push that make folding the load illegal.
for (auto I = DefMI; I != FrameSetup; ++I)
if (I->getOpcode() != X86::MOV32rm)
if (I->isLoadFoldBarrier())
return nullptr;
return DefMI;

View File

@ -357,3 +357,26 @@ entry:
call void @good(i32 9, i32 10, i32 11, i32 12)
ret void
}
; Make sure the add does not prevent folding loads into pushes.
; val1 and val2 will not be folded into pushes since they have
; an additional use, but val3 should be.
; NORMAL-LABEL: test13:
; NORMAL: movl ([[P1:%e..]]), [[V1:%e..]]
; NORMAL-NEXT: movl ([[P2:%e..]]), [[V2:%e..]]
; NORMAL-NEXT: , [[ADD:%e..]]
; NORMAL-NEXT: pushl [[ADD]]
; NORMAL-NEXT: pushl ([[P3:%e..]])
; NORMAL-NEXT: pushl [[V2]]
; NORMAL-NEXT: pushl [[V1]]
; NORMAL-NEXT: calll _good
; NORMAL: movl [[P3]], %eax
define i32* @test13(i32* inreg %ptr1, i32* inreg %ptr2, i32* inreg %ptr3) optsize {
entry:
%val1 = load i32, i32* %ptr1
%val2 = load i32, i32* %ptr2
%val3 = load i32, i32* %ptr3
%add = add i32 %val1, %val2
call void @good(i32 %val1, i32 %val2, i32 %val3, i32 %add)
ret i32* %ptr3
}