diff options
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 49 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/machine-outliner-calls.mir | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/machine-outliner.mir | 2 |
3 files changed, 20 insertions, 33 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 66950f50c82..2f147bcb2d5 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5066,7 +5066,13 @@ AArch64InstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT, if (MI.getOpcode() == AArch64::ADRP) return MachineOutlinerInstrType::Legal; - // Outline calls without stack parameters or aggregate parameters. + // If MI is a call we might be able to outline it. We don't want to outline + // any calls that rely on the position of items on the stack. When we outline + // something containing a call, we have to emit a save and restore of LR in + // the outlined function. Currently, this always happens by saving LR to the + // stack. Thus, if we outline, say, half the parameters for a function call + // plus the call, then we'll break the callee's expectations for the layout + // of the stack. if (MI.isCall()) { const Module *M = MF->getFunction().getParent(); assert(M && "No module?"); @@ -5089,44 +5095,25 @@ AArch64InstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT, // Only handle functions that we have information about. if (!Callee) return MachineOutlinerInstrType::Illegal; - + // We have a function we have information about. Check it if it's something // can safely outline. - - // If the callee is vararg, it passes parameters on the stack. Don't touch - // it. - // FIXME: Functions like printf are very common and we should be able to - // outline them. - if (Callee->isVarArg()) - return MachineOutlinerInstrType::Illegal; - - // Check if any of the arguments are a pointer to a struct. We don't want - // to outline these since they might be loaded in two instructions. - for (Argument &Arg : Callee->args()) { - if (Arg.getType()->isPointerTy() && - Arg.getType()->getPointerElementType()->isAggregateType()) - return MachineOutlinerInstrType::Illegal; - } - - // If the thing we're calling doesn't access memory at all, then we're good - // to go. - if (Callee->doesNotAccessMemory()) - return MachineOutlinerInstrType::Legal; - - - // It accesses memory. Get the machine function for the callee to see if - // it's safe to outline. MachineFunction *CalleeMF = MF->getMMI().getMachineFunction(*Callee); // We don't know what's going on with the callee at all. Don't touch it. - if (!CalleeMF) + if (!CalleeMF) return MachineOutlinerInstrType::Illegal; - // Does it pass anything on the stack? If it does, don't outline it. - if (CalleeMF->getInfo<AArch64FunctionInfo>()->getBytesInStackArgArea() != 0) + // Check if we know anything about the callee saves on the function. If we + // don't, then don't touch it, since that implies that we haven't + // computed anything about its stack frame yet. + MachineFrameInfo &MFI = CalleeMF->getFrameInfo(); + if (!MFI.isCalleeSavedInfoValid() || MFI.getStackSize() > 0 || + MFI.getNumObjects() > 0) return MachineOutlinerInstrType::Illegal; - - // It doesn't, so it's safe to outline and we're done. + + // At this point, we can say that CalleeMF ought to not pass anything on the + // stack. Therefore, we can outline it. return MachineOutlinerInstrType::Legal; } diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-calls.mir b/llvm/test/CodeGen/AArch64/machine-outliner-calls.mir index d47d96e7b99..41010d87cb8 100644 --- a/llvm/test/CodeGen/AArch64/machine-outliner-calls.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-calls.mir @@ -1,4 +1,4 @@ -# RUN: llc -simplify-mir -mtriple=aarch64--- -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s +# RUN: llc -mtriple=aarch64--- -run-pass=prologepilog -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s --- | define void @baz() #0 { ret void diff --git a/llvm/test/CodeGen/AArch64/machine-outliner.mir b/llvm/test/CodeGen/AArch64/machine-outliner.mir index 79d0ed2d070..d59dd12502a 100644 --- a/llvm/test/CodeGen/AArch64/machine-outliner.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner.mir @@ -1,4 +1,4 @@ -# RUN: llc -mtriple=aarch64--- -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s +# RUN: llc -mtriple=aarch64--- -run-pass=prologepilog -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s --- | @x = common global i32 0, align 4 |