mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +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 initializeTailDuplicatePassPass(PassRegistry&);
|
||||||
void initializeTargetPassConfigPass(PassRegistry&);
|
void initializeTargetPassConfigPass(PassRegistry&);
|
||||||
void initializeDataLayoutPass(PassRegistry&);
|
void initializeDataLayoutPass(PassRegistry&);
|
||||||
void initializeTargetTransformInfoPass(PassRegistry&);
|
void initializeTargetTransformInfoAnalysisGroup(PassRegistry&);
|
||||||
|
void initializeNoTTIPass(PassRegistry&);
|
||||||
void initializeTargetLibraryInfoPass(PassRegistry&);
|
void initializeTargetLibraryInfoPass(PassRegistry&);
|
||||||
void initializeTwoAddressInstructionPassPass(PassRegistry&);
|
void initializeTwoAddressInstructionPassPass(PassRegistry&);
|
||||||
void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
|
void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
|
||||||
|
@ -30,6 +30,164 @@
|
|||||||
|
|
||||||
namespace llvm {
|
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
|
// The classes below are inherited and implemented by target-specific classes
|
||||||
// in the codegen.
|
// 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
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -41,6 +41,7 @@ void llvm::initializeCore(PassRegistry &Registry) {
|
|||||||
initializePrintFunctionPassPass(Registry);
|
initializePrintFunctionPassPass(Registry);
|
||||||
initializeVerifierPass(Registry);
|
initializeVerifierPass(Registry);
|
||||||
initializePreVerifierPass(Registry);
|
initializePreVerifierPass(Registry);
|
||||||
|
initializeTargetTransformInfoAnalysisGroup(Registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMInitializeCore(LLVMPassRegistryRef R) {
|
void LLVMInitializeCore(LLVMPassRegistryRef R) {
|
||||||
|
@ -12,20 +12,252 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
/// Default ctor.
|
// Setup the analysis group to manage the TargetTransformInfo passes.
|
||||||
///
|
INITIALIZE_ANALYSIS_GROUP(TargetTransformInfo, "Target Information", NoTTI)
|
||||||
/// @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)
|
|
||||||
char TargetTransformInfo::ID = 0;
|
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) {
|
void llvm::initializeTarget(PassRegistry &Registry) {
|
||||||
initializeDataLayoutPass(Registry);
|
initializeDataLayoutPass(Registry);
|
||||||
initializeTargetLibraryInfoPass(Registry);
|
initializeTargetLibraryInfoPass(Registry);
|
||||||
initializeTargetTransformInfoPass(Registry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMInitializeTarget(LLVMPassRegistryRef R) {
|
void LLVMInitializeTarget(LLVMPassRegistryRef R) {
|
||||||
|
@ -321,7 +321,7 @@ static int compileModule(char **argv, LLVMContext &Context) {
|
|||||||
PM.add(TLI);
|
PM.add(TLI);
|
||||||
|
|
||||||
if (target.get()) {
|
if (target.get()) {
|
||||||
PM.add(new TargetTransformInfo(target->getScalarTargetTransformInfo(),
|
PM.add(createNoTTIPass(target->getScalarTargetTransformInfo(),
|
||||||
target->getVectorTargetTransformInfo()));
|
target->getVectorTargetTransformInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,7 +658,7 @@ int main(int argc, char **argv) {
|
|||||||
std::auto_ptr<TargetMachine> TM(Machine);
|
std::auto_ptr<TargetMachine> TM(Machine);
|
||||||
|
|
||||||
if (TM.get()) {
|
if (TM.get()) {
|
||||||
Passes.add(new TargetTransformInfo(TM->getScalarTargetTransformInfo(),
|
Passes.add(createNoTTIPass(TM->getScalarTargetTransformInfo(),
|
||||||
TM->getVectorTargetTransformInfo()));
|
TM->getVectorTargetTransformInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user