diff options
Diffstat (limited to 'include/llvm/Target')
-rw-r--r-- | include/llvm/Target/Target.td | 14 | ||||
-rw-r--r-- | include/llvm/Target/TargetAsmBackend.h | 131 | ||||
-rw-r--r-- | include/llvm/Target/TargetAsmInfo.h | 35 | ||||
-rw-r--r-- | include/llvm/Target/TargetAsmLexer.h | 89 | ||||
-rw-r--r-- | include/llvm/Target/TargetAsmParser.h | 85 | ||||
-rw-r--r-- | include/llvm/Target/TargetData.h | 13 | ||||
-rw-r--r-- | include/llvm/Target/TargetFrameLowering.h | 12 | ||||
-rw-r--r-- | include/llvm/Target/TargetInstrInfo.h | 55 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 107 | ||||
-rw-r--r-- | include/llvm/Target/TargetLoweringObjectFile.h | 5 | ||||
-rw-r--r-- | include/llvm/Target/TargetMachine.h | 33 | ||||
-rw-r--r-- | include/llvm/Target/TargetOptions.h | 2 | ||||
-rw-r--r-- | include/llvm/Target/TargetRegisterInfo.h | 186 | ||||
-rw-r--r-- | include/llvm/Target/TargetRegistry.h | 1050 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelect.h | 214 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAG.td | 44 |
16 files changed, 297 insertions, 1778 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 06c2299..9714172 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -83,7 +83,7 @@ class Register<string n, list<string> altNames = []> { // CostPerUse - Additional cost of instructions using this register compared // to other registers in its class. The register allocator will try to // minimize the number of instructions using a register with a CostPerUse. - // This is used by the x86-64 and ARM Thumb targets where some registers + // This is used by the x86-64 and ARM Thumb targets where some registers // require larger instruction encodings. int CostPerUse = 0; } @@ -328,6 +328,7 @@ class Instruction { bit isPredicable = 0; // Is this instruction predicable? bit hasDelaySlot = 0; // Does this instruction have an delay slot? bit usesCustomInserter = 0; // Pseudo instr needing special help. + bit hasPostISelHook = 0; // To be *adjusted* after isel by target hook. bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. @@ -355,6 +356,15 @@ class Instruction { // associated with them. Once we've migrated all of them over to true // pseudo-instructions that are lowered to real instructions prior to // the printer/emitter, we can remove this attribute and just use isPseudo. + // + // The intended use is: + // isPseudo: Does not have encoding information and should be expanded, + // at the latest, during lowering to MCInst. + // + // isCodeGenOnly: Does have encoding information and can go through to the + // CodeEmitter unchanged, but duplicates a canonical instruction + // definition's encoding and should be ignored when constructing the + // assembler match tables. bit isCodeGenOnly = 0; // Is this instruction a pseudo instruction for use by the assembler parser. @@ -585,7 +595,7 @@ class InstrInfo { // Standard Pseudo Instructions. // This list must match TargetOpcodes.h and CodeGenTarget.cpp. // Only these instructions are allowed in the TargetOpcode namespace. -let isCodeGenOnly = 1, Namespace = "TargetOpcode" in { +let isCodeGenOnly = 1, isPseudo = 1, Namespace = "TargetOpcode" in { def PHI : Instruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/Target/TargetAsmBackend.h deleted file mode 100644 index 2111f6b..0000000 --- a/include/llvm/Target/TargetAsmBackend.h +++ /dev/null @@ -1,131 +0,0 @@ -//===-- llvm/Target/TargetAsmBackend.h - Target Asm Backend -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETASMBACKEND_H -#define LLVM_TARGET_TARGETASMBACKEND_H - -#include "llvm/MC/MCDirectives.h" -#include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCFixupKindInfo.h" -#include "llvm/Support/DataTypes.h" - -namespace llvm { -class MCELFObjectTargetWriter; -class MCFixup; -class MCInst; -class MCObjectWriter; -class MCSection; -template<typename T> -class SmallVectorImpl; -class raw_ostream; - -/// TargetAsmBackend - Generic interface to target specific assembler backends. -class TargetAsmBackend { - TargetAsmBackend(const TargetAsmBackend &); // DO NOT IMPLEMENT - void operator=(const TargetAsmBackend &); // DO NOT IMPLEMENT -protected: // Can only create subclasses. - TargetAsmBackend(); - - unsigned HasReliableSymbolDifference : 1; - -public: - virtual ~TargetAsmBackend(); - - /// createObjectWriter - Create a new MCObjectWriter instance for use by the - /// assembler backend to emit the final object file. - virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0; - - /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable - /// non-standard ELFObjectWriters. - virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const { - assert(0 && "createELFObjectTargetWriter is not supported by asm backend"); - return 0; - } - - /// hasReliableSymbolDifference - Check whether this target implements - /// accurate relocations for differences between symbols. If not, differences - /// between symbols will always be relocatable expressions and any references - /// to temporary symbols will be assumed to be in the same atom, unless they - /// reside in a different section. - /// - /// This should always be true (since it results in fewer relocations with no - /// loss of functionality), but is currently supported as a way to maintain - /// exact object compatibility with Darwin 'as' (on non-x86_64). It should - /// eventually should be eliminated. - bool hasReliableSymbolDifference() const { - return HasReliableSymbolDifference; - } - - /// doesSectionRequireSymbols - Check whether the given section requires that - /// all symbols (even temporaries) have symbol table entries. - virtual bool doesSectionRequireSymbols(const MCSection &Section) const { - return false; - } - - /// isSectionAtomizable - Check whether the given section can be split into - /// atoms. - /// - /// \see MCAssembler::isSymbolLinkerVisible(). - virtual bool isSectionAtomizable(const MCSection &Section) const { - return true; - } - - /// @name Target Fixup Interfaces - /// @{ - - /// getNumFixupKinds - Get the number of target specific fixup kinds. - virtual unsigned getNumFixupKinds() const = 0; - - /// getFixupKindInfo - Get information on a fixup kind. - virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; - - /// @} - - /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided - /// data fragment, at the offset specified by the fixup and following the - /// fixup kind as appropriate. - virtual void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, - uint64_t Value) const = 0; - - /// @} - - /// @name Target Relaxation Interfaces - /// @{ - - /// MayNeedRelaxation - Check whether the given instruction may need - /// relaxation. - /// - /// \param Inst - The instruction to test. - virtual bool MayNeedRelaxation(const MCInst &Inst) const = 0; - - /// RelaxInstruction - Relax the instruction in the given fragment to the next - /// wider instruction. - /// - /// \param Inst - The instruction to relax, which may be the same as the - /// output. - /// \parm Res [output] - On return, the relaxed instruction. - virtual void RelaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; - - /// @} - - /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given - /// output. If the target cannot generate such a sequence, it should return an - /// error. - /// - /// \return - True on success. - virtual bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const = 0; - - /// HandleAssemblerFlag - Handle any target-specific assembler flags. - /// By default, do nothing. - virtual void HandleAssemblerFlag(MCAssemblerFlag Flag) {} -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h deleted file mode 100644 index 38bbab4..0000000 --- a/include/llvm/Target/TargetAsmInfo.h +++ /dev/null @@ -1,35 +0,0 @@ -//===-- llvm/Target/TargetAsmInfo.h -----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Interface to provide the information necessary for producing assembly files. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETASMINFO_H -#define LLVM_TARGET_TARGETASMINFO_H - -#include "llvm/Target/TargetLoweringObjectFile.h" - -namespace llvm { - class TargetMachine; - class TargetLoweringObjectFile; - -class TargetAsmInfo { - const TargetLoweringObjectFile *TLOF; - -public: - explicit TargetAsmInfo(const TargetMachine &TM); - - unsigned getFDEEncoding(bool CFI) const { - return TLOF->getFDEEncoding(CFI); - } -}; - -} -#endif diff --git a/include/llvm/Target/TargetAsmLexer.h b/include/llvm/Target/TargetAsmLexer.h deleted file mode 100644 index 9fcf449..0000000 --- a/include/llvm/Target/TargetAsmLexer.h +++ /dev/null @@ -1,89 +0,0 @@ -//===-- llvm/Target/TargetAsmLexer.h - Target Assembly Lexer ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETASMLEXER_H -#define LLVM_TARGET_TARGETASMLEXER_H - -#include "llvm/MC/MCParser/MCAsmLexer.h" - -namespace llvm { -class Target; - -/// TargetAsmLexer - Generic interface to target specific assembly lexers. -class TargetAsmLexer { - /// The current token - AsmToken CurTok; - - /// The location and description of the current error - SMLoc ErrLoc; - std::string Err; - - TargetAsmLexer(const TargetAsmLexer &); // DO NOT IMPLEMENT - void operator=(const TargetAsmLexer &); // DO NOT IMPLEMENT -protected: // Can only create subclasses. - TargetAsmLexer(const Target &); - - virtual AsmToken LexToken() = 0; - - void SetError(const SMLoc &errLoc, const std::string &err) { - ErrLoc = errLoc; - Err = err; - } - - /// TheTarget - The Target that this machine was created for. - const Target &TheTarget; - MCAsmLexer *Lexer; - -public: - virtual ~TargetAsmLexer(); - - const Target &getTarget() const { return TheTarget; } - - /// InstallLexer - Set the lexer to get tokens from lower-level lexer \arg L. - void InstallLexer(MCAsmLexer &L) { - Lexer = &L; - } - - MCAsmLexer *getLexer() { - return Lexer; - } - - /// Lex - Consume the next token from the input stream and return it. - const AsmToken &Lex() { - return CurTok = LexToken(); - } - - /// getTok - Get the current (last) lexed token. - const AsmToken &getTok() { - return CurTok; - } - - /// getErrLoc - Get the current error location - const SMLoc &getErrLoc() { - return ErrLoc; - } - - /// getErr - Get the current error string - const std::string &getErr() { - return Err; - } - - /// getKind - Get the kind of current token. - AsmToken::TokenKind getKind() const { return CurTok.getKind(); } - - /// is - Check if the current token has kind \arg K. - bool is(AsmToken::TokenKind K) const { return CurTok.is(K); } - - /// isNot - Check if the current token has kind \arg K. - bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); } -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h deleted file mode 100644 index df84231..0000000 --- a/include/llvm/Target/TargetAsmParser.h +++ /dev/null @@ -1,85 +0,0 @@ -//===-- llvm/Target/TargetAsmParser.h - Target Assembly Parser --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETPARSER_H -#define LLVM_TARGET_TARGETPARSER_H - -#include "llvm/MC/MCParser/MCAsmParserExtension.h" - -namespace llvm { -class MCStreamer; -class StringRef; -class SMLoc; -class AsmToken; -class MCParsedAsmOperand; -template <typename T> class SmallVectorImpl; - -/// TargetAsmParser - Generic interface to target specific assembly parsers. -class TargetAsmParser : public MCAsmParserExtension { - TargetAsmParser(const TargetAsmParser &); // DO NOT IMPLEMENT - void operator=(const TargetAsmParser &); // DO NOT IMPLEMENT -protected: // Can only create subclasses. - TargetAsmParser(); - - /// AvailableFeatures - The current set of available features. - unsigned AvailableFeatures; - -public: - virtual ~TargetAsmParser(); - - unsigned getAvailableFeatures() const { return AvailableFeatures; } - void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } - - virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, - SMLoc &EndLoc) = 0; - - /// ParseInstruction - Parse one assembly instruction. - /// - /// The parser is positioned following the instruction name. The target - /// specific instruction parser should parse the entire instruction and - /// construct the appropriate MCInst, or emit an error. On success, the entire - /// line should be parsed up to and including the end-of-statement token. On - /// failure, the parser is not required to read to the end of the line. - // - /// \param Name - The instruction name. - /// \param NameLoc - The source location of the name. - /// \param Operands [out] - The list of parsed operands, this returns - /// ownership of them to the caller. - /// \return True on failure. - virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0; - - /// ParseDirective - Parse a target specific assembler directive - /// - /// The parser is positioned following the directive name. The target - /// specific directive parser should parse the entire directive doing or - /// recording any target specific work, or return true and do nothing if the - /// directive is not target specific. If the directive is specific for - /// the target, the entire line is parsed up to and including the - /// end-of-statement token and false is returned. - /// - /// \param DirectiveID - the identifier token of the directive. - virtual bool ParseDirective(AsmToken DirectiveID) = 0; - - /// MatchAndEmitInstruction - Recognize a series of operands of a parsed - /// instruction as an actual MCInst and emit it to the specified MCStreamer. - /// This returns false on success and returns true on failure to match. - /// - /// On failure, the target parser is responsible for emitting a diagnostic - /// explaining the match failure. - virtual bool - MatchAndEmitInstruction(SMLoc IDLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MCStreamer &Out) = 0; - -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index 315bee9..26fd187 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -44,6 +44,7 @@ enum AlignTypeEnum { AGGREGATE_ALIGN = 'a', ///< Aggregate alignment STACK_ALIGN = 's' ///< Stack objects alignment }; + /// Target alignment element. /// /// Stores the alignment data associated with a given alignment type (pointer, @@ -64,12 +65,19 @@ struct TargetAlignElem { bool operator==(const TargetAlignElem &rhs) const; }; +/// TargetData - This class holds a parsed version of the target data layout +/// string in a module and provides methods for querying it. The target data +/// layout string is specified *by the target* - a frontend generating LLVM IR +/// is required to generate the right target data for the target being codegen'd +/// to. If some measure of portability is desired, an empty string may be +/// specified in the module. class TargetData : public ImmutablePass { private: bool LittleEndian; ///< Defaults to false unsigned PointerMemSize; ///< Pointer size in bytes unsigned PointerABIAlign; ///< Pointer ABI alignment unsigned PointerPrefAlign; ///< Pointer preferred alignment + unsigned StackNaturalAlign; ///< Stack natural alignment SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers. @@ -163,6 +171,11 @@ public: return !isLegalInteger(Width); } + /// Returns true if the given alignment exceeds the natural stack alignment. + bool exceedsNaturalStackAlignment(unsigned Align) const { + return (StackNaturalAlign != 0) && (Align > StackNaturalAlign); + } + /// fitsInLegalInteger - This function returns true if the specified type fits /// in a native integer type supported by the CPU. For example, if the CPU /// only supports i32 as a native integer type, then i27 fits in a legal diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index 352b7ae..4c759b2 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -114,6 +114,10 @@ public: virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const = 0; + /// Adjust the prologue to have the function use segmented stacks. This works + /// by adding a check even before the "normal" function prologue. + virtual void adjustForSegmentedStacks(MachineFunction &MF) const { } + /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee /// saved registers and returns true if it isn't possible / profitable to do /// so by issuing a series of store instructions via @@ -186,14 +190,6 @@ public: /// virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const { } - - /// getCompactUnwindEncoding - Get the compact unwind encoding for the - /// function. Return 0 if the compact unwind isn't available. - virtual uint32_t getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs, - int DataAlignmentFactor, - bool IsEH) const { - return 0; - } }; } // End llvm namespace diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index f663566..07f614d 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -49,7 +49,7 @@ public: : CallFrameSetupOpcode(CFSetupOpcode), CallFrameDestroyOpcode(CFDestroyOpcode) { } - + virtual ~TargetInstrInfo(); /// getRegClass - Givem a machine instruction descriptor, returns the register @@ -386,6 +386,16 @@ public: assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!"); } + /// expandPostRAPseudo - This function is called for all pseudo instructions + /// that remain after register allocation. Many pseudo instructions are + /// created to help register allocation. This is the place to convert them + /// into real instructions. The target can edit MI in place, or it can insert + /// new instructions and erase MI. The function should return true if + /// anything was changed. + virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const { + return false; + } + /// emitFrameIndexDebugValue - Emit a target-dependent form of /// DBG_VALUE encoding the address of a frame index. Addresses would /// normally be lowered the same way as other addresses on the target, @@ -671,6 +681,43 @@ public: bool hasLowDefLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx) const; + /// verifyInstruction - Perform target specific instruction verification. + virtual + bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const { + return true; + } + + /// getExecutionDomain - Return the current execution domain and bit mask of + /// possible domains for instruction. + /// + /// Some micro-architectures have multiple execution domains, and multiple + /// opcodes that perform the same operation in different domains. For + /// example, the x86 architecture provides the por, orps, and orpd + /// instructions that all do the same thing. There is a latency penalty if a + /// register is written in one domain and read in another. + /// + /// This function returns a pair (domain, mask) containing the execution + /// domain of MI, and a bit mask of possible domains. The setExecutionDomain + /// function can be used to change the opcode to one of the domains in the + /// bit mask. Instructions whose execution domain can't be changed should + /// return a 0 mask. + /// + /// The execution domain numbers don't have any special meaning except domain + /// 0 is used for instructions that are not associated with any interesting + /// execution domain. + /// + virtual std::pair<uint16_t, uint16_t> + getExecutionDomain(const MachineInstr *MI) const { + return std::make_pair(0, 0); + } + + /// setExecutionDomain - Change the opcode of MI to execute in Domain. + /// + /// The bit (1 << Domain) must be set in the mask returned from + /// getExecutionDomain(MI). + /// + virtual void setExecutionDomain(MachineInstr *MI, unsigned Domain) const {} + private: int CallFrameSetupOpcode, CallFrameDestroyOpcode; }; @@ -693,6 +740,12 @@ public: unsigned &SrcOpIdx2) const; virtual bool canFoldMemoryOperand(const MachineInstr *MI, const SmallVectorImpl<unsigned> &Ops) const; + virtual bool hasLoadFromStackSlot(const MachineInstr *MI, + const MachineMemOperand *&MMO, + int &FrameIndex) const; + virtual bool hasStoreToStackSlot(const MachineInstr *MI, + const MachineMemOperand *&MMO, + int &FrameIndex) const; virtual bool PredicateInstruction(MachineInstr *MI, const SmallVectorImpl<MachineOperand> &Pred) const; virtual void reMaterialize(MachineBasicBlock &MBB, diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 3484a79..dca78a3 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -113,6 +113,22 @@ public: ZeroOrNegativeOneBooleanContent // All bits equal to bit 0. }; + static ISD::NodeType getExtendForContent(BooleanContent Content) { + switch (Content) { + default: + assert(false && "Unknown BooleanContent!"); + case UndefinedBooleanContent: + // Extend by adding rubbish bits. + return ISD::ANY_EXTEND; + case ZeroOrOneBooleanContent: + // Extend by adding zero bits. + return ISD::ZERO_EXTEND; + case ZeroOrNegativeOneBooleanContent: + // Extend by copying the sign bit. + return ISD::SIGN_EXTEND; + } + } + /// NOTE: The constructor takes ownership of TLOF. explicit TargetLowering(const TargetMachine &TM, const TargetLoweringObjectFile *TLOF); @@ -148,8 +164,7 @@ public: /// the condition operand of SELECT and BRCOND nodes. In the case of /// BRCOND the argument passed is MVT::Other since there are no other /// operands to get a type hint from. - virtual - MVT::SimpleValueType getSetCCResultType(EVT VT) const; + virtual EVT getSetCCResultType(EVT VT) const; /// getCmpLibcallReturnType - Return the ValueType for comparison /// libcalls. Comparions libcalls include floating point comparion calls, @@ -162,7 +177,13 @@ public: /// "Boolean values" are special true/false values produced by nodes like /// SETCC and consumed (as the condition) by nodes like SELECT and BRCOND. /// Not to be confused with general values promoted from i1. - BooleanContent getBooleanContents() const { return BooleanContents;} + /// Some cpus distinguish between vectors of boolean and scalars; the isVec + /// parameter selects between the two kinds. For example on X86 a scalar + /// boolean should be zero extended from i1, while the elements of a vector + /// of booleans should be sign extended from i1. + BooleanContent getBooleanContents(bool isVec) const { + return isVec ? BooleanVectorContents : BooleanContents; + } /// getSchedulingPreference - Return target scheduling preference. Sched::Preference getSchedulingPreference() const { @@ -265,9 +286,9 @@ public: assert(!VT.isVector()); while (true) { switch (getTypeAction(Context, VT)) { - case Legal: + case TypeLegal: return VT; - case Expand: + case TypeExpandInteger: VT = getTypeToTransformTo(Context, VT); break; default: @@ -714,6 +735,13 @@ public: return ShouldFoldAtomicFences; } + /// getInsertFencesFor - return whether the DAG builder should automatically + /// insert fences and reduce ordering for atomics. + /// + bool getInsertFencesForAtomic() const { + return InsertFencesForAtomic; + } + /// getPreIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if the node's address /// can be legally represented as pre-indexed load / store address. @@ -931,6 +959,12 @@ protected: /// setBooleanContents - Specify how the target extends the result of a /// boolean value from i1 to a wider type. See getBooleanContents. void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; } + /// setBooleanVectorContents - Specify how the target extends the result + /// of a vector boolean value from a vector of i1 to a wider type. See + /// getBooleanContents. + void setBooleanVectorContents(BooleanContent Ty) { + BooleanVectorContents = Ty; + } /// setSchedulingPreference - Specify the target scheduling preference. void setSchedulingPreference(Sched::Preference Pref) { @@ -1104,26 +1138,28 @@ protected: JumpBufAlignment = Align; } - /// setMinFunctionAlignment - Set the target's minimum function alignment. + /// setMinFunctionAlignment - Set the target's minimum function alignment (in + /// log2(bytes)) void setMinFunctionAlignment(unsigned Align) { MinFunctionAlignment = Align; } /// setPrefFunctionAlignment - Set the target's preferred function alignment. /// This should be set if there is a performance benefit to - /// higher-than-minimum alignment + /// higher-than-minimum alignment (in log2(bytes)) void setPrefFunctionAlignment(unsigned Align) { PrefFunctionAlignment = Align; } /// setPrefLoopAlignment - Set the target's preferred loop alignment. Default /// alignment is zero, it means the target does not care about loop alignment. + /// The alignment is specified in log2(bytes). void setPrefLoopAlignment(unsigned Align) { PrefLoopAlignment = Align; } /// setMinStackArgumentAlignment - Set the minimum stack alignment of an - /// argument. + /// argument (in log2(bytes)). void setMinStackArgumentAlignment(unsigned Align) { MinStackArgumentAlignment = Align; } @@ -1134,6 +1170,13 @@ protected: ShouldFoldAtomicFences = fold; } + /// setInsertFencesForAtomic - Set if the the DAG builder should + /// automatically insert fences and reduce the order of atomic memory + /// operations to Monotonic. + void setInsertFencesForAtomic(bool fence) { + InsertFencesForAtomic = fence; + } + public: //===--------------------------------------------------------------------===// // Lowering methods - These methods must be implemented by targets so that @@ -1457,6 +1500,13 @@ public: virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; + /// AdjustInstrPostInstrSelection - This method should be implemented by + /// targets that mark instructions with the 'hasPostISelHook' flag. These + /// instructions must be adjusted after instruction selection by target hooks. + /// e.g. To fill in optional defs for ARM 's' setting instructions. + virtual void + AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const; + //===--------------------------------------------------------------------===// // Addressing mode description hooks (used by LSR etc). // @@ -1484,6 +1534,22 @@ public: /// TODO: Handle pre/postinc as well. virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) 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 { + return true; + } + + /// 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 { + return true; + } + /// 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. @@ -1518,22 +1584,6 @@ public: 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 Imm) const { - return true; - } - - /// 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 { - return true; - } - //===--------------------------------------------------------------------===// // Div utility functions // @@ -1636,6 +1686,10 @@ private: /// BooleanContents - Information about the contents of the high-bits in /// boolean values held in a type wider than i1. See getBooleanContents. BooleanContent BooleanContents; + /// BooleanVectorContents - Information about the contents of the high-bits + /// in boolean vector values when the element type is wider than i1. See + /// getBooleanContents. + BooleanContent BooleanVectorContents; /// SchedPreferenceInfo - The target scheduling preference: shortest possible /// total cycles or lowest register usage. @@ -1673,6 +1727,11 @@ private: /// combiner. bool ShouldFoldAtomicFences; + /// InsertFencesForAtomic - Whether the DAG builder should automatically + /// insert fences and reduce ordering for atomics. (This will be set for + /// for most architectures with weak memory ordering.) + bool InsertFencesForAtomic; + /// StackPointerRegisterToSaveRestore - If set to a physical register, this /// specifies the register that llvm.savestack/llvm.restorestack should save /// and restore. diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index d6428ff..7d06cec 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -122,11 +122,6 @@ public: getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const; - virtual unsigned getPersonalityEncoding() const; - virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding(bool CFI) const; - virtual unsigned getTTypeEncoding() const; - protected: virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index f4c845a..30c5b3a 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -43,17 +43,6 @@ class TargetSubtargetInfo; class formatted_raw_ostream; class raw_ostream; -// Code model types. -namespace CodeModel { - enum Model { - Default, - Small, - Kernel, - Medium, - Large - }; -} - // Code generation optimization level. namespace CodeGenOpt { enum Level { @@ -101,7 +90,6 @@ protected: // Can only create subclasses. std::string TargetFS; /// CodeGenInfo - Low level target information such as relocation model. - /// const MCCodeGenInfo *CodeGenInfo; /// AsmInfo - Contains target specific asm information. @@ -113,6 +101,7 @@ protected: // Can only create subclasses. unsigned MCSaveTempLabels : 1; unsigned MCUseLoc : 1; unsigned MCUseCFI : 1; + unsigned MCUseDwarfDirectory : 1; public: virtual ~TargetMachine(); @@ -208,17 +197,21 @@ public: /// setMCUseCFI - Set whether all we should use dwarf's .cfi_* directives. void setMCUseCFI(bool Value) { MCUseCFI = Value; } + /// hasMCUseDwarfDirectory - Check whether we should use .file directives with + /// explicit directories. + bool hasMCUseDwarfDirectory() const { return MCUseDwarfDirectory; } + + /// setMCUseDwarfDirectory - Set whether all we should use .file directives + /// with explicit directories. + void setMCUseDwarfDirectory(bool Value) { MCUseDwarfDirectory = Value; } + /// getRelocationModel - Returns the code generation relocation model. The /// choices are static, PIC, and dynamic-no-pic, and target default. Reloc::Model getRelocationModel() const; /// getCodeModel - Returns the code model. The choices are small, kernel, /// medium, large, and target default. - static CodeModel::Model getCodeModel(); - - /// setCodeModel - Sets the code model. - /// - static void setCodeModel(CodeModel::Model Model); + CodeModel::Model getCodeModel() const; /// getAsmVerbosityDefault - Returns the default value of asm verbosity. /// @@ -301,7 +294,8 @@ public: class LLVMTargetMachine : public TargetMachine { protected: // Can only create subclasses. LLVMTargetMachine(const Target &T, StringRef TargetTriple, - StringRef CPU, StringRef FS, Reloc::Model RM); + StringRef CPU, StringRef FS, + Reloc::Model RM, CodeModel::Model CM); private: /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for @@ -310,9 +304,6 @@ private: bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level, bool DisableVerify, MCContext *&OutCtx); - virtual void setCodeModelForJIT(); - virtual void setCodeModelForStatic(); - public: /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 55d50d9..e07e8c1 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -158,6 +158,8 @@ namespace llvm { /// instead of an ISD::TRAP node. extern StringRef getTrapFunctionName(); + extern bool EnableSegmentedStacks; + } // End llvm namespace #endif diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 3113cd4..682aa50 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -20,7 +20,6 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseSet.h" #include <cassert> #include <functional> @@ -36,76 +35,75 @@ class TargetRegisterClass { public: typedef const unsigned* iterator; typedef const unsigned* const_iterator; - typedef const EVT* vt_iterator; typedef const TargetRegisterClass* const * sc_iterator; private: - unsigned ID; - const char *Name; + const MCRegisterClass *MC; const vt_iterator VTs; - const sc_iterator SubClasses; + const unsigned *SubClassMask; const sc_iterator SuperClasses; - const sc_iterator SubRegClasses; const sc_iterator SuperRegClasses; - const unsigned RegSize, Alignment; // Size & Alignment of register in bytes - const int CopyCost; - const bool Allocatable; - const iterator RegsBegin, RegsEnd; - DenseSet<unsigned> RegSet; public: - TargetRegisterClass(unsigned id, - const char *name, - const EVT *vts, - const TargetRegisterClass * const *subcs, + TargetRegisterClass(const MCRegisterClass *MC, const EVT *vts, + const unsigned *subcm, const TargetRegisterClass * const *supcs, - const TargetRegisterClass * const *subregcs, - const TargetRegisterClass * const *superregcs, - unsigned RS, unsigned Al, int CC, bool Allocable, - iterator RB, iterator RE) - : ID(id), Name(name), VTs(vts), SubClasses(subcs), SuperClasses(supcs), - SubRegClasses(subregcs), SuperRegClasses(superregcs), - RegSize(RS), Alignment(Al), CopyCost(CC), Allocatable(Allocable), - RegsBegin(RB), RegsEnd(RE) { - for (iterator I = RegsBegin, E = RegsEnd; I != E; ++I) - RegSet.insert(*I); - } + const TargetRegisterClass * const *superregcs) + : MC(MC), VTs(vts), SubClassMask(subcm), SuperClasses(supcs), + SuperRegClasses(superregcs) {} + virtual ~TargetRegisterClass() {} // Allow subclasses /// getID() - Return the register class ID number. /// - unsigned getID() const { return ID; } + unsigned getID() const { return MC->getID(); } /// getName() - Return the register class name for debugging. /// - const char *getName() const { return Name; } + const char *getName() const { return MC->getName(); } /// begin/end - Return all of the registers in this class. /// - iterator begin() const { return RegsBegin; } - iterator end() const { return RegsEnd; } + iterator begin() const { return MC->begin(); } + iterator end() const { return MC->end(); } /// getNumRegs - Return the number of registers in this class. /// - unsigned getNumRegs() const { return (unsigned)(RegsEnd-RegsBegin); } + unsigned getNumRegs() const { return MC->getNumRegs(); } /// getRegister - Return the specified register in the class. /// unsigned getRegister(unsigned i) const { - assert(i < getNumRegs() && "Register number out of range!"); - return RegsBegin[i]; + return MC->getRegister(i); } /// contains - Return true if the specified register is included in this /// register class. This does not include virtual registers. bool contains(unsigned Reg) const { - return RegSet.count(Reg); + return MC->contains(Reg); } /// contains - Return true if both registers are in this class. bool contains(unsigned Reg1, unsigned Reg2) const { - return contains(Reg1) && contains(Reg2); + return MC->contains(Reg1, Reg2); } + /// getSize - Return the size of the register in bytes, which is also the size + /// of a stack slot allocated to hold a spilled copy of this register. + unsigned getSize() const { return MC->getSize(); } + + /// getAlignment - Return the minimum required alignment for a register of + /// this class. + unsigned getAlignment() const { return MC->getAlignment(); } + + /// getCopyCost - Return the cost of copying a value between two registers in + /// this class. A negative number means the register class is very expensive + /// to copy e.g. status flag register classes. + int getCopyCost() const { return MC->getCopyCost(); } + + /// isAllocatable - Return true if this register class may be used to create + /// virtual registers. + bool isAllocatable() const { return MC->isAllocatable(); } + /// hasType - return true if this TargetRegisterClass has the ValueType vt. /// bool hasType(EVT vt) const { @@ -127,25 +125,6 @@ public: return I; } - /// subregclasses_begin / subregclasses_end - Loop over all of - /// the subreg register classes of this register class. - sc_iterator subregclasses_begin() const { - return SubRegClasses; - } - - sc_iterator subregclasses_end() const { - sc_iterator I = SubRegClasses; - while (*I != NULL) ++I; - return I; - } - - /// getSubRegisterRegClass - Return the register class of subregisters with - /// index SubIdx, or NULL if no such class exists. - const TargetRegisterClass* getSubRegisterRegClass(unsigned SubIdx) const { - assert(SubIdx>0 && "Invalid subregister index"); - return SubRegClasses[SubIdx-1]; - } - /// superregclasses_begin / superregclasses_end - Loop over all of /// the superreg register classes of this register class. sc_iterator superregclasses_begin() const { @@ -159,57 +138,42 @@ public: } /// hasSubClass - return true if the specified TargetRegisterClass - /// is a proper subset of this TargetRegisterClass. - bool hasSubClass(const TargetRegisterClass *cs) const { - for (int i = 0; SubClasses[i] != NULL; ++i) - if (SubClasses[i] == cs) - return true; - return false; + /// is a proper sub-class of this TargetRegisterClass. + bool hasSubClass(const TargetRegisterClass *RC) const { + return RC != this && hasSubClassEq(RC); } - /// hasSubClassEq - Returns true if RC is a subclass of or equal to this + /// hasSubClassEq - Returns true if RC is a sub-class of or equal to this /// class. bool hasSubClassEq(const TargetRegisterClass *RC) const { - return RC == this || hasSubClass(RC); - } - - /// subclasses_begin / subclasses_end - Loop over all of the classes - /// that are proper subsets of this register class. - sc_iterator subclasses_begin() const { - return SubClasses; - } - - sc_iterator subclasses_end() const { - sc_iterator I = SubClasses; - while (*I != NULL) ++I; - return I; + unsigned ID = RC->getID(); + return (SubClassMask[ID / 32] >> (ID % 32)) & 1; } /// hasSuperClass - return true if the specified TargetRegisterClass is a - /// proper superset of this TargetRegisterClass. - bool hasSuperClass(const TargetRegisterClass *cs) const { - for (int i = 0; SuperClasses[i] != NULL; ++i) - if (SuperClasses[i] == cs) - return true; - return false; + /// proper super-class of this TargetRegisterClass. + bool hasSuperClass(const TargetRegisterClass *RC) const { + return RC->hasSubClass(this); } - /// hasSuperClassEq - Returns true if RC is a superclass of or equal to this + /// hasSuperClassEq - Returns true if RC is a super-class of or equal to this /// class. bool hasSuperClassEq(const TargetRegisterClass *RC) const { - return RC == this || hasSuperClass(RC); + return RC->hasSubClassEq(this); } - /// superclasses_begin / superclasses_end - Loop over all of the classes - /// that are proper supersets of this register class. - sc_iterator superclasses_begin() const { - return SuperClasses; + /// getSubClassMask - Returns a bit vector of subclasses, including this one. + /// The vector is indexed by class IDs, see hasSubClassEq() above for how to + /// use it. + const unsigned *getSubClassMask() const { + return SubClassMask; } - sc_iterator superclasses_end() const { - sc_iterator I = SuperClasses; - while (*I != NULL) ++I; - return I; + /// getSuperClasses - Returns a NULL terminated list of super-classes. The + /// classes are ordered by ID which is also a topological ordering from large + /// to small classes. The list does NOT include the current class. + sc_iterator getSuperClasses() const { + return SuperClasses; } /// isASubClass - return true if this TargetRegisterClass is a subset @@ -236,23 +200,6 @@ public: ArrayRef<unsigned> getRawAllocationOrder(const MachineFunction &MF) const { return makeArrayRef(begin(), getNumRegs()); } - - /// getSize - Return the size of the register in bytes, which is also the size - /// of a stack slot allocated to hold a spilled copy of this register. - unsigned getSize() const { return RegSize; } - - /// getAlignment - Return the minimum required alignment for a register of - /// this class. - unsigned getAlignment() const { return Alignment; } - - /// getCopyCost - Return the cost of copying a value between two registers in - /// this class. A negative number means the register class is very expensive - /// to copy e.g. status flag register classes. - int getCopyCost() const { return CopyCost; } - - /// isAllocatable - Return true if this register class may be used to create - /// virtual registers. - bool isAllocatable() const { return Allocatable; } }; /// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about @@ -461,6 +408,20 @@ public: return 0; } + /// getSubClassWithSubReg - Returns the largest legal sub-class of RC that + /// supports the sub-register index Idx. + /// If no such sub-class exists, return NULL. + /// If all registers in RC already have an Idx sub-register, return RC. + /// + /// TableGen generates a version of this function that is good enough in most + /// cases. Targets can override if they have constraints that TableGen + /// doesn't understand. For example, the x86 sub_8bit sub-register index is + /// supported by the full GR32 register class in 64-bit mode, but only by the + /// GR32_ABCD regiister class in 32-bit mode. + /// + virtual const TargetRegisterClass * + getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const =0; + /// composeSubRegIndices - Return the subregister index you get from composing /// two subregister indices. /// @@ -498,6 +459,12 @@ public: return RegClassBegin[i]; } + /// getCommonSubClass - find the largest common subclass of A and B. Return + /// NULL if there is no common subclass. + const TargetRegisterClass * + getCommonSubClass(const TargetRegisterClass *A, + const TargetRegisterClass *B) const; + /// getPointerRegClass - Returns a TargetRegisterClass used for pointer /// values. If a target supports multiple different pointer register classes, /// kind specifies which one is indicated. @@ -718,11 +685,6 @@ struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> { } }; -/// getCommonSubClass - find the largest common subclass of A and B. Return NULL -/// if there is no common subclass. -const TargetRegisterClass *getCommonSubClass(const TargetRegisterClass *A, - const TargetRegisterClass *B); - /// PrintReg - Helper class for printing registers on a raw_ostream. /// Prints virtual and physical registers with or without a TRI instance. /// diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h deleted file mode 100644 index 7d63d56..0000000 --- a/include/llvm/Target/TargetRegistry.h +++ /dev/null @@ -1,1050 +0,0 @@ -//===-- Target/TargetRegistry.h - Target Registration -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file exposes the TargetRegistry interface, which tools can use to access -// the appropriate target specific classes (TargetMachine, AsmPrinter, etc.) -// which have been registered. -// -// Target specific class implementations should register themselves using the -// appropriate TargetRegistry interfaces. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETREGISTRY_H -#define LLVM_TARGET_TARGETREGISTRY_H - -#include "llvm/MC/MCCodeGenInfo.h" -#include "llvm/ADT/Triple.h" -#include <string> -#include <cassert> - -namespace llvm { - class AsmPrinter; - class Module; - class MCAssembler; - class MCAsmInfo; - class MCAsmParser; - class MCCodeEmitter; - class MCContext; - class MCDisassembler; - class MCInstPrinter; - class MCInstrInfo; - class MCRegisterInfo; - class MCStreamer; - class MCSubtargetInfo; - class MCCodeGenInfo; - class TargetAsmBackend; - class TargetAsmLexer; - class TargetAsmParser; - class TargetMachine; - class raw_ostream; - class formatted_raw_ostream; - - MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, - bool isVerboseAsm, - bool useLoc, bool useCFI, - MCInstPrinter *InstPrint, - MCCodeEmitter *CE, - TargetAsmBackend *TAB, - bool ShowInst); - - /// Target - Wrapper for Target specific information. - /// - /// For registration purposes, this is a POD type so that targets can be - /// registered without the use of static constructors. - /// - /// Targets should implement a single global instance of this class (which - /// will be zero initialized), and pass that instance to the TargetRegistry as - /// part of their initialization. - class Target { - public: - friend struct TargetRegistry; - - typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); - - typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const Target &T, - StringRef TT); - typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model M); - typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void); - typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT); - typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT, - StringRef CPU, - StringRef Features); - typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T, - StringRef TT, - StringRef CPU, - StringRef Features, - Reloc::Model RM); - typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM, - MCStreamer &Streamer); - typedef TargetAsmBackend *(*AsmBackendCtorTy)(const Target &T, - const std::string &TT); - typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T, - const MCAsmInfo &MAI); - typedef TargetAsmParser *(*AsmParserCtorTy)(MCSubtargetInfo &STI, - MCAsmParser &P); - typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); - typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, - unsigned SyntaxVariant, - const MCAsmInfo &MAI); - typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const MCInstrInfo &II, - const MCSubtargetInfo &STI, - MCContext &Ctx); - typedef MCStreamer *(*ObjectStreamerCtorTy)(const Target &T, - const std::string &TT, - MCContext &Ctx, - TargetAsmBackend &TAB, - raw_ostream &_OS, - MCCodeEmitter *_Emitter, - bool RelaxAll, - bool NoExecStack); - typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx, - formatted_raw_ostream &OS, - bool isVerboseAsm, - bool useLoc, - bool useCFI, - MCInstPrinter *InstPrint, - MCCodeEmitter *CE, - TargetAsmBackend *TAB, - bool ShowInst); - - private: - /// Next - The next registered target in the linked list, maintained by the - /// TargetRegistry. - Target *Next; - - /// TripleMatchQualityFn - The target function for rating the match quality - /// of a triple. - TripleMatchQualityFnTy TripleMatchQualityFn; - - /// Name - The target name. - const char *Name; - - /// ShortDesc - A short description of the target. - const char *ShortDesc; - - /// HasJIT - Whether this target supports the JIT. - bool HasJIT; - - /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if - /// registered. - MCAsmInfoCtorFnTy MCAsmInfoCtorFn; - - /// MCCodeGenInfoCtorFn - Constructor function for this target's MCCodeGenInfo, - /// if registered. - MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn; - - /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo, - /// if registered. - MCInstrInfoCtorFnTy MCInstrInfoCtorFn; - - /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo, - /// if registered. - MCRegInfoCtorFnTy MCRegInfoCtorFn; - - /// MCSubtargetInfoCtorFn - Constructor function for this target's - /// MCSubtargetInfo, if registered. - MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn; - - /// TargetMachineCtorFn - Construction function for this target's - /// TargetMachine, if registered. - TargetMachineCtorTy TargetMachineCtorFn; - - /// AsmBackendCtorFn - Construction function for this target's - /// TargetAsmBackend, if registered. - AsmBackendCtorTy AsmBackendCtorFn; - - /// AsmLexerCtorFn - Construction function for this target's TargetAsmLexer, - /// if registered. - AsmLexerCtorTy AsmLexerCtorFn; - - /// AsmParserCtorFn - Construction function for this target's - /// TargetAsmParser, if registered. - AsmParserCtorTy AsmParserCtorFn; - - /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter, - /// if registered. - AsmPrinterCtorTy AsmPrinterCtorFn; - - /// MCDisassemblerCtorFn - Construction function for this target's - /// MCDisassembler, if registered. - MCDisassemblerCtorTy MCDisassemblerCtorFn; - - /// MCInstPrinterCtorFn - Construction function for this target's - /// MCInstPrinter, if registered. - MCInstPrinterCtorTy MCInstPrinterCtorFn; - - /// CodeEmitterCtorFn - Construction function for this target's CodeEmitter, - /// if registered. - CodeEmitterCtorTy CodeEmitterCtorFn; - - /// ObjectStreamerCtorFn - Construction function for this target's - /// ObjectStreamer, if registered. - ObjectStreamerCtorTy ObjectStreamerCtorFn; - - /// AsmStreamerCtorFn - Construction function for this target's - /// AsmStreamer, if registered (default = llvm::createAsmStreamer). - AsmStreamerCtorTy AsmStreamerCtorFn; - - public: - Target() : AsmStreamerCtorFn(llvm::createAsmStreamer) {} - - /// @name Target Information - /// @{ - - // getNext - Return the next registered target. - const Target *getNext() const { return Next; } - - /// getName - Get the target name. - const char *getName() const { return Name; } - - /// getShortDescription - Get a short description of the target. - const char *getShortDescription() const { return ShortDesc; } - - /// @} - /// @name Feature Predicates - /// @{ - - /// hasJIT - Check if this targets supports the just-in-time compilation. - bool hasJIT() const { return HasJIT; } - - /// hasTargetMachine - Check if this target supports code generation. - bool hasTargetMachine() const { return TargetMachineCtorFn != 0; } - - /// hasAsmBackend - Check if this target supports .o generation. - bool hasAsmBackend() const { return AsmBackendCtorFn != 0; } - - /// hasAsmLexer - Check if this target supports .s lexing. - bool hasAsmLexer() const { return AsmLexerCtorFn != 0; } - - /// hasAsmParser - Check if this target supports .s parsing. - bool hasAsmParser() const { return AsmParserCtorFn != 0; } - - /// hasAsmPrinter - Check if this target supports .s printing. - bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; } - - /// hasMCDisassembler - Check if this target has a disassembler. - bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; } - - /// hasMCInstPrinter - Check if this target has an instruction printer. - bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; } - - /// hasCodeEmitter - Check if this target supports instruction encoding. - bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; } - - /// hasObjectStreamer - Check if this target supports streaming to files. - bool hasObjectStreamer() const { return ObjectStreamerCtorFn != 0; } - - /// hasAsmStreamer - Check if this target supports streaming to files. - bool hasAsmStreamer() const { return AsmStreamerCtorFn != 0; } - - /// @} - /// @name Feature Constructors - /// @{ - - /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified - /// target triple. - /// - /// \arg Triple - This argument is used to determine the target machine - /// feature set; it should always be provided. Generally this should be - /// either the target triple from the module, or the target triple of the - /// host if that does not exist. - MCAsmInfo *createMCAsmInfo(StringRef Triple) const { - if (!MCAsmInfoCtorFn) - return 0; - return MCAsmInfoCtorFn(*this, Triple); - } - - /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation. - /// - MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model M) const { - if (!MCCodeGenInfoCtorFn) - return 0; - return MCCodeGenInfoCtorFn(Triple, M); - } - - /// createMCInstrInfo - Create a MCInstrInfo implementation. - /// - MCInstrInfo *createMCInstrInfo() const { - if (!MCInstrInfoCtorFn) - return 0; - return MCInstrInfoCtorFn(); - } - - /// createMCRegInfo - Create a MCRegisterInfo implementation. - /// - MCRegisterInfo *createMCRegInfo(StringRef Triple) const { - if (!MCRegInfoCtorFn) - return 0; - return MCRegInfoCtorFn(Triple); - } - - /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. - /// - /// \arg Triple - This argument is used to determine the target machine - /// feature set; it should always be provided. Generally this should be - /// either the target triple from the module, or the target triple of the - /// host if that does not exist. - /// \arg CPU - This specifies the name of the target CPU. - /// \arg Features - This specifies the string representation of the - /// additional target features. - MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU, - StringRef Features) const { - if (!MCSubtargetInfoCtorFn) - return 0; - return MCSubtargetInfoCtorFn(Triple, CPU, Features); - } - - /// createTargetMachine - Create a target specific machine implementation - /// for the specified \arg Triple. - /// - /// \arg Triple - This argument is used to determine the target machine - /// feature set; it should always be provided. Generally this should be - /// either the target triple from the module, or the target triple of the - /// host if that does not exist. - TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU, - StringRef Features, - Reloc::Model RM = Reloc::Default) const { - if (!TargetMachineCtorFn) - return 0; - return TargetMachineCtorFn(*this, Triple, CPU, Features, RM); - } - - /// createAsmBackend - Create a target specific assembly parser. - /// - /// \arg Triple - The target triple string. - /// \arg Backend - The target independent assembler object. - TargetAsmBackend *createAsmBackend(const std::string &Triple) const { - if (!AsmBackendCtorFn) - return 0; - return AsmBackendCtorFn(*this, Triple); - } - - /// createAsmLexer - Create a target specific assembly lexer. - /// - TargetAsmLexer *createAsmLexer(const MCAsmInfo &MAI) const { - if (!AsmLexerCtorFn) - return 0; - return AsmLexerCtorFn(*this, MAI); - } - - /// createAsmParser - Create a target specific assembly parser. - /// - /// \arg Parser - The target independent parser implementation to use for - /// parsing and lexing. - TargetAsmParser *createAsmParser(MCSubtargetInfo &STI, - MCAsmParser &Parser) const { - if (!AsmParserCtorFn) - return 0; - return AsmParserCtorFn(STI, Parser); - } - - /// createAsmPrinter - Create a target specific assembly printer pass. This - /// takes ownership of the MCStreamer object. - AsmPrinter *createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const{ - if (!AsmPrinterCtorFn) - return 0; - return AsmPrinterCtorFn(TM, Streamer); - } - - MCDisassembler *createMCDisassembler() const { - if (!MCDisassemblerCtorFn) - return 0; - return MCDisassemblerCtorFn(*this); - } - - MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant, - const MCAsmInfo &MAI) const { - if (!MCInstPrinterCtorFn) - return 0; - return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI); - } - - - /// createCodeEmitter - Create a target specific code emitter. - MCCodeEmitter *createCodeEmitter(const MCInstrInfo &II, - const MCSubtargetInfo &STI, - MCContext &Ctx) const { - if (!CodeEmitterCtorFn) - return 0; - return CodeEmitterCtorFn(II, STI, Ctx); - } - - /// createObjectStreamer - Create a target specific MCStreamer. - /// - /// \arg TT - The target triple. - /// \arg Ctx - The target context. - /// \arg TAB - The target assembler backend object. Takes ownership. - /// \arg _OS - The stream object. - /// \arg _Emitter - The target independent assembler object.Takes ownership. - /// \arg RelaxAll - Relax all fixups? - /// \arg NoExecStack - Mark file as not needing a executable stack. - MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx, - TargetAsmBackend &TAB, - raw_ostream &_OS, - MCCodeEmitter *_Emitter, - bool RelaxAll, - bool NoExecStack) const { - if (!ObjectStreamerCtorFn) - return 0; - return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll, - NoExecStack); - } - - /// createAsmStreamer - Create a target specific MCStreamer. - MCStreamer *createAsmStreamer(MCContext &Ctx, - formatted_raw_ostream &OS, - bool isVerboseAsm, - bool useLoc, - bool useCFI, - MCInstPrinter *InstPrint, - MCCodeEmitter *CE, - TargetAsmBackend *TAB, - bool ShowInst) const { - // AsmStreamerCtorFn is default to llvm::createAsmStreamer - return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI, - InstPrint, CE, TAB, ShowInst); - } - - /// @} - }; - - /// TargetRegistry - Generic interface to target specific features. - struct TargetRegistry { - class iterator { - const Target *Current; - explicit iterator(Target *T) : Current(T) {} - friend struct TargetRegistry; - public: - iterator(const iterator &I) : Current(I.Current) {} - iterator() : Current(0) {} - - bool operator==(const iterator &x) const { - return Current == x.Current; - } - bool operator!=(const iterator &x) const { - return !operator==(x); - } - - // Iterator traversal: forward iteration only - iterator &operator++() { // Preincrement - assert(Current && "Cannot increment end iterator!"); - Current = Current->getNext(); - return *this; - } - iterator operator++(int) { // Postincrement - iterator tmp = *this; - ++*this; - return tmp; - } - - const Target &operator*() const { - assert(Current && "Cannot dereference end iterator!"); - return *Current; - } - - const Target *operator->() const { - return &operator*(); - } - }; - - /// @name Registry Access - /// @{ - - static iterator begin(); - - static iterator end() { return iterator(); } - - /// lookupTarget - Lookup a target based on a target triple. - /// - /// \param Triple - The triple to use for finding a target. - /// \param Error - On failure, an error string describing why no target was - /// found. - static const Target *lookupTarget(const std::string &Triple, - std::string &Error); - - /// getClosestTargetForJIT - Pick the best target that is compatible with - /// the current host. If no close target can be found, this returns null - /// and sets the Error string to a reason. - /// - /// Maintained for compatibility through 2.6. - static const Target *getClosestTargetForJIT(std::string &Error); - - /// @} - /// @name Target Registration - /// @{ - - /// RegisterTarget - Register the given target. Attempts to register a - /// target which has already been registered will be ignored. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Name - The target name. This should be a static string. - /// @param ShortDesc - A short target description. This should be a static - /// string. - /// @param TQualityFn - The triple match quality computation function for - /// this target. - /// @param HasJIT - Whether the target supports JIT code - /// generation. - static void RegisterTarget(Target &T, - const char *Name, - const char *ShortDesc, - Target::TripleMatchQualityFnTy TQualityFn, - bool HasJIT = false); - - /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct a MCAsmInfo for the target. - static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) { - // Ignore duplicate registration. - if (!T.MCAsmInfoCtorFn) - T.MCAsmInfoCtorFn = Fn; - } - - /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct a MCCodeGenInfo for the target. - static void RegisterMCCodeGenInfo(Target &T, - Target::MCCodeGenInfoCtorFnTy Fn) { - // Ignore duplicate registration. - if (!T.MCCodeGenInfoCtorFn) - T.MCCodeGenInfoCtorFn = Fn; - } - - /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct a MCInstrInfo for the target. - static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) { - // Ignore duplicate registration. - if (!T.MCInstrInfoCtorFn) - T.MCInstrInfoCtorFn = Fn; - } - - /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct a MCRegisterInfo for the target. - static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) { - // Ignore duplicate registration. - if (!T.MCRegInfoCtorFn) - T.MCRegInfoCtorFn = Fn; - } - - /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for - /// the given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct a MCSubtargetInfo for the target. - static void RegisterMCSubtargetInfo(Target &T, - Target::MCSubtargetInfoCtorFnTy Fn) { - // Ignore duplicate registration. - if (!T.MCSubtargetInfoCtorFn) - T.MCSubtargetInfoCtorFn = Fn; - } - - /// RegisterTargetMachine - Register a TargetMachine implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct a TargetMachine for the target. - static void RegisterTargetMachine(Target &T, - Target::TargetMachineCtorTy Fn) { - // Ignore duplicate registration. - if (!T.TargetMachineCtorFn) - T.TargetMachineCtorFn = Fn; - } - - /// RegisterAsmBackend - Register a TargetAsmBackend implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmBackend for the target. - static void RegisterAsmBackend(Target &T, Target::AsmBackendCtorTy Fn) { - if (!T.AsmBackendCtorFn) - T.AsmBackendCtorFn = Fn; - } - - /// RegisterAsmLexer - Register a TargetAsmLexer implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmLexer for the target. - static void RegisterAsmLexer(Target &T, Target::AsmLexerCtorTy Fn) { - if (!T.AsmLexerCtorFn) - T.AsmLexerCtorFn = Fn; - } - - /// RegisterAsmParser - Register a TargetAsmParser implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmParser for the target. - static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) { - if (!T.AsmParserCtorFn) - T.AsmParserCtorFn = Fn; - } - - /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given - /// target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmPrinter for the target. - static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) { - // Ignore duplicate registration. - if (!T.AsmPrinterCtorFn) - T.AsmPrinterCtorFn = Fn; - } - - /// RegisterMCDisassembler - Register a MCDisassembler implementation for - /// the given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an MCDisassembler for the target. - static void RegisterMCDisassembler(Target &T, - Target::MCDisassemblerCtorTy Fn) { - if (!T.MCDisassemblerCtorFn) - T.MCDisassemblerCtorFn = Fn; - } - - /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an MCInstPrinter for the target. - static void RegisterMCInstPrinter(Target &T, - Target::MCInstPrinterCtorTy Fn) { - if (!T.MCInstPrinterCtorFn) - T.MCInstPrinterCtorFn = Fn; - } - - /// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the - /// given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an MCCodeEmitter for the target. - static void RegisterCodeEmitter(Target &T, Target::CodeEmitterCtorTy Fn) { - if (!T.CodeEmitterCtorFn) - T.CodeEmitterCtorFn = Fn; - } - - /// RegisterObjectStreamer - Register a object code MCStreamer implementation - /// for the given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an MCStreamer for the target. - static void RegisterObjectStreamer(Target &T, Target::ObjectStreamerCtorTy Fn) { - if (!T.ObjectStreamerCtorFn) - T.ObjectStreamerCtorFn = Fn; - } - - /// RegisterAsmStreamer - Register an assembly MCStreamer implementation - /// for the given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct an MCStreamer for the target. - static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) { - if (T.AsmStreamerCtorFn == createAsmStreamer) - T.AsmStreamerCtorFn = Fn; - } - - /// @} - }; - - - //===--------------------------------------------------------------------===// - - /// RegisterTarget - Helper template for registering a target, for use in the - /// target's initialization function. Usage: - /// - /// - /// Target TheFooTarget; // The global target instance. - /// - /// extern "C" void LLVMInitializeFooTargetInfo() { - /// RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description"); - /// } - template<Triple::ArchType TargetArchType = Triple::InvalidArch, - bool HasJIT = false> - struct RegisterTarget { - RegisterTarget(Target &T, const char *Name, const char *Desc) { - TargetRegistry::RegisterTarget(T, Name, Desc, - &getTripleMatchQuality, - HasJIT); - } - - static unsigned getTripleMatchQuality(const std::string &TT) { - if (Triple(TT).getArch() == TargetArchType) - return 20; - return 0; - } - }; - - /// RegisterMCAsmInfo - Helper template for registering a target assembly info - /// implementation. This invokes the static "Create" method on the class to - /// actually do the construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget); - /// } - template<class MCAsmInfoImpl> - struct RegisterMCAsmInfo { - RegisterMCAsmInfo(Target &T) { - TargetRegistry::RegisterMCAsmInfo(T, &Allocator); - } - private: - static MCAsmInfo *Allocator(const Target &T, StringRef TT) { - return new MCAsmInfoImpl(T, TT); - } - - }; - - /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info - /// implementation. This invokes the specified function to do the - /// construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction); - /// } - struct RegisterMCAsmInfoFn { - RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) { - TargetRegistry::RegisterMCAsmInfo(T, Fn); - } - }; - - /// RegisterMCCodeGenInfo - Helper template for registering a target codegen info - /// implementation. This invokes the static "Create" method on the class - /// to actually do the construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget); - /// } - template<class MCCodeGenInfoImpl> - struct RegisterMCCodeGenInfo { - RegisterMCCodeGenInfo(Target &T) { - TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator); - } - private: - static MCCodeGenInfo *Allocator(StringRef TT, Reloc::Model M) { - return new MCCodeGenInfoImpl(); - } - }; - - /// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen - /// info implementation. This invokes the specified function to do the - /// construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction); - /// } - struct RegisterMCCodeGenInfoFn { - RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) { - TargetRegistry::RegisterMCCodeGenInfo(T, Fn); - } - }; - - /// RegisterMCInstrInfo - Helper template for registering a target instruction - /// info implementation. This invokes the static "Create" method on the class - /// to actually do the construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget); - /// } - template<class MCInstrInfoImpl> - struct RegisterMCInstrInfo { - RegisterMCInstrInfo(Target &T) { - TargetRegistry::RegisterMCInstrInfo(T, &Allocator); - } - private: - static MCInstrInfo *Allocator() { - return new MCInstrInfoImpl(); - } - }; - - /// RegisterMCInstrInfoFn - Helper template for registering a target - /// instruction info implementation. This invokes the specified function to - /// do the construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction); - /// } - struct RegisterMCInstrInfoFn { - RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) { - TargetRegistry::RegisterMCInstrInfo(T, Fn); - } - }; - - /// RegisterMCRegInfo - Helper template for registering a target register info - /// implementation. This invokes the static "Create" method on the class to - /// actually do the construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget); - /// } - template<class MCRegisterInfoImpl> - struct RegisterMCRegInfo { - RegisterMCRegInfo(Target &T) { - TargetRegistry::RegisterMCRegInfo(T, &Allocator); - } - private: - static MCRegisterInfo *Allocator(StringRef TT) { - return new MCRegisterInfoImpl(); - } - }; - - /// RegisterMCRegInfoFn - Helper template for registering a target register - /// info implementation. This invokes the specified function to do the - /// construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction); - /// } - struct RegisterMCRegInfoFn { - RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) { - TargetRegistry::RegisterMCRegInfo(T, Fn); - } - }; - - /// RegisterMCSubtargetInfo - Helper template for registering a target - /// subtarget info implementation. This invokes the static "Create" method - /// on the class to actually do the construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget); - /// } - template<class MCSubtargetInfoImpl> - struct RegisterMCSubtargetInfo { - RegisterMCSubtargetInfo(Target &T) { - TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator); - } - private: - static MCSubtargetInfo *Allocator(StringRef TT, StringRef CPU, - StringRef FS) { - return new MCSubtargetInfoImpl(); - } - }; - - /// RegisterMCSubtargetInfoFn - Helper template for registering a target - /// subtarget info implementation. This invokes the specified function to - /// do the construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction); - /// } - struct RegisterMCSubtargetInfoFn { - RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) { - TargetRegistry::RegisterMCSubtargetInfo(T, Fn); - } - }; - - /// RegisterTargetMachine - Helper template for registering a target machine - /// implementation, for use in the target machine initialization - /// function. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget); - /// } - template<class TargetMachineImpl> - struct RegisterTargetMachine { - RegisterTargetMachine(Target &T) { - TargetRegistry::RegisterTargetMachine(T, &Allocator); - } - - private: - static TargetMachine *Allocator(const Target &T, StringRef TT, - StringRef CPU, StringRef FS, - Reloc::Model RM) { - return new TargetMachineImpl(T, TT, CPU, FS, RM); - } - }; - - /// RegisterAsmBackend - Helper template for registering a target specific - /// assembler backend. Usage: - /// - /// extern "C" void LLVMInitializeFooAsmBackend() { - /// extern Target TheFooTarget; - /// RegisterAsmBackend<FooAsmLexer> X(TheFooTarget); - /// } - template<class AsmBackendImpl> - struct RegisterAsmBackend { - RegisterAsmBackend(Target &T) { - TargetRegistry::RegisterAsmBackend(T, &Allocator); - } - - private: - static TargetAsmBackend *Allocator(const Target &T, - const std::string &Triple) { - return new AsmBackendImpl(T, Triple); - } - }; - - /// RegisterAsmLexer - Helper template for registering a target specific - /// assembly lexer, for use in the target machine initialization - /// function. Usage: - /// - /// extern "C" void LLVMInitializeFooAsmLexer() { - /// extern Target TheFooTarget; - /// RegisterAsmLexer<FooAsmLexer> X(TheFooTarget); - /// } - template<class AsmLexerImpl> - struct RegisterAsmLexer { - RegisterAsmLexer(Target &T) { - TargetRegistry::RegisterAsmLexer(T, &Allocator); - } - - private: - static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) { - return new AsmLexerImpl(T, MAI); - } - }; - - /// RegisterAsmParser - Helper template for registering a target specific - /// assembly parser, for use in the target machine initialization - /// function. Usage: - /// - /// extern "C" void LLVMInitializeFooAsmParser() { - /// extern Target TheFooTarget; - /// RegisterAsmParser<FooAsmParser> X(TheFooTarget); - /// } - template<class AsmParserImpl> - struct RegisterAsmParser { - RegisterAsmParser(Target &T) { - TargetRegistry::RegisterAsmParser(T, &Allocator); - } - - private: - static TargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) { - return new AsmParserImpl(STI, P); - } - }; - - /// RegisterAsmPrinter - Helper template for registering a target specific - /// assembly printer, for use in the target machine initialization - /// function. Usage: - /// - /// extern "C" void LLVMInitializeFooAsmPrinter() { - /// extern Target TheFooTarget; - /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget); - /// } - template<class AsmPrinterImpl> - struct RegisterAsmPrinter { - RegisterAsmPrinter(Target &T) { - TargetRegistry::RegisterAsmPrinter(T, &Allocator); - } - - private: - static AsmPrinter *Allocator(TargetMachine &TM, MCStreamer &Streamer) { - return new AsmPrinterImpl(TM, Streamer); - } - }; - - /// RegisterCodeEmitter - Helper template for registering a target specific - /// machine code emitter, for use in the target initialization - /// function. Usage: - /// - /// extern "C" void LLVMInitializeFooCodeEmitter() { - /// extern Target TheFooTarget; - /// RegisterCodeEmitter<FooCodeEmitter> X(TheFooTarget); - /// } - template<class CodeEmitterImpl> - struct RegisterCodeEmitter { - RegisterCodeEmitter(Target &T) { - TargetRegistry::RegisterCodeEmitter(T, &Allocator); - } - - private: - static MCCodeEmitter *Allocator(const MCInstrInfo &II, - const MCSubtargetInfo &STI, - MCContext &Ctx) { - return new CodeEmitterImpl(); - } - }; - -} - -#endif diff --git a/include/llvm/Target/TargetSelect.h b/include/llvm/Target/TargetSelect.h deleted file mode 100644 index 81fd9c9..0000000 --- a/include/llvm/Target/TargetSelect.h +++ /dev/null @@ -1,214 +0,0 @@ -//===- TargetSelect.h - Target Selection & Registration ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides utilities to make sure that certain classes of targets are -// linked into the main application executable, and initialize them as -// appropriate. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETSELECT_H -#define LLVM_TARGET_TARGETSELECT_H - -#include "llvm/Config/llvm-config.h" - -extern "C" { - // Declare all of the target-initialization functions that are available. -#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetInfo(); -#include "llvm/Config/Targets.def" - -#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(); -#include "llvm/Config/Targets.def" - -#define LLVM_TARGET(TargetName) \ - void LLVMInitialize##TargetName##MCAsmInfo(); -#include "llvm/Config/Targets.def" - -#define LLVM_TARGET(TargetName) \ - void LLVMInitialize##TargetName##MCCodeGenInfo(); -#include "llvm/Config/Targets.def" - -#define LLVM_TARGET(TargetName) \ - void LLVMInitialize##TargetName##MCInstrInfo(); -#include "llvm/Config/Targets.def" - -#define LLVM_TARGET(TargetName) \ - void LLVMInitialize##TargetName##MCRegisterInfo(); -#include "llvm/Config/Targets.def" - -#define LLVM_TARGET(TargetName) \ - void LLVMInitialize##TargetName##MCSubtargetInfo(); -#include "llvm/Config/Targets.def" - - // Declare all of the available assembly printer initialization functions. -#define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter(); -#include "llvm/Config/AsmPrinters.def" - - // Declare all of the available assembly parser initialization functions. -#define LLVM_ASM_PARSER(TargetName) void LLVMInitialize##TargetName##AsmParser(); -#include "llvm/Config/AsmParsers.def" - - // Declare all of the available disassembler initialization functions. -#define LLVM_DISASSEMBLER(TargetName) \ - void LLVMInitialize##TargetName##Disassembler(); -#include "llvm/Config/Disassemblers.def" -} - -namespace llvm { - /// InitializeAllTargetInfos - The main program should call this function if - /// it wants access to all available targets that LLVM is configured to - /// support, to make them available via the TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllTargetInfos() { -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo(); -#include "llvm/Config/Targets.def" - } - - /// InitializeAllTargets - The main program should call this function if it - /// wants access to all available target machines that LLVM is configured to - /// support, to make them available via the TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllTargets() { - // FIXME: Remove this, clients should do it. - InitializeAllTargetInfos(); - -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target(); -#include "llvm/Config/Targets.def" - } - - /// InitializeAllMCAsmInfos - The main program should call this function - /// if it wants access to all available assembly infos for targets that - /// LLVM is configured to support, to make them available via the - /// TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllMCAsmInfos() { -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCAsmInfo(); -#include "llvm/Config/Targets.def" - } - - /// InitializeAllMCCodeGenInfos - The main program should call this function - /// if it wants access to all targets machines that LLVM is configured to - /// support, to make them available via the TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllMCCodeGenInfos() { -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCCodeGenInfo(); -#include "llvm/Config/Targets.def" - } - - /// InitializeAllMCInstrInfos - The main program should call this function - /// if it wants access to all available instruction infos for targets that - /// LLVM is configured to support, to make them available via the - /// TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllMCInstrInfos() { -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCInstrInfo(); -#include "llvm/Config/Targets.def" - } - - /// InitializeAllMCRegisterInfos - The main program should call this function - /// if it wants access to all available register infos for targets that - /// LLVM is configured to support, to make them available via the - /// TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllMCRegisterInfos() { -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCRegisterInfo(); -#include "llvm/Config/Targets.def" - } - - /// InitializeAllMCSubtargetInfos - The main program should call this function - /// if it wants access to all available subtarget infos for targets that LLVM - /// is configured to support, to make them available via the TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllMCSubtargetInfos() { -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCSubtargetInfo(); -#include "llvm/Config/Targets.def" - } - - /// InitializeAllAsmPrinters - The main program should call this function if - /// it wants all asm printers that LLVM is configured to support, to make them - /// available via the TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllAsmPrinters() { -#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter(); -#include "llvm/Config/AsmPrinters.def" - } - - /// InitializeAllAsmParsers - The main program should call this function if it - /// wants all asm parsers that LLVM is configured to support, to make them - /// available via the TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllAsmParsers() { -#define LLVM_ASM_PARSER(TargetName) LLVMInitialize##TargetName##AsmParser(); -#include "llvm/Config/AsmParsers.def" - } - - /// InitializeAllDisassemblers - The main program should call this function if - /// it wants all disassemblers that LLVM is configured to support, to make - /// them available via the TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllDisassemblers() { -#define LLVM_DISASSEMBLER(TargetName) LLVMInitialize##TargetName##Disassembler(); -#include "llvm/Config/Disassemblers.def" - } - - /// InitializeNativeTarget - The main program should call this function to - /// initialize the native target corresponding to the host. This is useful - /// for JIT applications to ensure that the target gets linked in correctly. - /// - /// It is legal for a client to make multiple calls to this function. - inline bool InitializeNativeTarget() { - // If we have a native target, initialize it to ensure it is linked in. -#ifdef LLVM_NATIVE_TARGET - LLVM_NATIVE_TARGETINFO(); - LLVM_NATIVE_TARGET(); - LLVM_NATIVE_MCASMINFO(); - LLVM_NATIVE_MCCODEGENINFO(); - return false; -#else - return true; -#endif - } - - /// InitializeNativeTargetAsmPrinter - The main program should call - /// this function to initialize the native target asm printer. - inline bool InitializeNativeTargetAsmPrinter() { - // If we have a native target, initialize the corresponding asm printer. -#ifdef LLVM_NATIVE_ASMPRINTER - LLVM_NATIVE_ASMPRINTER(); - return false; -#else - return true; -#endif - } - - /// InitializeNativeTargetAsmParser - The main program should call - /// this function to initialize the native target asm parser. - inline bool InitializeNativeTargetAsmParser() { - // If we have a native target, initialize the corresponding asm parser. -#ifdef LLVM_NATIVE_ASMPARSER - LLVM_NATIVE_ASMPARSER(); - return false; -#else - return true; -#endif - } - -} - -#endif diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 9d1ef2c..612635e 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -149,6 +149,10 @@ def SDTSelect : SDTypeProfile<1, 3, [ // select SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> ]>; +def SDTVSelect : SDTypeProfile<1, 3, [ // vselect + SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> +]>; + def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>, SDTCisVT<5, OtherVT> @@ -205,12 +209,21 @@ def SDTMemBarrier : SDTypeProfile<0, 5, [ // memory barier SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisSameAs<0,4>, SDTCisInt<0> ]>; +def SDTAtomicFence : SDTypeProfile<0, 2, [ + SDTCisSameAs<0,1>, SDTCisPtrTy<0> +]>; def SDTAtomic3 : SDTypeProfile<1, 3, [ SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1> ]>; def SDTAtomic2 : SDTypeProfile<1, 2, [ SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1> ]>; +def SDTAtomicStore : SDTypeProfile<0, 2, [ + SDTCisPtrTy<0>, SDTCisInt<1> +]>; +def SDTAtomicLoad : SDTypeProfile<1, 1, [ + SDTCisInt<0>, SDTCisPtrTy<1> +]>; def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5> @@ -381,8 +394,8 @@ def f32_to_f16 : SDNode<"ISD::FP32_TO_FP16", SDTFPToIntOp>; def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; def select : SDNode<"ISD::SELECT" , SDTSelect>; +def vselect : SDNode<"ISD::VSELECT" , SDTVSelect>; def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>; -def vsetcc : SDNode<"ISD::VSETCC" , SDTSetCC>; def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>; def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; @@ -397,6 +410,9 @@ def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch, def membarrier : SDNode<"ISD::MEMBARRIER" , SDTMemBarrier, [SDNPHasChain, SDNPSideEffect]>; +def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence, + [SDNPHasChain, SDNPSideEffect]>; + def atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2, @@ -421,6 +437,10 @@ def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; // Do not use ld, st directly. Use load, extload, sextload, zextload, store, // and truncst (see below). @@ -838,6 +858,28 @@ defm atomic_load_min : binary_atomic_op<atomic_load_min>; defm atomic_load_max : binary_atomic_op<atomic_load_max>; defm atomic_load_umin : binary_atomic_op<atomic_load_umin>; defm atomic_load_umax : binary_atomic_op<atomic_load_umax>; +defm atomic_store : binary_atomic_op<atomic_store>; + +def atomic_load_8 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8; +}]>; +def atomic_load_16 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16; +}]>; +def atomic_load_32 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32; +}]>; +def atomic_load_64 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64; +}]>; //===----------------------------------------------------------------------===// // Selection DAG CONVERT_RNDSAT patterns |