/// Implements shrink-wrapping of the stack frame. By default, stack frame /// is created in the function entry block, and is cleaned up in every block /// that returns. This function finds alternate blocks: one for the frame /// setup (prolog) and one for the cleanup (epilog). void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF, MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB) const { static unsigned ShrinkCounter = 0; if (ShrinkLimit.getPosition()) { if (ShrinkCounter >= ShrinkLimit) return; ShrinkCounter++; } auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget()); auto &HRI = *HST.getRegisterInfo(); MachineDominatorTree MDT; MDT.runOnMachineFunction(MF); MachinePostDominatorTree MPT; MPT.runOnMachineFunction(MF); typedef DenseMap<unsigned,unsigned> UnsignedMap; UnsignedMap RPO; typedef ReversePostOrderTraversal<const MachineFunction*> RPOTType; RPOTType RPOT(&MF); unsigned RPON = 0; for (RPOTType::rpo_iterator I = RPOT.begin(), E = RPOT.end(); I != E; ++I) RPO[(*I)->getNumber()] = RPON++; // Don't process functions that have loops, at least for now. Placement // of prolog and epilog must take loop structure into account. For simpli- // city don't do it right now. for (auto &I : MF) { unsigned BN = RPO[I.getNumber()]; for (auto SI = I.succ_begin(), SE = I.succ_end(); SI != SE; ++SI) { // If found a back-edge, return. if (RPO[(*SI)->getNumber()] <= BN) return; } } // Collect the set of blocks that need a stack frame to execute. Scan // each block for uses/defs of callee-saved registers, calls, etc. SmallVector<MachineBasicBlock*,16> SFBlocks; BitVector CSR(Hexagon::NUM_TARGET_REGS); for (const MCPhysReg *P = HRI.getCalleeSavedRegs(&MF); *P; ++P) CSR[*P] = true; for (auto &I : MF) if (needsStackFrame(I, CSR)) SFBlocks.push_back(&I); DEBUG({ dbgs() << "Blocks needing SF: {"; for (auto &B : SFBlocks) dbgs() << " BB#" << B->getNumber(); dbgs() << " }\n"; });