diff options
Diffstat (limited to 'include/llvm/Target')
-rw-r--r-- | include/llvm/Target/Target.td | 28 | ||||
-rw-r--r-- | include/llvm/Target/TargetAsmParser.h | 4 | ||||
-rw-r--r-- | include/llvm/Target/TargetCallingConv.h | 142 | ||||
-rw-r--r-- | include/llvm/Target/TargetInstrDesc.h | 6 | ||||
-rw-r--r-- | include/llvm/Target/TargetInstrInfo.h | 141 | ||||
-rw-r--r-- | include/llvm/Target/TargetInstrItineraries.h | 3 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 282 | ||||
-rw-r--r-- | include/llvm/Target/TargetOpcodes.h | 48 | ||||
-rw-r--r-- | include/llvm/Target/TargetRegisterInfo.h | 60 |
9 files changed, 472 insertions, 242 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index ca551e5..9a89dc9 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -203,7 +203,6 @@ class Instruction { bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand? bit mayLoad = 0; // Is it possible for this inst to read memory? bit mayStore = 0; // Is it possible for this inst to write memory? - bit isTwoAddress = 0; // Is this a two address instruction? bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote? bit isCommutable = 0; // Is this 3 operand instruction commutable? bit isTerminator = 0; // Is this part of the terminator for a basic block? @@ -244,7 +243,7 @@ class Instruction { string DisableEncoding = ""; /// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc. - bits<32> TSFlags = 0; + bits<64> TSFlags = 0; } /// Predicates - These are extra conditionals which are turned into instruction @@ -397,24 +396,23 @@ class InstrInfo { } // Standard Pseudo Instructions. -let isCodeGenOnly = 1 in { +// This list must match TargetOpcodes.h and CodeGenTarget.cpp. +// Only these instructions are allowed in the TargetOpcode namespace. +let isCodeGenOnly = 1, Namespace = "TargetOpcode" in { def PHI : Instruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); let AsmString = "PHINODE"; - let Namespace = "TargetOpcode"; } def INLINEASM : Instruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); let AsmString = ""; - let Namespace = "TargetOpcode"; } def DBG_LABEL : Instruction { let OutOperandList = (outs); let InOperandList = (ins i32imm:$id); let AsmString = ""; - let Namespace = "TargetOpcode"; let hasCtrlDep = 1; let isNotDuplicable = 1; } @@ -422,7 +420,6 @@ def EH_LABEL : Instruction { let OutOperandList = (outs); let InOperandList = (ins i32imm:$id); let AsmString = ""; - let Namespace = "TargetOpcode"; let hasCtrlDep = 1; let isNotDuplicable = 1; } @@ -430,7 +427,6 @@ def GC_LABEL : Instruction { let OutOperandList = (outs); let InOperandList = (ins i32imm:$id); let AsmString = ""; - let Namespace = "TargetOpcode"; let hasCtrlDep = 1; let isNotDuplicable = 1; } @@ -438,21 +434,18 @@ def KILL : Instruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); let AsmString = ""; - let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; } def EXTRACT_SUBREG : Instruction { let OutOperandList = (outs unknown:$dst); let InOperandList = (ins unknown:$supersrc, i32imm:$subidx); let AsmString = ""; - let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; } def INSERT_SUBREG : Instruction { let OutOperandList = (outs unknown:$dst); let InOperandList = (ins unknown:$supersrc, unknown:$subsrc, i32imm:$subidx); let AsmString = ""; - let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; let Constraints = "$supersrc = $dst"; } @@ -460,7 +453,6 @@ def IMPLICIT_DEF : Instruction { let OutOperandList = (outs unknown:$dst); let InOperandList = (ins); let AsmString = ""; - let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; let isReMaterializable = 1; let isAsCheapAsAMove = 1; @@ -469,14 +461,12 @@ def SUBREG_TO_REG : Instruction { let OutOperandList = (outs unknown:$dst); let InOperandList = (ins unknown:$implsrc, unknown:$subsrc, i32imm:$subidx); let AsmString = ""; - let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; } def COPY_TO_REGCLASS : Instruction { let OutOperandList = (outs unknown:$dst); let InOperandList = (ins unknown:$src, i32imm:$regclass); let AsmString = ""; - let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; let isAsCheapAsAMove = 1; } @@ -484,15 +474,19 @@ def DBG_VALUE : Instruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); let AsmString = "DBG_VALUE"; - let Namespace = "TargetOpcode"; let isAsCheapAsAMove = 1; } - def REG_SEQUENCE : Instruction { let OutOperandList = (outs unknown:$dst); let InOperandList = (ins variable_ops); let AsmString = ""; - let Namespace = "TargetOpcode"; + let neverHasSideEffects = 1; + let isAsCheapAsAMove = 1; +} +def COPY : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src); + let AsmString = ""; let neverHasSideEffects = 1; let isAsCheapAsAMove = 1; } diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h index 85315c1..dc2b236 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/Target/TargetAsmParser.h @@ -10,6 +10,8 @@ #ifndef LLVM_TARGET_TARGETPARSER_H #define LLVM_TARGET_TARGETPARSER_H +#include "llvm/MC/MCParser/MCAsmParserExtension.h" + namespace llvm { class MCInst; class StringRef; @@ -20,7 +22,7 @@ class MCParsedAsmOperand; template <typename T> class SmallVectorImpl; /// TargetAsmParser - Generic interface to target specific assembly parsers. -class TargetAsmParser { +class TargetAsmParser : public MCAsmParserExtension { TargetAsmParser(const TargetAsmParser &); // DO NOT IMPLEMENT void operator=(const TargetAsmParser &); // DO NOT IMPLEMENT protected: // Can only create subclasses. diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h new file mode 100644 index 0000000..f368a2e --- /dev/null +++ b/include/llvm/Target/TargetCallingConv.h @@ -0,0 +1,142 @@ +//===-- llvm/Target/TargetCallingConv.h - Calling Convention ----*- 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 types for working with calling-convention information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_TARGETCALLINGCONV_H +#define LLVM_TARGET_TARGETCALLINGCONV_H + +namespace llvm { + +namespace ISD { + struct ArgFlagsTy { + private: + static const uint64_t NoFlagSet = 0ULL; + static const uint64_t ZExt = 1ULL<<0; ///< Zero extended + static const uint64_t ZExtOffs = 0; + static const uint64_t SExt = 1ULL<<1; ///< Sign extended + static const uint64_t SExtOffs = 1; + static const uint64_t InReg = 1ULL<<2; ///< Passed in register + static const uint64_t InRegOffs = 2; + static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr + static const uint64_t SRetOffs = 3; + static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value + static const uint64_t ByValOffs = 4; + static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain + static const uint64_t NestOffs = 5; + static const uint64_t ByValAlign = 0xFULL << 6; //< Struct alignment + static const uint64_t ByValAlignOffs = 6; + static const uint64_t Split = 1ULL << 10; + static const uint64_t SplitOffs = 10; + static const uint64_t OrigAlign = 0x1FULL<<27; + static const uint64_t OrigAlignOffs = 27; + static const uint64_t ByValSize = 0xffffffffULL << 32; //< Struct size + static const uint64_t ByValSizeOffs = 32; + + static const uint64_t One = 1ULL; //< 1 of this type, for shifts + + uint64_t Flags; + public: + ArgFlagsTy() : Flags(0) { } + + bool isZExt() const { return Flags & ZExt; } + void setZExt() { Flags |= One << ZExtOffs; } + + bool isSExt() const { return Flags & SExt; } + void setSExt() { Flags |= One << SExtOffs; } + + bool isInReg() const { return Flags & InReg; } + void setInReg() { Flags |= One << InRegOffs; } + + bool isSRet() const { return Flags & SRet; } + void setSRet() { Flags |= One << SRetOffs; } + + bool isByVal() const { return Flags & ByVal; } + void setByVal() { Flags |= One << ByValOffs; } + + bool isNest() const { return Flags & Nest; } + void setNest() { Flags |= One << NestOffs; } + + unsigned getByValAlign() const { + return (unsigned) + ((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2); + } + void setByValAlign(unsigned A) { + Flags = (Flags & ~ByValAlign) | + (uint64_t(Log2_32(A) + 1) << ByValAlignOffs); + } + + bool isSplit() const { return Flags & Split; } + void setSplit() { Flags |= One << SplitOffs; } + + unsigned getOrigAlign() const { + return (unsigned) + ((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2); + } + void setOrigAlign(unsigned A) { + Flags = (Flags & ~OrigAlign) | + (uint64_t(Log2_32(A) + 1) << OrigAlignOffs); + } + + unsigned getByValSize() const { + return (unsigned)((Flags & ByValSize) >> ByValSizeOffs); + } + void setByValSize(unsigned S) { + Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs); + } + + /// getArgFlagsString - Returns the flags as a string, eg: "zext align:4". + std::string getArgFlagsString(); + + /// getRawBits - Represent the flags as a bunch of bits. + uint64_t getRawBits() const { return Flags; } + }; + + /// InputArg - This struct carries flags and type information about a + /// single incoming (formal) argument or incoming (from the perspective + /// of the caller) return value virtual register. + /// + struct InputArg { + ArgFlagsTy Flags; + EVT VT; + bool Used; + + InputArg() : VT(MVT::Other), Used(false) {} + InputArg(ArgFlagsTy flags, EVT vt, bool used) + : Flags(flags), VT(vt), Used(used) { + assert(VT.isSimple() && + "InputArg value type must be Simple!"); + } + }; + + /// OutputArg - This struct carries flags and a value for a + /// single outgoing (actual) argument or outgoing (from the perspective + /// of the caller) return value virtual register. + /// + struct OutputArg { + ArgFlagsTy Flags; + EVT VT; + + /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...". + bool IsFixed; + + OutputArg() : IsFixed(false) {} + OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed) + : Flags(flags), VT(vt), IsFixed(isfixed) { + assert(VT.isSimple() && + "OutputArg value type must be Simple!"); + } + }; +} + +} // end llvm namespace + +#endif diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/Target/TargetInstrDesc.h index adc37e1..8f0a6cb 100644 --- a/include/llvm/Target/TargetInstrDesc.h +++ b/include/llvm/Target/TargetInstrDesc.h @@ -15,6 +15,8 @@ #ifndef LLVM_TARGET_TARGETINSTRDESC_H #define LLVM_TARGET_TARGETINSTRDESC_H +#include "llvm/System/DataTypes.h" + namespace llvm { class TargetRegisterClass; @@ -53,7 +55,7 @@ public: /// /// NOTE: This member should be considered to be private, all access should go /// through "getRegClass(TRI)" below. - unsigned short RegClass; + short RegClass; /// Flags - These are flags from the TOI::OperandFlags enum. unsigned short Flags; @@ -131,7 +133,7 @@ public: 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 - unsigned TSFlags; // Target Specific Flag values + 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" diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 2e5697e..6e69914 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -20,12 +20,14 @@ namespace llvm { class CalleeSavedInfo; +class InstrItineraryData; class LiveVariables; class MCAsmInfo; class MachineMemOperand; class MDNode; class MCInst; class SDNode; +class ScheduleHazardRecognizer; class SelectionDAG; class TargetRegisterClass; class TargetRegisterInfo; @@ -120,10 +122,6 @@ public: SrcReg == DstReg) return true; - if (MI.getOpcode() == TargetOpcode::EXTRACT_SUBREG && - MI.getOperand(0).getReg() == MI.getOperand(1).getReg()) - return true; - if ((MI.getOpcode() == TargetOpcode::INSERT_SUBREG || MI.getOpcode() == TargetOpcode::SUBREG_TO_REG) && MI.getOperand(0).getReg() == MI.getOperand(2).getReg()) @@ -194,11 +192,22 @@ public: /// reMaterialize - Re-issue the specified 'original' instruction at the /// specific location targeting a new destination register. + /// The register in Orig->getOperand(0).getReg() will be substituted by + /// DestReg:SubIdx. Any existing subreg index is preserved or composed with + /// SubIdx. virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubIdx, const MachineInstr *Orig, - const TargetRegisterInfo *TRI) const = 0; + const TargetRegisterInfo &TRI) const = 0; + + /// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the + /// two-addrss instruction inserted by two-address pass. + virtual void scheduleTwoAddrSource(MachineInstr *SrcMI, + MachineInstr *UseMI, + const TargetRegisterInfo &TRI) const { + // Do nothing. + } /// duplicate - Create a duplicate of the Orig instruction in MF. This is like /// MachineFunction::CloneMachineInstr(), but the target may update operands @@ -224,23 +233,19 @@ public: return 0; } - /// commuteInstruction - If a target has any instructions that are commutable, - /// but require converting to a different instruction or making non-trivial - /// changes to commute them, this method can overloaded to do this. The - /// default implementation of this method simply swaps the first two operands - /// of MI and returns it. - /// - /// If a target wants to make more aggressive changes, they can construct and - /// return a new machine instruction. If an instruction cannot commute, it - /// can also return null. - /// - /// If NewMI is true, then a new machine instruction must be created. - /// + /// commuteInstruction - If a target has any instructions that are + /// commutable but require converting to different instructions or making + /// non-trivial changes to commute them, this method can overloaded to do + /// that. The default implementation simply swaps the commutable operands. + /// If NewMI is false, MI is modified in place and returned; otherwise, a + /// new machine instruction is created and returned. Do not call this + /// method for a non-commutable instruction, but there may be some cases + /// where this method fails and returns null. virtual MachineInstr *commuteInstruction(MachineInstr *MI, bool NewMI = false) const = 0; /// findCommutedOpIndices - If specified MI is commutable, return the two - /// operand indices that would swap value. Return true if the instruction + /// operand indices that would swap value. Return false if the instruction /// is not in a form which this routine understands. virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const = 0; @@ -302,25 +307,60 @@ public: /// branch to analyze. At least this much must be implemented, else tail /// merging needs to be disabled. virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl<MachineOperand> &Cond) const { + MachineBasicBlock *FBB, + const SmallVectorImpl<MachineOperand> &Cond, + DebugLoc DL) const { assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!"); return 0; } + + /// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything + /// after it, replacing it with an unconditional branch to NewDest. This is + /// used by the tail merging pass. + virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, + MachineBasicBlock *NewDest) const = 0; + + /// isLegalToSplitMBBAt - Return true if it's legal to split the given basic + /// block at the specified instruction (i.e. instruction would be the start + /// of a new basic block). + virtual bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI) const { + return true; + } + + /// isProfitableToIfCvt - Return true if it's profitable to first "NumInstrs" + /// of the specified basic block. + virtual + bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumInstrs) const { + return false; + } - /// copyRegToReg - Emit instructions to copy between a pair of registers. It - /// returns false if the target does not how to copy between the specified - /// registers. - virtual bool copyRegToReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *DestRC, - const TargetRegisterClass *SrcRC, - DebugLoc DL) const { - assert(0 && "Target didn't implement TargetInstrInfo::copyRegToReg!"); + /// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one + /// checks for the case where two basic blocks from true and false path + /// of a if-then-else (diamond) are predicated on mutally exclusive + /// predicates. + virtual bool + isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumTInstrs, + MachineBasicBlock &FMBB, unsigned NumFInstrs) const { + return false; + } + + /// isProfitableToDupForIfCvt - Return true if it's profitable for + /// if-converter to duplicate a specific number of instructions in the + /// specified MBB to enable if-conversion. + virtual bool + isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumInstrs) const { return false; } + /// copyPhysReg - Emit instructions to copy a pair of physical registers. + virtual void copyPhysReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, DebugLoc DL, + unsigned DestReg, unsigned SrcReg, + bool KillSrc) const { + assert(0 && "Target didn't implement TargetInstrInfo::copyPhysReg!"); + } + /// storeRegToStackSlot - Store the specified register of the given register /// class to the specified stack frame index. The store instruction is to be /// added to the given machine basic block before the specified machine @@ -387,19 +427,17 @@ public: /// foldMemoryOperand - Attempt to fold a load or store of the specified stack /// slot into the specified machine instruction for the specified operand(s). /// If this is possible, a new instruction is returned with the specified - /// operand folded, otherwise NULL is returned. The client is responsible for - /// removing the old instruction and adding the new one in the instruction - /// stream. - MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, + /// operand folded, otherwise NULL is returned. + /// The new instruction is inserted before MI, and the client is responsible + /// for removing the old instruction. + MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, const SmallVectorImpl<unsigned> &Ops, int FrameIndex) const; /// foldMemoryOperand - Same as the previous version except it allows folding /// of any load and store from / to any address, not just from a specific /// stack slot. - MachineInstr* foldMemoryOperand(MachineFunction &MF, - MachineInstr* MI, + MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, const SmallVectorImpl<unsigned> &Ops, MachineInstr* LoadMI) const; @@ -429,9 +467,7 @@ public: /// folding is possible. virtual bool canFoldMemoryOperand(const MachineInstr *MI, - const SmallVectorImpl<unsigned> &Ops) const { - return false; - } + const SmallVectorImpl<unsigned> &Ops) const =0; /// unfoldMemoryOperand - Separate a single instruction which folded a load or /// a store or a load and a store into two or more instruction. If this is @@ -548,6 +584,13 @@ public: return true; } + /// isSchedulingBoundary - Test if the given instruction should be + /// considered a scheduling boundary. This primarily includes labels and + /// terminators. + virtual bool isSchedulingBoundary(const MachineInstr *MI, + const MachineBasicBlock *MBB, + const MachineFunction &MF) const = 0; + /// GetInstSize - Returns the size of the specified Instruction. /// virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const { @@ -564,6 +607,12 @@ public: /// length. virtual unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const; + + /// CreateTargetHazardRecognizer - Allocate and return a hazard recognizer + /// to use for this target when scheduling the machine instructions after + /// register allocation. + virtual ScheduleHazardRecognizer* + CreateTargetPostRAHazardRecognizer(const InstrItineraryData&) const = 0; }; /// TargetInstrInfoImpl - This is the default implementation of @@ -575,22 +624,32 @@ protected: TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes) : TargetInstrInfo(desc, NumOpcodes) {} public: + virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, + MachineBasicBlock *NewDest) const; virtual MachineInstr *commuteInstruction(MachineInstr *MI, bool NewMI = false) const; virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const; + virtual bool canFoldMemoryOperand(const MachineInstr *MI, + const SmallVectorImpl<unsigned> &Ops) const; virtual bool PredicateInstruction(MachineInstr *MI, const SmallVectorImpl<MachineOperand> &Pred) const; virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubReg, const MachineInstr *Orig, - const TargetRegisterInfo *TRI) const; + const TargetRegisterInfo &TRI) const; virtual MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const; virtual bool produceSameValue(const MachineInstr *MI0, const MachineInstr *MI1) const; + virtual bool isSchedulingBoundary(const MachineInstr *MI, + const MachineBasicBlock *MBB, + const MachineFunction &MF) const; virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const; + + virtual ScheduleHazardRecognizer * + CreateTargetPostRAHazardRecognizer(const InstrItineraryData&) const; }; } // End llvm namespace diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h index 3dfa8bc..39648c2 100644 --- a/include/llvm/Target/TargetInstrItineraries.h +++ b/include/llvm/Target/TargetInstrItineraries.h @@ -106,7 +106,8 @@ struct InstrItinerary { /// Instruction itinerary Data - Itinerary data supplied by a subtarget to be /// used by a target. /// -struct InstrItineraryData { +class InstrItineraryData { +public: const InstrStage *Stages; ///< Array of stages selected const unsigned *OperandCycles; ///< Array of operand cycles selected const InstrItinerary *Itineratries; ///< Array of itineraries selected diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 5efebe6..2b6e4fa 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -24,6 +24,7 @@ #include "llvm/CallingConv.h" #include "llvm/InlineAsm.h" +#include "llvm/Attributes.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/RuntimeLibcalls.h" #include "llvm/ADT/APFloat.h" @@ -32,6 +33,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/DebugLoc.h" +#include "llvm/Target/TargetCallingConv.h" #include "llvm/Target/TargetMachine.h" #include <climits> #include <map> @@ -42,6 +44,7 @@ namespace llvm { class CallInst; class Function; class FastISel; + class FunctionLoweringInfo; class MachineBasicBlock; class MachineFunction; class MachineFrameInfo; @@ -114,7 +117,7 @@ public: /// isSelectExpensive - Return true if the select operation is expensive for /// this target. bool isSelectExpensive() const { return SelectIsExpensive; } - + /// isIntDivCheap() - Return true if integer divide is usually cheaper than /// a sequence of several shifts, adds, and multiplies for this target. bool isIntDivCheap() const { return IntDivIsCheap; } @@ -131,10 +134,10 @@ public: virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; - /// getCmpLibcallReturnType - Return the ValueType for comparison + /// getCmpLibcallReturnType - Return the ValueType for comparison /// libcalls. Comparions libcalls include floating point comparion calls, /// and Ordered/Unordered check calls on floating point numbers. - virtual + virtual MVT::SimpleValueType getCmpLibcallReturnType() const; /// getBooleanContents - For targets without i1 registers, this gives the @@ -208,7 +211,7 @@ public: ValueTypeActions[I] = Action; } }; - + const ValueTypeActionImpl &getValueTypeActions() const { return ValueTypeActions; } @@ -229,7 +232,7 @@ public: /// returns the integer type to transform to. EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const { if (VT.isSimple()) { - assert((unsigned)VT.getSimpleVT().SimpleTy < + assert((unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(TransformToType)); EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy]; assert(getTypeAction(Context, NVT) != Promote && @@ -256,7 +259,7 @@ public: return EVT::getIntegerVT(Context, VT.getSizeInBits() / 2); else // Promote to a power of two size, avoiding multi-step promotion. - return getTypeAction(Context, NVT) == Promote ? + return getTypeAction(Context, NVT) == Promote ? getTypeToTransformTo(Context, NVT) : NVT; } assert(0 && "Unsupported extended type!"); @@ -302,11 +305,11 @@ public: /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If /// this is the case, it returns true and store the intrinsic /// information into the IntrinsicInfo that was passed to the function. - struct IntrinsicInfo { + struct IntrinsicInfo { unsigned opc; // target opcode EVT memVT; // memory VT const Value* ptrVal; // value representing memory location - int offset; // offset off of ptrVal + int offset; // offset off of ptrVal unsigned align; // alignment bool vol; // is volatile? bool readMem; // reads memory? @@ -324,7 +327,7 @@ public: virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const { return false; } - + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values @@ -446,7 +449,7 @@ public: "Table isn't big enough!"); unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy; return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f); - } + } /// isIndexedStoreLegal - Return true if the specified indexed load is legal /// on this target. @@ -492,7 +495,7 @@ public: assert((VT.isInteger() || VT.isFloatingPoint()) && "Cannot autopromote this type, add it with AddPromotedToType."); - + EVT NVT = VT; do { NVT = (MVT::SimpleValueType)(NVT.getSimpleVT().SimpleTy+1); @@ -516,14 +519,14 @@ public: /// function arguments in the caller parameter area. This is the actual /// alignment, not its logarithm. virtual unsigned getByValTypeAlignment(const Type *Ty) const; - + /// getRegisterType - Return the type of registers that this ValueType will /// eventually require. EVT getRegisterType(MVT VT) const { assert((unsigned)VT.SimpleTy < array_lengthof(RegisterTypeForVT)); return RegisterTypeForVT[VT.SimpleTy]; } - + /// getRegisterType - Return the type of registers that this ValueType will /// eventually require. EVT getRegisterType(LLVMContext &Context, EVT VT) const { @@ -606,7 +609,7 @@ public: /// of the specified type. This is used, for example, in situations where an /// array copy/move/set is converted to a sequence of store operations. It's /// use helps to ensure that such replacements don't generate code that causes - /// an alignment error (trap) on the target machine. + /// an alignment error (trap) on the target machine. /// @brief Determine if the target supports unaligned memory accesses. virtual bool allowsUnalignedMemoryAccesses(EVT VT) const { return false; @@ -637,7 +640,7 @@ public: MachineFunction &MF) const { return MVT::Other; } - + /// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp /// to implement llvm.setjmp. bool usesUnderscoreSetJmp() const { @@ -683,17 +686,10 @@ public: return JumpBufAlignment; } - /// getIfCvtBlockLimit - returns the target specific if-conversion block size - /// limit. Any block whose size is greater should not be predicated. - unsigned getIfCvtBlockSizeLimit() const { - return IfCvtBlockSizeLimit; - } - - /// getIfCvtDupBlockLimit - returns the target specific size limit for a - /// block to be considered for duplication. Any block whose size is greater - /// should not be duplicated to facilitate its predication. - unsigned getIfCvtDupBlockSizeLimit() const { - return IfCvtDupBlockSizeLimit; + /// getMinStackArgumentAlignment - return the minimum stack alignment of an + /// argument. + unsigned getMinStackArgumentAlignment() const { + return MinStackArgumentAlignment; } /// getPrefLoopAlignment - return the preferred loop alignment. @@ -701,7 +697,14 @@ public: unsigned getPrefLoopAlignment() const { return PrefLoopAlignment; } - + + /// getShouldFoldAtomicFences - return whether the combiner should fold + /// fence MEMBARRIER instructions into the atomic intrinsic instructions. + /// + bool getShouldFoldAtomicFences() const { + return ShouldFoldAtomicFences; + } + /// getPreIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if the node's address /// can be legally represented as pre-indexed load / store address. @@ -711,7 +714,7 @@ public: SelectionDAG &DAG) const { return false; } - + /// getPostIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if this node can be /// combined with a load / store to form a post-indexed load / store. @@ -721,12 +724,12 @@ public: SelectionDAG &DAG) const { return false; } - + /// getJumpTableEncoding - Return the entry encoding for a jump table in the /// current function. The returned value is a member of the /// MachineJumpTableInfo::JTEntryKind enum. virtual unsigned getJumpTableEncoding() const; - + virtual const MCExpr * LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned uid, @@ -734,7 +737,7 @@ public: assert(0 && "Need to implement this hook if target has custom JTIs"); return 0; } - + /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC /// jumptable. virtual SDValue getPICJumpTableRelocBase(SDValue Table, @@ -746,7 +749,7 @@ public: virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const; - + /// isOffsetFoldingLegal - Return true if folding a constant offset /// with the given GlobalAddress is legal. It is frequently not legal in /// PIC relocation models. @@ -755,36 +758,42 @@ public: /// getFunctionAlignment - Return the Log2 alignment of this function. virtual unsigned getFunctionAlignment(const Function *) const = 0; + /// getStackCookieLocation - Return true if the target stores stack + /// protector cookies at a fixed offset in some non-standard address + /// space, and populates the address space and offset as + /// appropriate. + virtual bool getStackCookieLocation(unsigned &AddressSpace, unsigned &Offset) const { + return false; + } + //===--------------------------------------------------------------------===// // TargetLowering Optimization Methods // - + /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two /// SDValues for returning information from TargetLowering to its clients - /// that want to combine + /// that want to combine struct TargetLoweringOpt { SelectionDAG &DAG; bool LegalTys; bool LegalOps; - bool ShrinkOps; SDValue Old; SDValue New; explicit TargetLoweringOpt(SelectionDAG &InDAG, - bool LT, bool LO, - bool Shrink = false) : - DAG(InDAG), LegalTys(LT), LegalOps(LO), ShrinkOps(Shrink) {} + bool LT, bool LO) : + DAG(InDAG), LegalTys(LT), LegalOps(LO) {} bool LegalTypes() const { return LegalTys; } bool LegalOperations() const { return LegalOps; } - - bool CombineTo(SDValue O, SDValue N) { - Old = O; - New = N; + + bool CombineTo(SDValue O, SDValue N) { + Old = O; + New = N; return true; } - - /// ShrinkDemandedConstant - Check to see if the specified operand of the + + /// ShrinkDemandedConstant - Check to see if the specified operand of the /// specified instruction is a constant integer. If so, check to see if /// there are any bits set in the constant that are not demanded. If so, /// shrink the constant and return true. @@ -797,25 +806,25 @@ public: bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded, DebugLoc dl); }; - + /// SimplifyDemandedBits - Look at Op. At this point, we know that only the /// DemandedMask bits of the result of Op are ever used downstream. If we can /// use this information to simplify Op, create a new simplified DAG node and - /// return true, returning the original and new nodes in Old and New. - /// Otherwise, analyze the expression and return a mask of KnownOne and - /// KnownZero bits for the expression (used to simplify the caller). - /// The KnownZero/One bits may only be accurate for those bits in the + /// return true, returning the original and new nodes in Old and New. + /// Otherwise, analyze the expression and return a mask of KnownOne and + /// KnownZero bits for the expression (used to simplify the caller). + /// The KnownZero/One bits may only be accurate for those bits in the /// DemandedMask. - bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask, + bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask, APInt &KnownZero, APInt &KnownOne, TargetLoweringOpt &TLO, unsigned Depth = 0) const; - + /// computeMaskedBitsForTargetNode - Determine which of the bits specified in - /// Mask are known to be either zero or one and return them in the + /// Mask are known to be either zero or one and return them in the /// KnownZero/KnownOne bitsets. virtual void computeMaskedBitsForTargetNode(const SDValue Op, const APInt &Mask, - APInt &KnownZero, + APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, unsigned Depth = 0) const; @@ -825,7 +834,7 @@ public: /// DAG Combiner. virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op, unsigned Depth = 0) const; - + struct DAGCombinerInfo { void *DC; // The DAG Combiner object. bool BeforeLegalize; @@ -833,15 +842,15 @@ public: bool CalledByLegalizer; public: SelectionDAG &DAG; - + DAGCombinerInfo(SelectionDAG &dag, bool bl, bool blo, bool cl, void *dc) : DC(dc), BeforeLegalize(bl), BeforeLegalizeOps(blo), CalledByLegalizer(cl), DAG(dag) {} - + bool isBeforeLegalize() const { return BeforeLegalize; } bool isBeforeLegalizeOps() const { return BeforeLegalizeOps; } bool isCalledByLegalizer() const { return CalledByLegalizer; } - + void AddToWorklist(SDNode *N); SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To, bool AddTo = true); @@ -851,7 +860,7 @@ public: void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO); }; - /// SimplifySetCC - Try to simplify a setcc built with the specified operands + /// SimplifySetCC - Try to simplify a setcc built with the specified operands /// and cc. If it is unable to simplify it, return a null SDValue. SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, bool foldBooleans, @@ -892,7 +901,7 @@ public: virtual bool IsDesirableToPromoteOp(SDValue Op, EVT &PVT) const { return false; } - + //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by // the derived class constructor to configure this object for the target. @@ -932,7 +941,7 @@ protected: void setStackPointerRegisterToSaveRestore(unsigned R) { StackPointerRegisterToSaveRestore = R; } - + /// setExceptionPointerRegister - If set to a physical register, this sets /// the register that receives the exception address on entry to a landing /// pad. @@ -955,12 +964,12 @@ protected: /// expensive, and if possible, should be replaced by an alternate sequence /// of instructions not containing an integer divide. void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; } - + /// setPow2DivIsCheap - Tells the code generator that it shouldn't generate /// srl/add/sra for a signed divide by power of two, and let the target handle /// it. void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; } - + /// addRegisterClass - Add the specified register class as an available /// regclass for the specified value type. This indicates the selector can /// handle values of that class natively. @@ -983,7 +992,7 @@ protected: assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!"); OpActions[(unsigned)VT.SimpleTy][Op] = (uint8_t)Action; } - + /// setLoadExtAction - Indicate that the specified load with extension does /// not work with the specified type and indicate what to do about it. void setLoadExtAction(unsigned ExtType, MVT VT, @@ -993,7 +1002,7 @@ protected: "Table isn't big enough!"); LoadExtActions[VT.SimpleTy][ExtType] = (uint8_t)Action; } - + /// setTruncStoreAction - Indicate that the specified truncating store does /// not work with the specified type and indicate what to do about it. void setTruncStoreAction(MVT ValVT, MVT MemVT, @@ -1018,7 +1027,7 @@ protected: IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0xf0; IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action) <<4; } - + /// setIndexedStoreAction - Indicate that the specified indexed store does or /// does not work with the specified type and indicate what to do about /// it. NOTE: All indexed mode stores are initialized to Expand in @@ -1033,7 +1042,7 @@ protected: IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0x0f; IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action); } - + /// setCondCodeAction - Indicate that the specified condition code is or isn't /// supported on the target and indicate what to do about it. void setCondCodeAction(ISD::CondCode CC, MVT VT, @@ -1060,7 +1069,7 @@ protected: assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray)); TargetDAGCombineArray[NT >> 3] |= 1 << (NT&7); } - + /// setJumpBufSize - Set the target's required jmp_buf buffer size (in /// bytes); default is 200 void setJumpBufSize(unsigned Size) { @@ -1073,25 +1082,24 @@ protected: JumpBufAlignment = Align; } - /// setIfCvtBlockSizeLimit - Set the target's if-conversion block size - /// limit (in number of instructions); default is 2. - void setIfCvtBlockSizeLimit(unsigned Limit) { - IfCvtBlockSizeLimit = Limit; - } - - /// setIfCvtDupBlockSizeLimit - Set the target's block size limit (in number - /// of instructions) to be considered for code duplication during - /// if-conversion; default is 2. - void setIfCvtDupBlockSizeLimit(unsigned Limit) { - IfCvtDupBlockSizeLimit = Limit; - } - /// setPrefLoopAlignment - Set the target's preferred loop alignment. Default /// alignment is zero, it means the target does not care about loop alignment. void setPrefLoopAlignment(unsigned Align) { PrefLoopAlignment = Align; } - + + /// setMinStackArgumentAlignment - Set the minimum stack alignment of an + /// argument. + void setMinStackArgumentAlignment(unsigned Align) { + MinStackArgumentAlignment = Align; + } + + /// setShouldFoldAtomicFences - Set if the target's implementation of the + /// atomic operation intrinsics includes locking. Default is false. + void setShouldFoldAtomicFences(bool fold) { + ShouldFoldAtomicFences = fold; + } + public: //===--------------------------------------------------------------------===// // Lowering methods - These methods must be implemented by targets so that @@ -1151,6 +1159,7 @@ public: LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg, bool &isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<SDValue> &OutVals, const SmallVectorImpl<ISD::InputArg> &Ins, DebugLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { @@ -1163,9 +1172,8 @@ public: /// registers. If false is returned, an sret-demotion is performed. /// virtual bool CanLowerReturn(CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl<EVT> &OutTys, - const SmallVectorImpl<ISD::ArgFlagsTy> &ArgsFlags, - SelectionDAG &DAG) const + const SmallVectorImpl<ISD::OutputArg> &Outs, + LLVMContext &Context) const { // Return true by default to get preexisting behavior. return true; @@ -1179,6 +1187,7 @@ public: virtual SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<SDValue> &OutVals, DebugLoc dl, SelectionDAG &DAG) const { assert(0 && "Not Implemented"); return SDValue(); // this is here to silence compiler errors @@ -1200,7 +1209,7 @@ public: SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG) const; - /// LowerOperation - This callback is invoked for operations that are + /// LowerOperation - This callback is invoked for operations that are /// unsupported by the target, which are registered to use 'custom' lowering, /// and whose defined values are all legal. /// If the target has no operations that require custom lowering, it need not @@ -1227,23 +1236,14 @@ public: /// createFastISel - This method returns a target specific FastISel object, /// or null if the target does not support "fast" ISel. - virtual FastISel * - createFastISel(MachineFunction &, - DenseMap<const Value *, unsigned> &, - DenseMap<const BasicBlock *, MachineBasicBlock *> &, - DenseMap<const AllocaInst *, int> &, - std::vector<std::pair<MachineInstr*, unsigned> > & -#ifndef NDEBUG - , SmallSet<const Instruction *, 8> &CatchInfoLost -#endif - ) const { + virtual FastISel *createFastISel(FunctionLoweringInfo &funcInfo) const { return 0; } //===--------------------------------------------------------------------===// // Inline Asm Support hooks // - + /// ExpandInlineAsm - This hook allows the target to expand an inline asm /// call to be explicit llvm code if it wants to. This is useful for /// turning simple inline asms into LLVM intrinsics, which gives the @@ -1251,7 +1251,7 @@ public: virtual bool ExpandInlineAsm(CallInst *CI) const { return false; } - + enum ConstraintType { C_Register, // Constraint represents specific register(s). C_RegisterClass, // Constraint represents any of register(s) in class. @@ -1259,7 +1259,7 @@ public: C_Other, // Something else. C_Unknown // Unsupported constraint. }; - + /// AsmOperandInfo - This contains information for each constraint that we are /// lowering. struct AsmOperandInfo : public InlineAsm::ConstraintInfo { @@ -1271,25 +1271,25 @@ public: /// ConstraintType - Information about the constraint code, e.g. Register, /// RegisterClass, Memory, Other, Unknown. TargetLowering::ConstraintType ConstraintType; - + /// CallOperandval - If this is the result output operand or a /// clobber, this is null, otherwise it is the incoming operand to the /// CallInst. This gets modified as the asm is processed. Value *CallOperandVal; - + /// ConstraintVT - The ValueType for the operand value. EVT ConstraintVT; - + /// isMatchingInputConstraint - Return true of this is an input operand that /// is a matching constraint like "4". bool isMatchingInputConstraint() const; - + /// getMatchedOperand - If this is an input matching constraint, this method /// returns the output operand it matches. unsigned getMatchedOperand() const; - + AsmOperandInfo(const InlineAsm::ConstraintInfo &info) - : InlineAsm::ConstraintInfo(info), + : InlineAsm::ConstraintInfo(info), ConstraintType(TargetLowering::C_Unknown), CallOperandVal(0), ConstraintVT(MVT::Other) { } @@ -1299,21 +1299,19 @@ public: /// type to use for the specific AsmOperandInfo, setting /// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand /// being passed in is available, it can be passed in as Op, otherwise an - /// empty SDValue can be passed. If hasMemory is true it means one of the asm - /// constraint of the inline asm instruction being processed is 'm'. + /// empty SDValue can be passed. virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, - bool hasMemory, SelectionDAG *DAG = 0) const; - + /// getConstraintType - Given a constraint, return the type of constraint it /// 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> + virtual std::vector<unsigned> getRegClassForInlineAsmConstraint(const std::string &Constraint, EVT VT) const; @@ -1327,29 +1325,26 @@ public: /// /// This should only be used for C_Register constraints. On error, /// this returns a register number of 0 and a null register class pointer.. - virtual std::pair<unsigned, const TargetRegisterClass*> + virtual std::pair<unsigned, const TargetRegisterClass*> getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const; - + /// LowerXConstraint - try to replace an X constraint, which matches anything, /// with another that has more specific requirements based on the type of the /// corresponding operand. This returns null if there is no replacement to /// make. virtual const char *LowerXConstraint(EVT ConstraintVT) const; - + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops - /// vector. If it is invalid, don't add anything to Ops. If hasMemory is true - /// it means one of the asm constraint of the inline asm instruction being - /// processed is 'm'. + /// vector. If it is invalid, don't add anything to Ops. virtual void LowerAsmOperandForConstraint(SDValue Op, char ConstraintLetter, - bool hasMemory, std::vector<SDValue> &Ops, SelectionDAG &DAG) const; - + //===--------------------------------------------------------------------===// // Instruction Emitting Hooks // - + // EmitInstrWithCustomInserter - This method should be implemented by targets // that mark instructions with the 'usesCustomInserter' flag. These // instructions are special in various ways, which require special support to @@ -1378,7 +1373,7 @@ public: int64_t Scale; AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {} }; - + /// isLegalAddressingMode - Return true if the addressing mode represented by /// AM is legal for this target, for a load/store of the specified type. /// The type may be VoidTy, in which case only return true if the addressing @@ -1431,9 +1426,9 @@ public: //===--------------------------------------------------------------------===// // Div utility functions // - SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, + SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, std::vector<SDNode*>* Created) const; - SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, + SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, std::vector<SDNode*>* Created) const; @@ -1470,7 +1465,7 @@ public: void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) { LibcallCallingConvs[Call] = CC; } - + /// getLibcallCallingConv - Get the CallingConv that should be used for the /// specified libcall. CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const { @@ -1499,12 +1494,12 @@ private: /// a real cost model is in place. If we ever optimize for size, this will be /// set to true unconditionally. bool IntDivIsCheap; - + /// Pow2DivIsCheap - Tells the code generator that it shouldn't generate /// srl/add/sra for a signed divide by power of two, and let the target handle /// it. bool Pow2DivIsCheap; - + /// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement /// llvm.setjmp. Defaults to false. bool UseUnderscoreSetJmp; @@ -1524,26 +1519,28 @@ private: /// SchedPreferenceInfo - The target scheduling preference: shortest possible /// total cycles or lowest register usage. Sched::Preference SchedPreferenceInfo; - + /// JumpBufSize - The size, in bytes, of the target's jmp_buf buffers unsigned JumpBufSize; - + /// JumpBufAlignment - The alignment, in bytes, of the target's jmp_buf /// buffers unsigned JumpBufAlignment; - /// IfCvtBlockSizeLimit - The maximum allowed size for a block to be - /// if-converted. - unsigned IfCvtBlockSizeLimit; - - /// IfCvtDupBlockSizeLimit - The maximum allowed size for a block to be - /// duplicated during if-conversion. - unsigned IfCvtDupBlockSizeLimit; + /// MinStackArgumentAlignment - The minimum alignment that any argument + /// on the stack needs to have. + /// + unsigned MinStackArgumentAlignment; /// PrefLoopAlignment - The perferred loop alignment. /// unsigned PrefLoopAlignment; + /// ShouldFoldAtomicFences - Whether fencing MEMBARRIER instructions should + /// be folded into the enclosed atomic intrinsic instruction by the + /// combiner. + bool ShouldFoldAtomicFences; + /// StackPointerRegisterToSaveRestore - If set to a physical register, this /// specifies the register that llvm.savestack/llvm.restorestack should save /// and restore. @@ -1583,12 +1580,12 @@ private: /// operations that are not should be described. Note that operations on /// non-legal value types are not described here. uint8_t OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END]; - + /// LoadExtActions - For each load extension type and each value type, /// keep a LegalizeAction that indicates how instruction selection should deal /// with a load of a specific value type and extension type. uint8_t LoadExtActions[MVT::LAST_VALUETYPE][ISD::LAST_LOADEXT_TYPE]; - + /// TruncStoreActions - For each value type pair keep a LegalizeAction that /// indicates whether a truncating store of a specific value type and /// truncating type is legal. @@ -1600,7 +1597,7 @@ private: /// value_type for the reference. The second dimension represents the various /// modes for load store. uint8_t IndexedModeActions[MVT::LAST_VALUETYPE][ISD::LAST_INDEXED_MODE]; - + /// CondCodeActions - For each condition code (ISD::CondCode) keep a /// LegalizeAction that indicates how instruction selection should /// deal with the condition code. @@ -1615,7 +1612,7 @@ private: /// which sets a bit in this array. unsigned char TargetDAGCombineArray[(ISD::BUILTIN_OP_END+CHAR_BIT-1)/CHAR_BIT]; - + /// PromoteToType - For operations that must be promoted to a specific type, /// this holds the destination type. This map should be sparse, so don't hold /// it as an array. @@ -1676,6 +1673,15 @@ protected: /// optimization. bool benefitFromCodePlacementOpt; }; + +/// GetReturnInfo - Given an LLVM IR type and return type attributes, +/// compute the return value EVTs and flags, and optionally also +/// the offsets, if the return value is being lowered to memory. +void GetReturnInfo(const Type* ReturnType, Attributes attr, + SmallVectorImpl<ISD::OutputArg> &Outs, + const TargetLowering &TLI, + SmallVectorImpl<uint64_t> *Offsets = 0); + } // end llvm namespace #endif diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index c4deaa8..cb772ec 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -15,52 +15,54 @@ #define LLVM_TARGET_TARGETOPCODES_H namespace llvm { - + /// Invariant opcodes: All instruction sets have these as their low opcodes. +/// +/// Every instruction defined here must also appear in Target.td and the order +/// must be the same as in CodeGenTarget.cpp. +/// namespace TargetOpcode { - enum { + enum { PHI = 0, INLINEASM = 1, DBG_LABEL = 2, EH_LABEL = 3, GC_LABEL = 4, - + /// KILL - This instruction is a noop that is used only to adjust the /// liveness of registers. This can be useful when dealing with /// sub-registers. KILL = 5, - + /// EXTRACT_SUBREG - This instruction takes two operands: a register /// that has subregisters, and a subregister index. It returns the /// extracted subregister value. This is commonly used to implement /// truncation operations on target architectures which support it. EXTRACT_SUBREG = 6, - - /// INSERT_SUBREG - This instruction takes three operands: a register - /// that has subregisters, a register providing an insert value, and a - /// subregister index. It returns the value of the first register with - /// the value of the second register inserted. The first register is - /// often defined by an IMPLICIT_DEF, as is commonly used to implement + + /// INSERT_SUBREG - This instruction takes three operands: a register that + /// has subregisters, a register providing an insert value, and a + /// subregister index. It returns the value of the first register with the + /// value of the second register inserted. The first register is often + /// defined by an IMPLICIT_DEF, because it is commonly used to implement /// anyext operations on target architectures which support it. INSERT_SUBREG = 7, - + /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef. IMPLICIT_DEF = 8, - - /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except - /// that the first operand is an immediate integer constant. This constant - /// is often zero, as is commonly used to implement zext operations on - /// target architectures which support it, such as with x86-64 (with - /// zext from i32 to i64 via implicit zero-extension). + + /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that + /// the first operand is an immediate integer constant. This constant is + /// often zero, because it is commonly used to assert that the instruction + /// defining the register implicitly clears the high bits. SUBREG_TO_REG = 9, - + /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain /// register-to-register copy into a specific register class. This is only /// used between instruction selection and MachineInstr creation, before /// virtual registers have been created for all the instructions, and it's /// only needed in cases where the register classes implied by the - /// instructions are insufficient. The actual MachineInstrs to perform - /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook. + /// instructions are insufficient. It is emitted as a COPY MachineInstr. COPY_TO_REGCLASS = 10, /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic @@ -72,7 +74,11 @@ namespace TargetOpcode { /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5 /// After register coalescing references of v1024 should be replace with /// v1027:3, v1025 with v1027:4, etc. - REG_SEQUENCE = 12 + REG_SEQUENCE = 12, + + /// COPY - Target-independent register copy. This instruction can also be + /// used to copy between subregisters of virtual registers. + COPY = 13 }; } // end namespace TargetOpcode } // end namespace llvm diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 7c37b73..f6ac2b7 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -115,6 +115,11 @@ public: return RegSet.count(Reg); } + /// contains - Return true if both registers are in this class. + bool contains(unsigned Reg1, unsigned Reg2) const { + return contains(Reg1) && contains(Reg2); + } + /// hasType - return true if this TargetRegisterClass has the ValueType vt. /// bool hasType(EVT vt) const { @@ -313,11 +318,11 @@ public: return Reg >= FirstVirtualRegister; } - /// getPhysicalRegisterRegClass - Returns the Register Class of a physical - /// register of the given type. If type is EVT::Other, then just return any - /// register class the register belongs to. - virtual const TargetRegisterClass * - getPhysicalRegisterRegClass(unsigned Reg, EVT VT = MVT::Other) const; + /// getMinimalPhysRegClass - Returns the Register Class of a physical + /// register of the given type, picking the most sub register class of + /// the right type that contains this physreg. + const TargetRegisterClass * + getMinimalPhysRegClass(unsigned Reg, EVT VT = MVT::Other) const; /// getAllocatableSet - Returns a bitset indexed by register number /// indicating if a register is allocatable or not. If a register class is @@ -438,11 +443,6 @@ public: virtual const unsigned* getCalleeSavedRegs(const MachineFunction *MF = 0) const = 0; - /// getCalleeSavedRegClasses - Return a null-terminated list of the preferred - /// register classes to spill each callee saved register with. The order and - /// length of this list match the getCalleeSaveRegs() list. - virtual const TargetRegisterClass* const *getCalleeSavedRegClasses( - const MachineFunction *MF) const =0; /// getReservedRegs - Returns a bitset indexed by physical register number /// indicating if a register is a special register that has particular uses @@ -456,7 +456,7 @@ public: virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0; /// getSubRegIndex - For a given register pair, return the sub-register index - /// if the are second register is a sub-register of the first. Return zero + /// if the second register is a sub-register of the first. Return zero /// otherwise. virtual unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const = 0; @@ -470,14 +470,15 @@ public: return 0; } - /// canCombinedSubRegIndex - Given a register class and a list of sub-register - /// indices, return true if it's possible to combine the sub-register indices - /// into one that corresponds to a larger sub-register. Return the new sub- - /// register index by reference. Note the new index by be zero if the given - /// sub-registers combined to form the whole register. - virtual bool canCombinedSubRegIndex(const TargetRegisterClass *RC, - SmallVectorImpl<unsigned> &SubIndices, - unsigned &NewSubIdx) const { + /// canCombineSubRegIndices - Given a register class and a list of + /// subregister indices, return true if it's possible to combine the + /// subregister indices into one that corresponds to a larger + /// subregister. Return the new subregister index by reference. Note the + /// new index may be zero if the given subregisters can be combined to + /// form the whole register. + virtual bool canCombineSubRegIndices(const TargetRegisterClass *RC, + SmallVectorImpl<unsigned> &SubIndices, + unsigned &NewSubIdx) const { return 0; } @@ -490,6 +491,23 @@ public: return 0; } + /// composeSubRegIndices - Return the subregister index you get from composing + /// two subregister indices. + /// + /// If R:a:b is the same register as R:c, then composeSubRegIndices(a, b) + /// returns c. Note that composeSubRegIndices does not tell you about illegal + /// compositions. If R does not have a subreg a, or R:a does not have a subreg + /// b, composeSubRegIndices doesn't tell you. + /// + /// The ARM register Q0 has two D subregs dsub_0:D0 and dsub_1:D1. It also has + /// ssub_0:S0 - ssub_3:S3 subregs. + /// If you compose subreg indices dsub_1, ssub_0 you get ssub_2. + /// + virtual unsigned composeSubRegIndices(unsigned a, unsigned b) const { + // This default implementation is correct for most targets. + return b; + } + //===--------------------------------------------------------------------===// // Register Class Information // @@ -506,8 +524,8 @@ public: /// getRegClass - Returns the register class associated with the enumeration /// value. See class TargetOperandInfo. const TargetRegisterClass *getRegClass(unsigned i) const { - assert(i <= getNumRegClasses() && "Register Class ID out of range"); - return i ? RegClassBegin[i - 1] : NULL; + assert(i < getNumRegClasses() && "Register Class ID out of range"); + return RegClassBegin[i]; } /// getPointerRegClass - Returns a TargetRegisterClass used for pointer |