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:
Evan Cheng 2012-12-11 23:26:14 +00:00
parent a2d35d153f
commit eb54240dc2
6 changed files with 58 additions and 33 deletions

View File

@ -371,16 +371,6 @@ public:
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
/// support *some* VECTOR_SHUFFLE operations, those with specific masks.
/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values

View File

@ -140,6 +140,13 @@ public:
virtual PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const {
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

View File

@ -41,6 +41,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetTransformInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetIntrinsicInfo.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;
}
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 SDValue(0, 0);
}

View File

@ -10260,24 +10260,6 @@ bool ARMTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
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
/// MemIntrinsicNodes. The associated MachineMemOperands record the alignment
/// specified in the intrinsic calls.
@ -10359,3 +10341,36 @@ bool ARMTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
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;
}

View File

@ -22,6 +22,7 @@
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetTransformImpl.h"
#include <vector>
namespace llvm {
@ -387,8 +388,6 @@ namespace llvm {
/// materialize the FP immediate as a load from a constant pool.
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
virtual bool isIntImmLegal(const APInt &Imm, EVT VT) const;
virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info,
const CallInst &I,
unsigned Intrinsic) const;
@ -575,6 +574,16 @@ namespace llvm {
FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
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

View File

@ -66,7 +66,7 @@ class ARMTargetMachine : public ARMBaseTargetMachine {
ARMTargetLowering TLInfo;
ARMSelectionDAGInfo TSInfo;
ARMFrameLowering FrameLowering;
ScalarTargetTransformImpl STTI;
ARMScalarTargetTransformImpl STTI;
VectorTargetTransformImpl VTTI;
public:
ARMTargetMachine(const Target &T, StringRef TT,
@ -112,7 +112,7 @@ class ThumbTargetMachine : public ARMBaseTargetMachine {
ARMSelectionDAGInfo TSInfo;
// Either Thumb1FrameLowering or ARMFrameLowering.
OwningPtr<ARMFrameLowering> FrameLowering;
ScalarTargetTransformImpl STTI;
ARMScalarTargetTransformImpl STTI;
VectorTargetTransformImpl VTTI;
public:
ThumbTargetMachine(const Target &T, StringRef TT,