mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Convert the TargetTransformInfo from an immutable pass with dynamic
interfaces which could be extracted from it, and must be provided on construction, to a chained analysis group. The end goal here is that TTI works much like AA -- there is a baseline "no-op" and target independent pass which is in the group, and each target can expose a target-specific pass in the group. These passes will naturally chain allowing each target-specific pass to delegate to the generic pass as needed. In particular, this will allow a much simpler interface for passes that would like to use TTI -- they can have a hard dependency on TTI and it will just be satisfied by the stub implementation when that is all that is available. This patch is a WIP however. In particular, the "stub" pass is actually the one and only pass, and everything there is implemented by delegating to the target-provided interfaces. As a consequence the tools still have to explicitly construct the pass. Switching targets to provide custom passes and sinking the stub behavior into the NoTTI pass is the next step. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171621 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
be73c7b903
commit
7bdf6b00e0
@ -250,7 +250,8 @@ void initializeTailCallElimPass(PassRegistry&);
|
||||
void initializeTailDuplicatePassPass(PassRegistry&);
|
||||
void initializeTargetPassConfigPass(PassRegistry&);
|
||||
void initializeDataLayoutPass(PassRegistry&);
|
||||
void initializeTargetTransformInfoPass(PassRegistry&);
|
||||
void initializeTargetTransformInfoAnalysisGroup(PassRegistry&);
|
||||
void initializeNoTTIPass(PassRegistry&);
|
||||
void initializeTargetLibraryInfoPass(PassRegistry&);
|
||||
void initializeTwoAddressInstructionPassPass(PassRegistry&);
|
||||
void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
|
||||
|
@ -30,6 +30,164 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ScalarTargetTransformInfo;
|
||||
class VectorTargetTransformInfo;
|
||||
|
||||
/// TargetTransformInfo - This pass provides access to the codegen
|
||||
/// interfaces that are needed for IR-level transformations.
|
||||
class TargetTransformInfo {
|
||||
protected:
|
||||
/// \brief The TTI instance one level down the stack.
|
||||
///
|
||||
/// This is used to implement the default behavior all of the methods which
|
||||
/// is to delegate up through the stack of TTIs until one can answer the
|
||||
/// query.
|
||||
const TargetTransformInfo *PrevTTI;
|
||||
|
||||
/// Every subclass must initialize the base with the previous TTI in the
|
||||
/// stack, or 0 if there is no previous TTI in the stack.
|
||||
TargetTransformInfo(const TargetTransformInfo *PrevTTI) : PrevTTI(PrevTTI) {}
|
||||
|
||||
/// All pass subclasses must call TargetTransformInfo::getAnalysisUsage.
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
||||
public:
|
||||
/// This class is intended to be subclassed by real implementations.
|
||||
virtual ~TargetTransformInfo() = 0;
|
||||
|
||||
/// \name Scalar Target Information
|
||||
/// @{
|
||||
|
||||
/// PopcntHwSupport - Hardware support for population count. Compared to the
|
||||
/// SW implementation, HW support is supposed to significantly boost the
|
||||
/// performance when the population is dense, and it may or may not degrade
|
||||
/// performance if the population is sparse. A HW support is considered as
|
||||
/// "Fast" if it can outperform, or is on a par with, SW implementaion when
|
||||
/// the population is sparse; otherwise, it is considered as "Slow".
|
||||
enum PopcntHwSupport {
|
||||
None,
|
||||
Fast,
|
||||
Slow
|
||||
};
|
||||
|
||||
/// isLegalAddImmediate - Return true if the specified immediate is legal
|
||||
/// add immediate, that is the target has add instructions which can add
|
||||
/// a register with the immediate without having to materialize the
|
||||
/// immediate into a register.
|
||||
virtual bool isLegalAddImmediate(int64_t Imm) const;
|
||||
|
||||
/// isLegalICmpImmediate - Return true if the specified immediate is legal
|
||||
/// icmp immediate, that is the target has icmp instructions which can compare
|
||||
/// a register against the immediate without having to materialize the
|
||||
/// immediate into a register.
|
||||
virtual bool isLegalICmpImmediate(int64_t Imm) const;
|
||||
|
||||
/// isLegalAddressingMode - Return true if the addressing mode represented by
|
||||
/// AM is legal for this target, for a load/store of the specified type.
|
||||
/// The type may be VoidTy, in which case only return true if the addressing
|
||||
/// mode is legal for a load/store of any legal type.
|
||||
/// TODO: Handle pre/postinc as well.
|
||||
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
|
||||
int64_t BaseOffset, bool HasBaseReg,
|
||||
int64_t Scale) const;
|
||||
|
||||
/// isTruncateFree - Return true if it's free to truncate a value of
|
||||
/// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in
|
||||
/// register EAX to i16 by referencing its sub-register AX.
|
||||
virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const;
|
||||
|
||||
/// Is this type legal.
|
||||
virtual bool isTypeLegal(Type *Ty) const;
|
||||
|
||||
/// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
|
||||
virtual unsigned getJumpBufAlignment() const;
|
||||
|
||||
/// getJumpBufSize - returns the target's jmp_buf size in bytes.
|
||||
virtual unsigned getJumpBufSize() const;
|
||||
|
||||
/// shouldBuildLookupTables - Return true if switches should be turned into
|
||||
/// lookup tables for the target.
|
||||
virtual bool shouldBuildLookupTables() const;
|
||||
|
||||
/// getPopcntHwSupport - Return hardware support for population count.
|
||||
virtual PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const;
|
||||
|
||||
/// getIntImmCost - Return the expected cost of materializing the given
|
||||
/// integer immediate of the specified type.
|
||||
virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Vector Target Information
|
||||
/// @{
|
||||
|
||||
enum ShuffleKind {
|
||||
Broadcast, // Broadcast element 0 to all other elements.
|
||||
Reverse, // Reverse the order of the vector.
|
||||
InsertSubvector, // InsertSubvector. Index indicates start offset.
|
||||
ExtractSubvector // ExtractSubvector Index indicates start offset.
|
||||
};
|
||||
|
||||
/// \return The number of scalar or vector registers that the target has.
|
||||
/// If 'Vectors' is true, it returns the number of vector registers. If it is
|
||||
/// set to false, it returns the number of scalar registers.
|
||||
virtual unsigned getNumberOfRegisters(bool Vector) const;
|
||||
|
||||
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
|
||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const;
|
||||
|
||||
/// \return The cost of a shuffle instruction of kind Kind and of type Tp.
|
||||
/// The index and subtype parameters are used by the subvector insertion and
|
||||
/// extraction shuffle kinds.
|
||||
virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0,
|
||||
Type *SubTp = 0) const;
|
||||
|
||||
/// \return The expected cost of cast instructions, such as bitcast, trunc,
|
||||
/// zext, etc.
|
||||
virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
|
||||
Type *Src) const;
|
||||
|
||||
/// \return The expected cost of control-flow related instrutctions such as
|
||||
/// Phi, Ret, Br.
|
||||
virtual unsigned getCFInstrCost(unsigned Opcode) const;
|
||||
|
||||
/// \returns The expected cost of compare and select instructions.
|
||||
virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
|
||||
Type *CondTy = 0) const;
|
||||
|
||||
/// \return The expected cost of vector Insert and Extract.
|
||||
/// Use -1 to indicate that there is no information on the index value.
|
||||
virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
|
||||
unsigned Index = -1) const;
|
||||
|
||||
/// \return The cost of Load and Store instructions.
|
||||
virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
|
||||
unsigned Alignment,
|
||||
unsigned AddressSpace) const;
|
||||
|
||||
/// \returns The cost of Intrinsic instructions.
|
||||
virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
|
||||
ArrayRef<Type *> Tys) const;
|
||||
|
||||
/// \returns The number of pieces into which the provided type must be
|
||||
/// split during legalization. Zero is returned when the answer is unknown.
|
||||
virtual unsigned getNumberOfParts(Type *Tp) const;
|
||||
|
||||
/// @}
|
||||
|
||||
/// Analysis group identification.
|
||||
static char ID;
|
||||
};
|
||||
|
||||
/// \brief Create the base case instance of a pass in the TTI analysis group.
|
||||
///
|
||||
/// This class provides the base case for the stack of TTI analyses. It doesn't
|
||||
/// delegate to anything and uses the STTI and VTTI objects passed in to
|
||||
/// satisfy the queries.
|
||||
ImmutablePass *createNoTTIPass(const ScalarTargetTransformInfo *S,
|
||||
const VectorTargetTransformInfo *V);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------//
|
||||
// The classes below are inherited and implemented by target-specific classes
|
||||
// in the codegen.
|
||||
@ -198,207 +356,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/// TargetTransformInfo - This pass provides access to the codegen
|
||||
/// interfaces that are needed for IR-level transformations.
|
||||
class TargetTransformInfo : public ImmutablePass {
|
||||
private:
|
||||
const ScalarTargetTransformInfo *STTI;
|
||||
const VectorTargetTransformInfo *VTTI;
|
||||
public:
|
||||
/// Default ctor.
|
||||
///
|
||||
/// @note This has to exist, because this is a pass, but it should never be
|
||||
/// used.
|
||||
TargetTransformInfo();
|
||||
|
||||
TargetTransformInfo(const ScalarTargetTransformInfo* S,
|
||||
const VectorTargetTransformInfo *V)
|
||||
: ImmutablePass(ID), STTI(S), VTTI(V) {
|
||||
initializeTargetTransformInfoPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
TargetTransformInfo(const TargetTransformInfo &T) :
|
||||
ImmutablePass(ID), STTI(T.STTI), VTTI(T.VTTI) { }
|
||||
|
||||
/// \name Scalar Target Information
|
||||
/// @{
|
||||
|
||||
/// PopcntHwSupport - Hardware support for population count. Compared to the
|
||||
/// SW implementation, HW support is supposed to significantly boost the
|
||||
/// performance when the population is dense, and it may or may not degrade
|
||||
/// performance if the population is sparse. A HW support is considered as
|
||||
/// "Fast" if it can outperform, or is on a par with, SW implementaion when
|
||||
/// the population is sparse; otherwise, it is considered as "Slow".
|
||||
enum PopcntHwSupport {
|
||||
None,
|
||||
Fast,
|
||||
Slow
|
||||
};
|
||||
|
||||
/// isLegalAddImmediate - Return true if the specified immediate is legal
|
||||
/// add immediate, that is the target has add instructions which can add
|
||||
/// a register with the immediate without having to materialize the
|
||||
/// immediate into a register.
|
||||
bool isLegalAddImmediate(int64_t Imm) const {
|
||||
return STTI->isLegalAddImmediate(Imm);
|
||||
}
|
||||
|
||||
/// isLegalICmpImmediate - Return true if the specified immediate is legal
|
||||
/// icmp immediate, that is the target has icmp instructions which can compare
|
||||
/// a register against the immediate without having to materialize the
|
||||
/// immediate into a register.
|
||||
bool isLegalICmpImmediate(int64_t Imm) const {
|
||||
return STTI->isLegalICmpImmediate(Imm);
|
||||
}
|
||||
|
||||
/// isLegalAddressingMode - Return true if the addressing mode represented by
|
||||
/// AM is legal for this target, for a load/store of the specified type.
|
||||
/// The type may be VoidTy, in which case only return true if the addressing
|
||||
/// mode is legal for a load/store of any legal type.
|
||||
/// TODO: Handle pre/postinc as well.
|
||||
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
|
||||
int64_t BaseOffset, bool HasBaseReg,
|
||||
int64_t Scale) const {
|
||||
return STTI->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
|
||||
Scale);
|
||||
}
|
||||
|
||||
/// isTruncateFree - Return true if it's free to truncate a value of
|
||||
/// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in
|
||||
/// register EAX to i16 by referencing its sub-register AX.
|
||||
bool isTruncateFree(Type *Ty1, Type *Ty2) const {
|
||||
return STTI->isTruncateFree(Ty1, Ty2);
|
||||
}
|
||||
|
||||
/// Is this type legal.
|
||||
bool isTypeLegal(Type *Ty) const {
|
||||
return STTI->isTypeLegal(Ty);
|
||||
}
|
||||
|
||||
/// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
|
||||
unsigned getJumpBufAlignment() const {
|
||||
return STTI->getJumpBufAlignment();
|
||||
}
|
||||
|
||||
/// getJumpBufSize - returns the target's jmp_buf size in bytes.
|
||||
unsigned getJumpBufSize() const {
|
||||
return STTI->getJumpBufSize();
|
||||
}
|
||||
|
||||
/// shouldBuildLookupTables - Return true if switches should be turned into
|
||||
/// lookup tables for the target.
|
||||
bool shouldBuildLookupTables() const {
|
||||
return STTI->shouldBuildLookupTables();
|
||||
}
|
||||
|
||||
/// getPopcntHwSupport - Return hardware support for population count.
|
||||
PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const {
|
||||
return (PopcntHwSupport)STTI->getPopcntHwSupport(IntTyWidthInBit);
|
||||
}
|
||||
|
||||
/// getIntImmCost - Return the expected cost of materializing the given
|
||||
/// integer immediate of the specified type.
|
||||
unsigned getIntImmCost(const APInt &Imm, Type *Ty) const {
|
||||
return STTI->getIntImmCost(Imm, Ty);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Vector Target Information
|
||||
/// @{
|
||||
|
||||
enum ShuffleKind {
|
||||
Broadcast, // Broadcast element 0 to all other elements.
|
||||
Reverse, // Reverse the order of the vector.
|
||||
InsertSubvector, // InsertSubvector. Index indicates start offset.
|
||||
ExtractSubvector // ExtractSubvector Index indicates start offset.
|
||||
};
|
||||
|
||||
/// \return The number of scalar or vector registers that the target has.
|
||||
/// If 'Vectors' is true, it returns the number of vector registers. If it is
|
||||
/// set to false, it returns the number of scalar registers.
|
||||
unsigned getNumberOfRegisters(bool Vector) const {
|
||||
return VTTI->getNumberOfRegisters(Vector);
|
||||
}
|
||||
|
||||
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
|
||||
unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const {
|
||||
return VTTI->getArithmeticInstrCost(Opcode, Ty);
|
||||
}
|
||||
|
||||
/// \return The cost of a shuffle instruction of kind Kind and of type Tp.
|
||||
/// The index and subtype parameters are used by the subvector insertion and
|
||||
/// extraction shuffle kinds.
|
||||
unsigned getShuffleCost(ShuffleKind Kind, Type *Tp,
|
||||
int Index = 0, Type *SubTp = 0) const {
|
||||
return VTTI->getShuffleCost((VectorTargetTransformInfo::ShuffleKind)Kind,
|
||||
Tp, Index, SubTp);
|
||||
}
|
||||
|
||||
/// \return The expected cost of cast instructions, such as bitcast, trunc,
|
||||
/// zext, etc.
|
||||
unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
|
||||
Type *Src) const {
|
||||
return VTTI->getCastInstrCost(Opcode, Dst, Src);
|
||||
}
|
||||
|
||||
/// \return The expected cost of control-flow related instrutctions such as
|
||||
/// Phi, Ret, Br.
|
||||
unsigned getCFInstrCost(unsigned Opcode) const {
|
||||
return VTTI->getCFInstrCost(Opcode);
|
||||
}
|
||||
|
||||
/// \returns The expected cost of compare and select instructions.
|
||||
unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
|
||||
Type *CondTy = 0) const {
|
||||
return VTTI->getCmpSelInstrCost(Opcode, ValTy, CondTy);
|
||||
}
|
||||
|
||||
/// \return The expected cost of vector Insert and Extract.
|
||||
/// Use -1 to indicate that there is no information on the index value.
|
||||
unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
|
||||
unsigned Index = -1) const {
|
||||
return VTTI->getVectorInstrCost(Opcode, Val, Index);
|
||||
}
|
||||
|
||||
/// \return The cost of Load and Store instructions.
|
||||
unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
|
||||
unsigned Alignment,
|
||||
unsigned AddressSpace) const {
|
||||
return VTTI->getMemoryOpCost(Opcode, Src, Alignment, AddressSpace);;
|
||||
}
|
||||
|
||||
/// \returns The cost of Intrinsic instructions.
|
||||
unsigned getIntrinsicInstrCost(Intrinsic::ID ID,
|
||||
Type *RetTy,
|
||||
ArrayRef<Type*> Tys) const {
|
||||
return VTTI->getIntrinsicInstrCost(ID, RetTy, Tys);
|
||||
}
|
||||
|
||||
/// \returns The number of pieces into which the provided type must be
|
||||
/// split during legalization. Zero is returned when the answer is unknown.
|
||||
unsigned getNumberOfParts(Type *Tp) const {
|
||||
return VTTI->getNumberOfParts(Tp);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Legacy sub-object getters
|
||||
/// @{
|
||||
|
||||
const ScalarTargetTransformInfo* getScalarTargetTransformInfo() const {
|
||||
return STTI;
|
||||
}
|
||||
const VectorTargetTransformInfo* getVectorTargetTransformInfo() const {
|
||||
return VTTI;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// Pass identification, replacement for typeid.
|
||||
static char ID;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -41,6 +41,7 @@ void llvm::initializeCore(PassRegistry &Registry) {
|
||||
initializePrintFunctionPassPass(Registry);
|
||||
initializeVerifierPass(Registry);
|
||||
initializePreVerifierPass(Registry);
|
||||
initializeTargetTransformInfoAnalysisGroup(Registry);
|
||||
}
|
||||
|
||||
void LLVMInitializeCore(LLVMPassRegistryRef R) {
|
||||
|
@ -12,20 +12,252 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
/// Default ctor.
|
||||
///
|
||||
/// @note This has to exist, because this is a pass, but it should never be
|
||||
/// used.
|
||||
TargetTransformInfo::TargetTransformInfo() : ImmutablePass(ID) {
|
||||
/// You are seeing this error because your pass required the TTI
|
||||
/// using a call to "getAnalysis<TargetTransformInfo>()", and you did
|
||||
/// not initialize a machine target which can provide the TTI.
|
||||
/// You should use "getAnalysisIfAvailable<TargetTransformInfo>()" instead.
|
||||
report_fatal_error("Bad TargetTransformInfo ctor used. "
|
||||
"Tool did not specify a TargetTransformInfo to use?");
|
||||
}
|
||||
|
||||
INITIALIZE_PASS(TargetTransformInfo, "targettransforminfo",
|
||||
"Target Transform Info", false, true)
|
||||
// Setup the analysis group to manage the TargetTransformInfo passes.
|
||||
INITIALIZE_ANALYSIS_GROUP(TargetTransformInfo, "Target Information", NoTTI)
|
||||
char TargetTransformInfo::ID = 0;
|
||||
|
||||
TargetTransformInfo::~TargetTransformInfo() {
|
||||
}
|
||||
|
||||
void TargetTransformInfo::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<TargetTransformInfo>();
|
||||
}
|
||||
|
||||
bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
|
||||
return PrevTTI->isLegalAddImmediate(Imm);
|
||||
}
|
||||
|
||||
bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const {
|
||||
return PrevTTI->isLegalICmpImmediate(Imm);
|
||||
}
|
||||
|
||||
bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
|
||||
int64_t BaseOffset,
|
||||
bool HasBaseReg,
|
||||
int64_t Scale) const {
|
||||
return PrevTTI->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
|
||||
Scale);
|
||||
}
|
||||
|
||||
bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const {
|
||||
return PrevTTI->isTruncateFree(Ty1, Ty2);
|
||||
}
|
||||
|
||||
bool TargetTransformInfo::isTypeLegal(Type *Ty) const {
|
||||
return PrevTTI->isTypeLegal(Ty);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getJumpBufAlignment() const {
|
||||
return PrevTTI->getJumpBufAlignment();
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getJumpBufSize() const {
|
||||
return PrevTTI->getJumpBufSize();
|
||||
}
|
||||
|
||||
bool TargetTransformInfo::shouldBuildLookupTables() const {
|
||||
return PrevTTI->shouldBuildLookupTables();
|
||||
}
|
||||
|
||||
TargetTransformInfo::PopcntHwSupport
|
||||
TargetTransformInfo::getPopcntHwSupport(unsigned IntTyWidthInBit) const {
|
||||
return PrevTTI->getPopcntHwSupport(IntTyWidthInBit);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty) const {
|
||||
return PrevTTI->getIntImmCost(Imm, Ty);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getNumberOfRegisters(bool Vector) const {
|
||||
return PrevTTI->getNumberOfRegisters(Vector);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getArithmeticInstrCost(unsigned Opcode,
|
||||
Type *Ty) const {
|
||||
return PrevTTI->getArithmeticInstrCost(Opcode, Ty);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getShuffleCost(ShuffleKind Kind, Type *Tp,
|
||||
int Index, Type *SubTp) const {
|
||||
return PrevTTI->getShuffleCost(Kind, Tp, Index, SubTp);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getCastInstrCost(unsigned Opcode, Type *Dst,
|
||||
Type *Src) const {
|
||||
return PrevTTI->getCastInstrCost(Opcode, Dst, Src);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getCFInstrCost(unsigned Opcode) const {
|
||||
return PrevTTI->getCFInstrCost(Opcode);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
|
||||
Type *CondTy) const {
|
||||
return PrevTTI->getCmpSelInstrCost(Opcode, ValTy, CondTy);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getVectorInstrCost(unsigned Opcode, Type *Val,
|
||||
unsigned Index) const {
|
||||
return PrevTTI->getVectorInstrCost(Opcode, Val, Index);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getMemoryOpCost(unsigned Opcode, Type *Src,
|
||||
unsigned Alignment,
|
||||
unsigned AddressSpace) const {
|
||||
return PrevTTI->getMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
|
||||
;
|
||||
}
|
||||
|
||||
unsigned
|
||||
TargetTransformInfo::getIntrinsicInstrCost(Intrinsic::ID ID,
|
||||
Type *RetTy,
|
||||
ArrayRef<Type *> Tys) const {
|
||||
return PrevTTI->getIntrinsicInstrCost(ID, RetTy, Tys);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getNumberOfParts(Type *Tp) const {
|
||||
return PrevTTI->getNumberOfParts(Tp);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class NoTTI : public ImmutablePass, public TargetTransformInfo {
|
||||
const ScalarTargetTransformInfo *STTI;
|
||||
const VectorTargetTransformInfo *VTTI;
|
||||
|
||||
public:
|
||||
// FIXME: This constructor doesn't work which breaks the use of NoTTI on the
|
||||
// commandline. This has to be fixed for NoTTI to be fully usable as an
|
||||
// analysis pass.
|
||||
NoTTI() : ImmutablePass(ID), TargetTransformInfo(0) {
|
||||
llvm_unreachable("Unsupported code path!");
|
||||
}
|
||||
|
||||
NoTTI(const ScalarTargetTransformInfo *S, const VectorTargetTransformInfo *V)
|
||||
: ImmutablePass(ID),
|
||||
TargetTransformInfo(0), // NoTTI is special and doesn't delegate here.
|
||||
STTI(S), VTTI(V) {
|
||||
initializeNoTTIPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
// Note that this subclass is special, and must *not* call
|
||||
// TTI::getAnalysisUsage as it breaks the recursion.
|
||||
}
|
||||
|
||||
/// Pass identification.
|
||||
static char ID;
|
||||
|
||||
/// Provide necessary pointer adjustments for the two base classes.
|
||||
virtual void *getAdjustedAnalysisPointer(const void *ID) {
|
||||
if (ID == &TargetTransformInfo::ID)
|
||||
return (TargetTransformInfo*)this;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Delegate all predicates through the STTI or VTTI interface.
|
||||
|
||||
bool isLegalAddImmediate(int64_t Imm) const {
|
||||
return STTI->isLegalAddImmediate(Imm);
|
||||
}
|
||||
|
||||
bool isLegalICmpImmediate(int64_t Imm) const {
|
||||
return STTI->isLegalICmpImmediate(Imm);
|
||||
}
|
||||
|
||||
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
|
||||
bool HasBaseReg, int64_t Scale) const {
|
||||
return STTI->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
|
||||
Scale);
|
||||
}
|
||||
|
||||
bool isTruncateFree(Type *Ty1, Type *Ty2) const {
|
||||
return STTI->isTruncateFree(Ty1, Ty2);
|
||||
}
|
||||
|
||||
bool isTypeLegal(Type *Ty) const {
|
||||
return STTI->isTypeLegal(Ty);
|
||||
}
|
||||
|
||||
unsigned getJumpBufAlignment() const {
|
||||
return STTI->getJumpBufAlignment();
|
||||
}
|
||||
|
||||
unsigned getJumpBufSize() const {
|
||||
return STTI->getJumpBufSize();
|
||||
}
|
||||
|
||||
bool shouldBuildLookupTables() const {
|
||||
return STTI->shouldBuildLookupTables();
|
||||
}
|
||||
|
||||
PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const {
|
||||
return (PopcntHwSupport)STTI->getPopcntHwSupport(IntTyWidthInBit);
|
||||
}
|
||||
|
||||
unsigned getIntImmCost(const APInt &Imm, Type *Ty) const {
|
||||
return STTI->getIntImmCost(Imm, Ty);
|
||||
}
|
||||
|
||||
unsigned getNumberOfRegisters(bool Vector) const {
|
||||
return VTTI->getNumberOfRegisters(Vector);
|
||||
}
|
||||
|
||||
unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const {
|
||||
return VTTI->getArithmeticInstrCost(Opcode, Ty);
|
||||
}
|
||||
|
||||
unsigned getShuffleCost(ShuffleKind Kind, Type *Tp,
|
||||
int Index = 0, Type *SubTp = 0) const {
|
||||
return VTTI->getShuffleCost((VectorTargetTransformInfo::ShuffleKind)Kind,
|
||||
Tp, Index, SubTp);
|
||||
}
|
||||
|
||||
unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
|
||||
Type *Src) const {
|
||||
return VTTI->getCastInstrCost(Opcode, Dst, Src);
|
||||
}
|
||||
|
||||
unsigned getCFInstrCost(unsigned Opcode) const {
|
||||
return VTTI->getCFInstrCost(Opcode);
|
||||
}
|
||||
|
||||
unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
|
||||
Type *CondTy = 0) const {
|
||||
return VTTI->getCmpSelInstrCost(Opcode, ValTy, CondTy);
|
||||
}
|
||||
|
||||
unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
|
||||
unsigned Index = -1) const {
|
||||
return VTTI->getVectorInstrCost(Opcode, Val, Index);
|
||||
}
|
||||
|
||||
unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
|
||||
unsigned Alignment,
|
||||
unsigned AddressSpace) const {
|
||||
return VTTI->getMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
|
||||
}
|
||||
|
||||
unsigned getIntrinsicInstrCost(Intrinsic::ID ID,
|
||||
Type *RetTy,
|
||||
ArrayRef<Type*> Tys) const {
|
||||
return VTTI->getIntrinsicInstrCost(ID, RetTy, Tys);
|
||||
}
|
||||
|
||||
unsigned getNumberOfParts(Type *Tp) const {
|
||||
return VTTI->getNumberOfParts(Tp);
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
INITIALIZE_AG_PASS(NoTTI, TargetTransformInfo, "no-tti",
|
||||
"No target information", true, true, true)
|
||||
char NoTTI::ID = 0;
|
||||
|
||||
ImmutablePass *llvm::createNoTTIPass(const ScalarTargetTransformInfo *S,
|
||||
const VectorTargetTransformInfo *V) {
|
||||
return new NoTTI(S, V);
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ using namespace llvm;
|
||||
void llvm::initializeTarget(PassRegistry &Registry) {
|
||||
initializeDataLayoutPass(Registry);
|
||||
initializeTargetLibraryInfoPass(Registry);
|
||||
initializeTargetTransformInfoPass(Registry);
|
||||
}
|
||||
|
||||
void LLVMInitializeTarget(LLVMPassRegistryRef R) {
|
||||
|
@ -321,8 +321,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
|
||||
PM.add(TLI);
|
||||
|
||||
if (target.get()) {
|
||||
PM.add(new TargetTransformInfo(target->getScalarTargetTransformInfo(),
|
||||
target->getVectorTargetTransformInfo()));
|
||||
PM.add(createNoTTIPass(target->getScalarTargetTransformInfo(),
|
||||
target->getVectorTargetTransformInfo()));
|
||||
}
|
||||
|
||||
// Add the target data from the target machine, if it exists, or the module.
|
||||
|
@ -658,8 +658,8 @@ int main(int argc, char **argv) {
|
||||
std::auto_ptr<TargetMachine> TM(Machine);
|
||||
|
||||
if (TM.get()) {
|
||||
Passes.add(new TargetTransformInfo(TM->getScalarTargetTransformInfo(),
|
||||
TM->getVectorTargetTransformInfo()));
|
||||
Passes.add(createNoTTIPass(TM->getScalarTargetTransformInfo(),
|
||||
TM->getVectorTargetTransformInfo()));
|
||||
}
|
||||
|
||||
OwningPtr<FunctionPassManager> FPasses;
|
||||
|
Loading…
Reference in New Issue
Block a user