diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
tree | 4def12e759965de927d963ac65840d663ef9d1ea /include/llvm/Target | |
parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) | |
download | src-01095a5d43bbfde13731688ddcf6048ebb8b7721.tar.gz src-01095a5d43bbfde13731688ddcf6048ebb8b7721.zip |
Vendor import of llvm release_39 branch r276489:vendor/llvm/llvm-release_39-r276489
Notes
Notes:
svn path=/vendor/llvm/dist/; revision=303231
svn path=/vendor/llvm/llvm-release_39-r276489/; revision=303232; tag=vendor/llvm/llvm-release_39-r276489
Diffstat (limited to 'include/llvm/Target')
-rw-r--r-- | include/llvm/Target/GenericOpcodes.td | 46 | ||||
-rw-r--r-- | include/llvm/Target/Target.td | 64 | ||||
-rw-r--r-- | include/llvm/Target/TargetCallingConv.h | 18 | ||||
-rw-r--r-- | include/llvm/Target/TargetCallingConv.td | 10 | ||||
-rw-r--r-- | include/llvm/Target/TargetFrameLowering.h | 72 | ||||
-rw-r--r-- | include/llvm/Target/TargetInstrInfo.h | 281 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 366 | ||||
-rw-r--r-- | include/llvm/Target/TargetLoweringObjectFile.h | 7 | ||||
-rw-r--r-- | include/llvm/Target/TargetMachine.h | 39 | ||||
-rw-r--r-- | include/llvm/Target/TargetOpcodes.def | 177 | ||||
-rw-r--r-- | include/llvm/Target/TargetOpcodes.h | 122 | ||||
-rw-r--r-- | include/llvm/Target/TargetOptions.h | 40 | ||||
-rw-r--r-- | include/llvm/Target/TargetRecip.h | 9 | ||||
-rw-r--r-- | include/llvm/Target/TargetRegisterInfo.h | 153 | ||||
-rw-r--r-- | include/llvm/Target/TargetSchedule.td | 23 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAG.td | 42 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAGInfo.h | 158 | ||||
-rw-r--r-- | include/llvm/Target/TargetSubtargetInfo.h | 24 |
18 files changed, 1088 insertions, 563 deletions
diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td new file mode 100644 index 000000000000..b4d95508f0a5 --- /dev/null +++ b/include/llvm/Target/GenericOpcodes.td @@ -0,0 +1,46 @@ +//===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===// +// +// 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 generic opcodes used with GlobalISel. +// After instruction selection, these opcodes should not appear. +// +//===----------------------------------------------------------------------===// + +//------------------------------------------------------------------------------ +// Binary ops. +//------------------------------------------------------------------------------ +// Generic addition. +def G_ADD : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src1, unknown:$src2); + let hasSideEffects = 0; + let isCommutable = 1; +} + +// Generic bitwise or. +def G_OR : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src1, unknown:$src2); + let hasSideEffects = 0; + let isCommutable = 1; +} + +//------------------------------------------------------------------------------ +// Branches. +//------------------------------------------------------------------------------ +// Generic unconditional branch. +def G_BR : Instruction { + let OutOperandList = (outs); + let InOperandList = (ins unknown:$src1); + let hasSideEffects = 0; + let isBranch = 1; + let isTerminator = 1; +} + +// TODO: Add the other generic opcodes. diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index c869341c384f..c71435a2564c 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -427,6 +427,11 @@ class Instruction { // Is this instruction a pseudo instruction for use by the assembler parser. bit isAsmParserOnly = 0; + // This instruction is not expected to be queried for scheduling latencies + // and therefore needs no scheduling information even for a complete + // scheduling model. + bit hasNoSchedulingInfo = 0; + InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling. // Scheduling information from TargetSchedule.td. @@ -605,6 +610,22 @@ class AsmOperandClass { // match failure error message. By default, use a generic "invalid operand" // diagnostic. The target AsmParser maps these codes to text. string DiagnosticType = ""; + + /// Set to 1 if this operand is optional and not always required. Typically, + /// the AsmParser will emit an error when it finishes parsing an + /// instruction if it hasn't matched all the operands yet. However, this + /// error will be suppressed if all of the remaining unmatched operands are + /// marked as IsOptional. + /// + /// Optional arguments must be at the end of the operand list. + bit IsOptional = 0; + + /// The name of the method on the target specific asm parser that returns the + /// default operand for this optional operand. This method is only used if + /// IsOptional == 1. If not set, this will default to "defaultFooOperands", + /// where Foo is the AsmOperandClass name. The method signature should be: + /// std::unique_ptr<MCParsedAsmOperand> defaultFooOperands() const; + string DefaultMethod = ?; } def ImmAsmOperand : AsmOperandClass { @@ -756,9 +777,10 @@ class InstrInfo { // Standard Pseudo Instructions. // This list must match TargetOpcodes.h and CodeGenTarget.cpp. // Only these instructions are allowed in the TargetOpcode namespace. -let isCodeGenOnly = 1, isPseudo = 1, Namespace = "TargetOpcode" in { +let isCodeGenOnly = 1, isPseudo = 1, hasNoSchedulingInfo = 1, + Namespace = "TargetOpcode" in { def PHI : Instruction { - let OutOperandList = (outs); + let OutOperandList = (outs unknown:$dst); let InOperandList = (ins variable_ops); let AsmString = "PHINODE"; } @@ -848,6 +870,7 @@ def COPY : Instruction { let AsmString = ""; let hasSideEffects = 0; let isAsCheapAsAMove = 1; + let hasNoSchedulingInfo = 0; } def BUNDLE : Instruction { let OutOperandList = (outs); @@ -912,7 +935,36 @@ def FAULTING_LOAD_OP : Instruction { let InOperandList = (ins variable_ops); let usesCustomInserter = 1; let mayLoad = 1; + let isTerminator = 1; + let isBranch = 1; } +def PATCHABLE_OP : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins variable_ops); + let usesCustomInserter = 1; + let mayLoad = 1; + let mayStore = 1; + let hasSideEffects = 1; +} +def PATCHABLE_FUNCTION_ENTER : Instruction { + let OutOperandList = (outs); + let InOperandList = (ins); + let AsmString = "# XRay Function Enter."; + let usesCustomInserter = 1; + let hasSideEffects = 0; +} +def PATCHABLE_RET : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins variable_ops); + let AsmString = "# XRay Function Exit."; + let usesCustomInserter = 1; + let hasSideEffects = 1; + let isReturn = 1; +} + +// Generic opcodes used in GlobalISel. +include "llvm/Target/GenericOpcodes.td" + } //===----------------------------------------------------------------------===// @@ -937,6 +989,14 @@ class AsmParser { // written register name matcher bit ShouldEmitMatchRegisterName = 1; + // Set to true if the target needs a generated 'alternative register name' + // matcher. + // + // This generates a function which can be used to lookup registers from + // their aliases. This function will fail when called on targets where + // several registers share the same alias (i.e. not a 1:1 mapping). + bit ShouldEmitMatchRegisterAltName = 0; + // HasMnemonicFirst - Set to false if target instructions don't always // start with a mnemonic as the first token. bit HasMnemonicFirst = 1; diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h index 0c6c1f1468c4..19d8917f17d3 100644 --- a/include/llvm/Target/TargetCallingConv.h +++ b/include/llvm/Target/TargetCallingConv.h @@ -17,8 +17,7 @@ #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/MathExtras.h" -#include <string> -#include <limits.h> +#include <climits> namespace llvm { @@ -48,6 +47,10 @@ namespace ISD { static const uint64_t InAllocaOffs = 12; static const uint64_t SplitEnd = 1ULL<<13; ///< Last part of a split static const uint64_t SplitEndOffs = 13; + static const uint64_t SwiftSelf = 1ULL<<14; ///< Swift self parameter + static const uint64_t SwiftSelfOffs = 14; + static const uint64_t SwiftError = 1ULL<<15; ///< Swift error parameter + static const uint64_t SwiftErrorOffs = 15; static const uint64_t OrigAlign = 0x1FULL<<27; static const uint64_t OrigAlignOffs = 27; static const uint64_t ByValSize = 0x3fffffffULL<<32; ///< Struct size @@ -60,6 +63,7 @@ namespace ISD { static const uint64_t One = 1ULL; ///< 1 of this type, for shifts uint64_t Flags; + public: ArgFlagsTy() : Flags(0) { } @@ -81,6 +85,12 @@ namespace ISD { bool isInAlloca() const { return Flags & InAlloca; } void setInAlloca() { Flags |= One << InAllocaOffs; } + bool isSwiftSelf() const { return Flags & SwiftSelf; } + void setSwiftSelf() { Flags |= One << SwiftSelfOffs; } + + bool isSwiftError() const { return Flags & SwiftError; } + void setSwiftError() { Flags |= One << SwiftErrorOffs; } + bool isNest() const { return Flags & Nest; } void setNest() { Flags |= One << NestOffs; } @@ -195,8 +205,8 @@ namespace ISD { ArgVT = argvt; } }; -} +} // end namespace ISD } // end llvm namespace -#endif +#endif // LLVM_TARGET_TARGETCALLINGCONV_H diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td index 2e766c448b34..3d8639dfe1da 100644 --- a/include/llvm/Target/TargetCallingConv.td +++ b/include/llvm/Target/TargetCallingConv.td @@ -42,6 +42,16 @@ class CCIf<string predicate, CCAction A> : CCPredicateAction<A> { class CCIfByVal<CCAction A> : CCIf<"ArgFlags.isByVal()", A> { } +/// CCIfSwiftSelf - If the current argument has swiftself parameter attribute, +/// apply Action A. +class CCIfSwiftSelf<CCAction A> : CCIf<"ArgFlags.isSwiftSelf()", A> { +} + +/// CCIfSwiftError - If the current argument has swifterror parameter attribute, +/// apply Action A. +class CCIfSwiftError<CCAction A> : CCIf<"ArgFlags.isSwiftError()", A> { +} + /// CCIfConsecutiveRegs - If the current argument has InConsecutiveRegs /// parameter attribute, apply Action A. class CCIfConsecutiveRegs<CCAction A> : CCIf<"ArgFlags.isInConsecutiveRegs()", A> { diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index cadd07d71f12..98065aca16f3 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -75,9 +75,9 @@ public: /// int alignSPAdjust(int SPAdj) const { if (SPAdj < 0) { - SPAdj = -RoundUpToAlignment(-SPAdj, StackAlignment); + SPAdj = -alignTo(-SPAdj, StackAlignment); } else { - SPAdj = RoundUpToAlignment(SPAdj, StackAlignment); + SPAdj = alignTo(SPAdj, StackAlignment); } return SPAdj; } @@ -151,6 +151,13 @@ public: return false; } + /// Returns true if the stack slot holes in the fixed and callee-save stack + /// area should be used when allocating other stack locations to reduce stack + /// size. + virtual bool enableStackSlotScavenging(const MachineFunction &MF) const { + return false; + } + /// emitProlog/emitEpilog - These methods insert prolog and epilog code into /// the function. virtual void emitPrologue(MachineFunction &MF, @@ -239,15 +246,17 @@ public: virtual int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const; - /// Same as above, except that the 'base register' will always be RSP, not - /// RBP on x86. This is generally used for emitting statepoint or EH tables - /// that use offsets from RSP. - /// TODO: This should really be a parameterizable choice. - virtual int getFrameIndexReferenceFromSP(const MachineFunction &MF, int FI, - unsigned &FrameReg) const { - // default to calling normal version, we override this on x86 only - llvm_unreachable("unimplemented for non-x86"); - return 0; + /// Same as \c getFrameIndexReference, except that the stack pointer (as + /// opposed to the frame pointer) will be the preferred value for \p + /// FrameReg. This is generally used for emitting statepoint or EH tables that + /// use offsets from RSP. If \p IgnoreSPUpdates is true, the returned + /// offset is only guaranteed to be valid with respect to the value of SP at + /// the end of the prologue. + virtual int getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, + unsigned &FrameReg, + bool IgnoreSPUpdates) const { + // Always safe to dispatch to getFrameIndexReference. + return getFrameIndexReference(MF, FI, FrameReg); } /// This method determines which of the registers reported by @@ -273,14 +282,13 @@ public: report_fatal_error("WinEH not implemented for this target"); } - /// 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 - /// for eliminating these instructions, replacing them with concrete - /// instructions. This method need only be implemented if using call frame - /// setup/destroy pseudo instructions. - /// - virtual void + /// 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 for eliminating these instructions, + /// replacing them with concrete instructions. This method need only be + /// implemented if using call frame setup/destroy pseudo instructions. + /// Returns an iterator pointing to the instruction after the replaced one. + virtual MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { @@ -288,6 +296,18 @@ public: "target!"); } + + /// Order the symbols in the local stack frame. + /// The list of objects that we want to order is in \p objectsToAllocate as + /// indices into the MachineFrameInfo. The array can be reordered in any way + /// upon return. The contents of the array, however, may not be modified (i.e. + /// only their order may be changed). + /// By default, just maintain the original order. + virtual void + orderFrameObjects(const MachineFunction &MF, + SmallVectorImpl<int> &objectsToAllocate) const { + } + /// Check whether or not the given \p MBB can be used as a prologue /// for the target. /// The prologue will be inserted first in this basic block. @@ -311,6 +331,20 @@ public: virtual bool canUseAsEpilogue(const MachineBasicBlock &MBB) const { return true; } + + /// Check if given function is safe for not having callee saved registers. + /// This is used when interprocedural register allocation is enabled. + static bool isSafeForNoCSROpt(const Function *F) { + if (!F->hasLocalLinkage() || F->hasAddressTaken() || + !F->hasFnAttribute(Attribute::NoRecurse)) + return false; + // Function should not be optimized as tail call. + for (const User *U : F->users()) + if (auto CS = ImmutableCallSite(U)) + if (CS.isTailCall()) + return false; + return true; + } }; } // End llvm namespace diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 0cebcf1c6b5d..e0b9a22ed5d0 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -21,6 +21,7 @@ #include "llvm/MC/MCInstrInfo.h" #include "llvm/Support/BranchProbability.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" namespace llvm { @@ -45,7 +46,6 @@ class DFAPacketizer; template<class T> class SmallVectorImpl; - //--------------------------------------------------------------------------- /// /// TargetInstrInfo - Interface to description of machine instruction set @@ -55,10 +55,11 @@ class TargetInstrInfo : public MCInstrInfo { void operator=(const TargetInstrInfo &) = delete; public: TargetInstrInfo(unsigned CFSetupOpcode = ~0u, unsigned CFDestroyOpcode = ~0u, - unsigned CatchRetOpcode = ~0u) + unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u) : CallFrameSetupOpcode(CFSetupOpcode), CallFrameDestroyOpcode(CFDestroyOpcode), - CatchRetOpcode(CatchRetOpcode) {} + CatchRetOpcode(CatchRetOpcode), + ReturnOpcode(ReturnOpcode) {} virtual ~TargetInstrInfo(); @@ -78,10 +79,10 @@ public: /// This means the only allowed uses are constants and unallocatable physical /// registers so that the instructions result is independent of the place /// in the function. - bool isTriviallyReMaterializable(const MachineInstr *MI, + bool isTriviallyReMaterializable(const MachineInstr &MI, AliasAnalysis *AA = nullptr) const { - return MI->getOpcode() == TargetOpcode::IMPLICIT_DEF || - (MI->getDesc().isRematerializable() && + return MI.getOpcode() == TargetOpcode::IMPLICIT_DEF || + (MI.getDesc().isRematerializable() && (isReallyTriviallyReMaterializable(MI, AA) || isReallyTriviallyReMaterializableGeneric(MI, AA))); } @@ -94,7 +95,7 @@ protected: /// than producing a value, or if it requres any address registers that are /// not always available. /// Requirements must be check as stated in isTriviallyReMaterializable() . - virtual bool isReallyTriviallyReMaterializable(const MachineInstr *MI, + virtual bool isReallyTriviallyReMaterializable(const MachineInstr &MI, AliasAnalysis *AA) const { return false; } @@ -114,8 +115,7 @@ protected: /// Do not call this method for a non-commutable instruction. /// Even though the instruction is commutable, the method may still /// fail to commute the operands, null pointer is returned in such cases. - virtual MachineInstr *commuteInstructionImpl(MachineInstr *MI, - bool NewMI, + virtual MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const; @@ -139,7 +139,7 @@ private: /// set and the target hook isReallyTriviallyReMaterializable returns false, /// this function does target-independent tests to determine if the /// instruction is really trivially rematerializable. - bool isReallyTriviallyReMaterializableGeneric(const MachineInstr *MI, + bool isReallyTriviallyReMaterializableGeneric(const MachineInstr &MI, AliasAnalysis *AA) const; public: @@ -152,12 +152,13 @@ public: unsigned getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; } unsigned getCatchReturnOpcode() const { return CatchRetOpcode; } + unsigned getReturnOpcode() const { return ReturnOpcode; } /// Returns the actual stack pointer adjustment made by an instruction /// as part of a call sequence. By default, only call frame setup/destroy /// instructions adjust the stack, but targets may want to override this /// to enable more fine-grained adjustment, or adjust by a different value. - virtual int getSPAdjust(const MachineInstr *MI) const; + virtual int getSPAdjust(const MachineInstr &MI) const; /// 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 @@ -175,14 +176,14 @@ public: /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + virtual unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const { return 0; } /// Check for post-frame ptr elimination stack locations as well. /// This uses a heuristic so it isn't reliable for correctness. - virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI, + virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const { return 0; } @@ -193,7 +194,7 @@ public: /// If not, return false. Unlike isLoadFromStackSlot, this returns true for /// any instructions that loads from the stack. This is just a hint, as some /// cases may be missed. - virtual bool hasLoadFromStackSlot(const MachineInstr *MI, + virtual bool hasLoadFromStackSlot(const MachineInstr &MI, const MachineMemOperand *&MMO, int &FrameIndex) const; @@ -202,14 +203,14 @@ public: /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + virtual unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const { return 0; } /// Check for post-frame ptr elimination stack locations as well. /// This uses a heuristic, so it isn't reliable for correctness. - virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI, + virtual unsigned isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const { return 0; } @@ -220,14 +221,14 @@ public: /// If not, return false. Unlike isStoreToStackSlot, /// this returns true for any instructions that stores to the /// stack. This is just a hint, as some cases may be missed. - virtual bool hasStoreToStackSlot(const MachineInstr *MI, + virtual bool hasStoreToStackSlot(const MachineInstr &MI, const MachineMemOperand *&MMO, int &FrameIndex) const; /// Return true if the specified machine instruction /// is a copy of one stack slot to another and has no other effect. /// Provide the identity of the two frame indices. - virtual bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex, + virtual bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex, int &SrcFrameIndex) const { return false; } @@ -253,8 +254,20 @@ public: /// /// Targets for different archs need to override this, and different /// micro-architectures can also be finely tuned inside. - virtual bool isAsCheapAsAMove(const MachineInstr *MI) const { - return MI->isAsCheapAsAMove(); + virtual bool isAsCheapAsAMove(const MachineInstr &MI) const { + return MI.isAsCheapAsAMove(); + } + + /// Return true if the instruction should be sunk by MachineSink. + /// + /// MachineSink determines on its own whether the instruction is safe to sink; + /// this gives the target a hook to override the default behavior with regards + /// to which instructions should be sunk. + /// The default behavior is to not sink insert_subreg, subreg_to_reg, and + /// reg_sequence. These are meant to be close to the source to make it easier + /// to coalesce. + virtual bool shouldSink(const MachineInstr &MI) const { + return !MI.isInsertSubreg() && !MI.isSubregToReg() && !MI.isRegSequence(); } /// Re-issue the specified 'original' instruction at the @@ -263,9 +276,8 @@ public: /// 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, + MachineBasicBlock::iterator MI, unsigned DestReg, + unsigned SubIdx, const MachineInstr &Orig, const TargetRegisterInfo &TRI) const; /// Create a duplicate of the Orig instruction in MF. This is like @@ -273,7 +285,7 @@ public: /// that are required to be unique. /// /// The instruction must be duplicable as indicated by isNotDuplicable(). - virtual MachineInstr *duplicate(MachineInstr *Orig, + virtual MachineInstr *duplicate(MachineInstr &Orig, MachineFunction &MF) const; /// This method must be implemented by targets that @@ -286,9 +298,9 @@ public: /// This method returns a null pointer if the transformation cannot be /// performed, otherwise it returns the last new instruction. /// - virtual MachineInstr * - convertToThreeAddress(MachineFunction::iterator &MFI, - MachineBasicBlock::iterator &MBBI, LiveVariables *LV) const { + virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, + MachineInstr &MI, + LiveVariables *LV) const { return nullptr; } @@ -315,8 +327,7 @@ public: /// Even though the instruction is commutable, the method may still /// fail to commute the operands, null pointer is returned in such cases. MachineInstr * - commuteInstruction(MachineInstr *MI, - bool NewMI = false, + commuteInstruction(MachineInstr &MI, bool NewMI = false, unsigned OpIdx1 = CommuteAnyOperandIndex, unsigned OpIdx2 = CommuteAnyOperandIndex) const; @@ -337,7 +348,7 @@ public: /// findCommutedOpIndices(MI, Op1, Op2); /// can be interpreted as a query asking to find an operand that would be /// commutable with the operand#1. - virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, + virtual bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const; /// A pair composed of a register and a sub-register index. @@ -424,8 +435,8 @@ public: /// are deemed identical except for defs. If this function is called when the /// IR is still in SSA form, the caller can pass the MachineRegisterInfo for /// aggressive checks. - virtual bool produceSameValue(const MachineInstr *MI0, - const MachineInstr *MI1, + virtual bool produceSameValue(const MachineInstr &MI0, + const MachineInstr &MI1, const MachineRegisterInfo *MRI = nullptr) const; /// Analyze the branching code at the end of MBB, returning @@ -453,7 +464,9 @@ public: /// If AllowModify is true, then this routine is allowed to modify the basic /// block (e.g. delete instructions after the unconditional branch). /// - virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, + /// The CFG information in MBB.Predecessors and MBB.Successors must be valid + /// before calling this function. + virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify = false) const { @@ -499,7 +512,7 @@ public: /// If AllowModify is true, then this routine is allowed to modify the basic /// block (e.g. delete instructions after the unconditional branch). /// - virtual bool AnalyzeBranchPredicate(MachineBasicBlock &MBB, + virtual bool analyzeBranchPredicate(MachineBasicBlock &MBB, MachineBranchPredicate &MBP, bool AllowModify = false) const { return true; @@ -522,10 +535,13 @@ public: /// cases where AnalyzeBranch doesn't apply because there was no original /// branch to analyze. At least this much must be implemented, else tail /// merging needs to be disabled. + /// + /// The CFG information in MBB.Predecessors and MBB.Successors must be valid + /// before calling this function. virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, - DebugLoc DL) const { + const DebugLoc &DL) const { llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch!"); } @@ -672,7 +688,7 @@ public: /// @param TrueReg Virtual register to copy when Cond is true. /// @param FalseReg Virtual register to copy when Cons is false. virtual void insertSelect(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, DebugLoc DL, + MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DstReg, ArrayRef<MachineOperand> Cond, unsigned TrueReg, unsigned FalseReg) const { llvm_unreachable("Target didn't implement TargetInstrInfo::insertSelect!"); @@ -696,11 +712,11 @@ public: /// @param FalseOp Operand number of the value selected when Cond is false. /// @param Optimizable Returned as true if MI is optimizable. /// @returns False on success. - virtual bool analyzeSelect(const MachineInstr *MI, + virtual bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const { - assert(MI && MI->getDesc().isSelect() && "MI must be a select instruction"); + assert(MI.getDesc().isSelect() && "MI must be a select instruction"); return true; } @@ -719,7 +735,7 @@ public: /// MI. Has to be updated with any newly created MI or deleted ones. /// @param PreferFalse Try to optimize FalseOp instead of TrueOp. /// @returns Optimized instruction or NULL. - virtual MachineInstr *optimizeSelect(MachineInstr *MI, + virtual MachineInstr *optimizeSelect(MachineInstr &MI, SmallPtrSetImpl<MachineInstr *> &NewMIs, bool PreferFalse = false) const { // This function must be implemented if Optimizable is ever set. @@ -735,7 +751,7 @@ public: /// careful implementation when multiple copy instructions are required for /// large registers. See for example the ARM target. virtual void copyPhysReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, DebugLoc DL, + MachineBasicBlock::iterator MI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const { llvm_unreachable("Target didn't implement TargetInstrInfo::copyPhysReg!"); @@ -772,9 +788,7 @@ public: /// into real instructions. The target can edit MI in place, or it can insert /// new instructions and erase MI. The function should return true if /// anything was changed. - virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const { - return false; - } + virtual bool expandPostRAPseudo(MachineInstr &MI) const { return false; } /// Attempt to fold a load or store of the specified stack /// slot into the specified machine instruction for the specified operand(s). @@ -782,14 +796,15 @@ public: /// 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, - ArrayRef<unsigned> Ops, int FrameIndex) const; + MachineInstr *foldMemoryOperand(MachineInstr &MI, ArrayRef<unsigned> Ops, + int FrameIndex, + LiveIntervals *LIS = nullptr) const; /// 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(MachineBasicBlock::iterator MI, - ArrayRef<unsigned> Ops, - MachineInstr *LoadMI) const; + MachineInstr *foldMemoryOperand(MachineInstr &MI, ArrayRef<unsigned> Ops, + MachineInstr &LoadMI, + LiveIntervals *LIS = nullptr) const; /// Return true when there is potentially a faster code sequence /// for an instruction chain ending in \p Root. All potential patterns are @@ -802,6 +817,11 @@ public: MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns) const; + /// Return true when a code sequence can improve throughput. It + /// should be called only for instructions in loops. + /// \param Pattern - combiner pattern + virtual bool isThroughputPattern(MachineCombinerPattern Pattern) const; + /// Return true if the input \P Inst is part of a chain of dependent ops /// that are suitable for reassociation, otherwise return false. /// If the instruction's operands must be commuted to have a previous @@ -850,8 +870,7 @@ public: virtual void setSpecialOperandAttr(MachineInstr &OldMI1, MachineInstr &OldMI2, MachineInstr &NewMI1, MachineInstr &NewMI2) const { - return; - }; + } /// Return true when a target supports MachineCombiner. virtual bool useMachineCombiner() const { return false; } @@ -862,9 +881,11 @@ protected: /// take care of adding a MachineMemOperand to the newly created instruction. /// The instruction and any auxiliary instructions necessary will be inserted /// at InsertPt. - virtual MachineInstr *foldMemoryOperandImpl( - MachineFunction &MF, MachineInstr *MI, ArrayRef<unsigned> Ops, - MachineBasicBlock::iterator InsertPt, int FrameIndex) const { + virtual MachineInstr * + foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, + ArrayRef<unsigned> Ops, + MachineBasicBlock::iterator InsertPt, int FrameIndex, + LiveIntervals *LIS = nullptr) const { return nullptr; } @@ -874,8 +895,9 @@ protected: /// The instruction and any auxiliary instructions necessary will be inserted /// at InsertPt. virtual MachineInstr *foldMemoryOperandImpl( - MachineFunction &MF, MachineInstr *MI, ArrayRef<unsigned> Ops, - MachineBasicBlock::iterator InsertPt, MachineInstr *LoadMI) const { + MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops, + MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI, + LiveIntervals *LIS = nullptr) const { return nullptr; } @@ -926,9 +948,10 @@ public: /// 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 /// possible, returns true as well as the new instructions by reference. - virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, - unsigned Reg, bool UnfoldLoad, bool UnfoldStore, - SmallVectorImpl<MachineInstr*> &NewMIs) const{ + virtual bool + unfoldMemoryOperand(MachineFunction &MF, MachineInstr &MI, unsigned Reg, + bool UnfoldLoad, bool UnfoldStore, + SmallVectorImpl<MachineInstr *> &NewMIs) const { return false; } @@ -974,24 +997,26 @@ public: /// Get the base register and byte offset of an instruction that reads/writes /// memory. - virtual bool getMemOpBaseRegImmOfs(MachineInstr *MemOp, unsigned &BaseReg, - unsigned &Offset, + virtual bool getMemOpBaseRegImmOfs(MachineInstr &MemOp, unsigned &BaseReg, + int64_t &Offset, const TargetRegisterInfo *TRI) const { return false; } virtual bool enableClusterLoads() const { return false; } - virtual bool shouldClusterLoads(MachineInstr *FirstLdSt, - MachineInstr *SecondLdSt, - unsigned NumLoads) const { + virtual bool enableClusterStores() const { return false; } + + virtual bool shouldClusterMemOps(MachineInstr &FirstLdSt, + MachineInstr &SecondLdSt, + unsigned NumLoads) const { return false; } /// Can this target fuse the given instructions if they are scheduled /// adjacent. - virtual bool shouldScheduleAdjacent(MachineInstr* First, - MachineInstr *Second) const { + virtual bool shouldScheduleAdjacent(MachineInstr &First, + MachineInstr &Second) const { return false; } @@ -1012,19 +1037,18 @@ public: /// Returns true if the instruction is already predicated. - virtual bool isPredicated(const MachineInstr *MI) const { + virtual bool isPredicated(const MachineInstr &MI) const { return false; } /// Returns true if the instruction is a /// terminator instruction that has not been predicated. - virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; + virtual bool isUnpredicatedTerminator(const MachineInstr &MI) const; /// Convert the instruction into a predicated instruction. /// It returns true if the operation was successful. - virtual - bool PredicateInstruction(MachineInstr *MI, - ArrayRef<MachineOperand> Pred) const; + virtual bool PredicateInstruction(MachineInstr &MI, + ArrayRef<MachineOperand> Pred) const; /// Returns true if the first specified predicate /// subsumes the second, e.g. GE subsumes GT. @@ -1037,7 +1061,7 @@ public: /// If the specified instruction defines any predicate /// or condition code register(s) used for predication, returns true as well /// as the definition predicate(s) by reference. - virtual bool DefinesPredicate(MachineInstr *MI, + virtual bool DefinesPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred) const { return false; } @@ -1045,8 +1069,8 @@ public: /// Return true if the specified instruction can be predicated. /// By default, this returns true for every instruction with a /// PredicateOperand. - virtual bool isPredicable(MachineInstr *MI) const { - return MI->getDesc().isPredicable(); + virtual bool isPredicable(MachineInstr &MI) const { + return MI.getDesc().isPredicable(); } /// Return true if it's safe to move a machine @@ -1057,7 +1081,7 @@ public: /// Test if the given instruction should be considered a scheduling boundary. /// This primarily includes labels and terminators. - virtual bool isSchedulingBoundary(const MachineInstr *MI, + virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const; @@ -1084,6 +1108,13 @@ public: CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, const ScheduleDAG *DAG) const; + /// Allocate and return a hazard recognizer to use for by non-scheduling + /// passes. + virtual ScheduleHazardRecognizer* + CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const { + return nullptr; + } + /// Provide a global flag for disabling the PreRA hazard recognizer that /// targets may choose to honor. bool usePreRAHazardRecognizer() const; @@ -1092,22 +1123,20 @@ public: /// in SrcReg and SrcReg2 if having two register operands, and the value it /// compares against in CmpValue. Return true if the comparison instruction /// can be analyzed. - virtual bool analyzeCompare(const MachineInstr *MI, - unsigned &SrcReg, unsigned &SrcReg2, - int &Mask, int &Value) const { + virtual bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, + unsigned &SrcReg2, int &Mask, int &Value) const { return false; } /// See if the comparison instruction can be converted /// into something more efficient. E.g., on ARM most instructions can set the /// flags register, obviating the need for a separate CMP. - virtual bool optimizeCompareInstr(MachineInstr *CmpInstr, - unsigned SrcReg, unsigned SrcReg2, - int Mask, int Value, + virtual bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, + unsigned SrcReg2, int Mask, int Value, const MachineRegisterInfo *MRI) const { return false; } - virtual bool optimizeCondBranch(MachineInstr *MI) const { return false; } + virtual bool optimizeCondBranch(MachineInstr &MI) const { return false; } /// Try to remove the load by folding it to a register operand at the use. /// We fold the load instructions if and only if the @@ -1116,10 +1145,10 @@ public: /// defined by the load we are trying to fold. DefMI returns the machine /// instruction that defines FoldAsLoadDefReg, and the function returns /// the machine instruction generated due to folding. - virtual MachineInstr* optimizeLoadInstr(MachineInstr *MI, - const MachineRegisterInfo *MRI, - unsigned &FoldAsLoadDefReg, - MachineInstr *&DefMI) const { + virtual MachineInstr *optimizeLoadInstr(MachineInstr &MI, + const MachineRegisterInfo *MRI, + unsigned &FoldAsLoadDefReg, + MachineInstr *&DefMI) const { return nullptr; } @@ -1129,7 +1158,7 @@ public: /// then the caller may assume that DefMI has been erased from its parent /// block. The caller may assume that it will not be erased by this /// function otherwise. - virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, + virtual bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg, MachineRegisterInfo *MRI) const { return false; } @@ -1139,7 +1168,7 @@ public: /// IssueWidth is the number of microops that can be dispatched each /// cycle. An instruction with zero microops takes no dispatch resources. virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, - const MachineInstr *MI) const; + const MachineInstr &MI) const; /// Return true for pseudo instructions that don't consume any /// machine resources in their current form. These are common cases that the @@ -1162,35 +1191,44 @@ public: /// by a target. Use computeOperandLatency to get the best estimate of /// latency. virtual int getOperandLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI, unsigned DefIdx, - const MachineInstr *UseMI, + const MachineInstr &DefMI, unsigned DefIdx, + const MachineInstr &UseMI, unsigned UseIdx) const; - /// Compute and return the latency of the given data - /// dependent def and use when the operand indices are already known. + /// Compute and return the latency of the given data dependent def and use + /// when the operand indices are already known. UseMI may be \c nullptr for + /// an unknown use. + /// + /// FindMin may be set to get the minimum vs. expected latency. Minimum + /// latency is used for scheduling groups, while expected latency is for + /// instruction cost and critical path. + /// + /// Depending on the subtarget's itinerary properties, this may or may not + /// need to call getOperandLatency(). For most subtargets, we don't need + /// DefIdx or UseIdx to compute min latency. unsigned computeOperandLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI, unsigned DefIdx, - const MachineInstr *UseMI, unsigned UseIdx) - const; + const MachineInstr &DefMI, unsigned DefIdx, + const MachineInstr *UseMI, + unsigned UseIdx) const; /// Compute the instruction latency of a given instruction. /// If the instruction has higher cost when predicated, it's returned via /// PredCost. virtual unsigned getInstrLatency(const InstrItineraryData *ItinData, - const MachineInstr *MI, + const MachineInstr &MI, unsigned *PredCost = nullptr) const; - virtual unsigned getPredicationCost(const MachineInstr *MI) const; + virtual unsigned getPredicationCost(const MachineInstr &MI) const; virtual int getInstrLatency(const InstrItineraryData *ItinData, SDNode *Node) const; - /// Return the default expected latency for a def based on it's opcode. + /// Return the default expected latency for a def based on its opcode. unsigned defaultDefLatency(const MCSchedModel &SchedModel, - const MachineInstr *DefMI) const; + const MachineInstr &DefMI) const; int computeDefOperandLatency(const InstrItineraryData *ItinData, - const MachineInstr *DefMI) const; + const MachineInstr &DefMI) const; /// Return true if this opcode has high latency to its result. virtual bool isHighLatencyDef(int opc) const { return false; } @@ -1200,23 +1238,23 @@ public: /// it 'high'. This is used by optimization passes such as machine LICM to /// determine whether it makes sense to hoist an instruction out even in a /// high register pressure situation. - virtual - bool hasHighOperandLatency(const TargetSchedModel &SchedModel, - const MachineRegisterInfo *MRI, - const MachineInstr *DefMI, unsigned DefIdx, - const MachineInstr *UseMI, unsigned UseIdx) const { + virtual bool hasHighOperandLatency(const TargetSchedModel &SchedModel, + const MachineRegisterInfo *MRI, + const MachineInstr &DefMI, unsigned DefIdx, + const MachineInstr &UseMI, + unsigned UseIdx) const { return false; } /// Compute operand latency of a def of 'Reg'. Return true /// if the target considered it 'low'. - virtual - bool hasLowDefLatency(const TargetSchedModel &SchedModel, - const MachineInstr *DefMI, unsigned DefIdx) const; + virtual bool hasLowDefLatency(const TargetSchedModel &SchedModel, + const MachineInstr &DefMI, + unsigned DefIdx) const; /// Perform target-specific instruction verification. - virtual - bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const { + virtual bool verifyInstruction(const MachineInstr &MI, + StringRef &ErrInfo) const { return true; } @@ -1240,7 +1278,7 @@ public: /// execution domain. /// virtual std::pair<uint16_t, uint16_t> - getExecutionDomain(const MachineInstr *MI) const { + getExecutionDomain(const MachineInstr &MI) const { return std::make_pair(0, 0); } @@ -1248,8 +1286,7 @@ public: /// /// The bit (1 << Domain) must be set in the mask returned from /// getExecutionDomain(MI). - virtual void setExecutionDomain(MachineInstr *MI, unsigned Domain) const {} - + virtual void setExecutionDomain(MachineInstr &MI, unsigned Domain) const {} /// Returns the preferred minimum clearance /// before an instruction with an unwanted partial register update. @@ -1291,7 +1328,7 @@ public: /// allows the target to insert a dependency breaking instruction. /// virtual unsigned - getPartialRegUpdateClearance(const MachineInstr *MI, unsigned OpNum, + getPartialRegUpdateClearance(const MachineInstr &MI, unsigned OpNum, const TargetRegisterInfo *TRI) const { // The default implementation returns 0 for no partial register dependency. return 0; @@ -1311,7 +1348,7 @@ public: /// This hook works similarly to getPartialRegUpdateClearance, except that it /// does not take an operand index. Instead sets \p OpNum to the index of the /// unused register. - virtual unsigned getUndefRegClearance(const MachineInstr *MI, unsigned &OpNum, + virtual unsigned getUndefRegClearance(const MachineInstr &MI, unsigned &OpNum, const TargetRegisterInfo *TRI) const { // The default implementation returns 0 for no undef register dependency. return 0; @@ -1334,9 +1371,8 @@ public: /// An <imp-kill> operand should be added to MI if an instruction was /// inserted. This ties the instructions together in the post-ra scheduler. /// - virtual void - breakPartialRegDependency(MachineBasicBlock::iterator MI, unsigned OpNum, - const TargetRegisterInfo *TRI) const {} + virtual void breakPartialRegDependency(MachineInstr &MI, unsigned OpNum, + const TargetRegisterInfo *TRI) const {} /// Create machine specific model for scheduling. virtual DFAPacketizer * @@ -1349,11 +1385,11 @@ public: // memory addresses. This function returns true if two MIs access different // memory addresses and false otherwise. virtual bool - areMemAccessesTriviallyDisjoint(MachineInstr *MIa, MachineInstr *MIb, + areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb, AliasAnalysis *AA = nullptr) const { - assert(MIa && (MIa->mayLoad() || MIa->mayStore()) && + assert((MIa.mayLoad() || MIa.mayStore()) && "MIa must load from or modify a memory location"); - assert(MIb && (MIb->mayLoad() || MIb->mayStore()) && + assert((MIb.mayLoad() || MIb.mayStore()) && "MIb must load from or modify a memory location"); return false; } @@ -1406,6 +1442,7 @@ public: private: unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode; unsigned CatchRetOpcode; + unsigned ReturnOpcode; }; /// \brief Provide DenseMapInfo for TargetInstrInfo::RegSubRegPair. @@ -1435,6 +1472,6 @@ struct DenseMapInfo<TargetInstrInfo::RegSubRegPair> { } }; -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_TARGET_TARGETINSTRINFO_H diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 304da4f87519..d21d3215860e 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -41,8 +41,10 @@ #include <vector> namespace llvm { + class BranchProbability; class CallInst; class CCState; + class CCValAssign; class FastISel; class FunctionLoweringInfo; class ImmutableCallSite; @@ -52,6 +54,7 @@ namespace llvm { class MachineInstr; class MachineJumpTableInfo; class MachineLoop; + class MachineRegisterInfo; class Mangler; class MCContext; class MCExpr; @@ -235,6 +238,11 @@ public: return false; } + /// Return true if the target can handle a standalone remainder operation. + virtual bool hasStandaloneRem(EVT VT) const { + return true; + } + /// Return true if sqrt(x) is as cheap or cheaper than 1 / rsqrt(x) bool isFsqrtCheap() const { return FsqrtIsCheap; @@ -259,18 +267,41 @@ public: return PredictableSelectIsExpensive; } - /// isLoadBitCastBeneficial() - Return true if the following transform - /// is beneficial. + /// If a branch or a select condition is skewed in one direction by more than + /// this factor, it is very likely to be predicted correctly. + virtual BranchProbability getPredictableBranchThreshold() const; + + /// Return true if the following transform is beneficial: /// fold (conv (load x)) -> (load (conv*)x) /// On architectures that don't natively support some vector loads /// efficiently, casting the load to a smaller vector of larger types and /// loading is more efficient, however, this can be undone by optimizations in /// dag combiner. - virtual bool isLoadBitCastBeneficial(EVT /* Load */, - EVT /* Bitcast */) const { + virtual bool isLoadBitCastBeneficial(EVT LoadVT, + EVT BitcastVT) const { + // Don't do if we could do an indexed load on the original type, but not on + // the new one. + if (!LoadVT.isSimple() || !BitcastVT.isSimple()) + return true; + + MVT LoadMVT = LoadVT.getSimpleVT(); + + // Don't bother doing this if it's just going to be promoted again later, as + // doing so might interfere with other combines. + if (getOperationAction(ISD::LOAD, LoadMVT) == Promote && + getTypeToPromoteTo(ISD::LOAD, LoadMVT) == BitcastVT.getSimpleVT()) + return false; + return true; } + /// Return true if the following transform is beneficial: + /// (store (y (conv x)), y*)) -> (store x, (x*)) + virtual bool isStoreBitCastBeneficial(EVT StoreVT, EVT BitcastVT) const { + // Default to the same logic as loads. + return isLoadBitCastBeneficial(StoreVT, BitcastVT); + } + /// Return true if it is expected to be cheaper to do a store of a non-zero /// vector constant with the given size and type for the address space than to /// store the individual scalar element constants. @@ -290,6 +321,14 @@ public: return false; } + /// Return true if it is safe to transform an integer-domain bitwise operation + /// into the equivalent floating-point operation. This should be set to true + /// if the target has IEEE-754-compliant fabs/fneg operations for the input + /// type. + virtual bool hasBitPreservingFPLogic(EVT VT) const { + return false; + } + /// \brief Return if the target supports combining a /// chain like: /// \code @@ -305,6 +344,22 @@ public: return MaskAndBranchFoldingIsLegal; } + /// Return true if the target should transform: + /// (X & Y) == Y ---> (~X & Y) == 0 + /// (X & Y) != Y ---> (~X & Y) != 0 + /// + /// This may be profitable if the target has a bitwise and-not operation that + /// sets comparison flags. A target may want to limit the transformation based + /// on the type of Y or if Y is a constant. + /// + /// Note that the transform will not occur if Y is known to be a power-of-2 + /// because a mask and compare of a single bit can be handled by inverting the + /// predicate, for example: + /// (X & 8) == 8 ---> (X & 8) != 0 + virtual bool hasAndNotCompare(SDValue Y) const { + return false; + } + /// \brief Return true if the target wants to use the optimization that /// turns ext(promotableInst1(...(promotableInstN(load)))) into /// promotedInst1(...(promotedInstN(ext(load)))). @@ -571,6 +626,23 @@ public: getOperationAction(Op, VT) == Promote); } + /// Return true if the specified operation is legal on this target or can be + /// made legal with custom lowering or using promotion. This is used to help + /// guide high-level lowering decisions. + bool isOperationLegalOrCustomOrPromote(unsigned Op, EVT VT) const { + return (VT == MVT::Other || isTypeLegal(VT)) && + (getOperationAction(Op, VT) == Legal || + getOperationAction(Op, VT) == Custom || + getOperationAction(Op, VT) == Promote); + } + + /// Return true if the specified operation is illegal but has a custom lowering + /// on that type. This is used to help guide high-level lowering + /// decisions. + bool isOperationCustom(unsigned Op, EVT VT) const { + return (!isTypeLegal(VT) && getOperationAction(Op, VT) == Custom); + } + /// Return true if the specified operation is illegal on this target or /// unlikely to be made legal with custom lowering. This is used to help guide /// high-level lowering decisions. @@ -594,21 +666,20 @@ public: unsigned MemI = (unsigned) MemVT.getSimpleVT().SimpleTy; assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValI < MVT::LAST_VALUETYPE && MemI < MVT::LAST_VALUETYPE && "Table isn't big enough!"); - return LoadExtActions[ValI][MemI][ExtType]; + unsigned Shift = 4 * ExtType; + return (LegalizeAction)((LoadExtActions[ValI][MemI] >> Shift) & 0xf); } /// Return true if the specified load with extension is legal on this target. bool isLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const { - return ValVT.isSimple() && MemVT.isSimple() && - getLoadExtAction(ExtType, ValVT, MemVT) == Legal; + return getLoadExtAction(ExtType, ValVT, MemVT) == Legal; } /// Return true if the specified load with extension is legal or custom /// on this target. bool isLoadExtLegalOrCustom(unsigned ExtType, EVT ValVT, EVT MemVT) const { - return ValVT.isSimple() && MemVT.isSimple() && - (getLoadExtAction(ExtType, ValVT, MemVT) == Legal || - getLoadExtAction(ExtType, ValVT, MemVT) == Custom); + return getLoadExtAction(ExtType, ValVT, MemVT) == Legal || + getLoadExtAction(ExtType, ValVT, MemVT) == Custom; } /// Return how this store with truncation should be treated: either it is @@ -626,8 +697,15 @@ public: /// Return true if the specified store with truncation is legal on this /// target. bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const { - return isTypeLegal(ValVT) && MemVT.isSimple() && - getTruncStoreAction(ValVT.getSimpleVT(), MemVT.getSimpleVT()) == Legal; + return isTypeLegal(ValVT) && getTruncStoreAction(ValVT, MemVT) == Legal; + } + + /// Return true if the specified store with truncation has solution on this + /// target. + bool isTruncStoreLegalOrCustom(EVT ValVT, EVT MemVT) const { + return isTypeLegal(ValVT) && + (getTruncStoreAction(ValVT, MemVT) == Legal || + getTruncStoreAction(ValVT, MemVT) == Custom); } /// Return how the indexed load should be treated: either it is legal, needs @@ -672,7 +750,7 @@ public: LegalizeAction getCondCodeAction(ISD::CondCode CC, MVT VT) const { assert((unsigned)CC < array_lengthof(CondCodeActions) && - ((unsigned)VT.SimpleTy >> 4) < array_lengthof(CondCodeActions[0]) && + ((unsigned)VT.SimpleTy >> 3) < array_lengthof(CondCodeActions[0]) && "Table isn't big enough!"); // See setCondCodeAction for how this is encoded. uint32_t Shift = 4 * (VT.SimpleTy & 0x7); @@ -960,6 +1038,10 @@ public: return 0; } + virtual bool needsFixedCatchObjects() const { + report_fatal_error("Funclet EH is not implemented for this target"); + } + /// Returns the target's jmp_buf size in bytes (if never set, the default is /// 200) unsigned getJumpBufSize() const { @@ -992,19 +1074,26 @@ public: return PrefLoopAlignment; } - /// Return whether the DAG builder should automatically insert fences and - /// reduce ordering for atomics. - bool getInsertFencesForAtomic() const { - return InsertFencesForAtomic; - } + /// If the target has a standard location for the stack protector guard, + /// returns the address of that location. Otherwise, returns nullptr. + /// DEPRECATED: please override useLoadStackGuardNode and customize + /// LOAD_STACK_GUARD, or customize @llvm.stackguard(). + virtual Value *getIRStackGuard(IRBuilder<> &IRB) const; - /// 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; - } + /// Inserts necessary declarations for SSP (stack protection) purpose. + /// Should be used only when getIRStackGuard returns nullptr. + virtual void insertSSPDeclarations(Module &M) const; + + /// Return the variable that's previously inserted by insertSSPDeclarations, + /// if any, otherwise return nullptr. Should be used only when + /// getIRStackGuard returns nullptr. + virtual Value *getSDagStackGuard(const Module &M) const; + + /// If the target has a standard stack protection check function that + /// performs validation and error handling, returns the function. Otherwise, + /// returns nullptr. Must be previously inserted by insertSSPDeclarations. + /// Should be used only when getIRStackGuard returns nullptr. + virtual Value *getSSPStackGuardCheck(const Module &M) const; /// If the target has a standard location for the unsafe stack pointer, /// returns the address of that location. Otherwise, returns nullptr. @@ -1041,6 +1130,30 @@ public: /// \name Helpers for atomic expansion. /// @{ + /// Returns the maximum atomic operation size (in bits) supported by + /// the backend. Atomic operations greater than this size (as well + /// as ones that are not naturally aligned), will be expanded by + /// AtomicExpandPass into an __atomic_* library call. + unsigned getMaxAtomicSizeInBitsSupported() const { + return MaxAtomicSizeInBitsSupported; + } + + /// Returns the size of the smallest cmpxchg or ll/sc instruction + /// the backend supports. Any smaller operations are widened in + /// AtomicExpandPass. + /// + /// Note that *unlike* operations above the maximum size, atomic ops + /// are still natively supported below the minimum; they just + /// require a more complex expansion. + unsigned getMinCmpXchgSizeInBits() const { return MinCmpXchgSizeInBits; } + + /// Whether AtomicExpandPass should automatically insert fences and reduce + /// ordering for this atomic. This should be true for most architectures with + /// weak memory ordering. Defaults to false. + virtual bool shouldInsertFencesForAtomic(const Instruction *I) const { + return false; + } + /// Perform a load-linked operation on Addr, returning a "Value *" with the /// corresponding pointee type. This may entail some non-trivial operations to /// truncate or reconstruct types that will be illegal in the backend. See @@ -1059,12 +1172,12 @@ public: /// Inserts in the IR a target-specific intrinsic specifying a fence. /// It is called by AtomicExpandPass before expanding an - /// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad. + /// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad + /// if shouldInsertFencesForAtomic returns true. /// RMW and CmpXchg set both IsStore and IsLoad to true. /// This function should either return a nullptr, or a pointer to an IR-level /// Instruction*. Even complex fence sequences can be represented by a /// single Instruction* through an intrinsic to be lowered later. - /// Backends with !getInsertFencesForAtomic() should keep a no-op here. /// Backends should override this method to produce target-specific intrinsic /// for their fences. /// FIXME: Please note that the default implementation here in terms of @@ -1090,10 +1203,7 @@ public: virtual Instruction *emitLeadingFence(IRBuilder<> &Builder, AtomicOrdering Ord, bool IsStore, bool IsLoad) const { - if (!getInsertFencesForAtomic()) - return nullptr; - - if (isAtLeastRelease(Ord) && IsStore) + if (isReleaseOrStronger(Ord) && IsStore) return Builder.CreateFence(Ord); else return nullptr; @@ -1102,10 +1212,7 @@ public: virtual Instruction *emitTrailingFence(IRBuilder<> &Builder, AtomicOrdering Ord, bool IsStore, bool IsLoad) const { - if (!getInsertFencesForAtomic()) - return nullptr; - - if (isAtLeastAcquire(Ord)) + if (isAcquireOrStronger(Ord)) return Builder.CreateFence(Ord); else return nullptr; @@ -1166,6 +1273,14 @@ public: return nullptr; } + /// Returns how the platform's atomic operations are extended (ZERO_EXTEND, + /// SIGN_EXTEND, or ANY_EXTEND). + virtual ISD::NodeType getExtendForAtomicOps() const { + return ISD::ZERO_EXTEND; + } + + /// @} + /// Returns true if we should normalize /// select(N0&N1, X, Y) => select(N0, select(N1, X, Y), Y) and /// select(N0|N1, X, Y) => select(N0, select(N1, X, Y, Y)) if it is likely @@ -1324,7 +1439,10 @@ protected: LegalizeAction Action) { assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValVT.isValid() && MemVT.isValid() && "Table isn't big enough!"); - LoadExtActions[(unsigned)ValVT.SimpleTy][MemVT.SimpleTy][ExtType] = Action; + assert((unsigned)Action < 0x10 && "too many bits for bitfield array"); + unsigned Shift = 4 * ExtType; + LoadExtActions[ValVT.SimpleTy][MemVT.SimpleTy] &= ~((uint16_t)0xF << Shift); + LoadExtActions[ValVT.SimpleTy][MemVT.SimpleTy] |= (uint16_t)Action << Shift; } /// Indicate that the specified truncating store does not work with the @@ -1386,6 +1504,13 @@ protected: PromoteToType[std::make_pair(Opc, OrigVT.SimpleTy)] = DestVT.SimpleTy; } + /// Convenience method to set an operation to Promote and specify the type + /// in a single call. + void setOperationPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT) { + setOperationAction(Opc, OrigVT, Promote); + AddPromotedToType(Opc, OrigVT, DestVT); + } + /// Targets should invoke this method for each target independent node that /// they want to provide a custom DAG combiner for by implementing the /// PerformDAGCombine virtual method. @@ -1430,10 +1555,17 @@ protected: MinStackArgumentAlignment = Align; } - /// Set if the DAG builder should automatically insert fences and reduce the - /// order of atomic memory operations to Monotonic. - void setInsertFencesForAtomic(bool fence) { - InsertFencesForAtomic = fence; + /// Set the maximum atomic operation size supported by the + /// backend. Atomic operations greater than this size (as well as + /// ones that are not naturally aligned), will be expanded by + /// AtomicExpandPass into an __atomic_* library call. + void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits) { + MaxAtomicSizeInBitsSupported = SizeInBits; + } + + // Sets the minimum cmpxchg or ll/sc size supported by the backend. + void setMinCmpXchgSizeInBits(unsigned SizeInBits) { + MinCmpXchgSizeInBits = SizeInBits; } public: @@ -1845,10 +1977,13 @@ private: /// The preferred loop alignment. unsigned PrefLoopAlignment; - /// Whether the DAG builder should automatically insert fences and reduce - /// ordering for atomics. (This will be set for for most architectures with - /// weak memory ordering.) - bool InsertFencesForAtomic; + /// Size in bits of the maximum atomics size the backend supports. + /// Accesses larger than this will be expanded by AtomicExpandPass. + unsigned MaxAtomicSizeInBitsSupported; + + /// Size in bits of the minimum cmpxchg or ll/sc operation the + /// backend supports. + unsigned MinCmpXchgSizeInBits; /// If set to a physical register, this specifies the register that /// llvm.savestack/llvm.restorestack should save and restore. @@ -1889,9 +2024,9 @@ private: /// 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. - LegalizeAction LoadExtActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE] - [ISD::LAST_LOADEXT_TYPE]; + /// specific value type and extension type. Uses 4-bits to store the action + /// for each of the 4 load ext types. + uint16_t LoadExtActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE]; /// For each value type pair keep a LegalizeAction that indicates whether a /// truncating store of a specific value type and truncating type is legal. @@ -2026,7 +2161,7 @@ protected: /// Replace/modify any TargetFrameIndex operands with a targte-dependent /// sequence of memory operands that is recognized by PrologEpilogInserter. - MachineBasicBlock *emitPatchPoint(MachineInstr *MI, + MachineBasicBlock *emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const; }; @@ -2043,6 +2178,8 @@ public: /// NOTE: The TargetMachine owns TLOF. explicit TargetLowering(const TargetMachine &TM); + bool isPositionIndependent() const; + /// 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. @@ -2092,18 +2229,26 @@ public: bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const; - void softenSetCCOperands(SelectionDAG &DAG, EVT VT, - SDValue &NewLHS, SDValue &NewRHS, - ISD::CondCode &CCCode, SDLoc DL) const; + void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, + SDValue &NewRHS, ISD::CondCode &CCCode, + const SDLoc &DL) const; /// Returns a pair of (return value, chain). /// It is an error to pass RTLIB::UNKNOWN_LIBCALL as \p LC. std::pair<SDValue, SDValue> makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef<SDValue> Ops, - bool isSigned, SDLoc dl, + bool isSigned, const SDLoc &dl, bool doesNotReturn = false, bool isReturnValueUsed = true) const; + /// Check whether parameters to a call that are passed in callee saved + /// registers are the same as from the calling function. This needs to be + /// checked for tail call eligibility. + bool parametersInCSRMatch(const MachineRegisterInfo &MRI, + const uint32_t *CallerPreservedMask, + const SmallVectorImpl<CCValAssign> &ArgLocs, + const SmallVectorImpl<SDValue> &OutVals) const; + //===--------------------------------------------------------------------===// // TargetLowering Optimization Methods // @@ -2141,7 +2286,7 @@ public: /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be /// generalized for targets with other types of implicit widening casts. bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded, - SDLoc dl); + const SDLoc &dl); }; /// Look at Op. At this point, we know that only the DemandedMask bits of the @@ -2204,11 +2349,14 @@ public: /// from getBooleanContents(). bool isConstFalseVal(const SDNode *N) const; + /// Return if \p N is a True value when extended to \p VT. + bool isExtendedTrueVal(const ConstantSDNode *N, EVT VT, bool Signed) const; + /// Try to simplify a setcc built with the specified operands and cc. If it is /// unable to simplify it, return a null SDValue. - SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, - ISD::CondCode Cond, bool foldBooleans, - DAGCombinerInfo &DCI, SDLoc dl) const; + SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, + bool foldBooleans, DAGCombinerInfo &DCI, + const SDLoc &dl) const; /// Returns true (and the GlobalValue and the offset) if the node is a /// GlobalAddress + offset. @@ -2263,6 +2411,12 @@ public: return false; } + /// Return true if the target supports swifterror attribute. It optimizes + /// loads and stores to reading and writing a specific register. + virtual bool supportSwiftError() const { + return false; + } + /// Return true if the target supports that a subset of CSRs for the given /// machine function is handled explicitly via copies. virtual bool supportSplitCSR(MachineFunction *MF) const { @@ -2302,12 +2456,10 @@ public: /// should fill in the InVals array with legal-type argument values, and /// return the resulting token chain value. /// - virtual SDValue - LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, - bool /*isVarArg*/, - const SmallVectorImpl<ISD::InputArg> &/*Ins*/, - SDLoc /*dl*/, SelectionDAG &/*DAG*/, - SmallVectorImpl<SDValue> &/*InVals*/) const { + virtual SDValue LowerFormalArguments( + SDValue /*Chain*/, CallingConv::ID /*CallConv*/, bool /*isVarArg*/, + const SmallVectorImpl<ISD::InputArg> & /*Ins*/, const SDLoc & /*dl*/, + SelectionDAG & /*DAG*/, SmallVectorImpl<SDValue> & /*InVals*/) const { llvm_unreachable("Not Implemented"); } @@ -2322,11 +2474,14 @@ public: bool isByVal : 1; bool isInAlloca : 1; bool isReturned : 1; + bool isSwiftSelf : 1; + bool isSwiftError : 1; uint16_t Alignment; ArgListEntry() : isSExt(false), isZExt(false), isInReg(false), isSRet(false), isNest(false), isByVal(false), isInAlloca(false), - isReturned(false), Alignment(0) { } + isReturned(false), isSwiftSelf(false), isSwiftError(false), + Alignment(0) { } void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx); }; @@ -2345,6 +2500,7 @@ public: bool IsInReg : 1; bool DoesNotReturn : 1; bool IsReturnValueUsed : 1; + bool IsConvergent : 1; // IsTailCall should be modified by implementations of // TargetLowering::LowerCall that perform tail call conversions. @@ -2361,14 +2517,16 @@ public: SmallVector<ISD::OutputArg, 32> Outs; SmallVector<SDValue, 32> OutVals; SmallVector<ISD::InputArg, 32> Ins; + SmallVector<SDValue, 4> InVals; CallLoweringInfo(SelectionDAG &DAG) - : RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false), - IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true), - IsTailCall(false), NumFixedArgs(-1), CallConv(CallingConv::C), - DAG(DAG), CS(nullptr), IsPatchPoint(false) {} + : RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false), + IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true), + IsConvergent(false), IsTailCall(false), NumFixedArgs(-1), + CallConv(CallingConv::C), DAG(DAG), CS(nullptr), IsPatchPoint(false) { + } - CallLoweringInfo &setDebugLoc(SDLoc dl) { + CallLoweringInfo &setDebugLoc(const SDLoc &dl) { DL = dl; return *this; } @@ -2379,13 +2537,11 @@ public: } CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultType, - SDValue Target, ArgListTy &&ArgsList, - unsigned FixedArgs = -1) { + SDValue Target, ArgListTy &&ArgsList) { RetTy = ResultType; Callee = Target; CallConv = CC; - NumFixedArgs = - (FixedArgs == static_cast<unsigned>(-1) ? Args.size() : FixedArgs); + NumFixedArgs = Args.size(); Args = std::move(ArgsList); return *this; } @@ -2396,7 +2552,10 @@ public: RetTy = ResultType; IsInReg = Call.paramHasAttr(0, Attribute::InReg); - DoesNotReturn = Call.doesNotReturn(); + DoesNotReturn = + Call.doesNotReturn() || + (!Call.isInvoke() && + isa<UnreachableInst>(Call.getInstruction()->getNextNode())); IsVarArg = FTy->isVarArg(); IsReturnValueUsed = !Call.getInstruction()->use_empty(); RetSExt = Call.paramHasAttr(0, Attribute::SExt); @@ -2438,6 +2597,11 @@ public: return *this; } + CallLoweringInfo &setConvergent(bool Value = true) { + IsConvergent = Value; + return *this; + } + CallLoweringInfo &setSExtResult(bool Value = true) { RetSExt = Value; return *this; @@ -2494,12 +2658,12 @@ public: /// This hook must be implemented to lower outgoing return values, described /// by the Outs array, into the specified DAG. The implementation should /// return the resulting token chain value. - virtual SDValue - LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, - bool /*isVarArg*/, - const SmallVectorImpl<ISD::OutputArg> &/*Outs*/, - const SmallVectorImpl<SDValue> &/*OutVals*/, - SDLoc /*dl*/, SelectionDAG &/*DAG*/) const { + virtual SDValue LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, + bool /*isVarArg*/, + const SmallVectorImpl<ISD::OutputArg> & /*Outs*/, + const SmallVectorImpl<SDValue> & /*OutVals*/, + const SDLoc & /*dl*/, + SelectionDAG & /*DAG*/) const { llvm_unreachable("Not Implemented"); } @@ -2534,12 +2698,12 @@ public: } /// Return the type that should be used to zero or sign extend a - /// zeroext/signext integer argument or return value. FIXME: Most C calling - /// convention requires the return type to be promoted, but this is not true - /// all the time, e.g. i1 on x86-64. It is also not necessary for non-C - /// calling conventions. The frontend should handle this and include all of - /// the necessary information. - virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, + /// zeroext/signext integer return value. FIXME: Some C calling conventions + /// require the return type to be promoted, but this is not true all the time, + /// e.g. i1/i8/i16 on x86/x86_64. It is also not necessary for non-C calling + /// conventions. The frontend should handle this and include all of the + /// necessary information. + virtual EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, ISD::NodeType /*ExtendKind*/) const { EVT MinVT = getRegisterType(Context, MVT::i32); return VT.bitsLT(MinVT) ? MinVT : VT; @@ -2567,7 +2731,7 @@ public: /// which allows a CPU to reuse the result of a previous load indefinitely, /// even if a cache-coherent store is performed by another CPU. The default /// implementation does nothing. - virtual SDValue prepareVolatileOrAtomicLoad(SDValue Chain, SDLoc DL, + virtual SDValue prepareVolatileOrAtomicLoad(SDValue Chain, const SDLoc &DL, SelectionDAG &DAG) const { return Chain; } @@ -2840,6 +3004,25 @@ public: /// \returns True, if the expansion was successful, false otherwise bool expandFP_TO_SINT(SDNode *N, SDValue &Result, SelectionDAG &DAG) const; + /// Turn load of vector type into a load of the individual elements. + /// \param LD load to expand + /// \returns MERGE_VALUEs of the scalar loads with their chains. + SDValue scalarizeVectorLoad(LoadSDNode *LD, SelectionDAG &DAG) const; + + // Turn a store of a vector type into stores of the individual elements. + /// \param ST Store with a vector value type + /// \returns MERGE_VALUs of the individual store chains. + SDValue scalarizeVectorStore(StoreSDNode *ST, SelectionDAG &DAG) const; + + /// Expands an unaligned load to 2 half-size loads for an integer, and + /// possibly more for vectors. + std::pair<SDValue, SDValue> expandUnalignedLoad(LoadSDNode *LD, + SelectionDAG &DAG) const; + + /// Expands an unaligned store to 2 half-size stores for integer values, and + /// possibly more for vectors. + SDValue expandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG) const; + //===--------------------------------------------------------------------===// // Instruction Emitting Hooks // @@ -2853,14 +3036,14 @@ public: /// As long as the returned basic block is different (i.e., we created a new /// one), the custom inserter is free to modify the rest of \p MBB. virtual MachineBasicBlock * - EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; + EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const; /// This method should be implemented by targets that mark instructions with /// the 'hasPostISelHook' flag. These instructions must be adjusted after /// instruction selection by target hooks. e.g. To fill in optional defs for /// ARM 's' setting instructions. - virtual void - AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const; + virtual void AdjustInstrPostInstrSelection(MachineInstr &MI, + SDNode *Node) const; /// If this function returns true, SelectionDAGBuilder emits a /// LOAD_STACK_GUARD node when it is lowering Intrinsic::stackprotector. @@ -2871,6 +3054,11 @@ public: /// Lower TLS global address SDNode for target independent emulated TLS model. virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const; + +private: + SDValue simplifySetCCWithAnd(EVT VT, SDValue N0, SDValue N1, + ISD::CondCode Cond, DAGCombinerInfo &DCI, + const SDLoc &DL) const; }; /// Given an LLVM IR type and return type attributes, compute the return value diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index cb52698c58b9..189eff4f3953 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -71,7 +71,8 @@ public: /// placed in. virtual MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind, - const Constant *C) const; + const Constant *C, + unsigned &Align) const; /// Classify the specified global variable into a set of target independent /// categories embodied in SectionKind. @@ -154,8 +155,8 @@ public: virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const; virtual const MCExpr * - getExecutableRelativeSymbol(const ConstantExpr *CE, Mangler &Mang, - const TargetMachine &TM) const { + lowerRelativeReference(const GlobalValue *LHS, const GlobalValue *RHS, + Mangler &Mang, const TargetMachine &TM) const { return nullptr; } diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 74e91b5790cb..563fef96acfc 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -29,15 +29,14 @@ class InstrItineraryData; class GlobalValue; class Mangler; class MachineFunctionInitializer; +class MachineModuleInfo; class MCAsmInfo; -class MCCodeGenInfo; class MCContext; class MCInstrInfo; class MCRegisterInfo; class MCSubtargetInfo; class MCSymbol; class Target; -class DataLayout; class TargetLibraryInfo; class TargetFrameLowering; class TargetIRAnalysis; @@ -45,7 +44,6 @@ class TargetIntrinsicInfo; class TargetLowering; class TargetPassConfig; class TargetRegisterInfo; -class TargetSelectionDAGInfo; class TargetSubtargetInfo; class TargetTransformInfo; class formatted_raw_ostream; @@ -90,9 +88,9 @@ protected: // Can only create subclasses. std::string TargetCPU; std::string TargetFS; - /// Low level target information such as relocation model. Non-const to - /// allow resetting optimization level per-function. - MCCodeGenInfo *CodeGenInfo; + Reloc::Model RM = Reloc::Static; + CodeModel::Model CMModel = CodeModel::Default; + CodeGenOpt::Level OptLevel = CodeGenOpt::Default; /// Contains target specific asm information. const MCAsmInfo *AsmInfo; @@ -104,11 +102,6 @@ protected: // Can only create subclasses. unsigned RequireStructuredCFG : 1; unsigned O0WantsFastISel : 1; - /// This API is here to support the C API, deprecated in 3.7 release. - /// This should never be used outside of legacy existing client. - const DataLayout &getDataLayout() const { return DL; } - friend struct C_API_PRIVATE_ACCESS; - public: mutable TargetOptions Options; @@ -181,6 +174,10 @@ public: /// target default. CodeModel::Model getCodeModel() const; + bool isPositionIndependent() const; + + bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const; + /// Returns the TLS model which should be used for the given global variable. TLSModel::Model getTLSModel(const GlobalValue *GV) const; @@ -188,7 +185,7 @@ public: CodeGenOpt::Level getOptLevel() const; /// \brief Overrides the optimization level. - void setOptLevel(CodeGenOpt::Level Level) const; + void setOptLevel(CodeGenOpt::Level Level); void setFastISel(bool Enable) { Options.EnableFastISel = Enable; } bool getO0WantsFastISel() { return O0WantsFastISel; } @@ -223,6 +220,11 @@ public: /// uses this to answer queries about the IR. virtual TargetIRAnalysis getTargetIRAnalysis(); + /// Add target-specific function passes that should be run as early as + /// possible in the optimization pipeline. Most TargetMachines have no such + /// passes. + virtual void addEarlyAsPossiblePasses(PassManagerBase &) {} + /// These enums are meant to be passed into addPassesToEmitFile to indicate /// what type of file to emit, and returned by it to indicate what type of /// file could actually be made. @@ -265,6 +267,12 @@ public: void getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV, Mangler &Mang, bool MayAlwaysUsePrivate = false) const; MCSymbol *getSymbol(const GlobalValue *GV, Mangler &Mang) const; + + /// True if the target uses physical regs at Prolog/Epilog insertion + /// time. If true (most machines), all vregs must be allocated before + /// PEI. If false (virtual-register machines), then callee-save register + /// spilling and scavenging are not needed or used. + virtual bool usesPhysRegsForPEI() const { return true; } }; /// This class describes a target machine that is implemented with the LLVM @@ -304,6 +312,13 @@ public: bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, raw_pwrite_stream &OS, bool DisableVerify = true) override; + + /// Add MachineModuleInfo pass to pass manager. + MachineModuleInfo &addMachineModuleInfo(PassManagerBase &PM) const; + + /// Add MachineFunctionAnalysis pass to pass manager. + void addMachineFunctionAnalysis(PassManagerBase &PM, + MachineFunctionInitializer *MFInitializer) const; }; } // End llvm namespace diff --git a/include/llvm/Target/TargetOpcodes.def b/include/llvm/Target/TargetOpcodes.def new file mode 100644 index 000000000000..abab6c7a2a7c --- /dev/null +++ b/include/llvm/Target/TargetOpcodes.def @@ -0,0 +1,177 @@ +//===-- llvm/Target/TargetOpcodes.def - Target Indep Opcodes ------*- 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 target independent instruction opcodes. +// +//===----------------------------------------------------------------------===// + +// NOTE: NO INCLUDE GUARD DESIRED! + +/// HANDLE_TARGET_OPCODE defines an opcode and its associated enum value. +/// +#ifndef HANDLE_TARGET_OPCODE +#define HANDLE_TARGET_OPCODE(OPC, NUM) +#endif + +/// HANDLE_TARGET_OPCODE_MARKER defines an alternative identifier for an opcode. +/// +#ifndef HANDLE_TARGET_OPCODE_MARKER +#define HANDLE_TARGET_OPCODE_MARKER(IDENT, OPC) +#endif + +/// Every instruction defined here must also appear in Target.td. +/// +HANDLE_TARGET_OPCODE(PHI, 0) +HANDLE_TARGET_OPCODE(INLINEASM, 1) +HANDLE_TARGET_OPCODE(CFI_INSTRUCTION, 2) +HANDLE_TARGET_OPCODE(EH_LABEL, 3) +HANDLE_TARGET_OPCODE(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. +HANDLE_TARGET_OPCODE(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. +HANDLE_TARGET_OPCODE(EXTRACT_SUBREG, 6) + +/// INSERT_SUBREG - This instruction takes three operands: a register that +/// has subregisters, a register providing an insert value, and a +/// subregister index. It returns the value of the first register with the +/// value of the second register inserted. The first register is often +/// defined by an IMPLICIT_DEF, because it is commonly used to implement +/// anyext operations on target architectures which support it. +HANDLE_TARGET_OPCODE(INSERT_SUBREG, 7) + +/// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef. +HANDLE_TARGET_OPCODE(IMPLICIT_DEF, 8) + +/// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that +/// the first operand is an immediate integer constant. This constant is +/// often zero, because it is commonly used to assert that the instruction +/// defining the register implicitly clears the high bits. +HANDLE_TARGET_OPCODE(SUBREG_TO_REG, 9) + +/// COPY_TO_REGCLASS - This instruction is a placeholder for a plain +/// register-to-register copy into a specific register class. This is only +/// used between instruction selection and MachineInstr creation, before +/// virtual registers have been created for all the instructions, and it's +/// only needed in cases where the register classes implied by the +/// instructions are insufficient. It is emitted as a COPY MachineInstr. +HANDLE_TARGET_OPCODE(COPY_TO_REGCLASS, 10) + +/// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic +HANDLE_TARGET_OPCODE(DBG_VALUE, 11) + +/// REG_SEQUENCE - This variadic instruction is used to form a register that +/// represents a consecutive sequence of sub-registers. It's used as a +/// register coalescing / allocation aid and must be eliminated before code +/// emission. +// In SDNode form, the first operand encodes the register class created by +// the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index +// pair. Once it has been lowered to a MachineInstr, the regclass operand +// is no longer present. +/// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5 +/// After register coalescing references of v1024 should be replace with +/// v1027:3, v1025 with v1027:4, etc. +HANDLE_TARGET_OPCODE(REG_SEQUENCE, 12) + +/// COPY - Target-independent register copy. This instruction can also be +/// used to copy between subregisters of virtual registers. +HANDLE_TARGET_OPCODE(COPY, 13) + +/// BUNDLE - This instruction represents an instruction bundle. Instructions +/// which immediately follow a BUNDLE instruction which are marked with +/// 'InsideBundle' flag are inside the bundle. +HANDLE_TARGET_OPCODE(BUNDLE, 14) + +/// Lifetime markers. +HANDLE_TARGET_OPCODE(LIFETIME_START, 15) +HANDLE_TARGET_OPCODE(LIFETIME_END, 16) + +/// A Stackmap instruction captures the location of live variables at its +/// position in the instruction stream. It is followed by a shadow of bytes +/// that must lie within the function and not contain another stackmap. +HANDLE_TARGET_OPCODE(STACKMAP, 17) + +/// Patchable call instruction - this instruction represents a call to a +/// constant address, followed by a series of NOPs. It is intended to +/// support optimizations for dynamic languages (such as javascript) that +/// rewrite calls to runtimes with more efficient code sequences. +/// This also implies a stack map. +HANDLE_TARGET_OPCODE(PATCHPOINT, 18) + +/// This pseudo-instruction loads the stack guard value. Targets which need +/// to prevent the stack guard value or address from being spilled to the +/// stack should override TargetLowering::emitLoadStackGuardNode and +/// additionally expand this pseudo after register allocation. +HANDLE_TARGET_OPCODE(LOAD_STACK_GUARD, 19) + +/// Call instruction with associated vm state for deoptimization and list +/// of live pointers for relocation by the garbage collector. It is +/// intended to support garbage collection with fully precise relocating +/// collectors and deoptimizations in either the callee or caller. +HANDLE_TARGET_OPCODE(STATEPOINT, 20) + +/// Instruction that records the offset of a local stack allocation passed to +/// llvm.localescape. It has two arguments: the symbol for the label and the +/// frame index of the local stack allocation. +HANDLE_TARGET_OPCODE(LOCAL_ESCAPE, 21) + +/// Loading instruction that may page fault, bundled with associated +/// information on how to handle such a page fault. It is intended to support +/// "zero cost" null checks in managed languages by allowing LLVM to fold +/// comparisons into existing memory operations. +HANDLE_TARGET_OPCODE(FAULTING_LOAD_OP, 22) + +/// Wraps a machine instruction to add patchability constraints. An +/// instruction wrapped in PATCHABLE_OP has to either have a minimum +/// size or be preceded with a nop of that size. The first operand is +/// an immediate denoting the minimum size of the instruction, the +/// second operand is an immediate denoting the opcode of the original +/// instruction. The rest of the operands are the operands of the +/// original instruction. +HANDLE_TARGET_OPCODE(PATCHABLE_OP, 23) + +/// This is a marker instruction which gets translated into a nop sled, useful +/// for inserting instrumentation instructions at runtime. +HANDLE_TARGET_OPCODE(PATCHABLE_FUNCTION_ENTER, 24) + +/// Wraps a return instruction and its operands to enable adding nop sleds +/// either before or after the return. The nop sleds are useful for inserting +/// instrumentation instructions at runtime. +HANDLE_TARGET_OPCODE(PATCHABLE_RET, 25) + +/// The following generic opcodes are not supposed to appear after ISel. +/// This is something we might want to relax, but for now, this is convenient +/// to produce diagnostics. + +/// Generic ADD instruction. This is an integer add. +HANDLE_TARGET_OPCODE(G_ADD, 26) +HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_START, G_ADD) + +/// Generic Bitwise-OR instruction. +HANDLE_TARGET_OPCODE(G_OR, 27) + +/// Generic BRANCH instruction. This is an unconditional branch. +HANDLE_TARGET_OPCODE(G_BR, 28) + +// TODO: Add more generic opcodes as we move along. + +/// Marker for the end of the generic opcode. +/// This is used to check if an opcode is in the range of the +/// generic opcodes. +HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_BR) + +/// BUILTIN_OP_END - This must be the last enum value in this list. +/// The target-specific post-isel opcode values start here. +HANDLE_TARGET_OPCODE_MARKER(GENERIC_OP_END, PRE_ISEL_GENERIC_OPCODE_END) diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index db37bdb62582..f851fc27527b 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -18,122 +18,20 @@ 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 { - PHI = 0, - INLINEASM = 1, - CFI_INSTRUCTION = 2, - EH_LABEL = 3, - GC_LABEL = 4, - - /// KILL - This instruction is a noop that is used only to adjust the - /// liveness of registers. This can be useful when dealing with - /// sub-registers. - KILL = 5, - - /// EXTRACT_SUBREG - This instruction takes two operands: a register - /// that has subregisters, and a subregister index. It returns the - /// extracted subregister value. This is commonly used to implement - /// truncation operations on target architectures which support it. - EXTRACT_SUBREG = 6, - - /// INSERT_SUBREG - This instruction takes three operands: a register that - /// has subregisters, a register providing an insert value, and a - /// subregister index. It returns the value of the first register with the - /// value of the second register inserted. The first register is often - /// defined by an IMPLICIT_DEF, because it is commonly used to implement - /// anyext operations on target architectures which support it. - INSERT_SUBREG = 7, - - /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef. - IMPLICIT_DEF = 8, - - /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that - /// the first operand is an immediate integer constant. This constant is - /// often zero, because it is commonly used to assert that the instruction - /// defining the register implicitly clears the high bits. - SUBREG_TO_REG = 9, - - /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain - /// register-to-register copy into a specific register class. This is only - /// used between instruction selection and MachineInstr creation, before - /// virtual registers have been created for all the instructions, and it's - /// only needed in cases where the register classes implied by the - /// instructions are insufficient. It is emitted as a COPY MachineInstr. - COPY_TO_REGCLASS = 10, - - /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic - DBG_VALUE = 11, - - /// REG_SEQUENCE - This variadic instruction is used to form a register that - /// represents a consecutive sequence of sub-registers. It's used as a - /// register coalescing / allocation aid and must be eliminated before code - /// emission. - // In SDNode form, the first operand encodes the register class created by - // the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index - // pair. Once it has been lowered to a MachineInstr, the regclass operand - // is no longer present. - /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5 - /// After register coalescing references of v1024 should be replace with - /// v1027:3, v1025 with v1027:4, etc. - REG_SEQUENCE = 12, - - /// COPY - Target-independent register copy. This instruction can also be - /// used to copy between subregisters of virtual registers. - COPY = 13, - - /// BUNDLE - This instruction represents an instruction bundle. Instructions - /// which immediately follow a BUNDLE instruction which are marked with - /// 'InsideBundle' flag are inside the bundle. - BUNDLE = 14, - - /// Lifetime markers. - LIFETIME_START = 15, - LIFETIME_END = 16, - - /// A Stackmap instruction captures the location of live variables at its - /// position in the instruction stream. It is followed by a shadow of bytes - /// that must lie within the function and not contain another stackmap. - STACKMAP = 17, - - /// Patchable call instruction - this instruction represents a call to a - /// constant address, followed by a series of NOPs. It is intended to - /// support optimizations for dynamic languages (such as javascript) that - /// rewrite calls to runtimes with more efficient code sequences. - /// This also implies a stack map. - PATCHPOINT = 18, - - /// This pseudo-instruction loads the stack guard value. Targets which need - /// to prevent the stack guard value or address from being spilled to the - /// stack should override TargetLowering::emitLoadStackGuardNode and - /// additionally expand this pseudo after register allocation. - LOAD_STACK_GUARD = 19, - - /// Call instruction with associated vm state for deoptimization and list - /// of live pointers for relocation by the garbage collector. It is - /// intended to support garbage collection with fully precise relocating - /// collectors and deoptimizations in either the callee or caller. - STATEPOINT = 20, - - /// Instruction that records the offset of a local stack allocation passed to - /// llvm.localescape. It has two arguments: the symbol for the label and the - /// frame index of the local stack allocation. - LOCAL_ESCAPE = 21, - - /// Loading instruction that may page fault, bundled with associated - /// information on how to handle such a page fault. It is intended to support - /// "zero cost" null checks in managed languages by allowing LLVM to fold - /// comparisons into existing memory operations. - FAULTING_LOAD_OP = 22, - - /// BUILTIN_OP_END - This must be the last enum value in this list. - /// The target-specific post-isel opcode values start here. - GENERIC_OP_END = FAULTING_LOAD_OP, +#define HANDLE_TARGET_OPCODE(OPC, NUM) OPC = NUM, +#define HANDLE_TARGET_OPCODE_MARKER(IDENT, OPC) IDENT = OPC, +#include "llvm/Target/TargetOpcodes.def" }; } // end namespace TargetOpcode + +/// Check whether the given Opcode is a generic opcode that is not supposed +/// to appear after ISel. +static inline bool isPreISelGenericOpcode(unsigned Opcode) { + return Opcode >= TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START && + Opcode <= TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END; +} } // end namespace llvm #endif diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index d98d0fa0ed5f..57873b4bd0b4 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -17,12 +17,11 @@ #include "llvm/Target/TargetRecip.h" #include "llvm/MC/MCTargetOptions.h" -#include <string> +#include "llvm/MC/MCAsmInfo.h" namespace llvm { class MachineFunction; class Module; - class StringRef; namespace FloatABI { enum ABIType { @@ -97,14 +96,16 @@ namespace llvm { UnsafeFPMath(false), NoInfsFPMath(false), NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false), GuaranteedTailCallOpt(false), StackAlignmentOverride(0), - EnableFastISel(false), PositionIndependentExecutable(false), - UseInitArray(false), DisableIntegratedAS(false), - CompressDebugSections(false), FunctionSections(false), + StackSymbolOrdering(true), EnableFastISel(false), UseInitArray(false), + DisableIntegratedAS(false), CompressDebugSections(false), + RelaxELFRelocations(false), FunctionSections(false), DataSections(false), UniqueSectionNames(true), TrapUnreachable(false), - EmulatedTLS(false), FloatABIType(FloatABI::Default), + EmulatedTLS(false), EnableIPRA(false), + FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard), Reciprocals(TargetRecip()), JTType(JumpTable::Single), ThreadModel(ThreadModel::POSIX), - EABIVersion(EABI::Default), DebuggerTuning(DebuggerKind::Default) {} + EABIVersion(EABI::Default), DebuggerTuning(DebuggerKind::Default), + ExceptionModel(ExceptionHandling::None) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs /// option is specified on the command line, and should enable debugging @@ -169,17 +170,17 @@ namespace llvm { /// StackAlignmentOverride - Override default stack alignment for target. unsigned StackAlignmentOverride; + /// StackSymbolOrdering - When true, this will allow CodeGen to order + /// the local stack symbols (for code size, code locality, or any other + /// heuristics). When false, the local symbols are left in whatever order + /// they were generated. Default is true. + unsigned StackSymbolOrdering : 1; + /// EnableFastISel - This flag enables fast-path instruction selection /// which trades away generated code quality in favor of reducing /// compile time. unsigned EnableFastISel : 1; - /// PositionIndependentExecutable - This flag indicates whether the code - /// will eventually be linked into a single executable, despite the PIC - /// relocation model being in use. It's value is undefined (and irrelevant) - /// if the relocation model is anything other than PIC. - unsigned PositionIndependentExecutable : 1; - /// UseInitArray - Use .init_array instead of .ctors for static /// constructors. unsigned UseInitArray : 1; @@ -190,6 +191,8 @@ namespace llvm { /// Compress DWARF debug sections. unsigned CompressDebugSections : 1; + unsigned RelaxELFRelocations : 1; + /// Emit functions into separate sections. unsigned FunctionSections : 1; @@ -205,6 +208,9 @@ namespace llvm { /// function in the runtime library.. unsigned EmulatedTLS : 1; + /// This flag enables InterProcedural Register Allocation (IPRA). + unsigned EnableIPRA : 1; + /// FloatABIType - This setting is set by -float-abi=xxx option is specfied /// on the command line. This setting may either be Default, Soft, or Hard. /// Default selects the target's default behavior. Soft selects the ABI for @@ -248,6 +254,9 @@ namespace llvm { /// Which debugger to tune for. DebuggerKind DebuggerTuning; + /// What exception model to use + ExceptionHandling ExceptionModel; + /// Machine level options. MCTargetOptions MCOptions; }; @@ -267,7 +276,6 @@ inline bool operator==(const TargetOptions &LHS, ARE_EQUAL(GuaranteedTailCallOpt) && ARE_EQUAL(StackAlignmentOverride) && ARE_EQUAL(EnableFastISel) && - ARE_EQUAL(PositionIndependentExecutable) && ARE_EQUAL(UseInitArray) && ARE_EQUAL(TrapUnreachable) && ARE_EQUAL(EmulatedTLS) && @@ -278,7 +286,9 @@ inline bool operator==(const TargetOptions &LHS, ARE_EQUAL(ThreadModel) && ARE_EQUAL(EABIVersion) && ARE_EQUAL(DebuggerTuning) && - ARE_EQUAL(MCOptions); + ARE_EQUAL(ExceptionModel) && + ARE_EQUAL(MCOptions) && + ARE_EQUAL(EnableIPRA); #undef ARE_EQUAL } diff --git a/include/llvm/Target/TargetRecip.h b/include/llvm/Target/TargetRecip.h index 210d49324848..309b96079131 100644 --- a/include/llvm/Target/TargetRecip.h +++ b/include/llvm/Target/TargetRecip.h @@ -18,9 +18,10 @@ #define LLVM_TARGET_TARGETRECIP_H #include "llvm/ADT/StringRef.h" -#include <vector> -#include <string> +#include <cstdint> #include <map> +#include <string> +#include <vector> namespace llvm { @@ -68,6 +69,6 @@ private: void parseIndividualParams(const std::vector<std::string> &Args); }; -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_TARGET_TARGETRECIP_H diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index fccaad4705d5..e5a6c8ed2f2d 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -21,7 +21,6 @@ #include "llvm/CodeGen/MachineValueType.h" #include "llvm/IR/CallingConv.h" #include "llvm/MC/MCRegisterInfo.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Printable.h" #include <cassert> #include <functional> @@ -71,6 +70,9 @@ public: const uint8_t AllocationPriority; /// Whether the class supports two (or more) disjunct subregister indices. const bool HasDisjunctSubRegs; + /// Whether a combination of subregisters can cover every register in the + /// class. See also the CoveredBySubRegs description in Target.td. + const bool CoveredBySubRegs; const sc_iterator SuperClasses; ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&); @@ -161,8 +163,21 @@ public: } /// Returns a bit vector of subclasses, including this one. - /// The vector is indexed by class IDs, see hasSubClassEq() above for how to - /// use it. + /// The vector is indexed by class IDs. + /// + /// To use it, consider the returned array as a chunk of memory that + /// contains an array of bits of size NumRegClasses. Each 32-bit chunk + /// contains a bitset of the ID of the subclasses in big-endian style. + + /// I.e., the representation of the memory from left to right at the + /// bit level looks like: + /// [31 30 ... 1 0] [ 63 62 ... 33 32] ... + /// [ XXX NumRegClasses NumRegClasses - 1 ... ] + /// Where the number represents the class ID and XXX bits that + /// should be ignored. + /// + /// See the implementation of hasSubClassEq for an example of how it + /// can be used. const uint32_t *getSubClassMask() const { return SubClassMask; } @@ -212,7 +227,7 @@ public: /// Returns the combination of all lane masks of register in this class. /// The lane masks of the registers are the combination of all lane masks - /// of their subregisters. + /// of their subregisters. Returns 1 if there are no subregisters. LaneBitmask getLaneMask() const { return LaneMask; } @@ -457,9 +472,13 @@ public: /// Return a register mask that clobbers everything. virtual const uint32_t *getNoPreservedMask() const { - llvm_unreachable("target does not provide no presered mask"); + llvm_unreachable("target does not provide no preserved mask"); } + /// Return true if all bits that are set in mask \p mask0 are also set in + /// \p mask1. + bool regmaskSubsetEqual(const uint32_t *mask0, const uint32_t *mask1) const; + /// Return all the call-preserved register masks defined for this target. virtual ArrayRef<const uint32_t *> getRegMasks() const = 0; virtual ArrayRef<const char *> getRegMaskNames() const = 0; @@ -548,6 +567,20 @@ public: return composeSubRegIndexLaneMaskImpl(IdxA, Mask); } + /// Transform a lanemask given for a virtual register to the corresponding + /// lanemask before using subregister with index \p IdxA. + /// This is the reverse of composeSubRegIndexLaneMask(), assuming Mask is a + /// valie lane mask (no invalid bits set) the following holds: + /// X0 = composeSubRegIndexLaneMask(Idx, Mask) + /// X1 = reverseComposeSubRegIndexLaneMask(Idx, X0) + /// => X1 == Mask + LaneBitmask reverseComposeSubRegIndexLaneMask(unsigned IdxA, + LaneBitmask LaneMask) const { + if (!IdxA) + return LaneMask; + return reverseComposeSubRegIndexLaneMaskImpl(IdxA, LaneMask); + } + /// Debugging helper: dump register in human readable form to dbgs() stream. static void dumpReg(unsigned Reg, unsigned SubRegIndex = 0, const TargetRegisterInfo* TRI = nullptr); @@ -564,6 +597,11 @@ protected: llvm_unreachable("Target has no sub-registers"); } + virtual LaneBitmask reverseComposeSubRegIndexLaneMaskImpl(unsigned, + LaneBitmask) const { + llvm_unreachable("Target has no sub-registers"); + } + public: /// Find a common super-register class if it exists. /// @@ -863,6 +901,17 @@ public: int SPAdj, unsigned FIOperandNum, RegScavenger *RS = nullptr) const = 0; + /// Return the assembly name for \p Reg. + virtual StringRef getRegAsmName(unsigned Reg) const { + // FIXME: We are assuming that the assembly name is equal to the TableGen + // name converted to lower case + // + // The TableGen name is the name of the definition for this register in the + // target's tablegen files. For example, the TableGen name of + // def EAX : Register <...>; is "EAX" + return StringRef(getName(Reg)); + } + //===--------------------------------------------------------------------===// /// Subtarget Hooks @@ -926,8 +975,9 @@ public: /// Returns the current sub-register index. unsigned getSubReg() const { return SubReg; } - /// Returns the bit mask if register classes that getSubReg() projects into + /// Returns the bit mask of register classes that getSubReg() projects into /// RC. + /// See TargetRegisterClass::getSubClassMask() for how to use it. const uint32_t *getMask() const { return Mask; } /// Advance iterator to the next entry. @@ -940,6 +990,97 @@ public: } }; +//===----------------------------------------------------------------------===// +// BitMaskClassIterator +//===----------------------------------------------------------------------===// +/// This class encapuslates the logic to iterate over bitmask returned by +/// the various RegClass related APIs. +/// E.g., this class can be used to iterate over the subclasses provided by +/// TargetRegisterClass::getSubClassMask or SuperRegClassIterator::getMask. +class BitMaskClassIterator { + /// Total number of register classes. + const unsigned NumRegClasses; + /// Base index of CurrentChunk. + /// In other words, the number of bit we read to get at the + /// beginning of that chunck. + unsigned Base; + /// Adjust base index of CurrentChunk. + /// Base index + how many bit we read within CurrentChunk. + unsigned Idx; + /// Current register class ID. + unsigned ID; + /// Mask we are iterating over. + const uint32_t *Mask; + /// Current chunk of the Mask we are traversing. + uint32_t CurrentChunk; + + /// Move ID to the next set bit. + void moveToNextID() { + // If the current chunk of memory is empty, move to the next one, + // while making sure we do not go pass the number of register + // classes. + while (!CurrentChunk) { + // Move to the next chunk. + Base += 32; + if (Base >= NumRegClasses) { + ID = NumRegClasses; + return; + } + CurrentChunk = *++Mask; + Idx = Base; + } + // Otherwise look for the first bit set from the right + // (representation of the class ID is big endian). + // See getSubClassMask for more details on the representation. + unsigned Offset = countTrailingZeros(CurrentChunk); + // Add the Offset to the adjusted base number of this chunk: Idx. + // This is the ID of the register class. + ID = Idx + Offset; + + // Consume the zeros, if any, and the bit we just read + // so that we are at the right spot for the next call. + // Do not do Offset + 1 because Offset may be 31 and 32 + // will be UB for the shift, though in that case we could + // have make the chunk being equal to 0, but that would + // have introduced a if statement. + moveNBits(Offset); + moveNBits(1); + } + + /// Move \p NumBits Bits forward in CurrentChunk. + void moveNBits(unsigned NumBits) { + assert(NumBits < 32 && "Undefined behavior spotted!"); + // Consume the bit we read for the next call. + CurrentChunk >>= NumBits; + // Adjust the base for the chunk. + Idx += NumBits; + } + +public: + /// Create a BitMaskClassIterator that visits all the register classes + /// represented by \p Mask. + /// + /// \pre \p Mask != nullptr + BitMaskClassIterator(const uint32_t *Mask, const TargetRegisterInfo &TRI) + : NumRegClasses(TRI.getNumRegClasses()), Base(0), Idx(0), ID(0), + Mask(Mask), CurrentChunk(*Mask) { + // Move to the first ID. + moveToNextID(); + } + + /// Returns true if this iterator is still pointing at a valid entry. + bool isValid() const { return getID() != NumRegClasses; } + + /// Returns the current register class ID. + unsigned getID() const { return ID; } + + /// Advance iterator to the next entry. + void operator++() { + assert(isValid() && "Cannot move iterator past end."); + moveToNextID(); + } +}; + // This is useful when building IndexedMaps keyed on virtual registers struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> { unsigned operator()(unsigned Reg) const { diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index 89db37ca859b..74b98ac5f6c5 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -13,7 +13,7 @@ // The SchedMachineModel is defined by subtargets for three categories of data: // 1. Basic properties for coarse grained instruction cost model. // 2. Scheduler Read/Write resources for simple per-opcode cost model. -// 3. Instruction itineraties for detailed reservation tables. +// 3. Instruction itineraries for detailed reservation tables. // // (1) Basic properties are defined by the SchedMachineModel // class. Target hooks allow subtargets to associate opcodes with @@ -55,6 +55,8 @@ include "llvm/Target/TargetItinerary.td" class Instruction; // Forward def +class Predicate; // Forward def + // DAG operator that interprets the DAG args as Instruction defs. def instrs; @@ -76,8 +78,6 @@ def instregex; // See MCSchedule.h for detailed comments. class SchedMachineModel { int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle. - int MinLatency = -1; // Determines which instructions are allowed in a group. - // (-1) inorder (0) ooo, (1): inorder +var latencies. int MicroOpBufferSize = -1; // Max micro-ops that can be buffered. int LoopMicroOpBufferSize = -1; // Max micro-ops that can be buffered for // optimized loop dispatch/execution. @@ -99,11 +99,26 @@ class SchedMachineModel { // resulting from changes to the instruction definitions. bit CompleteModel = 1; + // A processor may only implement part of published ISA, due to either new ISA + // extensions, (e.g. Pentium 4 doesn't have AVX) or implementation + // (ARM/MIPS/PowerPC/SPARC soft float cores). + // + // For a processor which doesn't support some feature(s), the schedule model + // can use: + // + // let<Predicate> UnsupportedFeatures = [HaveA,..,HaveY]; + // + // to skip the checks for scheduling information when building LLVM for + // instructions which have any of the listed predicates in their Predicates + // field. + list<Predicate> UnsupportedFeatures = []; + bit NoModel = 0; // Special tag to indicate missing machine model. } def NoSchedModel : SchedMachineModel { let NoModel = 1; + let CompleteModel = 0; } // Define a kind of processor resource that may be common across @@ -392,6 +407,8 @@ class InstRW<list<SchedReadWrite> rw, dag instrlist> { list<SchedReadWrite> OperandReadWrites = rw; dag Instrs = instrlist; SchedMachineModel SchedModel = ?; + // Allow a subtarget to mark some instructions as unsupported. + bit Unsupported = 0; } // Map a set of itinerary classes to SchedReadWrite resources. This is diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 565473658404..88375f77e230 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -116,6 +116,9 @@ def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. def SDTIntShiftOp : SDTypeProfile<1, 2, [ // shl, sra, srl SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2> ]>; +def SDTIntSatNoShOp : SDTypeProfile<1, 2, [ // ssat with no shift + SDTCisSameAs<0, 1>, SDTCisInt<2> +]>; def SDTIntBinHiLoOp : SDTypeProfile<2, 2, [ // mulhi, mullo, sdivrem, udivrem SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,SDTCisInt<0> ]>; @@ -167,7 +170,7 @@ def SDTSelect : SDTypeProfile<1, 3, [ // select ]>; def SDTVSelect : SDTypeProfile<1, 3, [ // vselect - SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> + SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1> ]>; def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc @@ -300,7 +303,9 @@ def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent //===----------------------------------------------------------------------===// // Selection DAG Pattern Operations -class SDPatternOperator; +class SDPatternOperator { + list<SDNodeProperty> Properties = []; +} //===----------------------------------------------------------------------===// // Selection DAG Node definitions. @@ -310,7 +315,7 @@ class SDNode<string opcode, SDTypeProfile typeprof, : SDPatternOperator { string Opcode = opcode; string SDClass = sdclass; - list<SDNodeProperty> Properties = props; + let Properties = props; SDTypeProfile TypeProfile = typeprof; } @@ -391,10 +396,14 @@ def subc : SDNode<"ISD::SUBC" , SDTIntBinOp, [SDNPOutGlue]>; def sube : SDNode<"ISD::SUBE" , SDTIntBinOp, [SDNPOutGlue, SDNPInGlue]>; -def smin : SDNode<"ISD::SMIN" , SDTIntBinOp>; -def smax : SDNode<"ISD::SMAX" , SDTIntBinOp>; -def umin : SDNode<"ISD::UMIN" , SDTIntBinOp>; -def umax : SDNode<"ISD::UMAX" , SDTIntBinOp>; +def smin : SDNode<"ISD::SMIN" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def smax : SDNode<"ISD::SMAX" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def umin : SDNode<"ISD::UMIN" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; +def umax : SDNode<"ISD::UMAX" , SDTIntBinOp, + [SDNPCommutative, SDNPAssociative]>; def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; def bitreverse : SDNode<"ISD::BITREVERSE" , SDTIntUnaryOp>; @@ -421,11 +430,14 @@ def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp>; def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp>; def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; -def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp>; -def fmaxnum : SDNode<"ISD::FMAXNUM" , SDTFPBinOp>; +def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp, + [SDNPCommutative, SDNPAssociative]>; +def fmaxnum : SDNode<"ISD::FMAXNUM" , SDTFPBinOp, + [SDNPCommutative, SDNPAssociative]>; def fminnan : SDNode<"ISD::FMINNAN" , SDTFPBinOp>; def fmaxnan : SDNode<"ISD::FMAXNAN" , SDTFPBinOp>; def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>; +def fcanonicalize : SDNode<"ISD::FCANONICALIZE", SDTFPUnaryOp>; def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>; @@ -944,6 +956,18 @@ def unalignednontemporalstore : PatFrag<(ops node:$val, node:$ptr), return St->getAlignment() < St->getMemoryVT().getStoreSize(); }]>; +// nontemporal load fragments. +def nontemporalload : PatFrag<(ops node:$ptr), + (load node:$ptr), [{ + return cast<LoadSDNode>(N)->isNonTemporal(); +}]>; + +def alignednontemporalload : PatFrag<(ops node:$ptr), + (nontemporalload node:$ptr), [{ + LoadSDNode *Ld = cast<LoadSDNode>(N); + return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize(); +}]>; + // setcc convenience fragments. def setoeq : PatFrag<(ops node:$lhs, node:$rhs), (setcc node:$lhs, node:$rhs, SETOEQ)>; diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h deleted file mode 100644 index a7143ac3fa66..000000000000 --- a/include/llvm/Target/TargetSelectionDAGInfo.h +++ /dev/null @@ -1,158 +0,0 @@ -//==-- llvm/Target/TargetSelectionDAGInfo.h - SelectionDAG Info --*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the TargetSelectionDAGInfo class, which targets can -// subclass to parameterize the SelectionDAG lowering and instruction -// selection process. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETSELECTIONDAGINFO_H -#define LLVM_TARGET_TARGETSELECTIONDAGINFO_H - -#include "llvm/CodeGen/SelectionDAGNodes.h" - -namespace llvm { - -//===----------------------------------------------------------------------===// -/// Targets can subclass this to parameterize the -/// SelectionDAG lowering and instruction selection process. -/// -class TargetSelectionDAGInfo { - TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) = delete; - void operator=(const TargetSelectionDAGInfo &) = delete; - -public: - explicit TargetSelectionDAGInfo() = default; - virtual ~TargetSelectionDAGInfo(); - - /// Emit target-specific code that performs a memcpy. - /// This can be used by targets to provide code sequences for cases - /// that don't fit the target's parameters for simple loads/stores and can be - /// more efficient than using a library call. This function can return a null - /// SDValue if the target declines to use custom code and a different - /// lowering strategy should be used. - /// - /// If AlwaysInline is true, the size is constant and the target should not - /// emit any calls and is strongly encouraged to attempt to emit inline code - /// even if it is beyond the usual threshold because this intrinsic is being - /// expanded in a place where calls are not feasible (e.g. within the prologue - /// for another call). If the target chooses to decline an AlwaysInline - /// request here, legalize will resort to using simple loads and stores. - virtual SDValue - EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl, - SDValue Chain, - SDValue Op1, SDValue Op2, - SDValue Op3, unsigned Align, bool isVolatile, - bool AlwaysInline, - MachinePointerInfo DstPtrInfo, - MachinePointerInfo SrcPtrInfo) const { - return SDValue(); - } - - /// Emit target-specific code that performs a memmove. - /// This can be used by targets to provide code sequences for cases - /// that don't fit the target's parameters for simple loads/stores and can be - /// more efficient than using a library call. This function can return a null - /// SDValue if the target declines to use custom code and a different - /// lowering strategy should be used. - virtual SDValue - EmitTargetCodeForMemmove(SelectionDAG &DAG, SDLoc dl, - SDValue Chain, - SDValue Op1, SDValue Op2, - SDValue Op3, unsigned Align, bool isVolatile, - MachinePointerInfo DstPtrInfo, - MachinePointerInfo SrcPtrInfo) const { - return SDValue(); - } - - /// Emit target-specific code that performs a memset. - /// This can be used by targets to provide code sequences for cases - /// that don't fit the target's parameters for simple stores and can be more - /// efficient than using a library call. This function can return a null - /// SDValue if the target declines to use custom code and a different - /// lowering strategy should be used. - virtual SDValue - EmitTargetCodeForMemset(SelectionDAG &DAG, SDLoc dl, - SDValue Chain, - SDValue Op1, SDValue Op2, - SDValue Op3, unsigned Align, bool isVolatile, - MachinePointerInfo DstPtrInfo) const { - return SDValue(); - } - - /// Emit target-specific code that performs a memcmp, in cases where that is - /// faster than a libcall. The first returned SDValue is the result of the - /// memcmp and the second is the chain. Both SDValues can be null if a normal - /// libcall should be used. - virtual std::pair<SDValue, SDValue> - EmitTargetCodeForMemcmp(SelectionDAG &DAG, SDLoc dl, - SDValue Chain, - SDValue Op1, SDValue Op2, - SDValue Op3, MachinePointerInfo Op1PtrInfo, - MachinePointerInfo Op2PtrInfo) const { - return std::make_pair(SDValue(), SDValue()); - } - - /// Emit target-specific code that performs a memchr, in cases where that is - /// faster than a libcall. The first returned SDValue is the result of the - /// memchr and the second is the chain. Both SDValues can be null if a normal - /// libcall should be used. - virtual std::pair<SDValue, SDValue> - EmitTargetCodeForMemchr(SelectionDAG &DAG, SDLoc dl, SDValue Chain, - SDValue Src, SDValue Char, SDValue Length, - MachinePointerInfo SrcPtrInfo) const { - return std::make_pair(SDValue(), SDValue()); - } - - /// Emit target-specific code that performs a strcpy or stpcpy, in cases - /// where that is faster than a libcall. - /// The first returned SDValue is the result of the copy (the start - /// of the destination string for strcpy, a pointer to the null terminator - /// for stpcpy) and the second is the chain. Both SDValues can be null - /// if a normal libcall should be used. - virtual std::pair<SDValue, SDValue> - EmitTargetCodeForStrcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain, - SDValue Dest, SDValue Src, - MachinePointerInfo DestPtrInfo, - MachinePointerInfo SrcPtrInfo, - bool isStpcpy) const { - return std::make_pair(SDValue(), SDValue()); - } - - /// Emit target-specific code that performs a strcmp, in cases where that is - /// faster than a libcall. - /// The first returned SDValue is the result of the strcmp and the second is - /// the chain. Both SDValues can be null if a normal libcall should be used. - virtual std::pair<SDValue, SDValue> - EmitTargetCodeForStrcmp(SelectionDAG &DAG, SDLoc dl, - SDValue Chain, - SDValue Op1, SDValue Op2, - MachinePointerInfo Op1PtrInfo, - MachinePointerInfo Op2PtrInfo) const { - return std::make_pair(SDValue(), SDValue()); - } - - virtual std::pair<SDValue, SDValue> - EmitTargetCodeForStrlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain, - SDValue Src, MachinePointerInfo SrcPtrInfo) const { - return std::make_pair(SDValue(), SDValue()); - } - - virtual std::pair<SDValue, SDValue> - EmitTargetCodeForStrnlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain, - SDValue Src, SDValue MaxLength, - MachinePointerInfo SrcPtrInfo) const { - return std::make_pair(SDValue(), SDValue()); - } -}; - -} // end llvm namespace - -#endif diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index d50aa4932f8f..b929070484f9 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -16,14 +16,18 @@ #include "llvm/CodeGen/PBQPRAConstraint.h" #include "llvm/CodeGen/SchedulerRegistry.h" +#include "llvm/CodeGen/ScheduleDAGMutation.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/CodeGen.h" +#include <vector> namespace llvm { +class CallLowering; class DataLayout; class MachineFunction; class MachineInstr; +class RegisterBankInfo; class SDep; class SUnit; class TargetFrameLowering; @@ -32,7 +36,7 @@ class TargetLowering; class TargetRegisterClass; class TargetRegisterInfo; class TargetSchedModel; -class TargetSelectionDAGInfo; +class SelectionDAGTargetInfo; struct MachineSchedPolicy; template <typename T> class SmallVectorImpl; @@ -71,6 +75,7 @@ public: // -- Pipelines and scheduling information // -- Stack frame information // -- Selection DAG lowering information + // -- Call lowering information // // N.B. These objects may change during compilation. It's not safe to cache // them between functions. @@ -79,9 +84,10 @@ public: return nullptr; } virtual const TargetLowering *getTargetLowering() const { return nullptr; } - virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const { + virtual const SelectionDAGTargetInfo *getSelectionDAGInfo() const { return nullptr; } + virtual const CallLowering *getCallLowering() const { return nullptr; } /// Target can subclass this hook to select a different DAG scheduler. virtual RegisterScheduler::FunctionPassCtor getDAGScheduler(CodeGenOpt::Level) const { @@ -89,11 +95,14 @@ public: } /// getRegisterInfo - If register information is available, return it. If - /// not, return null. This is kept separate from RegInfo until RegInfo has - /// details of graph coloring register allocation removed from it. + /// not, return null. /// virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; } + /// If the information for the register banks is available, return it. + /// Otherwise return nullptr. + virtual const RegisterBankInfo *getRegBankInfo() const { return nullptr; } + /// getInstrItineraryData - Returns instruction itinerary data for the target /// or specific subtarget. /// @@ -144,7 +153,6 @@ public: /// scheduling heuristics (no custom MachineSchedStrategy) to make /// changes to the generic scheduling policy. virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, - MachineInstr *begin, MachineInstr *end, unsigned NumRegionInstrs) const {} // \brief Perform target specific adjustments to the latency of a schedule @@ -162,6 +170,12 @@ public: return CriticalPathRCs.clear(); } + // \brief Provide an ordered list of schedule DAG mutations for the post-RA + // scheduler. + virtual void getPostRAMutations( + std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { + } + // For use with PostRAScheduling: get the minimum optimization level needed // to enable post-RA scheduling. virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const { |