diff options
Diffstat (limited to 'include/llvm/Target')
19 files changed, 625 insertions, 1211 deletions
diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/Target/SubtargetFeature.h deleted file mode 100644 index 4213d9b..0000000 --- a/include/llvm/Target/SubtargetFeature.h +++ /dev/null @@ -1,119 +0,0 @@ -//===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines and manages user or tool specified CPU characteristics. -// The intent is to be able to package specific features that should or should -// not be used on a specific target processor. A tool, such as llc, could, as -// as example, gather chip info from the command line, a long with features -// that should be used on that chip. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_SUBTARGETFEATURE_H -#define LLVM_TARGET_SUBTARGETFEATURE_H - -#include <string> -#include <vector> -#include <cstring> -#include "llvm/ADT/Triple.h" -#include "llvm/Support/DataTypes.h" - -namespace llvm { - class raw_ostream; - -//===----------------------------------------------------------------------===// -/// -/// SubtargetFeatureKV - Used to provide key value pairs for feature and -/// CPU bit flags. -// -struct SubtargetFeatureKV { - const char *Key; // K-V key string - const char *Desc; // Help descriptor - uint64_t Value; // K-V integer value - uint64_t Implies; // K-V bit mask - - // Compare routine for std binary search - bool operator<(const SubtargetFeatureKV &S) const { - return strcmp(Key, S.Key) < 0; - } -}; - -//===----------------------------------------------------------------------===// -/// -/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary -/// pointers. -// -struct SubtargetInfoKV { - const char *Key; // K-V key string - void *Value; // K-V pointer value - - // Compare routine for std binary search - bool operator<(const SubtargetInfoKV &S) const { - return strcmp(Key, S.Key) < 0; - } -}; - -//===----------------------------------------------------------------------===// -/// -/// SubtargetFeatures - Manages the enabling and disabling of subtarget -/// specific features. Features are encoded as a string of the form -/// "cpu,+attr1,+attr2,-attr3,...,+attrN" -/// A comma separates each feature from the next (all lowercase.) -/// The first feature is always the CPU subtype (eg. pentiumm). If the CPU -/// value is "generic" then the CPU subtype should be generic for the target. -/// Each of the remaining features is prefixed with + or - indicating whether -/// that feature should be enabled or disabled contrary to the cpu -/// specification. -/// - -class SubtargetFeatures { - std::vector<std::string> Features; // Subtarget features as a vector -public: - explicit SubtargetFeatures(const std::string &Initial = std::string()); - - /// Features string accessors. - std::string getString() const; - void setString(const std::string &Initial); - - /// Set the CPU string. Replaces previous setting. Setting to "" clears CPU. - void setCPU(const std::string &String); - - /// Setting CPU string only if no string is set. - void setCPUIfNone(const std::string &String); - - /// Returns current CPU string. - const std::string & getCPU() const; - - /// Adding Features. - void AddFeature(const std::string &String, bool IsEnabled = true); - - /// Get feature bits. - uint64_t getBits(const SubtargetFeatureKV *CPUTable, - size_t CPUTableSize, - const SubtargetFeatureKV *FeatureTable, - size_t FeatureTableSize); - - /// Get info pointer - void *getInfo(const SubtargetInfoKV *Table, size_t TableSize); - - /// Print feature string. - void print(raw_ostream &OS) const; - - // Dump feature info. - void dump() const; - - /// Retrieve a formatted string of the default features for the specified - /// target triple. - void getDefaultSubtargetFeatures(const std::string &CPU, - const Triple& Triple); -}; - -} // End namespace llvm - -#endif diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index ab6a4e2..018ccbd 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -26,11 +26,19 @@ class SubRegIndex { string Namespace = ""; } +// RegAltNameIndex - The alternate name set to use for register operands of +// this register class when printing. +class RegAltNameIndex { + string Namespace = ""; +} +def NoRegAltName : RegAltNameIndex; + // Register - You should define one instance of this class for each register // in the target machine. String n will become the "name" of the register. -class Register<string n> { +class Register<string n, list<string> altNames = []> { string Namespace = ""; string AsmName = n; + list<string> AltNames = altNames; // Aliases - A list of registers that this register overlaps with. A read or // modification of this register can potentially read or modify the aliased @@ -48,6 +56,10 @@ class Register<string n> { // SubRegs. list<SubRegIndex> SubRegIndices = []; + // RegAltNameIndices - The alternate name indices which are valid for this + // register. + list<RegAltNameIndex> RegAltNameIndices = []; + // CompositeIndices - Specify subreg indices that don't correspond directly to // a register in SubRegs and are not inherited. The following formats are // supported: @@ -92,7 +104,7 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> { // registers by register allocators. // class RegisterClass<string namespace, list<ValueType> regTypes, int alignment, - list<Register> regList> { + dag regList, RegAltNameIndex idx = NoRegAltName> { string Namespace = namespace; // RegType - Specify the list ValueType of the registers in this register @@ -122,7 +134,12 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment, // allocation_order_* method are not specified, this also defines the order of // allocation used by the register allocator. // - list<Register> MemberList = regList; + dag MemberList = regList; + + // AltNameIndex - The alternate register name to use when printing operands + // of this register class. Every register in the register class must have + // a valid alternate name for the given index. + RegAltNameIndex altNameIndex = idx; // SubRegClasses - Specify the register class of subregisters as a list of // dags: (RegClass SubRegIndex, SubRegindex, ...) @@ -133,11 +150,91 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment, // model instruction operand constraints, and should have isAllocatable = 0. bit isAllocatable = 1; - // MethodProtos/MethodBodies - These members can be used to insert arbitrary - // code into a generated register class. The normal usage of this is to - // overload virtual methods. - code MethodProtos = [{}]; - code MethodBodies = [{}]; + // AltOrders - List of alternative allocation orders. The default order is + // MemberList itself, and that is good enough for most targets since the + // register allocators automatically remove reserved registers and move + // callee-saved registers to the end. + list<dag> AltOrders = []; + + // AltOrderSelect - The body of a function that selects the allocation order + // to use in a given machine function. The code will be inserted in a + // function like this: + // + // static inline unsigned f(const MachineFunction &MF) { ... } + // + // The function should return 0 to select the default order defined by + // MemberList, 1 to select the first AltOrders entry and so on. + code AltOrderSelect = [{}]; +} + +// The memberList in a RegisterClass is a dag of set operations. TableGen +// evaluates these set operations and expand them into register lists. These +// are the most common operation, see test/TableGen/SetTheory.td for more +// examples of what is possible: +// +// (add R0, R1, R2) - Set Union. Each argument can be an individual register, a +// register class, or a sub-expression. This is also the way to simply list +// registers. +// +// (sub GPR, SP) - Set difference. Subtract the last arguments from the first. +// +// (and GPR, CSR) - Set intersection. All registers from the first set that are +// also in the second set. +// +// (sequence "R%u", 0, 15) -> [R0, R1, ..., R15]. Generate a sequence of +// numbered registers. +// +// (shl GPR, 4) - Remove the first N elements. +// +// (trunc GPR, 4) - Truncate after the first N elements. +// +// (rotl GPR, 1) - Rotate N places to the left. +// +// (rotr GPR, 1) - Rotate N places to the right. +// +// (decimate GPR, 2) - Pick every N'th element, starting with the first. +// +// All of these operators work on ordered sets, not lists. That means +// duplicates are removed from sub-expressions. + +// Set operators. The rest is defined in TargetSelectionDAG.td. +def sequence; +def decimate; + +// RegisterTuples - Automatically generate super-registers by forming tuples of +// sub-registers. This is useful for modeling register sequence constraints +// with pseudo-registers that are larger than the architectural registers. +// +// The sub-register lists are zipped together: +// +// def EvenOdd : RegisterTuples<[sube, subo], [(add R0, R2), (add R1, R3)]>; +// +// Generates the same registers as: +// +// let SubRegIndices = [sube, subo] in { +// def R0_R1 : RegisterWithSubRegs<"", [R0, R1]>; +// def R2_R3 : RegisterWithSubRegs<"", [R2, R3]>; +// } +// +// The generated pseudo-registers inherit super-classes and fields from their +// first sub-register. Most fields from the Register class are inferred, and +// the AsmName and Dwarf numbers are cleared. +// +// RegisterTuples instances can be used in other set operations to form +// register classes and so on. This is the only way of using the generated +// registers. +class RegisterTuples<list<SubRegIndex> Indices, list<dag> Regs> { + // SubRegs - N lists of registers to be zipped up. Super-registers are + // synthesized from the first element of each SubRegs list, the second + // element and so on. + list<dag> SubRegs = Regs; + + // SubRegIndices - N SubRegIndex instances. This provides the names of the + // sub-registers in the synthesized super-registers. + list<SubRegIndex> SubRegIndices = Indices; + + // Compose sub-register indices like in a normal Register. + list<dag> CompositeIndices = []; } @@ -196,7 +293,12 @@ class Instruction { // code. list<Predicate> Predicates = []; - // Code size. + // Size - Size of encoded instruction, or zero if the size cannot be determined + // from the opcode. + int Size = 0; + + // Code size, for instruction selection. + // FIXME: What does this actually mean? int CodeSize = 0; // Added complexity passed onto matching pattern. @@ -227,6 +329,9 @@ class Instruction { bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement? bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement? + bit isPseudo = 0; // Is this instruction a pseudo-instruction? + // If so, won't have encoding information for + // the [MC]CodeEmitter stuff. // Side effect flags - When set, the flags have these meanings: // @@ -241,6 +346,11 @@ class Instruction { // Is this instruction a "real" instruction (with a distinct machine // encoding), or is it a pseudo instruction used for codegen modeling // purposes. + // FIXME: For now this is distinct from isPseudo, above, as code-gen-only + // instructions can (and often do) still have encoding information + // 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. bit isCodeGenOnly = 0; // Is this instruction a pseudo instruction for use by the assembler parser. @@ -268,6 +378,14 @@ class Instruction { ///@} } +/// PseudoInstExpansion - Expansion information for a pseudo-instruction. +/// Which instruction it expands to and how the operands map from the +/// pseudo. +class PseudoInstExpansion<dag Result> { + dag ResultInst = Result; // The instruction to generate. + bit isPseudo = 1; +} + /// Predicates - These are extra conditionals which are turned into instruction /// selector matching code. Currently each predicate is just a string. class Predicate<string cond> { @@ -277,6 +395,15 @@ class Predicate<string cond> { /// matcher, this is true. Targets should set this by inheriting their /// feature from the AssemblerPredicate class in addition to Predicate. bit AssemblerMatcherPredicate = 0; + + /// AssemblerCondString - Name of the subtarget feature being tested used + /// as alternative condition string used for assembler matcher. + /// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0". + /// "!ModeThumb" is translated to "(Bits & ModeThumb) == 0". + /// It can also list multiple features separated by ",". + /// e.g. "ModeThumb,FeatureThumb2" is translated to + /// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0". + string AssemblerCondString = ""; } /// NoHonorSignDependentRounding - This predicate is true if support for @@ -373,6 +500,7 @@ class Operand<ValueType ty> { string EncoderMethod = ""; string DecoderMethod = ""; string AsmOperandLowerMethod = ?; + string OperandType = "OPERAND_UNKNOWN"; dag MIOperandInfo = (ops); // ParserMatchClass - The "match class" that operands of this type fit @@ -386,6 +514,25 @@ class Operand<ValueType ty> { AsmOperandClass ParserMatchClass = ImmAsmOperand; } +class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> { + // RegClass - The register class of the operand. + RegisterClass RegClass = regclass; + // PrintMethod - The target method to call to print register operands of + // this type. The method normally will just use an alt-name index to look + // up the name to print. Default to the generic printOperand(). + string PrintMethod = pm; + // ParserMatchClass - The "match class" that operands of this type fit + // in. Match classes are used to define the order in which instructions are + // match, to ensure that which instructions gets matched is deterministic. + // + // The target specific parser must be able to classify an parsed operand into + // a unique class, which does not partially overlap with any other classes. It + // can match a subset of some other class, in which case the AsmOperandClass + // should declare the other operand as one of its super classes. + AsmOperandClass ParserMatchClass; +} + +let OperandType = "OPERAND_IMMEDIATE" in { def i1imm : Operand<i1>; def i8imm : Operand<i8>; def i16imm : Operand<i16>; @@ -394,6 +541,7 @@ def i64imm : Operand<i64>; def f32imm : Operand<f32>; def f64imm : Operand<f64>; +} /// zero_reg definition - Special node to stand for the zero register. /// @@ -566,8 +714,9 @@ def DefaultAsmParser : AsmParser; /// AssemblerPredicate - This is a Predicate that can be used when the assembler /// matches instructions and aliases. -class AssemblerPredicate { +class AssemblerPredicate<string cond> { bit AssemblerMatcherPredicate = 1; + string AssemblerCondString = cond; } diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index 743a2d4..5a526dc 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -20,6 +20,7 @@ #include "llvm/Target/TargetRegisterInfo.h" namespace llvm { + template <typename T> class ArrayRef; class MCSection; class MCContext; class MachineFunction; @@ -27,30 +28,14 @@ namespace llvm { class TargetLoweringObjectFile; class TargetAsmInfo { - unsigned PointerSize; - bool IsLittleEndian; - TargetFrameLowering::StackDirection StackDir; - const TargetRegisterInfo *TRI; std::vector<MachineMove> InitialFrameState; + const TargetRegisterInfo *TRI; + const TargetFrameLowering *TFI; const TargetLoweringObjectFile *TLOF; public: explicit TargetAsmInfo(const TargetMachine &TM); - /// getPointerSize - Get the pointer size in bytes. - unsigned getPointerSize() const { - return PointerSize; - } - - /// islittleendian - True if the target is little endian. - bool isLittleEndian() const { - return IsLittleEndian; - } - - TargetFrameLowering::StackDirection getStackGrowthDirection() const { - return StackDir; - } - const MCSection *getDwarfLineSection() const { return TLOF->getDwarfLineSection(); } @@ -59,6 +44,10 @@ public: return TLOF->getEHFrameSection(); } + const MCSection *getCompactUnwindSection() const { + return TLOF->getCompactUnwindSection(); + } + const MCSection *getDwarfFrameSection() const { return TLOF->getDwarfFrameSection(); } @@ -79,6 +68,12 @@ public: return TLOF->isFunctionEHFrameSymbolPrivate(); } + int getCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs, + int DataAlignmentFactor, + bool IsEH) const { + return TFI->getCompactUnwindEncoding(Instrs, DataAlignmentFactor, IsEH); + } + const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const { return TRI->getCalleeSavedRegs(MF); } diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h index 9ff50cb..df84231 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/Target/TargetAsmParser.h @@ -15,7 +15,6 @@ namespace llvm { class MCStreamer; class StringRef; -class Target; class SMLoc; class AsmToken; class MCParsedAsmOperand; @@ -26,23 +25,19 @@ class TargetAsmParser : public MCAsmParserExtension { TargetAsmParser(const TargetAsmParser &); // DO NOT IMPLEMENT void operator=(const TargetAsmParser &); // DO NOT IMPLEMENT protected: // Can only create subclasses. - TargetAsmParser(const Target &); + TargetAsmParser(); - /// The Target that this machine was created for. - const Target &TheTarget; - - /// The current set of available features. + /// AvailableFeatures - The current set of available features. unsigned AvailableFeatures; public: virtual ~TargetAsmParser(); - const Target &getTarget() const { return TheTarget; } - unsigned getAvailableFeatures() const { return AvailableFeatures; } void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } - virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0; + virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, + SMLoc &EndLoc) = 0; /// ParseInstruction - Parse one assembly instruction. /// diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index 32e3e2b..c280810 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -259,7 +259,7 @@ public: /// getIntPtrType - Return an unsigned integer type that is the same size or /// greater to the host pointer size. /// - const IntegerType *getIntPtrType(LLVMContext &C) const; + IntegerType *getIntPtrType(LLVMContext &C) const; /// getIndexedOffset - return the offset from the beginning of the type for /// the specified indices. This is used to implement getelementptr. @@ -272,12 +272,6 @@ public: /// information is lazily cached. const StructLayout *getStructLayout(const StructType *Ty) const; - /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout - /// objects. If a TargetData object is alive when types are being refined and - /// removed, this method must be called whenever a StructType is removed to - /// avoid a dangling pointer in this cache. - void InvalidateStructLayoutInfo(const StructType *Ty) const; - /// getPreferredAlignment - Return the preferred alignment of the specified /// global. This includes an explicitly requested alignment (if the global /// has one). diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index e104b16..e3d77cf 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -15,6 +15,8 @@ #define LLVM_TARGET_TARGETFRAMELOWERING_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/ADT/ArrayRef.h" #include <utility> #include <vector> @@ -189,6 +191,14 @@ 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/TargetInstrDesc.h b/include/llvm/Target/TargetInstrDesc.h deleted file mode 100644 index 6e20e8a..0000000 --- a/include/llvm/Target/TargetInstrDesc.h +++ /dev/null @@ -1,520 +0,0 @@ -//===-- llvm/Target/TargetInstrDesc.h - Instruction Descriptors -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the TargetOperandInfo and TargetInstrDesc classes, which -// are used to describe target instructions and their operands. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETINSTRDESC_H -#define LLVM_TARGET_TARGETINSTRDESC_H - -#include "llvm/Support/DataTypes.h" - -namespace llvm { - -class TargetRegisterClass; -class TargetRegisterInfo; - -//===----------------------------------------------------------------------===// -// Machine Operand Flags and Description -//===----------------------------------------------------------------------===// - -namespace TOI { - // Operand constraints - enum OperandConstraint { - TIED_TO = 0, // Must be allocated the same register as. - EARLY_CLOBBER // Operand is an early clobber register operand - }; - - /// OperandFlags - These are flags set on operands, but should be considered - /// private, all access should go through the TargetOperandInfo accessors. - /// See the accessors for a description of what these are. - enum OperandFlags { - LookupPtrRegClass = 0, - Predicate, - OptionalDef - }; -} - -/// TargetOperandInfo - This holds information about one operand of a machine -/// instruction, indicating the register class for register operands, etc. -/// -class TargetOperandInfo { -public: - /// RegClass - This specifies the register class enumeration of the operand - /// if the operand is a register. If isLookupPtrRegClass is set, then this is - /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to - /// get a dynamic register class. - /// - /// NOTE: This member should be considered to be private, all access should go - /// through "getRegClass(TRI)" below. - short RegClass; - - /// Flags - These are flags from the TOI::OperandFlags enum. - unsigned short Flags; - - /// Lower 16 bits are used to specify which constraints are set. The higher 16 - /// bits are used to specify the value of constraints (4 bits each). - unsigned Constraints; - /// Currently no other information. - - /// getRegClass - Get the register class for the operand, handling resolution - /// of "symbolic" pointer register classes etc. If this is not a register - /// operand, this returns null. - const TargetRegisterClass *getRegClass(const TargetRegisterInfo *TRI) const; - - - /// isLookupPtrRegClass - Set if this operand is a pointer value and it - /// requires a callback to look up its register class. - bool isLookupPtrRegClass() const { return Flags&(1 <<TOI::LookupPtrRegClass);} - - /// isPredicate - Set if this is one of the operands that made up of - /// the predicate operand that controls an isPredicable() instruction. - bool isPredicate() const { return Flags & (1 << TOI::Predicate); } - - /// isOptionalDef - Set if this operand is a optional def. - /// - bool isOptionalDef() const { return Flags & (1 << TOI::OptionalDef); } -}; - - -//===----------------------------------------------------------------------===// -// Machine Instruction Flags and Description -//===----------------------------------------------------------------------===// - -/// TargetInstrDesc flags - These should be considered private to the -/// implementation of the TargetInstrDesc class. Clients should use the -/// predicate methods on TargetInstrDesc, not use these directly. These -/// all correspond to bitfields in the TargetInstrDesc::Flags field. -namespace TID { - enum { - Variadic = 0, - HasOptionalDef, - Return, - Call, - Barrier, - Terminator, - Branch, - IndirectBranch, - Compare, - MoveImm, - Bitcast, - DelaySlot, - FoldableAsLoad, - MayLoad, - MayStore, - Predicable, - NotDuplicable, - UnmodeledSideEffects, - Commutable, - ConvertibleTo3Addr, - UsesCustomInserter, - Rematerializable, - CheapAsAMove, - ExtraSrcRegAllocReq, - ExtraDefRegAllocReq - }; -} - -/// TargetInstrDesc - Describe properties that are true of each -/// instruction in the target description file. This captures information about -/// side effects, register use and many other things. There is one instance of -/// this struct for each target instruction class, and the MachineInstr class -/// points to this struct directly to describe itself. -class TargetInstrDesc { -public: - unsigned short Opcode; // The opcode number - unsigned short NumOperands; // Num of args (may be more if variable_ops) - unsigned short NumDefs; // Num of args that are definitions - unsigned short SchedClass; // enum identifying instr sched class - const char * Name; // Name of the instruction record in td file - unsigned Flags; // Flags identifying machine instr class - uint64_t TSFlags; // Target Specific Flag values - const unsigned *ImplicitUses; // Registers implicitly read by this instr - const unsigned *ImplicitDefs; // Registers implicitly defined by this instr - const TargetRegisterClass **RCBarriers; // Reg classes completely "clobbered" - const TargetOperandInfo *OpInfo; // 'NumOperands' entries about operands - - /// getOperandConstraint - Returns the value of the specific constraint if - /// it is set. Returns -1 if it is not set. - int getOperandConstraint(unsigned OpNum, - TOI::OperandConstraint Constraint) const { - if (OpNum < NumOperands && - (OpInfo[OpNum].Constraints & (1 << Constraint))) { - unsigned Pos = 16 + Constraint * 4; - return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf; - } - return -1; - } - - /// getRegClass - Returns the register class constraint for OpNum, or NULL. - const TargetRegisterClass *getRegClass(unsigned OpNum, - const TargetRegisterInfo *TRI) const { - return OpNum < NumOperands ? OpInfo[OpNum].getRegClass(TRI) : 0; - } - - /// getOpcode - Return the opcode number for this descriptor. - unsigned getOpcode() const { - return Opcode; - } - - /// getName - Return the name of the record in the .td file for this - /// instruction, for example "ADD8ri". - const char *getName() const { - return Name; - } - - /// getNumOperands - Return the number of declared MachineOperands for this - /// MachineInstruction. Note that variadic (isVariadic() returns true) - /// instructions may have additional operands at the end of the list, and note - /// that the machine instruction may include implicit register def/uses as - /// well. - unsigned getNumOperands() const { - return NumOperands; - } - - /// getNumDefs - Return the number of MachineOperands that are register - /// definitions. Register definitions always occur at the start of the - /// machine operand list. This is the number of "outs" in the .td file, - /// and does not include implicit defs. - unsigned getNumDefs() const { - return NumDefs; - } - - /// isVariadic - Return true if this instruction can have a variable number of - /// operands. In this case, the variable operands will be after the normal - /// operands but before the implicit definitions and uses (if any are - /// present). - bool isVariadic() const { - return Flags & (1 << TID::Variadic); - } - - /// hasOptionalDef - Set if this instruction has an optional definition, e.g. - /// ARM instructions which can set condition code if 's' bit is set. - bool hasOptionalDef() const { - return Flags & (1 << TID::HasOptionalDef); - } - - /// getImplicitUses - Return a list of registers that are potentially - /// read by any instance of this machine instruction. For example, on X86, - /// the "adc" instruction adds two register operands and adds the carry bit in - /// from the flags register. In this case, the instruction is marked as - /// implicitly reading the flags. Likewise, the variable shift instruction on - /// X86 is marked as implicitly reading the 'CL' register, which it always - /// does. - /// - /// This method returns null if the instruction has no implicit uses. - const unsigned *getImplicitUses() const { - return ImplicitUses; - } - - /// getNumImplicitUses - Return the number of implicit uses this instruction - /// has. - unsigned getNumImplicitUses() const { - if (ImplicitUses == 0) return 0; - unsigned i = 0; - for (; ImplicitUses[i]; ++i) /*empty*/; - return i; - } - - - /// getImplicitDefs - Return a list of registers that are potentially - /// written by any instance of this machine instruction. For example, on X86, - /// many instructions implicitly set the flags register. In this case, they - /// are marked as setting the FLAGS. Likewise, many instructions always - /// deposit their result in a physical register. For example, the X86 divide - /// instruction always deposits the quotient and remainder in the EAX/EDX - /// registers. For that instruction, this will return a list containing the - /// EAX/EDX/EFLAGS registers. - /// - /// This method returns null if the instruction has no implicit defs. - const unsigned *getImplicitDefs() const { - return ImplicitDefs; - } - - /// getNumImplicitDefs - Return the number of implicit defs this instruction - /// has. - unsigned getNumImplicitDefs() const { - if (ImplicitDefs == 0) return 0; - unsigned i = 0; - for (; ImplicitDefs[i]; ++i) /*empty*/; - return i; - } - - /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly - /// uses the specified physical register. - bool hasImplicitUseOfPhysReg(unsigned Reg) const { - if (const unsigned *ImpUses = ImplicitUses) - for (; *ImpUses; ++ImpUses) - if (*ImpUses == Reg) return true; - return false; - } - - /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly - /// defines the specified physical register. - bool hasImplicitDefOfPhysReg(unsigned Reg) const { - if (const unsigned *ImpDefs = ImplicitDefs) - for (; *ImpDefs; ++ImpDefs) - if (*ImpDefs == Reg) return true; - return false; - } - - /// getRegClassBarriers - Return a list of register classes that are - /// completely clobbered by this machine instruction. For example, on X86 - /// the call instructions will completely clobber all the registers in the - /// fp stack and XMM classes. - /// - /// This method returns null if the instruction doesn't completely clobber - /// any register class. - const TargetRegisterClass **getRegClassBarriers() const { - return RCBarriers; - } - - /// getSchedClass - Return the scheduling class for this instruction. The - /// scheduling class is an index into the InstrItineraryData table. This - /// returns zero if there is no known scheduling information for the - /// instruction. - /// - unsigned getSchedClass() const { - return SchedClass; - } - - bool isReturn() const { - return Flags & (1 << TID::Return); - } - - bool isCall() const { - return Flags & (1 << TID::Call); - } - - /// isBarrier - Returns true if the specified instruction stops control flow - /// from executing the instruction immediately following it. Examples include - /// unconditional branches and return instructions. - bool isBarrier() const { - return Flags & (1 << TID::Barrier); - } - - /// isTerminator - Returns true if this instruction part of the terminator for - /// a basic block. Typically this is things like return and branch - /// instructions. - /// - /// Various passes use this to insert code into the bottom of a basic block, - /// but before control flow occurs. - bool isTerminator() const { - return Flags & (1 << TID::Terminator); - } - - /// isBranch - Returns true if this is a conditional, unconditional, or - /// indirect branch. Predicates below can be used to discriminate between - /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to - /// get more information. - bool isBranch() const { - return Flags & (1 << TID::Branch); - } - - /// isIndirectBranch - Return true if this is an indirect branch, such as a - /// branch through a register. - bool isIndirectBranch() const { - return Flags & (1 << TID::IndirectBranch); - } - - /// isConditionalBranch - Return true if this is a branch which may fall - /// through to the next instruction or may transfer control flow to some other - /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more - /// information about this branch. - bool isConditionalBranch() const { - return isBranch() & !isBarrier() & !isIndirectBranch(); - } - - /// isUnconditionalBranch - Return true if this is a branch which always - /// transfers control flow to some other block. The - /// TargetInstrInfo::AnalyzeBranch method can be used to get more information - /// about this branch. - bool isUnconditionalBranch() const { - return isBranch() & isBarrier() & !isIndirectBranch(); - } - - // isPredicable - Return true if this instruction has a predicate operand that - // controls execution. It may be set to 'always', or may be set to other - /// values. There are various methods in TargetInstrInfo that can be used to - /// control and modify the predicate in this instruction. - bool isPredicable() const { - return Flags & (1 << TID::Predicable); - } - - /// isCompare - Return true if this instruction is a comparison. - bool isCompare() const { - return Flags & (1 << TID::Compare); - } - - /// isMoveImmediate - Return true if this instruction is a move immediate - /// (including conditional moves) instruction. - bool isMoveImmediate() const { - return Flags & (1 << TID::MoveImm); - } - - /// isBitcast - Return true if this instruction is a bitcast instruction. - /// - bool isBitcast() const { - return Flags & (1 << TID::Bitcast); - } - - /// isNotDuplicable - Return true if this instruction cannot be safely - /// duplicated. For example, if the instruction has a unique labels attached - /// to it, duplicating it would cause multiple definition errors. - bool isNotDuplicable() const { - return Flags & (1 << TID::NotDuplicable); - } - - /// hasDelaySlot - Returns true if the specified instruction has a delay slot - /// which must be filled by the code generator. - bool hasDelaySlot() const { - return Flags & (1 << TID::DelaySlot); - } - - /// canFoldAsLoad - Return true for instructions that can be folded as - /// memory operands in other instructions. The most common use for this - /// is instructions that are simple loads from memory that don't modify - /// the loaded value in any way, but it can also be used for instructions - /// that can be expressed as constant-pool loads, such as V_SETALLONES - /// on x86, to allow them to be folded when it is beneficial. - /// This should only be set on instructions that return a value in their - /// only virtual register definition. - bool canFoldAsLoad() const { - return Flags & (1 << TID::FoldableAsLoad); - } - - //===--------------------------------------------------------------------===// - // Side Effect Analysis - //===--------------------------------------------------------------------===// - - /// mayLoad - Return true if this instruction could possibly read memory. - /// Instructions with this flag set are not necessarily simple load - /// instructions, they may load a value and modify it, for example. - bool mayLoad() const { - return Flags & (1 << TID::MayLoad); - } - - - /// mayStore - Return true if this instruction could possibly modify memory. - /// Instructions with this flag set are not necessarily simple store - /// instructions, they may store a modified value based on their operands, or - /// may not actually modify anything, for example. - bool mayStore() const { - return Flags & (1 << TID::MayStore); - } - - /// hasUnmodeledSideEffects - Return true if this instruction has side - /// effects that are not modeled by other flags. This does not return true - /// for instructions whose effects are captured by: - /// - /// 1. Their operand list and implicit definition/use list. Register use/def - /// info is explicit for instructions. - /// 2. Memory accesses. Use mayLoad/mayStore. - /// 3. Calling, branching, returning: use isCall/isReturn/isBranch. - /// - /// Examples of side effects would be modifying 'invisible' machine state like - /// a control register, flushing a cache, modifying a register invisible to - /// LLVM, etc. - /// - bool hasUnmodeledSideEffects() const { - return Flags & (1 << TID::UnmodeledSideEffects); - } - - //===--------------------------------------------------------------------===// - // Flags that indicate whether an instruction can be modified by a method. - //===--------------------------------------------------------------------===// - - /// isCommutable - Return true if this may be a 2- or 3-address - /// instruction (of the form "X = op Y, Z, ..."), which produces the same - /// result if Y and Z are exchanged. If this flag is set, then the - /// TargetInstrInfo::commuteInstruction method may be used to hack on the - /// instruction. - /// - /// Note that this flag may be set on instructions that are only commutable - /// sometimes. In these cases, the call to commuteInstruction will fail. - /// Also note that some instructions require non-trivial modification to - /// commute them. - bool isCommutable() const { - return Flags & (1 << TID::Commutable); - } - - /// isConvertibleTo3Addr - Return true if this is a 2-address instruction - /// which can be changed into a 3-address instruction if needed. Doing this - /// transformation can be profitable in the register allocator, because it - /// means that the instruction can use a 2-address form if possible, but - /// degrade into a less efficient form if the source and dest register cannot - /// be assigned to the same register. For example, this allows the x86 - /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which - /// is the same speed as the shift but has bigger code size. - /// - /// If this returns true, then the target must implement the - /// TargetInstrInfo::convertToThreeAddress method for this instruction, which - /// is allowed to fail if the transformation isn't valid for this specific - /// instruction (e.g. shl reg, 4 on x86). - /// - bool isConvertibleTo3Addr() const { - return Flags & (1 << TID::ConvertibleTo3Addr); - } - - /// usesCustomInsertionHook - Return true if this instruction requires - /// custom insertion support when the DAG scheduler is inserting it into a - /// machine basic block. If this is true for the instruction, it basically - /// means that it is a pseudo instruction used at SelectionDAG time that is - /// expanded out into magic code by the target when MachineInstrs are formed. - /// - /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method - /// is used to insert this into the MachineBasicBlock. - bool usesCustomInsertionHook() const { - return Flags & (1 << TID::UsesCustomInserter); - } - - /// isRematerializable - Returns true if this instruction is a candidate for - /// remat. This flag is deprecated, please don't use it anymore. If this - /// flag is set, the isReallyTriviallyReMaterializable() method is called to - /// verify the instruction is really rematable. - bool isRematerializable() const { - return Flags & (1 << TID::Rematerializable); - } - - /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or - /// less) than a move instruction. This is useful during certain types of - /// optimizations (e.g., remat during two-address conversion or machine licm) - /// where we would like to remat or hoist the instruction, but not if it costs - /// more than moving the instruction into the appropriate register. Note, we - /// are not marking copies from and to the same register class with this flag. - bool isAsCheapAsAMove() const { - return Flags & (1 << TID::CheapAsAMove); - } - - /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands - /// have special register allocation requirements that are not captured by the - /// operand register classes. e.g. ARM::STRD's two source registers must be an - /// even / odd pair, ARM::STM registers have to be in ascending order. - /// Post-register allocation passes should not attempt to change allocations - /// for sources of instructions with this flag. - bool hasExtraSrcRegAllocReq() const { - return Flags & (1 << TID::ExtraSrcRegAllocReq); - } - - /// hasExtraDefRegAllocReq - Returns true if this instruction def operands - /// have special register allocation requirements that are not captured by the - /// operand register classes. e.g. ARM::LDRD's two def registers must be an - /// even / odd pair, ARM::LDM registers have to be in ascending order. - /// Post-register allocation passes should not attempt to change allocations - /// for definitions of instructions with this flag. - bool hasExtraDefRegAllocReq() const { - return Flags & (1 << TID::ExtraDefRegAllocReq); - } -}; - -} // end namespace llvm - -#endif diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 418f3fe..f663566 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -14,7 +14,7 @@ #ifndef LLVM_TARGET_TARGETINSTRINFO_H #define LLVM_TARGET_TARGETINSTRINFO_H -#include "llvm/Target/TargetInstrDesc.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/CodeGen/MachineFunction.h" namespace llvm { @@ -32,6 +32,7 @@ class SelectionDAG; class ScheduleDAG; class TargetRegisterClass; class TargetRegisterInfo; +class BranchProbability; template<class T> class SmallVectorImpl; @@ -40,25 +41,22 @@ template<class T> class SmallVectorImpl; /// /// TargetInstrInfo - Interface to description of machine instruction set /// -class TargetInstrInfo { - const TargetInstrDesc *Descriptors; // Raw array to allow static init'n - unsigned NumOpcodes; // Number of entries in the desc array - +class TargetInstrInfo : public MCInstrInfo { TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT public: - TargetInstrInfo(const TargetInstrDesc *desc, unsigned NumOpcodes); + TargetInstrInfo(int CFSetupOpcode = -1, int CFDestroyOpcode = -1) + : CallFrameSetupOpcode(CFSetupOpcode), + CallFrameDestroyOpcode(CFDestroyOpcode) { + } + virtual ~TargetInstrInfo(); - unsigned getNumOpcodes() const { return NumOpcodes; } - - /// get - Return the machine instruction descriptor that corresponds to the - /// specified instruction opcode. - /// - const TargetInstrDesc &get(unsigned Opcode) const { - assert(Opcode < NumOpcodes && "Invalid opcode!"); - return Descriptors[Opcode]; - } + /// getRegClass - Givem a machine instruction descriptor, returns the register + /// class constraint for OpNum, or NULL. + const TargetRegisterClass *getRegClass(const MCInstrDesc &TID, + unsigned OpNum, + const TargetRegisterInfo *TRI) const; /// isTriviallyReMaterializable - Return true if the instruction is trivially /// rematerializable, meaning it has no side effects and requires no operands @@ -93,6 +91,15 @@ private: AliasAnalysis *AA) const; public: + /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the + /// frame setup/destroy instructions if they exist (-1 otherwise). Some + /// targets use pseudo instructions in order to abstract away the difference + /// between operating with a frame pointer and operating without, through the + /// use of these two instructions. + /// + int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; } + int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; } + /// isCoalescableExtInstr - Return true if the instruction is a "coalescable" /// extension instruction. That is, it's like a copy where it's legal for the /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns @@ -315,7 +322,7 @@ public: virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, unsigned ExtraPredCycles, - float Probability, float Confidence) const { + const BranchProbability &Probability) const { return false; } @@ -330,7 +337,7 @@ public: unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB, unsigned NumFCycles, unsigned ExtraFCycles, - float Probability, float Confidence) const { + const BranchProbability &Probability) const { return false; } @@ -342,7 +349,7 @@ public: /// will be properly predicted. virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles, - float Probability, float Confidence) const { + const BranchProbability &Probability) const { return false; } @@ -663,6 +670,9 @@ public: virtual bool hasLowDefLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx) const; + +private: + int CallFrameSetupOpcode, CallFrameDestroyOpcode; }; /// TargetInstrInfoImpl - This is the default implementation of @@ -671,8 +681,9 @@ public: /// libcodegen, not in libtarget. class TargetInstrInfoImpl : public TargetInstrInfo { protected: - TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes) - : TargetInstrInfo(desc, NumOpcodes) {} + TargetInstrInfoImpl(int CallFrameSetupOpcode = -1, + int CallFrameDestroyOpcode = -1) + : TargetInstrInfo(CallFrameSetupOpcode, CallFrameDestroyOpcode) {} public: virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, MachineBasicBlock *NewDest) const; diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h deleted file mode 100644 index 6011402..0000000 --- a/include/llvm/Target/TargetInstrItineraries.h +++ /dev/null @@ -1,253 +0,0 @@ -//===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file describes the structures used for instruction -// itineraries, stages, and operand reads/writes. This is used by -// schedulers to determine instruction stages and latencies. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H -#define LLVM_TARGET_TARGETINSTRITINERARIES_H - -#include <algorithm> - -namespace llvm { - -//===----------------------------------------------------------------------===// -/// Instruction stage - These values represent a non-pipelined step in -/// the execution of an instruction. Cycles represents the number of -/// discrete time slots needed to complete the stage. Units represent -/// the choice of functional units that can be used to complete the -/// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many -/// cycles should elapse from the start of this stage to the start of -/// the next stage in the itinerary. A value of -1 indicates that the -/// next stage should start immediately after the current one. -/// For example: -/// -/// { 1, x, -1 } -/// indicates that the stage occupies FU x for 1 cycle and that -/// the next stage starts immediately after this one. -/// -/// { 2, x|y, 1 } -/// indicates that the stage occupies either FU x or FU y for 2 -/// consecuative cycles and that the next stage starts one cycle -/// after this stage starts. That is, the stage requirements -/// overlap in time. -/// -/// { 1, x, 0 } -/// indicates that the stage occupies FU x for 1 cycle and that -/// the next stage starts in this same cycle. This can be used to -/// indicate that the instruction requires multiple stages at the -/// same time. -/// -/// FU reservation can be of two different kinds: -/// - FUs which instruction actually requires -/// - FUs which instruction just reserves. Reserved unit is not available for -/// execution of other instruction. However, several instructions can reserve -/// the same unit several times. -/// Such two types of units reservation is used to model instruction domain -/// change stalls, FUs using the same resource (e.g. same register file), etc. - -struct InstrStage { - enum ReservationKinds { - Required = 0, - Reserved = 1 - }; - - unsigned Cycles_; ///< Length of stage in machine cycles - unsigned Units_; ///< Choice of functional units - int NextCycles_; ///< Number of machine cycles to next stage - ReservationKinds Kind_; ///< Kind of the FU reservation - - /// getCycles - returns the number of cycles the stage is occupied - unsigned getCycles() const { - return Cycles_; - } - - /// getUnits - returns the choice of FUs - unsigned getUnits() const { - return Units_; - } - - ReservationKinds getReservationKind() const { - return Kind_; - } - - /// getNextCycles - returns the number of cycles from the start of - /// this stage to the start of the next stage in the itinerary - unsigned getNextCycles() const { - return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_; - } -}; - - -//===----------------------------------------------------------------------===// -/// Instruction itinerary - An itinerary represents the scheduling -/// information for an instruction. This includes a set of stages -/// occupies by the instruction, and the pipeline cycle in which -/// operands are read and written. -/// -struct InstrItinerary { - unsigned NumMicroOps; ///< # of micro-ops, 0 means it's variable - unsigned FirstStage; ///< Index of first stage in itinerary - unsigned LastStage; ///< Index of last + 1 stage in itinerary - unsigned FirstOperandCycle; ///< Index of first operand rd/wr - unsigned LastOperandCycle; ///< Index of last + 1 operand rd/wr -}; - - -//===----------------------------------------------------------------------===// -/// Instruction itinerary Data - Itinerary data supplied by a subtarget to be -/// used by a target. -/// -class InstrItineraryData { -public: - const InstrStage *Stages; ///< Array of stages selected - const unsigned *OperandCycles; ///< Array of operand cycles selected - const unsigned *Forwardings; ///< Array of pipeline forwarding pathes - const InstrItinerary *Itineraries; ///< Array of itineraries selected - unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown. - - /// Ctors. - /// - InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0), - Itineraries(0), IssueWidth(0) {} - - InstrItineraryData(const InstrStage *S, const unsigned *OS, - const unsigned *F, const InstrItinerary *I) - : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I), - IssueWidth(0) {} - - /// isEmpty - Returns true if there are no itineraries. - /// - bool isEmpty() const { return Itineraries == 0; } - - /// isEndMarker - Returns true if the index is for the end marker - /// itinerary. - /// - bool isEndMarker(unsigned ItinClassIndx) const { - return ((Itineraries[ItinClassIndx].FirstStage == ~0U) && - (Itineraries[ItinClassIndx].LastStage == ~0U)); - } - - /// beginStage - Return the first stage of the itinerary. - /// - const InstrStage *beginStage(unsigned ItinClassIndx) const { - unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage; - return Stages + StageIdx; - } - - /// endStage - Return the last+1 stage of the itinerary. - /// - const InstrStage *endStage(unsigned ItinClassIndx) const { - unsigned StageIdx = Itineraries[ItinClassIndx].LastStage; - return Stages + StageIdx; - } - - /// getStageLatency - Return the total stage latency of the given - /// class. The latency is the maximum completion time for any stage - /// in the itinerary. - /// - unsigned getStageLatency(unsigned ItinClassIndx) const { - // If the target doesn't provide itinerary information, use a simple - // non-zero default value for all instructions. Some target's provide a - // dummy (Generic) itinerary which should be handled as if it's itinerary is - // empty. We identify this by looking for a reference to stage zero (invalid - // stage). This is different from beginStage == endState != 0, which could - // be used for zero-latency pseudo ops. - if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0) - return 1; - - // Calculate the maximum completion time for any stage. - unsigned Latency = 0, StartCycle = 0; - for (const InstrStage *IS = beginStage(ItinClassIndx), - *E = endStage(ItinClassIndx); IS != E; ++IS) { - Latency = std::max(Latency, StartCycle + IS->getCycles()); - StartCycle += IS->getNextCycles(); - } - - return Latency; - } - - /// getOperandCycle - Return the cycle for the given class and - /// operand. Return -1 if no cycle is specified for the operand. - /// - int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const { - if (isEmpty()) - return -1; - - unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle; - unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle; - if ((FirstIdx + OperandIdx) >= LastIdx) - return -1; - - return (int)OperandCycles[FirstIdx + OperandIdx]; - } - - /// hasPipelineForwarding - Return true if there is a pipeline forwarding - /// between instructions of itinerary classes DefClass and UseClasses so that - /// value produced by an instruction of itinerary class DefClass, operand - /// index DefIdx can be bypassed when it's read by an instruction of - /// itinerary class UseClass, operand index UseIdx. - bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx, - unsigned UseClass, unsigned UseIdx) const { - unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle; - unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle; - if ((FirstDefIdx + DefIdx) >= LastDefIdx) - return false; - if (Forwardings[FirstDefIdx + DefIdx] == 0) - return false; - - unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle; - unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle; - if ((FirstUseIdx + UseIdx) >= LastUseIdx) - return false; - - return Forwardings[FirstDefIdx + DefIdx] == - Forwardings[FirstUseIdx + UseIdx]; - } - - /// getOperandLatency - Compute and return the use operand latency of a given - /// itinerary class and operand index if the value is produced by an - /// instruction of the specified itinerary class and def operand index. - int getOperandLatency(unsigned DefClass, unsigned DefIdx, - unsigned UseClass, unsigned UseIdx) const { - if (isEmpty()) - return -1; - - int DefCycle = getOperandCycle(DefClass, DefIdx); - if (DefCycle == -1) - return -1; - - int UseCycle = getOperandCycle(UseClass, UseIdx); - if (UseCycle == -1) - return -1; - - UseCycle = DefCycle - UseCycle + 1; - if (UseCycle > 0 && - hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx)) - // FIXME: This assumes one cycle benefit for every pipeline forwarding. - --UseCycle; - return UseCycle; - } - - /// isMicroCoded - Return true if the instructions in the given class decode - /// to more than one micro-ops. - bool isMicroCoded(unsigned ItinClassIndx) const { - if (isEmpty()) - return false; - return Itineraries[ItinClassIndx].NumMicroOps != 1; - } -}; - - -} // End llvm namespace - -#endif diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 3e36fb7..533c3ac 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1421,13 +1421,6 @@ public: /// is for this target. virtual ConstraintType getConstraintType(const std::string &Constraint) const; - /// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"), - /// return a list of registers that can be used to satisfy the constraint. - /// This should only be used for C_RegisterClass constraints. - virtual std::vector<unsigned> - getRegClassForInlineAsmConstraint(const std::string &Constraint, - EVT VT) const; - /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g. /// {edx}), return the register number and the register class for the /// register. @@ -1547,6 +1540,8 @@ public: //===--------------------------------------------------------------------===// // Div utility functions // + SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl, + SelectionDAG &DAG) const; SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, std::vector<SDNode*>* Created) const; SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, @@ -1836,9 +1831,8 @@ private: // Build a new vector type and check if it is legal. MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); - // Found a legal promoted vector type. - if (ValueTypeActions.getTypeAction(NVT) == TypeLegal) + if (NVT != MVT() && ValueTypeActions.getTypeAction(NVT) == TypeLegal) return LegalizeKind(TypePromoteInteger, EVT::getVectorVT(Context, EltVT, NumElts)); } @@ -1853,6 +1847,7 @@ private: // If there is no simple vector type with this many elements then there // cannot be a larger legal vector type. Note that this assumes that // there are no skipped intermediate vector types in the simple types. + if (!EltVT.isSimple()) break; MVT LargerVector = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); if (LargerVector == MVT()) break; diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 3991035..2e1d6b9 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -68,6 +68,11 @@ protected: /// LSDASection - If exception handling is supported by the target, this is /// the section the Language Specific Data Area information is emitted to. const MCSection *LSDASection; + + /// CompactUnwindSection - If exception handling is supported by the target + /// and the target can support a compact representation of the CIE and FDE, + /// this is the section to emit them into. + const MCSection *CompactUnwindSection; // Dwarf sections for debug info. If a target supports debug info, these must // be set. @@ -102,8 +107,8 @@ protected: /// private linkage, aka an L or .L label) or false if it should be a normal /// non-.globl label. This defaults to true. bool IsFunctionEHFrameSymbolPrivate; + public: - MCContext &getContext() const { return *Ctx; } virtual ~TargetLoweringObjectFile(); @@ -121,7 +126,6 @@ public: bool getSupportsWeakOmittedEHFrame() const { return SupportsWeakOmittedEHFrame; } - bool getCommDirectiveSupportsAlignment() const { return CommDirectiveSupportsAlignment; } @@ -132,6 +136,7 @@ public: const MCSection *getStaticCtorSection() const { return StaticCtorSection; } const MCSection *getStaticDtorSection() const { return StaticDtorSection; } const MCSection *getLSDASection() const { return LSDASection; } + const MCSection *getCompactUnwindSection() const{return CompactUnwindSection;} virtual const MCSection *getEHFrameSection() const = 0; virtual void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 78f770c..ac41a58 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -14,29 +14,30 @@ #ifndef LLVM_TARGET_TARGETMACHINE_H #define LLVM_TARGET_TARGETMACHINE_H -#include "llvm/Target/TargetInstrItineraries.h" +#include "llvm/ADT/StringRef.h" #include <cassert> #include <string> namespace llvm { -class Target; +class InstrItineraryData; +class JITCodeEmitter; class MCAsmInfo; +class MCContext; +class Pass; +class PassManager; +class PassManagerBase; +class Target; class TargetData; -class TargetSubtarget; +class TargetELFWriterInfo; +class TargetFrameLowering; class TargetInstrInfo; class TargetIntrinsicInfo; class TargetJITInfo; class TargetLowering; -class TargetSelectionDAGInfo; -class TargetFrameLowering; -class JITCodeEmitter; -class MCContext; class TargetRegisterInfo; -class PassManagerBase; -class PassManager; -class Pass; -class TargetELFWriterInfo; +class TargetSelectionDAGInfo; +class TargetSubtargetInfo; class formatted_raw_ostream; class raw_ostream; @@ -91,15 +92,22 @@ class TargetMachine { TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT void operator=(const TargetMachine &); // DO NOT IMPLEMENT protected: // Can only create subclasses. - TargetMachine(const Target &); + TargetMachine(const Target &T, StringRef TargetTriple, + StringRef CPU, StringRef FS); /// getSubtargetImpl - virtual method implemented by subclasses that returns - /// a reference to that target's TargetSubtarget-derived member variable. - virtual const TargetSubtarget *getSubtargetImpl() const { return 0; } + /// a reference to that target's TargetSubtargetInfo-derived member variable. + virtual const TargetSubtargetInfo *getSubtargetImpl() const { return 0; } /// TheTarget - The Target that this machine was created for. const Target &TheTarget; + /// TargetTriple, TargetCPU, TargetFS - Triple string, CPU name, and target + /// feature strings the TargetMachine instance is created with. + std::string TargetTriple; + std::string TargetCPU; + std::string TargetFS; + /// AsmInfo - Contains target specific asm information. /// const MCAsmInfo *AsmInfo; @@ -115,6 +123,10 @@ public: const Target &getTarget() const { return TheTarget; } + const StringRef getTargetTriple() const { return TargetTriple; } + const StringRef getTargetCPU() const { return TargetCPU; } + const StringRef getTargetFeatureString() const { return TargetFS; } + // Interfaces to the major aspects of target machine information: // -- Instruction opcode and operand information // -- Pipelines and scheduling information @@ -132,7 +144,7 @@ public: const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; } /// getSubtarget - This method returns a pointer to the specified type of - /// TargetSubtarget. In debug builds, it verifies that the object being + /// TargetSubtargetInfo. In debug builds, it verifies that the object being /// returned is of the correct type. template<typename STC> const STC &getSubtarget() const { return *static_cast<const STC*>(getSubtargetImpl()); @@ -295,10 +307,9 @@ public: /// implemented with the LLVM target-independent code generator. /// class LLVMTargetMachine : public TargetMachine { - std::string TargetTriple; - protected: // Can only create subclasses. - LLVMTargetMachine(const Target &T, const std::string &TargetTriple); + LLVMTargetMachine(const Target &T, StringRef TargetTriple, + StringRef CPU, StringRef FS); private: /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for @@ -311,9 +322,6 @@ private: virtual void setCodeModelForStatic(); public: - - const std::string &getTargetTriple() const { return TargetTriple; } - /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code /// generation. If OptLevel is None, the code generator should emit code as diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index 01fba66..37f7b2f 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -71,6 +71,10 @@ namespace TargetOpcode { /// REG_SEQUENCE - This variadic instruction is used to form a register that /// represent a consecutive sequence of sub-registers. It's used as register /// coalescing / allocation aid and must be eliminated before code emission. + // In SDNode form, the first operand encodes the register class created by + // the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index + // pair. Once it has been lowered to a MachineInstr, the regclass operand + // is no longer present. /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5 /// After register coalescing references of v1024 should be replace with /// v1027:3, v1025 with v1027:4, etc. diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index beed039..55d50d9 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -133,8 +133,8 @@ namespace llvm { /// as their parent function, etc.), using an alternate ABI if necessary. extern bool GuaranteedTailCallOpt; - /// StackAlignment - Override default stack alignment for target. - extern unsigned StackAlignment; + /// StackAlignmentOverride - Override default stack alignment for target. + extern unsigned StackAlignmentOverride; /// RealignStack - This flag indicates whether the stack should be /// automatically realigned, if needed. diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index f6a8414..8d827f1 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -16,8 +16,10 @@ #ifndef LLVM_TARGET_TARGETREGISTERINFO_H #define LLVM_TARGET_TARGETREGISTERINFO_H +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include <cassert> #include <functional> @@ -26,30 +28,10 @@ namespace llvm { class BitVector; class MachineFunction; -class MachineMove; class RegScavenger; template<class T> class SmallVectorImpl; class raw_ostream; -/// TargetRegisterDesc - This record contains all of the information known about -/// a particular register. The Overlaps field contains a pointer to a zero -/// terminated array of registers that this register aliases, starting with -/// itself. This is needed for architectures like X86 which have AL alias AX -/// alias EAX. The SubRegs field is a zero terminated array of registers that -/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of -/// AX. The SuperRegs field is a zero terminated array of registers that are -/// super-registers of the specific register, e.g. RAX, EAX, are super-registers -/// of AX. -/// -struct TargetRegisterDesc { - const char *Name; // Printable name for the reg (for debugging) - const unsigned *Overlaps; // Overlapping registers, described above - const unsigned *SubRegs; // Sub-register set, described above - const unsigned *SuperRegs; // Super-register set, described above - unsigned CostPerUse; // Extra cost of instructions using register. - bool inAllocatableClass; // Register belongs to an allocatable regclass. -}; - class TargetRegisterClass { public: typedef const unsigned* iterator; @@ -236,27 +218,23 @@ public: return SuperClasses[0] != 0; } - /// allocation_order_begin/end - These methods define a range of registers - /// which specify the registers in this class that are valid to register - /// allocate, and the preferred order to allocate them in. For example, - /// callee saved registers should be at the end of the list, because it is - /// cheaper to allocate caller saved registers. - /// - /// These methods take a MachineFunction argument, which can be used to tune - /// the allocatable registers based on the characteristics of the function, - /// subtarget, or other criteria. + /// getRawAllocationOrder - Returns the preferred order for allocating + /// registers from this register class in MF. The raw order comes directly + /// from the .td file and may include reserved registers that are not + /// allocatable. Register allocators should also make sure to allocate + /// callee-saved registers only after all the volatiles are used. The + /// RegisterClassInfo class provides filtered allocation orders with + /// callee-saved registers moved to the end. /// - /// Register allocators should account for the fact that an allocation - /// order iterator may return a reserved register and always check - /// if the register is allocatable (getAllocatableSet()) before using it. + /// The MachineFunction argument can be used to tune the allocatable + /// registers based on the characteristics of the function, subtarget, or + /// other criteria. /// - /// By default, these methods return all registers in the class. + /// By default, this method returns all registers in the class. /// - virtual iterator allocation_order_begin(const MachineFunction &MF) const { - return begin(); - } - virtual iterator allocation_order_end(const MachineFunction &MF) const { - return end(); + virtual + ArrayRef<unsigned> getRawAllocationOrder(const MachineFunction &MF) const { + return ArrayRef<unsigned>(begin(), getNumRegs()); } /// getSize - Return the size of the register in bytes, which is also the size @@ -277,6 +255,12 @@ public: bool isAllocatable() const { return Allocatable; } }; +/// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about +/// registers. These are used by codegen, not by MC. +struct TargetRegisterInfoDesc { + unsigned CostPerUse; // Extra cost of instructions using register. + bool inAllocatableClass; // Register belongs to an allocatable regclass. +}; /// TargetRegisterInfo base class - We assume that the target defines a static /// array of TargetRegisterDesc objects that represent all of the machine @@ -284,34 +268,19 @@ public: /// to this array so that we can turn register number into a register /// descriptor. /// -class TargetRegisterInfo { -protected: - const unsigned* SubregHash; - const unsigned SubregHashSize; - const unsigned* AliasesHash; - const unsigned AliasesHashSize; +class TargetRegisterInfo : public MCRegisterInfo { public: typedef const TargetRegisterClass * const * regclass_iterator; private: - const TargetRegisterDesc *Desc; // Pointer to the descriptor array + const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen const char *const *SubRegIndexNames; // Names of subreg indexes. - unsigned NumRegs; // Number of entries in the array - regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses - int CallFrameSetupOpcode, CallFrameDestroyOpcode; - protected: - TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR, + TargetRegisterInfo(const TargetRegisterInfoDesc *ID, regclass_iterator RegClassBegin, regclass_iterator RegClassEnd, - const char *const *subregindexnames, - int CallFrameSetupOpcode = -1, - int CallFrameDestroyOpcode = -1, - const unsigned* subregs = 0, - const unsigned subregsize = 0, - const unsigned* aliases = 0, - const unsigned aliasessize = 0); + const char *const *subregindexnames); virtual ~TargetRegisterInfo(); public: @@ -391,71 +360,16 @@ public: BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC = NULL) const; - const TargetRegisterDesc &operator[](unsigned RegNo) const { - assert(RegNo < NumRegs && - "Attempting to access record for invalid register number!"); - return Desc[RegNo]; - } - - /// Provide a get method, equivalent to [], but more useful if we have a - /// pointer to this object. - /// - const TargetRegisterDesc &get(unsigned RegNo) const { - return operator[](RegNo); - } - - /// getAliasSet - Return the set of registers aliased by the specified - /// register, or a null list of there are none. The list returned is zero - /// terminated. - /// - const unsigned *getAliasSet(unsigned RegNo) const { - // The Overlaps set always begins with Reg itself. - return get(RegNo).Overlaps + 1; - } - - /// getOverlaps - Return a list of registers that overlap Reg, including - /// itself. This is the same as the alias set except Reg is included in the - /// list. - /// These are exactly the registers in { x | regsOverlap(x, Reg) }. - /// - const unsigned *getOverlaps(unsigned RegNo) const { - return get(RegNo).Overlaps; - } - - /// getSubRegisters - Return the list of registers that are sub-registers of - /// the specified register, or a null list of there are none. The list - /// returned is zero terminated and sorted according to super-sub register - /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH. - /// - const unsigned *getSubRegisters(unsigned RegNo) const { - return get(RegNo).SubRegs; - } - - /// getSuperRegisters - Return the list of registers that are super-registers - /// of the specified register, or a null list of there are none. The list - /// returned is zero terminated and sorted according to super-sub register - /// relations. e.g. X86::AL's super-register list is RAX, EAX, AX. - /// - const unsigned *getSuperRegisters(unsigned RegNo) const { - return get(RegNo).SuperRegs; - } - - /// getName - Return the human-readable symbolic target-specific name for the - /// specified physical register. - const char *getName(unsigned RegNo) const { - return get(RegNo).Name; - } - /// getCostPerUse - Return the additional cost of using this register instead /// of other registers in its class. unsigned getCostPerUse(unsigned RegNo) const { - return get(RegNo).CostPerUse; + return InfoDesc[RegNo].CostPerUse; } - /// getNumRegs - Return the number of registers this target has (useful for - /// sizing arrays holding per register information) - unsigned getNumRegs() const { - return NumRegs; + /// isInAllocatableClass - Return true if the register is in the allocation + /// of any register class. + bool isInAllocatableClass(unsigned RegNo) const { + return InfoDesc[RegNo].inAllocatableClass; } /// getSubRegIndexName - Return the human-readable symbolic target-specific @@ -468,49 +382,28 @@ public: /// regsOverlap - Returns true if the two registers are equal or alias each /// other. The registers may be virtual register. bool regsOverlap(unsigned regA, unsigned regB) const { - if (regA == regB) - return true; - + if (regA == regB) return true; if (isVirtualRegister(regA) || isVirtualRegister(regB)) return false; - - // regA and regB are distinct physical registers. Do they alias? - size_t index = (regA + regB * 37) & (AliasesHashSize-1); - unsigned ProbeAmt = 0; - while (AliasesHash[index*2] != 0 && - AliasesHash[index*2+1] != 0) { - if (AliasesHash[index*2] == regA && AliasesHash[index*2+1] == regB) - return true; - - index = (index + ProbeAmt) & (AliasesHashSize-1); - ProbeAmt += 2; + for (const unsigned *regList = getOverlaps(regA)+1; *regList; ++regList) { + if (*regList == regB) return true; } - return false; } /// isSubRegister - Returns true if regB is a sub-register of regA. /// bool isSubRegister(unsigned regA, unsigned regB) const { - // SubregHash is a simple quadratically probed hash table. - size_t index = (regA + regB * 37) & (SubregHashSize-1); - unsigned ProbeAmt = 2; - while (SubregHash[index*2] != 0 && - SubregHash[index*2+1] != 0) { - if (SubregHash[index*2] == regA && SubregHash[index*2+1] == regB) - return true; - - index = (index + ProbeAmt) & (SubregHashSize-1); - ProbeAmt += 2; - } - - return false; + return isSuperRegister(regB, regA); } /// isSuperRegister - Returns true if regB is a super-register of regA. /// bool isSuperRegister(unsigned regA, unsigned regB) const { - return isSubRegister(regB, regA); + for (const unsigned *regList = getSuperRegisters(regA); *regList;++regList){ + if (*regList == regB) return true; + } + return false; } /// getCalleeSavedRegs - Return a null-terminated list of all of the @@ -599,7 +492,7 @@ public: } /// getRegClass - Returns the register class associated with the enumeration - /// value. See class TargetOperandInfo. + /// value. See class MCOperandInfo. const TargetRegisterClass *getRegClass(unsigned i) const { assert(i < getNumRegClasses() && "Register Class ID out of range"); return RegClassBegin[i]; @@ -642,14 +535,17 @@ public: return 0; } - /// getAllocationOrder - Returns the register allocation order for a specified - /// register class in the form of a pair of TargetRegisterClass iterators. - virtual std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator> - getAllocationOrder(const TargetRegisterClass *RC, - unsigned HintType, unsigned HintReg, - const MachineFunction &MF) const { - return std::make_pair(RC->allocation_order_begin(MF), - RC->allocation_order_end(MF)); + /// getRawAllocationOrder - Returns the register allocation order for a + /// specified register class with a target-dependent hint. The returned list + /// may contain reserved registers that cannot be allocated. + /// + /// Register allocators need only call this function to resolve + /// target-dependent hints, but it should work without hinting as well. + virtual ArrayRef<unsigned> + getRawAllocationOrder(const TargetRegisterClass *RC, + unsigned HintType, unsigned HintReg, + const MachineFunction &MF) const { + return RC->getRawAllocationOrder(MF); } /// ResolveRegAllocHint - Resolves the specified register allocation hint @@ -762,15 +658,6 @@ public: return false; // Must return a value in order to compile with VS 2005 } - /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the - /// frame setup/destroy instructions if they exist (-1 otherwise). Some - /// targets use pseudo instructions in order to abstract away the difference - /// between operating with a frame pointer and operating without, through the - /// use of these two instructions. - /// - int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; } - int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; } - /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog /// code insertion to eliminate call frame setup and destroy pseudo /// instructions (but only if the Target is using them). It is responsible @@ -782,9 +669,6 @@ public: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { - assert(getCallFrameSetupOpcode()== -1 && getCallFrameDestroyOpcode()== -1 && - "eliminateCallFramePseudoInstr must be implemented if using" - " call frame setup/destroy pseudo instructions!"); assert(0 && "Call Frame Pseudo Instructions do not exist on this target!"); } @@ -836,6 +720,12 @@ public: virtual int getSEHRegNum(unsigned i) const { return i; } + + /// getCompactUnwindRegNum - This function maps the register to the number for + /// compact unwind encoding. Return -1 if the register isn't valid. + virtual int getCompactUnwindRegNum(unsigned, bool) const { + return -1; + } }; diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index a464822..7e0ce19 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -33,7 +33,10 @@ namespace llvm { class MCContext; class MCDisassembler; class MCInstPrinter; + class MCInstrInfo; + class MCRegisterInfo; class MCStreamer; + class MCSubtargetInfo; class TargetAsmBackend; class TargetAsmLexer; class TargetAsmParser; @@ -63,10 +66,16 @@ namespace llvm { typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); - typedef MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T, - StringRef TT); + typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const Target &T, + StringRef TT); + typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void); + typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(void); + typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT, + StringRef CPU, + StringRef Features); typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T, const std::string &TT, + const std::string &CPU, const std::string &Features); typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM, MCStreamer &Streamer); @@ -74,15 +83,14 @@ namespace llvm { const std::string &TT); typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T, const MCAsmInfo &MAI); - typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P, - TargetMachine &TM); + typedef TargetAsmParser *(*AsmParserCtorTy)(MCSubtargetInfo &STI, + MCAsmParser &P); typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, - TargetMachine &TM, unsigned SyntaxVariant, const MCAsmInfo &MAI); - typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T, - TargetMachine &TM, + typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const MCInstrInfo &II, + const MCSubtargetInfo &STI, MCContext &Ctx); typedef MCStreamer *(*ObjectStreamerCtorTy)(const Target &T, const std::string &TT, @@ -120,7 +128,21 @@ namespace llvm { /// HasJIT - Whether this target supports the JIT. bool HasJIT; - AsmInfoCtorFnTy AsmInfoCtorFn; + /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if + /// registered. + MCAsmInfoCtorFnTy MCAsmInfoCtorFn; + + /// 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. @@ -218,17 +240,49 @@ namespace llvm { /// @name Feature Constructors /// @{ - /// createAsmInfo - Create a MCAsmInfo implementation for the specified + /// 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 *createAsmInfo(StringRef Triple) const { - if (!AsmInfoCtorFn) + MCAsmInfo *createMCAsmInfo(StringRef Triple) const { + if (!MCAsmInfoCtorFn) + return 0; + return MCAsmInfoCtorFn(*this, Triple); + } + + /// createMCInstrInfo - Create a MCInstrInfo implementation. + /// + MCInstrInfo *createMCInstrInfo() const { + if (!MCInstrInfoCtorFn) + return 0; + return MCInstrInfoCtorFn(); + } + + /// createMCRegInfo - Create a MCRegisterInfo implementation. + /// + MCRegisterInfo *createMCRegInfo() const { + if (!MCRegInfoCtorFn) + return 0; + return MCRegInfoCtorFn(); + } + + /// 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 AsmInfoCtorFn(*this, Triple); + return MCSubtargetInfoCtorFn(Triple, CPU, Features); } /// createTargetMachine - Create a target specific machine implementation @@ -239,10 +293,11 @@ namespace llvm { /// either the target triple from the module, or the target triple of the /// host if that does not exist. TargetMachine *createTargetMachine(const std::string &Triple, + const std::string &CPU, const std::string &Features) const { if (!TargetMachineCtorFn) return 0; - return TargetMachineCtorFn(*this, Triple, Features); + return TargetMachineCtorFn(*this, Triple, CPU, Features); } /// createAsmBackend - Create a target specific assembly parser. @@ -267,11 +322,11 @@ namespace llvm { /// /// \arg Parser - The target independent parser implementation to use for /// parsing and lexing. - TargetAsmParser *createAsmParser(MCAsmParser &Parser, - TargetMachine &TM) const { + TargetAsmParser *createAsmParser(MCSubtargetInfo &STI, + MCAsmParser &Parser) const { if (!AsmParserCtorFn) return 0; - return AsmParserCtorFn(*this, Parser, TM); + return AsmParserCtorFn(STI, Parser); } /// createAsmPrinter - Create a target specific assembly printer pass. This @@ -288,20 +343,21 @@ namespace llvm { return MCDisassemblerCtorFn(*this); } - MCInstPrinter *createMCInstPrinter(TargetMachine &TM, - unsigned SyntaxVariant, + MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant, const MCAsmInfo &MAI) const { if (!MCInstPrinterCtorFn) return 0; - return MCInstPrinterCtorFn(*this, TM, SyntaxVariant, MAI); + return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI); } /// createCodeEmitter - Create a target specific code emitter. - MCCodeEmitter *createCodeEmitter(TargetMachine &TM, MCContext &Ctx) const { + MCCodeEmitter *createCodeEmitter(const MCInstrInfo &II, + const MCSubtargetInfo &STI, + MCContext &Ctx) const { if (!CodeEmitterCtorFn) return 0; - return CodeEmitterCtorFn(*this, TM, Ctx); + return CodeEmitterCtorFn(II, STI, Ctx); } /// createObjectStreamer - Create a target specific MCStreamer. @@ -429,7 +485,7 @@ namespace llvm { Target::TripleMatchQualityFnTy TQualityFn, bool HasJIT = false); - /// RegisterAsmInfo - Register a MCAsmInfo implementation for the + /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the /// given target. /// /// Clients are responsible for ensuring that registration doesn't occur @@ -438,10 +494,56 @@ namespace llvm { /// /// @param T - The target being registered. /// @param Fn - A function to construct a MCAsmInfo for the target. - static void RegisterAsmInfo(Target &T, Target::AsmInfoCtorFnTy Fn) { + static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCAsmInfoCtorFn) + T.MCAsmInfoCtorFn = 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.AsmInfoCtorFn) - T.AsmInfoCtorFn = Fn; + if (!T.MCSubtargetInfoCtorFn) + T.MCSubtargetInfoCtorFn = Fn; } /// RegisterTargetMachine - Register a TargetMachine implementation for the @@ -620,18 +722,18 @@ namespace llvm { } }; - /// RegisterAsmInfo - Helper template for registering a target assembly info + /// 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; - /// RegisterAsmInfo<FooMCAsmInfo> X(TheFooTarget); + /// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget); /// } template<class MCAsmInfoImpl> - struct RegisterAsmInfo { - RegisterAsmInfo(Target &T) { - TargetRegistry::RegisterAsmInfo(T, &Allocator); + struct RegisterMCAsmInfo { + RegisterMCAsmInfo(Target &T) { + TargetRegistry::RegisterMCAsmInfo(T, &Allocator); } private: static MCAsmInfo *Allocator(const Target &T, StringRef TT) { @@ -640,20 +742,119 @@ namespace llvm { }; - /// RegisterAsmInfoFn - Helper template for registering a target assembly info + /// 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; - /// RegisterAsmInfoFn X(TheFooTarget, TheFunction); + /// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction); /// } - struct RegisterAsmInfoFn { - RegisterAsmInfoFn(Target &T, Target::AsmInfoCtorFnTy Fn) { - TargetRegistry::RegisterAsmInfo(T, Fn); + struct RegisterMCAsmInfoFn { + RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCAsmInfo(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() { + 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 @@ -671,8 +872,9 @@ namespace llvm { private: static TargetMachine *Allocator(const Target &T, const std::string &TT, + const std::string &CPU, const std::string &FS) { - return new TargetMachineImpl(T, TT, FS); + return new TargetMachineImpl(T, TT, CPU, FS); } }; @@ -731,9 +933,8 @@ namespace llvm { } private: - static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P, - TargetMachine &TM) { - return new AsmParserImpl(T, P, TM); + static TargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) { + return new AsmParserImpl(STI, P); } }; @@ -772,9 +973,10 @@ namespace llvm { } private: - static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM, + static MCCodeEmitter *Allocator(const MCInstrInfo &II, + const MCSubtargetInfo &STI, MCContext &Ctx) { - return new CodeEmitterImpl(T, TM, Ctx); + return new CodeEmitterImpl(); } }; diff --git a/include/llvm/Target/TargetSelect.h b/include/llvm/Target/TargetSelect.h index c5ab90b..272ee09 100644 --- a/include/llvm/Target/TargetSelect.h +++ b/include/llvm/Target/TargetSelect.h @@ -26,6 +26,18 @@ extern "C" { #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##MCInstrInfo(); +#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" @@ -35,7 +47,8 @@ extern "C" { #include "llvm/Config/AsmParsers.def" // Declare all of the available disassembler initialization functions. -#define LLVM_DISASSEMBLER(TargetName) void LLVMInitialize##TargetName##Disassembler(); +#define LLVM_DISASSEMBLER(TargetName) \ + void LLVMInitialize##TargetName##Disassembler(); #include "llvm/Config/Disassemblers.def" } @@ -63,6 +76,38 @@ namespace llvm { #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" + } + + /// 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" + } + + /// 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. @@ -103,6 +148,7 @@ namespace llvm { #ifdef LLVM_NATIVE_TARGET LLVM_NATIVE_TARGETINFO(); LLVM_NATIVE_TARGET(); + LLVM_NATIVE_MCASMINFO(); return false; #else return true; diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 672117f..9d1ef2c 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -197,8 +197,8 @@ def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3> ]>; -def SDTPrefetch : SDTypeProfile<0, 3, [ // prefetch - SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisInt<1> +def SDTPrefetch : SDTypeProfile<0, 4, [ // prefetch + SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisInt<1> ]>; def SDTMemBarrier : SDTypeProfile<0, 5, [ // memory barier @@ -353,6 +353,7 @@ def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; +def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp>; def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>; def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; diff --git a/include/llvm/Target/TargetSubtarget.h b/include/llvm/Target/TargetSubtargetInfo.h index 22b09ba..9556c7a 100644 --- a/include/llvm/Target/TargetSubtarget.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -1,4 +1,4 @@ -//==-- llvm/Target/TargetSubtarget.h - Target Information --------*- C++ -*-==// +//==-- llvm/Target/TargetSubtargetInfo.h - Target Information ----*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -11,9 +11,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETSUBTARGET_H -#define LLVM_TARGET_TARGETSUBTARGET_H +#ifndef LLVM_TARGET_TARGETSUBTARGETINFO_H +#define LLVM_TARGET_TARGETSUBTARGETINFO_H +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Target/TargetMachine.h" namespace llvm { @@ -25,22 +26,22 @@ template <typename T> class SmallVectorImpl; //===----------------------------------------------------------------------===// /// -/// TargetSubtarget - Generic base class for all target subtargets. All +/// TargetSubtargetInfo - Generic base class for all target subtargets. All /// Target-specific options that control code generation and printing should -/// be exposed through a TargetSubtarget-derived class. +/// be exposed through a TargetSubtargetInfo-derived class. /// -class TargetSubtarget { - TargetSubtarget(const TargetSubtarget&); // DO NOT IMPLEMENT - void operator=(const TargetSubtarget&); // DO NOT IMPLEMENT +class TargetSubtargetInfo : public MCSubtargetInfo { + TargetSubtargetInfo(const TargetSubtargetInfo&); // DO NOT IMPLEMENT + void operator=(const TargetSubtargetInfo&); // DO NOT IMPLEMENT protected: // Can only create subclasses... - TargetSubtarget(); + TargetSubtargetInfo(); public: // AntiDepBreakMode - Type of anti-dependence breaking that should // be performed before post-RA scheduling. typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode; typedef SmallVectorImpl<TargetRegisterClass*> RegClassVector; - virtual ~TargetSubtarget(); + virtual ~TargetSubtargetInfo(); /// getSpecialAddressLatency - For targets where it is beneficial to /// backschedule instructions that compute addresses, return a value |