Author: rafael Date: Mon Nov 5 17:12:20 2007 New Revision: 43742 URL: http://llvm.org/viewvc/llvm-project?rev=43742&view=rev Log: Move the LowerMEMCPY and LowerMEMCPYCall to a common place.
Thanks for the suggestions Bill :-) Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/include/llvm/Target/TargetSubtarget.h llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=43742&r1=43741&r2=43742&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Mon Nov 5 17:12:20 2007 @@ -41,6 +41,7 @@ class MachineBasicBlock; class MachineInstr; class VectorType; + class TargetSubtarget; //===----------------------------------------------------------------------===// /// TargetLowering - This class defines information used to lower LLVM code to @@ -845,6 +846,9 @@ 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. @@ -878,6 +882,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. Modified: llvm/trunk/include/llvm/Target/TargetSubtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSubtarget.h?rev=43742&r1=43741&r2=43742&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetSubtarget.h (original) +++ llvm/trunk/include/llvm/Target/TargetSubtarget.h Mon Nov 5 17:12:20 2007 @@ -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(); }; Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=43742&r1=43741&r2=43742&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Mon Nov 5 17:12:20 2007 @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #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" @@ -21,6 +22,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 +196,59 @@ 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() { Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=43742&r1=43741&r2=43742&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Nov 5 17:12:20 2007 @@ -1287,55 +1287,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, Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=43742&r1=43741&r2=43742&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Mon Nov 5 17:12:20 2007 @@ -15,13 +15,13 @@ #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; - class ARMSubtarget; namespace ARMISD { // ARM Specific DAG Nodes @@ -114,6 +114,11 @@ 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. @@ -134,10 +139,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); Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=43742&r1=43741&r2=43742&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Nov 5 17:12:20 2007 @@ -4481,55 +4481,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, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=43742&r1=43741&r2=43742&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Nov 5 17:12:20 2007 @@ -386,6 +386,10 @@ 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. @@ -454,10 +458,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