diff options
Diffstat (limited to 'include/llvm/Target')
-rw-r--r-- | include/llvm/Target/Mangler.h | 67 | ||||
-rw-r--r-- | include/llvm/Target/Target.td | 44 | ||||
-rw-r--r-- | include/llvm/Target/TargetCallingConv.h | 6 | ||||
-rw-r--r-- | include/llvm/Target/TargetCallingConv.td | 14 | ||||
-rw-r--r-- | include/llvm/Target/TargetLibraryInfo.h | 24 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 157 | ||||
-rw-r--r-- | include/llvm/Target/TargetLoweringObjectFile.h | 139 | ||||
-rw-r--r-- | include/llvm/Target/TargetMachine.h | 42 | ||||
-rw-r--r-- | include/llvm/Target/TargetOpcodes.h | 168 | ||||
-rw-r--r-- | include/llvm/Target/TargetOptions.h | 79 | ||||
-rw-r--r-- | include/llvm/Target/TargetRegisterInfo.h | 26 | ||||
-rw-r--r-- | include/llvm/Target/TargetSchedule.td | 48 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAG.td | 15 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAGInfo.h | 4 |
14 files changed, 468 insertions, 365 deletions
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h deleted file mode 100644 index eee7bf6..0000000 --- a/include/llvm/Target/Mangler.h +++ /dev/null @@ -1,67 +0,0 @@ -//===-- llvm/Target/Mangler.h - Self-contained name mangler -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Unified name mangler for various backends. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_MANGLER_H -#define LLVM_TARGET_MANGLER_H - -#include "llvm/ADT/DenseMap.h" - -namespace llvm { - -class GlobalValue; -class MCContext; -template <typename T> class SmallVectorImpl; -class TargetMachine; -class Twine; - -class Mangler { -public: - enum ManglerPrefixTy { - Default, ///< Emit default string before each symbol. - Private, ///< Emit "private" prefix before each symbol. - LinkerPrivate ///< Emit "linker private" prefix before each symbol. - }; - -private: - const TargetMachine *TM; - - /// AnonGlobalIDs - We need to give global values the same name every time - /// they are mangled. This keeps track of the number we give to anonymous - /// ones. - /// - DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs; - - /// NextAnonGlobalID - This simple counter is used to unique value names. - /// - unsigned NextAnonGlobalID; - -public: - Mangler(const TargetMachine *TM) : TM(TM), NextAnonGlobalID(1) {} - - /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix - /// and the specified global variable's name. If the global variable doesn't - /// have a name, this fills in a unique name for the global. - void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, - bool isImplicitlyPrivate, bool UseGlobalPrefix = true); - - /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix - /// and the specified name as the global variable name. GVName must not be - /// empty. - void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName, - ManglerPrefixTy PrefixTy = Mangler::Default, - bool UseGlobalPrefix = true); -}; - -} // End llvm namespace - -#endif // LLVM_TARGET_MANGLER_H diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 3f6eae6..facb89a 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -685,6 +685,27 @@ class InstrInfo { // // This option is a temporary migration help. It will go away. bit guessInstructionProperties = 1; + + // TableGen's instruction encoder generator has support for matching operands + // to bit-field variables both by name and by position. While matching by + // name is preferred, this is currently not possible for complex operands, + // and some targets still reply on the positional encoding rules. When + // generating a decoder for such targets, the positional encoding rules must + // be used by the decoder generator as well. + // + // This option is temporary; it will go away once the TableGen decoder + // generator has better support for complex operands and targets have + // migrated away from using positionally encoded operands. + bit decodePositionallyEncodedOperands = 0; + + // When set, this indicates that there will be no overlap between those + // operands that are matched by ordering (positional operands) and those + // matched by name. + // + // This option is temporary; it will go away once the TableGen decoder + // generator has better support for complex operands and targets have + // migrated away from using positionally encoded operands. + bit noNamedPositionallyEncodedOperands = 0; } // Standard Pseudo Instructions. @@ -702,7 +723,7 @@ def INLINEASM : Instruction { let AsmString = ""; let neverHasSideEffects = 1; // Note side effect is encoded in an operand. } -def PROLOG_LABEL : Instruction { +def CFI_INSTRUCTION : Instruction { let OutOperandList = (outs); let InOperandList = (ins i32imm:$id); let AsmString = ""; @@ -802,16 +823,18 @@ def LIFETIME_END : Instruction { } def STACKMAP : Instruction { let OutOperandList = (outs); - let InOperandList = (ins i32imm:$id, i32imm:$nbytes, variable_ops); + let InOperandList = (ins i64imm:$id, i32imm:$nbytes, variable_ops); let isCall = 1; let mayLoad = 1; + let usesCustomInserter = 1; } def PATCHPOINT : Instruction { let OutOperandList = (outs unknown:$dst); - let InOperandList = (ins i32imm:$id, i32imm:$nbytes, unknown:$callee, + let InOperandList = (ins i64imm:$id, i32imm:$nbytes, unknown:$callee, i32imm:$nargs, i32imm:$cc, variable_ops); let isCall = 1; let mayLoad = 1; + let usesCustomInserter = 1; } } @@ -947,7 +970,7 @@ class AsmWriter { // AsmWriterClassName - This specifies the suffix to use for the asmwriter // class. Generated AsmWriter classes are always prefixed with the target // name. - string AsmWriterClassName = "AsmPrinter"; + string AsmWriterClassName = "InstPrinter"; // Variant - AsmWriters can be of multiple different variants. Variants are // used to support targets that need to emit assembly code in ways that are @@ -957,21 +980,8 @@ class AsmWriter { // == 1, will expand to "y". int Variant = 0; - - // FirstOperandColumn/OperandSpacing - If the assembler syntax uses a columnar - // layout, the asmwriter can actually generate output in this columns (in - // verbose-asm mode). These two values indicate the width of the first column - // (the "opcode" area) and the width to reserve for subsequent operands. When - // verbose asm mode is enabled, operands will be indented to respect this. - int FirstOperandColumn = -1; - // OperandSpacing - Space between operand columns. int OperandSpacing = -1; - - // isMCAsmWriter - Is this assembly writer for an MC emitter? This controls - // generation of the printInstruction() method. For MC printers, it takes - // an MCInstr* operand, otherwise it takes a MachineInstr*. - bit isMCAsmWriter = 0; } def DefaultAsmWriter : AsmWriter; diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h index 9cc52a5..a660403 100644 --- a/include/llvm/Target/TargetCallingConv.h +++ b/include/llvm/Target/TargetCallingConv.h @@ -14,6 +14,7 @@ #ifndef LLVM_TARGET_TARGETCALLINGCONV_H #define LLVM_TARGET_TARGETCALLINGCONV_H +#include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/MathExtras.h" #include <string> @@ -42,6 +43,8 @@ namespace ISD { static const uint64_t ByValAlignOffs = 7; static const uint64_t Split = 1ULL<<11; static const uint64_t SplitOffs = 11; + static const uint64_t InAlloca = 1ULL<<12; ///< Passed with inalloca + static const uint64_t InAllocaOffs = 12; static const uint64_t OrigAlign = 0x1FULL<<27; static const uint64_t OrigAlignOffs = 27; static const uint64_t ByValSize = 0xffffffffULL<<32; ///< Struct size @@ -68,6 +71,9 @@ namespace ISD { bool isByVal() const { return Flags & ByVal; } void setByVal() { Flags |= One << ByValOffs; } + bool isInAlloca() const { return Flags & InAlloca; } + void setInAlloca() { Flags |= One << InAllocaOffs; } + bool isNest() const { return Flags & Nest; } void setNest() { Flags |= One << NestOffs; } diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td index c1bef28..9d1dc38 100644 --- a/include/llvm/Target/TargetCallingConv.td +++ b/include/llvm/Target/TargetCallingConv.td @@ -89,11 +89,15 @@ class CCAssignToStack<int size, int align> : CCAction { int Align = align; } -/// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a register -/// to be shadowed. -class CCAssignToStackWithShadow<int size, int align, Register reg> : - CCAssignToStack<size, align> { - Register ShadowReg = reg; +/// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a list of +/// registers to be shadowed. Note that, unlike CCAssignToRegWithShadow, this +/// shadows ALL of the registers in shadowList. +class CCAssignToStackWithShadow<int size, + int align, + list<Register> shadowList> : CCAction { + int Size = size; + int Align = align; + list<Register> ShadowRegList = shadowList; } /// CCPassByVal - This action always matches: it assigns the value to a stack diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h index 46eaef2..d4f9f23 100644 --- a/include/llvm/Target/TargetLibraryInfo.h +++ b/include/llvm/Target/TargetLibraryInfo.h @@ -67,8 +67,8 @@ namespace llvm { memcpy_chk, /// double __sincospi_stret(double x); sincospi_stret, - /// float __sincospi_stretf(float x); - sincospi_stretf, + /// float __sincospif_stret(float x); + sincospif_stret, /// double __sinpi(double x); sinpi, /// float __sinpif(float x); @@ -251,6 +251,18 @@ namespace llvm { floorf, /// long double floorl(long double x); floorl, + /// double fmax(double x, double y); + fmax, + /// float fmaxf(float x, float y); + fmaxf, + /// long double fmaxl(long double x, long double y); + fmaxl, + /// double fmin(double x, double y); + fmin, + /// float fminf(float x, float y); + fminf, + /// long double fminl(long double x, long double y); + fminl, /// double fmod(double x, double y); fmod, /// float fmodf(float x, float y); @@ -340,6 +352,12 @@ namespace llvm { labs, /// int lchown(const char *path, uid_t owner, gid_t group); lchown, + /// double ldexp(double x, int n); + ldexp, + /// float ldexpf(float x, int n); + ldexpf, + /// long double ldexpl(long double x, int n); + ldexpl, /// long long int llabs(long long int j); llabs, /// double log(double x); @@ -703,6 +721,8 @@ public: case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl: case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite: case LibFunc::sqrtl_finite: + case LibFunc::fmax: case LibFunc::fmaxf: case LibFunc::fmaxl: + case LibFunc::fmin: case LibFunc::fminf: case LibFunc::fminl: case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl: case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl: case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill: diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 5ab04f7..2f6445f 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -28,9 +28,9 @@ #include "llvm/CodeGen/RuntimeLibcalls.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/InlineAsm.h" -#include "llvm/Support/CallSite.h" #include "llvm/Target/TargetCallingConv.h" #include "llvm/Target/TargetMachine.h" #include <climits> @@ -48,8 +48,10 @@ namespace llvm { class MachineFunction; class MachineInstr; class MachineJumpTableInfo; + class Mangler; class MCContext; class MCExpr; + class MCSymbol; template<typename T> class SmallVectorImpl; class DataLayout; class TargetRegisterClass; @@ -143,7 +145,7 @@ protected: public: const TargetMachine &getTargetMachine() const { return TM; } - const DataLayout *getDataLayout() const { return TD; } + const DataLayout *getDataLayout() const { return DL; } const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; } bool isBigEndian() const { return !IsLittleEndian; } @@ -173,10 +175,30 @@ public: return true; } + /// Return true if multiple condition registers are available. + bool hasMultipleConditionRegisters() const { + return HasMultipleConditionRegisters; + } + /// Return true if a vector of the given type should be split /// (TypeSplitVector) instead of promoted (TypePromoteInteger) during type /// legalization. - virtual bool shouldSplitVectorElementType(EVT /*VT*/) const { return false; } + virtual bool shouldSplitVectorType(EVT /*VT*/) const { return false; } + + // There are two general methods for expanding a BUILD_VECTOR node: + // 1. Use SCALAR_TO_VECTOR on the defined scalar values and then shuffle + // them together. + // 2. Build the vector on the stack and then load it. + // If this function returns true, then method (1) will be used, subject to + // the constraint that all of the necessary shuffles are legal (as determined + // by isShuffleMaskLegal). If this function returns false, then method (2) is + // always used. The vector type, and the number of defined values, are + // provided. + virtual bool + shouldExpandBuildVectorWithShuffles(EVT /* VT */, + unsigned DefinedValues) const { + return DefinedValues < 3; + } /// Return true if integer divide is usually cheaper than a sequence of /// several shifts, adds, and multiplies for this target. @@ -215,6 +237,21 @@ public: return true; } + /// \brief Return if the target supports combining a + /// chain like: + /// \code + /// %andResult = and %val1, #imm-with-one-bit-set; + /// %icmpResult = icmp %andResult, 0 + /// br i1 %icmpResult, label %dest1, label %dest2 + /// \endcode + /// into a single machine instruction of a form like: + /// \code + /// brOnBitSet %register, #bitNumber, dest + /// \endcode + bool isMaskAndBranchFoldingLegal() const { + return MaskAndBranchFoldingIsLegal; + } + /// Return the ValueType of the result of SETCC operations. Also used to /// obtain the target's preferred type for the condition operand of SELECT and /// BRCOND nodes. In the case of BRCOND the argument passed is MVT::Other @@ -604,8 +641,9 @@ public: return getValueType(Ty, AllowUnknown).getSimpleVT(); } - /// Return the desired alignment for ByVal aggregate function arguments in the - /// caller parameter area. This is the actual alignment, not its logarithm. + /// Return the desired alignment for ByVal or InAlloca aggregate function + /// arguments in the caller parameter area. This is the actual alignment, not + /// its logarithm. virtual unsigned getByValTypeAlignment(Type *Ty) const; /// Return the type of registers that this ValueType will eventually require. @@ -707,14 +745,16 @@ public: /// \brief Determine if the target supports unaligned memory accesses. /// - /// This function returns true if the target allows unaligned memory accesses. - /// of the specified type. If true, it also returns whether the unaligned - /// memory access is "fast" in the second argument by reference. This is used, - /// for example, in situations where an array copy/move/set is converted to a - /// sequence of store operations. It's use helps to ensure that such - /// replacements don't generate code that causes an alignment error (trap) on - /// the target machine. - virtual bool allowsUnalignedMemoryAccesses(EVT, bool * /*Fast*/ = 0) const { + /// This function returns true if the target allows unaligned memory accesses + /// of the specified type in the given address space. If true, it also returns + /// whether the unaligned memory access is "fast" in the third argument by + /// reference. This is used, for example, in situations where an array + /// copy/move/set is converted to a sequence of store operations. Its use + /// helps to ensure that such replacements don't generate code that causes an + /// alignment error (trap) on the target machine. + virtual bool allowsUnalignedMemoryAccesses(EVT, + unsigned AddrSpace = 0, + bool * /*Fast*/ = 0) const { return false; } @@ -880,13 +920,13 @@ protected: } /// Indicate whether this target prefers to use _setjmp to implement - /// llvm.setjmp or the non _ version. Defaults to false. + /// llvm.setjmp or the version without _. Defaults to false. void setUseUnderscoreSetJmp(bool Val) { UseUnderscoreSetJmp = Val; } /// Indicate whether this target prefers to use _longjmp to implement - /// llvm.longjmp or the non _ version. Defaults to false. + /// llvm.longjmp or the version without _. Defaults to false. void setUseUnderscoreLongJmp(bool Val) { UseUnderscoreLongJmp = Val; } @@ -926,6 +966,15 @@ protected: SelectIsExpensive = isExpensive; } + /// Tells the code generator that the target has multiple (allocatable) + /// condition registers that can be used to store the results of comparisons + /// for use by selects and conditional branches. With multiple condition + /// registers, the code generator will not aggressively sink comparisons into + /// the blocks of their users. + void setHasMultipleConditionRegisters(bool hasManyRegs = true) { + HasMultipleConditionRegisters = hasManyRegs; + } + /// Tells the code generator not to expand sequence of operations into a /// separate sequences that increases the amount of flow control. void setJumpIsExpensive(bool isExpensive = true) { @@ -1166,6 +1215,14 @@ public: return true; } + /// Return true if it's significantly cheaper to shift a vector by a uniform + /// scalar than by an amount which will vary across each lane. On x86, for + /// example, there is a "psllw" instruction for the former case, but no simple + /// instruction for a general "a << b" operation on vectors. + virtual bool isVectorShiftByScalarCheap(Type *Ty) const { + return false; + } + /// 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. @@ -1273,6 +1330,15 @@ public: return false; } + /// \brief Return true if it is beneficial to convert a load of a constant to + /// just the constant itself. + /// On some targets it might be more efficient to use a combination of + /// arithmetic instructions to materialize the constant instead of loading it + /// from a constant pool. + virtual bool shouldConvertConstantLoadToIntImm(const APInt &Imm, + Type *Ty) const { + return false; + } //===--------------------------------------------------------------------===// // Runtime Library hooks // @@ -1311,7 +1377,7 @@ public: private: const TargetMachine &TM; - const DataLayout *TD; + const DataLayout *DL; const TargetLoweringObjectFile &TLOF; /// True if this is a little endian target. @@ -1321,6 +1387,13 @@ private: /// the select operations if possible. bool SelectIsExpensive; + /// Tells the code generator that the target has multiple (allocatable) + /// condition registers that can be used to store the results of comparisons + /// for use by selects and conditional branches. With multiple condition + /// registers, the code generator will not aggressively sink comparisons into + /// the blocks of their users. + bool HasMultipleConditionRegisters; + /// Tells the code generator not to expand integer divides by constants into a /// sequence of muls, adds, and shifts. This is a hack until a real cost /// model is in place. If we ever optimize for size, this will be set to true @@ -1681,10 +1754,18 @@ protected: /// the branch is usually predicted right. bool PredictableSelectIsExpensive; + /// MaskAndBranchFoldingIsLegal - Indicates if the target supports folding + /// a mask of a single bit, a compare, and a branch into a single instruction. + bool MaskAndBranchFoldingIsLegal; + protected: /// Return true if the value types that can be represented by the specified /// register class are all legal. bool isLegalRC(const TargetRegisterClass *RC) const; + + /// Replace/modify any TargetFrameIndex operands with a targte-dependent + /// sequence of memory operands that is recognized by PrologEpilogInserter. + MachineBasicBlock *emitPatchPoint(MachineInstr *MI, MachineBasicBlock *MBB) const; }; /// This class defines information used to lower LLVM code to legal SelectionDAG @@ -1853,6 +1934,14 @@ public: void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO); }; + /// Return if the N is a constant or constant vector equal to the true value + /// from getBooleanContents(). + bool isConstTrueVal(const SDNode *N) const; + + /// Return if the N is a constant or constant vector equal to the false value + /// from getBooleanContents(). + bool isConstFalseVal(const SDNode *N) const; + /// Try to simplify a setcc built with the specified operands and cc. If it is /// unable to simplify it, return a null SDValue. SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, @@ -1931,12 +2020,13 @@ public: bool isSRet : 1; bool isNest : 1; bool isByVal : 1; + bool isInAlloca : 1; bool isReturned : 1; uint16_t Alignment; ArgListEntry() : isSExt(false), isZExt(false), isInReg(false), - isSRet(false), isNest(false), isByVal(false), isReturned(false), - Alignment(0) { } + isSRet(false), isNest(false), isByVal(false), isInAlloca(false), + isReturned(false), Alignment(0) { } void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx); }; @@ -2060,6 +2150,12 @@ public: return false; } + /// Return the builtin name for the __builtin___clear_cache intrinsic + /// Default is to invoke the clear cache library call + virtual const char * getClearCacheBuiltinName() const { + return "__clear_cache"; + } + /// Return the type that should be used to zero or sign extend a /// zeroext/signext integer argument or return value. FIXME: Most C calling /// convention requires the return type to be promoted, but this is not true @@ -2078,6 +2174,18 @@ public: return NULL; } + /// This callback is used to prepare for a volatile or atomic load. + /// It takes a chain node as input and returns the chain for the load itself. + /// + /// Having a callback like this is necessary for targets like SystemZ, + /// which allows a CPU to reuse the result of a previous load indefinitely, + /// even if a cache-coherent store is performed by another CPU. The default + /// implementation does nothing. + virtual SDValue prepareVolatileOrAtomicLoad(SDValue Chain, SDLoc DL, + SelectionDAG &DAG) const { + return Chain; + } + /// This callback is invoked by the type legalizer to legalize nodes with an /// illegal operand type but legal result types. It replaces the /// LowerOperation callback in the type Legalizer. The reason we can not do @@ -2127,6 +2235,10 @@ public: return 0; } + + bool verifyReturnAddressArgumentIsConstant(SDValue Op, + SelectionDAG &DAG) const; + //===--------------------------------------------------------------------===// // Inline Asm Support hooks // @@ -2190,15 +2302,6 @@ public: /// operand it matches. unsigned getMatchedOperand() const; - /// Copy constructor for copying from an AsmOperandInfo. - AsmOperandInfo(const AsmOperandInfo &info) - : InlineAsm::ConstraintInfo(info), - ConstraintCode(info.ConstraintCode), - ConstraintType(info.ConstraintType), - CallOperandVal(info.CallOperandVal), - ConstraintVT(info.ConstraintVT) { - } - /// Copy constructor for copying from a ConstraintInfo. AsmOperandInfo(const InlineAsm::ConstraintInfo &info) : InlineAsm::ConstraintInfo(info), diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 284b6bb..cdb7ea6 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -29,11 +29,13 @@ namespace llvm { class MCSymbol; class MCSymbolRefExpr; class MCStreamer; + class ConstantExpr; class GlobalValue; class TargetMachine; - + class TargetLoweringObjectFile : public MCObjectFileInfo { MCContext *Ctx; + const DataLayout *DL; TargetLoweringObjectFile( const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION; @@ -42,91 +44,88 @@ class TargetLoweringObjectFile : public MCObjectFileInfo { public: MCContext &getContext() const { return *Ctx; } - TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(0) {} - + TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(0), DL(0) {} + virtual ~TargetLoweringObjectFile(); - - /// Initialize - this method must be called before any actual lowering is - /// done. This specifies the current context for codegen, and gives the - /// lowering implementations a chance to set up their default sections. + + /// This method must be called before any actual lowering is done. This + /// specifies the current context for codegen, and gives the lowering + /// implementations a chance to set up their default sections. virtual void Initialize(MCContext &ctx, const TargetMachine &TM); - + virtual void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, const MCSymbol *Sym) const; - /// emitModuleFlags - Emit the module flags that the platform cares about. - virtual void emitModuleFlags(MCStreamer &, - ArrayRef<Module::ModuleFlagEntry>, - Mangler *, const TargetMachine &) const { + /// Extract the dependent library name from a linker option string. Returns + /// StringRef() if the option does not specify a library. + virtual StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const { + return StringRef(); } - /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively - /// decide not to emit the UsedDirective for some symbols in llvm.used. - /// FIXME: REMOVE this (rdar://7071300) - virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, - Mangler *) const { - return GV != 0; - } - - /// getSectionForConstant - Given a constant with the SectionKind, return a - /// section that it should be placed in. + /// Emit the module flags that the platform cares about. + virtual void emitModuleFlags(MCStreamer &Streamer, + ArrayRef<Module::ModuleFlagEntry> Flags, + Mangler &Mang, const TargetMachine &TM) const {} + + /// Given a constant with the SectionKind, return a section that it should be + /// placed in. virtual const MCSection *getSectionForConstant(SectionKind Kind) const; - - /// getKindForGlobal - Classify the specified global variable into a set of - /// target independent categories embodied in SectionKind. + + /// Classify the specified global variable into a set of target independent + /// categories embodied in SectionKind. static SectionKind getKindForGlobal(const GlobalValue *GV, const TargetMachine &TM); - - /// SectionForGlobal - This method computes the appropriate section to emit - /// the specified global variable or function definition. This should not - /// be passed external (or available externally) globals. + + /// This method computes the appropriate section to emit the specified global + /// variable or function definition. This should not be passed external (or + /// available externally) globals. const MCSection *SectionForGlobal(const GlobalValue *GV, - SectionKind Kind, Mangler *Mang, + SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const; - - /// SectionForGlobal - This method computes the appropriate section to emit - /// the specified global variable or function definition. This should not - /// be passed external (or available externally) globals. + + /// This method computes the appropriate section to emit the specified global + /// variable or function definition. This should not be passed external (or + /// available externally) globals. const MCSection *SectionForGlobal(const GlobalValue *GV, - Mangler *Mang, + Mangler &Mang, const TargetMachine &TM) const { return SectionForGlobal(GV, getKindForGlobal(GV, TM), Mang, TM); } - /// getExplicitSectionGlobal - Targets should implement this method to assign - /// a section to globals with an explicit section specfied. The - /// implementation of this method can assume that GV->hasSection() is true. - virtual const MCSection * - getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const = 0; - - /// getSpecialCasedSectionGlobals - Allow the target to completely override - /// section assignment of a global. + /// Targets should implement this method to assign a section to globals with + /// an explicit section specfied. The implementation of this method can + /// assume that GV->hasSection() is true. virtual const MCSection * - getSpecialCasedSectionGlobals(const GlobalValue *GV, Mangler *Mang, - SectionKind Kind) const { + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler &Mang, const TargetMachine &TM) const = 0; + + /// Allow the target to completely override section assignment of a global. + virtual const MCSection *getSpecialCasedSectionGlobals(const GlobalValue *GV, + SectionKind Kind, + Mangler &Mang) const { return 0; } - - /// getTTypeGlobalReference - Return an MCExpr to use for a reference - /// to the specified global variable from exception handling information. - /// - virtual const MCExpr * - getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, unsigned Encoding, - MCStreamer &Streamer) const; - - /// Return the MCSymbol for the specified global value. This symbol is the - /// main label that is the address of the global - MCSymbol *getSymbol(Mangler &M, const GlobalValue *GV) const; - // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. - virtual MCSymbol * - getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI) const; + /// Return an MCExpr to use for a reference to the specified global variable + /// from exception handling information. + virtual const MCExpr * + getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding, + Mangler &Mang, const TargetMachine &TM, + MachineModuleInfo *MMI, MCStreamer &Streamer) const; + + /// Return the MCSymbol for a private symbol with global value name as its + /// base, with the specified suffix. + MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV, + StringRef Suffix, Mangler &Mang, + const TargetMachine &TM) const; + + // The symbol that gets passed to .cfi_personality. + virtual MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, + Mangler &Mang, + const TargetMachine &TM, + MachineModuleInfo *MMI) const; - /// const MCExpr * getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, MCStreamer &Streamer) const; @@ -146,10 +145,22 @@ public: /// emitting the address in debug info. virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const; + virtual const MCExpr * + getExecutableRelativeSymbol(const ConstantExpr *CE, Mangler &Mang, + const TargetMachine &TM) const { + return 0; + } + + /// \brief True if the section is atomized using the symbols in it. + /// This is false if the section is not atomized at all (most ELF sections) or + /// if it is atomized based on its contents (MachO' __TEXT,__cstring for + /// example). + virtual bool isSectionAtomizableBySymbols(const MCSection &Section) const; + protected: virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler *Mang, const TargetMachine &TM) const; + Mangler &Mang, const TargetMachine &TM) const; }; } // end namespace llvm diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 11b0f5f..ce3f866 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -26,9 +26,11 @@ namespace llvm { class InstrItineraryData; class JITCodeEmitter; class GlobalValue; +class Mangler; class MCAsmInfo; class MCCodeGenInfo; class MCContext; +class MCSymbol; class Target; class DataLayout; class TargetLibraryInfo; @@ -85,9 +87,9 @@ protected: // Can only create subclasses. unsigned MCRelaxAll : 1; unsigned MCNoExecStack : 1; unsigned MCSaveTempLabels : 1; - unsigned MCUseLoc : 1; unsigned MCUseCFI : 1; unsigned MCUseDwarfDirectory : 1; + unsigned RequireStructuredCFG : 1; public: virtual ~TargetMachine(); @@ -108,7 +110,7 @@ public: void resetTargetOptions(const MachineFunction *MF) const; // Interfaces to the major aspects of target machine information: - // + // // -- Instruction opcode and operand information // -- Pipelines and scheduling information // -- Stack frame information @@ -156,6 +158,9 @@ public: return 0; } + bool requiresStructuredCFG() const { return RequireStructuredCFG; } + void setRequiresStructuredCFG(bool Value) { RequireStructuredCFG = Value; } + /// hasMCRelaxAll - Check whether all machine code instructions should be /// relaxed. bool hasMCRelaxAll() const { return MCRelaxAll; } @@ -178,12 +183,6 @@ public: /// setMCNoExecStack - Set whether an executabel stack is not needed. void setMCNoExecStack(bool Value) { MCNoExecStack = Value; } - /// hasMCUseLoc - Check whether we should use dwarf's .loc directive. - bool hasMCUseLoc() const { return MCUseLoc; } - - /// setMCUseLoc - Set whether all we should use dwarf's .loc directive. - void setMCUseLoc(bool Value) { MCUseLoc = Value; } - /// hasMCUseCFI - Check whether we should use dwarf's .cfi_* directives. bool hasMCUseCFI() const { return MCUseCFI; } @@ -292,6 +291,10 @@ public: bool /*DisableVerify*/ = true) { return true; } + + void getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV, + Mangler &Mang, bool MayAlwaysUsePrivate = false) const; + MCSymbol *getSymbol(const GlobalValue *GV, Mangler &Mang) const; }; /// LLVMTargetMachine - This class describes a target machine that is @@ -309,7 +312,7 @@ public: /// \brief Register analysis passes for this target with a pass manager. /// /// This registers target independent analysis passes. - virtual void addAnalysisPasses(PassManagerBase &PM); + void addAnalysisPasses(PassManagerBase &PM) override; /// createPassConfig - Create a pass configuration object to be used by /// addPassToEmitX methods for generating a pipeline of CodeGen passes. @@ -318,12 +321,10 @@ public: /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code /// generation. - virtual bool addPassesToEmitFile(PassManagerBase &PM, - formatted_raw_ostream &Out, - CodeGenFileType FileType, - bool DisableVerify = true, - AnalysisID StartAfter = 0, - AnalysisID StopAfter = 0); + bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, + CodeGenFileType FileType, bool DisableVerify = true, + AnalysisID StartAfter = 0, + AnalysisID StopAfter = 0) override; /// addPassesToEmitMachineCode - Add passes to the specified pass manager to /// get machine code emitted. This uses a JITCodeEmitter object to handle @@ -331,19 +332,16 @@ public: /// of functions. This method returns true if machine code emission is /// not supported. /// - virtual bool addPassesToEmitMachineCode(PassManagerBase &PM, - JITCodeEmitter &MCE, - bool DisableVerify = true); + bool addPassesToEmitMachineCode(PassManagerBase &PM, JITCodeEmitter &MCE, + bool DisableVerify = true) override; /// addPassesToEmitMC - Add passes to the specified pass manager to get /// machine code emitted with the MCJIT. This method returns true if machine /// code is not supported. It fills the MCContext Ctx pointer which can be /// used to build custom MCStreamer. /// - virtual bool addPassesToEmitMC(PassManagerBase &PM, - MCContext *&Ctx, - raw_ostream &OS, - bool DisableVerify = true); + bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, + raw_ostream &OS, bool DisableVerify = true) override; /// addCodeEmitter - This pass should be overridden by the target to add a /// code emitter, if supported. If this is not supported, 'true' should be diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index bd74cb9..abb3eca 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -22,90 +22,90 @@ namespace llvm { /// must be the same as in CodeGenTarget.cpp. /// namespace TargetOpcode { - enum { - PHI = 0, - INLINEASM = 1, - PROLOG_LABEL = 2, - EH_LABEL = 3, - GC_LABEL = 4, - - /// KILL - This instruction is a noop that is used only to adjust the - /// liveness of registers. This can be useful when dealing with - /// sub-registers. - KILL = 5, - - /// EXTRACT_SUBREG - This instruction takes two operands: a register - /// that has subregisters, and a subregister index. It returns the - /// extracted subregister value. This is commonly used to implement - /// truncation operations on target architectures which support it. - EXTRACT_SUBREG = 6, - - /// INSERT_SUBREG - This instruction takes three operands: a register that - /// has subregisters, a register providing an insert value, and a - /// subregister index. It returns the value of the first register with the - /// value of the second register inserted. The first register is often - /// defined by an IMPLICIT_DEF, because it is commonly used to implement - /// anyext operations on target architectures which support it. - INSERT_SUBREG = 7, - - /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef. - IMPLICIT_DEF = 8, - - /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that - /// the first operand is an immediate integer constant. This constant is - /// often zero, because it is commonly used to assert that the instruction - /// defining the register implicitly clears the high bits. - SUBREG_TO_REG = 9, - - /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain - /// register-to-register copy into a specific register class. This is only - /// used between instruction selection and MachineInstr creation, before - /// virtual registers have been created for all the instructions, and it's - /// only needed in cases where the register classes implied by the - /// instructions are insufficient. It is emitted as a COPY MachineInstr. - COPY_TO_REGCLASS = 10, - - /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic - DBG_VALUE = 11, - - /// REG_SEQUENCE - This variadic instruction is used to form a register that - /// represents a consecutive sequence of sub-registers. It's used as a - /// register coalescing / allocation aid and must be eliminated before code - /// emission. - // In SDNode form, the first operand encodes the register class created by - // the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index - // pair. Once it has been lowered to a MachineInstr, the regclass operand - // is no longer present. - /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5 - /// After register coalescing references of v1024 should be replace with - /// v1027:3, v1025 with v1027:4, etc. - REG_SEQUENCE = 12, - - /// COPY - Target-independent register copy. This instruction can also be - /// used to copy between subregisters of virtual registers. - COPY = 13, - - /// BUNDLE - This instruction represents an instruction bundle. Instructions - /// which immediately follow a BUNDLE instruction which are marked with - /// 'InsideBundle' flag are inside the bundle. - BUNDLE = 14, - - /// Lifetime markers. - LIFETIME_START = 15, - LIFETIME_END = 16, - - /// A Stackmap instruction captures the location of live variables at its - /// position in the instruction stream. It is followed by a shadow of bytes - /// that must lie within the function and not contain another stackmap. - STACKMAP = 17, - - /// Patchable call instruction - this instruction represents a call to a - /// constant address, followed by a series of NOPs. It is intended to - /// support optimizations for dynamic languages (such as javascript) that - /// rewrite calls to runtimes with more efficient code sequences. - /// This also implies a stack map. - PATCHPOINT = 18 - }; +enum { + PHI = 0, + INLINEASM = 1, + CFI_INSTRUCTION = 2, + EH_LABEL = 3, + GC_LABEL = 4, + + /// KILL - This instruction is a noop that is used only to adjust the + /// liveness of registers. This can be useful when dealing with + /// sub-registers. + KILL = 5, + + /// EXTRACT_SUBREG - This instruction takes two operands: a register + /// that has subregisters, and a subregister index. It returns the + /// extracted subregister value. This is commonly used to implement + /// truncation operations on target architectures which support it. + EXTRACT_SUBREG = 6, + + /// INSERT_SUBREG - This instruction takes three operands: a register that + /// has subregisters, a register providing an insert value, and a + /// subregister index. It returns the value of the first register with the + /// value of the second register inserted. The first register is often + /// defined by an IMPLICIT_DEF, because it is commonly used to implement + /// anyext operations on target architectures which support it. + INSERT_SUBREG = 7, + + /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef. + IMPLICIT_DEF = 8, + + /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that + /// the first operand is an immediate integer constant. This constant is + /// often zero, because it is commonly used to assert that the instruction + /// defining the register implicitly clears the high bits. + SUBREG_TO_REG = 9, + + /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain + /// register-to-register copy into a specific register class. This is only + /// used between instruction selection and MachineInstr creation, before + /// virtual registers have been created for all the instructions, and it's + /// only needed in cases where the register classes implied by the + /// instructions are insufficient. It is emitted as a COPY MachineInstr. + COPY_TO_REGCLASS = 10, + + /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic + DBG_VALUE = 11, + + /// REG_SEQUENCE - This variadic instruction is used to form a register that + /// represents a consecutive sequence of sub-registers. It's used as a + /// register coalescing / allocation aid and must be eliminated before code + /// emission. + // In SDNode form, the first operand encodes the register class created by + // the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index + // pair. Once it has been lowered to a MachineInstr, the regclass operand + // is no longer present. + /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5 + /// After register coalescing references of v1024 should be replace with + /// v1027:3, v1025 with v1027:4, etc. + REG_SEQUENCE = 12, + + /// COPY - Target-independent register copy. This instruction can also be + /// used to copy between subregisters of virtual registers. + COPY = 13, + + /// BUNDLE - This instruction represents an instruction bundle. Instructions + /// which immediately follow a BUNDLE instruction which are marked with + /// 'InsideBundle' flag are inside the bundle. + BUNDLE = 14, + + /// Lifetime markers. + LIFETIME_START = 15, + LIFETIME_END = 16, + + /// A Stackmap instruction captures the location of live variables at its + /// position in the instruction stream. It is followed by a shadow of bytes + /// that must lie within the function and not contain another stackmap. + STACKMAP = 17, + + /// Patchable call instruction - this instruction represents a call to a + /// constant address, followed by a series of NOPs. It is intended to + /// support optimizations for dynamic languages (such as javascript) that + /// rewrite calls to runtimes with more efficient code sequences. + /// This also implies a stack map. + PATCHPOINT = 18 +}; } // end namespace TargetOpcode } // end namespace llvm diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index e77be0e..1f87343 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -42,70 +42,17 @@ namespace llvm { public: TargetOptions() : PrintMachineCode(false), NoFramePointerElim(false), - LessPreciseFPMADOption(false), - UnsafeFPMath(false), NoInfsFPMath(false), - NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false), - UseSoftFloat(false), NoZerosInBSS(false), - JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false), - GuaranteedTailCallOpt(false), DisableTailCalls(false), - StackAlignmentOverride(0), + LessPreciseFPMADOption(false), UnsafeFPMath(false), + NoInfsFPMath(false), NoNaNsFPMath(false), + HonorSignDependentRoundingFPMathOption(false), UseSoftFloat(false), + NoZerosInBSS(false), JITEmitDebugInfo(false), + JITEmitDebugInfoToDisk(false), GuaranteedTailCallOpt(false), + DisableTailCalls(false), StackAlignmentOverride(0), EnableFastISel(false), PositionIndependentExecutable(false), - EnableSegmentedStacks(false), UseInitArray(false), TrapFuncName(""), - FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard) - {} - - TargetOptions(const TargetOptions& rhs) - : PrintMachineCode(rhs.PrintMachineCode), - NoFramePointerElim(rhs.NoFramePointerElim), - LessPreciseFPMADOption(rhs.LessPreciseFPMADOption), - UnsafeFPMath(rhs.UnsafeFPMath), - NoInfsFPMath(rhs.NoInfsFPMath), - NoNaNsFPMath(rhs.NoNaNsFPMath), - HonorSignDependentRoundingFPMathOption(rhs.HonorSignDependentRoundingFPMathOption), - UseSoftFloat(rhs.UseSoftFloat), - NoZerosInBSS(rhs.NoZerosInBSS), - JITEmitDebugInfo(rhs.JITEmitDebugInfo), - JITEmitDebugInfoToDisk(rhs.JITEmitDebugInfoToDisk), - GuaranteedTailCallOpt(rhs.GuaranteedTailCallOpt), - DisableTailCalls(rhs.DisableTailCalls), - StackAlignmentOverride(rhs.StackAlignmentOverride), - EnableFastISel(rhs.EnableFastISel), - PositionIndependentExecutable(rhs.PositionIndependentExecutable), - EnableSegmentedStacks(rhs.EnableSegmentedStacks), - UseInitArray(rhs.UseInitArray), - TrapFuncName(rhs.TrapFuncName), - FloatABIType(rhs.FloatABIType), - AllowFPOpFusion(rhs.AllowFPOpFusion) - {} - - TargetOptions& operator =(const TargetOptions& rhs) - { - if (&rhs == this) - return *this; - - PrintMachineCode = rhs.PrintMachineCode; - NoFramePointerElim = rhs.NoFramePointerElim; - LessPreciseFPMADOption = rhs.LessPreciseFPMADOption; - UnsafeFPMath = rhs.UnsafeFPMath; - NoInfsFPMath = rhs.NoInfsFPMath; - NoNaNsFPMath = rhs.NoNaNsFPMath; - HonorSignDependentRoundingFPMathOption = rhs.HonorSignDependentRoundingFPMathOption; - UseSoftFloat = rhs.UseSoftFloat; - NoZerosInBSS = rhs.NoZerosInBSS; - JITEmitDebugInfo = rhs.JITEmitDebugInfo; - JITEmitDebugInfoToDisk = rhs.JITEmitDebugInfoToDisk; - GuaranteedTailCallOpt = rhs.GuaranteedTailCallOpt; - DisableTailCalls = rhs.DisableTailCalls; - StackAlignmentOverride = rhs.StackAlignmentOverride; - EnableFastISel = rhs.EnableFastISel; - PositionIndependentExecutable = rhs.PositionIndependentExecutable; - EnableSegmentedStacks = rhs.EnableSegmentedStacks; - UseInitArray = rhs.UseInitArray; - TrapFuncName = rhs.TrapFuncName; - FloatABIType = rhs.FloatABIType; - AllowFPOpFusion = rhs.AllowFPOpFusion; - return *this; - } + EnableSegmentedStacks(false), UseInitArray(false), + DisableIntegratedAS(false), CompressDebugSections(false), + TrapFuncName(""), FloatABIType(FloatABI::Default), + AllowFPOpFusion(FPOpFusion::Standard) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs /// option is specified on the command line, and should enable debugging @@ -211,6 +158,12 @@ namespace llvm { /// constructors. unsigned UseInitArray : 1; + /// Disable the integrated assembler. + unsigned DisableIntegratedAS : 1; + + /// Compress DWARF debug sections. + unsigned CompressDebugSections : 1; + /// getTrapFunctionName - If this returns a non-empty string, this means /// isel should lower Intrinsic::trap to a call to the specified function /// name instead of an ISD::TRAP node. diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 958bea6..b0c21c1 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -672,6 +672,28 @@ public: // Do nothing. } + /// Allow the target to reverse allocation order of local live ranges. This + /// will generally allocate shorter local live ranges first. For targets with + /// many registers, this could reduce regalloc compile time by a large + /// factor. It is disabled by default for three reasons: + /// (1) Top-down allocation is simpler and easier to debug for targets that + /// don't benefit from reversing the order. + /// (2) Bottom-up allocation could result in poor evicition decisions on some + /// targets affecting the performance of compiled code. + /// (3) Bottom-up allocation is no longer guaranteed to optimally color. + virtual bool reverseLocalAssignment() const { return false; } + + /// Allow the target to override register assignment heuristics based on the + /// live range size. If this returns false, then local live ranges are always + /// assigned in order regardless of their size. This is a temporary hook for + /// debugging downstream codegen failures exposed by regalloc. + virtual bool mayOverrideLocalAssignment() const { return true; } + + /// Allow the target to override the cost of using a callee-saved register for + /// the first time. Default value of 0 means we will use a callee-saved + /// register if it is available. + virtual unsigned getCSRFirstUseCost() const { return 0; } + /// requiresRegisterScavenging - returns true if the target requires (and can /// make use of) the register scavenger. virtual bool requiresRegisterScavenging(const MachineFunction &MF) const { @@ -748,8 +770,8 @@ public: /// resolveFrameIndex - Resolve a frame index operand of an instruction /// to reference the indicated base register plus offset instead. - virtual void resolveFrameIndex(MachineBasicBlock::iterator I, - unsigned BaseReg, int64_t Offset) const { + virtual void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, + int64_t Offset) const { llvm_unreachable("resolveFrameIndex does not exist on this target"); } diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index 9d4858a..b4d0c44 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -114,14 +114,46 @@ class ProcResourceKind; // resources implies using one of the super resoruces. // // ProcResourceUnits normally model a few buffered resources within an -// out-of-order engine that the compiler attempts to conserve. -// Buffered resources may be held for multiple clock cycles, but the -// scheduler does not pin them to a particular clock cycle relative to -// instruction dispatch. Setting BufferSize=0 changes this to an -// in-order resource. In this case, the scheduler counts down from the -// cycle that the instruction issues in-order, forcing an interlock -// with subsequent instructions that require the same resource until -// the number of ResourceCyles specified in WriteRes expire. +// out-of-order engine. Buffered resources may be held for multiple +// clock cycles, but the scheduler does not pin them to a particular +// clock cycle relative to instruction dispatch. Setting BufferSize=0 +// changes this to an in-order issue/dispatch resource. In this case, +// the scheduler counts down from the cycle that the instruction +// issues in-order, forcing a stall whenever a subsequent instruction +// requires the same resource until the number of ResourceCyles +// specified in WriteRes expire. Setting BufferSize=1 changes this to +// an in-order latency resource. In this case, the scheduler models +// producer/consumer stalls between instructions that use the +// resource. +// +// Examples (all assume an out-of-order engine): +// +// Use BufferSize = -1 for "issue ports" fed by a unified reservation +// station. Here the size of the reservation station is modeled by +// MicroOpBufferSize, which should be the minimum size of either the +// register rename pool, unified reservation station, or reorder +// buffer. +// +// Use BufferSize = 0 for resources that force "dispatch/issue +// groups". (Different processors define dispath/issue +// differently. Here we refer to stage between decoding into micro-ops +// and moving them into a reservation station.) Normally NumMicroOps +// is sufficient to limit dispatch/issue groups. However, some +// processors can form groups of with only certain combinitions of +// instruction types. e.g. POWER7. +// +// Use BufferSize = 1 for in-order execution units. This is used for +// an in-order pipeline within an out-of-order core where scheduling +// dependent operations back-to-back is guaranteed to cause a +// bubble. e.g. Cortex-a9 floating-point. +// +// Use BufferSize > 1 for out-of-order executions units with a +// separate reservation station. This simply models the size of the +// reservation station. +// +// To model both dispatch/issue groups and in-order execution units, +// create two types of units, one with BufferSize=0 and one with +// BufferSize=1. // // SchedModel ties these units to a processor for any stand-alone defs // of this class. Instances of subclass ProcResource will be automatically diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index d94bdc6..16cfff1 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -362,7 +362,6 @@ def bitconvert : SDNode<"ISD::BITCAST" , SDTUnaryOp>; def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>; def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>; - def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; @@ -466,7 +465,7 @@ def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT", def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>; def concat_vectors : SDNode<"ISD::CONCAT_VECTORS", - SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1, 2>]>,[]>; + SDTypeProfile<1, 2, [SDTCisSubVecOfVec<1, 0>, SDTCisSameAs<1, 2>]>,[]>; // This operator does not do subvector type checking. The ARM // backend, at least, needs it. @@ -492,6 +491,12 @@ def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN", // Do not use cvt directly. Use cvt forms below def cvt : SDNode<"ISD::CONVERT_RNDSAT", SDTConvertOp>; +def SDT_assertext : SDTypeProfile<1, 1, + [SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>; +def assertsext : SDNode<"ISD::AssertSext", SDT_assertext>; +def assertzext : SDNode<"ISD::AssertZext", SDT_assertext>; + + //===----------------------------------------------------------------------===// // Selection DAG Condition Codes @@ -554,6 +559,12 @@ class PatFrag<dag ops, dag frag, code pred = [{}], SDNodeXForm OperandTransform = xform; } +// OutPatFrag is a pattern fragment that is used as part of an output pattern +// (not an input pattern). These do not have predicates or transforms, but are +// used to avoid repeated subexpressions in output patterns. +class OutPatFrag<dag ops, dag frag> + : PatFrag<ops, frag, [{}], NOOP_SDNodeXForm>; + // PatLeaf's are pattern fragments that have no operands. This is just a helper // to define immediates and other common things concisely. class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm> diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h index 3474ee4..98a5149 100644 --- a/include/llvm/Target/TargetSelectionDAGInfo.h +++ b/include/llvm/Target/TargetSelectionDAGInfo.h @@ -31,10 +31,10 @@ class TargetSelectionDAGInfo { TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION; void operator=(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION; - const DataLayout *TD; + const DataLayout *DL; protected: - const DataLayout *getDataLayout() const { return TD; } + const DataLayout *getDataLayout() const { return DL; } public: explicit TargetSelectionDAGInfo(const TargetMachine &TM); |