]> granicus.if.org Git - llvm/commitdiff
[GlobalISel] Defer setting HasCalls on MachineFrameInfo to selection time.
authorAmara Emerson <aemerson@apple.com>
Fri, 20 Sep 2019 23:52:07 +0000 (23:52 +0000)
committerAmara Emerson <aemerson@apple.com>
Fri, 20 Sep 2019 23:52:07 +0000 (23:52 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372443 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/GlobalISel/IRTranslator.cpp
lib/CodeGen/GlobalISel/InstructionSelect.cpp
lib/CodeGen/GlobalISel/LegalizerHelper.cpp
test/CodeGen/AArch64/GlobalISel/call-translator.ll
test/CodeGen/AArch64/GlobalISel/tail-call-no-save-fp-lr.ll [new file with mode: 0644]

index c44532e240f8bd52d0dd56d4987d4d763baf30f9..74365af7a2b7334df69bf5dc52448d2f2b0ce01d 100644 (file)
@@ -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()); });
index bf441afc9dc80db5bb3519b7d786b7414b842481..7c4fd2d140d366d41ade0adf406e551149ecb9f3 100644 (file)
@@ -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())
index d4ae3b52a465c1fdc5567b2add33098470629477..f2b37eada2e0e7d858bbe9e44dd8a76e1674bdeb 100644 (file)
@@ -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);
index b5e66d69ca07b840b0519eacf9595faaf8e05946..d6d39281f9beac8d2c9cdce5231d57d7d6b2919c 100644 (file)
@@ -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/test/CodeGen/AArch64/GlobalISel/tail-call-no-save-fp-lr.ll b/test/CodeGen/AArch64/GlobalISel/tail-call-no-save-fp-lr.ll
new file mode 100644 (file)
index 0000000..533e126
--- /dev/null
@@ -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" }
+