From 722aa9573bf4d6b1a0b29fd3bd573fefafc20ebb Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Fri, 10 Jul 2015 22:09:55 +0000 Subject: [PATCH] [ShrinkWrap][PEI] Do not insert epilogue for unreachable blocks. Although this is not incorrect to insert such code, it is useless and it hurts the binary size. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241946 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/PrologEpilogInserter.cpp | 11 ++++-- test/CodeGen/AArch64/arm64-shrink-wrapping.ll | 39 +++++++++++++++++++ test/CodeGen/X86/x86-shrink-wrapping.ll | 39 +++++++++++++++++++ 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 76583f0de88..7e162332de6 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -92,7 +92,7 @@ private: void insertPrologEpilogCode(MachineFunction &Fn); // Convenience for recognizing return blocks. - bool isReturnBlock(MachineBasicBlock *MBB); + bool isReturnBlock(const MachineBasicBlock *MBB) const; }; } // namespace @@ -127,7 +127,7 @@ void PEI::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } -bool PEI::isReturnBlock(MachineBasicBlock* MBB) { +bool PEI::isReturnBlock(const MachineBasicBlock* MBB) const { return (MBB && !MBB->empty() && MBB->back().isReturn()); } @@ -143,7 +143,12 @@ void PEI::calculateSets(MachineFunction &Fn) { if (MFI->getSavePoint()) { SaveBlock = MFI->getSavePoint(); assert(MFI->getRestorePoint() && "Both restore and save must be set"); - RestoreBlocks.push_back(MFI->getRestorePoint()); + MachineBasicBlock *RestoreBlock = MFI->getRestorePoint(); + // If RestoreBlock does not have any successor and is not a return block + // then the end point is unreachable and we do not need to insert any + // epilogue. + if (!RestoreBlock->succ_empty() || isReturnBlock(RestoreBlock)) + RestoreBlocks.push_back(RestoreBlock); return; } diff --git a/test/CodeGen/AArch64/arm64-shrink-wrapping.ll b/test/CodeGen/AArch64/arm64-shrink-wrapping.ll index c1777513fa0..599712be401 100644 --- a/test/CodeGen/AArch64/arm64-shrink-wrapping.ll +++ b/test/CodeGen/AArch64/arm64-shrink-wrapping.ll @@ -500,3 +500,42 @@ if.end: ; preds = %if.else, %if.then } declare i32 @someVariadicFunc(i32, ...) + +; Make sure we do not insert unreachable code after noreturn function. +; Although this is not incorrect to insert such code, it is useless +; and it hurts the binary size. +; +; CHECK-LABEL: noreturn: +; DISABLE: stp +; +; CHECK: and [[TEST:w[0-9]+]], w0, #0xff +; CHECK-NEXT: cbnz [[TEST]], [[ABORT:LBB[0-9_]+]] +; +; CHECK: movz w0, #0x2a +; +; DISABLE-NEXT: ldp +; +; CHECK-NEXT: ret +; +; CHECK: [[ABORT]]: ; %if.abort +; +; ENABLE: stp +; +; CHECK: bl _abort +; ENABLE-NOT: ldp +define i32 @noreturn(i8 signext %bad_thing) { +entry: + %tobool = icmp eq i8 %bad_thing, 0 + br i1 %tobool, label %if.end, label %if.abort + +if.abort: + tail call void @abort() #0 + unreachable + +if.end: + ret i32 42 +} + +declare void @abort() #0 + +attributes #0 = { noreturn nounwind } diff --git a/test/CodeGen/X86/x86-shrink-wrapping.ll b/test/CodeGen/X86/x86-shrink-wrapping.ll index 5848eddf437..8c91335d91a 100644 --- a/test/CodeGen/X86/x86-shrink-wrapping.ll +++ b/test/CodeGen/X86/x86-shrink-wrapping.ll @@ -598,3 +598,42 @@ if.then.60: ; preds = %if.end.55 cleanup: ; preds = %if.then.60, %if.end.55, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %lor.lhs.false, %if.end, %entry ret void } + +; Make sure we do not insert unreachable code after noreturn function. +; Although this is not incorrect to insert such code, it is useless +; and it hurts the binary size. +; +; CHECK-LABEL: noreturn: +; DISABLE: pushq +; +; CHECK: testb %dil, %dil +; CHECK-NEXT: jne [[ABORT:LBB[0-9_]+]] +; +; CHECK: movl $42, %eax +; +; DISABLE-NEXT: popq +; +; CHECK-NEXT: retq +; +; CHECK: [[ABORT]]: ## %if.abort +; +; ENABLE: pushq +; +; CHECK: callq _abort +; ENABLE-NOT: popq +define i32 @noreturn(i8 signext %bad_thing) { +entry: + %tobool = icmp eq i8 %bad_thing, 0 + br i1 %tobool, label %if.end, label %if.abort + +if.abort: + tail call void @abort() #0 + unreachable + +if.end: + ret i32 42 +} + +declare void @abort() #0 + +attributes #0 = { noreturn nounwind } -- 2.34.1