#include "bolt/Passes/ShrinkWrapping.h"
#include "bolt/Passes/DataflowInfoManager.h"
#include "bolt/Passes/MCF.h"
#include "bolt/Utils/CommandLineOpts.h"
#include <numeric>
#include <optional>
#include <stack>
#define DEBUG_TYPE …
usingnamespacellvm;
namespace opts {
extern cl::opt<bool> TimeOpts;
extern cl::OptionCategory BoltOptCategory;
static cl::opt<unsigned> ShrinkWrappingThreshold(
"shrink-wrapping-threshold",
cl::desc("Percentage of prologue execution count to use as threshold when"
" evaluating whether a block is cold enough to be profitable to"
" move eligible spills there"),
cl::init(30), cl::ZeroOrMore, cl::cat(BoltOptCategory));
}
namespace llvm {
namespace bolt {
void CalleeSavedAnalysis::analyzeSaves() { … }
void CalleeSavedAnalysis::analyzeRestores() { … }
std::vector<MCInst *> CalleeSavedAnalysis::getSavesByReg(uint16_t Reg) { … }
std::vector<MCInst *> CalleeSavedAnalysis::getRestoresByReg(uint16_t Reg) { … }
CalleeSavedAnalysis::~CalleeSavedAnalysis() { … }
void StackLayoutModifier::blacklistRegion(int64_t Offset, int64_t Size) { … }
bool StackLayoutModifier::isRegionBlacklisted(int64_t Offset, int64_t Size) { … }
bool StackLayoutModifier::blacklistAllInConflictWith(int64_t Offset,
int64_t Size) { … }
void StackLayoutModifier::checkFramePointerInitialization(MCInst &Point) { … }
void StackLayoutModifier::checkStackPointerRestore(MCInst &Point) { … }
void StackLayoutModifier::classifyStackAccesses() { … }
void StackLayoutModifier::classifyCFIs() { … }
void StackLayoutModifier::scheduleChange(
MCInst &Inst, StackLayoutModifier::WorklistItem Item) { … }
bool StackLayoutModifier::canCollapseRegion(MCInst *DeletedPush) { … }
bool StackLayoutModifier::canCollapseRegion(int64_t RegionAddr) { … }
bool StackLayoutModifier::collapseRegion(MCInst *DeletedPush) { … }
bool StackLayoutModifier::collapseRegion(MCInst *Alloc, int64_t RegionAddr,
int64_t RegionSz) { … }
void StackLayoutModifier::setOffsetForCollapsedAccesses(int64_t NewOffset) { … }
bool StackLayoutModifier::canInsertRegion(ProgramPoint P) { … }
bool StackLayoutModifier::insertRegion(ProgramPoint P, int64_t RegionSz) { … }
void StackLayoutModifier::performChanges() { … }
void StackLayoutModifier::initialize() { … }
std::atomic<std::uint64_t> ShrinkWrapping::SpillsMovedRegularMode{ … };
std::atomic<std::uint64_t> ShrinkWrapping::SpillsMovedPushPopMode{ … };
std::atomic<std::uint64_t> ShrinkWrapping::SpillsMovedDynamicCount{ … };
std::atomic<std::uint64_t> ShrinkWrapping::SpillsFailedDynamicCount{ … };
std::atomic<std::uint64_t> ShrinkWrapping::InstrDynamicCount{ … };
std::atomic<std::uint64_t> ShrinkWrapping::StoreDynamicCount{ … };
BBIterTy;
void ShrinkWrapping::classifyCSRUses() { … }
void ShrinkWrapping::pruneUnwantedCSRs() { … }
void ShrinkWrapping::computeSaveLocations() { … }
void ShrinkWrapping::computeDomOrder() { … }
bool ShrinkWrapping::isBestSavePosCold(unsigned CSR, MCInst *&BestPosSave,
uint64_t &TotalEstimatedWin) { … }
void ShrinkWrapping::splitFrontierCritEdges(
BinaryFunction *Func, SmallVector<ProgramPoint, 4> &Frontier,
const SmallVector<bool, 4> &IsCritEdge,
const SmallVector<BinaryBasicBlock *, 4> &From,
const SmallVector<SmallVector<BinaryBasicBlock *, 4>, 4> &To) { … }
SmallVector<ProgramPoint, 4>
ShrinkWrapping::doRestorePlacement(MCInst *BestPosSave, unsigned CSR,
uint64_t TotalEstimatedWin) { … }
bool ShrinkWrapping::validatePushPopsMode(unsigned CSR, MCInst *BestPosSave,
int64_t SaveOffset) { … }
SmallVector<ProgramPoint, 4> ShrinkWrapping::fixPopsPlacements(
const SmallVector<ProgramPoint, 4> &RestorePoints, int64_t SaveOffset,
unsigned CSR) { … }
void ShrinkWrapping::scheduleOldSaveRestoresRemoval(unsigned CSR,
bool UsePushPops) { … }
bool ShrinkWrapping::doesInstUsesCSR(const MCInst &Inst, uint16_t CSR) { … }
void ShrinkWrapping::scheduleSaveRestoreInsertions(
unsigned CSR, MCInst *BestPosSave,
SmallVector<ProgramPoint, 4> &RestorePoints, bool UsePushPops) { … }
void ShrinkWrapping::moveSaveRestores() { … }
namespace {
bool isIdenticalSplitEdgeBB(const BinaryContext &BC, const BinaryBasicBlock &A,
const BinaryBasicBlock &B) { … }
}
bool ShrinkWrapping::foldIdenticalSplitEdges() { … }
namespace {
class PredictiveStackPointerTracking
: public StackPointerTrackingBase<PredictiveStackPointerTracking> { … };
}
void ShrinkWrapping::insertUpdatedCFI(unsigned CSR, int SPValPush,
int SPValPop) { … }
void ShrinkWrapping::rebuildCFIForSP() { … }
Expected<MCInst> ShrinkWrapping::createStackAccess(int SPVal, int FPVal,
const FrameIndexEntry &FIE,
bool CreatePushOrPop) { … }
void ShrinkWrapping::updateCFIInstOffset(MCInst &Inst, int64_t NewOffset) { … }
BBIterTy ShrinkWrapping::insertCFIsForPushOrPop(BinaryBasicBlock &BB,
BBIterTy Pos, unsigned Reg,
bool isPush, int Sz,
int64_t NewOffset) { … }
Expected<BBIterTy> ShrinkWrapping::processInsertion(BBIterTy InsertionPoint,
BinaryBasicBlock *CurBB,
const WorklistItem &Item,
int64_t SPVal,
int64_t FPVal) { … }
Expected<BBIterTy> ShrinkWrapping::processInsertionsList(
BBIterTy InsertionPoint, BinaryBasicBlock *CurBB,
std::vector<WorklistItem> &TodoList, int64_t SPVal, int64_t FPVal) { … }
Expected<bool> ShrinkWrapping::processInsertions() { … }
void ShrinkWrapping::processDeletions() { … }
void ShrinkWrapping::rebuildCFI() { … }
Expected<bool> ShrinkWrapping::perform(bool HotOnly) { … }
void ShrinkWrapping::printStats(BinaryContext &BC) { … }
raw_ostream &operator<<(raw_ostream &OS,
const std::vector<ShrinkWrapping::WorklistItem> &Vec) { … }
raw_ostream &
operator<<(raw_ostream &OS,
const std::vector<StackLayoutModifier::WorklistItem> &Vec) { … }
bool operator==(const ShrinkWrapping::WorklistItem &A,
const ShrinkWrapping::WorklistItem &B) { … }
bool operator==(const StackLayoutModifier::WorklistItem &A,
const StackLayoutModifier::WorklistItem &B) { … }
}
}