<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Justin,<div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On May 23, 2016, at 1:25 PM, Justin Bogner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Derek Schuff via llvm-commits <</span><a href="mailto:llvm-commits@lists.llvm.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">llvm-commits@lists.llvm.org</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">> writes:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Author: dschuff<br class="">Date: Tue May 17 03:49:59 2016<br class="">New Revision: 269750<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=269750&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=269750&view=rev</a><br class="">Log:<br class="">Factor PrologEpilogInserter around spilling, frame finalization, and scavenging<br class=""><br class="">PrologEpilogInserter has these 3 phases, which are related, but not<br class="">all of them are needed by all targets. This patch reorganizes PEI's<br class="">varous functions around those phases for more clear separation. It also<br class="">introduces a new TargetMachine hook, usesPhysRegsForPEI, which is true<br class="">for non-virtual targets. When it is true, all the phases operate as<br class="">before, and PEI requires the AllVRegsAllocated property on<br class="">MachineFunctions. Otherwise, CSR spilling and scavenging are skipped and<br class="">only prolog/epilog insertion/frame finalization is done.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">A couple of comments below.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Differential Revision: <a href="http://reviews.llvm.org/D18366" class="">http://reviews.llvm.org/D18366</a><br class=""><br class="">Modified:<br class=""> llvm/trunk/include/llvm/CodeGen/Passes.h<br class=""> llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h<br class=""> llvm/trunk/include/llvm/Target/TargetMachine.h<br class=""> llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp<br class=""> llvm/trunk/lib/CodeGen/TargetPassConfig.cpp<br class=""> llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp<br class=""> llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h<br class=""><br class="">Modified: llvm/trunk/include/llvm/CodeGen/Passes.h<br class="">URL:<br class=""><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=269750&r1=269749&r2=269750&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=269750&r1=269749&r2=269750&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/CodeGen/Passes.h (original)<br class="">+++ llvm/trunk/include/llvm/CodeGen/Passes.h Tue May 17 03:49:59 2016<br class="">@@ -152,6 +152,7 @@ namespace llvm {<br class=""> /// PrologEpilogCodeInserter - This pass inserts prolog and epilog code,<br class=""> /// and eliminates abstract frame references.<br class=""> extern char &PrologEpilogCodeInserterID;<br class="">+ MachineFunctionPass *createPrologEpilogInserterPass(const TargetMachine *TM);<br class=""><br class=""> /// ExpandPostRAPseudos - This pass expands pseudo instructions after<br class=""> /// register allocation.<br class=""><br class="">Modified: llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h<br class="">URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h?rev=269750&r1=269749&r2=269750&view=diff<br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h (original)<br class="">+++ llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h Tue May 17 03:49:59 2016<br class="">@@ -178,6 +178,10 @@ public:<br class=""> /// If no substitution exists, return StandardID.<br class=""> IdentifyingPassPtr getPassSubstitution(AnalysisID StandardID) const;<br class=""><br class="">+ /// Return true if the pass has been substituted by the target or<br class="">+ /// overridden on the command line.<br class="">+ bool isPassSubstitutedOrOverridden(AnalysisID ID) const;<br class="">+<br class=""> /// Return true if the optimized regalloc pipeline is enabled.<br class=""> bool getOptimizeRegAlloc() const;<br class=""><br class=""><br class="">Modified: llvm/trunk/include/llvm/Target/TargetMachine.h<br class="">URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetMachine.h?rev=269750&r1=269749&r2=269750&view=diff<br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/Target/TargetMachine.h (original)<br class="">+++ llvm/trunk/include/llvm/Target/TargetMachine.h Tue May 17 03:49:59 2016<br class="">@@ -264,6 +264,12 @@ public:<br class=""> void getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV,<br class=""> Mangler &Mang, bool MayAlwaysUsePrivate = false) const;<br class=""> MCSymbol *getSymbol(const GlobalValue *GV, Mangler &Mang) const;<br class="">+<br class="">+ /// True if the target uses physical regs at Prolog/Epilog insertion<br class="">+ /// time. If true (most machines), all vregs must be allocated before<br class="">+ /// PEI. If false (virtual-register machines), then callee-save register<br class="">+ /// spilling and scavenging are not needed or used.<br class="">+ virtual bool usesPhysRegsForPEI() const { return true; }<br class="">};<br class=""><br class="">/// This class describes a target machine that is implemented with the LLVM<br class=""><br class="">Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp<br class="">URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=269750&r1=269749&r2=269750&view=diff<br class="">==============================================================================<br class="">--- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original)<br class="">+++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Tue May 17 03:49:59 2016<br class="">@@ -47,19 +47,41 @@ using namespace llvm;<br class=""><br class="">#define DEBUG_TYPE "pei"<br class=""><br class="">+typedef SmallVector<MachineBasicBlock *, 4> MBBVector;<br class="">+static void doSpillCalleeSavedRegs(MachineFunction &MF, RegScavenger *RS,<br class="">+ unsigned &MinCSFrameIndex,<br class="">+ unsigned &MaxCXFrameIndex,<br class="">+ const MBBVector &SaveBlocks,<br class="">+ const MBBVector &RestoreBlocks);<br class="">+<br class="">+static void doScavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger *RS);<br class="">+<br class="">namespace {<br class="">class PEI : public MachineFunctionPass {<br class="">public:<br class=""> static char ID;<br class="">- PEI() : MachineFunctionPass(ID) {<br class="">+ explicit PEI(const TargetMachine *TM = nullptr) : MachineFunctionPass(ID) {<br class=""> initializePEIPass(*PassRegistry::getPassRegistry());<br class="">+<br class="">+ if (TM && (!TM->usesPhysRegsForPEI())) {<br class="">+ SpillCalleeSavedRegisters = [](MachineFunction &, RegScavenger *,<br class="">+ unsigned &, unsigned &, const MBBVector &,<br class="">+ const MBBVector &) {};<br class="">+ ScavengeFrameVirtualRegs = [](MachineFunction &, RegScavenger *) {};<br class="">+ } else {<br class="">+ SpillCalleeSavedRegisters = doSpillCalleeSavedRegs;<br class="">+ ScavengeFrameVirtualRegs = doScavengeFrameVirtualRegs;<br class="">+ UsesCalleeSaves = true;<br class="">+ }<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">This is a pretty strange and confusing way to do this. Wouldn't it be</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">way simpler to just set a bool (I'd call it UsesPhysReg) and check it</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">before the single call to each of these functions? You'd presumably also</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">be able to use the same bool in the one place we check UsesCalleeSaves</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">as well.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div><div>A comment on that, because this situation is my doing :).</div><div><br class=""></div><div>The difference is performance and maintainability.</div><div>Performance: We check what to call only once (at build time) against every time we process a function.</div><div>Maintainability: All the code that is modified because of that check is in one place.</div><div><br class=""></div><div>Cheers,</div><div>-Quentin</div><br class=""><blockquote type="cite" class=""><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""> }<br class=""><br class=""> void getAnalysisUsage(AnalysisUsage &AU) const override;<br class=""><br class=""> MachineFunctionProperties getRequiredProperties() const override {<br class="">- return MachineFunctionProperties().set(<br class="">- MachineFunctionProperties::Property::AllVRegsAllocated);<br class="">+ MachineFunctionProperties MFP;<br class="">+ if (UsesCalleeSaves)<br class="">+ MFP.set(MachineFunctionProperties::Property::AllVRegsAllocated);<br class="">+ return MFP;<br class=""> }<br class=""><br class=""> /// runOnMachineFunction - Insert prolog/epilog code and replace abstract<br class="">@@ -68,32 +90,40 @@ public:<br class=""> bool runOnMachineFunction(MachineFunction &Fn) override;<br class=""><br class="">private:<br class="">+ std::function<void(MachineFunction &MF, RegScavenger *RS,<br class="">+ unsigned &MinCSFrameIndex, unsigned &MaxCSFrameIndex,<br class="">+ const MBBVector &SaveBlocks,<br class="">+ const MBBVector &RestoreBlocks)><br class="">+ SpillCalleeSavedRegisters;<br class="">+ std::function<void(MachineFunction &MF, RegScavenger *RS)><br class="">+ ScavengeFrameVirtualRegs;<br class="">+<br class="">+ bool UsesCalleeSaves = false;<br class="">+<br class=""> RegScavenger *RS;<br class=""><br class=""> // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved<br class=""> // stack frame indexes.<br class="">- unsigned MinCSFrameIndex, MaxCSFrameIndex;<br class="">+ unsigned MinCSFrameIndex = std::numeric_limits<unsigned>::max();<br class="">+ unsigned MaxCSFrameIndex = 0;<br class=""><br class=""> // Save and Restore blocks of the current function. Typically there is a<br class=""> // single save block, unless Windows EH funclets are involved.<br class="">- SmallVector<MachineBasicBlock *, 1> SaveBlocks;<br class="">- SmallVector<MachineBasicBlock *, 4> RestoreBlocks;<br class="">+ MBBVector SaveBlocks;<br class="">+ MBBVector RestoreBlocks;<br class=""><br class=""> // Flag to control whether to use the register scavenger to resolve<br class=""> // frame index materialization registers. Set according to<br class=""> // TRI->requiresFrameIndexScavenging() for the current function.<br class=""> bool FrameIndexVirtualScavenging;<br class=""><br class="">- void calculateSets(MachineFunction &Fn);<br class="">- void calculateCallsInformation(MachineFunction &Fn);<br class="">- void assignCalleeSavedSpillSlots(MachineFunction &Fn,<br class="">- const BitVector &SavedRegs);<br class="">- void insertCSRSpillsAndRestores(MachineFunction &Fn);<br class="">+ void calculateCallFrameInfo(MachineFunction &Fn);<br class="">+ void calculateSaveRestoreBlocks(MachineFunction &Fn);<br class="">+<br class=""> void calculateFrameObjectOffsets(MachineFunction &Fn);<br class=""> void replaceFrameIndices(MachineFunction &Fn);<br class=""> void replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &Fn,<br class=""> int &SPAdj);<br class="">- void scavengeFrameVirtualRegs(MachineFunction &Fn);<br class=""> void insertPrologEpilogCode(MachineFunction &Fn);<br class="">};<br class="">} // namespace<br class="">@@ -106,14 +136,19 @@ WarnStackSize("warn-stack-size", cl::Hid<br class=""> cl::desc("Warn for stack size bigger than the given"<br class=""> " number"));<br class=""><br class="">-INITIALIZE_PASS_BEGIN(PEI, "prologepilog",<br class="">- "Prologue/Epilogue Insertion", false, false)<br class="">+INITIALIZE_TM_PASS_BEGIN(PEI, "prologepilog", "Prologue/Epilogue Insertion",<br class="">+ false, false)<br class="">INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)<br class="">INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)<br class="">INITIALIZE_PASS_DEPENDENCY(StackProtector)<br class="">-INITIALIZE_PASS_END(PEI, "prologepilog",<br class="">- "Prologue/Epilogue Insertion & Frame Finalization",<br class="">- false, false)<br class="">+INITIALIZE_TM_PASS_END(PEI, "prologepilog",<br class="">+ "Prologue/Epilogue Insertion & Frame Finalization",<br class="">+ false, false)<br class="">+<br class="">+MachineFunctionPass *<br class="">+llvm::createPrologEpilogInserterPass(const TargetMachine *TM) {<br class="">+ return new PEI(TM);<br class="">+}<br class=""><br class="">STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");<br class="">STATISTIC(NumBytesStackSpace,<br class="">@@ -127,36 +162,6 @@ void PEI::getAnalysisUsage(AnalysisUsage<br class=""> MachineFunctionPass::getAnalysisUsage(AU);<br class="">}<br class=""><br class="">-/// Compute the set of return blocks<br class="">-void PEI::calculateSets(MachineFunction &Fn) {<br class="">- const MachineFrameInfo *MFI = Fn.getFrameInfo();<br class="">-<br class="">- // Even when we do not change any CSR, we still want to insert the<br class="">- // prologue and epilogue of the function.<br class="">- // So set the save points for those.<br class="">-<br class="">- // Use the points found by shrink-wrapping, if any.<br class="">- if (MFI->getSavePoint()) {<br class="">- SaveBlocks.push_back(MFI->getSavePoint());<br class="">- assert(MFI->getRestorePoint() && "Both restore and save must be set");<br class="">- MachineBasicBlock *RestoreBlock = MFI->getRestorePoint();<br class="">- // If RestoreBlock does not have any successor and is not a return block<br class="">- // then the end point is unreachable and we do not need to insert any<br class="">- // epilogue.<br class="">- if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())<br class="">- RestoreBlocks.push_back(RestoreBlock);<br class="">- return;<br class="">- }<br class="">-<br class="">- // Save refs to entry and return blocks.<br class="">- SaveBlocks.push_back(&Fn.front());<br class="">- for (MachineBasicBlock &MBB : Fn) {<br class="">- if (MBB.isEHFuncletEntry())<br class="">- SaveBlocks.push_back(&MBB);<br class="">- if (MBB.isReturnBlock())<br class="">- RestoreBlocks.push_back(&MBB);<br class="">- }<br class="">-}<br class=""><br class="">/// StackObjSet - A set of stack object indexes<br class="">typedef SmallSetVector<int, 8> StackObjSet;<br class="">@@ -169,30 +174,21 @@ bool PEI::runOnMachineFunction(MachineFu<br class=""> const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo();<br class=""> const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();<br class=""><br class="">- assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs");<br class="">-<br class=""> RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : nullptr;<br class=""> FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);<br class=""><br class=""> // Calculate the MaxCallFrameSize and AdjustsStack variables for the<br class=""> // function's frame information. Also eliminates call frame pseudo<br class=""> // instructions.<br class="">- calculateCallsInformation(Fn);<br class="">+ calculateCallFrameInfo(Fn);<br class=""><br class="">- // Determine which of the registers in the callee save list should be saved.<br class="">- BitVector SavedRegs;<br class="">- TFI->determineCalleeSaves(Fn, SavedRegs, RS);<br class="">-<br class="">- // Insert spill code for any callee saved registers that are modified.<br class="">- assignCalleeSavedSpillSlots(Fn, SavedRegs);<br class="">-<br class="">- // Determine placement of CSR spill/restore code:<br class="">+ // Determine placement of CSR spill/restore code and prolog/epilog code:<br class=""> // place all spills in the entry block, all restores in return blocks.<br class="">- calculateSets(Fn);<br class="">+ calculateSaveRestoreBlocks(Fn);<br class=""><br class="">- // Add the code to save and restore the callee saved registers.<br class="">- if (!F->hasFnAttribute(Attribute::Naked))<br class="">- insertCSRSpillsAndRestores(Fn);<br class="">+ // Handle CSR spilling and restoring, for targets that need it.<br class="">+ SpillCalleeSavedRegisters(Fn, RS, MinCSFrameIndex, MaxCSFrameIndex,<br class="">+ SaveBlocks, RestoreBlocks);<br class=""><br class=""> // Allow the target machine to make final modifications to the function<br class=""> // before the frame layout is finalized.<br class="">@@ -217,11 +213,12 @@ bool PEI::runOnMachineFunction(MachineFu<br class=""> // If register scavenging is needed, as we've enabled doing it as a<br class=""> // post-pass, scavenge the virtual registers that frame index elimination<br class=""> // inserted.<br class="">- if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging)<br class="">- scavengeFrameVirtualRegs(Fn);<br class="">+ if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging) {<br class="">+ ScavengeFrameVirtualRegs(Fn, RS);<br class=""><br class="">- // Clear any vregs created by virtual scavenging.<br class="">- Fn.getRegInfo().clearVirtRegs();<br class="">+ // Clear any vregs created by virtual scavenging.<br class="">+ Fn.getRegInfo().clearVirtRegs();<br class="">+ }<br class=""><br class=""> // Warn on stack size when we exceeds the given limit.<br class=""> MachineFrameInfo *MFI = Fn.getFrameInfo();<br class="">@@ -239,10 +236,10 @@ bool PEI::runOnMachineFunction(MachineFu<br class=""> return true;<br class="">}<br class=""><br class="">-/// calculateCallsInformation - Calculate the MaxCallFrameSize and AdjustsStack<br class="">+/// Calculate the MaxCallFrameSize and AdjustsStack<br class="">/// variables for the function's frame information and eliminate call frame<br class="">/// pseudo instructions.<br class="">-void PEI::calculateCallsInformation(MachineFunction &Fn) {<br class="">+void PEI::calculateCallFrameInfo(MachineFunction &Fn) {<br class=""> const TargetInstrInfo &TII = *Fn.getSubtarget().getInstrInfo();<br class=""> const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();<br class=""> MachineFrameInfo *MFI = Fn.getFrameInfo();<br class="">@@ -293,12 +290,42 @@ void PEI::calculateCallsInformation(Mach<br class=""> }<br class="">}<br class=""><br class="">-void PEI::assignCalleeSavedSpillSlots(MachineFunction &F,<br class="">- const BitVector &SavedRegs) {<br class="">- // These are used to keep track the callee-save area. Initialize them.<br class="">- MinCSFrameIndex = INT_MAX;<br class="">- MaxCSFrameIndex = 0;<br class="">+/// Compute the sets of entry and return blocks for saving and restoring<br class="">+/// callee-saved registers, and placing prolog and epilog code.<br class="">+void PEI::calculateSaveRestoreBlocks(MachineFunction &Fn) {<br class="">+ const MachineFrameInfo *MFI = Fn.getFrameInfo();<br class="">+<br class="">+ // Even when we do not change any CSR, we still want to insert the<br class="">+ // prologue and epilogue of the function.<br class="">+ // So set the save points for those.<br class="">+<br class="">+ // Use the points found by shrink-wrapping, if any.<br class="">+ if (MFI->getSavePoint()) {<br class="">+ SaveBlocks.push_back(MFI->getSavePoint());<br class="">+ assert(MFI->getRestorePoint() && "Both restore and save must be set");<br class="">+ MachineBasicBlock *RestoreBlock = MFI->getRestorePoint();<br class="">+ // If RestoreBlock does not have any successor and is not a return block<br class="">+ // then the end point is unreachable and we do not need to insert any<br class="">+ // epilogue.<br class="">+ if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())<br class="">+ RestoreBlocks.push_back(RestoreBlock);<br class="">+ return;<br class="">+ }<br class="">+<br class="">+ // Save refs to entry and return blocks.<br class="">+ SaveBlocks.push_back(&Fn.front());<br class="">+ for (MachineBasicBlock &MBB : Fn) {<br class="">+ if (MBB.isEHFuncletEntry())<br class="">+ SaveBlocks.push_back(&MBB);<br class="">+ if (MBB.isReturnBlock())<br class="">+ RestoreBlocks.push_back(&MBB);<br class="">+ }<br class="">+}<br class=""><br class="">+static void assignCalleeSavedSpillSlots(MachineFunction &F,<br class="">+ const BitVector &SavedRegs,<br class="">+ unsigned &MinCSFrameIndex,<br class="">+ unsigned &MaxCSFrameIndex) {<br class=""> if (SavedRegs.empty())<br class=""> return;<br class=""><br class="">@@ -429,7 +456,9 @@ static void updateLiveness(MachineFuncti<br class="">/// insertCSRSpillsAndRestores - Insert spill and restore code for<br class="">/// callee saved registers used in the function.<br class="">///<br class="">-void PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) {<br class="">+static void insertCSRSpillsAndRestores(MachineFunction &Fn,<br class="">+ const MBBVector &SaveBlocks,<br class="">+ const MBBVector &RestoreBlocks) {<br class=""> // Get callee saved register information.<br class=""> MachineFrameInfo *MFI = Fn.getFrameInfo();<br class=""> const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();<br class="">@@ -498,6 +527,28 @@ void PEI::insertCSRSpillsAndRestores(Mac<br class=""> }<br class="">}<br class=""><br class="">+static void doSpillCalleeSavedRegs(MachineFunction &Fn, RegScavenger *RS,<br class="">+ unsigned &MinCSFrameIndex,<br class="">+ unsigned &MaxCSFrameIndex,<br class="">+ const MBBVector &SaveBlocks,<br class="">+ const MBBVector &RestoreBlocks) {<br class="">+ const Function *F = Fn.getFunction();<br class="">+ const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();<br class="">+ MinCSFrameIndex = std::numeric_limits<unsigned>::max();<br class="">+ MaxCSFrameIndex = 0;<br class="">+<br class="">+ // Determine which of the registers in the callee save list should be saved.<br class="">+ BitVector SavedRegs;<br class="">+ TFI->determineCalleeSaves(Fn, SavedRegs, RS);<br class="">+<br class="">+ // Assign stack slots for any callee-saved registers that must be spilled.<br class="">+ assignCalleeSavedSpillSlots(Fn, SavedRegs, MinCSFrameIndex, MaxCSFrameIndex);<br class="">+<br class="">+ // Add the code to save and restore the callee saved registers.<br class="">+ if (!F->hasFnAttribute(Attribute::Naked))<br class="">+ insertCSRSpillsAndRestores(Fn, SaveBlocks, RestoreBlocks);<br class="">+}<br class="">+<br class="">/// AdjustStackOffset - Helper function used to adjust the stack frame offset.<br class="">static inline void<br class="">AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx,<br class="">@@ -604,8 +655,8 @@ void PEI::calculateFrameObjectOffsets(Ma<br class=""> MFI->setObjectOffset(i, -Offset); // Set the computed offset<br class=""> }<br class=""> } else {<br class="">- int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex;<br class="">- for (int i = MaxCSFI; i >= MinCSFI ; --i) {<br class="">+ unsigned MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex;<br class="">+ for (unsigned i = MaxCSFI; i >= MinCSFI; --i) {<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">This doesn't work. When MinCSFI == 0 we'll wrap to UINT_MAX and get an</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">infinite loop (well, an assert in getObjectAlignment). Presumably the</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">way this was awkwardly doing this loop in a signed int was a cute way to</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">avoid this previously.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">It's also kind of silly to make local variables for MaxCSFI and MinCSFI</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">- why not just use *CSFrameIndex directly?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""> unsigned Align = MFI->getObjectAlignment(i);<br class=""> // Adjust to alignment boundary<br class=""> Offset = alignTo(Offset, Align, Skew);<br class="">@@ -977,15 +1028,15 @@ void PEI::replaceFrameIndices(MachineBas<br class=""> }<br class="">}<br class=""><br class="">-/// scavengeFrameVirtualRegs - Replace all frame index virtual registers<br class="">+/// doScavengeFrameVirtualRegs - Replace all frame index virtual registers<br class="">/// with physical registers. Use the register scavenger to find an<br class="">/// appropriate register to use.<br class="">///<br class="">/// FIXME: Iterating over the instruction stream is unnecessary. We can simply<br class="">/// iterate over the vreg use list, which at this point only contains machine<br class="">/// operands for which eliminateFrameIndex need a new scratch reg.<br class="">-void<br class="">-PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {<br class="">+static void<br class="">+doScavengeFrameVirtualRegs(MachineFunction &Fn, RegScavenger *RS) {<br class=""> // Run through the instructions and find any virtual registers.<br class=""> for (MachineFunction::iterator BB = Fn.begin(),<br class=""> E = Fn.end(); BB != E; ++BB) {<br class=""><br class="">Modified: llvm/trunk/lib/CodeGen/TargetPassConfig.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetPassConfig.cpp?rev=269750&r1=269749&r2=269750&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetPassConfig.cpp?rev=269750&r1=269749&r2=269750&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/CodeGen/TargetPassConfig.cpp (original)<br class="">+++ llvm/trunk/lib/CodeGen/TargetPassConfig.cpp Tue May 17 03:49:59 2016<br class="">@@ -312,6 +312,13 @@ IdentifyingPassPtr TargetPassConfig::get<br class=""> return I->second;<br class="">}<br class=""><br class="">+bool TargetPassConfig::isPassSubstitutedOrOverridden(AnalysisID ID) const {<br class="">+ IdentifyingPassPtr TargetID = getPassSubstitution(ID);<br class="">+ IdentifyingPassPtr FinalPtr = overridePass(ID, TargetID);<br class="">+ return !FinalPtr.isValid() || FinalPtr.isInstance() ||<br class="">+ FinalPtr.getID() != ID;<br class="">+}<br class="">+<br class="">/// Add a pass to the PassManager if that pass is supposed to be run. If the<br class="">/// Started/Stopped flags indicate either that the compilation should start at<br class="">/// a later pass or that it should stop after an earlier pass, then do not add<br class="">@@ -565,7 +572,10 @@ void TargetPassConfig::addMachinePasses(<br class=""> if (getOptLevel() != CodeGenOpt::None)<br class=""> addPass(&ShrinkWrapID);<br class=""><br class="">- addPass(&PrologEpilogCodeInserterID);<br class="">+ // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only<br class="">+ // do so if it hasn't been disabled, substituted, or overridden.<br class="">+ if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID))<br class="">+ addPass(createPrologEpilogInserterPass(TM));<br class=""><br class=""> /// Add passes that optimize machine instructions after register allocation.<br class=""> if (getOptLevel() != CodeGenOpt::None)<br class=""><br class="">Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp?rev=269750&r1=269749&r2=269750&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp?rev=269750&r1=269749&r2=269750&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp (original)<br class="">+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp Tue May 17 03:49:59 2016<br class="">@@ -167,9 +167,6 @@ void WebAssemblyPassConfig::addPostRegAl<br class=""><br class=""> // Has no asserts of its own, but was not written to handle virtual regs.<br class=""> disablePass(&ShrinkWrapID);<br class="">- // We use our own PrologEpilogInserter which is very slightly modified to<br class="">- // tolerate virtual registers.<br class="">- disablePass(&PrologEpilogCodeInserterID);<br class=""><br class=""> // These functions all require the AllVRegsAllocated property.<br class=""> disablePass(&MachineCopyPropagationID);<br class="">@@ -180,11 +177,6 @@ void WebAssemblyPassConfig::addPostRegAl<br class=""> disablePass(&PatchableFunctionID);<br class=""><br class=""> TargetPassConfig::addPostRegAlloc();<br class="">-<br class="">- // Run WebAssembly's version of the PrologEpilogInserter. Target-independent<br class="">- // PEI runs after PostRegAlloc and after ShrinkWrap. Putting it here will run<br class="">- // PEI before ShrinkWrap but otherwise in the same position in the order.<br class="">- addPass(createWebAssemblyPEI());<br class="">}<br class=""><br class="">void WebAssemblyPassConfig::addPreEmitPass() {<br class=""><br class="">Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h?rev=269750&r1=269749&r2=269750&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h?rev=269750&r1=269749&r2=269750&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h (original)<br class="">+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyTargetMachine.h Tue May 17 03:49:59 2016<br class="">@@ -44,6 +44,8 @@ public:<br class=""><br class=""> /// \brief Get the TargetIRAnalysis for this target.<br class=""> TargetIRAnalysis getTargetIRAnalysis() override;<br class="">+<br class="">+ bool usesPhysRegsForPEI() const override { return false; }<br class="">};<br class=""><br class="">} // end namespace llvm<br class=""><br class=""><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits<br class=""></blockquote><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">llvm-commits mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="mailto:llvm-commits@lists.llvm.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">llvm-commits@lists.llvm.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a></div></blockquote></div><br class=""></div></body></html>