OSDN Git Service

TargetLowering: Factor out common code for tail call eligibility checking; NFC
authorMatthias Braun <matze@braunis.de>
Thu, 14 Apr 2016 01:10:42 +0000 (01:10 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 14 Apr 2016 01:10:42 +0000 (01:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266270 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/TargetLowering.cpp
lib/Target/AArch64/AArch64ISelLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/X86/X86ISelLowering.cpp

index 994071b..ba77a88 100644 (file)
@@ -43,6 +43,7 @@
 namespace llvm {
   class CallInst;
   class CCState;
+  class CCValAssign;
   class FastISel;
   class FunctionLoweringInfo;
   class ImmutableCallSite;
@@ -52,6 +53,7 @@ namespace llvm {
   class MachineInstr;
   class MachineJumpTableInfo;
   class MachineLoop;
+  class MachineRegisterInfo;
   class Mangler;
   class MCContext;
   class MCExpr;
@@ -2139,6 +2141,14 @@ public:
                                           bool doesNotReturn = false,
                                           bool isReturnValueUsed = true) const;
 
+  /// Check whether parameters to a call that are passed in callee saved
+  /// registers are the same as from the calling function.  This needs to be
+  /// checked for tail call eligibility.
+  bool parametersInCSRMatch(const MachineRegisterInfo &MRI,
+      const uint32_t *CallerPreservedMask,
+      const SmallVectorImpl<CCValAssign> &ArgLocs,
+      const SmallVectorImpl<SDValue> &OutVals) const;
+
   //===--------------------------------------------------------------------===//
   // TargetLowering Optimization Methods
   //
index 97cf3c5..e58a634 100644 (file)
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/CodeGen/Analysis.h"
+#include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -65,6 +67,31 @@ bool TargetLowering::isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
   return isUsedByReturnOnly(Node, Chain);
 }
 
+bool TargetLowering::parametersInCSRMatch(const MachineRegisterInfo &MRI,
+    const uint32_t *CallerPreservedMask,
+    const SmallVectorImpl<CCValAssign> &ArgLocs,
+    const SmallVectorImpl<SDValue> &OutVals) const {
+  for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
+    const CCValAssign &ArgLoc = ArgLocs[I];
+    if (!ArgLoc.isRegLoc())
+      continue;
+    unsigned Reg = ArgLoc.getLocReg();
+    // Only look at callee saved registers.
+    if (MachineOperand::clobbersPhysReg(CallerPreservedMask, Reg))
+      continue;
+    // Check that we pass the value used for the caller.
+    // (We look for a CopyFromReg reading a virtual register that is used
+    //  for the function live-in value of register Reg)
+    SDValue Value = OutVals[I];
+    if (Value->getOpcode() != ISD::CopyFromReg)
+      return false;
+    unsigned ArgReg = cast<RegisterSDNode>(Value->getOperand(1))->getReg();
+    if (MRI.getLiveInPhysReg(ArgReg) != Reg)
+      return false;
+  }
+  return true;
+}
+
 /// \brief Set CallLoweringInfo attribute flags based on a call instruction
 /// and called function attributes.
 void TargetLowering::ArgListEntry::setAttributes(ImmutableCallSite *CS,
index 7cd8ca9..4d7f774 100644 (file)
@@ -2899,27 +2899,9 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization(
   if (CCInfo.getNextStackOffset() > FuncInfo->getBytesInStackArgArea())
     return false;
 
-  // Parameters passed in callee saved registers must have the same value in
-  // caller and callee.
-  for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
-    const CCValAssign &ArgLoc = ArgLocs[I];
-    if (!ArgLoc.isRegLoc())
-      continue;
-    unsigned Reg = ArgLoc.getLocReg();
-    // Only look at callee saved registers.
-    if (MachineOperand::clobbersPhysReg(CallerPreserved, Reg))
-      continue;
-    // Check that we pass the value used for the caller.
-    // (We look for a CopyFromReg reading a virtual register that is used
-    //  for the function live-in value of register Reg)
-    SDValue Value = OutVals[I];
-    if (Value->getOpcode() != ISD::CopyFromReg)
-      return false;
-    unsigned ArgReg = cast<RegisterSDNode>(Value->getOperand(1))->getReg();
-    const MachineRegisterInfo &MRI = MF.getRegInfo();
-    if (MRI.getLiveInPhysReg(ArgReg) != Reg)
-      return false;
-  }
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
+  if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals))
+    return false;
 
   return true;
 }
index 217e255..9535474 100644 (file)
@@ -2208,27 +2208,9 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
       }
     }
 
-    // Parameters passed in callee saved registers must have the same value in
-    // caller and callee.
-    for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
-      const CCValAssign &ArgLoc = ArgLocs[I];
-      if (!ArgLoc.isRegLoc())
-        continue;
-      unsigned Reg = ArgLoc.getLocReg();
-      // Only look at callee saved registers.
-      if (MachineOperand::clobbersPhysReg(CallerPreserved, Reg))
-        continue;
-      // Check that we pass the value used for the caller.
-      // (We look for a CopyFromReg reading a virtual register that is used
-      //  for the function live-in value of register Reg)
-      SDValue Value = OutVals[I];
-      if (Value->getOpcode() != ISD::CopyFromReg)
-        return false;
-      unsigned ArgReg = cast<RegisterSDNode>(Value->getOperand(1))->getReg();
-      const MachineRegisterInfo &MRI = MF.getRegInfo();
-      if (MRI.getLiveInPhysReg(ArgReg) != Reg)
-        return false;
-    }
+    const MachineRegisterInfo &MRI = MF.getRegInfo();
+    if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals))
+      return false;
   }
 
   return true;
index 7cf909f..fcd7f07 100644 (file)
@@ -3849,27 +3849,9 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(
       }
     }
 
-    // Parameters passed in callee saved registers must have the same value in
-    // caller and callee.
-    for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
-      const CCValAssign &ArgLoc = ArgLocs[I];
-      if (!ArgLoc.isRegLoc())
-        continue;
-      unsigned Reg = ArgLoc.getLocReg();
-      // Only look at callee saved registers.
-      if (MachineOperand::clobbersPhysReg(CallerPreserved, Reg))
-        continue;
-      // Check that we pass the value used for the caller.
-      // (We look for a CopyFromReg reading a virtual register that is used
-      //  for the function live-in value of register Reg)
-      SDValue Value = OutVals[I];
-      if (Value->getOpcode() != ISD::CopyFromReg)
-        return false;
-      unsigned ArgReg = cast<RegisterSDNode>(Value->getOperand(1))->getReg();
-      const MachineRegisterInfo &MRI = MF.getRegInfo();
-      if (MRI.getLiveInPhysReg(ArgReg) != Reg)
-        return false;
-    }
+    const MachineRegisterInfo &MRI = MF.getRegInfo();
+    if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals))
+      return false;
   }
 
   bool CalleeWillPop =