From bb63f66686ce2fd17e7391596dad35451328a66f Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 28 Mar 2016 14:52:21 +0000 Subject: [PATCH] [Hexagon] Only use restore functions for single register at -Oz llvm-svn: 264581 --- llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | 11 +++++++ llvm/test/CodeGen/Hexagon/restore-single-reg.ll | 42 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 llvm/test/CodeGen/Hexagon/restore-single-reg.ll diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index 2b7c71c..81c85c4 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -2218,7 +2218,18 @@ bool HexagonFrameLowering::useRestoreFunction(MachineFunction &MF, const CSIVect &CSI) const { if (shouldInlineCSR(MF, CSI)) return false; + // The restore functions do a bit more than just restoring registers. + // The non-returning versions will go back directly to the caller's + // caller, others will clean up the stack frame in preparation for + // a tail call. Using them can still save code size even if only one + // register is getting restores. Make the decision based on -Oz: + // using -Os will use inline restore for a single register. + if (isMinSize(MF)) + return true; unsigned NumCSI = CSI.size(); + if (NumCSI <= 1) + return false; + unsigned Threshold = isOptSize(MF) ? SpillFuncThresholdOs-1 : SpillFuncThreshold; return Threshold < NumCSI; diff --git a/llvm/test/CodeGen/Hexagon/restore-single-reg.ll b/llvm/test/CodeGen/Hexagon/restore-single-reg.ll new file mode 100644 index 0000000..8abd4a8 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/restore-single-reg.ll @@ -0,0 +1,42 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048" +target triple = "hexagon" + +; Generate the inline restore for single register pair for functions +; with "optsize" attribute. + +; CHECK-LABEL: fred_os +; CHECK-DAG: memd{{.*}} = r17:16 +; CHECK-DAG: r17:16 = memd{{.*}} +; CHECK-DAG: deallocframe +; CHECK-NOT: call __restore + +define i32 @fred_os(i32 %x) #0 { +entry: + %call = tail call i32 @foo(i32 %x) #2 + %call1 = tail call i32 @bar(i32 %x, i32 %call) #2 + ret i32 %call1 +} + +; Generate the restoring call for single register pair for functions +; with "minsize" attribute. + +; CHECK-LABEL: fred_oz +; CHECK-DAG: memd{{.*}} = r17:16 +; CHECK-NOT: r17:16 = memd{{.*}} +; CHECK-DAG: call __restore + +define i32 @fred_oz(i32 %x) #1 { +entry: + %call = tail call i32 @foo(i32 %x) #2 + %call1 = tail call i32 @bar(i32 %x, i32 %call) #2 + ret i32 %call1 +} + +declare i32 @foo(i32) #2 +declare i32 @bar(i32, i32) #2 + +attributes #0 = { nounwind optsize "disable-tail-calls"="false" } +attributes #1 = { nounwind minsize "disable-tail-calls"="false" } +attributes #2 = { nounwind optsize } -- 2.7.4