aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Target
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
commit01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch)
tree4def12e759965de927d963ac65840d663ef9d1ea /include/llvm/Target
parentf0f4822ed4b66e3579e92a89f368f8fb860e218e (diff)
downloadsrc-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.td46
-rw-r--r--include/llvm/Target/Target.td64
-rw-r--r--include/llvm/Target/TargetCallingConv.h18
-rw-r--r--include/llvm/Target/TargetCallingConv.td10
-rw-r--r--include/llvm/Target/TargetFrameLowering.h72
-rw-r--r--include/llvm/Target/TargetInstrInfo.h281
-rw-r--r--include/llvm/Target/TargetLowering.h366
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h7
-rw-r--r--include/llvm/Target/TargetMachine.h39
-rw-r--r--include/llvm/Target/TargetOpcodes.def177
-rw-r--r--include/llvm/Target/TargetOpcodes.h122
-rw-r--r--include/llvm/Target/TargetOptions.h40
-rw-r--r--include/llvm/Target/TargetRecip.h9
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h153
-rw-r--r--include/llvm/Target/TargetSchedule.td23
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td42
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h158
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h24
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 {