From 7ac1039957f9aebcdf3ccf36cdd11067eb42b832 Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Fri, 20 Sep 2019 23:52:07 +0000 Subject: [PATCH] [GlobalISel] Defer setting HasCalls on MachineFrameInfo to selection time. We currently always set the HasCalls on MFI during translation and legalization if we're handling a call or legalizing to a libcall. However, if that call is later optimized to a tail call then we don't need the flag. The flag being set to true causes frame lowering to always save and restore FP/LR, which adds unnecessary code. This change does the same thing as SelectionDAG and ports over some code that scans instructions after selection, using TargetInstrInfo to determine if target opcodes are known calls. Code size geomean improvements on CTMark: -O0 : 0.1% -Os : 0.3% Differential Revision: https://reviews.llvm.org/D67868 llvm-svn: 372443 --- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 4 +++- llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp | 18 ++++++++++++++++++ llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 3 --- .../CodeGen/AArch64/GlobalISel/call-translator.ll | 1 - .../AArch64/GlobalISel/tail-call-no-save-fp-lr.ll | 20 ++++++++++++++++++++ 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/tail-call-no-save-fp-lr.ll diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index c44532e..74365af 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1564,7 +1564,9 @@ bool IRTranslator::translateCallSite(const ImmutableCallSite &CS, Args.push_back(getOrCreateVRegs(*Arg)); } - MF->getFrameInfo().setHasCalls(true); + // We don't set HasCalls on MFI here yet because call lowering may decide to + // optimize into tail calls. Instead, we defer that to selection where a final + // scan is done to check if any instructions are calls. bool Success = CLI->lowerCall(MIRBuilder, CS, Res, Args, SwiftErrorVReg, [&]() { return getOrCreateVReg(*CS.getCalledValue()); }); diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp index bf441af..7c4fd2d 100644 --- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -17,7 +17,9 @@ #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" @@ -223,6 +225,22 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { auto &TLI = *MF.getSubtarget().getTargetLowering(); TLI.finalizeLowering(MF); + // Determine if there are any calls in this machine function. Ported from + // SelectionDAG. + MachineFrameInfo &MFI = MF.getFrameInfo(); + for (const auto &MBB : MF) { + if (MFI.hasCalls() && MF.hasInlineAsm()) + break; + + for (const auto &MI : MBB) { + if ((MI.isCall() && !MI.isReturn()) || MI.isStackAligningInlineAsm()) + MFI.setHasCalls(true); + if (MI.isInlineAsm()) + MF.setHasInlineAsm(true); + } + } + + LLVM_DEBUG({ dbgs() << "Rules covered by selecting function: " << MF.getName() << ":"; for (auto RuleID : CoverageInfo.covered()) diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index d4ae3b5..f2b37ea 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -364,8 +364,6 @@ llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering(); const char *Name = TLI.getLibcallName(Libcall); - MIRBuilder.getMF().getFrameInfo().setHasCalls(true); - CallLowering::CallLoweringInfo Info; Info.CallConv = TLI.getLibcallCallingConv(Libcall); Info.Callee = MachineOperand::CreateES(Name); @@ -430,7 +428,6 @@ llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, const char *Name = TLI.getLibcallName(RTLibcall); MIRBuilder.setInstr(MI); - MIRBuilder.getMF().getFrameInfo().setHasCalls(true); CallLowering::CallLoweringInfo Info; Info.CallConv = TLI.getLibcallCallingConv(RTLibcall); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll index b5e66d6..d6d3928 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll @@ -100,7 +100,6 @@ define {double, i64, i32} @test_struct_return({double, i64, i32}* %addr) { } ; CHECK-LABEL: name: test_arr_call -; CHECK: hasCalls: true ; CHECK: %0:_(p0) = COPY $x0 ; CHECK: [[LD1:%[0-9]+]]:_(s64) = G_LOAD %0(p0) :: (load 8 from %ir.addr) ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 8 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/tail-call-no-save-fp-lr.ll b/llvm/test/CodeGen/AArch64/GlobalISel/tail-call-no-save-fp-lr.ll new file mode 100644 index 0000000..533e126 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/tail-call-no-save-fp-lr.ll @@ -0,0 +1,20 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc %s -verify-machineinstrs -mtriple aarch64-apple-darwin -global-isel -global-isel-abort=1 -o - 2>&1 | FileCheck %s + +; Check that we get a tail call to foo without saving fp/lr. +define void @bar(i32 %a) #1 { +; CHECK-LABEL: bar: +; CHECK: ; %bb.0: ; %entry +; CHECK-NEXT: b _zoo +entry: + tail call void @zoo(i32 undef) + ret void +} + +define void @zoo(i32 %a) { +entry: + ret void +} + +attributes #1 = { "frame-pointer"="all" } + -- 2.7.4