Index: lib/CodeGen/PrologEpilogInserter.cpp =================================================================== --- lib/CodeGen/PrologEpilogInserter.cpp +++ lib/CodeGen/PrologEpilogInserter.cpp @@ -25,6 +25,7 @@ #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" @@ -98,6 +99,9 @@ // FrameIndexVirtualScavenging is used. bool FrameIndexEliminationScavenging; + // Emit remarks. + MachineOptimizationRemarkEmitter *ORE = nullptr; + void calculateCallFrameInfo(MachineFunction &Fn); void calculateSaveRestoreBlocks(MachineFunction &Fn); void doSpillCalleeSavedRegs(MachineFunction &MF); @@ -122,6 +126,7 @@ 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) @@ -138,6 +143,7 @@ AU.addPreserved(); AU.addPreserved(); AU.addRequired(); + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -171,6 +177,7 @@ FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn); FrameIndexEliminationScavenging = (RS && !FrameIndexVirtualScavenging) || TRI->requiresFrameIndexReplacementScavenging(Fn); + ORE = &getAnalysis().getORE(); // Calculate the MaxCallFrameSize and AdjustsStack variables for the // function's frame information. Also eliminates call frame pseudo @@ -939,6 +946,12 @@ 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(StackSize)) + << " stack bytes in function"; + ORE->emit(R); } /// insertPrologEpilogCode - Scan the function for modified callee saved Index: test/CodeGen/AArch64/prologue-epilogue-remarks.mir =================================================================== --- /dev/null +++ test/CodeGen/AArch64/prologue-epilogue-remarks.mir @@ -0,0 +1,57 @@ +# 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 + +... Index: test/CodeGen/X86/O0-pipeline.ll =================================================================== --- test/CodeGen/X86/O0-pipeline.ll +++ test/CodeGen/X86/O0-pipeline.ll @@ -42,6 +42,8 @@ ; 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 Index: test/CodeGen/X86/prologue-epilogue-remarks.mir =================================================================== --- /dev/null +++ test/CodeGen/X86/prologue-epilogue-remarks.mir @@ -0,0 +1,58 @@ +# 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 + +...