#include "HexagonFrameLowering.h"
#include "HexagonBlockRanges.h"
#include "HexagonInstrInfo.h"
#include "HexagonMachineFunctionInfo.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <limits>
#include <map>
#include <optional>
#include <utility>
#include <vector>
#define DEBUG_TYPE …
usingnamespacellvm;
static cl::opt<bool> DisableDeallocRet("disable-hexagon-dealloc-ret",
cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target"));
static cl::opt<unsigned>
NumberScavengerSlots("number-scavenger-slots", cl::Hidden,
cl::desc("Set the number of scavenger slots"),
cl::init(2));
static cl::opt<int>
SpillFuncThreshold("spill-func-threshold", cl::Hidden,
cl::desc("Specify O2(not Os) spill func threshold"),
cl::init(6));
static cl::opt<int>
SpillFuncThresholdOs("spill-func-threshold-Os", cl::Hidden,
cl::desc("Specify Os spill func threshold"),
cl::init(1));
static cl::opt<bool> EnableStackOVFSanitizer(
"enable-stackovf-sanitizer", cl::Hidden,
cl::desc("Enable runtime checks for stack overflow."), cl::init(false));
static cl::opt<bool>
EnableShrinkWrapping("hexagon-shrink-frame", cl::init(true), cl::Hidden,
cl::desc("Enable stack frame shrink wrapping"));
static cl::opt<unsigned>
ShrinkLimit("shrink-frame-limit",
cl::init(std::numeric_limits<unsigned>::max()), cl::Hidden,
cl::desc("Max count of stack frame shrink-wraps"));
static cl::opt<bool>
EnableSaveRestoreLong("enable-save-restore-long", cl::Hidden,
cl::desc("Enable long calls for save-restore stubs."),
cl::init(false));
static cl::opt<bool> EliminateFramePointer("hexagon-fp-elim", cl::init(true),
cl::Hidden, cl::desc("Refrain from using FP whenever possible"));
static cl::opt<bool> OptimizeSpillSlots("hexagon-opt-spill", cl::Hidden,
cl::init(true), cl::desc("Optimize spill slots"));
#ifndef NDEBUG
static cl::opt<unsigned> SpillOptMax("spill-opt-max", cl::Hidden,
cl::init(std::numeric_limits<unsigned>::max()));
static unsigned SpillOptCount = 0;
#endif
namespace llvm {
void initializeHexagonCallFrameInformationPass(PassRegistry&);
FunctionPass *createHexagonCallFrameInformation();
}
namespace {
class HexagonCallFrameInformation : public MachineFunctionPass { … };
char HexagonCallFrameInformation::ID = …;
}
bool HexagonCallFrameInformation::runOnMachineFunction(MachineFunction &MF) { … }
INITIALIZE_PASS(…)
FunctionPass *llvm::createHexagonCallFrameInformation() { … }
static Register getMax32BitSubRegister(Register Reg,
const TargetRegisterInfo &TRI,
bool hireg = true) { … }
static Register getMaxCalleeSavedReg(ArrayRef<CalleeSavedInfo> CSI,
const TargetRegisterInfo &TRI) { … }
static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR,
const HexagonRegisterInfo &HRI) { … }
static bool hasTailCall(const MachineBasicBlock &MBB) { … }
static bool hasReturn(const MachineBasicBlock &MBB) { … }
static MachineInstr *getReturn(MachineBasicBlock &MBB) { … }
static bool isRestoreCall(unsigned Opc) { … }
static inline bool isOptNone(const MachineFunction &MF) { … }
static inline bool isOptSize(const MachineFunction &MF) { … }
static inline bool isMinSize(const MachineFunction &MF) { … }
void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF,
MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB) const { … }
void HexagonFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const { … }
bool HexagonFrameLowering::enableCalleeSaveSkip(
const MachineFunction &MF) const { … }
static bool enableAllocFrameElim(const MachineFunction &MF) { … }
void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB,
bool PrologueStubs) const { … }
void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const { … }
void HexagonFrameLowering::insertAllocframe(MachineBasicBlock &MBB,
MachineBasicBlock::iterator InsertPt, unsigned NumBytes) const { … }
void HexagonFrameLowering::updateEntryPaths(MachineFunction &MF,
MachineBasicBlock &SaveB) const { … }
bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &MBB,
MachineBasicBlock &RestoreB, BitVector &DoneT, BitVector &DoneF,
BitVector &Path) const { … }
static std::optional<MachineBasicBlock::iterator>
findCFILocation(MachineBasicBlock &B) { … }
void HexagonFrameLowering::insertCFIInstructions(MachineFunction &MF) const { … }
void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB,
MachineBasicBlock::iterator At) const { … }
bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const { … }
enum SpillKind { … };
static const char *getSpillFunctionFor(Register MaxReg, SpillKind SpillType,
bool Stkchk = false) { … }
StackOffset
HexagonFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
Register &FrameReg) const { … }
bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
const CSIVect &CSI, const HexagonRegisterInfo &HRI,
bool &PrologueStubs) const { … }
bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
const CSIVect &CSI, const HexagonRegisterInfo &HRI) const { … }
MachineBasicBlock::iterator HexagonFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const { … }
void HexagonFrameLowering::processFunctionBeforeFrameFinalized(
MachineFunction &MF, RegScavenger *RS) const { … }
static bool needToReserveScavengingSpillSlots(MachineFunction &MF,
const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC) { … }
#ifndef NDEBUG
static void dump_registers(BitVector &Regs, const TargetRegisterInfo &TRI) {
dbgs() << '{';
for (int x = Regs.find_first(); x >= 0; x = Regs.find_next(x)) {
Register R = x;
dbgs() << ' ' << printReg(R, &TRI);
}
dbgs() << " }";
}
#endif
bool HexagonFrameLowering::assignCalleeSavedSpillSlots(MachineFunction &MF,
const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) const { … }
bool HexagonFrameLowering::expandCopy(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const { … }
bool HexagonFrameLowering::expandStoreInt(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const { … }
bool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const { … }
bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const { … }
bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const { … }
bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const { … }
bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const { … }
bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const { … }
bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs) const { … }
bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF,
SmallVectorImpl<Register> &NewRegs) const { … }
void HexagonFrameLowering::determineCalleeSaves(MachineFunction &MF,
BitVector &SavedRegs,
RegScavenger *RS) const { … }
Register HexagonFrameLowering::findPhysReg(MachineFunction &MF,
HexagonBlockRanges::IndexRange &FIR,
HexagonBlockRanges::InstrIndexMap &IndexMap,
HexagonBlockRanges::RegToRangeMap &DeadMap,
const TargetRegisterClass *RC) const { … }
void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
SmallVectorImpl<Register> &VRegs) const { … }
void HexagonFrameLowering::expandAlloca(MachineInstr *AI,
const HexagonInstrInfo &HII, Register SP, unsigned CF) const { … }
bool HexagonFrameLowering::needsAligna(const MachineFunction &MF) const { … }
const MachineInstr *HexagonFrameLowering::getAlignaInstr(
const MachineFunction &MF) const { … }
void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(MachineInstr *MI,
const CSIVect &CSI, bool IsDef, bool IsKill) const { … }
bool HexagonFrameLowering::shouldInlineCSR(const MachineFunction &MF,
const CSIVect &CSI) const { … }
bool HexagonFrameLowering::useSpillFunction(const MachineFunction &MF,
const CSIVect &CSI) const { … }
bool HexagonFrameLowering::useRestoreFunction(const MachineFunction &MF,
const CSIVect &CSI) const { … }
bool HexagonFrameLowering::mayOverflowFrameOffset(MachineFunction &MF) const { … }
namespace {
struct HexagonFrameSortingObject { … };
struct HexagonFrameSortingComparator { … };
}
void HexagonFrameLowering::orderFrameObjects(
const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const { … }