<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>