mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
Move the LowerMEMCPY and LowerMEMCPYCall to a common place.
Thanks for the suggestions Bill :-) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43742 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0a6d98e10e
commit
f1ba1cad38
@ -41,6 +41,7 @@ namespace llvm {
|
||||
class MachineBasicBlock;
|
||||
class MachineInstr;
|
||||
class VectorType;
|
||||
class TargetSubtarget;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// TargetLowering - This class defines information used to lower LLVM code to
|
||||
@ -845,6 +846,9 @@ protected:
|
||||
|
||||
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 @@ public:
|
||||
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.
|
||||
|
@ -28,6 +28,9 @@ class TargetSubtarget {
|
||||
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();
|
||||
};
|
||||
|
||||
|
@ -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(TargetMachine &tm)
|
||||
|
||||
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() {
|
||||
|
@ -1287,55 +1287,6 @@ static SDOperand LowerSRx(SDOperand Op, SelectionDAG &DAG,
|
||||
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,
|
||||
|
@ -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 @@ namespace llvm {
|
||||
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 @@ 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 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);
|
||||
|
@ -4481,55 +4481,6 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
|
||||
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,
|
||||
|
@ -386,6 +386,10 @@ namespace llvm {
|
||||
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 @@ namespace llvm {
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user