34 changes: 34 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
int64_t &Offset, unsigned &Width,
const TargetRegisterInfo *TRI) const;

/// Return the immediate offset of the base register in a load/store \p LdSt.
MachineOperand &getMemOpBaseRegImmOfsOffsetOperand(MachineInstr &LdSt) const;

/// \brief Returns true if opcode \p Opc is a memory operation. If it is, set
/// \p Scale, \p Width, \p MinOffset, and \p MaxOffset accordingly.
///
/// For unscaled instructions, \p Scale is set to 1.
bool getMemOpInfo(unsigned Opcode, unsigned &Scale, unsigned &Width,
int64_t &MinOffset, int64_t &MaxOffset) const;

bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt,
unsigned NumLoads) const override;

Expand Down Expand Up @@ -242,7 +252,31 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
ArrayRef<std::pair<unsigned, const char *>>
getSerializableBitmaskMachineOperandTargetFlags() const override;

bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const override;
unsigned getOutliningBenefit(size_t SequenceSize, size_t Occurrences,
bool CanBeTailCall) const override;
AArch64GenInstrInfo::MachineOutlinerInstrType
getOutliningType(MachineInstr &MI) const override;
void insertOutlinerEpilogue(MachineBasicBlock &MBB,
MachineFunction &MF,
bool IsTailCall) const override;
void insertOutlinerPrologue(MachineBasicBlock &MBB,
MachineFunction &MF,
bool isTailCall) const override;
MachineBasicBlock::iterator
insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
MachineBasicBlock::iterator &It,
MachineFunction &MF,
bool IsTailCall) const override;

private:

/// \brief Sets the offsets on outlined instructions in \p MBB which use SP
/// so that they will be valid post-outlining.
///
/// \param MBB A \p MachineBasicBlock in an outlined function.
void fixupPostOutline(MachineBasicBlock &MBB) const;

void instantiateCondBranch(MachineBasicBlock &MBB, const DebugLoc &DL,
MachineBasicBlock *TBB,
ArrayRef<MachineOperand> Cond) const;
Expand Down
43 changes: 43 additions & 0 deletions llvm/test/CodeGen/AArch64/machine-outliner.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
; RUN: llc -enable-machine-outliner -mtriple=aarch64-apple-darwin < %s | FileCheck %s

define void @cat() #0 {
; CHECK-LABEL: _cat:
; CHECK: b l_OUTLINED_FUNCTION_0
; CHECK-NOT: ret
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
ret void
}

define void @dog() #0 {
; CHECK-LABEL: _dog:
; CHECK: b l_OUTLINED_FUNCTION_0
; CHECK-NOT: ret
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
%4 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 1, i32* %2, align 4
store i32 2, i32* %3, align 4
store i32 3, i32* %4, align 4
ret void
}

; CHECK-LABEL: l_OUTLINED_FUNCTION_0:
; CHECK: orr w8, wzr, #0x1
; CHECK-NEXT: stp w8, wzr, [sp, #8]
; CHECK-NEXT: orr w8, wzr, #0x2
; CHECK-NEXT: str w8, [sp, #4]
; CHECK-NEXT: orr w8, wzr, #0x3
; CHECK-NEXT: str w8, [sp], #16
; CHECK-NEXT: ret


attributes #0 = { noredzone nounwind ssp uwtable "no-frame-pointer-elim"="false" "target-cpu"="cyclone" }