summaryrefslogtreecommitdiff
path: root/include/llvm/Target
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Target')
-rw-r--r--include/llvm/Target/Target.td72
-rw-r--r--include/llvm/Target/TargetFrameLowering.h14
-rw-r--r--include/llvm/Target/TargetInstrInfo.h230
-rw-r--r--include/llvm/Target/TargetIntrinsicInfo.h2
-rw-r--r--include/llvm/Target/TargetJITInfo.h137
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h27
-rw-r--r--include/llvm/Target/TargetLowering.h377
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h8
-rw-r--r--include/llvm/Target/TargetMachine.h95
-rw-r--r--include/llvm/Target/TargetOpcodes.h19
-rw-r--r--include/llvm/Target/TargetOptions.h49
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h55
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td20
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h2
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h61
15 files changed, 811 insertions, 357 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index f77cc7a35eb8..6c970d0c19db 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -378,20 +378,25 @@ class Instruction {
bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction.
bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement?
bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement?
+ bit isRegSequence = 0; // Is this instruction a kind of reg sequence?
+ // If so, make sure to override
+ // TargetInstrInfo::getRegSequenceLikeInputs.
bit isPseudo = 0; // Is this instruction a pseudo-instruction?
// If so, won't have encoding information for
// the [MC]CodeEmitter stuff.
+ bit isExtractSubreg = 0; // Is this instruction a kind of extract subreg?
+ // If so, make sure to override
+ // TargetInstrInfo::getExtractSubregLikeInputs.
+ bit isInsertSubreg = 0; // Is this instruction a kind of insert subreg?
+ // If so, make sure to override
+ // TargetInstrInfo::getInsertSubregLikeInputs.
// Side effect flags - When set, the flags have these meanings:
//
// hasSideEffects - The instruction has side effects that are not
// captured by any operands of the instruction or other flags.
//
- // neverHasSideEffects (deprecated) - Set on an instruction with no pattern
- // if it has no side effects. This is now equivalent to setting
- // "hasSideEffects = 0".
bit hasSideEffects = ?;
- bit neverHasSideEffects = 0;
// Is this instruction a "real" instruction (with a distinct machine
// encoding), or is it a pseudo instruction used for codegen modeling
@@ -583,7 +588,6 @@ class Operand<ValueType ty> : DAGOperand {
string PrintMethod = "printOperand";
string EncoderMethod = "";
string DecoderMethod = "";
- string AsmOperandLowerMethod = ?;
string OperandType = "OPERAND_UNKNOWN";
dag MIOperandInfo = (ops);
@@ -620,6 +624,9 @@ class RegisterOperand<RegisterClass regclass, string pm = "printOperand">
// can match a subset of some other class, in which case the AsmOperandClass
// should declare the other operand as one of its super classes.
AsmOperandClass ParserMatchClass;
+
+ string OperandNamespace = "MCOI";
+ string OperandType = "OPERAND_REGISTER";
}
let OperandType = "OPERAND_IMMEDIATE" in {
@@ -726,7 +733,7 @@ def INLINEASM : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
- let neverHasSideEffects = 1; // Note side effect is encoded in an operand.
+ let hasSideEffects = 0; // Note side effect is encoded in an operand.
}
def CFI_INSTRUCTION : Instruction {
let OutOperandList = (outs);
@@ -753,26 +760,26 @@ def KILL : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def EXTRACT_SUBREG : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$supersrc, i32imm:$subidx);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def INSERT_SUBREG : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let Constraints = "$supersrc = $dst";
}
def IMPLICIT_DEF : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let isReMaterializable = 1;
let isAsCheapAsAMove = 1;
}
@@ -780,33 +787,33 @@ def SUBREG_TO_REG : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def COPY_TO_REGCLASS : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$src, i32imm:$regclass);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let isAsCheapAsAMove = 1;
}
def DBG_VALUE : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "DBG_VALUE";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def REG_SEQUENCE : Instruction {
let OutOperandList = (outs unknown:$dst);
- let InOperandList = (ins variable_ops);
+ let InOperandList = (ins unknown:$supersrc, variable_ops);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let isAsCheapAsAMove = 1;
}
def COPY : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$src);
let AsmString = "";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
let isAsCheapAsAMove = 1;
}
def BUNDLE : Instruction {
@@ -818,13 +825,13 @@ def LIFETIME_START : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "LIFETIME_START";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def LIFETIME_END : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "LIFETIME_END";
- let neverHasSideEffects = 1;
+ let hasSideEffects = 0;
}
def STACKMAP : Instruction {
let OutOperandList = (outs);
@@ -841,6 +848,32 @@ def PATCHPOINT : Instruction {
let mayLoad = 1;
let usesCustomInserter = 1;
}
+def STATEPOINT : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let usesCustomInserter = 1;
+ let mayLoad = 1;
+ let mayStore = 1;
+ let hasSideEffects = 1;
+ let isCall = 1;
+}
+def LOAD_STACK_GUARD : Instruction {
+ let OutOperandList = (outs ptr_rc:$dst);
+ let InOperandList = (ins);
+ let mayLoad = 1;
+ bit isReMaterializable = 1;
+ let hasSideEffects = 0;
+ bit isPseudo = 1;
+}
+def FRAME_ALLOC : Instruction {
+ // This instruction is really just a label. It has to be part of the chain so
+ // that it doesn't get dropped from the DAG, but it produces nothing and has
+ // no side effects.
+ let OutOperandList = (outs);
+ let InOperandList = (ins ptr_rc:$symbol, i32imm:$id);
+ let hasSideEffects = 0;
+ let hasCtrlDep = 1;
+}
}
//===----------------------------------------------------------------------===//
@@ -989,9 +1022,6 @@ class AsmWriter {
// will specify which alternative to use. For example "{x|y|z}" with Variant
// == 1, will expand to "y".
int Variant = 0;
-
- // OperandSpacing - Space between operand columns.
- int OperandSpacing = -1;
}
def DefaultAsmWriter : AsmWriter;
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
index bfddd0601794..277bd98d371c 100644
--- a/include/llvm/Target/TargetFrameLowering.h
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -142,6 +142,10 @@ public:
/// the assembly prologue to explicitly handle the stack.
virtual void adjustForHiPEPrologue(MachineFunction &MF) const { }
+ /// Adjust the prologue to add an allocation at a fixed offset from the frame
+ /// pointer.
+ virtual void adjustForFrameAllocatePrologue(MachineFunction &MF) const { }
+
/// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
/// saved registers and returns true if it isn't possible / profitable to do
/// so by issuing a series of store instructions via
@@ -199,6 +203,16 @@ 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 used exclusively for lowering STATEPOINT nodes.
+ /// 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;
+ }
+
/// processFunctionBeforeCalleeSavedScan - This method is called immediately
/// before PrologEpilogInserter scans the physical registers used to determine
/// what callee saved registers should be spilled. This method is optional.
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 87e7c14ac1e8..e8a50fff1fe8 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -14,10 +14,12 @@
#ifndef LLVM_TARGET_TARGETINSTRINFO_H
#define LLVM_TARGET_TARGETINSTRINFO_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/CodeGen/DFAPacketizer.h"
+#include "llvm/CodeGen/MachineCombinerPattern.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
namespace llvm {
@@ -28,7 +30,7 @@ class MachineMemOperand;
class MachineRegisterInfo;
class MDNode;
class MCInst;
-class MCSchedModel;
+struct MCSchedModel;
class MCSymbolRefExpr;
class SDNode;
class ScheduleHazardRecognizer;
@@ -38,6 +40,7 @@ class TargetRegisterClass;
class TargetRegisterInfo;
class BranchProbability;
class TargetSubtargetInfo;
+class DFAPacketizer;
template<class T> class SmallVectorImpl;
@@ -106,6 +109,12 @@ public:
int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
+ /// 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;
+
/// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
/// extension instruction. That is, it's like a copy where it's legal for the
/// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
@@ -200,6 +209,15 @@ public:
unsigned &Size, unsigned &Offset,
const TargetMachine *TM) const;
+ /// isAsCheapAsAMove - Return true if the instruction is as cheap as a move
+ /// instruction.
+ ///
+ /// 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();
+ }
+
/// reMaterialize - Re-issue the specified 'original' instruction at the
/// specific location targeting a new destination register.
/// The register in Orig->getOperand(0).getReg() will be substituted by
@@ -252,6 +270,85 @@ public:
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
unsigned &SrcOpIdx2) const;
+ /// A pair composed of a register and a sub-register index.
+ /// Used to give some type checking when modeling Reg:SubReg.
+ struct RegSubRegPair {
+ unsigned Reg;
+ unsigned SubReg;
+ RegSubRegPair(unsigned Reg = 0, unsigned SubReg = 0)
+ : Reg(Reg), SubReg(SubReg) {}
+ };
+ /// A pair composed of a pair of a register and a sub-register index,
+ /// and another sub-register index.
+ /// Used to give some type checking when modeling Reg:SubReg1, SubReg2.
+ struct RegSubRegPairAndIdx : RegSubRegPair {
+ unsigned SubIdx;
+ RegSubRegPairAndIdx(unsigned Reg = 0, unsigned SubReg = 0,
+ unsigned SubIdx = 0)
+ : RegSubRegPair(Reg, SubReg), SubIdx(SubIdx) {}
+ };
+
+ /// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI
+ /// and \p DefIdx.
+ /// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of
+ /// the list is modeled as <Reg:SubReg, SubIdx>.
+ /// E.g., REG_SEQUENCE vreg1:sub1, sub0, vreg2, sub1 would produce
+ /// two elements:
+ /// - vreg1:sub1, sub0
+ /// - vreg2<:0>, sub1
+ ///
+ /// \returns true if it is possible to build such an input sequence
+ /// with the pair \p MI, \p DefIdx. False otherwise.
+ ///
+ /// \pre MI.isRegSequence() or MI.isRegSequenceLike().
+ ///
+ /// \note The generic implementation does not provide any support for
+ /// MI.isRegSequenceLike(). In other words, one has to override
+ /// getRegSequenceLikeInputs for target specific instructions.
+ bool
+ getRegSequenceInputs(const MachineInstr &MI, unsigned DefIdx,
+ SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const;
+
+ /// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI
+ /// and \p DefIdx.
+ /// \p [out] InputReg of the equivalent EXTRACT_SUBREG.
+ /// E.g., EXTRACT_SUBREG vreg1:sub1, sub0, sub1 would produce:
+ /// - vreg1:sub1, sub0
+ ///
+ /// \returns true if it is possible to build such an input sequence
+ /// with the pair \p MI, \p DefIdx. False otherwise.
+ ///
+ /// \pre MI.isExtractSubreg() or MI.isExtractSubregLike().
+ ///
+ /// \note The generic implementation does not provide any support for
+ /// MI.isExtractSubregLike(). In other words, one has to override
+ /// getExtractSubregLikeInputs for target specific instructions.
+ bool
+ getExtractSubregInputs(const MachineInstr &MI, unsigned DefIdx,
+ RegSubRegPairAndIdx &InputReg) const;
+
+ /// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI
+ /// and \p DefIdx.
+ /// \p [out] BaseReg and \p [out] InsertedReg contain
+ /// the equivalent inputs of INSERT_SUBREG.
+ /// E.g., INSERT_SUBREG vreg0:sub0, vreg1:sub1, sub3 would produce:
+ /// - BaseReg: vreg0:sub0
+ /// - InsertedReg: vreg1:sub1, sub3
+ ///
+ /// \returns true if it is possible to build such an input sequence
+ /// with the pair \p MI, \p DefIdx. False otherwise.
+ ///
+ /// \pre MI.isInsertSubreg() or MI.isInsertSubregLike().
+ ///
+ /// \note The generic implementation does not provide any support for
+ /// MI.isInsertSubregLike(). In other words, one has to override
+ /// getInsertSubregLikeInputs for target specific instructions.
+ bool
+ getInsertSubregInputs(const MachineInstr &MI, unsigned DefIdx,
+ RegSubRegPair &BaseReg,
+ RegSubRegPairAndIdx &InsertedReg) const;
+
+
/// produceSameValue - Return true if two machine instructions would produce
/// identical values. By default, this is only true when the two instructions
/// are deemed identical except for defs. If this function is called when the
@@ -337,6 +434,26 @@ public:
llvm_unreachable("Target didn't implement TargetInstrInfo::getTrap!");
}
+ /// getJumpInstrTableEntryBound - Get a number of bytes that suffices to hold
+ /// either the instruction returned by getUnconditionalBranch or the
+ /// instruction returned by getTrap. This only makes sense because
+ /// getUnconditionalBranch returns a single, specific instruction. This
+ /// information is needed by the jumptable construction code, since it must
+ /// decide how many bytes to use for a jumptable entry so it can generate the
+ /// right mask.
+ ///
+ /// Note that if the jumptable instruction requires alignment, then that
+ /// alignment should be factored into this required bound so that the
+ /// resulting bound gives the right alignment for the instruction.
+ virtual unsigned getJumpInstrTableEntryBound() const {
+ // This method gets called by LLVMTargetMachine always, so it can't fail
+ // just because there happens to be no implementation for this target.
+ // Any code that tries to use a jumptable annotation without defining
+ // getUnconditionalBranch on the appropriate Target will fail anyway, and
+ // the value returned here won't matter in that case.
+ return 0;
+ }
+
/// isLegalToSplitMBBAt - Return true if it's legal to split the given basic
/// block at the specified instruction (i.e. instruction would be the start
/// of a new basic block).
@@ -486,9 +603,12 @@ public:
/// a side.
///
/// @param MI Optimizable select instruction.
+ /// @param NewMIs Set that record all MIs in the basic block up to \p
+ /// 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,
+ SmallPtrSetImpl<MachineInstr *> &NewMIs,
bool PreferFalse = false) const {
// This function must be implemented if Optimizable is ever set.
llvm_unreachable("Target must implement TargetInstrInfo::optimizeSelect!");
@@ -563,6 +683,42 @@ public:
const SmallVectorImpl<unsigned> &Ops,
MachineInstr* LoadMI) const;
+ /// hasPattern - return true when there is potentially a faster code sequence
+ /// for an instruction chain ending in \p Root. All potential pattern are
+ /// returned in the \p Pattern vector. Pattern should be sorted in priority
+ /// order since the pattern evaluator stops checking as soon as it finds a
+ /// faster sequence.
+ /// \param Root - Instruction that could be combined with one of its operands
+ /// \param Pattern - Vector of possible combination pattern
+
+ virtual bool hasPattern(
+ MachineInstr &Root,
+ SmallVectorImpl<MachineCombinerPattern::MC_PATTERN> &Pattern) const {
+ return false;
+ }
+
+ /// genAlternativeCodeSequence - when hasPattern() finds a pattern this
+ /// function generates the instructions that could replace the original code
+ /// sequence. The client has to decide whether the actual replacementment is
+ /// beneficial or not.
+ /// \param Root - Instruction that could be combined with one of its operands
+ /// \param P - Combination pattern for Root
+ /// \param InsInstrs - Vector of new instructions that implement P
+ /// \param DelInstrs - Old instructions, including Root, that could be replaced
+ /// by InsInstr
+ /// \param InstrIdxForVirtReg - map of virtual register to instruction in
+ /// InsInstr that defines it
+ virtual void genAlternativeCodeSequence(
+ MachineInstr &Root, MachineCombinerPattern::MC_PATTERN P,
+ SmallVectorImpl<MachineInstr *> &InsInstrs,
+ SmallVectorImpl<MachineInstr *> &DelInstrs,
+ DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const {
+ return;
+ }
+
+ /// useMachineCombiner - return true when a target supports MachineCombiner
+ virtual bool useMachineCombiner() const { return false; }
+
protected:
/// foldMemoryOperandImpl - Target-dependent implementation for
/// foldMemoryOperand. Target-independent code in foldMemoryOperand will
@@ -584,6 +740,49 @@ protected:
return nullptr;
}
+ /// \brief Target-dependent implementation of getRegSequenceInputs.
+ ///
+ /// \returns true if it is possible to build the equivalent
+ /// REG_SEQUENCE inputs with the pair \p MI, \p DefIdx. False otherwise.
+ ///
+ /// \pre MI.isRegSequenceLike().
+ ///
+ /// \see TargetInstrInfo::getRegSequenceInputs.
+ virtual bool getRegSequenceLikeInputs(
+ const MachineInstr &MI, unsigned DefIdx,
+ SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const {
+ return false;
+ }
+
+ /// \brief Target-dependent implementation of getExtractSubregInputs.
+ ///
+ /// \returns true if it is possible to build the equivalent
+ /// EXTRACT_SUBREG inputs with the pair \p MI, \p DefIdx. False otherwise.
+ ///
+ /// \pre MI.isExtractSubregLike().
+ ///
+ /// \see TargetInstrInfo::getExtractSubregInputs.
+ virtual bool getExtractSubregLikeInputs(
+ const MachineInstr &MI, unsigned DefIdx,
+ RegSubRegPairAndIdx &InputReg) const {
+ return false;
+ }
+
+ /// \brief Target-dependent implementation of getInsertSubregInputs.
+ ///
+ /// \returns true if it is possible to build the equivalent
+ /// INSERT_SUBREG inputs with the pair \p MI, \p DefIdx. False otherwise.
+ ///
+ /// \pre MI.isInsertSubregLike().
+ ///
+ /// \see TargetInstrInfo::getInsertSubregInputs.
+ virtual bool
+ getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
+ RegSubRegPair &BaseReg,
+ RegSubRegPairAndIdx &InsertedReg) const {
+ return false;
+ }
+
public:
/// canFoldMemoryOperand - Returns true for the specified load / store if
/// folding is possible.
@@ -677,10 +876,8 @@ public:
MachineBasicBlock::iterator MI) const;
- /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
- virtual void getNoopForMachoTarget(MCInst &NopInst) const {
- // Default to just using 'nop' string.
- }
+ /// Return the noop instruction to use for a noop.
+ virtual void getNoopForMachoTarget(MCInst &NopInst) const;
/// isPredicated - Returns true if the instruction is already predicated.
@@ -784,6 +981,7 @@ public:
const MachineRegisterInfo *MRI) const {
return false;
}
+ virtual bool optimizeCondBranch(MachineInstr *MI) const { return false; }
/// optimizeLoadInstr - 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
@@ -862,7 +1060,7 @@ public:
SDNode *Node) const;
/// Return the default expected latency for a def based on it's opcode.
- unsigned defaultDefLatency(const MCSchedModel *SchedModel,
+ unsigned defaultDefLatency(const MCSchedModel &SchedModel,
const MachineInstr *DefMI) const;
int computeDefOperandLatency(const InstrItineraryData *ItinData,
@@ -1017,11 +1215,25 @@ public:
const TargetRegisterInfo *TRI) const {}
/// Create machine specific model for scheduling.
- virtual DFAPacketizer*
- CreateTargetScheduleState(const TargetMachine*, const ScheduleDAG*) const {
+ virtual DFAPacketizer *
+ CreateTargetScheduleState(const TargetSubtargetInfo &) const {
return nullptr;
}
+ // areMemAccessesTriviallyDisjoint - Sometimes, it is possible for the target
+ // to tell, even without aliasing information, that two MIs access different
+ // memory addresses. This function returns true if two MIs access different
+ // memory addresses, and false otherwise.
+ virtual bool
+ areMemAccessesTriviallyDisjoint(MachineInstr *MIa, MachineInstr *MIb,
+ AliasAnalysis *AA = nullptr) const {
+ assert(MIa && (MIa->mayLoad() || MIa->mayStore()) &&
+ "MIa must load from or modify a memory location");
+ assert(MIb && (MIb->mayLoad() || MIb->mayStore()) &&
+ "MIb must load from or modify a memory location");
+ return false;
+ }
+
private:
int CallFrameSetupOpcode, CallFrameDestroyOpcode;
};
diff --git a/include/llvm/Target/TargetIntrinsicInfo.h b/include/llvm/Target/TargetIntrinsicInfo.h
index 6de264e90ef7..71c0166d49b0 100644
--- a/include/llvm/Target/TargetIntrinsicInfo.h
+++ b/include/llvm/Target/TargetIntrinsicInfo.h
@@ -52,7 +52,7 @@ public:
/// Returns true if the intrinsic can be overloaded.
virtual bool isOverloaded(unsigned IID) const = 0;
-
+
/// Create or insert an LLVM Function declaration for an intrinsic,
/// and return it. The Tys and numTys are for intrinsics with overloaded
/// types. See above for more information.
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
deleted file mode 100644
index f9bd0fb9f981..000000000000
--- a/include/llvm/Target/TargetJITInfo.h
+++ /dev/null
@@ -1,137 +0,0 @@
-//===- Target/TargetJITInfo.h - Target Information for JIT ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file exposes an abstract interface used by the Just-In-Time code
-// generator to perform target-specific activities, such as emitting stubs. If
-// a TargetMachine supports JIT code generation, it should provide one of these
-// objects through the getJITInfo() method.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGETJITINFO_H
-#define LLVM_TARGET_TARGETJITINFO_H
-
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <cassert>
-
-namespace llvm {
- class Function;
- class GlobalValue;
- class JITCodeEmitter;
- class MachineRelocation;
-
- /// TargetJITInfo - Target specific information required by the Just-In-Time
- /// code generator.
- class TargetJITInfo {
- virtual void anchor();
- public:
- virtual ~TargetJITInfo() {}
-
- /// replaceMachineCodeForFunction - Make it so that calling the function
- /// whose machine code is at OLD turns into a call to NEW, perhaps by
- /// overwriting OLD with a branch to NEW. This is used for self-modifying
- /// code.
- ///
- virtual void replaceMachineCodeForFunction(void *Old, void *New) = 0;
-
- /// emitGlobalValueIndirectSym - Use the specified JITCodeEmitter object
- /// to emit an indirect symbol which contains the address of the specified
- /// ptr.
- virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
- JITCodeEmitter &JCE) {
- llvm_unreachable("This target doesn't implement "
- "emitGlobalValueIndirectSym!");
- }
-
- /// Records the required size and alignment for a call stub in bytes.
- struct StubLayout {
- size_t Size;
- size_t Alignment;
- };
- /// Returns the maximum size and alignment for a call stub on this target.
- virtual StubLayout getStubLayout() {
- llvm_unreachable("This target doesn't implement getStubLayout!");
- }
-
- /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
- /// small native function that simply calls the function at the specified
- /// address. The JITCodeEmitter must already have storage allocated for the
- /// stub. Return the address of the resultant function, which may have been
- /// aligned from the address the JCE was set up to emit at.
- virtual void *emitFunctionStub(const Function* F, void *Target,
- JITCodeEmitter &JCE) {
- llvm_unreachable("This target doesn't implement emitFunctionStub!");
- }
-
- /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
- /// specific basic block.
- virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase) {
- llvm_unreachable("This target doesn't implement getPICJumpTableEntry!");
- }
-
- /// LazyResolverFn - This typedef is used to represent the function that
- /// unresolved call points should invoke. This is a target specific
- /// function that knows how to walk the stack and find out which stub the
- /// call is coming from.
- typedef void (*LazyResolverFn)();
-
- /// JITCompilerFn - This typedef is used to represent the JIT function that
- /// lazily compiles the function corresponding to a stub. The JIT keeps
- /// track of the mapping between stubs and LLVM Functions, the target
- /// provides the ability to figure out the address of a stub that is called
- /// by the LazyResolverFn.
- typedef void* (*JITCompilerFn)(void *);
-
- /// getLazyResolverFunction - This method is used to initialize the JIT,
- /// giving the target the function that should be used to compile a
- /// function, and giving the JIT the target function used to do the lazy
- /// resolving.
- virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn) {
- llvm_unreachable("Not implemented for this target!");
- }
-
- /// relocate - Before the JIT can run a block of code that has been emitted,
- /// it must rewrite the code to contain the actual addresses of any
- /// referenced global symbols.
- virtual void relocate(void *Function, MachineRelocation *MR,
- unsigned NumRelocs, unsigned char* GOTBase) {
- assert(NumRelocs == 0 && "This target does not have relocations!");
- }
-
-
- /// allocateThreadLocalMemory - Each target has its own way of
- /// handling thread local variables. This method returns a value only
- /// meaningful to the target.
- virtual char* allocateThreadLocalMemory(size_t size) {
- llvm_unreachable("This target does not implement thread local storage!");
- }
-
- /// needsGOT - Allows a target to specify that it would like the
- /// JIT to manage a GOT for it.
- bool needsGOT() const { return useGOT; }
-
- /// hasCustomConstantPool - Allows a target to specify that constant
- /// pool address resolution is handled by the target.
- virtual bool hasCustomConstantPool() const { return false; }
-
- /// hasCustomJumpTables - Allows a target to specify that jumptables
- /// are emitted by the target.
- virtual bool hasCustomJumpTables() const { return false; }
-
- /// allocateSeparateGVMemory - If true, globals should be placed in
- /// separately allocated heap memory rather than in the same
- /// code memory allocated by JITCodeEmitter.
- virtual bool allocateSeparateGVMemory() const { return false; }
- protected:
- bool useGOT;
- };
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
index d4f9f2330594..46f87b93b001 100644
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -26,10 +26,18 @@ namespace llvm {
ZdaPv,
/// void operator delete[](void*, nothrow);
ZdaPvRKSt9nothrow_t,
+ /// void operator delete[](void*, unsigned int);
+ ZdaPvj,
+ /// void operator delete[](void*, unsigned long);
+ ZdaPvm,
/// void operator delete(void*);
ZdlPv,
/// void operator delete(void*, nothrow);
ZdlPvRKSt9nothrow_t,
+ /// void operator delete(void*, unsigned int);
+ ZdlPvj,
+ /// void operator delete(void*, unsigned long);
+ ZdlPvm,
/// void *new[](unsigned int);
Znaj,
/// void *new[](unsigned int, nothrow);
@@ -54,7 +62,7 @@ namespace llvm {
cxa_atexit,
/// void __cxa_guard_abort(guard_t *guard);
/// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi.
- cxa_guard_abort,
+ cxa_guard_abort,
/// int __cxa_guard_acquire(guard_t *guard);
cxa_guard_acquire,
/// void __cxa_guard_release(guard_t *guard);
@@ -65,6 +73,11 @@ namespace llvm {
dunder_isoc99_sscanf,
/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
memcpy_chk,
+ /// void *__memmove_chk(void *s1, const void *s2, size_t n,
+ /// size_t s1size);
+ memmove_chk,
+ /// void *__memset_chk(void *s, char v, size_t n, size_t s1size);
+ memset_chk,
/// double __sincospi_stret(double x);
sincospi_stret,
/// float __sincospif_stret(float x);
@@ -79,8 +92,18 @@ namespace llvm {
sqrtf_finite,
/// long double __sqrt_finite(long double x);
sqrtl_finite,
+ /// char *__stpcpy_chk(char *s1, const char *s2, size_t s1size);
+ stpcpy_chk,
+ /// char *__stpncpy_chk(char *s1, const char *s2, size_t n,
+ /// size_t s1size);
+ stpncpy_chk,
+ /// char *__strcpy_chk(char *s1, const char *s2, size_t s1size);
+ strcpy_chk,
/// char * __strdup(const char *s);
dunder_strdup,
+ /// char *__strncpy_chk(char *s1, const char *s2, size_t n,
+ /// size_t s1size);
+ strncpy_chk,
/// char *__strndup(const char *s, size_t n);
dunder_strndup,
/// char * __strtok_r(char *s, const char *delim, char **save_ptr);
@@ -696,7 +719,7 @@ public:
TargetLibraryInfo();
TargetLibraryInfo(const Triple &T);
explicit TargetLibraryInfo(const TargetLibraryInfo &TLI);
-
+
/// getLibFunc - Search for a particular function name. If it is one of the
/// known library functions, return true and set F to the corresponding value.
bool getLibFunc(StringRef funcName, LibFunc::Func &F) const;
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index ea9a48e2db8a..c5fed02e17b8 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -30,8 +30,9 @@
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
-#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Target/TargetCallingConv.h"
#include "llvm/Target/TargetMachine.h"
@@ -50,6 +51,7 @@ namespace llvm {
class MachineFunction;
class MachineInstr;
class MachineJumpTableInfo;
+ class MachineLoop;
class Mangler;
class MCContext;
class MCExpr;
@@ -136,10 +138,9 @@ public:
llvm_unreachable("Invalid content kind");
}
- /// NOTE: The constructor takes ownership of TLOF.
- explicit TargetLoweringBase(const TargetMachine &TM,
- const TargetLoweringObjectFile *TLOF);
- virtual ~TargetLoweringBase();
+ /// NOTE: The TargetMachine owns TLOF.
+ explicit TargetLoweringBase(const TargetMachine &TM);
+ virtual ~TargetLoweringBase() {}
protected:
/// \brief Initialize all of the actions to default values.
@@ -148,7 +149,9 @@ protected:
public:
const TargetMachine &getTargetMachine() const { return TM; }
const DataLayout *getDataLayout() const { return DL; }
- const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
+ const TargetLoweringObjectFile &getObjFileLowering() const {
+ return *TM.getObjFileLowering();
+ }
bool isBigEndian() const { return !IsLittleEndian; }
bool isLittleEndian() const { return IsLittleEndian; }
@@ -214,6 +217,11 @@ public:
/// several shifts, adds, and multiplies for this target.
bool isIntDivCheap() const { return IntDivIsCheap; }
+ /// Return true if sqrt(x) is as cheap or cheaper than 1 / rsqrt(x)
+ bool isFsqrtCheap() const {
+ return FsqrtIsCheap;
+ }
+
/// Returns true if target has indicated at least one type should be bypassed.
bool isSlowDivBypassed() const { return !BypassSlowDivWidths.empty(); }
@@ -223,8 +231,8 @@ public:
return BypassSlowDivWidths;
}
- /// Return true if pow2 div is cheaper than a chain of srl/add/sra.
- bool isPow2DivCheap() const { return Pow2DivIsCheap; }
+ /// Return true if pow2 sdiv is cheaper than a chain of sra/srl/add/sra.
+ bool isPow2SDivCheap() const { return Pow2SDivIsCheap; }
/// Return true if Flow Control is an expensive operation that should be
/// avoided.
@@ -247,6 +255,16 @@ public:
return true;
}
+ /// \brief Return true if it is cheap to speculate a call to intrinsic cttz.
+ virtual bool isCheapToSpeculateCttz() const {
+ return false;
+ }
+
+ /// \brief Return true if it is cheap to speculate a call to intrinsic ctlz.
+ virtual bool isCheapToSpeculateCtlz() const {
+ return false;
+ }
+
/// \brief Return if the target supports combining a
/// chain like:
/// \code
@@ -262,10 +280,32 @@ public:
return MaskAndBranchFoldingIsLegal;
}
- /// Return the ValueType of the result of SETCC operations. Also used to
- /// obtain the target's preferred type for the condition operand of SELECT and
- /// BRCOND nodes. In the case of BRCOND the argument passed is MVT::Other
- /// since there are no other operands to get a type hint from.
+ /// \brief Return true if the target wants to use the optimization that
+ /// turns ext(promotableInst1(...(promotableInstN(load)))) into
+ /// promotedInst1(...(promotedInstN(ext(load)))).
+ bool enableExtLdPromotion() const { return EnableExtLdPromotion; }
+
+ /// Return true if the target can combine store(extractelement VectorTy,
+ /// Idx).
+ /// \p Cost[out] gives the cost of that transformation when this is true.
+ virtual bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
+ unsigned &Cost) const {
+ return false;
+ }
+
+ /// Return true if target supports floating point exceptions.
+ bool hasFloatingPointExceptions() const {
+ return HasFloatingPointExceptions;
+ }
+
+ /// Return true if target always beneficiates from combining into FMA for a
+ /// given value type. This must typically return false on targets where FMA
+ /// takes more cycles to execute than FADD.
+ virtual bool enableAggressiveFMAFusion(EVT VT) const {
+ return false;
+ }
+
+ /// Return the ValueType of the result of SETCC operations.
virtual EVT getSetCCResultType(LLVMContext &Context, EVT VT) const;
/// Return the ValueType for comparison libcalls. Comparions libcalls include
@@ -426,10 +466,15 @@ public:
EVT memVT; // memory VT
const Value* ptrVal; // value representing memory location
int offset; // offset off of ptrVal
+ unsigned size; // the size of the memory location
+ // (taken from memVT if zero)
unsigned align; // alignment
bool vol; // is volatile?
bool readMem; // reads memory?
bool writeMem; // writes memory?
+
+ IntrinsicInfo() : opc(0), ptrVal(nullptr), offset(0), size(0), align(1),
+ vol(false), readMem(false), writeMem(false) {}
};
/// Given an intrinsic, checks if on the target the intrinsic will need to map
@@ -517,26 +562,31 @@ public:
/// Return how this load with extension should be treated: either it is legal,
/// needs to be promoted to a larger size, needs to be expanded to some other
/// code sequence, or the target has a custom expander for it.
- LegalizeAction getLoadExtAction(unsigned ExtType, MVT VT) const {
- assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
- "Table isn't big enough!");
- return (LegalizeAction)LoadExtActions[VT.SimpleTy][ExtType];
+ LegalizeAction getLoadExtAction(unsigned ExtType, EVT ValVT, EVT MemVT) const {
+ if (ValVT.isExtended() || MemVT.isExtended()) return Expand;
+ unsigned ValI = (unsigned) ValVT.getSimpleVT().SimpleTy;
+ 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 (LegalizeAction)LoadExtActions[ValI][MemI][ExtType];
}
/// Return true if the specified load with extension is legal on this target.
- bool isLoadExtLegal(unsigned ExtType, EVT VT) const {
- return VT.isSimple() &&
- getLoadExtAction(ExtType, VT.getSimpleVT()) == Legal;
+ bool isLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const {
+ return ValVT.isSimple() && MemVT.isSimple() &&
+ getLoadExtAction(ExtType, ValVT, MemVT) == Legal;
}
/// Return how this store with truncation should be treated: either it is
/// legal, needs to be promoted to a larger size, needs to be expanded to some
/// other code sequence, or the target has a custom expander for it.
- LegalizeAction getTruncStoreAction(MVT ValVT, MVT MemVT) const {
- assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
+ LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const {
+ if (ValVT.isExtended() || MemVT.isExtended()) return Expand;
+ unsigned ValI = (unsigned) ValVT.getSimpleVT().SimpleTy;
+ unsigned MemI = (unsigned) MemVT.getSimpleVT().SimpleTy;
+ assert(ValI < MVT::LAST_VALUETYPE && MemI < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)TruncStoreActions[ValVT.SimpleTy]
- [MemVT.SimpleTy];
+ return (LegalizeAction)TruncStoreActions[ValI][MemI];
}
/// Return true if the specified store with truncation is legal on this
@@ -551,7 +601,7 @@ public:
/// sequence, or the target has a custom expander for it.
LegalizeAction
getIndexedLoadAction(unsigned IdxMode, MVT VT) const {
- assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
+ assert(IdxMode < ISD::LAST_INDEXED_MODE && VT.isValid() &&
"Table isn't big enough!");
unsigned Ty = (unsigned)VT.SimpleTy;
return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4);
@@ -569,7 +619,7 @@ public:
/// sequence, or the target has a custom expander for it.
LegalizeAction
getIndexedStoreAction(unsigned IdxMode, MVT VT) const {
- assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
+ assert(IdxMode < ISD::LAST_INDEXED_MODE && VT.isValid() &&
"Table isn't big enough!");
unsigned Ty = (unsigned)VT.SimpleTy;
return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f);
@@ -725,6 +775,16 @@ public:
/// reduce runtime.
virtual bool ShouldShrinkFPConstant(EVT) const { return true; }
+ // Return true if it is profitable to reduce the given load node to a smaller
+ // type.
+ //
+ // e.g. (i16 (trunc (i32 (load x))) -> i16 load x should be performed
+ virtual bool shouldReduceLoadWidth(SDNode *Load,
+ ISD::LoadExtType ExtTy,
+ EVT NewVT) const {
+ return true;
+ }
+
/// When splitting a value of the specified type into parts, does the Lo
/// or Hi part come first? This usually follows the endianness, except
/// for ppcf128, where the Hi part always comes first.
@@ -773,14 +833,15 @@ public:
///
/// This function returns true if the target allows unaligned memory accesses
/// of the specified type in the given address space. If true, it also returns
- /// whether the unaligned memory access is "fast" in the third argument by
+ /// whether the unaligned memory access is "fast" in the last argument by
/// reference. This is used, for example, in situations where an array
/// copy/move/set is converted to a sequence of store operations. Its use
/// helps to ensure that such replacements don't generate code that causes an
/// alignment error (trap) on the target machine.
- virtual bool allowsUnalignedMemoryAccesses(EVT,
- unsigned AddrSpace = 0,
- bool * /*Fast*/ = nullptr) const {
+ virtual bool allowsMisalignedMemoryAccesses(EVT,
+ unsigned AddrSpace = 0,
+ unsigned Align = 1,
+ bool * /*Fast*/ = nullptr) const {
return false;
}
@@ -823,11 +884,6 @@ public:
return UseUnderscoreLongJmp;
}
- /// Return whether the target can generate code for jump tables.
- bool supportJumpTables() const {
- return SupportJumpTables;
- }
-
/// Return integer threshold on number of blocks to use jump tables rather
/// than if sequence.
int getMinimumJumpTableEntries() const {
@@ -880,7 +936,7 @@ public:
}
/// Return the preferred loop alignment.
- unsigned getPrefLoopAlignment() const {
+ virtual unsigned getPrefLoopAlignment(MachineLoop *ML = nullptr) const {
return PrefLoopAlignment;
}
@@ -922,9 +978,13 @@ public:
/// @}
//===--------------------------------------------------------------------===//
- /// \name Helpers for load-linked/store-conditional atomic expansion.
+ /// \name Helpers for atomic expansion.
/// @{
+ /// True if AtomicExpandPass should use emitLoadLinked/emitStoreConditional
+ /// and expand AtomicCmpXchgInst.
+ virtual bool hasLoadLinkedStoreConditional() 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
@@ -941,15 +1001,90 @@ public:
llvm_unreachable("Store conditional unimplemented on this target");
}
- /// Return true if the given (atomic) instruction should be expanded by the
- /// IR-level AtomicExpandLoadLinked pass into a loop involving
- /// load-linked/store-conditional pairs. Atomic stores will be expanded in the
- /// same way as "atomic xchg" operations which ignore their output if needed.
- virtual bool shouldExpandAtomicInIR(Instruction *Inst) const {
+ /// Inserts in the IR a target-specific intrinsic specifying a fence.
+ /// It is called by AtomicExpandPass before expanding an
+ /// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad.
+ /// 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
+ /// IR-level fences exists for historical/compatibility reasons and is
+ /// *unsound* ! Fences cannot, in general, be used to restore sequential
+ /// consistency. For example, consider the following example:
+ /// atomic<int> x = y = 0;
+ /// int r1, r2, r3, r4;
+ /// Thread 0:
+ /// x.store(1);
+ /// Thread 1:
+ /// y.store(1);
+ /// Thread 2:
+ /// r1 = x.load();
+ /// r2 = y.load();
+ /// Thread 3:
+ /// r3 = y.load();
+ /// r4 = x.load();
+ /// r1 = r3 = 1 and r2 = r4 = 0 is impossible as long as the accesses are all
+ /// seq_cst. But if they are lowered to monotonic accesses, no amount of
+ /// IR-level fences can prevent it.
+ /// @{
+ virtual Instruction* emitLeadingFence(IRBuilder<> &Builder, AtomicOrdering Ord,
+ bool IsStore, bool IsLoad) const {
+ if (!getInsertFencesForAtomic())
+ return nullptr;
+
+ if (isAtLeastRelease(Ord) && IsStore)
+ return Builder.CreateFence(Ord);
+ else
+ return nullptr;
+ }
+
+ virtual Instruction* emitTrailingFence(IRBuilder<> &Builder, AtomicOrdering Ord,
+ bool IsStore, bool IsLoad) const {
+ if (!getInsertFencesForAtomic())
+ return nullptr;
+
+ if (isAtLeastAcquire(Ord))
+ return Builder.CreateFence(Ord);
+ else
+ return nullptr;
+ }
+ /// @}
+
+ /// Returns true if the given (atomic) store should be expanded by the
+ /// IR-level AtomicExpand pass into an "atomic xchg" which ignores its input.
+ virtual bool shouldExpandAtomicStoreInIR(StoreInst *SI) const {
return false;
}
+ /// Returns true if the given (atomic) load should be expanded by the
+ /// IR-level AtomicExpand pass into a load-linked instruction
+ /// (through emitLoadLinked()).
+ virtual bool shouldExpandAtomicLoadInIR(LoadInst *LI) const { return false; }
+ /// Returns true if the given AtomicRMW should be expanded by the
+ /// IR-level AtomicExpand pass into a loop using LoadLinked/StoreConditional.
+ virtual bool shouldExpandAtomicRMWInIR(AtomicRMWInst *RMWI) const {
+ return false;
+ }
+
+ /// On some platforms, an AtomicRMW that never actually modifies the value
+ /// (such as fetch_add of 0) can be turned into a fence followed by an
+ /// atomic load. This may sound useless, but it makes it possible for the
+ /// processor to keep the cacheline shared, dramatically improving
+ /// performance. And such idempotent RMWs are useful for implementing some
+ /// kinds of locks, see for example (justification + benchmarks):
+ /// http://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf
+ /// This method tries doing that transformation, returning the atomic load if
+ /// it succeeds, and nullptr otherwise.
+ /// If shouldExpandAtomicLoadInIR returns true on that load, it will undergo
+ /// another round of expansion.
+ virtual LoadInst *lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *RMWI) const {
+ return nullptr;
+ }
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by
// the derived class constructor to configure this object for the target.
@@ -996,11 +1131,6 @@ protected:
UseUnderscoreLongJmp = Val;
}
- /// Indicate whether the target can generate code for jump tables.
- void setSupportJumpTables(bool Val) {
- SupportJumpTables = Val;
- }
-
/// Indicate the number of blocks to generate jump tables rather than if
/// sequence.
void setMinimumJumpTableEntries(int Val) {
@@ -1059,14 +1189,24 @@ protected:
/// containing an integer divide.
void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; }
+ /// Tells the code generator that fsqrt is cheap, and should not be replaced
+ /// with an alternative sequence of instructions.
+ void setFsqrtIsCheap(bool isCheap = true) { FsqrtIsCheap = isCheap; }
+
+ /// Tells the code generator that this target supports floating point
+ /// exceptions and cares about preserving floating point exception behavior.
+ void setHasFloatingPointExceptions(bool FPExceptions = true) {
+ HasFloatingPointExceptions = FPExceptions;
+ }
+
/// Tells the code generator which bitwidths to bypass.
void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth) {
BypassSlowDivWidths[SlowBitWidth] = FastBitWidth;
}
- /// Tells the code generator that it shouldn't generate srl/add/sra for a
- /// signed divide by power of two, and let the target handle it.
- void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; }
+ /// Tells the code generator that it shouldn't generate sra/srl/add/sra for a
+ /// signed divide by power of two; let the target handle it.
+ void setPow2SDivIsCheap(bool isCheap = true) { Pow2SDivIsCheap = isCheap; }
/// Add the specified register class as an available regclass for the
/// specified value type. This indicates the selector can handle values of
@@ -1107,19 +1247,18 @@ protected:
/// Indicate that the specified load with extension does not work with the
/// specified type and indicate what to do about it.
- void setLoadExtAction(unsigned ExtType, MVT VT,
+ void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT,
LegalizeAction Action) {
- assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
- "Table isn't big enough!");
- LoadExtActions[VT.SimpleTy][ExtType] = (uint8_t)Action;
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValVT.isValid() &&
+ MemVT.isValid() && "Table isn't big enough!");
+ LoadExtActions[ValVT.SimpleTy][MemVT.SimpleTy][ExtType] = (uint8_t)Action;
}
/// Indicate that the specified truncating store does not work with the
/// specified type and indicate what to do about it.
void setTruncStoreAction(MVT ValVT, MVT MemVT,
LegalizeAction Action) {
- assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
- "Table isn't big enough!");
+ assert(ValVT.isValid() && MemVT.isValid() && "Table isn't big enough!");
TruncStoreActions[ValVT.SimpleTy][MemVT.SimpleTy] = (uint8_t)Action;
}
@@ -1130,7 +1269,7 @@ protected:
/// TargetLowering.cpp
void setIndexedLoadAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
- assert(VT < MVT::LAST_VALUETYPE && IdxMode < ISD::LAST_INDEXED_MODE &&
+ assert(VT.isValid() && IdxMode < ISD::LAST_INDEXED_MODE &&
(unsigned)Action < 0xf && "Table isn't big enough!");
// Load action are kept in the upper half.
IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0xf0;
@@ -1144,7 +1283,7 @@ protected:
/// TargetLowering.cpp
void setIndexedStoreAction(unsigned IdxMode, MVT VT,
LegalizeAction Action) {
- assert(VT < MVT::LAST_VALUETYPE && IdxMode < ISD::LAST_INDEXED_MODE &&
+ assert(VT.isValid() && IdxMode < ISD::LAST_INDEXED_MODE &&
(unsigned)Action < 0xf && "Table isn't big enough!");
// Store action are kept in the lower half.
IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0x0f;
@@ -1155,8 +1294,7 @@ protected:
/// target and indicate what to do about it.
void setCondCodeAction(ISD::CondCode CC, MVT VT,
LegalizeAction Action) {
- assert(VT < MVT::LAST_VALUETYPE &&
- (unsigned)CC < array_lengthof(CondCodeActions) &&
+ assert(VT.isValid() && (unsigned)CC < array_lengthof(CondCodeActions) &&
"Table isn't big enough!");
/// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 32-bit
/// value and the upper 27 bits index into the second dimension of the array
@@ -1207,7 +1345,8 @@ protected:
/// Set the target's preferred loop alignment. Default alignment is zero, it
/// means the target does not care about loop alignment. The alignment is
- /// specified in log2(bytes).
+ /// specified in log2(bytes). The target may also override
+ /// getPrefLoopAlignment to provide per-loop values.
void setPrefLoopAlignment(unsigned Align) {
PrefLoopAlignment = Align;
}
@@ -1370,6 +1509,14 @@ public:
return isZExtFree(Val.getValueType(), VT2);
}
+ /// Return true if an fpext operation is free (for instance, because
+ /// single-precision floating-point numbers are implicitly extended to
+ /// double-precision).
+ virtual bool isFPExtFree(EVT VT) const {
+ assert(VT.isFloatingPoint());
+ return false;
+ }
+
/// Return true if an fneg operation is free to the point where it is never
/// worthwhile to replace it with a bitwise operation.
virtual bool isFNegFree(EVT VT) const {
@@ -1412,6 +1559,15 @@ public:
Type *Ty) const {
return false;
}
+
+ /// Return true if EXTRACT_SUBVECTOR is cheap for this result type
+ /// with this index. This is needed because EXTRACT_SUBVECTOR usually
+ /// has custom lowering that depends on the index of the first element,
+ /// and only the target knows which lowering is cheap.
+ virtual bool isExtractSubvectorCheap(EVT ResVT, unsigned Index) const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
// Runtime Library hooks
//
@@ -1451,7 +1607,6 @@ public:
private:
const TargetMachine &TM;
const DataLayout *DL;
- const TargetLoweringObjectFile &TLOF;
/// True if this is a little endian target.
bool IsLittleEndian;
@@ -1479,21 +1634,28 @@ private:
/// unconditionally.
bool IntDivIsCheap;
+ // Don't expand fsqrt with an approximation based on the inverse sqrt.
+ bool FsqrtIsCheap;
+
/// Tells the code generator to bypass slow divide or remainder
/// instructions. For example, BypassSlowDivWidths[32,8] tells the code
/// generator to bypass 32-bit integer div/rem with an 8-bit unsigned integer
/// div/rem when the operands are positive and less than 256.
DenseMap <unsigned int, unsigned int> BypassSlowDivWidths;
- /// Tells the code generator that it shouldn't generate srl/add/sra for a
- /// signed divide by power of two, and let the target handle it.
- bool Pow2DivIsCheap;
+ /// Tells the code generator that it shouldn't generate sra/srl/add/sra for a
+ /// signed divide by power of two; let the target handle it.
+ bool Pow2SDivIsCheap;
/// Tells the code generator that it shouldn't generate extra flow control
/// instructions and should attempt to combine flow control instructions via
/// predication.
bool JumpIsExpensive;
+ /// Whether the target supports or cares about preserving floating point
+ /// exception behavior.
+ bool HasFloatingPointExceptions;
+
/// This target prefers to use _setjmp to implement llvm.setjmp.
///
/// Defaults to false.
@@ -1504,10 +1666,6 @@ private:
/// Defaults to false.
bool UseUnderscoreLongJmp;
- /// Whether the target can generate code for jumptables. If it's not true,
- /// then each jumptable must be lowered into if-then-else's.
- bool SupportJumpTables;
-
/// Number of blocks threshold to use jump tables.
int MinimumJumpTableEntries;
@@ -1600,7 +1758,8 @@ 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.
- uint8_t LoadExtActions[MVT::LAST_VALUETYPE][ISD::LAST_LOADEXT_TYPE];
+ uint8_t LoadExtActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE]
+ [ISD::LAST_LOADEXT_TYPE];
/// For each value type pair keep a LegalizeAction that indicates whether a
/// truncating store of a specific value type and truncating type is legal.
@@ -1841,6 +2000,9 @@ protected:
/// a mask of a single bit, a compare, and a branch into a single instruction.
bool MaskAndBranchFoldingIsLegal;
+ /// \see enableExtLdPromotion.
+ bool EnableExtLdPromotion;
+
protected:
/// Return true if the value types that can be represented by the specified
/// register class are all legal.
@@ -1861,9 +2023,8 @@ class TargetLowering : public TargetLoweringBase {
void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION;
public:
- /// NOTE: The constructor takes ownership of TLOF.
- explicit TargetLowering(const TargetMachine &TM,
- const TargetLoweringObjectFile *TLOF);
+ /// NOTE: The TargetMachine owns TLOF.
+ explicit TargetLowering(const TargetMachine &TM);
/// Returns true by value, base pointer and offset pointer and addressing mode
/// by reference if the node's address can be legally represented as
@@ -2150,6 +2311,7 @@ public:
SelectionDAG &DAG;
SDLoc DL;
ImmutableCallSite *CS;
+ bool IsPatchPoint;
SmallVector<ISD::OutputArg, 32> Outs;
SmallVector<SDValue, 32> OutVals;
SmallVector<ISD::InputArg, 32> Ins;
@@ -2158,7 +2320,7 @@ public:
: 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) {}
+ DAG(DAG), CS(nullptr), IsPatchPoint(false) {}
CallLoweringInfo &setDebugLoc(SDLoc dl) {
DL = dl;
@@ -2240,6 +2402,11 @@ public:
return *this;
}
+ CallLoweringInfo &setIsPatchPoint(bool Value = true) {
+ IsPatchPoint = Value;
+ return *this;
+ }
+
ArgListTy &getArgs() {
return Args;
}
@@ -2324,9 +2491,9 @@ public:
/// 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 MVT getTypeForExtArgOrReturn(MVT VT,
+ virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT,
ISD::NodeType /*ExtendKind*/) const {
- MVT MinVT = getRegisterType(MVT::i32);
+ EVT MinVT = getRegisterType(Context, MVT::i32);
return VT.bitsLT(MinVT) ? MinVT : VT;
}
@@ -2474,11 +2641,10 @@ public:
unsigned getMatchedOperand() const;
/// Copy constructor for copying from a ConstraintInfo.
- AsmOperandInfo(const InlineAsm::ConstraintInfo &info)
- : InlineAsm::ConstraintInfo(info),
- ConstraintType(TargetLowering::C_Unknown),
- CallOperandVal(nullptr), ConstraintVT(MVT::Other) {
- }
+ AsmOperandInfo(InlineAsm::ConstraintInfo Info)
+ : InlineAsm::ConstraintInfo(std::move(Info)),
+ ConstraintType(TargetLowering::C_Unknown), CallOperandVal(nullptr),
+ ConstraintVT(MVT::Other) {}
};
typedef std::vector<AsmOperandInfo> AsmOperandInfoVector;
@@ -2545,6 +2711,51 @@ public:
SDValue BuildUDIV(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
bool IsAfterLegalization,
std::vector<SDNode *> *Created) const;
+ virtual SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor,
+ SelectionDAG &DAG,
+ std::vector<SDNode *> *Created) const {
+ return SDValue();
+ }
+
+ /// Indicate whether this target prefers to combine the given number of FDIVs
+ /// with the same divisor.
+ virtual bool combineRepeatedFPDivisors(unsigned NumUsers) const {
+ return false;
+ }
+
+ /// Hooks for building estimates in place of slower divisions and square
+ /// roots.
+
+ /// Return a reciprocal square root estimate value for the input operand.
+ /// The RefinementSteps output is the number of Newton-Raphson refinement
+ /// iterations required to generate a sufficient (though not necessarily
+ /// IEEE-754 compliant) estimate for the value type.
+ /// The boolean UseOneConstNR output is used to select a Newton-Raphson
+ /// algorithm implementation that uses one constant or two constants.
+ /// A target may choose to implement its own refinement within this function.
+ /// If that's true, then return '0' as the number of RefinementSteps to avoid
+ /// any further refinement of the estimate.
+ /// An empty SDValue return means no estimate sequence can be created.
+ virtual SDValue getRsqrtEstimate(SDValue Operand,
+ DAGCombinerInfo &DCI,
+ unsigned &RefinementSteps,
+ bool &UseOneConstNR) const {
+ return SDValue();
+ }
+
+ /// Return a reciprocal estimate value for the input operand.
+ /// The RefinementSteps output is the number of Newton-Raphson refinement
+ /// iterations required to generate a sufficient (though not necessarily
+ /// IEEE-754 compliant) estimate for the value type.
+ /// A target may choose to implement its own refinement within this function.
+ /// If that's true, then return '0' as the number of RefinementSteps to avoid
+ /// any further refinement of the estimate.
+ /// An empty SDValue return means no estimate sequence can be created.
+ virtual SDValue getRecipEstimate(SDValue Operand,
+ DAGCombinerInfo &DCI,
+ unsigned &RefinementSteps) const {
+ return SDValue();
+ }
//===--------------------------------------------------------------------===//
// Legalization utility functions
@@ -2589,6 +2800,12 @@ public:
/// ARM 's' setting instructions.
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.
+ virtual bool useLoadStackGuardNode() const {
+ return false;
+ }
};
/// 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 7c32a5e3d0ca..73bf56f018e9 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -151,16 +151,10 @@ public:
return nullptr;
}
- /// \brief True if the section is atomized using the symbols in it.
- /// This is false if the section is not atomized at all (most ELF sections) or
- /// if it is atomized based on its contents (MachO' __TEXT,__cstring for
- /// example).
- virtual bool isSectionAtomizableBySymbols(const MCSection &Section) const;
-
protected:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler &Mang, const TargetMachine &TM) const;
+ Mangler &Mang, const TargetMachine &TM) const = 0;
};
} // end namespace llvm
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index b263c571d9e6..a4f95c061283 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -24,7 +24,6 @@
namespace llvm {
class InstrItineraryData;
-class JITCodeEmitter;
class GlobalValue;
class Mangler;
class MCAsmInfo;
@@ -35,9 +34,7 @@ class Target;
class DataLayout;
class TargetLibraryInfo;
class TargetFrameLowering;
-class TargetInstrInfo;
class TargetIntrinsicInfo;
-class TargetJITInfo;
class TargetLowering;
class TargetPassConfig;
class TargetRegisterInfo;
@@ -47,6 +44,7 @@ class ScalarTargetTransformInfo;
class VectorTargetTransformInfo;
class formatted_raw_ostream;
class raw_ostream;
+class TargetLoweringObjectFile;
// The old pass manager infrastructure is hidden in a legacy namespace now.
namespace legacy {
@@ -87,47 +85,27 @@ protected: // Can only create subclasses.
unsigned RequireStructuredCFG : 1;
public:
+ mutable TargetOptions Options;
+
virtual ~TargetMachine();
const Target &getTarget() const { return TheTarget; }
- const StringRef getTargetTriple() const { return TargetTriple; }
- const StringRef getTargetCPU() const { return TargetCPU; }
- const StringRef getTargetFeatureString() const { return TargetFS; }
+ StringRef getTargetTriple() const { return TargetTriple; }
+ StringRef getTargetCPU() const { return TargetCPU; }
+ StringRef getTargetFeatureString() const { return TargetFS; }
/// getSubtargetImpl - virtual method implemented by subclasses that returns
/// a reference to that target's TargetSubtargetInfo-derived member variable.
virtual const TargetSubtargetInfo *getSubtargetImpl() const {
return nullptr;
}
-
- mutable TargetOptions Options;
-
- /// \brief Reset the target options based on the function's attributes.
- void resetTargetOptions(const MachineFunction *MF) const;
-
- // Interfaces to the major aspects of target machine information:
- //
- // -- Instruction opcode and operand information
- // -- Pipelines and scheduling information
- // -- Stack frame information
- // -- Selection DAG lowering information
- //
- // N.B. These objects may change during compilation. It's not safe to cache
- // them between functions.
- virtual const TargetInstrInfo *getInstrInfo() const { return nullptr; }
- virtual const TargetFrameLowering *getFrameLowering() const {
- return nullptr;
+ virtual const TargetSubtargetInfo *getSubtargetImpl(const Function &) const {
+ return getSubtargetImpl();
}
- virtual const TargetLowering *getTargetLowering() const { return nullptr; }
- virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const {
+ virtual TargetLoweringObjectFile *getObjFileLowering() const {
return nullptr;
}
- virtual const DataLayout *getDataLayout() const { return nullptr; }
-
- /// getMCAsmInfo - Return target specific asm information.
- ///
- const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; }
/// getSubtarget - This method returns a pointer to the specified type of
/// TargetSubtargetInfo. In debug builds, it verifies that the object being
@@ -135,27 +113,23 @@ public:
template<typename STC> const STC &getSubtarget() const {
return *static_cast<const STC*>(getSubtargetImpl());
}
+ template <typename STC> const STC &getSubtarget(const Function *) const {
+ return *static_cast<const STC*>(getSubtargetImpl());
+ }
+
+ /// \brief Reset the target options based on the function's attributes.
+ // FIXME: Remove TargetOptions that affect per-function code generation
+ // from TargetMachine.
+ void resetTargetOptions(const Function &F) const;
- /// 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.
+ /// getMCAsmInfo - Return target specific asm information.
///
- virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; }
+ const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; }
/// getIntrinsicInfo - If intrinsic information is available, return it. If
/// not, return null.
///
- virtual const TargetIntrinsicInfo *getIntrinsicInfo() const { return nullptr;}
-
- /// getJITInfo - If this target supports a JIT, return information for it,
- /// otherwise return null.
- ///
- virtual TargetJITInfo *getJITInfo() { return nullptr; }
-
- /// getInstrItineraryData - Returns instruction itinerary data for the target
- /// or specific subtarget.
- ///
- virtual const InstrItineraryData *getInstrItineraryData() const {
+ virtual const TargetIntrinsicInfo *getIntrinsicInfo() const {
return nullptr;
}
@@ -233,18 +207,6 @@ public:
return true;
}
- /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
- /// get machine code emitted. This uses a JITCodeEmitter object to handle
- /// actually outputting the machine code and resolving things like the address
- /// of functions. This method returns true if machine code emission is
- /// not supported.
- ///
- virtual bool addPassesToEmitMachineCode(PassManagerBase &,
- JITCodeEmitter &,
- bool /*DisableVerify*/ = true) {
- return true;
- }
-
/// addPassesToEmitMC - Add passes to the specified pass manager to get
/// machine code emitted with the MCJIT. This method returns true if machine
/// code is not supported. It fills the MCContext Ctx pointer which can be
@@ -291,15 +253,6 @@ public:
AnalysisID StartAfter = nullptr,
AnalysisID StopAfter = nullptr) override;
- /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
- /// get machine code emitted. This uses a JITCodeEmitter object to handle
- /// actually outputting the machine code and resolving things like the address
- /// of functions. This method returns true if machine code emission is
- /// not supported.
- ///
- bool addPassesToEmitMachineCode(PassManagerBase &PM, JITCodeEmitter &MCE,
- bool DisableVerify = true) override;
-
/// addPassesToEmitMC - Add passes to the specified pass manager to get
/// machine code emitted with the MCJIT. This method returns true if machine
/// code is not supported. It fills the MCContext Ctx pointer which can be
@@ -307,14 +260,6 @@ public:
///
bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
raw_ostream &OS, bool DisableVerify = true) override;
-
- /// addCodeEmitter - This pass should be overridden by the target to add a
- /// code emitter, if supported. If this is not supported, 'true' should be
- /// returned.
- virtual bool addCodeEmitter(PassManagerBase &,
- JITCodeEmitter &) {
- return true;
- }
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
index abb3ecacaefd..afc22365eba7 100644
--- a/include/llvm/Target/TargetOpcodes.h
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -104,7 +104,24 @@ enum {
/// 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
+ 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 function's frame allocation in a
+ /// label. Created by the llvm.frameallocate intrinsic. It has two arguments:
+ /// the symbol for the label and the frame index of the stack allocation.
+ FRAME_ALLOC = 21,
};
} // end namespace TargetOpcode
} // end namespace llvm
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index 922fae54bb80..9ab8242578fd 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -50,6 +50,21 @@ namespace llvm {
};
}
+ namespace ThreadModel {
+ enum Model {
+ POSIX, // POSIX Threads
+ Single // Single Threaded Environment
+ };
+ }
+
+ enum class CFIntegrity {
+ Sub, // Use subtraction-based checks.
+ Ror, // Use rotation-based checks.
+ Add // Use addition-based checks. This depends on having
+ // sufficient alignment in the code and is usually not
+ // feasible.
+ };
+
class TargetOptions {
public:
TargetOptions()
@@ -63,9 +78,11 @@ namespace llvm {
EnableFastISel(false), PositionIndependentExecutable(false),
UseInitArray(false), DisableIntegratedAS(false),
CompressDebugSections(false), FunctionSections(false),
- DataSections(false), TrapUnreachable(false), TrapFuncName(""),
+ DataSections(false), TrapUnreachable(false), TrapFuncName(),
FloatABIType(FloatABI::Default),
- AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single) {}
+ AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single),
+ FCFI(false), ThreadModel(ThreadModel::POSIX),
+ CFIType(CFIntegrity::Sub), CFIEnforcing(false), CFIFuncName() {}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
/// option is specified on the command line, and should enable debugging
@@ -220,6 +237,28 @@ namespace llvm {
/// create for functions that have the jumptable attribute.
JumpTable::JumpTableType JTType;
+ /// FCFI - This flags controls whether or not forward-edge control-flow
+ /// integrity is applied.
+ bool FCFI;
+
+ /// ThreadModel - This flag specifies the type of threading model to assume
+ /// for things like atomics
+ ThreadModel::Model ThreadModel;
+
+ /// CFIType - This flag specifies the type of control-flow integrity check
+ /// to add as a preamble to indirect calls.
+ CFIntegrity CFIType;
+
+ /// CFIEnforcing - This flags controls whether or not CFI violations cause
+ /// the program to halt.
+ bool CFIEnforcing;
+
+ /// getCFIFuncName - If this returns a non-empty string, then this is the
+ /// name of the function that will be called for each CFI violation in
+ /// non-enforcing mode.
+ std::string CFIFuncName;
+ StringRef getCFIFuncName() const;
+
/// Machine level options.
MCTargetOptions MCOptions;
};
@@ -249,6 +288,12 @@ inline bool operator==(const TargetOptions &LHS,
ARE_EQUAL(TrapFuncName) &&
ARE_EQUAL(FloatABIType) &&
ARE_EQUAL(AllowFPOpFusion) &&
+ ARE_EQUAL(JTType) &&
+ ARE_EQUAL(FCFI) &&
+ ARE_EQUAL(ThreadModel) &&
+ ARE_EQUAL(CFIType) &&
+ ARE_EQUAL(CFIEnforcing) &&
+ ARE_EQUAL(CFIFuncName) &&
ARE_EQUAL(MCOptions);
#undef ARE_EQUAL
}
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 5dda8bd4b938..a7552565c938 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/MC/MCRegisterInfo.h"
#include <cassert>
@@ -45,6 +45,7 @@ public:
const vt_iterator VTs;
const uint32_t *SubClassMask;
const uint16_t *SuperRegIndices;
+ const unsigned LaneMask;
const sc_iterator SuperClasses;
ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
@@ -52,10 +53,6 @@ public:
///
unsigned getID() const { return MC->getID(); }
- /// getName() - Return the register class name for debugging.
- ///
- const char *getName() const { return MC->getName(); }
-
/// begin/end - Return all of the registers in this class.
///
iterator begin() const { return MC->begin(); }
@@ -101,9 +98,9 @@ public:
/// hasType - return true if this TargetRegisterClass has the ValueType vt.
///
- bool hasType(EVT vt) const {
+ bool hasType(MVT vt) const {
for(int i = 0; VTs[i] != MVT::Other; ++i)
- if (EVT(VTs[i]) == vt)
+ if (MVT(VTs[i]) == vt)
return true;
return false;
}
@@ -194,6 +191,13 @@ public:
ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF) const {
return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs());
}
+
+ /// 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.
+ unsigned getLaneMask() const {
+ return LaneMask;
+ }
};
/// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about
@@ -306,7 +310,7 @@ public:
/// register of the given type, picking the most sub register class of
/// the right type that contains this physreg.
const TargetRegisterClass *
- getMinimalPhysRegClass(unsigned Reg, EVT VT = MVT::Other) const;
+ getMinimalPhysRegClass(unsigned Reg, MVT VT = MVT::Other) const;
/// getAllocatableClass - Return the maximal subclass of the given register
/// class that is alloctable, or NULL.
@@ -452,6 +456,11 @@ public:
/// used by register scavenger to determine what registers are free.
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
+ /// Prior to adding the live-out mask to a stackmap or patchpoint
+ /// instruction, provide the target the opportunity to adjust it (mainly to
+ /// remove pseudo-registers that should be ignored).
+ virtual void adjustStackMapLiveOutMask(uint32_t *Mask) const { }
+
/// getMatchingSuperReg - Return a super-register of the specified register
/// Reg so its sub-register of index SubIdx is Reg.
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
@@ -506,12 +515,31 @@ public:
return composeSubRegIndicesImpl(a, b);
}
+ /// Transforms a LaneMask computed for one subregister to the lanemask that
+ /// would have been computed when composing the subsubregisters with IdxA
+ /// first. @sa composeSubRegIndices()
+ unsigned composeSubRegIndexLaneMask(unsigned IdxA, unsigned LaneMask) const {
+ if (!IdxA)
+ return LaneMask;
+ return composeSubRegIndexLaneMaskImpl(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);
+
protected:
/// Overridden by TableGen in targets that have sub-registers.
virtual unsigned composeSubRegIndicesImpl(unsigned, unsigned) const {
llvm_unreachable("Target has no sub-registers");
}
+ /// Overridden by TableGen in targets that have sub-registers.
+ virtual unsigned
+ composeSubRegIndexLaneMaskImpl(unsigned, unsigned) const {
+ llvm_unreachable("Target has no sub-registers");
+ }
+
public:
/// getCommonSuperRegClass - Find a common super-register class if it exists.
///
@@ -561,6 +589,11 @@ public:
return RegClassBegin[i];
}
+ /// getRegClassName - Returns the name of the register class.
+ const char *getRegClassName(const TargetRegisterClass *Class) const {
+ return MCRegisterInfo::getRegClassName(Class->MC);
+ }
+
/// getCommonSubClass - find the largest common subclass of A and B. Return
/// NULL if there is no common subclass.
const TargetRegisterClass *
@@ -683,12 +716,6 @@ public:
/// (3) Bottom-up allocation is no longer guaranteed to optimally color.
virtual bool reverseLocalAssignment() const { return false; }
- /// Allow the target to override register assignment heuristics based on the
- /// live range size. If this returns false, then local live ranges are always
- /// assigned in order regardless of their size. This is a temporary hook for
- /// debugging downstream codegen failures exposed by regalloc.
- virtual bool mayOverrideLocalAssignment() const { return true; }
-
/// Allow the target to override the cost of using a callee-saved register for
/// the first time. Default value of 0 means we will use a callee-saved
/// register if it is available.
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 2d822de4ad69..907baa1b9b1f 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -162,6 +162,10 @@ def SDTBr : SDTypeProfile<0, 1, [ // br
SDTCisVT<0, OtherVT>
]>;
+def SDTBrCC : SDTypeProfile<0, 4, [ // brcc
+ SDTCisVT<0, OtherVT>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
+]>;
+
def SDTBrcond : SDTypeProfile<0, 2, [ // brcond
SDTCisInt<0>, SDTCisVT<1, OtherVT>
]>;
@@ -184,6 +188,14 @@ def SDTIStore : SDTypeProfile<1, 3, [ // indexed store
SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3>
]>;
+def SDTMaskedStore: SDTypeProfile<0, 3, [ // masked store
+ SDTCisPtrTy<0>, SDTCisVec<1>, SDTCisVec<2>
+]>;
+
+def SDTMaskedLoad: SDTypeProfile<1, 3, [ // masked load
+ SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisVec<2>, SDTCisSameAs<0, 3>
+]>;
+
def SDTVecShuffle : SDTypeProfile<1, 2, [
SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
]>;
@@ -369,6 +381,8 @@ def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>;
def frem : SDNode<"ISD::FREM" , SDTFPBinOp>;
def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp>;
def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>;
+def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp>;
+def fmaxnum : SDNode<"ISD::FMAXNUM" , SDTFPBinOp>;
def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>;
def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>;
def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>;
@@ -400,6 +414,7 @@ def select : SDNode<"ISD::SELECT" , SDTSelect>;
def vselect : SDNode<"ISD::VSELECT" , SDTVSelect>;
def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>;
+def brcc : SDNode<"ISD::BR_CC" , SDTBrCC, [SDNPHasChain]>;
def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>;
def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>;
def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
@@ -447,6 +462,11 @@ def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad,
def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore,
[SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+def masked_store : SDNode<"ISD::MSTORE", SDTMaskedStore,
+ [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+def masked_load : SDNode<"ISD::MLOAD", SDTMaskedLoad,
+ [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
+
// Do not use ld, st directly. Use load, extload, sextload, zextload, store,
// and truncst (see below).
def ld : SDNode<"ISD::LOAD" , SDTLoad,
diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h
index 78a2db183fb1..d1a3fcf4a50e 100644
--- a/include/llvm/Target/TargetSelectionDAGInfo.h
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -46,7 +46,7 @@ public:
/// 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
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index 86e303e18348..4ff88d07bf27 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -14,17 +14,24 @@
#ifndef LLVM_TARGET_TARGETSUBTARGETINFO_H
#define LLVM_TARGET_TARGETSUBTARGETINFO_H
+#include "llvm/CodeGen/PBQPRAConstraint.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/CodeGen.h"
namespace llvm {
+class DataLayout;
class MachineFunction;
class MachineInstr;
class SDep;
class SUnit;
+class TargetFrameLowering;
+class TargetInstrInfo;
+class TargetLowering;
class TargetRegisterClass;
+class TargetRegisterInfo;
class TargetSchedModel;
+class TargetSelectionDAGInfo;
struct MachineSchedPolicy;
template <typename T> class SmallVectorImpl;
@@ -47,6 +54,38 @@ public:
virtual ~TargetSubtargetInfo();
+ // Interfaces to the major aspects of target machine information:
+ //
+ // -- Instruction opcode and operand information
+ // -- Pipelines and scheduling information
+ // -- Stack frame information
+ // -- Selection DAG lowering information
+ //
+ // N.B. These objects may change during compilation. It's not safe to cache
+ // them between functions.
+ virtual const TargetInstrInfo *getInstrInfo() const { return nullptr; }
+ virtual const TargetFrameLowering *getFrameLowering() const {
+ return nullptr;
+ }
+ virtual const TargetLowering *getTargetLowering() const { return nullptr; }
+ virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const {
+ return nullptr;
+ }
+ virtual const DataLayout *getDataLayout() const { return nullptr; }
+
+ /// 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.
+ ///
+ virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; }
+
+ /// getInstrItineraryData - Returns instruction itinerary data for the target
+ /// or specific subtarget.
+ ///
+ virtual const InstrItineraryData *getInstrItineraryData() const {
+ return nullptr;
+ }
+
/// Resolve a SchedClass at runtime, where SchedClass identifies an
/// MCSchedClassDesc with the isVariant property. This may return the ID of
/// another variant SchedClass, but repeated invocation must quickly terminate
@@ -74,7 +113,7 @@ public:
virtual bool enablePostMachineScheduler() const;
/// \brief True if the subtarget should run the atomic expansion pass.
- virtual bool enableAtomicExpandLoadLinked() const;
+ virtual bool enableAtomicExpand() const;
/// \brief Override generic scheduling policy within a region.
///
@@ -90,26 +129,26 @@ public:
// dependency.
virtual void adjustSchedDependency(SUnit *def, SUnit *use,
SDep& dep) const { }
-
+
// For use with PostRAScheduling: get the anti-dependence breaking that should
// be performed before post-RA scheduling.
virtual AntiDepBreakMode getAntiDepBreakMode() const {
return ANTIDEP_NONE;
}
-
+
// For use with PostRAScheduling: in CriticalPathRCs, return any register
// classes that should only be considered for anti-dependence breaking if they
// are on the critical path.
virtual void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
return CriticalPathRCs.clear();
}
-
+
// For use with PostRAScheduling: get the minimum optimization level needed
// to enable post-RA scheduling.
virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const {
return CodeGenOpt::Default;
}
-
+
/// \brief True if the subtarget should run the local reassignment
/// heuristic of the register allocator.
/// This heuristic may be compile time intensive, \p OptLevel provides
@@ -123,9 +162,17 @@ public:
/// \brief Enable the use of the early if conversion pass.
virtual bool enableEarlyIfConversion() const { return false; }
- /// \brief Reset the features for the subtarget.
- virtual void resetSubtargetFeatures(const MachineFunction *MF) { }
+ /// \brief Return PBQPConstraint(s) for the target.
+ ///
+ /// Override to provide custom PBQP constraints.
+ virtual std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const {
+ return nullptr;
+ }
+ /// Enable tracking of subregister liveness in register allocator.
+ virtual bool enableSubRegLiveness() const {
+ return false;
+ }
};
} // End llvm namespace