The attached patch passes a "make check". I haven't committed yet
because I am going on vacations and will be a bit slow to respond. I
will still have Internet access and can commit if there is positive
feedback.

One ugly hack in the CL in to make "Subtarget" and "BaseSubtarget"
independent fields that point to the same object. I did this just to
make the type checker happy. Is there an easier way to merge them then
adding virtual getters to the base class and replacing all uses of
Subtarget?

Cheers,
-- 
Rafael Avila de Espindola

Google Ireland Ltd.
Gordon House
Barrow Street
Dublin 4
Ireland

Registered in Dublin, Ireland
Registration Number: 368047
Index: include/llvm/Target/TargetLowering.h
===================================================================
--- include/llvm/Target/TargetLowering.h	(revision 43703)
+++ include/llvm/Target/TargetLowering.h	(working copy)
@@ -22,6 +22,7 @@
 #ifndef LLVM_TARGET_TARGETLOWERING_H
 #define LLVM_TARGET_TARGETLOWERING_H
 
+#include "llvm/Target/TargetSubtarget.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
 #include "llvm/CodeGen/RuntimeLibcalls.h"
 #include "llvm/ADT/APFloat.h"
@@ -845,6 +846,7 @@
   
 public:
 
+  const TargetSubtarget *BaseSubtarget;
   //===--------------------------------------------------------------------===//
   // Lowering methods - These methods must be implemented by targets so that
   // the SelectionDAGLowering code knows how to lower these.
@@ -878,6 +880,18 @@
               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.
Index: include/llvm/Target/TargetSubtarget.h
===================================================================
--- include/llvm/Target/TargetSubtarget.h	(revision 43703)
+++ include/llvm/Target/TargetSubtarget.h	(working copy)
@@ -28,6 +28,9 @@
 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();
 };
 
Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/TargetLowering.cpp	(revision 43703)
+++ lib/CodeGen/SelectionDAG/TargetLowering.cpp	(working copy)
@@ -21,6 +21,7 @@
 #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.
@@ -194,6 +195,59 @@
 
 TargetLowering::~TargetLowering() {}
 
+
+SDOperand TargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG) {
+  assert(BaseSubtarget && "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 <= BaseSubtarget->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() {
Index: lib/Target/ARM/ARMISelLowering.h
===================================================================
--- lib/Target/ARM/ARMISelLowering.h	(revision 43703)
+++ lib/Target/ARM/ARMISelLowering.h	(working copy)
@@ -134,10 +134,6 @@
     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);
Index: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- lib/Target/ARM/ARMISelLowering.cpp	(revision 43703)
+++ lib/Target/ARM/ARMISelLowering.cpp	(working copy)
@@ -37,6 +37,7 @@
 ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
     : TargetLowering(TM), ARMPCLabelIndex(0) {
   Subtarget = &TM.getSubtarget<ARMSubtarget>();
+  BaseSubtarget = Subtarget;
 
   if (Subtarget->isTargetDarwin()) {
     // Don't have these.
@@ -1287,55 +1288,6 @@
   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,
Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp	(revision 43703)
+++ lib/Target/X86/X86ISelLowering.cpp	(working copy)
@@ -42,6 +42,7 @@
 X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   : TargetLowering(TM) {
   Subtarget = &TM.getSubtarget<X86Subtarget>();
+  BaseSubtarget = Subtarget;
   X86ScalarSSEf64 = Subtarget->hasSSE2();
   X86ScalarSSEf32 = Subtarget->hasSSE1();
   X86StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
@@ -4481,55 +4482,6 @@
   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,
Index: lib/Target/X86/X86ISelLowering.h
===================================================================
--- lib/Target/X86/X86ISelLowering.h	(revision 43703)
+++ lib/Target/X86/X86ISelLowering.h	(working copy)
@@ -454,10 +454,6 @@
     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);
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to