[llvm] r275347 - [IPRA] Set callee saved registers to none for local function when IPRA is enabled.

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 13 16:39:35 PDT 2016


Author: mehdi_amini
Date: Wed Jul 13 18:39:34 2016
New Revision: 275347

URL: http://llvm.org/viewvc/llvm-project?rev=275347&view=rev
Log:
[IPRA] Set callee saved registers to none for local function when IPRA is enabled.

IPRA try to optimize caller saved register by propagating register
usage information from callee to caller so it is beneficial to have
caller saved registers compare to callee saved registers when IPRA
is enabled. Please find more detailed explanation here
https://groups.google.com/d/msg/llvm-dev/XRzGhJ9wtZg/tjAJqb0eEgAJ.

This change makes local function do not have any callee preserved
register when IPRA is enabled. A simple test case is also added to
verify this change.

Patch by Vivek Pandya <vivekvpandya at gmail.com>

Differential Revision: http://reviews.llvm.org/D21561

Modified:
    llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h
    llvm/trunk/include/llvm/Target/TargetFrameLowering.h
    llvm/trunk/lib/CodeGen/RegUsageInfoCollector.cpp
    llvm/trunk/lib/CodeGen/TargetFrameLoweringImpl.cpp
    llvm/trunk/lib/CodeGen/TargetPassConfig.cpp

Modified: llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h?rev=275347&r1=275346&r2=275347&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h (original)
+++ llvm/trunk/include/llvm/CodeGen/TargetPassConfig.h Wed Jul 13 18:39:34 2016
@@ -16,8 +16,11 @@
 
 #include "llvm/Pass.h"
 #include "llvm/Support/CodeGen.h"
+#include "llvm/Support/CommandLine.h"
 #include <string>
 
+extern llvm::cl::opt<bool> UseIPRA;
+
 namespace llvm {
 
 class PassConfigImpl;

Modified: llvm/trunk/include/llvm/Target/TargetFrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetFrameLowering.h?rev=275347&r1=275346&r2=275347&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetFrameLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetFrameLowering.h Wed Jul 13 18:39:34 2016
@@ -331,6 +331,20 @@ public:
   virtual bool canUseAsEpilogue(const MachineBasicBlock &MBB) const {
     return true;
   }
+
+  /// Check if given function is safe for not having callee saved registers.
+  /// This is used when interprocedural register allocation is enabled.
+  static bool isSafeForNoCSROpt(const Function *F) {
+    if (!F->hasLocalLinkage() || F->hasAddressTaken() ||
+        !F->hasFnAttribute(Attribute::NoRecurse))
+      return false;
+    // Function should not be optimized as tail call.
+    for (const User *U : F->users())
+      if (auto CS = ImmutableCallSite(U))
+        if (CS.isTailCall())
+          return false;
+    return true;
+  }
 };
 
 } // End llvm namespace

Modified: llvm/trunk/lib/CodeGen/RegUsageInfoCollector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegUsageInfoCollector.cpp?rev=275347&r1=275346&r2=275347&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegUsageInfoCollector.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegUsageInfoCollector.cpp Wed Jul 13 18:39:34 2016
@@ -17,6 +17,7 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
@@ -26,11 +27,15 @@
 #include "llvm/CodeGen/RegisterUsageInfo.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetFrameLowering.h"
 
 using namespace llvm;
 
 #define DEBUG_TYPE "ip-regalloc"
 
+STATISTIC(NumCSROpt,
+          "Number of functions optimized for callee saved registers");
+
 namespace llvm {
 void initializeRegUsageInfoCollectorPass(PassRegistry &);
 }
@@ -101,6 +106,8 @@ bool RegUsageInfoCollector::runOnMachine
   unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32;
   RegMask.resize(RegMaskSize, 0xFFFFFFFF);
 
+  const Function *F = MF.getFunction();
+
   PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>();
 
   PRUI->setTargetMachine(&TM);
@@ -111,11 +118,17 @@ bool RegUsageInfoCollector::runOnMachine
     if (MRI->isPhysRegModified(PReg, true))
       markRegClobbered(TRI, &RegMask[0], PReg);
 
-  const uint32_t *CallPreservedMask =
-      TRI->getCallPreservedMask(MF, MF.getFunction()->getCallingConv());
-  // Set callee saved register as preserved.
-  for (unsigned i = 0; i < RegMaskSize; ++i)
-    RegMask[i] = RegMask[i] | CallPreservedMask[i];
+  if (!TargetFrameLowering::isSafeForNoCSROpt(F)) {
+    const uint32_t *CallPreservedMask =
+        TRI->getCallPreservedMask(MF, F->getCallingConv());
+    // Set callee saved register as preserved.
+    for (unsigned i = 0; i < RegMaskSize; ++i)
+      RegMask[i] = RegMask[i] | CallPreservedMask[i];
+  } else {
+    ++NumCSROpt;
+    DEBUG(dbgs() << MF.getName()
+                 << " function optimized for not having CSR.\n");
+  }
 
   for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg)
     if (MachineOperand::clobbersPhysReg(&(RegMask[0]), PReg))
@@ -123,7 +136,7 @@ bool RegUsageInfoCollector::runOnMachine
 
   DEBUG(dbgs() << " \n----------------------------------------\n");
 
-  PRUI->storeUpdateRegUsageInfo(MF.getFunction(), std::move(RegMask));
+  PRUI->storeUpdateRegUsageInfo(F, std::move(RegMask));
 
   return false;
 }

Modified: llvm/trunk/lib/CodeGen/TargetFrameLoweringImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetFrameLoweringImpl.cpp?rev=275347&r1=275346&r2=275347&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetFrameLoweringImpl.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetFrameLoweringImpl.cpp Wed Jul 13 18:39:34 2016
@@ -12,13 +12,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/BitVector.h"
-#include "llvm/Target/TargetFrameLowering.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Function.h"
+#include "llvm/Target/TargetFrameLowering.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetSubtargetInfo.h"
 #include <cstdlib>
@@ -59,15 +60,21 @@ bool TargetFrameLowering::needsFrameInde
 void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF,
                                                BitVector &SavedRegs,
                                                RegScavenger *RS) const {
-  // Get the callee saved register list...
   const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
-  const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF);
 
   // Resize before the early returns. Some backends expect that
   // SavedRegs.size() == TRI.getNumRegs() after this call even if there are no
   // saved registers.
   SavedRegs.resize(TRI.getNumRegs());
 
+  // When interprocedural register allocation is enabled caller saved registers
+  // are preferred over callee saved registers.
+  if (UseIPRA && isSafeForNoCSROpt(MF.getFunction()))
+    return;
+
+  // Get the callee saved register list...
+  const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF);
+
   // Early exit if there are no callee saved registers.
   if (!CSRegs || CSRegs[0] == 0)
     return;

Modified: llvm/trunk/lib/CodeGen/TargetPassConfig.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetPassConfig.cpp?rev=275347&r1=275346&r2=275347&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetPassConfig.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetPassConfig.cpp Wed Jul 13 18:39:34 2016
@@ -28,7 +28,6 @@
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"




More information about the llvm-commits mailing list