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:
Chandler Carruth 2013-01-05 11:43:11 +00:00
parent be73c7b903
commit 7bdf6b00e0
7 changed files with 412 additions and 222 deletions

View File

@ -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&);

View File

@ -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

View File

@ -41,6 +41,7 @@ void llvm::initializeCore(PassRegistry &Registry) {
initializePrintFunctionPassPass(Registry);
initializeVerifierPass(Registry);
initializePreVerifierPass(Registry);
initializeTargetTransformInfoAnalysisGroup(Registry);
}
void LLVMInitializeCore(LLVMPassRegistryRef R) {

View File

@ -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);
}

View File

@ -26,7 +26,6 @@ using namespace llvm;
void llvm::initializeTarget(PassRegistry &Registry) {
initializeDataLayoutPass(Registry);
initializeTargetLibraryInfoPass(Registry);
initializeTargetTransformInfoPass(Registry);
}
void LLVMInitializeTarget(LLVMPassRegistryRef R) {

View File

@ -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.

View File

@ -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;