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 MachineBasicBlock;
|
||||||
class MachineInstr;
|
class MachineInstr;
|
||||||
class VectorType;
|
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
|
// Lowering methods - These methods must be implemented by targets so that
|
||||||
// the SelectionDAGLowering code knows how to lower these.
|
// the SelectionDAGLowering code knows how to lower these.
|
||||||
@ -878,6 +882,18 @@ public:
|
|||||||
bool isVarArg, unsigned CallingConv, bool isTailCall,
|
bool isVarArg, unsigned CallingConv, bool isTailCall,
|
||||||
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
|
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
|
/// LowerOperation - This callback is invoked for operations that are
|
||||||
/// unsupported by the target, which are registered to use 'custom' lowering,
|
/// unsupported by the target, which are registered to use 'custom' lowering,
|
||||||
/// and whose defined values are all legal.
|
/// and whose defined values are all legal.
|
||||||
|
@ -28,6 +28,9 @@ class TargetSubtarget {
|
|||||||
protected: // Can only create subclasses...
|
protected: // Can only create subclasses...
|
||||||
TargetSubtarget();
|
TargetSubtarget();
|
||||||
public:
|
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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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/TargetData.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/MRegisterInfo.h"
|
#include "llvm/Target/MRegisterInfo.h"
|
||||||
@ -21,6 +22,7 @@
|
|||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Target/TargetAsmInfo.h"
|
#include "llvm/Target/TargetAsmInfo.h"
|
||||||
|
#include "llvm/CallingConv.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
/// InitLibcallNames - Set default libcall names.
|
/// 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,
|
/// computeRegisterProperties - Once all of the register classes are added,
|
||||||
/// this allows us to compute derived properties we expose.
|
/// this allows us to compute derived properties we expose.
|
||||||
void TargetLowering::computeRegisterProperties() {
|
void TargetLowering::computeRegisterProperties() {
|
||||||
|
@ -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 ARMTargetLowering::LowerMEMCPYInline(SDOperand Chain,
|
||||||
SDOperand Dest,
|
SDOperand Dest,
|
||||||
SDOperand Source,
|
SDOperand Source,
|
||||||
|
@ -15,13 +15,13 @@
|
|||||||
#ifndef ARMISELLOWERING_H
|
#ifndef ARMISELLOWERING_H
|
||||||
#define ARMISELLOWERING_H
|
#define ARMISELLOWERING_H
|
||||||
|
|
||||||
|
#include "ARMSubtarget.h"
|
||||||
#include "llvm/Target/TargetLowering.h"
|
#include "llvm/Target/TargetLowering.h"
|
||||||
#include "llvm/CodeGen/SelectionDAG.h"
|
#include "llvm/CodeGen/SelectionDAG.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class ARMConstantPoolValue;
|
class ARMConstantPoolValue;
|
||||||
class ARMSubtarget;
|
|
||||||
|
|
||||||
namespace ARMISD {
|
namespace ARMISD {
|
||||||
// ARM Specific DAG Nodes
|
// ARM Specific DAG Nodes
|
||||||
@ -114,6 +114,11 @@ namespace llvm {
|
|||||||
std::vector<unsigned>
|
std::vector<unsigned>
|
||||||
getRegClassForInlineAsmConstraint(const std::string &Constraint,
|
getRegClassForInlineAsmConstraint(const std::string &Constraint,
|
||||||
MVT::ValueType VT) const;
|
MVT::ValueType VT) const;
|
||||||
|
|
||||||
|
virtual const TargetSubtarget* getSubtarget() {
|
||||||
|
return static_cast<const TargetSubtarget*>(Subtarget);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
|
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
|
||||||
/// make the right decision when generating code for different targets.
|
/// 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 LowerGLOBAL_OFFSET_TABLE(SDOperand Op, SelectionDAG &DAG);
|
||||||
SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
|
SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
|
||||||
SDOperand LowerBR_JT(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 LowerMEMCPYInline(SDOperand Chain, SDOperand Dest,
|
||||||
SDOperand Source, unsigned Size,
|
SDOperand Source, unsigned Size,
|
||||||
unsigned Align, SelectionDAG &DAG);
|
unsigned Align, SelectionDAG &DAG);
|
||||||
|
@ -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 X86TargetLowering::LowerMEMCPYInline(SDOperand Chain,
|
||||||
SDOperand Dest,
|
SDOperand Dest,
|
||||||
SDOperand Source,
|
SDOperand Source,
|
||||||
|
@ -386,6 +386,10 @@ namespace llvm {
|
|||||||
SDOperand Ret,
|
SDOperand Ret,
|
||||||
SelectionDAG &DAG) const;
|
SelectionDAG &DAG) const;
|
||||||
|
|
||||||
|
virtual const TargetSubtarget* getSubtarget() {
|
||||||
|
return static_cast<const TargetSubtarget*>(Subtarget);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
|
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
|
||||||
/// make the right decision when generating code for different targets.
|
/// make the right decision when generating code for different targets.
|
||||||
@ -454,10 +458,6 @@ namespace llvm {
|
|||||||
SDOperand LowerMEMCPYInline(SDOperand Dest, SDOperand Source,
|
SDOperand LowerMEMCPYInline(SDOperand Dest, SDOperand Source,
|
||||||
SDOperand Chain, unsigned Size, unsigned Align,
|
SDOperand Chain, unsigned Size, unsigned Align,
|
||||||
SelectionDAG &DAG);
|
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 LowerJumpTable(SDOperand Op, SelectionDAG &DAG);
|
||||||
SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
|
SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
|
||||||
SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG);
|
SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG);
|
||||||
|
Loading…
Reference in New Issue
Block a user