mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 12:19:53 +00:00
Implement a bunch more TargetSelectionDAGInfo infrastructure.
Move EmitTargetCodeForMemcpy, EmitTargetCodeForMemset, and EmitTargetCodeForMemmove out of TargetLowering and into SelectionDAGInfo to exercise this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103481 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
651804c3d6
commit
ff7a562751
@ -36,6 +36,7 @@ class MDNode;
|
||||
class SDNodeOrdering;
|
||||
class SDDbgValue;
|
||||
class TargetLowering;
|
||||
class TargetSelectionDAGInfo;
|
||||
|
||||
template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
|
||||
private:
|
||||
@ -131,6 +132,7 @@ void checkForCycles(const SelectionDAG *DAG);
|
||||
class SelectionDAG {
|
||||
const TargetMachine &TM;
|
||||
const TargetLowering &TLI;
|
||||
const TargetSelectionDAGInfo &TSI;
|
||||
MachineFunction *MF;
|
||||
FunctionLoweringInfo &FLI;
|
||||
LLVMContext *Context;
|
||||
@ -201,6 +203,7 @@ public:
|
||||
MachineFunction &getMachineFunction() const { return *MF; }
|
||||
const TargetMachine &getTarget() const { return TM; }
|
||||
const TargetLowering &getTargetLoweringInfo() const { return TLI; }
|
||||
const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
|
||||
FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; }
|
||||
LLVMContext *getContext() const {return Context; }
|
||||
|
||||
|
@ -1194,61 +1194,6 @@ public:
|
||||
return SDValue(); // this is here to silence compiler errors
|
||||
}
|
||||
|
||||
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
|
||||
/// memcpy. This can be used by targets to provide code sequences for cases
|
||||
/// that don't fit the target's parameters for simple loads/stores and can be
|
||||
/// more efficient than using a library call. This function can return a null
|
||||
/// SDValue if the target declines to use custom code and a different
|
||||
/// lowering strategy should be used.
|
||||
///
|
||||
/// If AlwaysInline is true, the size is constant and the target should not
|
||||
/// emit any calls and is strongly encouraged to attempt to emit inline code
|
||||
/// even if it is beyond the usual threshold because this intrinsic is being
|
||||
/// expanded in a place where calls are not feasible (e.g. within the prologue
|
||||
/// for another call). If the target chooses to decline an AlwaysInline
|
||||
/// request here, legalize will resort to using simple loads and stores.
|
||||
virtual SDValue
|
||||
EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Op1, SDValue Op2,
|
||||
SDValue Op3, unsigned Align, bool isVolatile,
|
||||
bool AlwaysInline,
|
||||
const Value *DstSV, uint64_t DstOff,
|
||||
const Value *SrcSV, uint64_t SrcOff) const {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
/// EmitTargetCodeForMemmove - Emit target-specific code that performs a
|
||||
/// memmove. This can be used by targets to provide code sequences for cases
|
||||
/// that don't fit the target's parameters for simple loads/stores and can be
|
||||
/// more efficient than using a library call. This function can return a null
|
||||
/// SDValue if the target declines to use custom code and a different
|
||||
/// lowering strategy should be used.
|
||||
virtual SDValue
|
||||
EmitTargetCodeForMemmove(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Op1, SDValue Op2,
|
||||
SDValue Op3, unsigned Align, bool isVolatile,
|
||||
const Value *DstSV, uint64_t DstOff,
|
||||
const Value *SrcSV, uint64_t SrcOff) const {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
/// EmitTargetCodeForMemset - Emit target-specific code that performs a
|
||||
/// memset. This can be used by targets to provide code sequences for cases
|
||||
/// that don't fit the target's parameters for simple stores and can be more
|
||||
/// efficient than using a library call. This function can return a null
|
||||
/// SDValue if the target declines to use custom code and a different
|
||||
/// lowering strategy should be used.
|
||||
virtual SDValue
|
||||
EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Op1, SDValue Op2,
|
||||
SDValue Op3, unsigned Align, bool isVolatile,
|
||||
const Value *DstSV, uint64_t DstOff) const {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
/// LowerOperationWrapper - This callback is invoked by the type legalizer
|
||||
/// to legalize nodes with an illegal operand type but legal result types.
|
||||
/// It replaces the LowerOperation callback in the type Legalizer.
|
||||
|
@ -16,8 +16,13 @@
|
||||
#ifndef LLVM_TARGET_TARGETSELECTIONDAGINFO_H
|
||||
#define LLVM_TARGET_TARGETSELECTIONDAGINFO_H
|
||||
|
||||
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class TargetData;
|
||||
class TargetMachine;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// TargetSelectionDAGLowering - Targets can subclass this to parameterize the
|
||||
/// SelectionDAG lowering and instruction selection process.
|
||||
@ -26,9 +31,69 @@ class TargetSelectionDAGInfo {
|
||||
TargetSelectionDAGInfo(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
|
||||
void operator=(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
|
||||
|
||||
const TargetData *TD;
|
||||
|
||||
protected:
|
||||
const TargetData *getTargetData() const { return TD; }
|
||||
|
||||
public:
|
||||
TargetSelectionDAGInfo();
|
||||
explicit TargetSelectionDAGInfo(const TargetMachine &TM);
|
||||
virtual ~TargetSelectionDAGInfo();
|
||||
|
||||
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
|
||||
/// memcpy. This can be used by targets to provide code sequences for cases
|
||||
/// that don't fit the target's parameters for simple loads/stores and can be
|
||||
/// more efficient than using a library call. This function can return a null
|
||||
/// SDValue if the target declines to use custom code and a different
|
||||
/// lowering strategy should be used.
|
||||
///
|
||||
/// If AlwaysInline is true, the size is constant and the target should not
|
||||
/// emit any calls and is strongly encouraged to attempt to emit inline code
|
||||
/// even if it is beyond the usual threshold because this intrinsic is being
|
||||
/// expanded in a place where calls are not feasible (e.g. within the prologue
|
||||
/// for another call). If the target chooses to decline an AlwaysInline
|
||||
/// request here, legalize will resort to using simple loads and stores.
|
||||
virtual SDValue
|
||||
EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Op1, SDValue Op2,
|
||||
SDValue Op3, unsigned Align, bool isVolatile,
|
||||
bool AlwaysInline,
|
||||
const Value *DstSV, uint64_t DstOff,
|
||||
const Value *SrcSV, uint64_t SrcOff) const {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
/// EmitTargetCodeForMemmove - Emit target-specific code that performs a
|
||||
/// memmove. This can be used by targets to provide code sequences for cases
|
||||
/// that don't fit the target's parameters for simple loads/stores and can be
|
||||
/// more efficient than using a library call. This function can return a null
|
||||
/// SDValue if the target declines to use custom code and a different
|
||||
/// lowering strategy should be used.
|
||||
virtual SDValue
|
||||
EmitTargetCodeForMemmove(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Op1, SDValue Op2,
|
||||
SDValue Op3, unsigned Align, bool isVolatile,
|
||||
const Value *DstSV, uint64_t DstOff,
|
||||
const Value *SrcSV, uint64_t SrcOff) const {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
/// EmitTargetCodeForMemset - Emit target-specific code that performs a
|
||||
/// memset. This can be used by targets to provide code sequences for cases
|
||||
/// that don't fit the target's parameters for simple stores and can be more
|
||||
/// efficient than using a library call. This function can return a null
|
||||
/// SDValue if the target declines to use custom code and a different
|
||||
/// lowering strategy should be used.
|
||||
virtual SDValue
|
||||
EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Op1, SDValue Op2,
|
||||
SDValue Op3, unsigned Align, bool isVolatile,
|
||||
const Value *DstSV, uint64_t DstOff) const {
|
||||
return SDValue();
|
||||
}
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetFrameInfo.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetSelectionDAGInfo.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetIntrinsicInfo.h"
|
||||
@ -790,7 +791,8 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {
|
||||
|
||||
// EntryNode could meaningfully have debug info if we can find it...
|
||||
SelectionDAG::SelectionDAG(const TargetMachine &tm, FunctionLoweringInfo &fli)
|
||||
: TM(tm), TLI(*tm.getTargetLowering()), FLI(fli),
|
||||
: TM(tm), TLI(*tm.getTargetLowering()), TSI(*tm.getSelectionDAGInfo()),
|
||||
FLI(fli),
|
||||
EntryNode(ISD::EntryToken, DebugLoc(), getVTList(MVT::Other)),
|
||||
Root(getEntryNode()), Ordering(0) {
|
||||
AllNodes.push_back(&EntryNode);
|
||||
@ -3536,7 +3538,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
|
||||
// Then check to see if we should lower the memcpy with target-specific
|
||||
// code. If the target chooses to do this, this is the next best.
|
||||
SDValue Result =
|
||||
TLI.EmitTargetCodeForMemcpy(*this, dl, Chain, Dst, Src, Size, Align,
|
||||
TSI.EmitTargetCodeForMemcpy(*this, dl, Chain, Dst, Src, Size, Align,
|
||||
isVol, AlwaysInline,
|
||||
DstSV, DstSVOff, SrcSV, SrcSVOff);
|
||||
if (Result.getNode())
|
||||
@ -3601,7 +3603,7 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
|
||||
// Then check to see if we should lower the memmove with target-specific
|
||||
// code. If the target chooses to do this, this is the next best.
|
||||
SDValue Result =
|
||||
TLI.EmitTargetCodeForMemmove(*this, dl, Chain, Dst, Src, Size, Align, isVol,
|
||||
TSI.EmitTargetCodeForMemmove(*this, dl, Chain, Dst, Src, Size, Align, isVol,
|
||||
DstSV, DstSVOff, SrcSV, SrcSVOff);
|
||||
if (Result.getNode())
|
||||
return Result;
|
||||
@ -3652,7 +3654,7 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
|
||||
// Then check to see if we should lower the memset with target-specific
|
||||
// code. If the target chooses to do this, this is the next best.
|
||||
SDValue Result =
|
||||
TLI.EmitTargetCodeForMemset(*this, dl, Chain, Dst, Src, Size, Align, isVol,
|
||||
TSI.EmitTargetCodeForMemset(*this, dl, Chain, Dst, Src, Size, Align, isVol,
|
||||
DstSV, DstSVOff);
|
||||
if (Result.getNode())
|
||||
return Result;
|
||||
|
@ -12,9 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Target/TargetSelectionDAGInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
TargetSelectionDAGInfo::TargetSelectionDAGInfo() {
|
||||
TargetSelectionDAGInfo::TargetSelectionDAGInfo(const TargetMachine &TM)
|
||||
: TD(TM.getTargetData()) {
|
||||
}
|
||||
|
||||
TargetSelectionDAGInfo::~TargetSelectionDAGInfo() {
|
||||
|
@ -2124,116 +2124,6 @@ SDValue ARMTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
|
||||
return FrameAddr;
|
||||
}
|
||||
|
||||
SDValue
|
||||
ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile, bool AlwaysInline,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff,
|
||||
const Value *SrcSV,
|
||||
uint64_t SrcSVOff) const {
|
||||
// Do repeated 4-byte loads and stores. To be improved.
|
||||
// This requires 4-byte alignment.
|
||||
if ((Align & 3) != 0)
|
||||
return SDValue();
|
||||
// This requires the copy size to be a constant, preferrably
|
||||
// within a subtarget-specific limit.
|
||||
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
|
||||
if (!ConstantSize)
|
||||
return SDValue();
|
||||
uint64_t SizeVal = ConstantSize->getZExtValue();
|
||||
if (!AlwaysInline && SizeVal > getSubtarget()->getMaxInlineSizeThreshold())
|
||||
return SDValue();
|
||||
|
||||
unsigned BytesLeft = SizeVal & 3;
|
||||
unsigned NumMemOps = SizeVal >> 2;
|
||||
unsigned EmittedNumMemOps = 0;
|
||||
EVT VT = MVT::i32;
|
||||
unsigned VTSize = 4;
|
||||
unsigned i = 0;
|
||||
const unsigned MAX_LOADS_IN_LDM = 6;
|
||||
SDValue TFOps[MAX_LOADS_IN_LDM];
|
||||
SDValue Loads[MAX_LOADS_IN_LDM];
|
||||
uint64_t SrcOff = 0, DstOff = 0;
|
||||
|
||||
// Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the
|
||||
// same number of stores. The loads and stores will get combined into
|
||||
// ldm/stm later on.
|
||||
while (EmittedNumMemOps < NumMemOps) {
|
||||
for (i = 0;
|
||||
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
|
||||
Loads[i] = DAG.getLoad(VT, dl, Chain,
|
||||
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
|
||||
DAG.getConstant(SrcOff, MVT::i32)),
|
||||
SrcSV, SrcSVOff + SrcOff, isVolatile, false, 0);
|
||||
TFOps[i] = Loads[i].getValue(1);
|
||||
SrcOff += VTSize;
|
||||
}
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
|
||||
|
||||
for (i = 0;
|
||||
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
|
||||
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
|
||||
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
|
||||
DAG.getConstant(DstOff, MVT::i32)),
|
||||
DstSV, DstSVOff + DstOff, isVolatile, false, 0);
|
||||
DstOff += VTSize;
|
||||
}
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
|
||||
|
||||
EmittedNumMemOps += i;
|
||||
}
|
||||
|
||||
if (BytesLeft == 0)
|
||||
return Chain;
|
||||
|
||||
// Issue loads / stores for the trailing (1 - 3) bytes.
|
||||
unsigned BytesLeftSave = BytesLeft;
|
||||
i = 0;
|
||||
while (BytesLeft) {
|
||||
if (BytesLeft >= 2) {
|
||||
VT = MVT::i16;
|
||||
VTSize = 2;
|
||||
} else {
|
||||
VT = MVT::i8;
|
||||
VTSize = 1;
|
||||
}
|
||||
|
||||
Loads[i] = DAG.getLoad(VT, dl, Chain,
|
||||
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
|
||||
DAG.getConstant(SrcOff, MVT::i32)),
|
||||
SrcSV, SrcSVOff + SrcOff, false, false, 0);
|
||||
TFOps[i] = Loads[i].getValue(1);
|
||||
++i;
|
||||
SrcOff += VTSize;
|
||||
BytesLeft -= VTSize;
|
||||
}
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
|
||||
|
||||
i = 0;
|
||||
BytesLeft = BytesLeftSave;
|
||||
while (BytesLeft) {
|
||||
if (BytesLeft >= 2) {
|
||||
VT = MVT::i16;
|
||||
VTSize = 2;
|
||||
} else {
|
||||
VT = MVT::i8;
|
||||
VTSize = 1;
|
||||
}
|
||||
|
||||
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
|
||||
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
|
||||
DAG.getConstant(DstOff, MVT::i32)),
|
||||
DstSV, DstSVOff + DstOff, false, false, 0);
|
||||
++i;
|
||||
DstOff += VTSize;
|
||||
BytesLeft -= VTSize;
|
||||
}
|
||||
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
|
||||
}
|
||||
|
||||
/// ExpandBIT_CONVERT - If the target supports VFP, this function is called to
|
||||
/// expand a bit convert where either the source or destination type is i64 to
|
||||
/// use a VMOVDRR or VMOVRRD node. This should not be done when the non-i64
|
||||
|
@ -301,15 +301,6 @@ namespace llvm {
|
||||
SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile, bool AlwaysInline,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff,
|
||||
const Value *SrcSV,
|
||||
uint64_t SrcSVOff) const;
|
||||
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
|
@ -12,11 +12,123 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "arm-selectiondag-info"
|
||||
#include "ARMSelectionDAGInfo.h"
|
||||
#include "ARMTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
ARMSelectionDAGInfo::ARMSelectionDAGInfo() {
|
||||
ARMSelectionDAGInfo::ARMSelectionDAGInfo(const TargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM),
|
||||
Subtarget(&TM.getSubtarget<ARMSubtarget>()) {
|
||||
}
|
||||
|
||||
ARMSelectionDAGInfo::~ARMSelectionDAGInfo() {
|
||||
}
|
||||
|
||||
SDValue
|
||||
ARMSelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile, bool AlwaysInline,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff,
|
||||
const Value *SrcSV,
|
||||
uint64_t SrcSVOff) const {
|
||||
// Do repeated 4-byte loads and stores. To be improved.
|
||||
// This requires 4-byte alignment.
|
||||
if ((Align & 3) != 0)
|
||||
return SDValue();
|
||||
// This requires the copy size to be a constant, preferrably
|
||||
// within a subtarget-specific limit.
|
||||
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
|
||||
if (!ConstantSize)
|
||||
return SDValue();
|
||||
uint64_t SizeVal = ConstantSize->getZExtValue();
|
||||
if (!AlwaysInline && SizeVal > Subtarget->getMaxInlineSizeThreshold())
|
||||
return SDValue();
|
||||
|
||||
unsigned BytesLeft = SizeVal & 3;
|
||||
unsigned NumMemOps = SizeVal >> 2;
|
||||
unsigned EmittedNumMemOps = 0;
|
||||
EVT VT = MVT::i32;
|
||||
unsigned VTSize = 4;
|
||||
unsigned i = 0;
|
||||
const unsigned MAX_LOADS_IN_LDM = 6;
|
||||
SDValue TFOps[MAX_LOADS_IN_LDM];
|
||||
SDValue Loads[MAX_LOADS_IN_LDM];
|
||||
uint64_t SrcOff = 0, DstOff = 0;
|
||||
|
||||
// Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the
|
||||
// same number of stores. The loads and stores will get combined into
|
||||
// ldm/stm later on.
|
||||
while (EmittedNumMemOps < NumMemOps) {
|
||||
for (i = 0;
|
||||
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
|
||||
Loads[i] = DAG.getLoad(VT, dl, Chain,
|
||||
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
|
||||
DAG.getConstant(SrcOff, MVT::i32)),
|
||||
SrcSV, SrcSVOff + SrcOff, isVolatile, false, 0);
|
||||
TFOps[i] = Loads[i].getValue(1);
|
||||
SrcOff += VTSize;
|
||||
}
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
|
||||
|
||||
for (i = 0;
|
||||
i < MAX_LOADS_IN_LDM && EmittedNumMemOps + i < NumMemOps; ++i) {
|
||||
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
|
||||
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
|
||||
DAG.getConstant(DstOff, MVT::i32)),
|
||||
DstSV, DstSVOff + DstOff, isVolatile, false, 0);
|
||||
DstOff += VTSize;
|
||||
}
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
|
||||
|
||||
EmittedNumMemOps += i;
|
||||
}
|
||||
|
||||
if (BytesLeft == 0)
|
||||
return Chain;
|
||||
|
||||
// Issue loads / stores for the trailing (1 - 3) bytes.
|
||||
unsigned BytesLeftSave = BytesLeft;
|
||||
i = 0;
|
||||
while (BytesLeft) {
|
||||
if (BytesLeft >= 2) {
|
||||
VT = MVT::i16;
|
||||
VTSize = 2;
|
||||
} else {
|
||||
VT = MVT::i8;
|
||||
VTSize = 1;
|
||||
}
|
||||
|
||||
Loads[i] = DAG.getLoad(VT, dl, Chain,
|
||||
DAG.getNode(ISD::ADD, dl, MVT::i32, Src,
|
||||
DAG.getConstant(SrcOff, MVT::i32)),
|
||||
SrcSV, SrcSVOff + SrcOff, false, false, 0);
|
||||
TFOps[i] = Loads[i].getValue(1);
|
||||
++i;
|
||||
SrcOff += VTSize;
|
||||
BytesLeft -= VTSize;
|
||||
}
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
|
||||
|
||||
i = 0;
|
||||
BytesLeft = BytesLeftSave;
|
||||
while (BytesLeft) {
|
||||
if (BytesLeft >= 2) {
|
||||
VT = MVT::i16;
|
||||
VTSize = 2;
|
||||
} else {
|
||||
VT = MVT::i8;
|
||||
VTSize = 1;
|
||||
}
|
||||
|
||||
TFOps[i] = DAG.getStore(Chain, dl, Loads[i],
|
||||
DAG.getNode(ISD::ADD, dl, MVT::i32, Dst,
|
||||
DAG.getConstant(DstOff, MVT::i32)),
|
||||
DstSV, DstSVOff + DstOff, false, false, 0);
|
||||
++i;
|
||||
DstOff += VTSize;
|
||||
BytesLeft -= VTSize;
|
||||
}
|
||||
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &TFOps[0], i);
|
||||
}
|
||||
|
@ -19,9 +19,24 @@
|
||||
namespace llvm {
|
||||
|
||||
class ARMSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
|
||||
/// make the right decision when generating code for different targets.
|
||||
const ARMSubtarget *Subtarget;
|
||||
|
||||
public:
|
||||
ARMSelectionDAGInfo();
|
||||
explicit ARMSelectionDAGInfo(const TargetMachine &TM);
|
||||
~ARMSelectionDAGInfo();
|
||||
|
||||
virtual
|
||||
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile, bool AlwaysInline,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff,
|
||||
const Value *SrcSV,
|
||||
uint64_t SrcSVOff) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -62,7 +62,8 @@ ARMTargetMachine::ARMTargetMachine(const Target &T, const std::string &TT,
|
||||
DataLayout(Subtarget.isAPCS_ABI() ?
|
||||
std::string("e-p:32:32-f64:32:32-i64:32:32-n32") :
|
||||
std::string("e-p:32:32-f64:64:64-i64:64:64-n32")),
|
||||
TLInfo(*this) {
|
||||
TLInfo(*this),
|
||||
TSInfo(*this) {
|
||||
}
|
||||
|
||||
ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
|
||||
@ -76,7 +77,8 @@ ThumbTargetMachine::ThumbTargetMachine(const Target &T, const std::string &TT,
|
||||
"i16:16:32-i8:8:32-i1:8:32-a:0:32-n32") :
|
||||
std::string("e-p:32:32-f64:64:64-i64:64:64-"
|
||||
"i16:16:32-i8:8:32-i1:8:32-a:0:32-n32")),
|
||||
TLInfo(*this) {
|
||||
TLInfo(*this),
|
||||
TSInfo(*this) {
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ARMJITInfo.h"
|
||||
#include "ARMSubtarget.h"
|
||||
#include "ARMISelLowering.h"
|
||||
#include "ARMSelectionDAGInfo.h"
|
||||
#include "Thumb1InstrInfo.h"
|
||||
#include "Thumb2InstrInfo.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
@ -63,6 +64,7 @@ class ARMTargetMachine : public ARMBaseTargetMachine {
|
||||
ARMInstrInfo InstrInfo;
|
||||
const TargetData DataLayout; // Calculates type size & alignment
|
||||
ARMTargetLowering TLInfo;
|
||||
ARMSelectionDAGInfo TSInfo;
|
||||
public:
|
||||
ARMTargetMachine(const Target &T, const std::string &TT,
|
||||
const std::string &FS);
|
||||
@ -75,6 +77,10 @@ public:
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
virtual const ARMSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
virtual const ARMInstrInfo *getInstrInfo() const { return &InstrInfo; }
|
||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
||||
};
|
||||
@ -88,6 +94,7 @@ class ThumbTargetMachine : public ARMBaseTargetMachine {
|
||||
OwningPtr<ARMBaseInstrInfo> InstrInfo;
|
||||
const TargetData DataLayout; // Calculates type size & alignment
|
||||
ARMTargetLowering TLInfo;
|
||||
ARMSelectionDAGInfo TSInfo;
|
||||
public:
|
||||
ThumbTargetMachine(const Target &T, const std::string &TT,
|
||||
const std::string &FS);
|
||||
@ -101,6 +108,10 @@ public:
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
virtual const ARMSelectionDAGInfo *getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
/// returns either Thumb1InstrInfo or Thumb2InstrInfo
|
||||
virtual const ARMBaseInstrInfo *getInstrInfo() const {
|
||||
return InstrInfo.get();
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "alpha-selectiondag-info"
|
||||
#include "AlphaSelectionDAGInfo.h"
|
||||
#include "AlphaTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
AlphaSelectionDAGInfo::AlphaSelectionDAGInfo() {
|
||||
AlphaSelectionDAGInfo::AlphaSelectionDAGInfo(const AlphaTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
AlphaSelectionDAGInfo::~AlphaSelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AlphaTargetMachine;
|
||||
|
||||
class AlphaSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
AlphaSelectionDAGInfo();
|
||||
explicit AlphaSelectionDAGInfo(const AlphaTargetMachine &TM);
|
||||
~AlphaSelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -32,7 +32,8 @@ AlphaTargetMachine::AlphaTargetMachine(const Target &T, const std::string &TT,
|
||||
FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
|
||||
JITInfo(*this),
|
||||
Subtarget(TT, FS),
|
||||
TLInfo(*this) {
|
||||
TLInfo(*this),
|
||||
TSInfo(*this) {
|
||||
setRelocationModel(Reloc::PIC_);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "AlphaInstrInfo.h"
|
||||
#include "AlphaJITInfo.h"
|
||||
#include "AlphaISelLowering.h"
|
||||
#include "AlphaSelectionDAGInfo.h"
|
||||
#include "AlphaSubtarget.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -33,6 +34,7 @@ class AlphaTargetMachine : public LLVMTargetMachine {
|
||||
AlphaJITInfo JITInfo;
|
||||
AlphaSubtarget Subtarget;
|
||||
AlphaTargetLowering TLInfo;
|
||||
AlphaSelectionDAGInfo TSInfo;
|
||||
|
||||
public:
|
||||
AlphaTargetMachine(const Target &T, const std::string &TT,
|
||||
@ -47,6 +49,9 @@ public:
|
||||
virtual const AlphaTargetLowering* getTargetLowering() const {
|
||||
return &TLInfo;
|
||||
}
|
||||
virtual const AlphaSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
||||
virtual AlphaJITInfo* getJITInfo() {
|
||||
return &JITInfo;
|
||||
|
@ -12,10 +12,12 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "blackfin-selectiondag-info"
|
||||
#include "BlackfinSelectionDAGInfo.h"
|
||||
#include "BlackfinTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
BlackfinSelectionDAGInfo::BlackfinSelectionDAGInfo() {
|
||||
BlackfinSelectionDAGInfo::BlackfinSelectionDAGInfo(
|
||||
const BlackfinTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
BlackfinSelectionDAGInfo::~BlackfinSelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BlackfinTargetMachine;
|
||||
|
||||
class BlackfinSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
BlackfinSelectionDAGInfo();
|
||||
explicit BlackfinSelectionDAGInfo(const BlackfinTargetMachine &TM);
|
||||
~BlackfinSelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,7 @@ BlackfinTargetMachine::BlackfinTargetMachine(const Target &T,
|
||||
DataLayout("e-p:32:32-i64:32-f64:32-n32"),
|
||||
Subtarget(TT, FS),
|
||||
TLInfo(*this),
|
||||
TSInfo(*this),
|
||||
InstrInfo(Subtarget),
|
||||
FrameInfo(TargetFrameInfo::StackGrowsDown, 4, 0) {
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "BlackfinInstrInfo.h"
|
||||
#include "BlackfinSubtarget.h"
|
||||
#include "BlackfinISelLowering.h"
|
||||
#include "BlackfinSelectionDAGInfo.h"
|
||||
#include "BlackfinIntrinsicInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -28,6 +29,7 @@ namespace llvm {
|
||||
const TargetData DataLayout;
|
||||
BlackfinSubtarget Subtarget;
|
||||
BlackfinTargetLowering TLInfo;
|
||||
BlackfinSelectionDAGInfo TSInfo;
|
||||
BlackfinInstrInfo InstrInfo;
|
||||
TargetFrameInfo FrameInfo;
|
||||
BlackfinIntrinsicInfo IntrinsicInfo;
|
||||
@ -46,6 +48,9 @@ namespace llvm {
|
||||
virtual const BlackfinTargetLowering* getTargetLowering() const {
|
||||
return &TLInfo;
|
||||
}
|
||||
virtual const BlackfinSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
||||
virtual bool addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "cellspu-selectiondag-info"
|
||||
#include "SPUSelectionDAGInfo.h"
|
||||
#include "SPUTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
SPUSelectionDAGInfo::SPUSelectionDAGInfo() {
|
||||
SPUSelectionDAGInfo::SPUSelectionDAGInfo(const SPUTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
SPUSelectionDAGInfo::~SPUSelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SPUTargetMachine;
|
||||
|
||||
class SPUSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
SPUSelectionDAGInfo();
|
||||
explicit SPUSelectionDAGInfo(const SPUTargetMachine &TM);
|
||||
~SPUSelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -42,6 +42,7 @@ SPUTargetMachine::SPUTargetMachine(const Target &T, const std::string &TT,
|
||||
InstrInfo(*this),
|
||||
FrameInfo(*this),
|
||||
TLInfo(*this),
|
||||
TSInfo(*this),
|
||||
InstrItins(Subtarget.getInstrItineraryData()) {
|
||||
// For the time being, use static relocations, since there's really no
|
||||
// support for PIC yet.
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "SPUSubtarget.h"
|
||||
#include "SPUInstrInfo.h"
|
||||
#include "SPUISelLowering.h"
|
||||
#include "SPUSelectionDAGInfo.h"
|
||||
#include "SPUFrameInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -34,6 +35,7 @@ class SPUTargetMachine : public LLVMTargetMachine {
|
||||
SPUInstrInfo InstrInfo;
|
||||
SPUFrameInfo FrameInfo;
|
||||
SPUTargetLowering TLInfo;
|
||||
SPUSelectionDAGInfo TSInfo;
|
||||
InstrItineraryData InstrItins;
|
||||
public:
|
||||
SPUTargetMachine(const Target &T, const std::string &TT,
|
||||
@ -61,6 +63,10 @@ public:
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
virtual const SPUSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
virtual const SPURegisterInfo *getRegisterInfo() const {
|
||||
return &InstrInfo.getRegisterInfo();
|
||||
}
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "mblaze-selectiondag-info"
|
||||
#include "MBlazeSelectionDAGInfo.h"
|
||||
#include "MBlazeTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
MBlazeSelectionDAGInfo::MBlazeSelectionDAGInfo() {
|
||||
MBlazeSelectionDAGInfo::MBlazeSelectionDAGInfo(const MBlazeTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
MBlazeSelectionDAGInfo::~MBlazeSelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MBlazeTargetMachine;
|
||||
|
||||
class MBlazeSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
MBlazeSelectionDAGInfo();
|
||||
explicit MBlazeSelectionDAGInfo(const MBlazeTargetMachine &TM);
|
||||
~MBlazeSelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@ MBlazeTargetMachine(const Target &T, const std::string &TT,
|
||||
"f64:32:32-v64:32:32-v128:32:32-n32"),
|
||||
InstrInfo(*this),
|
||||
FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0),
|
||||
TLInfo(*this) {
|
||||
TLInfo(*this), TSInfo(*this) {
|
||||
if (getRelocationModel() == Reloc::Default) {
|
||||
setRelocationModel(Reloc::Static);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "MBlazeSubtarget.h"
|
||||
#include "MBlazeInstrInfo.h"
|
||||
#include "MBlazeISelLowering.h"
|
||||
#include "MBlazeSelectionDAGInfo.h"
|
||||
#include "MBlazeIntrinsicInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -31,6 +32,7 @@ namespace llvm {
|
||||
MBlazeInstrInfo InstrInfo;
|
||||
TargetFrameInfo FrameInfo;
|
||||
MBlazeTargetLowering TLInfo;
|
||||
MBlazeSelectionDAGInfo TSInfo;
|
||||
MBlazeIntrinsicInfo IntrinsicInfo;
|
||||
public:
|
||||
MBlazeTargetMachine(const Target &T, const std::string &TT,
|
||||
@ -54,6 +56,9 @@ namespace llvm {
|
||||
virtual const MBlazeTargetLowering *getTargetLowering() const
|
||||
{ return &TLInfo; }
|
||||
|
||||
virtual const MBlazeSelectionDAGInfo* getSelectionDAGInfo() const
|
||||
{ return &TSInfo; }
|
||||
|
||||
const TargetIntrinsicInfo *getIntrinsicInfo() const
|
||||
{ return &IntrinsicInfo; }
|
||||
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "msp430-selectiondag-info"
|
||||
#include "MSP430SelectionDAGInfo.h"
|
||||
#include "MSP430TargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
MSP430SelectionDAGInfo::MSP430SelectionDAGInfo() {
|
||||
MSP430SelectionDAGInfo::MSP430SelectionDAGInfo(const MSP430TargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
MSP430SelectionDAGInfo::~MSP430SelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MSP430TargetMachine;
|
||||
|
||||
class MSP430SelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
MSP430SelectionDAGInfo();
|
||||
explicit MSP430SelectionDAGInfo(const MSP430TargetMachine &TM);
|
||||
~MSP430SelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,7 @@ MSP430TargetMachine::MSP430TargetMachine(const Target &T,
|
||||
Subtarget(TT, FS),
|
||||
// FIXME: Check TargetData string.
|
||||
DataLayout("e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"),
|
||||
InstrInfo(*this), TLInfo(*this),
|
||||
InstrInfo(*this), TLInfo(*this), TSInfo(*this),
|
||||
FrameInfo(TargetFrameInfo::StackGrowsDown, 2, -2) { }
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "MSP430InstrInfo.h"
|
||||
#include "MSP430ISelLowering.h"
|
||||
#include "MSP430SelectionDAGInfo.h"
|
||||
#include "MSP430RegisterInfo.h"
|
||||
#include "MSP430Subtarget.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -32,6 +33,7 @@ class MSP430TargetMachine : public LLVMTargetMachine {
|
||||
const TargetData DataLayout; // Calculates type size & alignment
|
||||
MSP430InstrInfo InstrInfo;
|
||||
MSP430TargetLowering TLInfo;
|
||||
MSP430SelectionDAGInfo TSInfo;
|
||||
|
||||
// MSP430 does not have any call stack frame, therefore not having
|
||||
// any MSP430 specific FrameInfo class.
|
||||
@ -54,6 +56,10 @@ public:
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
virtual const MSP430SelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
|
||||
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
|
||||
}; // MSP430TargetMachine.
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "mips-selectiondag-info"
|
||||
#include "MipsSelectionDAGInfo.h"
|
||||
#include "MipsTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
MipsSelectionDAGInfo::MipsSelectionDAGInfo() {
|
||||
MipsSelectionDAGInfo::MipsSelectionDAGInfo(const MipsTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
MipsSelectionDAGInfo::~MipsSelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MipsTargetMachine;
|
||||
|
||||
class MipsSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
MipsSelectionDAGInfo();
|
||||
explicit MipsSelectionDAGInfo(const MipsTargetMachine &TM);
|
||||
~MipsSelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -42,7 +42,7 @@ MipsTargetMachine(const Target &T, const std::string &TT, const std::string &FS,
|
||||
std::string("E-p:32:32:32-i8:8:32-i16:16:32-n32")),
|
||||
InstrInfo(*this),
|
||||
FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0),
|
||||
TLInfo(*this) {
|
||||
TLInfo(*this), TSInfo(*this) {
|
||||
// Abicall enables PIC by default
|
||||
if (getRelocationModel() == Reloc::Default) {
|
||||
if (Subtarget.isABI_O32())
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "MipsSubtarget.h"
|
||||
#include "MipsInstrInfo.h"
|
||||
#include "MipsISelLowering.h"
|
||||
#include "MipsSelectionDAGInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetFrameInfo.h"
|
||||
@ -30,6 +31,7 @@ namespace llvm {
|
||||
MipsInstrInfo InstrInfo;
|
||||
TargetFrameInfo FrameInfo;
|
||||
MipsTargetLowering TLInfo;
|
||||
MipsSelectionDAGInfo TSInfo;
|
||||
public:
|
||||
MipsTargetMachine(const Target &T, const std::string &TT,
|
||||
const std::string &FS, bool isLittle);
|
||||
@ -51,6 +53,10 @@ namespace llvm {
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
virtual const MipsSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
// Pass Pipeline Configuration
|
||||
virtual bool addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "pic16-selectiondag-info"
|
||||
#include "PIC16SelectionDAGInfo.h"
|
||||
#include "PIC16TargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
PIC16SelectionDAGInfo::PIC16SelectionDAGInfo() {
|
||||
PIC16SelectionDAGInfo::PIC16SelectionDAGInfo(const PIC16TargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
PIC16SelectionDAGInfo::~PIC16SelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class PIC16TargetMachine;
|
||||
|
||||
class PIC16SelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
PIC16SelectionDAGInfo();
|
||||
explicit PIC16SelectionDAGInfo(const PIC16TargetMachine &TM);
|
||||
~PIC16SelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,7 @@ PIC16TargetMachine::PIC16TargetMachine(const Target &T, const std::string &TT,
|
||||
: LLVMTargetMachine(T, TT),
|
||||
Subtarget(TT, FS, Trad),
|
||||
DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-n8"),
|
||||
InstrInfo(*this), TLInfo(*this),
|
||||
InstrInfo(*this), TLInfo(*this), TSInfo(*this),
|
||||
FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0) { }
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "PIC16InstrInfo.h"
|
||||
#include "PIC16ISelLowering.h"
|
||||
#include "PIC16SelectionDAGInfo.h"
|
||||
#include "PIC16RegisterInfo.h"
|
||||
#include "PIC16Subtarget.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -32,6 +33,7 @@ class PIC16TargetMachine : public LLVMTargetMachine {
|
||||
const TargetData DataLayout; // Calculates type size & alignment
|
||||
PIC16InstrInfo InstrInfo;
|
||||
PIC16TargetLowering TLInfo;
|
||||
PIC16SelectionDAGInfo TSInfo;
|
||||
|
||||
// PIC16 does not have any call stack frame, therefore not having
|
||||
// any PIC16 specific FrameInfo class.
|
||||
@ -54,6 +56,10 @@ public:
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
virtual const PIC16SelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
virtual bool addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "powerpc-selectiondag-info"
|
||||
#include "PPCSelectionDAGInfo.h"
|
||||
#include "PPCTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
PPCSelectionDAGInfo::PPCSelectionDAGInfo() {
|
||||
PPCSelectionDAGInfo::PPCSelectionDAGInfo(const PPCTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
PPCSelectionDAGInfo::~PPCSelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class PPCTargetMachine;
|
||||
|
||||
class PPCSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
PPCSelectionDAGInfo();
|
||||
explicit PPCSelectionDAGInfo(const PPCTargetMachine &TM);
|
||||
~PPCSelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -44,7 +44,8 @@ PPCTargetMachine::PPCTargetMachine(const Target &T, const std::string &TT,
|
||||
: LLVMTargetMachine(T, TT),
|
||||
Subtarget(TT, FS, is64Bit),
|
||||
DataLayout(Subtarget.getTargetDataString()), InstrInfo(*this),
|
||||
FrameInfo(*this, is64Bit), JITInfo(*this, is64Bit), TLInfo(*this),
|
||||
FrameInfo(*this, is64Bit), JITInfo(*this, is64Bit),
|
||||
TLInfo(*this), TSInfo(*this),
|
||||
InstrItins(Subtarget.getInstrItineraryData()) {
|
||||
|
||||
if (getRelocationModel() == Reloc::Default) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "PPCJITInfo.h"
|
||||
#include "PPCInstrInfo.h"
|
||||
#include "PPCISelLowering.h"
|
||||
#include "PPCSelectionDAGInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
|
||||
@ -35,6 +36,7 @@ class PPCTargetMachine : public LLVMTargetMachine {
|
||||
PPCFrameInfo FrameInfo;
|
||||
PPCJITInfo JITInfo;
|
||||
PPCTargetLowering TLInfo;
|
||||
PPCSelectionDAGInfo TSInfo;
|
||||
InstrItineraryData InstrItins;
|
||||
|
||||
public:
|
||||
@ -47,6 +49,9 @@ public:
|
||||
virtual const PPCTargetLowering *getTargetLowering() const {
|
||||
return &TLInfo;
|
||||
}
|
||||
virtual const PPCSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
virtual const PPCRegisterInfo *getRegisterInfo() const {
|
||||
return &InstrInfo.getRegisterInfo();
|
||||
}
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "sparc-selectiondag-info"
|
||||
#include "SparcSelectionDAGInfo.h"
|
||||
#include "SparcTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
SparcSelectionDAGInfo::SparcSelectionDAGInfo() {
|
||||
SparcSelectionDAGInfo::SparcSelectionDAGInfo(const SparcTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
SparcSelectionDAGInfo::~SparcSelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SparcTargetMachine;
|
||||
|
||||
class SparcSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
SparcSelectionDAGInfo();
|
||||
explicit SparcSelectionDAGInfo(const SparcTargetMachine &TM);
|
||||
~SparcSelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -34,7 +34,7 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, const std::string &TT,
|
||||
: LLVMTargetMachine(T, TT),
|
||||
Subtarget(TT, FS, is64bit),
|
||||
DataLayout(Subtarget.getDataLayout()),
|
||||
TLInfo(*this), InstrInfo(Subtarget),
|
||||
TLInfo(*this), TSInfo(*this), InstrInfo(Subtarget),
|
||||
FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "SparcInstrInfo.h"
|
||||
#include "SparcSubtarget.h"
|
||||
#include "SparcISelLowering.h"
|
||||
#include "SparcSelectionDAGInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -27,6 +28,7 @@ class SparcTargetMachine : public LLVMTargetMachine {
|
||||
SparcSubtarget Subtarget;
|
||||
const TargetData DataLayout; // Calculates type size & alignment
|
||||
SparcTargetLowering TLInfo;
|
||||
SparcSelectionDAGInfo TSInfo;
|
||||
SparcInstrInfo InstrInfo;
|
||||
TargetFrameInfo FrameInfo;
|
||||
public:
|
||||
@ -42,6 +44,9 @@ public:
|
||||
virtual const SparcTargetLowering* getTargetLowering() const {
|
||||
return &TLInfo;
|
||||
}
|
||||
virtual const SparcSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
||||
|
||||
// Pass Pipeline Configuration
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "systemz-selectiondag-info"
|
||||
#include "SystemZSelectionDAGInfo.h"
|
||||
#include "SystemZTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
SystemZSelectionDAGInfo::SystemZSelectionDAGInfo() {
|
||||
SystemZSelectionDAGInfo::SystemZSelectionDAGInfo(const SystemZTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
SystemZSelectionDAGInfo::~SystemZSelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SystemZTargetMachine;
|
||||
|
||||
class SystemZSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
SystemZSelectionDAGInfo();
|
||||
explicit SystemZSelectionDAGInfo(const SystemZTargetMachine &TM);
|
||||
~SystemZSelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -29,7 +29,7 @@ SystemZTargetMachine::SystemZTargetMachine(const Target &T,
|
||||
Subtarget(TT, FS),
|
||||
DataLayout("E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32"
|
||||
"-f64:64:64-f128:128:128-a0:16:16-n32:64"),
|
||||
InstrInfo(*this), TLInfo(*this),
|
||||
InstrInfo(*this), TLInfo(*this), TSInfo(*this),
|
||||
FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160) {
|
||||
|
||||
if (getRelocationModel() == Reloc::Default)
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "SystemZInstrInfo.h"
|
||||
#include "SystemZISelLowering.h"
|
||||
#include "SystemZSelectionDAGInfo.h"
|
||||
#include "SystemZRegisterInfo.h"
|
||||
#include "SystemZSubtarget.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -32,6 +33,7 @@ class SystemZTargetMachine : public LLVMTargetMachine {
|
||||
const TargetData DataLayout; // Calculates type size & alignment
|
||||
SystemZInstrInfo InstrInfo;
|
||||
SystemZTargetLowering TLInfo;
|
||||
SystemZSelectionDAGInfo TSInfo;
|
||||
|
||||
// SystemZ does not have any call stack frame, therefore not having
|
||||
// any SystemZ specific FrameInfo class.
|
||||
@ -53,6 +55,10 @@ public:
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
virtual const SystemZSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
|
||||
}; // SystemZTargetMachine.
|
||||
|
||||
|
@ -6593,221 +6593,6 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
|
||||
return DAG.getMergeValues(Ops1, 2, dl);
|
||||
}
|
||||
|
||||
SDValue
|
||||
X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff) const {
|
||||
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
|
||||
|
||||
// If not DWORD aligned or size is more than the threshold, call the library.
|
||||
// The libc version is likely to be faster for these cases. It can use the
|
||||
// address value and run time information about the CPU.
|
||||
if ((Align & 3) != 0 ||
|
||||
!ConstantSize ||
|
||||
ConstantSize->getZExtValue() >
|
||||
getSubtarget()->getMaxInlineSizeThreshold()) {
|
||||
SDValue InFlag(0, 0);
|
||||
|
||||
// Check to see if there is a specialized entry-point for memory zeroing.
|
||||
ConstantSDNode *V = dyn_cast<ConstantSDNode>(Src);
|
||||
|
||||
if (const char *bzeroEntry = V &&
|
||||
V->isNullValue() ? Subtarget->getBZeroEntry() : 0) {
|
||||
EVT IntPtr = getPointerTy();
|
||||
const Type *IntPtrTy = TD->getIntPtrType(*DAG.getContext());
|
||||
TargetLowering::ArgListTy Args;
|
||||
TargetLowering::ArgListEntry Entry;
|
||||
Entry.Node = Dst;
|
||||
Entry.Ty = IntPtrTy;
|
||||
Args.push_back(Entry);
|
||||
Entry.Node = Size;
|
||||
Args.push_back(Entry);
|
||||
std::pair<SDValue,SDValue> CallResult =
|
||||
LowerCallTo(Chain, Type::getVoidTy(*DAG.getContext()),
|
||||
false, false, false, false,
|
||||
0, CallingConv::C, false, /*isReturnValueUsed=*/false,
|
||||
DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG, dl);
|
||||
return CallResult.second;
|
||||
}
|
||||
|
||||
// Otherwise have the target-independent code call memset.
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
uint64_t SizeVal = ConstantSize->getZExtValue();
|
||||
SDValue InFlag(0, 0);
|
||||
EVT AVT;
|
||||
SDValue Count;
|
||||
ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Src);
|
||||
unsigned BytesLeft = 0;
|
||||
bool TwoRepStos = false;
|
||||
if (ValC) {
|
||||
unsigned ValReg;
|
||||
uint64_t Val = ValC->getZExtValue() & 255;
|
||||
|
||||
// If the value is a constant, then we can potentially use larger sets.
|
||||
switch (Align & 3) {
|
||||
case 2: // WORD aligned
|
||||
AVT = MVT::i16;
|
||||
ValReg = X86::AX;
|
||||
Val = (Val << 8) | Val;
|
||||
break;
|
||||
case 0: // DWORD aligned
|
||||
AVT = MVT::i32;
|
||||
ValReg = X86::EAX;
|
||||
Val = (Val << 8) | Val;
|
||||
Val = (Val << 16) | Val;
|
||||
if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) { // QWORD aligned
|
||||
AVT = MVT::i64;
|
||||
ValReg = X86::RAX;
|
||||
Val = (Val << 32) | Val;
|
||||
}
|
||||
break;
|
||||
default: // Byte aligned
|
||||
AVT = MVT::i8;
|
||||
ValReg = X86::AL;
|
||||
Count = DAG.getIntPtrConstant(SizeVal);
|
||||
break;
|
||||
}
|
||||
|
||||
if (AVT.bitsGT(MVT::i8)) {
|
||||
unsigned UBytes = AVT.getSizeInBits() / 8;
|
||||
Count = DAG.getIntPtrConstant(SizeVal / UBytes);
|
||||
BytesLeft = SizeVal % UBytes;
|
||||
}
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, dl, ValReg, DAG.getConstant(Val, AVT),
|
||||
InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
} else {
|
||||
AVT = MVT::i8;
|
||||
Count = DAG.getIntPtrConstant(SizeVal);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, X86::AL, Src, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX :
|
||||
X86::ECX,
|
||||
Count, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI :
|
||||
X86::EDI,
|
||||
Dst, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
|
||||
Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops));
|
||||
|
||||
if (TwoRepStos) {
|
||||
InFlag = Chain.getValue(1);
|
||||
Count = Size;
|
||||
EVT CVT = Count.getValueType();
|
||||
SDValue Left = DAG.getNode(ISD::AND, dl, CVT, Count,
|
||||
DAG.getConstant((AVT == MVT::i64) ? 7 : 3, CVT));
|
||||
Chain = DAG.getCopyToReg(Chain, dl, (CVT == MVT::i64) ? X86::RCX :
|
||||
X86::ECX,
|
||||
Left, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Tys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDValue Ops[] = { Chain, DAG.getValueType(MVT::i8), InFlag };
|
||||
Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops));
|
||||
} else if (BytesLeft) {
|
||||
// Handle the last 1 - 7 bytes.
|
||||
unsigned Offset = SizeVal - BytesLeft;
|
||||
EVT AddrVT = Dst.getValueType();
|
||||
EVT SizeVT = Size.getValueType();
|
||||
|
||||
Chain = DAG.getMemset(Chain, dl,
|
||||
DAG.getNode(ISD::ADD, dl, AddrVT, Dst,
|
||||
DAG.getConstant(Offset, AddrVT)),
|
||||
Src,
|
||||
DAG.getConstant(BytesLeft, SizeVT),
|
||||
Align, isVolatile, DstSV, DstSVOff + Offset);
|
||||
}
|
||||
|
||||
// TODO: Use a Tokenfactor, as in memcpy, instead of a single chain.
|
||||
return Chain;
|
||||
}
|
||||
|
||||
SDValue
|
||||
X86TargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain, SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile, bool AlwaysInline,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff,
|
||||
const Value *SrcSV,
|
||||
uint64_t SrcSVOff) const {
|
||||
// This requires the copy size to be a constant, preferrably
|
||||
// within a subtarget-specific limit.
|
||||
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
|
||||
if (!ConstantSize)
|
||||
return SDValue();
|
||||
uint64_t SizeVal = ConstantSize->getZExtValue();
|
||||
if (!AlwaysInline && SizeVal > getSubtarget()->getMaxInlineSizeThreshold())
|
||||
return SDValue();
|
||||
|
||||
/// If not DWORD aligned, call the library.
|
||||
if ((Align & 3) != 0)
|
||||
return SDValue();
|
||||
|
||||
// DWORD aligned
|
||||
EVT AVT = MVT::i32;
|
||||
if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) // QWORD aligned
|
||||
AVT = MVT::i64;
|
||||
|
||||
unsigned UBytes = AVT.getSizeInBits() / 8;
|
||||
unsigned CountVal = SizeVal / UBytes;
|
||||
SDValue Count = DAG.getIntPtrConstant(CountVal);
|
||||
unsigned BytesLeft = SizeVal % UBytes;
|
||||
|
||||
SDValue InFlag(0, 0);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX :
|
||||
X86::ECX,
|
||||
Count, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI :
|
||||
X86::EDI,
|
||||
Dst, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RSI :
|
||||
X86::ESI,
|
||||
Src, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
|
||||
SDValue RepMovs = DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops,
|
||||
array_lengthof(Ops));
|
||||
|
||||
SmallVector<SDValue, 4> Results;
|
||||
Results.push_back(RepMovs);
|
||||
if (BytesLeft) {
|
||||
// Handle the last 1 - 7 bytes.
|
||||
unsigned Offset = SizeVal - BytesLeft;
|
||||
EVT DstVT = Dst.getValueType();
|
||||
EVT SrcVT = Src.getValueType();
|
||||
EVT SizeVT = Size.getValueType();
|
||||
Results.push_back(DAG.getMemcpy(Chain, dl,
|
||||
DAG.getNode(ISD::ADD, dl, DstVT, Dst,
|
||||
DAG.getConstant(Offset, DstVT)),
|
||||
DAG.getNode(ISD::ADD, dl, SrcVT, Src,
|
||||
DAG.getConstant(Offset, SrcVT)),
|
||||
DAG.getConstant(BytesLeft, SizeVT),
|
||||
Align, isVolatile, AlwaysInline,
|
||||
DstSV, DstSVOff + Offset,
|
||||
SrcSV, SrcSVOff + Offset));
|
||||
}
|
||||
|
||||
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
|
||||
&Results[0], Results.size());
|
||||
}
|
||||
|
||||
SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
|
||||
|
@ -743,23 +743,6 @@ namespace llvm {
|
||||
void ReplaceATOMIC_BINARY_64(SDNode *N, SmallVectorImpl<SDValue> &Results,
|
||||
SelectionDAG &DAG, unsigned NewOp) const;
|
||||
|
||||
SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff) const;
|
||||
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile, bool AlwaysInline,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff,
|
||||
const Value *SrcSV,
|
||||
uint64_t SrcSVOff) const;
|
||||
|
||||
/// Utility function to emit string processing sse4.2 instructions
|
||||
/// that return in xmm0.
|
||||
/// This takes the instruction to expand, the associated machine basic
|
||||
|
@ -12,11 +12,232 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "x86-selectiondag-info"
|
||||
#include "X86SelectionDAGInfo.h"
|
||||
#include "X86TargetMachine.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
using namespace llvm;
|
||||
|
||||
X86SelectionDAGInfo::X86SelectionDAGInfo() {
|
||||
X86SelectionDAGInfo::X86SelectionDAGInfo(const X86TargetMachine &TM) :
|
||||
TargetSelectionDAGInfo(TM),
|
||||
Subtarget(&TM.getSubtarget<X86Subtarget>()),
|
||||
TLI(*TM.getTargetLowering()) {
|
||||
}
|
||||
|
||||
X86SelectionDAGInfo::~X86SelectionDAGInfo() {
|
||||
}
|
||||
|
||||
SDValue
|
||||
X86SelectionDAGInfo::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff) const {
|
||||
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
|
||||
|
||||
// If not DWORD aligned or size is more than the threshold, call the library.
|
||||
// The libc version is likely to be faster for these cases. It can use the
|
||||
// address value and run time information about the CPU.
|
||||
if ((Align & 3) != 0 ||
|
||||
!ConstantSize ||
|
||||
ConstantSize->getZExtValue() >
|
||||
Subtarget->getMaxInlineSizeThreshold()) {
|
||||
SDValue InFlag(0, 0);
|
||||
|
||||
// Check to see if there is a specialized entry-point for memory zeroing.
|
||||
ConstantSDNode *V = dyn_cast<ConstantSDNode>(Src);
|
||||
|
||||
if (const char *bzeroEntry = V &&
|
||||
V->isNullValue() ? Subtarget->getBZeroEntry() : 0) {
|
||||
EVT IntPtr = TLI.getPointerTy();
|
||||
const Type *IntPtrTy = getTargetData()->getIntPtrType(*DAG.getContext());
|
||||
TargetLowering::ArgListTy Args;
|
||||
TargetLowering::ArgListEntry Entry;
|
||||
Entry.Node = Dst;
|
||||
Entry.Ty = IntPtrTy;
|
||||
Args.push_back(Entry);
|
||||
Entry.Node = Size;
|
||||
Args.push_back(Entry);
|
||||
std::pair<SDValue,SDValue> CallResult =
|
||||
TLI.LowerCallTo(Chain, Type::getVoidTy(*DAG.getContext()),
|
||||
false, false, false, false,
|
||||
0, CallingConv::C, false, /*isReturnValueUsed=*/false,
|
||||
DAG.getExternalSymbol(bzeroEntry, IntPtr), Args,
|
||||
DAG, dl);
|
||||
return CallResult.second;
|
||||
}
|
||||
|
||||
// Otherwise have the target-independent code call memset.
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
uint64_t SizeVal = ConstantSize->getZExtValue();
|
||||
SDValue InFlag(0, 0);
|
||||
EVT AVT;
|
||||
SDValue Count;
|
||||
ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Src);
|
||||
unsigned BytesLeft = 0;
|
||||
bool TwoRepStos = false;
|
||||
if (ValC) {
|
||||
unsigned ValReg;
|
||||
uint64_t Val = ValC->getZExtValue() & 255;
|
||||
|
||||
// If the value is a constant, then we can potentially use larger sets.
|
||||
switch (Align & 3) {
|
||||
case 2: // WORD aligned
|
||||
AVT = MVT::i16;
|
||||
ValReg = X86::AX;
|
||||
Val = (Val << 8) | Val;
|
||||
break;
|
||||
case 0: // DWORD aligned
|
||||
AVT = MVT::i32;
|
||||
ValReg = X86::EAX;
|
||||
Val = (Val << 8) | Val;
|
||||
Val = (Val << 16) | Val;
|
||||
if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) { // QWORD aligned
|
||||
AVT = MVT::i64;
|
||||
ValReg = X86::RAX;
|
||||
Val = (Val << 32) | Val;
|
||||
}
|
||||
break;
|
||||
default: // Byte aligned
|
||||
AVT = MVT::i8;
|
||||
ValReg = X86::AL;
|
||||
Count = DAG.getIntPtrConstant(SizeVal);
|
||||
break;
|
||||
}
|
||||
|
||||
if (AVT.bitsGT(MVT::i8)) {
|
||||
unsigned UBytes = AVT.getSizeInBits() / 8;
|
||||
Count = DAG.getIntPtrConstant(SizeVal / UBytes);
|
||||
BytesLeft = SizeVal % UBytes;
|
||||
}
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, dl, ValReg, DAG.getConstant(Val, AVT),
|
||||
InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
} else {
|
||||
AVT = MVT::i8;
|
||||
Count = DAG.getIntPtrConstant(SizeVal);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, X86::AL, Src, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX :
|
||||
X86::ECX,
|
||||
Count, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI :
|
||||
X86::EDI,
|
||||
Dst, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
|
||||
Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops));
|
||||
|
||||
if (TwoRepStos) {
|
||||
InFlag = Chain.getValue(1);
|
||||
Count = Size;
|
||||
EVT CVT = Count.getValueType();
|
||||
SDValue Left = DAG.getNode(ISD::AND, dl, CVT, Count,
|
||||
DAG.getConstant((AVT == MVT::i64) ? 7 : 3, CVT));
|
||||
Chain = DAG.getCopyToReg(Chain, dl, (CVT == MVT::i64) ? X86::RCX :
|
||||
X86::ECX,
|
||||
Left, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Tys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDValue Ops[] = { Chain, DAG.getValueType(MVT::i8), InFlag };
|
||||
Chain = DAG.getNode(X86ISD::REP_STOS, dl, Tys, Ops, array_lengthof(Ops));
|
||||
} else if (BytesLeft) {
|
||||
// Handle the last 1 - 7 bytes.
|
||||
unsigned Offset = SizeVal - BytesLeft;
|
||||
EVT AddrVT = Dst.getValueType();
|
||||
EVT SizeVT = Size.getValueType();
|
||||
|
||||
Chain = DAG.getMemset(Chain, dl,
|
||||
DAG.getNode(ISD::ADD, dl, AddrVT, Dst,
|
||||
DAG.getConstant(Offset, AddrVT)),
|
||||
Src,
|
||||
DAG.getConstant(BytesLeft, SizeVT),
|
||||
Align, isVolatile, DstSV, DstSVOff + Offset);
|
||||
}
|
||||
|
||||
// TODO: Use a Tokenfactor, as in memcpy, instead of a single chain.
|
||||
return Chain;
|
||||
}
|
||||
|
||||
SDValue
|
||||
X86SelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain, SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile, bool AlwaysInline,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff,
|
||||
const Value *SrcSV,
|
||||
uint64_t SrcSVOff) const {
|
||||
// This requires the copy size to be a constant, preferrably
|
||||
// within a subtarget-specific limit.
|
||||
ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
|
||||
if (!ConstantSize)
|
||||
return SDValue();
|
||||
uint64_t SizeVal = ConstantSize->getZExtValue();
|
||||
if (!AlwaysInline && SizeVal > Subtarget->getMaxInlineSizeThreshold())
|
||||
return SDValue();
|
||||
|
||||
/// If not DWORD aligned, call the library.
|
||||
if ((Align & 3) != 0)
|
||||
return SDValue();
|
||||
|
||||
// DWORD aligned
|
||||
EVT AVT = MVT::i32;
|
||||
if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) // QWORD aligned
|
||||
AVT = MVT::i64;
|
||||
|
||||
unsigned UBytes = AVT.getSizeInBits() / 8;
|
||||
unsigned CountVal = SizeVal / UBytes;
|
||||
SDValue Count = DAG.getIntPtrConstant(CountVal);
|
||||
unsigned BytesLeft = SizeVal % UBytes;
|
||||
|
||||
SDValue InFlag(0, 0);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RCX :
|
||||
X86::ECX,
|
||||
Count, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RDI :
|
||||
X86::EDI,
|
||||
Dst, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, Subtarget->is64Bit() ? X86::RSI :
|
||||
X86::ESI,
|
||||
Src, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDValue Ops[] = { Chain, DAG.getValueType(AVT), InFlag };
|
||||
SDValue RepMovs = DAG.getNode(X86ISD::REP_MOVS, dl, Tys, Ops,
|
||||
array_lengthof(Ops));
|
||||
|
||||
SmallVector<SDValue, 4> Results;
|
||||
Results.push_back(RepMovs);
|
||||
if (BytesLeft) {
|
||||
// Handle the last 1 - 7 bytes.
|
||||
unsigned Offset = SizeVal - BytesLeft;
|
||||
EVT DstVT = Dst.getValueType();
|
||||
EVT SrcVT = Src.getValueType();
|
||||
EVT SizeVT = Size.getValueType();
|
||||
Results.push_back(DAG.getMemcpy(Chain, dl,
|
||||
DAG.getNode(ISD::ADD, dl, DstVT, Dst,
|
||||
DAG.getConstant(Offset, DstVT)),
|
||||
DAG.getNode(ISD::ADD, dl, SrcVT, Src,
|
||||
DAG.getConstant(Offset, SrcVT)),
|
||||
DAG.getConstant(BytesLeft, SizeVT),
|
||||
Align, isVolatile, AlwaysInline,
|
||||
DstSV, DstSVOff + Offset,
|
||||
SrcSV, SrcSVOff + Offset));
|
||||
}
|
||||
|
||||
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
|
||||
&Results[0], Results.size());
|
||||
}
|
||||
|
@ -18,10 +18,40 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class X86TargetLowering;
|
||||
class X86TargetMachine;
|
||||
class X86Subtarget;
|
||||
|
||||
class X86SelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
|
||||
/// make the right decision when generating code for different targets.
|
||||
const X86Subtarget *Subtarget;
|
||||
|
||||
const X86TargetLowering &TLI;
|
||||
|
||||
public:
|
||||
X86SelectionDAGInfo();
|
||||
explicit X86SelectionDAGInfo(const X86TargetMachine &TM);
|
||||
~X86SelectionDAGInfo();
|
||||
|
||||
virtual
|
||||
SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff) const;
|
||||
|
||||
virtual
|
||||
SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Chain,
|
||||
SDValue Dst, SDValue Src,
|
||||
SDValue Size, unsigned Align,
|
||||
bool isVolatile, bool AlwaysInline,
|
||||
const Value *DstSV,
|
||||
uint64_t DstSVOff,
|
||||
const Value *SrcSV,
|
||||
uint64_t SrcSVOff) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -82,7 +82,8 @@ X86TargetMachine::X86TargetMachine(const Target &T, const std::string &TT,
|
||||
Subtarget.getStackAlignment(),
|
||||
(Subtarget.isTargetWin64() ? -40 :
|
||||
(Subtarget.is64Bit() ? -8 : -4))),
|
||||
InstrInfo(*this), JITInfo(*this), TLInfo(*this), ELFWriterInfo(*this) {
|
||||
InstrInfo(*this), JITInfo(*this), TLInfo(*this), TSInfo(*this),
|
||||
ELFWriterInfo(*this) {
|
||||
DefRelocModel = getRelocationModel();
|
||||
|
||||
// If no relocation model was picked, default as appropriate for the target.
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "X86JITInfo.h"
|
||||
#include "X86Subtarget.h"
|
||||
#include "X86ISelLowering.h"
|
||||
#include "X86SelectionDAGInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -35,6 +36,7 @@ class X86TargetMachine : public LLVMTargetMachine {
|
||||
X86InstrInfo InstrInfo;
|
||||
X86JITInfo JITInfo;
|
||||
X86TargetLowering TLInfo;
|
||||
X86SelectionDAGInfo TSInfo;
|
||||
X86ELFWriterInfo ELFWriterInfo;
|
||||
Reloc::Model DefRelocModel; // Reloc model before it's overridden.
|
||||
|
||||
@ -54,6 +56,9 @@ public:
|
||||
virtual const X86TargetLowering *getTargetLowering() const {
|
||||
return &TLInfo;
|
||||
}
|
||||
virtual const X86SelectionDAGInfo *getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
virtual const X86RegisterInfo *getRegisterInfo() const {
|
||||
return &InstrInfo.getRegisterInfo();
|
||||
}
|
||||
|
@ -12,10 +12,11 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "xcore-selectiondag-info"
|
||||
#include "XCoreSelectionDAGInfo.h"
|
||||
#include "XCoreTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
XCoreSelectionDAGInfo::XCoreSelectionDAGInfo() {
|
||||
XCoreSelectionDAGInfo::XCoreSelectionDAGInfo(const XCoreTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
XCoreSelectionDAGInfo::~XCoreSelectionDAGInfo() {
|
||||
|
@ -18,9 +18,11 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class XCoreTargetMachine;
|
||||
|
||||
class XCoreSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
XCoreSelectionDAGInfo();
|
||||
explicit XCoreSelectionDAGInfo(const XCoreTargetMachine &TM);
|
||||
~XCoreSelectionDAGInfo();
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,8 @@ XCoreTargetMachine::XCoreTargetMachine(const Target &T, const std::string &TT,
|
||||
"i16:16:32-i32:32:32-i64:32:32-n32"),
|
||||
InstrInfo(),
|
||||
FrameInfo(*this),
|
||||
TLInfo(*this) {
|
||||
TLInfo(*this),
|
||||
TSInfo(*this) {
|
||||
}
|
||||
|
||||
bool XCoreTargetMachine::addInstSelector(PassManagerBase &PM,
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "XCoreSubtarget.h"
|
||||
#include "XCoreInstrInfo.h"
|
||||
#include "XCoreISelLowering.h"
|
||||
#include "XCoreSelectionDAGInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -29,6 +30,7 @@ class XCoreTargetMachine : public LLVMTargetMachine {
|
||||
XCoreInstrInfo InstrInfo;
|
||||
XCoreFrameInfo FrameInfo;
|
||||
XCoreTargetLowering TLInfo;
|
||||
XCoreSelectionDAGInfo TSInfo;
|
||||
public:
|
||||
XCoreTargetMachine(const Target &T, const std::string &TT,
|
||||
const std::string &FS);
|
||||
@ -40,6 +42,10 @@ public:
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
virtual const XCoreSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
virtual const TargetRegisterInfo *getRegisterInfo() const {
|
||||
return &InstrInfo.getRegisterInfo();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user