summaryrefslogtreecommitdiff
path: root/include/llvm/Target
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Target')
-rw-r--r--include/llvm/Target/GenericOpcodes.td121
-rw-r--r--include/llvm/Target/GlobalISel/RegisterBank.td16
-rw-r--r--include/llvm/Target/GlobalISel/SelectionDAGCompat.td (renamed from include/llvm/Target/TargetGlobalISel.td)24
-rw-r--r--include/llvm/Target/GlobalISel/Target.td56
-rw-r--r--include/llvm/Target/Target.td33
-rw-r--r--include/llvm/Target/TargetCallingConv.h202
-rw-r--r--include/llvm/Target/TargetInstrInfo.h140
-rw-r--r--include/llvm/Target/TargetLowering.h154
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h50
-rw-r--r--include/llvm/Target/TargetMachine.h12
-rw-r--r--include/llvm/Target/TargetOpcodes.def55
-rw-r--r--include/llvm/Target/TargetOptions.h89
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h12
-rw-r--r--include/llvm/Target/TargetSchedule.td5
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td22
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h8
16 files changed, 687 insertions, 312 deletions
diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td
index 8694eb5797d04..de3796cd4ee56 100644
--- a/include/llvm/Target/GenericOpcodes.td
+++ b/include/llvm/Target/GenericOpcodes.td
@@ -91,6 +91,21 @@ def G_FCONSTANT : Instruction {
let hasSideEffects = 0;
}
+def G_VASTART : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins type0:$list);
+ let hasSideEffects = 0;
+ let mayStore = 1;
+}
+
+def G_VAARG : Instruction {
+ let OutOperandList = (outs type0:$val);
+ let InOperandList = (ins type1:$list, unknown:$align);
+ let hasSideEffects = 0;
+ let mayLoad = 1;
+ let mayStore = 1;
+}
+
//------------------------------------------------------------------------------
// Binary ops.
//------------------------------------------------------------------------------
@@ -103,13 +118,6 @@ def G_ADD : Instruction {
let isCommutable = 1;
}
-// Generic pointer offset.
-def G_GEP : Instruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = 0;
-}
-
// Generic subtraction.
def G_SUB : Instruction {
let OutOperandList = (outs type0:$dst);
@@ -224,6 +232,19 @@ def G_SELECT : Instruction {
let hasSideEffects = 0;
}
+// Generic pointer offset.
+def G_GEP : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type1:$src2);
+ let hasSideEffects = 0;
+}
+
+def G_PTR_MASK : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src, unknown:$bits);
+ let hasSideEffects = 0;
+}
+
//------------------------------------------------------------------------------
// Overflow ops
//------------------------------------------------------------------------------
@@ -273,10 +294,34 @@ def G_SMULO : Instruction {
let isCommutable = 1;
}
+// Multiply two numbers at twice the incoming bit width (unsigned) and return
+// the high half of the result.
+def G_UMULH : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+ let isCommutable = 1;
+}
+
+// Multiply two numbers at twice the incoming bit width (signed) and return
+// the high half of the result.
+def G_SMULH : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+ let isCommutable = 1;
+}
+
//------------------------------------------------------------------------------
// Floating Point Unary Ops.
//------------------------------------------------------------------------------
+def G_FNEG : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src);
+ let hasSideEffects = 0;
+}
+
def G_FPEXT : Instruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
@@ -355,6 +400,13 @@ def G_FREM : Instruction {
let hasSideEffects = 0;
}
+// Floating point exponentiation.
+def G_FPOW : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+}
+
//------------------------------------------------------------------------------
// Memory ops
//------------------------------------------------------------------------------
@@ -383,17 +435,24 @@ def G_STORE : Instruction {
// indexes. This will almost certainly be mapped to sub-register COPYs after
// register banks have been selected.
def G_EXTRACT : Instruction {
+ let OutOperandList = (outs type0:$res);
+ let InOperandList = (ins type1:$src, unknown:$offset);
+ let hasSideEffects = 0;
+}
+
+// Extract multiple registers specified size, starting from blocks given by
+// indexes. This will almost certainly be mapped to sub-register COPYs after
+// register banks have been selected.
+def G_UNMERGE_VALUES : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let hasSideEffects = 0;
}
-// Insert a sequence of smaller registers into a larger one at the specified
-// indices (interleaved with the values in the operand list "op0, bit0, op1,
-// bit1, ...")).
+// Insert a smaller register into a larger one at the specified bit-index.
def G_INSERT : Instruction {
let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, variable_ops);
+ let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
let hasSideEffects = 0;
}
@@ -406,6 +465,12 @@ def G_SEQUENCE : Instruction {
let hasSideEffects = 0;
}
+def G_MERGE_VALUES : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins variable_ops);
+ let hasSideEffects = 0;
+}
+
// Intrinsic without side effects.
def G_INTRINSIC : Instruction {
let OutOperandList = (outs);
@@ -445,4 +510,38 @@ def G_BRCOND : Instruction {
let isTerminator = 1;
}
+// Generic indirect branch.
+def G_BRINDIRECT : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins type0:$src1);
+ let hasSideEffects = 0;
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+
+//------------------------------------------------------------------------------
+// Vector ops
+//------------------------------------------------------------------------------
+
+// Generic insertelement.
+def G_INSERT_VECTOR_ELT : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
+ let hasSideEffects = 0;
+}
+
+// Generic extractelement.
+def G_EXTRACT_VECTOR_ELT : Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$src, type2:$idx);
+ let hasSideEffects = 0;
+}
+
+// Generic shufflevector.
+def G_SHUFFLE_VECTOR: Instruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask);
+ let hasSideEffects = 0;
+}
+
// TODO: Add the other generic opcodes.
diff --git a/include/llvm/Target/GlobalISel/RegisterBank.td b/include/llvm/Target/GlobalISel/RegisterBank.td
new file mode 100644
index 0000000000000..4dfd139e9fb6f
--- /dev/null
+++ b/include/llvm/Target/GlobalISel/RegisterBank.td
@@ -0,0 +1,16 @@
+//===- RegisterBank.td - Register bank definitions ---------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+class RegisterBank<string name, list<RegisterClass> classes> {
+ string Name = name;
+ list<RegisterClass> RegisterClasses = classes;
+}
diff --git a/include/llvm/Target/TargetGlobalISel.td b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
index 0727c9802e5e4..9f034220815f2 100644
--- a/include/llvm/Target/TargetGlobalISel.td
+++ b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -25,5 +25,29 @@ class GINodeEquiv<Instruction i, SDNode node> {
SDNode Node = node;
}
+def : GINodeEquiv<G_ZEXT, zext>;
+def : GINodeEquiv<G_SEXT, sext>;
def : GINodeEquiv<G_ADD, add>;
+def : GINodeEquiv<G_SUB, sub>;
+def : GINodeEquiv<G_MUL, mul>;
+
+def : GINodeEquiv<G_OR, or>;
+def : GINodeEquiv<G_XOR, xor>;
+def : GINodeEquiv<G_AND, and>;
+
+def : GINodeEquiv<G_SHL, shl>;
+def : GINodeEquiv<G_LSHR, srl>;
+def : GINodeEquiv<G_ASHR, sra>;
+
+def : GINodeEquiv<G_SDIV, sdiv>;
+def : GINodeEquiv<G_UDIV, udiv>;
+def : GINodeEquiv<G_SREM, srem>;
+def : GINodeEquiv<G_UREM, urem>;
+
def : GINodeEquiv<G_BR, br>;
+
+// Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern.
+// Should be used on defs that subclass GIComplexOperandMatcher<>.
+class GIComplexPatternEquiv<ComplexPattern seldag> {
+ ComplexPattern SelDAGEquivalent = seldag;
+}
diff --git a/include/llvm/Target/GlobalISel/Target.td b/include/llvm/Target/GlobalISel/Target.td
new file mode 100644
index 0000000000000..fa1a424b58954
--- /dev/null
+++ b/include/llvm/Target/GlobalISel/Target.td
@@ -0,0 +1,56 @@
+//===- Target.td - Define GlobalISel rules -----------------*- 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 target-independent interfaces used to support
+// SelectionDAG instruction selection patterns (specified in
+// TargetSelectionDAG.td) when generating GlobalISel instruction selectors.
+//
+// This is intended as a compatibility layer, to enable reuse of target
+// descriptions written for SelectionDAG without requiring explicit GlobalISel
+// support. It will eventually supersede SelectionDAG patterns.
+//
+//===----------------------------------------------------------------------===//
+
+// Definitions that inherit from LLT define types that will be used in the
+// GlobalISel matcher.
+class LLT;
+
+def s32 : LLT;
+def s64 : LLT;
+
+// Defines a matcher for complex operands. This is analogous to ComplexPattern
+// from SelectionDAG.
+//
+// Definitions that inherit from this may also inherit from
+// GIComplexPatternEquiv to enable the import of SelectionDAG patterns involving
+// those ComplexPatterns.
+class GIComplexOperandMatcher<LLT type, dag operands, string matcherfn> {
+ // The expected type of the root of the match.
+ //
+ // TODO: We should probably support, any-type, any-scalar, and multiple types
+ // in the future.
+ LLT Type = type;
+
+ // The operands that result from a successful match
+ // Should be of the form '(ops ty1, ty2, ...)' where ty1/ty2 are definitions
+ // that inherit from Operand.
+ //
+ // FIXME: Which definition is used for ty1/ty2 doesn't actually matter at the
+ // moment. Only the number of operands is used.
+ dag Operands = operands;
+
+ // The function that determines whether the operand matches. It should be of
+ // the form:
+ // bool select(const MatchOperand &Root, MatchOperand &Result1)
+ // and should have the same number of ResultX arguments as the number of
+ // result operands. It must return true on successful match and false
+ // otherwise. If it returns true, then all the ResultX arguments must be
+ // overwritten.
+ string MatcherFn = matcherfn;
+}
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 729d7669e0fae..b21689e0e1346 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -402,11 +402,8 @@ class Instruction {
// 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.
- //
+ // Does the instruction have side effects that are not captured by any
+ // operands of the instruction or other flags?
bit hasSideEffects = ?;
// Is this instruction a "real" instruction (with a distinct machine
@@ -951,11 +948,12 @@ def LOCAL_ESCAPE : Instruction {
let hasSideEffects = 0;
let hasCtrlDep = 1;
}
-def FAULTING_LOAD_OP : Instruction {
+def FAULTING_OP : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins variable_ops);
let usesCustomInserter = 1;
let mayLoad = 1;
+ let mayStore = 1;
let isTerminator = 1;
let isBranch = 1;
}
@@ -998,6 +996,15 @@ def PATCHABLE_TAIL_CALL : Instruction {
let hasSideEffects = 1;
let isReturn = 1;
}
+def FENTRY_CALL : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "# FEntry call";
+ let usesCustomInserter = 1;
+ let mayLoad = 1;
+ let mayStore = 1;
+ let hasSideEffects = 1;
+}
// Generic opcodes used in GlobalISel.
include "llvm/Target/GenericOpcodes.td"
@@ -1342,6 +1349,16 @@ include "llvm/Target/TargetCallingConv.td"
include "llvm/Target/TargetSelectionDAG.td"
//===----------------------------------------------------------------------===//
-// Pull in the common support for Global ISel generation.
+// Pull in the common support for Global ISel register bank info generation.
+//
+include "llvm/Target/GlobalISel/RegisterBank.td"
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for DAG isel generation.
+//
+include "llvm/Target/GlobalISel/Target.td"
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for the Global ISel DAG-based selector generation.
//
-include "llvm/Target/TargetGlobalISel.td"
+include "llvm/Target/GlobalISel/SelectionDAGCompat.td"
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index be09236cdab02..4f750b8a289ff 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -14,146 +14,120 @@
#ifndef LLVM_TARGET_TARGETCALLINGCONV_H
#define LLVM_TARGET_TARGETCALLINGCONV_H
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
+#include <cassert>
#include <climits>
+#include <cstdint>
namespace llvm {
-
namespace ISD {
+
struct ArgFlagsTy {
private:
- static const uint64_t NoFlagSet = 0ULL;
- static const uint64_t ZExt = 1ULL<<0; ///< Zero extended
- static const uint64_t ZExtOffs = 0;
- static const uint64_t SExt = 1ULL<<1; ///< Sign extended
- static const uint64_t SExtOffs = 1;
- static const uint64_t InReg = 1ULL<<2; ///< Passed in register
- static const uint64_t InRegOffs = 2;
- static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr
- static const uint64_t SRetOffs = 3;
- static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value
- static const uint64_t ByValOffs = 4;
- static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain
- static const uint64_t NestOffs = 5;
- static const uint64_t Returned = 1ULL<<6; ///< Always returned
- static const uint64_t ReturnedOffs = 6;
- static const uint64_t ByValAlign = 0xFULL<<7; ///< Struct alignment
- static const uint64_t ByValAlignOffs = 7;
- static const uint64_t Split = 1ULL<<11;
- static const uint64_t SplitOffs = 11;
- static const uint64_t InAlloca = 1ULL<<12; ///< Passed with inalloca
- 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 Hva = 1ULL << 16; ///< HVA field for
- ///< vectorcall
- static const uint64_t HvaOffs = 16;
- static const uint64_t HvaStart = 1ULL << 17; ///< HVA structure start
- ///< for vectorcall
- static const uint64_t HvaStartOffs = 17;
- static const uint64_t SecArgPass = 1ULL << 18; ///< Second argument
- ///< pass for vectorcall
- static const uint64_t SecArgPassOffs = 18;
- static const uint64_t OrigAlign = 0x1FULL<<27;
- static const uint64_t OrigAlignOffs = 27;
- static const uint64_t ByValSize = 0x3fffffffULL<<32; ///< Struct size
- static const uint64_t ByValSizeOffs = 32;
- static const uint64_t InConsecutiveRegsLast = 0x1ULL<<62; ///< Struct size
- static const uint64_t InConsecutiveRegsLastOffs = 62;
- static const uint64_t InConsecutiveRegs = 0x1ULL<<63; ///< Struct size
- static const uint64_t InConsecutiveRegsOffs = 63;
-
- static const uint64_t One = 1ULL; ///< 1 of this type, for shifts
-
- uint64_t Flags;
+ unsigned IsZExt : 1; ///< Zero extended
+ unsigned IsSExt : 1; ///< Sign extended
+ unsigned IsInReg : 1; ///< Passed in register
+ unsigned IsSRet : 1; ///< Hidden struct-ret ptr
+ unsigned IsByVal : 1; ///< Struct passed by value
+ unsigned IsNest : 1; ///< Nested fn static chain
+ unsigned IsReturned : 1; ///< Always returned
+ unsigned IsSplit : 1;
+ unsigned IsInAlloca : 1; ///< Passed with inalloca
+ unsigned IsSplitEnd : 1; ///< Last part of a split
+ unsigned IsSwiftSelf : 1; ///< Swift self parameter
+ unsigned IsSwiftError : 1; ///< Swift error parameter
+ unsigned IsHva : 1; ///< HVA field for
+ unsigned IsHvaStart : 1; ///< HVA structure start
+ unsigned IsSecArgPass : 1; ///< Second argument
+ unsigned ByValAlign : 4; ///< Log 2 of byval alignment
+ unsigned OrigAlign : 5; ///< Log 2 of original alignment
+ unsigned IsInConsecutiveRegsLast : 1;
+ unsigned IsInConsecutiveRegs : 1;
+ unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
+
+ unsigned ByValSize; ///< Byval struct size
public:
- ArgFlagsTy() : Flags(0) { }
+ ArgFlagsTy()
+ : IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsNest(0),
+ IsReturned(0), IsSplit(0), IsInAlloca(0), IsSplitEnd(0),
+ IsSwiftSelf(0), IsSwiftError(0), IsHva(0), IsHvaStart(0),
+ IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
+ IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
+ IsCopyElisionCandidate(0), ByValSize(0) {
+ static_assert(sizeof(*this) == 2 * sizeof(unsigned), "flags are too big");
+ }
- bool isZExt() const { return Flags & ZExt; }
- void setZExt() { Flags |= One << ZExtOffs; }
+ bool isZExt() const { return IsZExt; }
+ void setZExt() { IsZExt = 1; }
- bool isSExt() const { return Flags & SExt; }
- void setSExt() { Flags |= One << SExtOffs; }
+ bool isSExt() const { return IsSExt; }
+ void setSExt() { IsSExt = 1; }
- bool isInReg() const { return Flags & InReg; }
- void setInReg() { Flags |= One << InRegOffs; }
+ bool isInReg() const { return IsInReg; }
+ void setInReg() { IsInReg = 1; }
- bool isSRet() const { return Flags & SRet; }
- void setSRet() { Flags |= One << SRetOffs; }
+ bool isSRet() const { return IsSRet; }
+ void setSRet() { IsSRet = 1; }
- bool isByVal() const { return Flags & ByVal; }
- void setByVal() { Flags |= One << ByValOffs; }
+ bool isByVal() const { return IsByVal; }
+ void setByVal() { IsByVal = 1; }
- bool isInAlloca() const { return Flags & InAlloca; }
- void setInAlloca() { Flags |= One << InAllocaOffs; }
+ bool isInAlloca() const { return IsInAlloca; }
+ void setInAlloca() { IsInAlloca = 1; }
- bool isSwiftSelf() const { return Flags & SwiftSelf; }
- void setSwiftSelf() { Flags |= One << SwiftSelfOffs; }
+ bool isSwiftSelf() const { return IsSwiftSelf; }
+ void setSwiftSelf() { IsSwiftSelf = 1; }
- bool isSwiftError() const { return Flags & SwiftError; }
- void setSwiftError() { Flags |= One << SwiftErrorOffs; }
+ bool isSwiftError() const { return IsSwiftError; }
+ void setSwiftError() { IsSwiftError = 1; }
- bool isHva() const { return Flags & Hva; }
- void setHva() { Flags |= One << HvaOffs; }
+ bool isHva() const { return IsHva; }
+ void setHva() { IsHva = 1; }
- bool isHvaStart() const { return Flags & HvaStart; }
- void setHvaStart() { Flags |= One << HvaStartOffs; }
+ bool isHvaStart() const { return IsHvaStart; }
+ void setHvaStart() { IsHvaStart = 1; }
- bool isSecArgPass() const { return Flags & SecArgPass; }
- void setSecArgPass() { Flags |= One << SecArgPassOffs; }
+ bool isSecArgPass() const { return IsSecArgPass; }
+ void setSecArgPass() { IsSecArgPass = 1; }
- bool isNest() const { return Flags & Nest; }
- void setNest() { Flags |= One << NestOffs; }
+ bool isNest() const { return IsNest; }
+ void setNest() { IsNest = 1; }
- bool isReturned() const { return Flags & Returned; }
- void setReturned() { Flags |= One << ReturnedOffs; }
+ bool isReturned() const { return IsReturned; }
+ void setReturned() { IsReturned = 1; }
- bool isInConsecutiveRegs() const { return Flags & InConsecutiveRegs; }
- void setInConsecutiveRegs() { Flags |= One << InConsecutiveRegsOffs; }
+ bool isInConsecutiveRegs() const { return IsInConsecutiveRegs; }
+ void setInConsecutiveRegs() { IsInConsecutiveRegs = 1; }
- bool isInConsecutiveRegsLast() const { return Flags & InConsecutiveRegsLast; }
- void setInConsecutiveRegsLast() { Flags |= One << InConsecutiveRegsLastOffs; }
+ bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; }
+ void setInConsecutiveRegsLast() { IsInConsecutiveRegsLast = 1; }
- unsigned getByValAlign() const {
- return (unsigned)
- ((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2);
- }
- void setByValAlign(unsigned A) {
- Flags = (Flags & ~ByValAlign) |
- (uint64_t(Log2_32(A) + 1) << ByValAlignOffs);
- }
+ bool isSplit() const { return IsSplit; }
+ void setSplit() { IsSplit = 1; }
- bool isSplit() const { return Flags & Split; }
- void setSplit() { Flags |= One << SplitOffs; }
+ bool isSplitEnd() const { return IsSplitEnd; }
+ void setSplitEnd() { IsSplitEnd = 1; }
- bool isSplitEnd() const { return Flags & SplitEnd; }
- void setSplitEnd() { Flags |= One << SplitEndOffs; }
+ bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; }
+ void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
- unsigned getOrigAlign() const {
- return (unsigned)
- ((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2);
- }
- void setOrigAlign(unsigned A) {
- Flags = (Flags & ~OrigAlign) |
- (uint64_t(Log2_32(A) + 1) << OrigAlignOffs);
+ unsigned getByValAlign() const { return (1U << ByValAlign) / 2; }
+ void setByValAlign(unsigned A) {
+ ByValAlign = Log2_32(A) + 1;
+ assert(getByValAlign() == A && "bitfield overflow");
}
- unsigned getByValSize() const {
- return (unsigned)((Flags & ByValSize) >> ByValSizeOffs);
- }
- void setByValSize(unsigned S) {
- Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
+ unsigned getOrigAlign() const { return (1U << OrigAlign) / 2; }
+ void setOrigAlign(unsigned A) {
+ OrigAlign = Log2_32(A) + 1;
+ assert(getOrigAlign() == A && "bitfield overflow");
}
- /// getRawBits - Represent the flags as a bunch of bits.
- uint64_t getRawBits() const { return Flags; }
+ unsigned getByValSize() const { return ByValSize; }
+ void setByValSize(unsigned S) { ByValSize = S; }
};
/// InputArg - This struct carries flags and type information about a
@@ -162,9 +136,9 @@ namespace ISD {
///
struct InputArg {
ArgFlagsTy Flags;
- MVT VT;
+ MVT VT = MVT::Other;
EVT ArgVT;
- bool Used;
+ bool Used = false;
/// Index original Function's argument.
unsigned OrigArgIndex;
@@ -176,7 +150,7 @@ namespace ISD {
/// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
unsigned PartOffset;
- InputArg() : VT(MVT::Other), Used(false) {}
+ InputArg() = default;
InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
unsigned origIdx, unsigned partOffs)
: Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
@@ -204,7 +178,7 @@ namespace ISD {
EVT ArgVT;
/// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
- bool IsFixed;
+ bool IsFixed = false;
/// Index original Function's argument.
unsigned OrigArgIndex;
@@ -214,7 +188,7 @@ namespace ISD {
/// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
unsigned PartOffset;
- OutputArg() : IsFixed(false) {}
+ OutputArg() = default;
OutputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool isfixed,
unsigned origIdx, unsigned partOffs)
: Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
@@ -223,8 +197,8 @@ namespace ISD {
ArgVT = argvt;
}
};
-} // end namespace ISD
-} // end llvm namespace
+} // end namespace ISD
+} // end namespace llvm
#endif // LLVM_TARGET_TARGETCALLINGCONV_H
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 247d694f2e47d..0dc9cf70d3350 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -152,6 +152,31 @@ public:
unsigned getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
unsigned getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
+ /// Returns true if the argument is a frame pseudo instruction.
+ bool isFrameInstr(const MachineInstr &I) const {
+ return I.getOpcode() == getCallFrameSetupOpcode() ||
+ I.getOpcode() == getCallFrameDestroyOpcode();
+ }
+
+ /// Returns true if the argument is a frame setup pseudo instruction.
+ bool isFrameSetup(const MachineInstr &I) const {
+ return I.getOpcode() == getCallFrameSetupOpcode();
+ }
+
+ /// Returns size of the frame associated with the given frame instruction.
+ /// For frame setup instruction this is frame that is set up space set up
+ /// after the instruction. For frame destroy instruction this is the frame
+ /// freed by the caller.
+ /// Note, in some cases a call frame (or a part of it) may be prepared prior
+ /// to the frame setup instruction. It occurs in the calls that involve
+ /// inalloca arguments. This function reports only the size of the frame part
+ /// that is set up between the frame setup and destroy pseudo instructions.
+ int64_t getFrameSize(const MachineInstr &I) const {
+ assert(isFrameInstr(I));
+ assert(I.getOperand(0).getImm() >= 0);
+ return I.getOperand(0).getImm();
+ }
+
unsigned getCatchReturnOpcode() const { return CatchRetOpcode; }
unsigned getReturnOpcode() const { return ReturnOpcode; }
@@ -1070,15 +1095,6 @@ public:
llvm_unreachable("target did not implement shouldClusterMemOps()");
}
- /// Can this target fuse the given instructions if they are scheduled
- /// adjacent. Note that you have to add:
- /// DAG.addMutation(createMacroFusionDAGMutation());
- /// to TargetPassConfig::createMachineScheduler() to have an effect.
- virtual bool shouldScheduleAdjacent(const MachineInstr &First,
- const MachineInstr &Second) const {
- llvm_unreachable("target did not implement shouldScheduleAdjacent()");
- }
-
/// Reverses the branch condition of the specified condition list,
/// returning false on success and true if it cannot be reversed.
virtual
@@ -1108,6 +1124,25 @@ public:
/// terminator instruction that has not been predicated.
virtual bool isUnpredicatedTerminator(const MachineInstr &MI) const;
+ /// Returns true if MI is an unconditional tail call.
+ virtual bool isUnconditionalTailCall(const MachineInstr &MI) const {
+ return false;
+ }
+
+ /// Returns true if the tail call can be made conditional on BranchCond.
+ virtual bool
+ canMakeTailCallConditional(SmallVectorImpl<MachineOperand> &Cond,
+ const MachineInstr &TailCall) const {
+ return false;
+ }
+
+ /// Replace the conditional branch in MBB with a conditional tail call.
+ virtual void replaceBranchWithTailCall(MachineBasicBlock &MBB,
+ SmallVectorImpl<MachineOperand> &Cond,
+ const MachineInstr &TailCall) const {
+ llvm_unreachable("Target didn't implement replaceBranchWithTailCall!");
+ }
+
/// Convert the instruction into a predicated instruction.
/// It returns true if the operation was successful.
virtual bool PredicateInstruction(MachineInstr &MI,
@@ -1132,7 +1167,7 @@ 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 {
+ virtual bool isPredicable(const MachineInstr &MI) const {
return MI.getDesc().isPredicable();
}
@@ -1427,10 +1462,17 @@ public:
return nullptr;
}
- // 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.
+ /// 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.
+ ///
+ /// Assumes any physical registers used to compute addresses have the same
+ /// value for both instructions. (This is the most useful assumption for
+ /// post-RA scheduling.)
+ ///
+ /// See also MachineInstr::mayAlias, which is implemented on top of this
+ /// function.
virtual bool
areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
AliasAnalysis *AA = nullptr) const {
@@ -1486,11 +1528,79 @@ public:
return None;
}
- /// Determines whether |Inst| is a tail call instruction.
+ /// Determines whether \p Inst is a tail call instruction. Override this
+ /// method on targets that do not properly set MCID::Return and MCID::Call on
+ /// tail call instructions."
virtual bool isTailCall(const MachineInstr &Inst) const {
+ return Inst.isReturn() && Inst.isCall();
+ }
+
+ /// True if the instruction is bound to the top of its basic block and no
+ /// other instructions shall be inserted before it. This can be implemented
+ /// to prevent register allocator to insert spills before such instructions.
+ virtual bool isBasicBlockPrologue(const MachineInstr &MI) const {
return false;
}
+ /// \brief Return how many instructions would be saved by outlining a
+ /// sequence containing \p SequenceSize instructions that appears
+ /// \p Occurrences times in a module.
+ virtual unsigned getOutliningBenefit(size_t SequenceSize, size_t Occurrences,
+ bool CanBeTailCall) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::getOutliningBenefit!");
+ }
+
+ /// Represents how an instruction should be mapped by the outliner.
+ /// \p Legal instructions are those which are safe to outline.
+ /// \p Illegal instructions are those which cannot be outlined.
+ /// \p Invisible instructions are instructions which can be outlined, but
+ /// shouldn't actually impact the outlining result.
+ enum MachineOutlinerInstrType {Legal, Illegal, Invisible};
+
+ /// Returns how or if \p MI should be outlined.
+ virtual MachineOutlinerInstrType getOutliningType(MachineInstr &MI) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::getOutliningType!");
+ }
+
+ /// Insert a custom epilogue for outlined functions.
+ /// This may be empty, in which case no epilogue or return statement will be
+ /// emitted.
+ virtual void insertOutlinerEpilogue(MachineBasicBlock &MBB,
+ MachineFunction &MF,
+ bool IsTailCall) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::insertOutlinerEpilogue!");
+ }
+
+ /// Insert a call to an outlined function into the program.
+ /// Returns an iterator to the spot where we inserted the call. This must be
+ /// implemented by the target.
+ virtual MachineBasicBlock::iterator
+ insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator &It, MachineFunction &MF,
+ bool IsTailCall) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::insertOutlinedCall!");
+ }
+
+ /// Insert a custom prologue for outlined functions.
+ /// This may be empty, in which case no prologue will be emitted.
+ virtual void insertOutlinerPrologue(MachineBasicBlock &MBB,
+ MachineFunction &MF,
+ bool IsTailCall) const {
+ llvm_unreachable(
+ "Target didn't implement TargetInstrInfo::insertOutlinerPrologue!");
+ }
+
+ /// Return true if the function can safely be outlined from.
+ /// By default, this means that the function has no red zone.
+ virtual bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const {
+ llvm_unreachable("Target didn't implement "
+ "TargetInstrInfo::isFunctionSafeToOutlineFrom!");
+ }
+
private:
unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
unsigned CatchRetOpcode;
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 3728a7a8cb179..85297ae837c56 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -25,13 +25,14 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
+#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Attributes.h"
@@ -163,6 +164,35 @@ public:
// or custom.
};
+ class ArgListEntry {
+ public:
+ Value *Val = nullptr;
+ SDValue Node = SDValue();
+ Type *Ty = nullptr;
+ bool IsSExt : 1;
+ bool IsZExt : 1;
+ bool IsInReg : 1;
+ bool IsSRet : 1;
+ bool IsNest : 1;
+ bool IsByVal : 1;
+ bool IsInAlloca : 1;
+ bool IsReturned : 1;
+ bool IsSwiftSelf : 1;
+ bool IsSwiftError : 1;
+ uint16_t Alignment = 0;
+
+ ArgListEntry()
+ : IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
+ IsNest(false), IsByVal(false), IsInAlloca(false), IsReturned(false),
+ IsSwiftSelf(false), IsSwiftError(false) {}
+
+ void setAttributes(ImmutableCallSite *CS, unsigned ArgIdx);
+ };
+ typedef std::vector<ArgListEntry> ArgListTy;
+
+ virtual void markLibCallAttributes(MachineFunction *MF, unsigned CC,
+ ArgListTy &Args) const {};
+
static ISD::NodeType getExtendForContent(BooleanContent Content) {
switch (Content) {
case UndefinedBooleanContent:
@@ -254,9 +284,7 @@ public:
/// several shifts, adds, and multiplies for this target.
/// The definition of "cheaper" may depend on whether we're optimizing
/// for speed or for size.
- virtual bool isIntDivCheap(EVT VT, AttributeSet Attr) const {
- return false;
- }
+ virtual bool isIntDivCheap(EVT VT, AttributeList Attr) const { return false; }
/// Return true if the target can handle a standalone remainder operation.
virtual bool hasStandaloneRem(EVT VT) const {
@@ -363,6 +391,9 @@ public:
return false;
}
+ /// Returns if it's reasonable to merge stores to MemVT size.
+ virtual bool canMergeStoresTo(EVT MemVT) const { return true; }
+
/// \brief Return true if it is cheap to speculate a call to intrinsic cttz.
virtual bool isCheapToSpeculateCttz() const {
return false;
@@ -395,16 +426,33 @@ public:
/// \brief Return if the target supports combining a
/// chain like:
/// \code
- /// %andResult = and %val1, #imm-with-one-bit-set;
+ /// %andResult = and %val1, #mask
/// %icmpResult = icmp %andResult, 0
- /// br i1 %icmpResult, label %dest1, label %dest2
/// \endcode
/// into a single machine instruction of a form like:
/// \code
- /// brOnBitSet %register, #bitNumber, dest
+ /// cc = test %register, #mask
/// \endcode
- bool isMaskAndBranchFoldingLegal() const {
- return MaskAndBranchFoldingIsLegal;
+ virtual bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const {
+ return false;
+ }
+
+ /// Use bitwise logic to make pairs of compares more efficient. For example:
+ /// and (seteq A, B), (seteq C, D) --> seteq (or (xor A, B), (xor C, D)), 0
+ /// This should be true when it takes more than one instruction to lower
+ /// setcc (cmp+set on x86 scalar), when bitwise ops are faster than logic on
+ /// condition bits (crand on PowerPC), and/or when reducing cmp+br is a win.
+ virtual bool convertSetCCLogicToBitwiseLogic(EVT VT) const {
+ return false;
+ }
+
+ /// Return the preferred operand type if the target has a quick way to compare
+ /// integer values of the given size. Assume that any legal integer type can
+ /// be compared efficiently. Targets may override this to allow illegal wide
+ /// types to return a vector type if there is support to compare that type.
+ virtual MVT hasFastEqualityCompare(unsigned NumBits) const {
+ MVT VT = MVT::getIntegerVT(NumBits);
+ return isTypeLegal(VT) ? VT : MVT::INVALID_SIMPLE_VALUE_TYPE;
}
/// Return true if the target should transform:
@@ -987,6 +1035,11 @@ public:
return GatherAllAliasesMaxDepth;
}
+ /// Returns the size of the platform's va_list object.
+ virtual unsigned getVaListSizeInBits(const DataLayout &DL) const {
+ return getPointerTy(DL).getSizeInBits();
+ }
+
/// \brief Get maximum # of store operations permitted for llvm.memset
///
/// This function returns the maximum number of store operations permitted
@@ -1384,6 +1437,13 @@ public:
Action != TypeSplitVector;
}
+ /// Return true if a select of constants (select Cond, C1, C2) should be
+ /// transformed into simple math ops with the condition value. For example:
+ /// select Cond, C1, C1-1 --> add (zext Cond), C1-1
+ virtual bool convertSelectOfConstantsToMath() const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by
// the derived class constructor to configure this object for the target.
@@ -1490,7 +1550,8 @@ protected:
void computeRegisterProperties(const TargetRegisterInfo *TRI);
/// Indicate that the specified operation does not work with the specified
- /// type and indicate what to do about it.
+ /// type and indicate what to do about it. Note that VT may refer to either
+ /// the type of a result or that of an operand of Op.
void setOperationAction(unsigned Op, MVT VT,
LegalizeAction Action) {
assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
@@ -1642,10 +1703,9 @@ public:
/// possible to be done in the address mode for that operand. This hook lets
/// targets also pass back when this should be done on intrinsics which
/// load/store.
- virtual bool GetAddrModeArguments(IntrinsicInst * /*I*/,
+ virtual bool getAddrModeArguments(IntrinsicInst * /*I*/,
SmallVectorImpl<Value*> &/*Ops*/,
- Type *&/*AccessTy*/,
- unsigned AddrSpace = 0) const {
+ Type *&/*AccessTy*/) const {
return false;
}
@@ -2197,10 +2257,6 @@ protected:
/// the branch is usually predicted right.
bool PredictableSelectIsExpensive;
- /// MaskAndBranchFoldingIsLegal - Indicates if the target supports folding
- /// a mask of a single bit, a compare, and a branch into a single instruction.
- bool MaskAndBranchFoldingIsLegal;
-
/// \see enableExtLdPromotion.
bool EnableExtLdPromotion;
@@ -2357,11 +2413,11 @@ public:
/// expression and return a mask of KnownOne and KnownZero bits for the
/// expression (used to simplify the caller). The KnownZero/One bits may only
/// be accurate for those bits in the DemandedMask.
- /// \p AssumeSingleUse When this paramater is true, this function will
+ /// \p AssumeSingleUse When this parameter is true, this function will
/// attempt to simplify \p Op even if there are multiple uses.
/// Callers are responsible for correctly updating the DAG based on the
/// results of this function, because simply replacing replacing TLO.Old
- /// with TLO.New will be incorrect when this paramater is true and TLO.Old
+ /// with TLO.New will be incorrect when this parameter is true and TLO.Old
/// has multiple uses.
bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
APInt &KnownZero, APInt &KnownOne,
@@ -2369,17 +2425,27 @@ public:
unsigned Depth = 0,
bool AssumeSingleUse = false) const;
+ /// Helper wrapper around SimplifyDemandedBits
+ bool SimplifyDemandedBits(SDValue Op, APInt &DemandedMask,
+ DAGCombinerInfo &DCI) const;
+
/// Determine which of the bits specified in Mask are known to be either zero
- /// or one and return them in the KnownZero/KnownOne bitsets.
+ /// or one and return them in the KnownZero/KnownOne bitsets. The DemandedElts
+ /// argument allows us to only collect the known bits that are shared by the
+ /// requested vector elements.
virtual void computeKnownBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
+ const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const;
/// This method can be implemented by targets that want to expose additional
- /// information about sign bits to the DAG Combiner.
+ /// information about sign bits to the DAG Combiner. The DemandedElts
+ /// argument allows us to only collect the minimum sign bits that are shared
+ /// by the requested vector elements.
virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
+ const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const;
@@ -2536,30 +2602,6 @@ public:
llvm_unreachable("Not Implemented");
}
- struct ArgListEntry {
- SDValue Node;
- Type* Ty;
- bool isSExt : 1;
- bool isZExt : 1;
- bool isInReg : 1;
- bool isSRet : 1;
- bool isNest : 1;
- 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), isSwiftSelf(false), isSwiftError(false),
- Alignment(0) {}
-
- void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
- };
- typedef std::vector<ArgListEntry> ArgListTy;
-
/// This structure contains all information that is necessary for lowering
/// calls. It is passed to TLI::LowerCallTo when the SelectionDAG builder
/// needs to lower a call, and targets will see this struct in their LowerCall
@@ -2609,6 +2651,20 @@ public:
return *this;
}
+ // setCallee with target/module-specific attributes
+ CallLoweringInfo &setLibCallee(CallingConv::ID CC, Type *ResultType,
+ SDValue Target, ArgListTy &&ArgsList) {
+ RetTy = ResultType;
+ Callee = Target;
+ CallConv = CC;
+ NumFixedArgs = Args.size();
+ Args = std::move(ArgsList);
+
+ DAG.getTargetLoweringInfo().markLibCallAttributes(
+ &(DAG.getMachineFunction()), CC, Args);
+ return *this;
+ }
+
CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultType,
SDValue Target, ArgListTy &&ArgsList) {
RetTy = ResultType;
@@ -2624,15 +2680,15 @@ public:
ImmutableCallSite &Call) {
RetTy = ResultType;
- IsInReg = Call.paramHasAttr(0, Attribute::InReg);
+ IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn =
Call.doesNotReturn() ||
(!Call.isInvoke() &&
isa<UnreachableInst>(Call.getInstruction()->getNextNode()));
IsVarArg = FTy->isVarArg();
IsReturnValueUsed = !Call.getInstruction()->use_empty();
- RetSExt = Call.paramHasAttr(0, Attribute::SExt);
- RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
+ RetSExt = Call.hasRetAttr(Attribute::SExt);
+ RetZExt = Call.hasRetAttr(Attribute::ZExt);
Callee = Target;
@@ -3183,7 +3239,7 @@ private:
/// Given an LLVM IR type and return type attributes, compute the return value
/// EVTs and flags, and optionally also the offsets, if the return value is
/// being lowered to memory.
-void GetReturnInfo(Type *ReturnType, AttributeSet attr,
+void GetReturnInfo(Type *ReturnType, AttributeList attr,
SmallVectorImpl<ISD::OutputArg> &Outs,
const TargetLowering &TLI, const DataLayout &DL);
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 72bae0a38e657..0ffd4b7f8c786 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -16,37 +16,35 @@
#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/SectionKind.h"
+#include <cstdint>
namespace llvm {
- class MachineModuleInfo;
- class Mangler;
- class MCContext;
- class MCExpr;
- class MCSection;
- class MCSymbol;
- class MCSymbolRefExpr;
- class MCStreamer;
- class MCValue;
- class ConstantExpr;
- class GlobalValue;
- class TargetMachine;
+
+class GlobalValue;
+class MachineModuleInfo;
+class Mangler;
+class MCContext;
+class MCExpr;
+class MCSection;
+class MCSymbol;
+class MCSymbolRefExpr;
+class MCStreamer;
+class MCValue;
+class TargetMachine;
class TargetLoweringObjectFile : public MCObjectFileInfo {
- MCContext *Ctx;
+ MCContext *Ctx = nullptr;
/// Name-mangler for global names.
Mangler *Mang = nullptr;
- TargetLoweringObjectFile(
- const TargetLoweringObjectFile&) = delete;
- void operator=(const TargetLoweringObjectFile&) = delete;
-
protected:
- bool SupportIndirectSymViaGOTPCRel;
- bool SupportGOTPCRelWithOffset;
+ bool SupportIndirectSymViaGOTPCRel = false;
+ bool SupportGOTPCRelWithOffset = true;
/// This section contains the static constructor pointer list.
MCSection *StaticCtorSection;
@@ -55,15 +53,15 @@ protected:
MCSection *StaticDtorSection;
public:
+ TargetLoweringObjectFile() = default;
+ TargetLoweringObjectFile(const TargetLoweringObjectFile &) = delete;
+ TargetLoweringObjectFile &
+ operator=(const TargetLoweringObjectFile &) = delete;
+ virtual ~TargetLoweringObjectFile();
+
MCContext &getContext() const { return *Ctx; }
Mangler &getMangler() const { return *Mang; }
- TargetLoweringObjectFile()
- : MCObjectFileInfo(), Ctx(nullptr), Mang(nullptr),
- SupportIndirectSymViaGOTPCRel(false), SupportGOTPCRelWithOffset(true) {}
-
- virtual ~TargetLoweringObjectFile();
-
/// This method must be called before any actual lowering is done. This
/// specifies the current context for codegen, and gives the lowering
/// implementations a chance to set up their default sections.
@@ -194,4 +192,4 @@ protected:
} // end namespace llvm
-#endif
+#endif // LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index b1d8f8f1e9173..73ae2ad129881 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -34,6 +34,7 @@ class MCRegisterInfo;
class MCSubtargetInfo;
class MCSymbol;
class raw_pwrite_stream;
+class PassManagerBuilder;
class Target;
class TargetIntrinsicInfo;
class TargetIRAnalysis;
@@ -205,10 +206,9 @@ 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 &) {}
+ /// Allow the target to modify the pass manager, e.g. by calling
+ /// PassManagerBuilder::addExtension.
+ virtual void adjustPassManager(PassManagerBuilder &) {}
/// 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
@@ -268,8 +268,8 @@ class LLVMTargetMachine : public TargetMachine {
protected: // Can only create subclasses.
LLVMTargetMachine(const Target &T, StringRef DataLayoutString,
const Triple &TargetTriple, StringRef CPU, StringRef FS,
- TargetOptions Options, Reloc::Model RM, CodeModel::Model CM,
- CodeGenOpt::Level OL);
+ const TargetOptions &Options, Reloc::Model RM,
+ CodeModel::Model CM, CodeGenOpt::Level OL);
void initAsmInfo();
public:
diff --git a/include/llvm/Target/TargetOpcodes.def b/include/llvm/Target/TargetOpcodes.def
index edb9b7350ca79..96db6e0a97698 100644
--- a/include/llvm/Target/TargetOpcodes.def
+++ b/include/llvm/Target/TargetOpcodes.def
@@ -107,6 +107,9 @@ HANDLE_TARGET_OPCODE(LIFETIME_END)
/// that must lie within the function and not contain another stackmap.
HANDLE_TARGET_OPCODE(STACKMAP)
+/// FEntry all - This is a marker instruction which gets translated into a raw fentry call.
+HANDLE_TARGET_OPCODE(FENTRY_CALL)
+
/// 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
@@ -131,11 +134,13 @@ HANDLE_TARGET_OPCODE(STATEPOINT)
/// frame index of the local stack allocation.
HANDLE_TARGET_OPCODE(LOCAL_ESCAPE)
-/// Loading instruction that may page fault, bundled with associated
+/// Wraps a machine instruction which can fault, bundled with associated
+/// information on how to handle such a fault.
+/// For example 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)
+HANDLE_TARGET_OPCODE(FAULTING_OP)
/// Wraps a machine instruction to add patchability constraints. An
/// instruction wrapped in PATCHABLE_OP has to either have a minimum
@@ -224,6 +229,8 @@ HANDLE_TARGET_OPCODE(G_GLOBAL_VALUE)
/// (typically a sub-register COPY after instruction selection).
HANDLE_TARGET_OPCODE(G_EXTRACT)
+HANDLE_TARGET_OPCODE(G_UNMERGE_VALUES)
+
/// Generic instruction to insert blocks of bits from the registers given into
/// the source.
HANDLE_TARGET_OPCODE(G_INSERT)
@@ -232,6 +239,8 @@ HANDLE_TARGET_OPCODE(G_INSERT)
/// larger register.
HANDLE_TARGET_OPCODE(G_SEQUENCE)
+HANDLE_TARGET_OPCODE(G_MERGE_VALUES)
+
/// Generic pointer to int conversion.
HANDLE_TARGET_OPCODE(G_PTRTOINT)
@@ -251,6 +260,9 @@ HANDLE_TARGET_OPCODE(G_STORE)
/// Generic conditional branch instruction.
HANDLE_TARGET_OPCODE(G_BRCOND)
+/// Generic indirect branch instruction.
+HANDLE_TARGET_OPCODE(G_BRINDIRECT)
+
/// Generic intrinsic use (without side effects).
HANDLE_TARGET_OPCODE(G_INTRINSIC)
@@ -272,6 +284,12 @@ HANDLE_TARGET_OPCODE(G_CONSTANT)
/// Generic floating constant.
HANDLE_TARGET_OPCODE(G_FCONSTANT)
+/// Generic va_start instruction. Stores to its one pointer operand.
+HANDLE_TARGET_OPCODE(G_VASTART)
+
+/// Generic va_start instruction. Stores to its one pointer operand.
+HANDLE_TARGET_OPCODE(G_VAARG)
+
// Generic sign extend
HANDLE_TARGET_OPCODE(G_SEXT)
@@ -320,6 +338,14 @@ HANDLE_TARGET_OPCODE(G_UMULO)
/// overflow flag.
HANDLE_TARGET_OPCODE(G_SMULO)
+// Multiply two numbers at twice the incoming bit width (unsigned) and return
+// the high half of the result.
+HANDLE_TARGET_OPCODE(G_UMULH)
+
+// Multiply two numbers at twice the incoming bit width (signed) and return
+// the high half of the result.
+HANDLE_TARGET_OPCODE(G_SMULH)
+
/// Generic FP addition.
HANDLE_TARGET_OPCODE(G_FADD)
@@ -335,7 +361,13 @@ HANDLE_TARGET_OPCODE(G_FDIV)
/// Generic FP remainder.
HANDLE_TARGET_OPCODE(G_FREM)
-/// Generic float to signed-int conversion
+/// Generic FP exponentiation.
+HANDLE_TARGET_OPCODE(G_FPOW)
+
+/// Generic FP negation.
+HANDLE_TARGET_OPCODE(G_FNEG)
+
+/// Generic FP extension.
HANDLE_TARGET_OPCODE(G_FPEXT)
/// Generic float to signed-int conversion
@@ -353,18 +385,31 @@ HANDLE_TARGET_OPCODE(G_SITOFP)
/// Generic unsigned-int to float conversion
HANDLE_TARGET_OPCODE(G_UITOFP)
-/// Generic unsigned-int to float conversion
+/// Generic pointer offset
HANDLE_TARGET_OPCODE(G_GEP)
+/// Clear the specified number of low bits in a pointer. This rounds the value
+/// *down* to the given alignment.
+HANDLE_TARGET_OPCODE(G_PTR_MASK)
+
/// Generic BRANCH instruction. This is an unconditional branch.
HANDLE_TARGET_OPCODE(G_BR)
+/// Generic insertelement.
+HANDLE_TARGET_OPCODE(G_INSERT_VECTOR_ELT)
+
+/// Generic extractelement.
+HANDLE_TARGET_OPCODE(G_EXTRACT_VECTOR_ELT)
+
+/// Generic shufflevector.
+HANDLE_TARGET_OPCODE(G_SHUFFLE_VECTOR)
+
// 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)
+HANDLE_TARGET_OPCODE_MARKER(PRE_ISEL_GENERIC_OPCODE_END, G_SHUFFLE_VECTOR)
/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific post-isel opcode values start here.
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index f5134d99b0392..7cc33f2fdccbb 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -99,22 +99,16 @@ namespace llvm {
class TargetOptions {
public:
TargetOptions()
- : PrintMachineCode(false), LessPreciseFPMADOption(false),
- UnsafeFPMath(false), NoInfsFPMath(false), NoNaNsFPMath(false),
- NoTrappingFPMath(false),
+ : PrintMachineCode(false), UnsafeFPMath(false), NoInfsFPMath(false),
+ NoNaNsFPMath(false), NoTrappingFPMath(false),
+ NoSignedZerosFPMath(false),
HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false),
- GuaranteedTailCallOpt(false), StackAlignmentOverride(0),
- StackSymbolOrdering(true), EnableFastISel(false), UseInitArray(false),
+ GuaranteedTailCallOpt(false), StackSymbolOrdering(true),
+ EnableFastISel(false), UseInitArray(false),
DisableIntegratedAS(false), CompressDebugSections(false),
RelaxELFRelocations(false), FunctionSections(false),
DataSections(false), UniqueSectionNames(true), TrapUnreachable(false),
- EmulatedTLS(false), EnableIPRA(false),
- FloatABIType(FloatABI::Default),
- AllowFPOpFusion(FPOpFusion::Standard),
- ThreadModel(ThreadModel::POSIX),
- EABIVersion(EABI::Default), DebuggerTuning(DebuggerKind::Default),
- FPDenormalMode(FPDenormal::IEEE),
- ExceptionModel(ExceptionHandling::None) {}
+ EmulatedTLS(false), EnableIPRA(false) {}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
/// option is specified on the command line, and should enable debugging
@@ -125,20 +119,11 @@ namespace llvm {
/// optimization should be disabled for the given machine function.
bool DisableFramePointerElim(const MachineFunction &MF) const;
- /// LessPreciseFPMAD - This flag is enabled when the
- /// -enable-fp-mad is specified on the command line. When this flag is off
- /// (the default), the code generator is not allowed to generate mad
- /// (multiply add) if the result is "less precise" than doing those
- /// operations individually.
- unsigned LessPreciseFPMADOption : 1;
- bool LessPreciseFPMAD() const;
-
/// UnsafeFPMath - This flag is enabled when the
/// -enable-unsafe-fp-math flag is specified on the command line. When
/// this flag is off (the default), the code generator is not allowed to
/// produce results that are "less precise" than IEEE allows. This includes
/// use of X86 instructions like FSIN and FCOS instead of libcalls.
- /// UnsafeFPMath implies LessPreciseFPMAD.
unsigned UnsafeFPMath : 1;
/// NoInfsFPMath - This flag is enabled when the
@@ -153,11 +138,17 @@ namespace llvm {
/// assume the FP arithmetic arguments and results are never NaNs.
unsigned NoNaNsFPMath : 1;
- /// NoTrappingFPMath - This flag is enabled when the
- /// -enable-no-trapping-fp-math is specified on the command line. This
+ /// NoTrappingFPMath - This flag is enabled when the
+ /// -enable-no-trapping-fp-math is specified on the command line. This
/// specifies that there are no trap handlers to handle exceptions.
unsigned NoTrappingFPMath : 1;
+ /// NoSignedZerosFPMath - This flag is enabled when the
+ /// -enable-no-signed-zeros-fp-math is specified on the command line. This
+ /// specifies that optimizations are allowed to treat the sign of a zero
+ /// argument or result as insignificant.
+ unsigned NoSignedZerosFPMath : 1;
+
/// HonorSignDependentRoundingFPMath - This returns true when the
/// -enable-sign-dependent-rounding-fp-math is specified. If this returns
/// false (the default), the code generator is allowed to assume that the
@@ -182,7 +173,7 @@ namespace llvm {
unsigned GuaranteedTailCallOpt : 1;
/// StackAlignmentOverride - Override default stack alignment for target.
- unsigned StackAlignmentOverride;
+ unsigned StackAlignmentOverride = 0;
/// StackSymbolOrdering - When true, this will allow CodeGen to order
/// the local stack symbols (for code size, code locality, or any other
@@ -231,7 +222,7 @@ namespace llvm {
/// software floating point, but does not indicate that FP hardware may not
/// be used. Such a combination is unfortunately popular (e.g.
/// arm-apple-darwin). Hard presumes that the normal FP ABI is used.
- FloatABI::ABIType FloatABIType;
+ FloatABI::ABIType FloatABIType = FloatABI::Default;
/// AllowFPOpFusion - This flag is set by the -fuse-fp-ops=xxx option.
/// This controls the creation of fused FP ops that store intermediate
@@ -249,65 +240,29 @@ namespace llvm {
/// optimizers. Fused operations that are explicitly specified (e.g. FMA
/// via the llvm.fma.* intrinsic) will always be honored, regardless of
/// the value of this option.
- FPOpFusion::FPOpFusionMode AllowFPOpFusion;
+ FPOpFusion::FPOpFusionMode AllowFPOpFusion = FPOpFusion::Standard;
/// ThreadModel - This flag specifies the type of threading model to assume
/// for things like atomics
- ThreadModel::Model ThreadModel;
+ ThreadModel::Model ThreadModel = ThreadModel::POSIX;
/// EABIVersion - This flag specifies the EABI version
- EABI EABIVersion;
+ EABI EABIVersion = EABI::Default;
/// Which debugger to tune for.
- DebuggerKind DebuggerTuning;
+ DebuggerKind DebuggerTuning = DebuggerKind::Default;
/// FPDenormalMode - This flags specificies which denormal numbers the code
/// is permitted to require.
- FPDenormal::DenormalMode FPDenormalMode;
+ FPDenormal::DenormalMode FPDenormalMode = FPDenormal::IEEE;
/// What exception model to use
- ExceptionHandling ExceptionModel;
+ ExceptionHandling ExceptionModel = ExceptionHandling::None;
/// Machine level options.
MCTargetOptions MCOptions;
};
-// Comparison operators:
-
-
-inline bool operator==(const TargetOptions &LHS,
- const TargetOptions &RHS) {
-#define ARE_EQUAL(X) LHS.X == RHS.X
- return
- ARE_EQUAL(UnsafeFPMath) &&
- ARE_EQUAL(NoInfsFPMath) &&
- ARE_EQUAL(NoNaNsFPMath) &&
- ARE_EQUAL(NoTrappingFPMath) &&
- ARE_EQUAL(HonorSignDependentRoundingFPMathOption) &&
- ARE_EQUAL(NoZerosInBSS) &&
- ARE_EQUAL(GuaranteedTailCallOpt) &&
- ARE_EQUAL(StackAlignmentOverride) &&
- ARE_EQUAL(EnableFastISel) &&
- ARE_EQUAL(UseInitArray) &&
- ARE_EQUAL(TrapUnreachable) &&
- ARE_EQUAL(EmulatedTLS) &&
- ARE_EQUAL(FloatABIType) &&
- ARE_EQUAL(AllowFPOpFusion) &&
- ARE_EQUAL(ThreadModel) &&
- ARE_EQUAL(EABIVersion) &&
- ARE_EQUAL(DebuggerTuning) &&
- ARE_EQUAL(FPDenormalMode) &&
- ARE_EQUAL(ExceptionModel) &&
- ARE_EQUAL(MCOptions) &&
- ARE_EQUAL(EnableIPRA);
-#undef ARE_EQUAL
-}
-
-inline bool operator!=(const TargetOptions &LHS,
- const TargetOptions &RHS) {
- return !(LHS == RHS);
-}
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 3080e9a32c3ac..3f5daea63ab59 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -45,6 +45,7 @@ public:
// Instance variables filled by tablegen, do not use!
const MCRegisterClass *MC;
+ const uint16_t SpillSize, SpillAlignment;
const vt_iterator VTs;
const uint32_t *SubClassMask;
const uint16_t *SuperRegIndices;
@@ -94,10 +95,10 @@ public:
/// Return the size of the register in bytes, which is also the size
/// of a stack slot allocated to hold a spilled copy of this register.
- unsigned getSize() const { return MC->getSize(); }
+ unsigned getSize() const { return SpillSize; }
/// Return the minimum required alignment for a register of this class.
- unsigned getAlignment() const { return MC->getAlignment(); }
+ unsigned getAlignment() const { return SpillAlignment; }
/// Return the cost of copying a value between two registers in this class.
/// A negative number means the register class is very expensive
@@ -426,7 +427,9 @@ public:
/// this target. The register should be in the order of desired callee-save
/// stack frame offset. The first register is closest to the incoming stack
/// pointer if stack grows down, and vice versa.
- ///
+ /// Notice: This function does not take into account disabled CSRs.
+ /// In most cases you will want to use instead the function
+ /// getCalleeSavedRegs that is implemented in MachineRegisterInfo.
virtual const MCPhysReg*
getCalleeSavedRegs(const MachineFunction *MF) const = 0;
@@ -633,6 +636,9 @@ public:
///
regclass_iterator regclass_begin() const { return RegClassBegin; }
regclass_iterator regclass_end() const { return RegClassEnd; }
+ iterator_range<regclass_iterator> regclasses() const {
+ return make_range(regclass_begin(), regclass_end());
+ }
unsigned getNumRegClasses() const {
return (unsigned)(regclass_end()-regclass_begin());
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index 74b98ac5f6c5d..d342e4fe26135 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -139,7 +139,7 @@ class ProcResourceKind;
// changes this to an in-order issue/dispatch resource. In this case,
// the scheduler counts down from the cycle that the instruction
// issues in-order, forcing a stall whenever a subsequent instruction
-// requires the same resource until the number of ResourceCyles
+// requires the same resource until the number of ResourceCycles
// specified in WriteRes expire. Setting BufferSize=1 changes this to
// an in-order latency resource. In this case, the scheduler models
// producer/consumer stalls between instructions that use the
@@ -255,6 +255,9 @@ class ProcWriteResources<list<ProcResourceKind> resources> {
// Allow a processor to mark some scheduling classes as unsupported
// for stronger verification.
bit Unsupported = 0;
+ // Allow a processor to mark some scheduling classes as single-issue.
+ // SingleIssue is an alias for Begin/End Group.
+ bit SingleIssue = 0;
SchedMachineModel SchedModel = ?;
}
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 55e2c2bce3db9..45a842f77a21a 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -136,30 +136,34 @@ def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz
SDTCisSameAs<0, 1>, SDTCisInt<0>
]>;
def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext
- SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc
- SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc
SDTCisSameAs<0, 1>, SDTCisFP<0>
]>;
def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround
- SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>
+ SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend
- SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>
+ SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp
- SDTCisFP<0>, SDTCisInt<1>
+ SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int
- SDTCisInt<0>, SDTCisFP<1>
+ SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg
SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>,
SDTCisVTSmallerThanOp<2, 1>
]>;
+def SDTExtInvec : SDTypeProfile<1, 1, [ // sext_invec
+ SDTCisInt<0>, SDTCisVec<0>, SDTCisInt<1>, SDTCisVec<1>,
+ SDTCisOpSmallerThanOp<1, 0>, SDTCisSameSizeAs<0,1>
+]>;
def SDTSetCC : SDTypeProfile<1, 3, [ // setcc
SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
@@ -170,7 +174,7 @@ def SDTSelect : SDTypeProfile<1, 3, [ // select
]>;
def SDTVSelect : SDTypeProfile<1, 3, [ // vselect
- SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1>
+ SDTCisVec<0>, SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1>
]>;
def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc
@@ -406,6 +410,10 @@ def umax : SDNode<"ISD::UMAX" , SDTIntBinOp,
[SDNPCommutative, SDNPAssociative]>;
def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
+def sext_invec : SDNode<"ISD::SIGN_EXTEND_VECTOR_INREG", SDTExtInvec>;
+def zext_invec : SDNode<"ISD::ZERO_EXTEND_VECTOR_INREG", SDTExtInvec>;
+
+def abs : SDNode<"ISD::ABS" , SDTIntUnaryOp>;
def bitreverse : SDNode<"ISD::BITREVERSE" , SDTIntUnaryOp>;
def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>;
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index 0b43515960216..83950a9cd027a 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -20,6 +20,7 @@
#include "llvm/CodeGen/PBQPRAConstraint.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/ScheduleDAGMutation.h"
+#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/CodeGen.h"
#include <memory>
@@ -143,6 +144,9 @@ public:
/// TargetLowering preference). It does not yet disable the postRA scheduler.
virtual bool enableMachineScheduler() const;
+ /// \brief Support printing of [latency:throughput] comment in output .S file.
+ virtual bool supportPrintSchedInfo() const { return false; }
+
/// \brief True if the machine scheduler should disable the TLI preference
/// for preRA scheduling with the source level scheduler.
virtual bool enableMachineSchedDefaultSched() const { return true; }
@@ -227,6 +231,10 @@ public:
/// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where
/// possible.
virtual bool enableSubRegLiveness() const { return false; }
+
+ /// Returns string representation of scheduler comment
+ std::string getSchedInfoStr(const MachineInstr &MI) const override;
+ std::string getSchedInfoStr(MCInst const &MCI) const override;
};
} // end namespace llvm