diff options
47 files changed, 1117 insertions, 1202 deletions
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 7831d1211e..0d027006e6 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -280,6 +280,12 @@ protected: /// List of target independent CodeGen pass IDs. namespace llvm { + /// \brief Create a basic TargetTransformInfo analysis pass. + /// + /// This pass implements the target transform info analysis using the target + /// independent information available to the LLVM code generator. + ImmutablePass *createBasicTargetTransformInfoPass(const TargetLowering *TLI); + /// createUnreachableBlockEliminationPass - The LLVM code generator does not /// work well with unreachable basic blocks (what live ranges make sense for a /// block that cannot be reached?). As such, a code generator should either diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 9ee74dde1d..79037f78d3 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -69,6 +69,7 @@ void initializeArgPromotionPass(PassRegistry&); void initializeBarrierNoopPass(PassRegistry&); void initializeBasicAliasAnalysisPass(PassRegistry&); void initializeBasicCallGraphPass(PassRegistry&); +void initializeBasicTTIPass(PassRegistry&); void initializeBlockExtractorPassPass(PassRegistry&); void initializeBlockFrequencyInfoPass(PassRegistry&); void initializeBlockPlacementPass(PassRegistry&); diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index ce6abc5170..8359a5c68c 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -895,6 +895,18 @@ public: } //===--------------------------------------------------------------------===// + /// \name Helpers for TargetTransformInfo implementations + /// @{ + + /// Get the ISD node that corresponds to the Instruction class opcode. + int InstructionOpcodeToISD(unsigned Opcode) const; + + /// Estimate the cost of type-legalization and the legalized type. + std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const; + + /// @} + + //===--------------------------------------------------------------------===// // TargetLowering Optimization Methods // diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 5756f2c552..aa049f02fc 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -108,10 +108,6 @@ public: virtual const TargetLowering *getTargetLowering() const { return 0; } virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; } virtual const DataLayout *getDataLayout() const { return 0; } - virtual const ScalarTargetTransformInfo* - getScalarTargetTransformInfo() const { return 0; } - virtual const VectorTargetTransformInfo* - getVectorTargetTransformInfo() const { return 0; } /// getMCAsmInfo - Return target specific asm information. /// @@ -232,6 +228,9 @@ public: /// sections. static void setFunctionSections(bool); + /// \brief Register analysis passes for this target with a pass manager. + virtual void addAnalysisPasses(PassManagerBase &) {} + /// CodeGenFileType - These enums are meant to be passed into /// addPassesToEmitFile to indicate what type of file to emit, and returned by /// it to indicate what type of file could actually be made. @@ -290,6 +289,11 @@ protected: // Can only create subclasses. CodeGenOpt::Level OL); public: + /// \brief Register analysis passes for this target with a pass manager. + /// + /// This registers target independent analysis passes. + virtual void addAnalysisPasses(PassManagerBase &PM); + /// createPassConfig - Create a pass configuration object to be used by /// addPassToEmitX methods for generating a pipeline of CodeGen passes. virtual TargetPassConfig *createPassConfig(PassManagerBase &PM); diff --git a/include/llvm/Target/TargetTransformImpl.h b/include/llvm/Target/TargetTransformImpl.h deleted file mode 100644 index 2069927619..0000000000 --- a/include/llvm/Target/TargetTransformImpl.h +++ /dev/null @@ -1,104 +0,0 @@ -//=- llvm/Target/TargetTransformImpl.h - Target Loop Trans Info----*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the target-specific implementations of the -// TargetTransform interfaces. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H -#define LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H - -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/TargetTransformInfo.h" - -namespace llvm { - -class TargetLowering; - -/// ScalarTargetTransformInfo - This is a default implementation for the -/// ScalarTargetTransformInfo interface. Different targets can implement -/// this interface differently. -class ScalarTargetTransformImpl : public ScalarTargetTransformInfo { -protected: - const TargetLowering *TLI; - -public: - /// Ctor - explicit ScalarTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {} - - virtual bool isLegalAddImmediate(int64_t imm) const; - - virtual bool isLegalICmpImmediate(int64_t imm) const; - - virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, - int64_t BaseOffset, bool HasBaseReg, - int64_t Scale) const; - - virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; - - virtual bool isTypeLegal(Type *Ty) const; - - virtual unsigned getJumpBufAlignment() const; - - virtual unsigned getJumpBufSize() const; - - virtual bool shouldBuildLookupTables() const; -}; - -class VectorTargetTransformImpl : public VectorTargetTransformInfo { -protected: - const TargetLowering *TLI; - - /// Estimate the cost of type-legalization and the legalized type. - std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const; - - /// Estimate the overhead of scalarizing an instruction. Insert and Extract - /// are set if the result needs to be inserted and/or extracted from vectors. - unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const; - - // Get the ISD node that corresponds to the Instruction class opcode. - int InstructionOpcodeToISD(unsigned Opcode) const; - -public: - explicit VectorTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {} - - virtual ~VectorTargetTransformImpl() {} - - virtual unsigned getNumberOfRegisters(bool Vector) const; - - virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const; - - virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, - int Index, Type *SubTp) const; - - virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, - Type *Src) const; - - virtual unsigned getCFInstrCost(unsigned Opcode) const; - - virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - Type *CondTy) const; - - virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, - unsigned Index) const; - - virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, - unsigned Alignment, - unsigned AddressSpace) const; - - virtual unsigned getIntrinsicInstrCost(Intrinsic::ID, Type *RetTy, - ArrayRef<Type*> Tys) const; - - virtual unsigned getNumberOfParts(Type *Tp) const; -}; - -} // end llvm namespace - -#endif diff --git a/include/llvm/TargetTransformInfo.h b/include/llvm/TargetTransformInfo.h index 97d0304a38..253960da27 100644 --- a/include/llvm/TargetTransformInfo.h +++ b/include/llvm/TargetTransformInfo.h @@ -30,9 +30,6 @@ namespace llvm { -class ScalarTargetTransformInfo; -class VectorTargetTransformInfo; - /// TargetTransformInfo - This pass provides access to the codegen /// interfaces that are needed for IR-level transformations. class TargetTransformInfo { @@ -42,11 +39,26 @@ protected: /// 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; + 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) {} + /// \brief The top of the stack of TTI analyses available. + /// + /// This is a convenience routine maintained as TTI analyses become available + /// that complements the PrevTTI delegation chain. When one part of an + /// analysis pass wants to query another part of the analysis pass it can use + /// this to start back at the top of the stack. + TargetTransformInfo *TopTTI; + + /// All pass subclasses must in their initializePass routine call + /// pushTTIStack with themselves to update the pointers tracking the previous + /// TTI instance in the analysis group's stack, and the top of the analysis + /// group's stack. + void pushTTIStack(Pass *P); + + /// All pass subclasses must in their finalizePass routine call popTTIStack + /// to update the pointers tracking the previous TTI instance in the analysis + /// group's stack, and the top of the analysis group's stack. + void popTTIStack(); /// All pass subclasses must call TargetTransformInfo::getAnalysisUsage. virtual void getAnalysisUsage(AnalysisUsage &AU) const; @@ -184,177 +196,7 @@ public: /// 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. -// ---------------------------------------------------------------------------// - -/// ScalarTargetTransformInfo - This interface is used by IR-level passes -/// that need target-dependent information for generic scalar transformations. -/// LSR, and LowerInvoke use this interface. -class ScalarTargetTransformInfo { -public: - /// 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 - }; - - virtual ~ScalarTargetTransformInfo() {} - - /// 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) const { - return false; - } - /// 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) const { - return false; - } - /// 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 { - return false; - } - /// 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 { - return false; - } - /// Is this type legal. - virtual bool isTypeLegal(Type *Ty) const { - return false; - } - /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes - virtual unsigned getJumpBufAlignment() const { - return 0; - } - /// getJumpBufSize - returns the target's jmp_buf size in bytes. - virtual unsigned getJumpBufSize() const { - return 0; - } - /// shouldBuildLookupTables - Return true if switches should be turned into - /// lookup tables for the target. - virtual bool shouldBuildLookupTables() const { - return true; - } - /// getPopcntHwSupport - Return hardware support for population count. - 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 { - // The default assumption is that the immediate is cheap. - return 1; - } -}; - -/// VectorTargetTransformInfo - This interface is used by the vectorizers -/// to estimate the profitability of vectorization for different instructions. -/// This interface provides the cost of different IR instructions. The cost -/// is unit-less and represents the estimated throughput of the instruction -/// (not the latency!) assuming that all branches are predicted, cache is hit, -/// etc. -class VectorTargetTransformInfo { -public: - virtual ~VectorTargetTransformInfo() {} - - 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 8; - } - - /// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc. - virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const { - return 1; - } - - /// \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 1; - } - - /// \return The expected cost of cast instructions, such as bitcast, trunc, - /// zext, etc. - virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, - Type *Src) const { - return 1; - } - - /// \return The expected cost of control-flow related instrutctions such as - /// Phi, Ret, Br. - virtual unsigned getCFInstrCost(unsigned Opcode) const { - return 1; - } - - /// \returns The expected cost of compare and select instructions. - virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - Type *CondTy = 0) const { - return 1; - } - - /// \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 1; - } - - /// \return The cost of Load and Store instructions. - virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, - unsigned Alignment, - unsigned AddressSpace) const { - return 1; - } - - /// \returns The cost of Intrinsic instructions. - virtual unsigned getIntrinsicInstrCost(Intrinsic::ID, - Type *RetTy, - ArrayRef<Type*> Tys) const { - return 1; - } - - /// \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 { - return 0; - } -}; - +ImmutablePass *createNoTargetTransformInfoPass(); } // End llvm namespace diff --git a/lib/CodeGen/BasicTargetTransformInfo.cpp b/lib/CodeGen/BasicTargetTransformInfo.cpp new file mode 100644 index 0000000000..bafe3da1d2 --- /dev/null +++ b/lib/CodeGen/BasicTargetTransformInfo.cpp @@ -0,0 +1,383 @@ +//===- BasicTargetTransformInfo.cpp - Basic target-independent TTI impl ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file provides the implementation of a basic TargetTransformInfo pass +/// predicated on the target abstractions present in the target independent +/// code generator. It uses these (primarily TargetLowering) to model as much +/// of the TTI query interface as possible. It is included by most targets so +/// that they can specialize only a small subset of the query space. +/// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "basictti" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/TargetTransformInfo.h" +#include <utility> + +using namespace llvm; + +namespace { + +class BasicTTI : public ImmutablePass, public TargetTransformInfo { + const TargetLowering *TLI; + + /// Estimate the overhead of scalarizing an instruction. Insert and Extract + /// are set if the result needs to be inserted and/or extracted from vectors. + unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const; + +public: + BasicTTI() : ImmutablePass(ID), TLI(0) { + llvm_unreachable("This pass cannot be directly constructed"); + } + + BasicTTI(const TargetLowering *TLI) : ImmutablePass(ID), TLI(TLI) { + initializeBasicTTIPass(*PassRegistry::getPassRegistry()); + } + + virtual void initializePass() { + pushTTIStack(this); + } + + virtual void finalizePass() { + popTTIStack(); + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + TargetTransformInfo::getAnalysisUsage(AU); + } + + /// 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; + } + + /// \name Scalar TTI Implementations + /// @{ + + virtual bool isLegalAddImmediate(int64_t imm) const; + virtual bool isLegalICmpImmediate(int64_t imm) const; + virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, + int64_t BaseOffset, bool HasBaseReg, + int64_t Scale) const; + virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; + virtual bool isTypeLegal(Type *Ty) const; + virtual unsigned getJumpBufAlignment() const; + virtual unsigned getJumpBufSize() const; + virtual bool shouldBuildLookupTables() const; + + /// @} + + /// \name Vector TTI Implementations + /// @{ + + virtual unsigned getNumberOfRegisters(bool Vector) const; + virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const; + virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, + int Index, Type *SubTp) const; + virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, + Type *Src) const; + virtual unsigned getCFInstrCost(unsigned Opcode) const; + virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, + Type *CondTy) const; + virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, + unsigned Index) const; + virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, + unsigned Alignment, + unsigned AddressSpace) const; + virtual unsigned getIntrinsicInstrCost(Intrinsic::ID, Type *RetTy, + ArrayRef<Type*> Tys) const; + virtual unsigned getNumberOfParts(Type *Tp) const; + + /// @} +}; + +} + +INITIALIZE_AG_PASS(BasicTTI, TargetTransformInfo, "basictti", + "Target independent code generator's TTI", true, true, false) +char BasicTTI::ID = 0; + +ImmutablePass * +llvm::createBasicTargetTransformInfoPass(const TargetLowering *TLI) { + return new BasicTTI(TLI); +} + + +bool BasicTTI::isLegalAddImmediate(int64_t imm) const { + return TLI->isLegalAddImmediate(imm); +} + +bool BasicTTI::isLegalICmpImmediate(int64_t imm) const { + return TLI->isLegalICmpImmediate(imm); +} + +bool BasicTTI::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, + int64_t BaseOffset, bool HasBaseReg, + int64_t Scale) const { + AddrMode AM; + AM.BaseGV = BaseGV; + AM.BaseOffs = BaseOffset; + AM.HasBaseReg = HasBaseReg; + AM.Scale = Scale; + return TLI->isLegalAddressingMode(AM, Ty); +} + +bool BasicTTI::isTruncateFree(Type *Ty1, Type *Ty2) const { + return TLI->isTruncateFree(Ty1, Ty2); +} + +bool BasicTTI::isTypeLegal(Type *Ty) const { + EVT T = TLI->getValueType(Ty); + return TLI->isTypeLegal(T); +} + +unsigned BasicTTI::getJumpBufAlignment() const { + return TLI->getJumpBufAlignment(); +} + +unsigned BasicTTI::getJumpBufSize() const { + return TLI->getJumpBufSize(); +} + +bool BasicTTI::shouldBuildLookupTables() const { + return TLI->supportJumpTables() && + (TLI->isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) || + TLI->isOperationLegalOrCustom(ISD::BRIND, MVT::Other)); +} + +//===----------------------------------------------------------------------===// +// +// Calls used by the vectorizers. +// +//===----------------------------------------------------------------------===// + +unsigned BasicTTI::getScalarizationOverhead(Type *Ty, bool Insert, + bool Extract) const { + assert (Ty->isVectorTy() && "Can only scalarize vectors"); + unsigned Cost = 0; + + for (int i = 0, e = Ty->getVectorNumElements(); i < e; ++i) { + if (Insert) + Cost += TopTTI->getVectorInstrCost(Instruction::InsertElement, Ty, i); + if (Extract) + Cost += TopTTI->getVectorInstrCost(Instruction::ExtractElement, Ty, i); + } + + return Cost; +} + +unsigned BasicTTI::getNumberOfRegisters(bool Vector) const { + return 1; +} + +unsigned BasicTTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty) const { + // Check if any of the operands are vector operands. + int ISD = TLI->InstructionOpcodeToISD(Opcode); + assert(ISD && "Invalid opcode"); + + std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Ty); + + if (TLI->isOperationLegalOrPromote(ISD, LT.second)) { + // The operation is legal. Assume it costs 1. + // If the type is split to multiple registers, assume that thre is some + // overhead to this. + // TODO: Once we have extract/insert subvector cost we need to use them. + if (LT.first > 1) + return LT.first * 2; + return LT.first * 1; + } + + if (!TLI->isOperationExpand(ISD, LT.second)) { + // If the operation is custom lowered then assume + // thare the code is twice as expensive. + return LT.first * 2; + } + + // Else, assume that we need to scalarize this op. + if (Ty->isVectorTy()) { + unsigned Num = Ty->getVectorNumElements(); + unsigned Cost = TopTTI->getArithmeticInstrCost(Opcode, Ty->getScalarType()); + // return the cost of multiple s |