#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegisterScavenging.h"
// FrameIndexVirtualScavenging is used.
bool FrameIndexEliminationScavenging;
+ // Emit remarks.
+ MachineOptimizationRemarkEmitter *ORE = nullptr;
+
void calculateCallFrameInfo(MachineFunction &Fn);
void calculateSaveRestoreBlocks(MachineFunction &Fn);
void doSpillCalleeSavedRegs(MachineFunction &MF);
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(StackProtector)
+INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
INITIALIZE_PASS_END(PEI, DEBUG_TYPE,
"Prologue/Epilogue Insertion & Frame Finalization", false,
false)
AU.addPreserved<MachineLoopInfo>();
AU.addPreserved<MachineDominatorTree>();
AU.addRequired<StackProtector>();
+ AU.addRequired<MachineOptimizationRemarkEmitterPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);
FrameIndexEliminationScavenging = (RS && !FrameIndexVirtualScavenging) ||
TRI->requiresFrameIndexReplacementScavenging(Fn);
+ ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
// Calculate the MaxCallFrameSize and AdjustsStack variables for the
// function's frame information. Also eliminates call frame pseudo
int64_t StackSize = Offset - LocalAreaOffset;
MFI.setStackSize(StackSize);
NumBytesStackSpace += StackSize;
+
+ MachineOptimizationRemarkAnalysis R(
+ DEBUG_TYPE, "StackSize", Fn.getFunction()->getSubprogram(), &Fn.front());
+ R << ore::NV("NumStackBytes", static_cast<unsigned>(StackSize))
+ << " stack bytes in function";
+ ORE->emit(R);
}
/// insertPrologEpilogCode - Scan the function for modified callee saved
--- /dev/null
+# RUN: llc -mtriple=aarch64-unknown-unknown -run-pass=prologepilog -pass-remarks-output=%t -pass-remarks-analysis=prologepilog -o /dev/null %s 2>&1
+# RUN: cat %t | FileCheck %s
+...
+---
+name: fun0
+stack:
+ - { id: 0, type: default, offset: 0, size: 8, alignment: 4 }
+# CHECK: --- !Analysis
+# CHECK-NEXT: Pass: prologepilog
+# CHECK-NEXT: Name: StackSize
+# CHECK-NEXT: Function: fun0
+# CHECK-NEXT: Args:
+# CHECK-NEXT: - NumStackBytes: '16'
+# CHECK-NEXT: - String: ' stack bytes in function'
+# CHECK-NEXT: ...
+constants:
+body: |
+ bb.0:
+ RET_ReallyLR
+
+...
+---
+name: fun1
+stack:
+ - { id: 0, type: default, offset: 0, size: 19, alignment: 4 }
+# CHECK: --- !Analysis
+# CHECK-NEXT: Pass: prologepilog
+# CHECK-NEXT: Name: StackSize
+# CHECK-NEXT: Function: fun1
+# CHECK-NEXT: Args:
+# CHECK-NEXT: - NumStackBytes: '32'
+# CHECK-NEXT: - String: ' stack bytes in function'
+# CHECK-NEXT: ...
+constants:
+body: |
+ bb.0:
+ RET_ReallyLR
+
+...
+---
+name: fun2
+stack:
+ - { id: 0, type: default, offset: 0, size: 1024, alignment: 4 }
+# --- !Analysis
+# CHECK: Pass: prologepilog
+# CHECK-NEXT: Name: StackSize
+# CHECK-NEXT: Function: fun2
+# CHECK-NEXT: Args:
+# CHECK-NEXT: - NumStackBytes: '1040'
+# CHECK-NEXT: - String: ' stack bytes in function'
+# CHECK-NEXT: ...
+constants:
+body: |
+ bb.0:
+ RET_ReallyLR
+
+...
; CHECK-NEXT: Fast Register Allocator
; CHECK-NEXT: Bundle Machine CFG Edges
; CHECK-NEXT: X86 FP Stackifier
+; CHECK-NEXT: Lazy Machine Block Frequency Analysis
+; CHECK-NEXT: Machine Optimization Remark Emitter
; CHECK-NEXT: Prologue/Epilogue Insertion & Frame Finalization
; CHECK-NEXT: Post-RA pseudo instruction expansion pass
; CHECK-NEXT: X86 pseudo instruction expansion pass
--- /dev/null
+# RUN: llc -mtriple=x86_64-unknown-unknown -run-pass=prologepilog -pass-remarks-output=%t -pass-remarks-analysis=prologepilog -o /dev/null %s 2>&1
+# RUN: cat %t | FileCheck %s
+...
+---
+name: fun0
+stack:
+ - { id: 0, type: default, offset: 0, size: 8, alignment: 4 }
+# --- !Analysis
+# CHECK: Pass: prologepilog
+# CHECK-NEXT: Name: StackSize
+# CHECK-NEXT: Function: fun0
+# CHECK-NEXT: Args:
+# CHECK-NEXT: - NumStackBytes: '8'
+# CHECK-NEXT: - String: ' stack bytes in function'
+# CHECK-NEXT: ...
+
+constants:
+body: |
+ bb.0:
+ RETQ
+
+...
+---
+name: fun1
+stack:
+ - { id: 0, type: default, offset: 0, size: 19, alignment: 4 }
+# --- !Analysis
+# CHECK: Pass: prologepilog
+# CHECK-NEXT: Name: StackSize
+# CHECK-NEXT: Function: fun1
+# CHECK-NEXT: Args:
+# CHECK-NEXT: - NumStackBytes: '20'
+# CHECK-NEXT: - String: ' stack bytes in function'
+# CHECK-NEXT: ...
+constants:
+body: |
+ bb.0:
+ RETQ
+
+...
+---
+name: fun2
+stack:
+ - { id: 0, type: default, offset: 0, size: 1024, alignment: 8 }
+# --- !Analysis
+# CHECK: Pass: prologepilog
+# CHECK-NEXT: Name: StackSize
+# CHECK-NEXT: Function: fun2
+# CHECK-NEXT: Args:
+# CHECK-NEXT: - NumStackBytes: '1024'
+# CHECK-NEXT: - String: ' stack bytes in function'
+# CHECK-NEXT: ...
+constants:
+body: |
+ bb.0:
+ RETQ
+
+...