1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This pass is responsible for finalizing the functions frame layout, saving 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// callee saved registers, and for emitting prolog & epilog code for the 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// function. 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This pass must be run after register allocation. After this pass is 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// executed, it is illegal to construct MO_FrameIndex operands. 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This pass provides an optional shrink wrapping variant of prolog/epilog 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// insertion, enabled via --shrink-wrap. See ShrinkWrapping.cpp. 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define DEBUG_TYPE "pei" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "PrologEpilogInserter.h" 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/InlineAsm.h" 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineDominators.h" 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineLoopInfo.h" 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineInstr.h" 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFrameInfo.h" 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineRegisterInfo.h" 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/RegisterScavenging.h" 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetMachine.h" 3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetOptions.h" 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetRegisterInfo.h" 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetFrameLowering.h" 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetInstrInfo.h" 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/CommandLine.h" 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Compiler.h" 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Debug.h" 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/IndexedMap.h" 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/SmallSet.h" 4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Statistic.h" 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/STLExtras.h" 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <climits> 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanchar PEI::ID = 0; 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_BEGIN(PEI, "prologepilog", 5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Prologue/Epilogue Insertion", false, false) 5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) 5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_END(PEI, "prologepilog", 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Prologue/Epilogue Insertion", false, false) 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumVirtualFrameRegs, "Number of virtual frame regs encountered"); 5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumScavengedRegs, "Number of frame index regs scavenged"); 5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumBytesStackSpace, 5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Number of bytes used for stack in all functions"); 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// createPrologEpilogCodeInserter - This function returns a pass that inserts 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// prolog and epilog code, and eliminates abstract frame references. 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanFunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// runOnMachineFunction - Insert prolog/epilog code and replace abstract 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// frame indexes with appropriate references. 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool PEI::runOnMachineFunction(MachineFunction &Fn) { 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Function* F = Fn.getFunction(); 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn); 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Calculate the MaxCallFrameSize and AdjustsStack variables for the 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // function's frame information. Also eliminates call frame pseudo 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // instructions. 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman calculateCallsInformation(Fn); 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Allow the target machine to make some adjustments to the function 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TFI->processFunctionBeforeCalleeSavedScan(Fn, RS); 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Scan the function for modified callee saved registers and insert spill code 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // for any callee saved registers that are modified. 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman calculateCalleeSavedRegisters(Fn); 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Determine placement of CSR spill/restore code: 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // - With shrink wrapping, place spills and restores to tightly 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // enclose regions in the Machine CFG of the function where 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // they are used. 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // - Without shink wrapping (default), place all spills in the 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // entry block, all restores in return blocks. 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman placeCSRSpillsAndRestores(Fn); 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add the code to save and restore the callee saved registers 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!F->hasFnAttr(Attribute::Naked)) 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insertCSRSpillsAndRestores(Fn); 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Allow the target machine to make final modifications to the function 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // before the frame layout is finalized. 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TFI->processFunctionBeforeFrameFinalized(Fn); 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Calculate actual frame offsets for all abstract stack objects... 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman calculateFrameObjectOffsets(Fn); 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add prolog and epilog code to the function. This function is required 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to align the stack frame as necessary for any stack variables or 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // called functions. Because of this, calculateCalleeSavedRegisters() 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // must be called before this function in order to set the AdjustsStack 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // and MaxCallFrameSize variables. 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!F->hasFnAttr(Attribute::Naked)) 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insertPrologEpilogCode(Fn); 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Replace all MO_FrameIndex operands with physical register references 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // and actual offsets. 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman replaceFrameIndices(Fn); 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If register scavenging is needed, as we've enabled doing it as a 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // post-pass, scavenge the virtual registers that frame index elimiation 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // inserted. 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging) 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman scavengeFrameVirtualRegs(Fn); 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete RS; 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clearAllSets(); 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if 0 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid PEI::getAnalysisUsage(AnalysisUsage &AU) const { 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AU.setPreservesCFG(); 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ShrinkWrapping || ShrinkWrapFunc != "") { 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AU.addRequired<MachineLoopInfo>(); 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AU.addRequired<MachineDominatorTree>(); 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AU.addPreserved<MachineLoopInfo>(); 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AU.addPreserved<MachineDominatorTree>(); 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFunctionPass::getAnalysisUsage(AU); 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// calculateCallsInformation - Calculate the MaxCallFrameSize and AdjustsStack 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// variables for the function's frame information and eliminate call frame 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// pseudo instructions. 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid PEI::calculateCallsInformation(MachineFunction &Fn) { 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFrameInfo *MFI = Fn.getFrameInfo(); 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned MaxCallFrameSize = 0; 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool AdjustsStack = MFI->adjustsStack(); 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the function call frame set-up and tear-down instruction opcode 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FrameSetupOpcode = TII.getCallFrameSetupOpcode(); 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Early exit for targets which have no call frame setup/destroy pseudo 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // instructions. 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FrameSetupOpcode == -1 && FrameDestroyOpcode == -1) 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<MachineBasicBlock::iterator> FrameSDOps; 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I->getOpcode() == FrameSetupOpcode || 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I->getOpcode() == FrameDestroyOpcode) { 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo" 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman " instructions should have a single immediate argument!"); 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Size = I->getOperand(0).getImm(); 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AdjustsStack = true; 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameSDOps.push_back(I); 17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (I->isInlineAsm()) { 17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Some inline asm's need a stack frame, as indicated by operand 1. 18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ExtraInfo = I->getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AdjustsStack = true; 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MFI->setAdjustsStack(AdjustsStack); 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MFI->setMaxCallFrameSize(MaxCallFrameSize); 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (std::vector<MachineBasicBlock::iterator>::iterator 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) { 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I = *i; 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If call frames are not being included as part of the stack frame, and 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the target doesn't indicate otherwise, remove the call frame pseudos 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // here. The sub/add sp instruction pairs are still inserted, but we don't 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // need to track the SP adjustment for frame index elimination. 19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TFI->canSimplifyCallFramePseudos(Fn)) 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I); 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// calculateCalleeSavedRegisters - Scan the function for modified callee saved 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// registers. 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFrameInfo *MFI = Fn.getFrameInfo(); 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the callee saved register list... 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(&Fn); 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // These are used to keep track the callee-save area. Initialize them. 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MinCSFrameIndex = INT_MAX; 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MaxCSFrameIndex = 0; 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Early exit for targets which have no callee saved registers. 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CSRegs == 0 || CSRegs[0] == 0) 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // In Naked functions we aren't going to save any registers. 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Fn.getFunction()->hasFnAttr(Attribute::Naked)) 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<CalleeSavedInfo> CSI; 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; CSRegs[i]; ++i) { 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg = CSRegs[i]; 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Fn.getRegInfo().isPhysRegUsed(Reg)) { 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the reg is modified, save it! 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CSI.push_back(CalleeSavedInfo(Reg)); 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman *AliasSet; ++AliasSet) { // Check alias registers too. 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Fn.getRegInfo().isPhysRegUsed(*AliasSet)) { 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CSI.push_back(CalleeSavedInfo(Reg)); 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CSI.empty()) 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; // Early exit if no callee saved registers are modified! 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumFixedSpillSlots; 24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering::SpillSlot *FixedSpillSlots = 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots); 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Now that we know which registers need to be saved and restored, allocate 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // stack slots for them. 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (std::vector<CalleeSavedInfo>::iterator 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = CSI.begin(), E = CSI.end(); I != E; ++I) { 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg = I->getReg(); 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg); 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FrameIdx; 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RegInfo->hasReservedSpillSlot(Fn, Reg, FrameIdx)) { 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I->setFrameIdx(FrameIdx); 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Check to see if this physreg must be spilled to a particular stack slot 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // on this target. 26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering::SpillSlot *FixedSlot = FixedSpillSlots; 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (FixedSlot != FixedSpillSlots+NumFixedSpillSlots && 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FixedSlot->Reg != Reg) 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++FixedSlot; 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) { 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Nope, just spill it anywhere convenient. 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Align = RC->getAlignment(); 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned StackAlign = TFI->getStackAlignment(); 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We may not be able to satisfy the desired alignment specification of 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the TargetRegisterClass if the stack alignment is smaller. Use the 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // min. 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Align = std::min(Align, StackAlign); 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIdx = MFI->CreateStackObject(RC->getSize(), Align, true); 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx; 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Spill it to the stack where we must. 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIdx = MFI->CreateFixedObject(RC->getSize(), FixedSlot->Offset, true); 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I->setFrameIdx(FrameIdx); 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MFI->setCalleeSavedInfo(CSI); 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// insertCSRSpillsAndRestores - Insert spill and restore code for 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// callee saved registers used in the function, handling shrink wrapping. 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) { 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get callee saved register information. 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFrameInfo *MFI = Fn.getFrameInfo(); 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MFI->setCalleeSavedInfoValid(true); 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Early exit if no callee saved registers are modified! 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CSI.empty()) 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering(); 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I; 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (! ShrinkWrapThisFunction) { 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Spill using target interface. 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = EntryBlock->begin(); 31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!TFI->spillCalleeSavedRegisters(*EntryBlock, I, CSI, TRI)) { 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add the callee-saved register as live-in. 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // It's killed at the spill. 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EntryBlock->addLiveIn(CSI[i].getReg()); 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Insert the spill to the stack frame. 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg = CSI[i].getReg(); 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TII.storeRegToStackSlot(*EntryBlock, I, Reg, true, 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CSI[i].getFrameIdx(), RC, TRI); 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Restore using target interface. 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) { 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock* MBB = ReturnBlocks[ri]; 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = MBB->end(); --I; 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Skip over all terminator instructions, which are part of the return 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // sequence. 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I2 = I; 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = I2; 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool AtStart = I == MBB->begin(); 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator BeforeI = I; 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!AtStart) 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --BeforeI; 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Restore all registers immediately before the return and any 34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // terminators that precede it. 34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!TFI->restoreCalleeSavedRegisters(*MBB, I, CSI, TRI)) { 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg = CSI[i].getReg(); 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TII.loadRegFromStackSlot(*MBB, I, Reg, 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CSI[i].getFrameIdx(), 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RC, TRI); 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(I != MBB->begin() && 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "loadRegFromStackSlot didn't insert any code!"); 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Insert in reverse order. loadRegFromStackSlot can insert 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // multiple instructions. 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (AtStart) 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = MBB->begin(); 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else { 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = BeforeI; 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++I; 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Insert spills. 369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<CalleeSavedInfo> blockCSI; 370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (CSRegBlockMap::iterator BI = CSRSave.begin(), 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BE = CSRSave.end(); BI != BE; ++BI) { 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock* MBB = BI->first; 373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CSRegSet save = BI->second; 374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (save.empty()) 376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman blockCSI.clear(); 379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (CSRegSet::iterator RI = save.begin(), 380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RE = save.end(); RI != RE; ++RI) { 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman blockCSI.push_back(CSI[*RI]); 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(blockCSI.size() > 0 && 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Could not collect callee saved register info"); 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = MBB->begin(); 387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // When shrink wrapping, use stack slot stores/loads. 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add the callee-saved register as live-in. 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // It's killed at the spill. 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MBB->addLiveIn(blockCSI[i].getReg()); 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Insert the spill to the stack frame. 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg = blockCSI[i].getReg(); 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TII.storeRegToStackSlot(*MBB, I, Reg, 398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman true, 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman blockCSI[i].getFrameIdx(), 400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RC, TRI); 401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (CSRegBlockMap::iterator BI = CSRRestore.begin(), 405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BE = CSRRestore.end(); BI != BE; ++BI) { 406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock* MBB = BI->first; 407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CSRegSet restore = BI->second; 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (restore.empty()) 410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman blockCSI.clear(); 413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (CSRegSet::iterator RI = restore.begin(), 414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RE = restore.end(); RI != RE; ++RI) { 415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman blockCSI.push_back(CSI[*RI]); 416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(blockCSI.size() > 0 && 418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Could not find callee saved register info"); 419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If MBB is empty and needs restores, insert at the _beginning_. 421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MBB->empty()) { 422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = MBB->begin(); 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = MBB->end(); 425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --I; 426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Skip over all terminator instructions, which are part of the 428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // return sequence. 429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (! I->getDesc().isTerminator()) { 430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++I; 431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I2 = I; 433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) 434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = I2; 435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool AtStart = I == MBB->begin(); 439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator BeforeI = I; 440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!AtStart) 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --BeforeI; 442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Restore all registers immediately before the return and any 44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // terminators that precede it. 445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { 446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg = blockCSI[i].getReg(); 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TII.loadRegFromStackSlot(*MBB, I, Reg, 449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman blockCSI[i].getFrameIdx(), 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RC, TRI); 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(I != MBB->begin() && 452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "loadRegFromStackSlot didn't insert any code!"); 453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Insert in reverse order. loadRegFromStackSlot can insert 454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // multiple instructions. 455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (AtStart) 456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = MBB->begin(); 457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else { 458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = BeforeI; 459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++I; 460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic inline void 467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanAdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, 468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool StackGrowsDown, int64_t &Offset, 469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned &MaxAlign) { 470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the stack grows down, add the object size to find the lowest address. 471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (StackGrowsDown) 472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset += MFI->getObjectSize(FrameIdx); 473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Align = MFI->getObjectAlignment(FrameIdx); 475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the alignment of this object is greater than that of the stack, then 477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // increase the stack alignment to match. 478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MaxAlign = std::max(MaxAlign, Align); 479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Adjust to alignment boundary. 481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset = (Offset + Align - 1) / Align * Align; 482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (StackGrowsDown) { 48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n"); 485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset 486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n"); 488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MFI->setObjectOffset(FrameIdx, Offset); 489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset += MFI->getObjectSize(FrameIdx); 490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// abstract stack objects. 495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool StackGrowsDown = 50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Loop over all of the stack objects, assigning sequential addresses... 503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineFrameInfo *MFI = Fn.getFrameInfo(); 504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Start at the beginning of the local area. 506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The Offset is the distance from the stack top in the direction 507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // of stack growth -- so it's always nonnegative. 508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int LocalAreaOffset = TFI.getOffsetOfLocalArea(); 509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (StackGrowsDown) 510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LocalAreaOffset = -LocalAreaOffset; 511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LocalAreaOffset >= 0 512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && "Local area offset should be in direction of stack growth"); 513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int64_t Offset = LocalAreaOffset; 514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If there are fixed sized objects that are preallocated in the local area, 516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // non-fixed objects can't be allocated right at the start of local area. 517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We currently don't support filling in holes in between fixed sized 518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // objects, so we adjust 'Offset' to point to the end of last fixed sized 519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // preallocated object. 520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) { 521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int64_t FixedOff; 522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (StackGrowsDown) { 523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The maximum distance from the stack pointer is at lower address of 524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the object -- which is given by offset. For down growing stack 525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the offset is negative, so we negate the offset to get the distance. 526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FixedOff = -MFI->getObjectOffset(i); 527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The maximum distance from the start pointer is at the upper 529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // address of the object. 530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i); 531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FixedOff > Offset) Offset = FixedOff; 533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // First assign frame offsets to stack objects that are used to spill 536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // callee saved registers. 537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (StackGrowsDown) { 538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) { 539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the stack grows down, we need to add the size to find the lowest 540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // address of the object. 541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset += MFI->getObjectSize(i); 542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Align = MFI->getObjectAlignment(i); 544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Adjust to alignment boundary 545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset = (Offset+Align-1)/Align*Align; 546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MFI->setObjectOffset(i, -Offset); // Set the computed offset 548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex; 551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = MaxCSFI; i >= MinCSFI ; --i) { 552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Align = MFI->getObjectAlignment(i); 553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Adjust to alignment boundary 554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset = (Offset+Align-1)/Align*Align; 555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MFI->setObjectOffset(i, Offset); 557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset += MFI->getObjectSize(i); 558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned MaxAlign = MFI->getMaxAlignment(); 562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make sure the special register scavenging spill slot is closest to the 564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // frame pointer if a frame pointer is required. 565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RS && TFI.hasFP(Fn) && RegInfo->useFPForScavengingIndex(Fn) && 56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !RegInfo->needsStackRealignment(Fn)) { 568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int SFI = RS->getScavengingFrameIndex(); 569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SFI >= 0) 570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign); 571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: Once this is working, then enable flag will change to a target 57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // check for whether the frame is large enough to want to use virtual 57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // frame index registers. Functions which don't want/need this optimization 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // will continue to use the existing code path. 57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MFI->getUseLocalStackAllocationBlock()) { 57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Align = MFI->getLocalFrameMaxAlign(); 57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Adjust to alignment boundary. 58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset = (Offset + Align - 1) / Align * Align; 58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n"); 58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Resolve offsets for objects in the local block. 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) { 58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i); 58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second; 58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" << 59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FIOffset << "]\n"); 59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MFI->setObjectOffset(Entry.first, FIOffset); 59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Allocate the local block 59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset += MFI->getLocalFrameSize(); 59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MaxAlign = std::max(Align, MaxAlign); 59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make sure that the stack protector comes before the local variables on the 600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // stack. 601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallSet<int, 16> LargeStackObjs; 602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MFI->getStackProtectorIndex() >= 0) { 603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown, 604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset, MaxAlign); 605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Assign large stack objects first. 607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MFI->isObjectPreAllocated(i) && 60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MFI->getUseLocalStackAllocationBlock()) 61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RS && (int)i == RS->getScavengingFrameIndex()) 614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MFI->isDeadObjectIndex(i)) 616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MFI->getStackProtectorIndex() == (int)i) 618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!MFI->MayNeedStackProtector(i)) 620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign); 623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LargeStackObjs.insert(i); 624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Then assign frame offsets to stack objects that are not used to spill 628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // callee saved registers. 629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MFI->isObjectPreAllocated(i) && 63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MFI->getUseLocalStackAllocationBlock()) 63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) 634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RS && (int)i == RS->getScavengingFrameIndex()) 636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MFI->isDeadObjectIndex(i)) 638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MFI->getStackProtectorIndex() == (int)i) 640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (LargeStackObjs.count(i)) 642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign); 645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make sure the special register scavenging spill slot is closest to the 648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // stack pointer. 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RS && (!TFI.hasFP(Fn) || RegInfo->needsStackRealignment(Fn) || 65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman !RegInfo->useFPForScavengingIndex(Fn))) { 651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int SFI = RS->getScavengingFrameIndex(); 652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SFI >= 0) 653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign); 654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!TFI.targetHandlesStackFrameRounding()) { 657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have reserved argument space for call sites in the function 658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // immediately on entry to the current function, count it as part of the 659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // overall stack size. 66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn)) 661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset += MFI->getMaxCallFrameSize(); 662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Round up the size to a multiple of the alignment. If the function has 664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // any calls or alloca's, align to the target's StackAlignment value to 665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ensure that the callee's frame or the alloca data is suitably aligned; 666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // otherwise, for leaf functions, align to the TransientStackAlignment 667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // value. 668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned StackAlign; 669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MFI->adjustsStack() || MFI->hasVarSizedObjects() || 670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0)) 671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StackAlign = TFI.getStackAlignment(); 672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StackAlign = TFI.getTransientStackAlignment(); 674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the frame pointer is eliminated, all frame offsets will be relative to 676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SP not FP. Align to MaxAlign so this works. 677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StackAlign = std::max(StackAlign, MaxAlign); 678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned AlignMask = StackAlign - 1; 679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Update frame info to pretend that this is part of the stack... 68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t StackSize = Offset - LocalAreaOffset; 68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MFI->setStackSize(StackSize); 68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NumBytesStackSpace += StackSize; 686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// insertPrologEpilogCode - Scan the function for modified callee saved 689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// registers, insert spill code for these callee saved registers, then add 690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// prolog and epilog code to the function. 691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid PEI::insertPrologEpilogCode(MachineFunction &Fn) { 69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add prologue to the function... 69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TFI.emitPrologue(Fn); 697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add epilogue to restore the callee-save registers in each exiting block 699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { 700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If last instruction is a return instruction, add an epilogue 701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!I->empty() && I->back().getDesc().isReturn()) 70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TFI.emitEpilogue(Fn, *I); 703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Emit additional code that is required to support segmented stacks, if 70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // we've been asked for it. This, when linked with a runtime with support 70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // for segmented stacks (libgcc is one), will result in allocating stack 70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // space in small chunks instead of one large contiguous block. 70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (EnableSegmentedStacks) 71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TFI.adjustForSegmentedStacks(Fn); 711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical 714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// register references and actual offsets. 715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid PEI::replaceFrameIndices(MachineFunction &Fn) { 717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Fn.getFrameInfo()->hasStackObjects()) return; // Nothing to do? 718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetMachine &TM = Fn.getTarget(); 720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); 72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterInfo &TRI = *TM.getRegisterInfo(); 72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetFrameLowering *TFI = TM.getFrameLowering(); 724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool StackGrowsDown = 72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TFI->getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FrameSetupOpcode = TII.getCallFrameSetupOpcode(); 72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); 728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (MachineFunction::iterator BB = Fn.begin(), 730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman E = Fn.end(); BB != E; ++BB) { 731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG 732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int SPAdjCount = 0; // frame setup / destroy count. 733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int SPAdj = 0; // SP offset due to call frame setup / destroy. 735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB); 736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I->getOpcode() == FrameSetupOpcode || 740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I->getOpcode() == FrameDestroyOpcode) { 741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG 742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Track whether we see even pairs of them 743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPAdjCount += I->getOpcode() == FrameSetupOpcode ? 1 : -1; 744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Remember how much SP has been adjusted to create the call 746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // frame. 747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int Size = I->getOperand(0).getImm(); 748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) || 750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode)) 751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Size = -Size; 752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SPAdj += Size; 754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator PrevI = BB->end(); 756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I != BB->begin()) PrevI = prior(I); 757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TRI.eliminateCallFramePseudoInstr(Fn, *BB, I); 758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Visit the instructions created by eliminateCallFramePseudoInstr(). 760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (PrevI == BB->end()) 761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = BB->begin(); // The replaced instr was the first in the block. 762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = llvm::next(PrevI); 764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineInstr *MI = I; 768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool DoIncr = true; 769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) 770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MI->getOperand(i).isFI()) { 771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Some instructions (e.g. inline asm instructions) can have 772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // multiple frame indices and/or cause eliminateFrameIndex 773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to insert more than one instruction. We need the register 774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // scavenger to go through all of these instructions so that 775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // it can update its register information. We keep the 776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // iterator at the point before insertion so that we can 777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // revisit them in full. 778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool AtBeginning = (I == BB->begin()); 779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!AtBeginning) --I; 780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this instruction has a FrameIndex operand, we need to 782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // use that target machine register info object to eliminate 783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // it. 78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TRI.eliminateFrameIndex(MI, SPAdj, 78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FrameIndexVirtualScavenging ? NULL : RS); 786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Reset the iterator if we were at the beginning of the BB. 788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (AtBeginning) { 789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = BB->begin(); 790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DoIncr = false; 791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MI = 0; 794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DoIncr && I != BB->end()) ++I; 798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Update register states. 800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RS && !FrameIndexVirtualScavenging && MI) RS->forward(MI); 801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have evenly matched pairs of frame setup / destroy instructions, 804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // make sure the adjustments come out to zero. If we don't have matched 805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // pairs, we can't be sure the missing bit isn't in another basic block 806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // due to a custom inserter playing tricks, so just asserting SPAdj==0 807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // isn't sufficient. See tMOVCC on Thumb1, for example. 808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert((SPAdjCount || SPAdj == 0) && 809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Unbalanced call frame setup / destroy pairs?"); 810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// scavengeFrameVirtualRegs - Replace all frame index virtual registers 814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// with physical registers. Use the register scavenger to find an 815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// appropriate register to use. 816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { 817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Run through the instructions and find any virtual registers. 818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (MachineFunction::iterator BB = Fn.begin(), 819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman E = Fn.end(); BB != E; ++BB) { 820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RS->enterBasicBlock(BB); 821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned VirtReg = 0; 82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ScratchReg = 0; 824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int SPAdj = 0; 825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The instruction stream may change in the loop, so check BB->end() 827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // directly. 828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { 829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineInstr *MI = I; 830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MI->getOperand(i).isReg()) { 832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineOperand &MO = MI->getOperand(i); 833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Reg = MO.getReg(); 834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Reg == 0) 835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!TargetRegisterInfo::isVirtualRegister(Reg)) 837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++NumVirtualFrameRegs; 840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Have we already allocated a scratch register for this virtual? 84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Reg != VirtReg) { 843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // When we first encounter a new virtual register, it 844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // must be a definition. 845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(MI->getOperand(i).isDef() && 846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "frame index virtual missing def!"); 847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Scavenge a new scratch register 84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VirtReg = Reg; 849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg); 85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ScratchReg = RS->scavengeRegister(RC, I, SPAdj); 85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++NumScavengedRegs; 852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Replace this reference to the virtual register with the 854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // scratch register. 85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert (ScratchReg && "Missing scratch register!"); 85619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MI->getOperand(i).setReg(ScratchReg); 857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 86019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RS->forward(I); 86119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++I; 862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 865