Move the LowerMEMCPY and LowerMEMCPYCall to a common place.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 5 Nov 2007 23:12:20 +0000 (23:12 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 5 Nov 2007 23:12:20 +0000 (23:12 +0000)
Thanks for the suggestions Bill :-)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43742 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 9d7a1ec60f988e5d2a9d6f8f670f3af49cc62b62..e8f8c12ac62556435938c7320c1d58d8f298ec08 100644 (file)
@@ -41,6 +41,7 @@ namespace llvm {
   class MachineBasicBlock;
   class MachineInstr;
   class VectorType;
   class MachineBasicBlock;
   class MachineInstr;
   class VectorType;
+  class TargetSubtarget;
 
 //===----------------------------------------------------------------------===//
 /// TargetLowering - This class defines information used to lower LLVM code to
 
 //===----------------------------------------------------------------------===//
 /// TargetLowering - This class defines information used to lower LLVM code to
@@ -845,6 +846,9 @@ protected:
   
 public:
 
   
 public:
 
+  virtual const TargetSubtarget *getSubtarget() {
+    assert(0 && "Not Implemented");
+  }
   //===--------------------------------------------------------------------===//
   // Lowering methods - These methods must be implemented by targets so that
   // the SelectionDAGLowering code knows how to lower these.
   //===--------------------------------------------------------------------===//
   // Lowering methods - These methods must be implemented by targets so that
   // the SelectionDAGLowering code knows how to lower these.
@@ -878,6 +882,18 @@ public:
               bool isVarArg, unsigned CallingConv, bool isTailCall, 
               SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
 
               bool isVarArg, unsigned CallingConv, bool isTailCall, 
               SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
 
+
+  virtual SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG);
+  virtual SDOperand LowerMEMCPYCall(SDOperand Chain, SDOperand Dest,
+                                    SDOperand Source, SDOperand Count,
+                                    SelectionDAG &DAG);
+  virtual SDOperand LowerMEMCPYInline(SDOperand Chain, SDOperand Dest,
+                                      SDOperand Source, unsigned Size,
+                                      unsigned Align, SelectionDAG &DAG) {
+    assert(0 && "Not Implemented");
+  }
+
+
   /// LowerOperation - This callback is invoked for operations that are 
   /// unsupported by the target, which are registered to use 'custom' lowering,
   /// and whose defined values are all legal.
   /// LowerOperation - This callback is invoked for operations that are 
   /// unsupported by the target, which are registered to use 'custom' lowering,
   /// and whose defined values are all legal.
index 3b174c2ee4630c911cc3604d99db649b0088f161..1185b09bd99733413c2c9ae1543775ffd597d59b 100644 (file)
@@ -28,6 +28,9 @@ class TargetSubtarget {
 protected: // Can only create subclasses...
   TargetSubtarget();
 public:
 protected: // Can only create subclasses...
   TargetSubtarget();
 public:
+  /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
+  /// that still makes it profitable to inline the call.
+  virtual unsigned getMaxInlineSizeThreshold() const {return 0; }
   virtual ~TargetSubtarget();
 };
 
   virtual ~TargetSubtarget();
 };
 
index 9309cf46bd257f54f0978982a4fbac187805a41d..3708b1cb9a7330804cf643ca5cd09f43104a76b8 100644 (file)
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Target/TargetLowering.h"
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetSubtarget.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/MRegisterInfo.h"
@@ -21,6 +22,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/CallingConv.h"
 using namespace llvm;
 
 /// InitLibcallNames - Set default libcall names.
 using namespace llvm;
 
 /// InitLibcallNames - Set default libcall names.
@@ -194,6 +196,59 @@ TargetLowering::TargetLowering(TargetMachine &tm)
 
 TargetLowering::~TargetLowering() {}
 
 
 TargetLowering::~TargetLowering() {}
 
+
+SDOperand TargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG) {
+  assert(getSubtarget() && "Subtarget not defined");
+  SDOperand ChainOp = Op.getOperand(0);
+  SDOperand DestOp = Op.getOperand(1);
+  SDOperand SourceOp = Op.getOperand(2);
+  SDOperand CountOp = Op.getOperand(3);
+  SDOperand AlignOp = Op.getOperand(4);
+  SDOperand AlwaysInlineOp = Op.getOperand(5);
+
+  bool AlwaysInline = (bool)cast<ConstantSDNode>(AlwaysInlineOp)->getValue();
+  unsigned Align = (unsigned)cast<ConstantSDNode>(AlignOp)->getValue();
+  if (Align == 0) Align = 1;
+
+  // If size is unknown, call memcpy.
+  ConstantSDNode *I = dyn_cast<ConstantSDNode>(CountOp);
+  if (!I) {
+    assert(!AlwaysInline && "Cannot inline copy of unknown size");
+    return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG);
+  }
+
+  // If not DWORD aligned or if size is more than threshold, then call memcpy.
+  // The libc version is likely to be faster for the following cases. It can
+  // use the address value and run time information about the CPU.
+  // With glibc 2.6.1 on a core 2, coping an array of 100M longs was 30% faster
+  unsigned Size = I->getValue();
+  if (AlwaysInline ||
+      (Size <= getSubtarget()->getMaxInlineSizeThreshold() &&
+       (Align & 3) == 0))
+    return LowerMEMCPYInline(ChainOp, DestOp, SourceOp, Size, Align, DAG);
+  return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG);
+}
+
+
+SDOperand TargetLowering::LowerMEMCPYCall(SDOperand Chain,
+                                          SDOperand Dest,
+                                          SDOperand Source,
+                                          SDOperand Count,
+                                          SelectionDAG &DAG) {
+  MVT::ValueType IntPtr = getPointerTy();
+  TargetLowering::ArgListTy Args;
+  TargetLowering::ArgListEntry Entry;
+  Entry.Ty = getTargetData()->getIntPtrType();
+  Entry.Node = Dest; Args.push_back(Entry);
+  Entry.Node = Source; Args.push_back(Entry);
+  Entry.Node = Count; Args.push_back(Entry);
+  std::pair<SDOperand,SDOperand> CallResult =
+      LowerCallTo(Chain, Type::VoidTy, false, false, CallingConv::C, false,
+                  DAG.getExternalSymbol("memcpy", IntPtr), Args, DAG);
+  return CallResult.second;
+}
+
+
 /// computeRegisterProperties - Once all of the register classes are added,
 /// this allows us to compute derived properties we expose.
 void TargetLowering::computeRegisterProperties() {
 /// computeRegisterProperties - Once all of the register classes are added,
 /// this allows us to compute derived properties we expose.
 void TargetLowering::computeRegisterProperties() {
index b7e37660a7b6cb5e988ba50ff294f6f52e12558c..bc2c7c3e1ef6bba5f262a74f33688ce2c867603b 100644 (file)
@@ -1287,55 +1287,6 @@ static SDOperand LowerSRx(SDOperand Op, SelectionDAG &DAG,
   return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi);
 }
 
   return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi);
 }
 
-SDOperand ARMTargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand ChainOp = Op.getOperand(0);
-  SDOperand DestOp = Op.getOperand(1);
-  SDOperand SourceOp = Op.getOperand(2);
-  SDOperand CountOp = Op.getOperand(3);
-  SDOperand AlignOp = Op.getOperand(4);
-  SDOperand AlwaysInlineOp = Op.getOperand(5);
-
-  bool AlwaysInline = (bool)cast<ConstantSDNode>(AlwaysInlineOp)->getValue();
-  unsigned Align = (unsigned)cast<ConstantSDNode>(AlignOp)->getValue();
-  if (Align == 0) Align = 1;
-
-  // If size is unknown, call memcpy.
-  ConstantSDNode *I = dyn_cast<ConstantSDNode>(CountOp);
-  if (!I) {
-    assert(!AlwaysInline && "Cannot inline copy of unknown size");
-    return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG);
-  }
-
-  // If not DWORD aligned or if size is more than threshold, then call memcpy.
-  // The libc version is likely to be faster for the these cases. It can
-  // use the address value and run time information about the CPU.
-  // With glibc 2.6.1 on a core 2, coping an array of 100M longs was 30% faster
-  unsigned Size = I->getValue();
-  if (AlwaysInline ||
-      (Size <= Subtarget->getMaxInlineSizeThreshold() &&
-       (Align & 3) == 0))
-    return LowerMEMCPYInline(ChainOp, DestOp, SourceOp, Size, Align, DAG);
-  return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG);
-}
-
-SDOperand ARMTargetLowering::LowerMEMCPYCall(SDOperand Chain,
-                                             SDOperand Dest,
-                                             SDOperand Source,
-                                             SDOperand Count,
-                                             SelectionDAG &DAG) {
-  MVT::ValueType IntPtr = getPointerTy();
-  TargetLowering::ArgListTy Args;
-  TargetLowering::ArgListEntry Entry;
-  Entry.Ty = getTargetData()->getIntPtrType();
-  Entry.Node = Dest; Args.push_back(Entry);
-  Entry.Node = Source; Args.push_back(Entry);
-  Entry.Node = Count; Args.push_back(Entry);
-  std::pair<SDOperand,SDOperand> CallResult =
-      LowerCallTo(Chain, Type::VoidTy, false, false, CallingConv::C, false,
-                  DAG.getExternalSymbol("memcpy", IntPtr), Args, DAG);
-  return CallResult.second;
-}
-
 SDOperand ARMTargetLowering::LowerMEMCPYInline(SDOperand Chain,
                                                SDOperand Dest,
                                                SDOperand Source,
 SDOperand ARMTargetLowering::LowerMEMCPYInline(SDOperand Chain,
                                                SDOperand Dest,
                                                SDOperand Source,
index 41045e7569624482c083842da4257580c473fdcb..e6fb9458b6c59cdb9c72149871585381efbec7b2 100644 (file)
 #ifndef ARMISELLOWERING_H
 #define ARMISELLOWERING_H
 
 #ifndef ARMISELLOWERING_H
 #define ARMISELLOWERING_H
 
+#include "ARMSubtarget.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include <vector>
 
 namespace llvm {
   class ARMConstantPoolValue;
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include <vector>
 
 namespace llvm {
   class ARMConstantPoolValue;
-  class ARMSubtarget;
 
   namespace ARMISD {
     // ARM Specific DAG Nodes
 
   namespace ARMISD {
     // ARM Specific DAG Nodes
@@ -114,6 +114,11 @@ namespace llvm {
     std::vector<unsigned>
     getRegClassForInlineAsmConstraint(const std::string &Constraint,
                                       MVT::ValueType VT) const;
     std::vector<unsigned>
     getRegClassForInlineAsmConstraint(const std::string &Constraint,
                                       MVT::ValueType VT) const;
+
+    virtual const TargetSubtarget* getSubtarget() {
+      return static_cast<const TargetSubtarget*>(Subtarget);
+    }
+
   private:
     /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
     /// make the right decision when generating code for different targets.
   private:
     /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
     /// make the right decision when generating code for different targets.
@@ -134,10 +139,6 @@ namespace llvm {
     SDOperand LowerGLOBAL_OFFSET_TABLE(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerGLOBAL_OFFSET_TABLE(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG);
-    SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG);
-    SDOperand LowerMEMCPYCall(SDOperand Chain, SDOperand Dest,
-                              SDOperand Source, SDOperand Count,
-                              SelectionDAG &DAG);
     SDOperand LowerMEMCPYInline(SDOperand Chain, SDOperand Dest,
                                 SDOperand Source, unsigned Size,
                                 unsigned Align, SelectionDAG &DAG);
     SDOperand LowerMEMCPYInline(SDOperand Chain, SDOperand Dest,
                                 SDOperand Source, unsigned Size,
                                 unsigned Align, SelectionDAG &DAG);
index 58004f0201ed71ad7e7475e54896787cb6b9c527..e9df3f5337547918026c803edb958a38247ed9ac 100644 (file)
@@ -4481,55 +4481,6 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
   return Chain;
 }
 
   return Chain;
 }
 
-SDOperand X86TargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand ChainOp = Op.getOperand(0);
-  SDOperand DestOp = Op.getOperand(1);
-  SDOperand SourceOp = Op.getOperand(2);
-  SDOperand CountOp = Op.getOperand(3);
-  SDOperand AlignOp = Op.getOperand(4);
-  SDOperand AlwaysInlineOp = Op.getOperand(5);
-
-  bool AlwaysInline = (bool)cast<ConstantSDNode>(AlwaysInlineOp)->getValue();
-  unsigned Align = (unsigned)cast<ConstantSDNode>(AlignOp)->getValue();
-  if (Align == 0) Align = 1;
-
-  // If size is unknown, call memcpy.
-  ConstantSDNode *I = dyn_cast<ConstantSDNode>(CountOp);
-  if (!I) {
-    assert(!AlwaysInline && "Cannot inline copy of unknown size");
-    return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG);
-  }
-
-  // If not DWORD aligned or if size is more than threshold, then call memcpy.
-  // The libc version is likely to be faster for the following cases. It can
-  // use the address value and run time information about the CPU.
-  // With glibc 2.6.1 on a core 2, coping an array of 100M longs was 30% faster
-  unsigned Size = I->getValue();
-  if (AlwaysInline ||
-      (Size <= Subtarget->getMaxInlineSizeThreshold() &&
-       (Align & 3) == 0))
-    return LowerMEMCPYInline(ChainOp, DestOp, SourceOp, Size, Align, DAG);
-  return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG);
-}
-
-SDOperand X86TargetLowering::LowerMEMCPYCall(SDOperand Chain,
-                                             SDOperand Dest,
-                                             SDOperand Source,
-                                             SDOperand Count,
-                                             SelectionDAG &DAG) {
-  MVT::ValueType IntPtr = getPointerTy();
-  TargetLowering::ArgListTy Args;
-  TargetLowering::ArgListEntry Entry;
-  Entry.Ty = getTargetData()->getIntPtrType();
-  Entry.Node = Dest; Args.push_back(Entry);
-  Entry.Node = Source; Args.push_back(Entry);
-  Entry.Node = Count; Args.push_back(Entry);
-  std::pair<SDOperand,SDOperand> CallResult =
-      LowerCallTo(Chain, Type::VoidTy, false, false, CallingConv::C, false,
-                  DAG.getExternalSymbol("memcpy", IntPtr), Args, DAG);
-  return CallResult.second;
-}
-
 SDOperand X86TargetLowering::LowerMEMCPYInline(SDOperand Chain,
                                                SDOperand Dest,
                                                SDOperand Source,
 SDOperand X86TargetLowering::LowerMEMCPYInline(SDOperand Chain,
                                                SDOperand Dest,
                                                SDOperand Source,
index 2330f98bb8f9caf0dfe15101350c2a75be9a0f28..4f422a9aae17e3f52ae94a3da2658d98fa023dc2 100644 (file)
@@ -386,6 +386,10 @@ namespace llvm {
                                                    SDOperand Ret, 
                                                    SelectionDAG &DAG) const;
 
                                                    SDOperand Ret, 
                                                    SelectionDAG &DAG) const;
 
+    virtual const TargetSubtarget* getSubtarget() {
+      return static_cast<const TargetSubtarget*>(Subtarget);
+    }
+
   private:
     /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
     /// make the right decision when generating code for different targets.
   private:
     /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
     /// make the right decision when generating code for different targets.
@@ -454,10 +458,6 @@ namespace llvm {
     SDOperand LowerMEMCPYInline(SDOperand Dest, SDOperand Source,
                                 SDOperand Chain, unsigned Size, unsigned Align,
                                 SelectionDAG &DAG);
     SDOperand LowerMEMCPYInline(SDOperand Dest, SDOperand Source,
                                 SDOperand Chain, unsigned Size, unsigned Align,
                                 SelectionDAG &DAG);
-    SDOperand LowerMEMCPYCall(SDOperand ChainOp, SDOperand DestOp,
-                              SDOperand SourceOp, SDOperand CountOp,
-                              SelectionDAG &DAG);
-    SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG);