forked from OSchip/llvm-project
Replace TargetLowering::isIntImmLegal() with
ScalarTargetTransformInfo::getIntImmCost() instead. "Legal" is a poorly defined term for something like integer immediate materialization. It is always possible to materialize an integer immediate. Whether to use it for memcpy expansion is more a "cost" conceern. llvm-svn: 169929
This commit is contained in:
parent
a2d35d153f
commit
eb54240dc2
|
@ -371,16 +371,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isIntImmLegal - Returns true if the target can instruction select the
|
|
||||||
/// specified integer immediate natively (that is, it's materialized with one
|
|
||||||
/// instruction). The current *assumption* in isel is all of integer
|
|
||||||
/// immediates are "legal" and only the memcpy / memset expansion code is
|
|
||||||
/// making use of this. The rest of isel doesn't have proper cost model for
|
|
||||||
/// immediate materialization.
|
|
||||||
virtual bool isIntImmLegal(const APInt &/*Imm*/, EVT /*VT*/) const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// isShuffleMaskLegal - Targets can use this to indicate that they only
|
/// isShuffleMaskLegal - Targets can use this to indicate that they only
|
||||||
/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
|
/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
|
||||||
/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
|
/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
|
||||||
|
|
|
@ -140,6 +140,13 @@ public:
|
||||||
virtual PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const {
|
virtual PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getIntImmCost - Return the expected cost of materializing the given
|
||||||
|
/// integer immediate of the specified type.
|
||||||
|
virtual unsigned getIntImmCost(const APInt&, Type*) const {
|
||||||
|
// Default assumption is immediate is cheap.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// VectorTargetTransformInfo - This interface is used by the vectorizers
|
/// VectorTargetTransformInfo - This interface is used by the vectorizers
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Support/Mutex.h"
|
#include "llvm/Support/Mutex.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/TargetTransformInfo.h"
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
#include "llvm/Target/TargetIntrinsicInfo.h"
|
#include "llvm/Target/TargetIntrinsicInfo.h"
|
||||||
#include "llvm/Target/TargetLowering.h"
|
#include "llvm/Target/TargetLowering.h"
|
||||||
|
@ -3382,7 +3383,10 @@ static SDValue getMemsetStringVal(EVT VT, DebugLoc dl, SelectionDAG &DAG,
|
||||||
Val |= (uint64_t)(unsigned char)Str[i] << (NumVTBytes-i-1)*8;
|
Val |= (uint64_t)(unsigned char)Str[i] << (NumVTBytes-i-1)*8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TLI.isIntImmLegal(Val, VT))
|
// If the "cost" of materializing the integer immediate is 1 or free, then
|
||||||
|
// it is cost effective to turn the load into the immediate.
|
||||||
|
if (DAG.getTarget().getScalarTargetTransformInfo()->
|
||||||
|
getIntImmCost(Val, VT.getTypeForEVT(*DAG.getContext())) < 2)
|
||||||
return DAG.getConstant(Val, VT);
|
return DAG.getConstant(Val, VT);
|
||||||
return SDValue(0, 0);
|
return SDValue(0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10260,24 +10260,6 @@ bool ARMTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMTargetLowering::isIntImmLegal(const APInt &Imm, EVT VT) const {
|
|
||||||
if (VT.getSizeInBits() > 32)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int32_t ImmVal = Imm.getSExtValue();
|
|
||||||
if (!Subtarget->isThumb()) {
|
|
||||||
return (ImmVal >= 0 && ImmVal < 65536) ||
|
|
||||||
(ARM_AM::getSOImmVal(ImmVal) != -1) ||
|
|
||||||
(ARM_AM::getSOImmVal(~ImmVal) != -1);
|
|
||||||
} else if (Subtarget->isThumb2()) {
|
|
||||||
return (ImmVal >= 0 && ImmVal < 65536) ||
|
|
||||||
(ARM_AM::getT2SOImmVal(ImmVal) != -1) ||
|
|
||||||
(ARM_AM::getT2SOImmVal(~ImmVal) != -1);
|
|
||||||
} else /*Thumb1*/ {
|
|
||||||
return (ImmVal >= 0 && ImmVal < 256);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getTgtMemIntrinsic - Represent NEON load and store intrinsics as
|
/// getTgtMemIntrinsic - Represent NEON load and store intrinsics as
|
||||||
/// MemIntrinsicNodes. The associated MachineMemOperands record the alignment
|
/// MemIntrinsicNodes. The associated MachineMemOperands record the alignment
|
||||||
/// specified in the intrinsic calls.
|
/// specified in the intrinsic calls.
|
||||||
|
@ -10359,3 +10341,36 @@ bool ARMTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
ARMScalarTargetTransformImpl::getIntImmCost(const APInt &Imm, Type *Ty) const {
|
||||||
|
assert(Ty->isIntegerTy());
|
||||||
|
|
||||||
|
unsigned Bits = Ty->getPrimitiveSizeInBits();
|
||||||
|
if (Bits == 0 || Bits > 32)
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
int32_t SImmVal = Imm.getSExtValue();
|
||||||
|
uint32_t ZImmVal = Imm.getZExtValue();
|
||||||
|
if (!Subtarget->isThumb()) {
|
||||||
|
if ((SImmVal >= 0 && SImmVal < 65536) ||
|
||||||
|
(ARM_AM::getSOImmVal(ZImmVal) != -1) ||
|
||||||
|
(ARM_AM::getSOImmVal(~ZImmVal) != -1))
|
||||||
|
return 1;
|
||||||
|
return Subtarget->hasV6T2Ops() ? 2 : 3;
|
||||||
|
} else if (Subtarget->isThumb2()) {
|
||||||
|
if ((SImmVal >= 0 && SImmVal < 65536) ||
|
||||||
|
(ARM_AM::getT2SOImmVal(ZImmVal) != -1) ||
|
||||||
|
(ARM_AM::getT2SOImmVal(~ZImmVal) != -1))
|
||||||
|
return 1;
|
||||||
|
return Subtarget->hasV6T2Ops() ? 2 : 3;
|
||||||
|
} else /*Thumb1*/ {
|
||||||
|
if (SImmVal >= 0 && SImmVal < 256)
|
||||||
|
return 1;
|
||||||
|
if ((~ZImmVal < 256) || ARM_AM::isThumbImmShiftedVal(ZImmVal))
|
||||||
|
return 2;
|
||||||
|
// Load from constantpool.
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "llvm/CodeGen/SelectionDAG.h"
|
#include "llvm/CodeGen/SelectionDAG.h"
|
||||||
#include "llvm/Target/TargetLowering.h"
|
#include "llvm/Target/TargetLowering.h"
|
||||||
#include "llvm/Target/TargetRegisterInfo.h"
|
#include "llvm/Target/TargetRegisterInfo.h"
|
||||||
|
#include "llvm/Target/TargetTransformImpl.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -387,8 +388,6 @@ namespace llvm {
|
||||||
/// materialize the FP immediate as a load from a constant pool.
|
/// materialize the FP immediate as a load from a constant pool.
|
||||||
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
|
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
|
||||||
|
|
||||||
virtual bool isIntImmLegal(const APInt &Imm, EVT VT) const;
|
|
||||||
|
|
||||||
virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info,
|
virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info,
|
||||||
const CallInst &I,
|
const CallInst &I,
|
||||||
unsigned Intrinsic) const;
|
unsigned Intrinsic) const;
|
||||||
|
@ -575,6 +574,16 @@ namespace llvm {
|
||||||
FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
|
FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
|
||||||
const TargetLibraryInfo *libInfo);
|
const TargetLibraryInfo *libInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ARMScalarTargetTransformImpl : public ScalarTargetTransformImpl {
|
||||||
|
const ARMSubtarget *Subtarget;
|
||||||
|
public:
|
||||||
|
explicit ARMScalarTargetTransformImpl(const TargetLowering *TL) :
|
||||||
|
ScalarTargetTransformImpl(TL),
|
||||||
|
Subtarget(&TL->getTargetMachine().getSubtarget<ARMSubtarget>()) {};
|
||||||
|
|
||||||
|
virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ARMISELLOWERING_H
|
#endif // ARMISELLOWERING_H
|
||||||
|
|
|
@ -66,7 +66,7 @@ class ARMTargetMachine : public ARMBaseTargetMachine {
|
||||||
ARMTargetLowering TLInfo;
|
ARMTargetLowering TLInfo;
|
||||||
ARMSelectionDAGInfo TSInfo;
|
ARMSelectionDAGInfo TSInfo;
|
||||||
ARMFrameLowering FrameLowering;
|
ARMFrameLowering FrameLowering;
|
||||||
ScalarTargetTransformImpl STTI;
|
ARMScalarTargetTransformImpl STTI;
|
||||||
VectorTargetTransformImpl VTTI;
|
VectorTargetTransformImpl VTTI;
|
||||||
public:
|
public:
|
||||||
ARMTargetMachine(const Target &T, StringRef TT,
|
ARMTargetMachine(const Target &T, StringRef TT,
|
||||||
|
@ -112,7 +112,7 @@ class ThumbTargetMachine : public ARMBaseTargetMachine {
|
||||||
ARMSelectionDAGInfo TSInfo;
|
ARMSelectionDAGInfo TSInfo;
|
||||||
// Either Thumb1FrameLowering or ARMFrameLowering.
|
// Either Thumb1FrameLowering or ARMFrameLowering.
|
||||||
OwningPtr<ARMFrameLowering> FrameLowering;
|
OwningPtr<ARMFrameLowering> FrameLowering;
|
||||||
ScalarTargetTransformImpl STTI;
|
ARMScalarTargetTransformImpl STTI;
|
||||||
VectorTargetTransformImpl VTTI;
|
VectorTargetTransformImpl VTTI;
|
||||||
public:
|
public:
|
||||||
ThumbTargetMachine(const Target &T, StringRef TT,
|
ThumbTargetMachine(const Target &T, StringRef TT,
|
||||||
|
|
Loading…
Reference in New Issue