Skip to content
This repository has been archived by the owner on Jan 1, 2023. It is now read-only.

Commit

Permalink
[PGO][PGSO] SizeOpts changes.
Browse files Browse the repository at this point in the history
Summary:
(Split of off D67120)

SizeOpts/MachineSizeOpts changes for profile guided size optimization.

Reviewers: davidxl

Subscribers: mgorny, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D69070

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@375254 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
hjyamauchi committed Oct 18, 2019
1 parent d694690 commit 1794a21
Show file tree
Hide file tree
Showing 15 changed files with 661 additions and 20 deletions.
3 changes: 3 additions & 0 deletions include/llvm/CodeGen/MachineBlockFrequencyInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class MachineBlockFrequencyInfo : public MachineFunctionPass {
static char ID;

MachineBlockFrequencyInfo();
explicit MachineBlockFrequencyInfo(MachineFunction &F,
MachineBranchProbabilityInfo &MBPI,
MachineLoopInfo &MLI);
~MachineBlockFrequencyInfo() override;

void getAnalysisUsage(AnalysisUsage &AU) const override;
Expand Down
5 changes: 5 additions & 0 deletions include/llvm/CodeGen/MachineDominators.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class MachineDominatorTree : public MachineFunctionPass {
static char ID; // Pass ID, replacement for typeid

MachineDominatorTree();
explicit MachineDominatorTree(MachineFunction &MF) : MachineFunctionPass(ID) {
calculate(MF);
}

DomTreeT &getBase() {
if (!DT) DT.reset(new DomTreeT());
Expand Down Expand Up @@ -111,6 +114,8 @@ class MachineDominatorTree : public MachineFunctionPass {

bool runOnMachineFunction(MachineFunction &F) override;

void calculate(MachineFunction &F);

bool dominates(const MachineDomTreeNode *A,
const MachineDomTreeNode *B) const {
applySplitCriticalEdges();
Expand Down
6 changes: 6 additions & 0 deletions include/llvm/CodeGen/MachineLoopInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

namespace llvm {

class MachineDominatorTree;
// Implementation in LoopInfoImpl.h
class MachineLoop;
extern template class LoopBase<MachineBasicBlock, MachineLoop>;
Expand Down Expand Up @@ -91,6 +92,10 @@ class MachineLoopInfo : public MachineFunctionPass {
MachineLoopInfo() : MachineFunctionPass(ID) {
initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
}
explicit MachineLoopInfo(MachineDominatorTree &MDT)
: MachineFunctionPass(ID) {
calculate(MDT);
}
MachineLoopInfo(const MachineLoopInfo &) = delete;
MachineLoopInfo &operator=(const MachineLoopInfo &) = delete;

Expand Down Expand Up @@ -133,6 +138,7 @@ class MachineLoopInfo : public MachineFunctionPass {

/// Calculate the natural loop information.
bool runOnMachineFunction(MachineFunction &F) override;
void calculate(MachineDominatorTree &MDT);

void releaseMemory() override { LI.releaseMemory(); }

Expand Down
37 changes: 37 additions & 0 deletions include/llvm/CodeGen/MachineSizeOpts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===- MachineSizeOpts.h - machine size optimization ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains some shared machine IR code size optimization related
// code.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINE_SIZEOPTS_H
#define LLVM_CODEGEN_MACHINE_SIZEOPTS_H

#include "llvm/Transforms/Utils/SizeOpts.h"

namespace llvm {

class ProfileSummaryInfo;
class MachineBasicBlock;
class MachineBlockFrequencyInfo;
class MachineFunction;

/// Returns true if machine function \p MF is suggested to be size-optimized
/// base on the profile.
bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo *BFI);
/// Returns true if machine basic block \p MBB is suggested to be size-optimized
/// base on the profile.
bool shouldOptimizeForSize(const MachineBasicBlock *MBB,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo *MBFI);

} // end namespace llvm

#endif // LLVM_CODEGEN_MACHINE_SIZEOPTS_H
55 changes: 53 additions & 2 deletions include/llvm/Transforms/Utils/SizeOpts.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,71 @@
#ifndef LLVM_TRANSFORMS_UTILS_SIZEOPTS_H
#define LLVM_TRANSFORMS_UTILS_SIZEOPTS_H

#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Support/CommandLine.h"

using namespace llvm;

extern cl::opt<bool> EnablePGSO;
extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
extern cl::opt<bool> ForcePGSO;
extern cl::opt<int> PgsoCutoffInstrProf;
extern cl::opt<int> PgsoCutoffSampleProf;

namespace llvm {

class BasicBlock;
class BlockFrequencyInfo;
class Function;
class ProfileSummaryInfo;

template<typename AdapterT, typename FuncT, typename BFIT>
bool shouldFuncOptimizeForSizeImpl(const FuncT *F, ProfileSummaryInfo *PSI,
BFIT *BFI) {
assert(F);
if (!PSI || !BFI || !PSI->hasProfileSummary())
return false;
if (ForcePGSO)
return true;
if (!EnablePGSO)
return false;
if (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize()) {
// Even if the working set size isn't large, size-optimize cold code.
return AdapterT::isFunctionColdInCallGraph(F, PSI, *BFI);
}
return !AdapterT::isFunctionHotInCallGraphNthPercentile(
PSI->hasSampleProfile() ? PgsoCutoffSampleProf : PgsoCutoffInstrProf,
F, PSI, *BFI);
}

template<typename AdapterT, typename BlockT, typename BFIT>
bool shouldOptimizeForSizeImpl(const BlockT *BB, ProfileSummaryInfo *PSI,
BFIT *BFI) {
assert(BB);
if (!PSI || !BFI || !PSI->hasProfileSummary())
return false;
if (ForcePGSO)
return true;
if (!EnablePGSO)
return false;
if (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize()) {
// Even if the working set size isn't large, size-optimize cold code.
return AdapterT::isColdBlock(BB, PSI, BFI);
}
return !AdapterT::isHotBlockNthPercentile(
PSI->hasSampleProfile() ? PgsoCutoffSampleProf : PgsoCutoffInstrProf,
BB, PSI, BFI);
}

/// Returns true if function \p F is suggested to be size-optimized base on the
/// profile.
bool shouldOptimizeForSize(Function *F, ProfileSummaryInfo *PSI,
bool shouldOptimizeForSize(const Function *F, ProfileSummaryInfo *PSI,
BlockFrequencyInfo *BFI);

/// Returns true if basic block \p BB is suggested to be size-optimized base
/// on the profile.
bool shouldOptimizeForSize(BasicBlock *BB, ProfileSummaryInfo *PSI,
bool shouldOptimizeForSize(const BasicBlock *BB, ProfileSummaryInfo *PSI,
BlockFrequencyInfo *BFI);

} // end namespace llvm
Expand Down
1 change: 1 addition & 0 deletions lib/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ add_llvm_library(LLVMCodeGen
MachineRegisterInfo.cpp
MachineScheduler.cpp
MachineSink.cpp
MachineSizeOpts.cpp
MachineSSAUpdater.cpp
MachineTraceMetrics.cpp
MachineVerifier.cpp
Expand Down
7 changes: 7 additions & 0 deletions lib/CodeGen/MachineBlockFrequencyInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ MachineBlockFrequencyInfo::MachineBlockFrequencyInfo()
initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
}

MachineBlockFrequencyInfo::MachineBlockFrequencyInfo(
MachineFunction &F,
MachineBranchProbabilityInfo &MBPI,
MachineLoopInfo &MLI) : MachineFunctionPass(ID) {
calculate(F, MBPI, MLI);
}

MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() = default;

void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
Expand Down
6 changes: 5 additions & 1 deletion lib/CodeGen/MachineDominators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,15 @@ void MachineDominatorTree::getAnalysisUsage(AnalysisUsage &AU) const {
}

bool MachineDominatorTree::runOnMachineFunction(MachineFunction &F) {
calculate(F);
return false;
}

void MachineDominatorTree::calculate(MachineFunction &F) {
CriticalEdgesToSplit.clear();
NewBBs.clear();
DT.reset(new DomTreeBase<MachineBasicBlock>());
DT->recalculate(F);
return false;
}

MachineDominatorTree::MachineDominatorTree()
Expand Down
8 changes: 6 additions & 2 deletions lib/CodeGen/MachineLoopInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ INITIALIZE_PASS_END(MachineLoopInfo, "machine-loops",
char &llvm::MachineLoopInfoID = MachineLoopInfo::ID;

bool MachineLoopInfo::runOnMachineFunction(MachineFunction &) {
releaseMemory();
LI.analyze(getAnalysis<MachineDominatorTree>().getBase());
calculate(getAnalysis<MachineDominatorTree>());
return false;
}

void MachineLoopInfo::calculate(MachineDominatorTree &MDT) {
releaseMemory();
LI.analyze(MDT.getBase());
}

void MachineLoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineDominatorTree>();
Expand Down
120 changes: 120 additions & 0 deletions lib/CodeGen/MachineSizeOpts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
//===- MachineSizeOpts.cpp - code size optimization related code ----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains some shared machine IR code size optimization related
// code.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineSizeOpts.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"

using namespace llvm;

extern cl::opt<bool> EnablePGSO;
extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
extern cl::opt<bool> ForcePGSO;
extern cl::opt<int> PgsoCutoffInstrProf;
extern cl::opt<int> PgsoCutoffSampleProf;

namespace machine_size_opts_detail {

/// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock.
bool isColdBlock(const MachineBasicBlock *MBB,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo *MBFI) {
auto Count = MBFI->getBlockProfileCount(MBB);
return Count && PSI->isColdCount(*Count);
}

/// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock.
static bool isHotBlockNthPercentile(int PercentileCutoff,
const MachineBasicBlock *MBB,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo *MBFI) {
auto Count = MBFI->getBlockProfileCount(MBB);
return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
}

/// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for
/// MachineFunction.
bool isFunctionColdInCallGraph(
const MachineFunction *MF,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo &MBFI) {
if (auto FunctionCount = MF->getFunction().getEntryCount())
if (!PSI->isColdCount(FunctionCount.getCount()))
return false;
for (const auto &MBB : *MF)
if (!isColdBlock(&MBB, PSI, &MBFI))
return false;
return true;
}

/// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for
/// MachineFunction.
bool isFunctionHotInCallGraphNthPercentile(
int PercentileCutoff,
const MachineFunction *MF,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo &MBFI) {
if (auto FunctionCount = MF->getFunction().getEntryCount())
if (PSI->isHotCountNthPercentile(PercentileCutoff,
FunctionCount.getCount()))
return true;
for (const auto &MBB : *MF)
if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
return true;
return false;
}
} // namespace machine_size_opts_detail

namespace {
struct MachineBasicBlockBFIAdapter {
static bool isFunctionColdInCallGraph(const MachineFunction *MF,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo &MBFI) {
return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI);
}
static bool isFunctionHotInCallGraphNthPercentile(
int CutOff,
const MachineFunction *MF,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo &MBFI) {
return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile(
CutOff, MF, PSI, MBFI);
}
static bool isColdBlock(const MachineBasicBlock *MBB,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo *MBFI) {
return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI);
}
static bool isHotBlockNthPercentile(int CutOff,
const MachineBasicBlock *MBB,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo *MBFI) {
return machine_size_opts_detail::isHotBlockNthPercentile(
CutOff, MBB, PSI, MBFI);
}
};
} // end anonymous namespace

bool llvm::shouldOptimizeForSize(const MachineFunction *MF,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo *MBFI) {
return shouldFuncOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
MF, PSI, MBFI);
}

bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo *MBFI) {
return shouldOptimizeForSizeImpl<MachineBasicBlockBFIAdapter>(
MBB, PSI, MBFI);
}
Loading

0 comments on commit 1794a21

Please sign in to comment.