]> granicus.if.org Git - llvm/commitdiff
GlobalISel: add callseq instructions to record stack usage
authorTim Northover <tnorthover@apple.com>
Tue, 17 Jan 2017 22:43:34 +0000 (22:43 +0000)
committerTim Northover <tnorthover@apple.com>
Tue, 17 Jan 2017 22:43:34 +0000 (22:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292284 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64CallLowering.cpp
test/CodeGen/AArch64/GlobalISel/call-translator.ll

index 7efee8bf8c23ba6c92307e7500bbfdf5481e0edb..4f5b2886b1a715dc8e3a0ca97c96aa7555bf5367 100644 (file)
@@ -97,7 +97,7 @@ struct OutgoingArgHandler : public CallLowering::ValueHandler {
                      MachineInstrBuilder MIB, CCAssignFn *AssignFn,
                      CCAssignFn *AssignFnVarArg)
       : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB),
-        AssignFnVarArg(AssignFnVarArg) {}
+        AssignFnVarArg(AssignFnVarArg), StackSize(0) {}
 
   unsigned getStackAddress(uint64_t Size, int64_t Offset,
                            MachinePointerInfo &MPO) override {
@@ -113,6 +113,7 @@ struct OutgoingArgHandler : public CallLowering::ValueHandler {
     MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
 
     MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
+    StackSize = std::max(StackSize, Size + Offset);
     return AddrReg;
   }
 
@@ -141,6 +142,7 @@ struct OutgoingArgHandler : public CallLowering::ValueHandler {
 
   MachineInstrBuilder MIB;
   CCAssignFn *AssignFnVarArg;
+  uint64_t StackSize;
 };
 
 void AArch64CallLowering::splitToValueTypes(
@@ -275,6 +277,8 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
   CCAssignFn *AssignFnVarArg =
       TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/true);
 
+  auto CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
+
   // Create a temporarily-floating call instruction so we can add the implicit
   // uses of arg registers.
   auto MIB = MIRBuilder.buildInstrNoInsert(Callee.isReg() ? AArch64::BLR
@@ -329,5 +333,10 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
       MIRBuilder.buildSequence(OrigRet.Reg, SplitRegs, RegOffsets);
   }
 
+  CallSeqStart.addImm(Handler.StackSize);
+  MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP)
+      .addImm(Handler.StackSize)
+      .addImm(0);
+
   return true;
 }
index 7bedad38de1aea177b3b6e8347861c40c83d58c4..f9c0fdb5bb201e57b2c2221203a82bbdc6f96389 100644 (file)
@@ -1,7 +1,9 @@
 ; RUN: llc -mtriple=aarch64-linux-gnu -O0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
 
 ; CHECK-LABEL: name: test_trivial_call
+; CHECK: ADJCALLSTACKDOWN 0, implicit-def %sp, implicit %sp
 ; CHECK: BL @trivial_callee, csr_aarch64_aapcs, implicit-def %lr
+; CHECK: ADJCALLSTACKUP 0, 0, implicit-def %sp, implicit %sp
 declare void @trivial_callee()
 define void @test_trivial_call() {
   call void @trivial_callee()
@@ -168,6 +170,7 @@ define void @test_stack_slots([8 x i64], i64 %lhs, i64 %rhs, i64* %addr) {
 ; CHECK: [[C42:%[0-9]+]](s64) = G_CONSTANT i64 42
 ; CHECK: [[C12:%[0-9]+]](s64) = G_CONSTANT i64 12
 ; CHECK: [[PTR:%[0-9]+]](p0) = G_CONSTANT i64 0
+; CHECK: ADJCALLSTACKDOWN 24, implicit-def %sp, implicit %sp
 ; CHECK: [[SP:%[0-9]+]](p0) = COPY %sp
 ; CHECK: [[C42_OFFS:%[0-9]+]](s64) = G_CONSTANT i64 0
 ; CHECK: [[C42_LOC:%[0-9]+]](p0) = G_GEP [[SP]], [[C42_OFFS]](s64)
@@ -181,6 +184,7 @@ define void @test_stack_slots([8 x i64], i64 %lhs, i64 %rhs, i64* %addr) {
 ; CHECK: [[PTR_LOC:%[0-9]+]](p0) = G_GEP [[SP]], [[PTR_OFFS]](s64)
 ; CHECK: G_STORE [[PTR]](p0), [[PTR_LOC]](p0) :: (store 8 into stack + 16, align 0)
 ; CHECK: BL @test_stack_slots
+; CHECK: ADJCALLSTACKUP 24, 0, implicit-def %sp, implicit %sp
 define void @test_call_stack() {
   call void @test_stack_slots([8 x i64] undef, i64 42, i64 12, i64* null)
   ret void