aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Target
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
committerStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
commitebe69fe11e48d322045d5949c83283927a0d790b (patch)
treec92f1907a6b8006628a4b01615f38264d29834ea /include/llvm/Target
parentb7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff)
downloadexternal_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.gz
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.bz2
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.zip
Update aosp/master LLVM for rebase to r230699.
Change-Id: I2b5be30509658cb8266be782de0ab24f9099f9b9
Diffstat (limited to 'include/llvm/Target')
-rw-r--r--include/llvm/Target/Target.td55
-rw-r--r--include/llvm/Target/TargetCallingConv.h11
-rw-r--r--include/llvm/Target/TargetFrameLowering.h19
-rw-r--r--include/llvm/Target/TargetInstrInfo.h17
-rw-r--r--include/llvm/Target/TargetIntrinsicInfo.h4
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h813
-rw-r--r--include/llvm/Target/TargetLowering.h312
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h33
-rw-r--r--include/llvm/Target/TargetMachine.h64
-rw-r--r--include/llvm/Target/TargetOpcodes.h13
-rw-r--r--include/llvm/Target/TargetOptions.h12
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h32
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td27
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h5
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h10
15 files changed, 357 insertions, 1070 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 902647e2b9..3e65a5d795 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -396,12 +396,9 @@ class Instruction {
// 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;
-
+ bit hasTwoExplicitDefs = 0; // Does this instruction have 2 explicit
+ // destinations?
// Is this instruction a "real" instruction (with a distinct machine
// encoding), or is it a pseudo instruction used for codegen modeling
// purposes.
@@ -628,6 +625,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 {
@@ -734,7 +734,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);
@@ -761,26 +761,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;
}
@@ -788,33 +788,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 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 {
@@ -826,13 +826,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);
@@ -849,6 +849,15 @@ 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);
@@ -857,6 +866,15 @@ def LOAD_STACK_GUARD : Instruction {
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;
+}
}
//===----------------------------------------------------------------------===//
@@ -1005,9 +1023,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/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index a0f26741a8..9071bfeec7 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -134,6 +134,8 @@ namespace ISD {
/// Index original Function's argument.
unsigned OrigArgIndex;
+ /// Sentinel value for implicit machine-level input arguments.
+ static const unsigned NoArgIndex = UINT_MAX;
/// Offset in bytes of current input value relative to the beginning of
/// original argument. E.g. if argument was splitted into four 32 bit
@@ -147,6 +149,15 @@ namespace ISD {
VT = vt.getSimpleVT();
ArgVT = argvt;
}
+
+ bool isOrigArg() const {
+ return OrigArgIndex != NoArgIndex;
+ }
+
+ unsigned getOrigArgIndex() const {
+ assert(OrigArgIndex != NoArgIndex && "Implicit machine-level argument");
+ return OrigArgIndex;
+ }
};
/// OutputArg - This struct carries flags and a value for a
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
index bfddd06017..f17640f71e 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
@@ -189,6 +193,11 @@ public:
return hasReservedCallFrame(MF) || hasFP(MF);
}
+ // needsFrameIndexResolution - Do we need to perform FI resolution for
+ // this function. Normally, this is required only when the function
+ // has any stack objects. However, targets may want to override this.
+ virtual bool needsFrameIndexResolution(const MachineFunction &MF) const;
+
/// getFrameIndexOffset - Returns the displacement from the frame register to
/// the stack frame of the specified index.
virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
@@ -199,6 +208,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 a37a7f93fd..247f9d8915 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -14,10 +14,10 @@
#ifndef LLVM_TARGET_TARGETINSTRINFO_H
#define LLVM_TARGET_TARGETINSTRINFO_H
-#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/MachineCombinerPattern.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
@@ -50,8 +50,8 @@ template<class T> class SmallVectorImpl;
/// TargetInstrInfo - Interface to description of machine instruction set
///
class TargetInstrInfo : public MCInstrInfo {
- TargetInstrInfo(const TargetInstrInfo &) LLVM_DELETED_FUNCTION;
- void operator=(const TargetInstrInfo &) LLVM_DELETED_FUNCTION;
+ TargetInstrInfo(const TargetInstrInfo &) = delete;
+ void operator=(const TargetInstrInfo &) = delete;
public:
TargetInstrInfo(int CFSetupOpcode = -1, int CFDestroyOpcode = -1)
: CallFrameSetupOpcode(CFSetupOpcode),
@@ -109,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
@@ -597,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!");
diff --git a/include/llvm/Target/TargetIntrinsicInfo.h b/include/llvm/Target/TargetIntrinsicInfo.h
index 71c0166d49..c630f5b12a 100644
--- a/include/llvm/Target/TargetIntrinsicInfo.h
+++ b/include/llvm/Target/TargetIntrinsicInfo.h
@@ -28,8 +28,8 @@ class Type;
/// TargetIntrinsicInfo - Interface to description of machine instruction set
///
class TargetIntrinsicInfo {
- TargetIntrinsicInfo(const TargetIntrinsicInfo &) LLVM_DELETED_FUNCTION;
- void operator=(const TargetIntrinsicInfo &) LLVM_DELETED_FUNCTION;
+ TargetIntrinsicInfo(const TargetIntrinsicInfo &) = delete;
+ void operator=(const TargetIntrinsicInfo &) = delete;
public:
TargetIntrinsicInfo();
virtual ~TargetIntrinsicInfo();
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
deleted file mode 100644
index 249849b866..0000000000
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ /dev/null
@@ -1,813 +0,0 @@
-//===-- llvm/Target/TargetLibraryInfo.h - Library information ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGETLIBRARYINFO_H
-#define LLVM_TARGET_TARGETLIBRARYINFO_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Pass.h"
-
-// BEGIN ANDROID-SPECIFIC
-#ifdef WIN32
-#ifdef fseeko
-#undef fseeko
-#endif
-#ifdef ftello
-#undef ftello
-#endif
-#endif // WIN32
-// END ANDROID-SPECIFIC
-
-namespace llvm {
- class Triple;
-
- namespace LibFunc {
- enum Func {
- /// int _IO_getc(_IO_FILE * __fp);
- under_IO_getc,
- /// int _IO_putc(int __c, _IO_FILE * __fp);
- under_IO_putc,
- /// void operator delete[](void*);
- 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);
- ZnajRKSt9nothrow_t,
- /// void *new[](unsigned long);
- Znam,
- /// void *new[](unsigned long, nothrow);
- ZnamRKSt9nothrow_t,
- /// void *new(unsigned int);
- Znwj,
- /// void *new(unsigned int, nothrow);
- ZnwjRKSt9nothrow_t,
- /// void *new(unsigned long);
- Znwm,
- /// void *new(unsigned long, nothrow);
- ZnwmRKSt9nothrow_t,
- /// double __cospi(double x);
- cospi,
- /// float __cospif(float x);
- cospif,
- /// int __cxa_atexit(void (*f)(void *), void *p, void *d);
- 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,
- /// int __cxa_guard_acquire(guard_t *guard);
- cxa_guard_acquire,
- /// void __cxa_guard_release(guard_t *guard);
- cxa_guard_release,
- /// int __isoc99_scanf (const char *format, ...)
- dunder_isoc99_scanf,
- /// int __isoc99_sscanf(const char *s, const char *format, ...)
- 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);
- sincospif_stret,
- /// double __sinpi(double x);
- sinpi,
- /// float __sinpif(float x);
- sinpif,
- /// double __sqrt_finite(double x);
- sqrt_finite,
- /// float __sqrt_finite(float x);
- 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);
- dunder_strtok_r,
- /// int abs(int j);
- abs,
- /// int access(const char *path, int amode);
- access,
- /// double acos(double x);
- acos,
- /// float acosf(float x);
- acosf,
- /// double acosh(double x);
- acosh,
- /// float acoshf(float x);
- acoshf,
- /// long double acoshl(long double x);
- acoshl,
- /// long double acosl(long double x);
- acosl,
- /// double asin(double x);
- asin,
- /// float asinf(float x);
- asinf,
- /// double asinh(double x);
- asinh,
- /// float asinhf(float x);
- asinhf,
- /// long double asinhl(long double x);
- asinhl,
- /// long double asinl(long double x);
- asinl,
- /// double atan(double x);
- atan,
- /// double atan2(double y, double x);
- atan2,
- /// float atan2f(float y, float x);
- atan2f,
- /// long double atan2l(long double y, long double x);
- atan2l,
- /// float atanf(float x);
- atanf,
- /// double atanh(double x);
- atanh,
- /// float atanhf(float x);
- atanhf,
- /// long double atanhl(long double x);
- atanhl,
- /// long double atanl(long double x);
- atanl,
- /// double atof(const char *str);
- atof,
- /// int atoi(const char *str);
- atoi,
- /// long atol(const char *str);
- atol,
- /// long long atoll(const char *nptr);
- atoll,
- /// int bcmp(const void *s1, const void *s2, size_t n);
- bcmp,
- /// void bcopy(const void *s1, void *s2, size_t n);
- bcopy,
- /// void bzero(void *s, size_t n);
- bzero,
- /// void *calloc(size_t count, size_t size);
- calloc,
- /// double cbrt(double x);
- cbrt,
- /// float cbrtf(float x);
- cbrtf,
- /// long double cbrtl(long double x);
- cbrtl,
- /// double ceil(double x);
- ceil,
- /// float ceilf(float x);
- ceilf,
- /// long double ceill(long double x);
- ceill,
- /// int chmod(const char *path, mode_t mode);
- chmod,
- /// int chown(const char *path, uid_t owner, gid_t group);
- chown,
- /// void clearerr(FILE *stream);
- clearerr,
- /// int closedir(DIR *dirp);
- closedir,
- /// double copysign(double x, double y);
- copysign,
- /// float copysignf(float x, float y);
- copysignf,
- /// long double copysignl(long double x, long double y);
- copysignl,
- /// double cos(double x);
- cos,
- /// float cosf(float x);
- cosf,
- /// double cosh(double x);
- cosh,
- /// float coshf(float x);
- coshf,
- /// long double coshl(long double x);
- coshl,
- /// long double cosl(long double x);
- cosl,
- /// char *ctermid(char *s);
- ctermid,
- /// double exp(double x);
- exp,
- /// double exp10(double x);
- exp10,
- /// float exp10f(float x);
- exp10f,
- /// long double exp10l(long double x);
- exp10l,
- /// double exp2(double x);
- exp2,
- /// float exp2f(float x);
- exp2f,
- /// long double exp2l(long double x);
- exp2l,
- /// float expf(float x);
- expf,
- /// long double expl(long double x);
- expl,
- /// double expm1(double x);
- expm1,
- /// float expm1f(float x);
- expm1f,
- /// long double expm1l(long double x);
- expm1l,
- /// double fabs(double x);
- fabs,
- /// float fabsf(float x);
- fabsf,
- /// long double fabsl(long double x);
- fabsl,
- /// int fclose(FILE *stream);
- fclose,
- /// FILE *fdopen(int fildes, const char *mode);
- fdopen,
- /// int feof(FILE *stream);
- feof,
- /// int ferror(FILE *stream);
- ferror,
- /// int fflush(FILE *stream);
- fflush,
- /// int ffs(int i);
- ffs,
- /// int ffsl(long int i);
- ffsl,
- /// int ffsll(long long int i);
- ffsll,
- /// int fgetc(FILE *stream);
- fgetc,
- /// int fgetpos(FILE *stream, fpos_t *pos);
- fgetpos,
- /// char *fgets(char *s, int n, FILE *stream);
- fgets,
- /// int fileno(FILE *stream);
- fileno,
- /// int fiprintf(FILE *stream, const char *format, ...);
- fiprintf,
- /// void flockfile(FILE *file);
- flockfile,
- /// double floor(double x);
- floor,
- /// float floorf(float x);
- floorf,
- /// long double floorl(long double x);
- floorl,
- /// double fmax(double x, double y);
- fmax,
- /// float fmaxf(float x, float y);
- fmaxf,
- /// long double fmaxl(long double x, long double y);
- fmaxl,
- /// double fmin(double x, double y);
- fmin,
- /// float fminf(float x, float y);
- fminf,
- /// long double fminl(long double x, long double y);
- fminl,
- /// double fmod(double x, double y);
- fmod,
- /// float fmodf(float x, float y);
- fmodf,
- /// long double fmodl(long double x, long double y);
- fmodl,
- /// FILE *fopen(const char *filename, const char *mode);
- fopen,
- /// FILE *fopen64(const char *filename, const char *opentype)
- fopen64,
- /// int fprintf(FILE *stream, const char *format, ...);
- fprintf,
- /// int fputc(int c, FILE *stream);
- fputc,
- /// int fputs(const char *s, FILE *stream);
- fputs,
- /// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
- fread,
- /// void free(void *ptr);
- free,
- /// double frexp(double num, int *exp);
- frexp,
- /// float frexpf(float num, int *exp);
- frexpf,
- /// long double frexpl(long double num, int *exp);
- frexpl,
- /// int fscanf(FILE *stream, const char *format, ... );
- fscanf,
- /// int fseek(FILE *stream, long offset, int whence);
- fseek,
- /// int fseeko(FILE *stream, off_t offset, int whence);
- fseeko,
- /// int fseeko64(FILE *stream, off64_t offset, int whence)
- fseeko64,
- /// int fsetpos(FILE *stream, const fpos_t *pos);
- fsetpos,
- /// int fstat(int fildes, struct stat *buf);
- fstat,
- /// int fstat64(int filedes, struct stat64 *buf)
- fstat64,
- /// int fstatvfs(int fildes, struct statvfs *buf);
- fstatvfs,
- /// int fstatvfs64(int fildes, struct statvfs64 *buf);
- fstatvfs64,
- /// long ftell(FILE *stream);
- ftell,
- /// off_t ftello(FILE *stream);
- ftello,
- /// off64_t ftello64(FILE *stream)
- ftello64,
- /// int ftrylockfile(FILE *file);
- ftrylockfile,
- /// void funlockfile(FILE *file);
- funlockfile,
- /// size_t fwrite(const void *ptr, size_t size, size_t nitems,
- /// FILE *stream);
- fwrite,
- /// int getc(FILE *stream);
- getc,
- /// int getc_unlocked(FILE *stream);
- getc_unlocked,
- /// int getchar(void);
- getchar,
- /// char *getenv(const char *name);
- getenv,
- /// int getitimer(int which, struct itimerval *value);
- getitimer,
- /// int getlogin_r(char *name, size_t namesize);
- getlogin_r,
- /// struct passwd *getpwnam(const char *name);
- getpwnam,
- /// char *gets(char *s);
- gets,
- /// int gettimeofday(struct timeval *tp, void *tzp);
- gettimeofday,
- /// uint32_t htonl(uint32_t hostlong);
- htonl,
- /// uint16_t htons(uint16_t hostshort);
- htons,
- /// int iprintf(const char *format, ...);
- iprintf,
- /// int isascii(int c);
- isascii,
- /// int isdigit(int c);
- isdigit,
- /// long int labs(long int j);
- labs,
- /// int lchown(const char *path, uid_t owner, gid_t group);
- lchown,
- /// double ldexp(double x, int n);
- ldexp,
- /// float ldexpf(float x, int n);
- ldexpf,
- /// long double ldexpl(long double x, int n);
- ldexpl,
- /// long long int llabs(long long int j);
- llabs,
- /// double log(double x);
- log,
- /// double log10(double x);
- log10,
- /// float log10f(float x);
- log10f,
- /// long double log10l(long double x);
- log10l,
- /// double log1p(double x);
- log1p,
- /// float log1pf(float x);
- log1pf,
- /// long double log1pl(long double x);
- log1pl,
- /// double log2(double x);
- log2,
- /// float log2f(float x);
- log2f,
- /// double long double log2l(long double x);
- log2l,
- /// double logb(double x);
- logb,
- /// float logbf(float x);
- logbf,
- /// long double logbl(long double x);
- logbl,
- /// float logf(float x);
- logf,
- /// long double logl(long double x);
- logl,
- /// int lstat(const char *path, struct stat *buf);
- lstat,
- /// int lstat64(const char *path, struct stat64 *buf);
- lstat64,
- /// void *malloc(size_t size);
- malloc,
- /// void *memalign(size_t boundary, size_t size);
- memalign,
- /// void *memccpy(void *s1, const void *s2, int c, size_t n);
- memccpy,
- /// void *memchr(const void *s, int c, size_t n);
- memchr,
- /// int memcmp(const void *s1, const void *s2, size_t n);
- memcmp,
- /// void *memcpy(void *s1, const void *s2, size_t n);
- memcpy,
- /// void *memmove(void *s1, const void *s2, size_t n);
- memmove,
- // void *memrchr(const void *s, int c, size_t n);
- memrchr,
- /// void *memset(void *b, int c, size_t len);
- memset,
- /// void memset_pattern16(void *b, const void *pattern16, size_t len);
- memset_pattern16,
- /// int mkdir(const char *path, mode_t mode);
- mkdir,
- /// time_t mktime(struct tm *timeptr);
- mktime,
- /// double modf(double x, double *iptr);
- modf,
- /// float modff(float, float *iptr);
- modff,
- /// long double modfl(long double value, long double *iptr);
- modfl,
- /// double nearbyint(double x);
- nearbyint,
- /// float nearbyintf(float x);
- nearbyintf,
- /// long double nearbyintl(long double x);
- nearbyintl,
- /// uint32_t ntohl(uint32_t netlong);
- ntohl,
- /// uint16_t ntohs(uint16_t netshort);
- ntohs,
- /// int open(const char *path, int oflag, ... );
- open,
- /// int open64(const char *filename, int flags[, mode_t mode])
- open64,
- /// DIR *opendir(const char *dirname);
- opendir,
- /// int pclose(FILE *stream);
- pclose,
- /// void perror(const char *s);
- perror,
- /// FILE *popen(const char *command, const char *mode);
- popen,
- /// int posix_memalign(void **memptr, size_t alignment, size_t size);
- posix_memalign,
- /// double pow(double x, double y);
- pow,
- /// float powf(float x, float y);
- powf,
- /// long double powl(long double x, long double y);
- powl,
- /// ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
- pread,
- /// int printf(const char *format, ...);
- printf,
- /// int putc(int c, FILE *stream);
- putc,
- /// int putchar(int c);
- putchar,
- /// int puts(const char *s);
- puts,
- /// ssize_t pwrite(int fildes, const void *buf, size_t nbyte,
- /// off_t offset);
- pwrite,
- /// void qsort(void *base, size_t nel, size_t width,
- /// int (*compar)(const void *, const void *));
- qsort,
- /// ssize_t read(int fildes, void *buf, size_t nbyte);
- read,
- /// ssize_t readlink(const char *path, char *buf, size_t bufsize);
- readlink,
- /// void *realloc(void *ptr, size_t size);
- realloc,
- /// void *reallocf(void *ptr, size_t size);
- reallocf,
- /// char *realpath(const char *file_name, char *resolved_name);
- realpath,
- /// int remove(const char *path);
- remove,
- /// int rename(const char *old, const char *new);
- rename,
- /// void rewind(FILE *stream);
- rewind,
- /// double rint(double x);
- rint,
- /// float rintf(float x);
- rintf,
- /// long double rintl(long double x);
- rintl,
- /// int rmdir(const char *path);
- rmdir,
- /// double round(double x);
- round,
- /// float roundf(float x);
- roundf,
- /// long double roundl(long double x);
- roundl,
- /// int scanf(const char *restrict format, ... );
- scanf,
- /// void setbuf(FILE *stream, char *buf);
- setbuf,
- /// int setitimer(int which, const struct itimerval *value,
- /// struct itimerval *ovalue);
- setitimer,
- /// int setvbuf(FILE *stream, char *buf, int type, size_t size);
- setvbuf,
- /// double sin(double x);
- sin,
- /// float sinf(float x);
- sinf,
- /// double sinh(double x);
- sinh,
- /// float sinhf(float x);
- sinhf,
- /// long double sinhl(long double x);
- sinhl,
- /// long double sinl(long double x);
- sinl,
- /// int siprintf(char *str, const char *format, ...);
- siprintf,
- /// int snprintf(char *s, size_t n, const char *format, ...);
- snprintf,
- /// int sprintf(char *str, const char *format, ...);
- sprintf,
- /// double sqrt(double x);
- sqrt,
- /// float sqrtf(float x);
- sqrtf,
- /// long double sqrtl(long double x);
- sqrtl,
- /// int sscanf(const char *s, const char *format, ... );
- sscanf,
- /// int stat(const char *path, struct stat *buf);
- stat,
- /// int stat64(const char *path, struct stat64 *buf);
- stat64,
- /// int statvfs(const char *path, struct statvfs *buf);
- statvfs,
- /// int statvfs64(const char *path, struct statvfs64 *buf)
- statvfs64,
- /// char *stpcpy(char *s1, const char *s2);
- stpcpy,
- /// char *stpncpy(char *s1, const char *s2, size_t n);
- stpncpy,
- /// int strcasecmp(const char *s1, const char *s2);
- strcasecmp,
- /// char *strcat(char *s1, const char *s2);
- strcat,
- /// char *strchr(const char *s, int c);
- strchr,
- /// int strcmp(const char *s1, const char *s2);
- strcmp,
- /// int strcoll(const char *s1, const char *s2);
- strcoll,
- /// char *strcpy(char *s1, const char *s2);
- strcpy,
- /// size_t strcspn(const char *s1, const char *s2);
- strcspn,
- /// char *strdup(const char *s1);
- strdup,
- /// size_t strlen(const char *s);
- strlen,
- /// int strncasecmp(const char *s1, const char *s2, size_t n);
- strncasecmp,
- /// char *strncat(char *s1, const char *s2, size_t n);
- strncat,
- /// int strncmp(const char *s1, const char *s2, size_t n);
- strncmp,
- /// char *strncpy(char *s1, const char *s2, size_t n);
- strncpy,
- /// char *strndup(const char *s1, size_t n);
- strndup,
- /// size_t strnlen(const char *s, size_t maxlen);
- strnlen,
- /// char *strpbrk(const char *s1, const char *s2);
- strpbrk,
- /// char *strrchr(const char *s, int c);
- strrchr,
- /// size_t strspn(const char *s1, const char *s2);
- strspn,
- /// char *strstr(const char *s1, const char *s2);
- strstr,
- /// double strtod(const char *nptr, char **endptr);
- strtod,
- /// float strtof(const char *nptr, char **endptr);
- strtof,
- // char *strtok(char *s1, const char *s2);
- strtok,
- // char *strtok_r(char *s, const char *sep, char **lasts);
- strtok_r,
- /// long int strtol(const char *nptr, char **endptr, int base);
- strtol,
- /// long double strtold(const char *nptr, char **endptr);
- strtold,
- /// long long int strtoll(const char *nptr, char **endptr, int base);
- strtoll,
- /// unsigned long int strtoul(const char *nptr, char **endptr, int base);
- strtoul,
- /// unsigned long long int strtoull(const char *nptr, char **endptr,
- /// int base);
- strtoull,
- /// size_t strxfrm(char *s1, const char *s2, size_t n);
- strxfrm,
- /// int system(const char *command);
- system,
- /// double tan(double x);
- tan,
- /// float tanf(float x);
- tanf,
- /// double tanh(double x);
- tanh,
- /// float tanhf(float x);
- tanhf,
- /// long double tanhl(long double x);
- tanhl,
- /// long double tanl(long double x);
- tanl,
- /// clock_t times(struct tms *buffer);
- times,
- /// FILE *tmpfile(void);
- tmpfile,
- /// FILE *tmpfile64(void)
- tmpfile64,
- /// int toascii(int c);
- toascii,
- /// double trunc(double x);
- trunc,
- /// float truncf(float x);
- truncf,
- /// long double truncl(long double x);
- truncl,
- /// int uname(struct utsname *name);
- uname,
- /// int ungetc(int c, FILE *stream);
- ungetc,
- /// int unlink(const char *path);
- unlink,
- /// int unsetenv(const char *name);
- unsetenv,
- /// int utime(const char *path, const struct utimbuf *times);
- utime,
- /// int utimes(const char *path, const struct timeval times[2]);
- utimes,
- /// void *valloc(size_t size);
- valloc,
- /// int vfprintf(FILE *stream, const char *format, va_list ap);
- vfprintf,
- /// int vfscanf(FILE *stream, const char *format, va_list arg);
- vfscanf,
- /// int vprintf(const char *restrict format, va_list ap);
- vprintf,
- /// int vscanf(const char *format, va_list arg);
- vscanf,
- /// int vsnprintf(char *s, size_t n, const char *format, va_list ap);
- vsnprintf,
- /// int vsprintf(char *s, const char *format, va_list ap);
- vsprintf,
- /// int vsscanf(const char *s, const char *format, va_list arg);
- vsscanf,
- /// ssize_t write(int fildes, const void *buf, size_t nbyte);
- write,
-
- NumLibFuncs
- };
- }
-
-/// TargetLibraryInfo - This immutable pass captures information about what
-/// library functions are available for the current target, and allows a
-/// frontend to disable optimizations through -fno-builtin etc.
-class TargetLibraryInfo : public ImmutablePass {
- virtual void anchor();
- unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
- llvm::DenseMap<unsigned, std::string> CustomNames;
- static const char* StandardNames[LibFunc::NumLibFuncs];
-
- enum AvailabilityState {
- StandardName = 3, // (memset to all ones)
- CustomName = 1,
- Unavailable = 0 // (memset to all zeros)
- };
- void setState(LibFunc::Func F, AvailabilityState State) {
- AvailableArray[F/4] &= ~(3 << 2*(F&3));
- AvailableArray[F/4] |= State << 2*(F&3);
- }
- AvailabilityState getState(LibFunc::Func F) const {
- return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
- }
-
-public:
- static char ID;
- 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;
-
- /// has - This function is used by optimizations that want to match on or form
- /// a given library function.
- bool has(LibFunc::Func F) const {
- return getState(F) != Unavailable;
- }
-
- /// hasOptimizedCodeGen - Return true if the function is both available as
- /// a builtin and a candidate for optimized code generation.
- bool hasOptimizedCodeGen(LibFunc::Func F) const {
- if (getState(F) == Unavailable)
- return false;
- switch (F) {
- default: break;
- case LibFunc::copysign: case LibFunc::copysignf: case LibFunc::copysignl:
- case LibFunc::fabs: case LibFunc::fabsf: case LibFunc::fabsl:
- case LibFunc::sin: case LibFunc::sinf: case LibFunc::sinl:
- case LibFunc::cos: case LibFunc::cosf: case LibFunc::cosl:
- case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl:
- case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite:
- case LibFunc::sqrtl_finite:
- case LibFunc::fmax: case LibFunc::fmaxf: case LibFunc::fmaxl:
- case LibFunc::fmin: case LibFunc::fminf: case LibFunc::fminl:
- case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl:
- case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
- case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill:
- case LibFunc::rint: case LibFunc::rintf: case LibFunc::rintl:
- case LibFunc::round: case LibFunc::roundf: case LibFunc::roundl:
- case LibFunc::trunc: case LibFunc::truncf: case LibFunc::truncl:
- case LibFunc::log2: case LibFunc::log2f: case LibFunc::log2l:
- case LibFunc::exp2: case LibFunc::exp2f: case LibFunc::exp2l:
- case LibFunc::memcmp: case LibFunc::strcmp: case LibFunc::strcpy:
- case LibFunc::stpcpy: case LibFunc::strlen: case LibFunc::strnlen:
- case LibFunc::memchr:
- return true;
- }
- return false;
- }
-
- StringRef getName(LibFunc::Func F) const {
- AvailabilityState State = getState(F);
- if (State == Unavailable)
- return StringRef();
- if (State == StandardName)
- return StandardNames[F];
- assert(State == CustomName);
- return CustomNames.find(F)->second;
- }
-
- /// setUnavailable - this can be used by whatever sets up TargetLibraryInfo to
- /// ban use of specific library functions.
- void setUnavailable(LibFunc::Func F) {
- setState(F, Unavailable);
- }
-
- void setAvailable(LibFunc::Func F) {
- setState(F, StandardName);
- }
-
- void setAvailableWithName(LibFunc::Func F, StringRef Name) {
- if (StandardNames[F] != Name) {
- setState(F, CustomName);
- CustomNames[F] = Name;
- assert(CustomNames.find(F) != CustomNames.end());
- } else {
- setState(F, StandardName);
- }
- }
-
- /// disableAllFunctions - This disables all builtins, which is used for
- /// options like -fno-builtin.
- void disableAllFunctions();
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 882dab40e4..4118917810 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -30,9 +30,9 @@
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IRBuilder.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Target/TargetCallingConv.h"
#include "llvm/Target/TargetMachine.h"
@@ -51,6 +51,7 @@ namespace llvm {
class MachineFunction;
class MachineInstr;
class MachineJumpTableInfo;
+ class MachineLoop;
class Mangler;
class MCContext;
class MCExpr;
@@ -76,8 +77,8 @@ namespace llvm {
/// This base class for TargetLowering contains the SelectionDAG-independent
/// parts that can be used from the rest of CodeGen.
class TargetLoweringBase {
- TargetLoweringBase(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
- void operator=(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
+ TargetLoweringBase(const TargetLoweringBase&) = delete;
+ void operator=(const TargetLoweringBase&) = delete;
public:
/// This enum indicates whether operations are valid for a target, and if not,
@@ -148,9 +149,6 @@ protected:
public:
const TargetMachine &getTargetMachine() const { return TM; }
const DataLayout *getDataLayout() const { return DL; }
- const TargetLoweringObjectFile &getObjFileLowering() const {
- return *TM.getObjFileLowering();
- }
bool isBigEndian() const { return !IsLittleEndian; }
bool isLittleEndian() const { return IsLittleEndian; }
@@ -216,6 +214,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(); }
@@ -249,6 +252,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
@@ -264,6 +277,11 @@ public:
return MaskAndBranchFoldingIsLegal;
}
+ /// \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.
@@ -541,18 +559,27 @@ 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, EVT VT) const {
- if (VT.isExtended()) return Expand;
- unsigned I = (unsigned) VT.getSimpleVT().SimpleTy;
- assert(ExtType < ISD::LAST_LOADEXT_TYPE && I < MVT::LAST_VALUETYPE &&
- "Table isn't big enough!");
- return (LegalizeAction)LoadExtActions[I][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 true if the specified load with extension is legal or custom
+ /// on this target.
+ bool isLoadExtLegalOrCustom(unsigned ExtType, EVT ValVT, EVT MemVT) const {
+ return ValVT.isSimple() && MemVT.isSimple() &&
+ (getLoadExtAction(ExtType, ValVT, MemVT) == Legal ||
+ getLoadExtAction(ExtType, ValVT, MemVT) == Custom);
}
/// Return how this store with truncation should be treated: either it is
@@ -579,7 +606,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);
@@ -597,7 +624,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);
@@ -753,6 +780,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.
@@ -904,7 +941,7 @@ public:
}
/// Return the preferred loop alignment.
- unsigned getPrefLoopAlignment() const {
+ virtual unsigned getPrefLoopAlignment(MachineLoop *ML = nullptr) const {
return PrefLoopAlignment;
}
@@ -922,12 +959,6 @@ public:
return false;
}
- /// Returns the maximal possible offset which can be used for loads / stores
- /// from the global.
- virtual unsigned getMaximalGlobalOffset() const {
- return 0;
- }
-
/// Returns true if a cast between SrcAS and DestAS is a noop.
virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
return false;
@@ -1057,10 +1088,6 @@ public:
// TargetLowering Configuration Methods - These methods should be invoked by
// the derived class constructor to configure this object for the target.
//
-
- /// \brief Reset the operation actions based on target options.
- virtual void resetOperationActions() {}
-
protected:
/// Specify how the target extends the result of integer and floating point
/// boolean values from i1 to a wider type. See getBooleanContents.
@@ -1156,7 +1183,11 @@ protected:
/// possible, should be replaced by an alternate sequence of instructions not
/// 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) {
@@ -1194,12 +1225,12 @@ protected:
/// Return the largest legal super-reg register class of the register class
/// for the specified type and its associated "cost".
- virtual std::pair<const TargetRegisterClass*, uint8_t>
- findRepresentativeClass(MVT VT) const;
+ virtual std::pair<const TargetRegisterClass *, uint8_t>
+ findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const;
/// Once all of the register classes are added, this allows us to compute
/// derived properties we expose.
- void computeRegisterProperties();
+ void computeRegisterProperties(const TargetRegisterInfo *TRI);
/// Indicate that the specified operation does not work with the specified
/// type and indicate what to do about it.
@@ -1211,19 +1242,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;
}
@@ -1234,7 +1264,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;
@@ -1248,7 +1278,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;
@@ -1259,8 +1289,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
@@ -1311,7 +1340,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;
}
@@ -1420,6 +1450,8 @@ public:
return false;
}
+ virtual bool isProfitableToHoist(Instruction *I) const { return true; }
+
/// Return true if any actual instruction that defines a value of type Ty1
/// implicitly zero-extends the value to Ty2 in the result register.
///
@@ -1474,6 +1506,18 @@ 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 folding a vector load into ExtVal (a sign, zero, or any
+ /// extend node) is profitable.
+ virtual bool isVectorLoadExtDesirable(SDValue ExtVal) const { 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 {
@@ -1516,6 +1560,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
//
@@ -1582,6 +1635,9 @@ 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
@@ -1703,7 +1759,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.
@@ -1727,136 +1784,8 @@ private:
ValueTypeActionImpl ValueTypeActions;
-public:
- LegalizeKind
- getTypeConversion(LLVMContext &Context, EVT VT) const {
- // If this is a simple type, use the ComputeRegisterProp mechanism.
- if (VT.isSimple()) {
- MVT SVT = VT.getSimpleVT();
- assert((unsigned)SVT.SimpleTy < array_lengthof(TransformToType));
- MVT NVT = TransformToType[SVT.SimpleTy];
- LegalizeTypeAction LA = ValueTypeActions.getTypeAction(SVT);
-
- assert(
- (LA == TypeLegal || LA == TypeSoftenFloat ||
- ValueTypeActions.getTypeAction(NVT) != TypePromoteInteger)
- && "Promote may not follow Expand or Promote");
-
- if (LA == TypeSplitVector)
- return LegalizeKind(LA, EVT::getVectorVT(Context,
- SVT.getVectorElementType(),
- SVT.getVectorNumElements()/2));
- if (LA == TypeScalarizeVector)
- return LegalizeKind(LA, SVT.getVectorElementType());
- return LegalizeKind(LA, NVT);
- }
-
- // Handle Extended Scalar Types.
- if (!VT.isVector()) {
- assert(VT.isInteger() && "Float types must be simple");
- unsigned BitSize = VT.getSizeInBits();
- // First promote to a power-of-two size, then expand if necessary.
- if (BitSize < 8 || !isPowerOf2_32(BitSize)) {
- EVT NVT = VT.getRoundIntegerType(Context);
- assert(NVT != VT && "Unable to round integer VT");
- LegalizeKind NextStep = getTypeConversion(Context, NVT);
- // Avoid multi-step promotion.
- if (NextStep.first == TypePromoteInteger) return NextStep;
- // Return rounded integer type.
- return LegalizeKind(TypePromoteInteger, NVT);
- }
-
- return LegalizeKind(TypeExpandInteger,
- EVT::getIntegerVT(Context, VT.getSizeInBits()/2));
- }
-
- // Handle vector types.
- unsigned NumElts = VT.getVectorNumElements();
- EVT EltVT = VT.getVectorElementType();
-
- // Vectors with only one element are always scalarized.
- if (NumElts == 1)
- return LegalizeKind(TypeScalarizeVector, EltVT);
-
- // Try to widen vector elements until the element type is a power of two and
- // promote it to a legal type later on, for example:
- // <3 x i8> -> <4 x i8> -> <4 x i32>
- if (EltVT.isInteger()) {
- // Vectors with a number of elements that is not a power of two are always
- // widened, for example <3 x i8> -> <4 x i8>.
- if (!VT.isPow2VectorType()) {
- NumElts = (unsigned)NextPowerOf2(NumElts);
- EVT NVT = EVT::getVectorVT(Context, EltVT, NumElts);
- return LegalizeKind(TypeWidenVector, NVT);
- }
-
- // Examine the element type.
- LegalizeKind LK = getTypeConversion(Context, EltVT);
-
- // If type is to be expanded, split the vector.
- // <4 x i140> -> <2 x i140>
- if (LK.first == TypeExpandInteger)
- return LegalizeKind(TypeSplitVector,
- EVT::getVectorVT(Context, EltVT, NumElts / 2));
-
- // Promote the integer element types until a legal vector type is found
- // or until the element integer type is too big. If a legal type was not
- // found, fallback to the usual mechanism of widening/splitting the
- // vector.
- EVT OldEltVT = EltVT;
- while (1) {
- // Increase the bitwidth of the element to the next pow-of-two
- // (which is greater than 8 bits).
- EltVT = EVT::getIntegerVT(Context, 1 + EltVT.getSizeInBits()
- ).getRoundIntegerType(Context);
-
- // Stop trying when getting a non-simple element type.
- // Note that vector elements may be greater than legal vector element
- // types. Example: X86 XMM registers hold 64bit element on 32bit
- // systems.
- if (!EltVT.isSimple()) break;
-
- // Build a new vector type and check if it is legal.
- MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts);
- // Found a legal promoted vector type.
- if (NVT != MVT() && ValueTypeActions.getTypeAction(NVT) == TypeLegal)
- return LegalizeKind(TypePromoteInteger,
- EVT::getVectorVT(Context, EltVT, NumElts));
- }
-
- // Reset the type to the unexpanded type if we did not find a legal vector
- // type with a promoted vector element type.
- EltVT = OldEltVT;
- }
-
- // Try to widen the vector until a legal type is found.
- // If there is no wider legal type, split the vector.
- while (1) {
- // Round up to the next power of 2.
- NumElts = (unsigned)NextPowerOf2(NumElts);
-
- // If there is no simple vector type with this many elements then there
- // cannot be a larger legal vector type. Note that this assumes that
- // there are no skipped intermediate vector types in the simple types.
- if (!EltVT.isSimple()) break;
- MVT LargerVector = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts);
- if (LargerVector == MVT()) break;
-
- // If this type is legal then widen the vector.
- if (ValueTypeActions.getTypeAction(LargerVector) == TypeLegal)
- return LegalizeKind(TypeWidenVector, LargerVector);
- }
-
- // Widen odd vectors to next power of two.
- if (!VT.isPow2VectorType()) {
- EVT NVT = VT.getPow2VectorType(Context);
- return LegalizeKind(TypeWidenVector, NVT);
- }
-
- // Vectors with illegal element types are expanded.
- EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2);
- return LegalizeKind(TypeSplitVector, NVT);
- }
+private:
+ LegalizeKind getTypeConversion(LLVMContext &Context, EVT VT) const;
private:
std::vector<std::pair<MVT, const TargetRegisterClass*> > AvailableRegClasses;
@@ -1944,6 +1873,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.
@@ -1960,8 +1892,8 @@ protected:
/// This class also defines callbacks that targets must implement to lower
/// target-specific constructs to SelectionDAG operators.
class TargetLowering : public TargetLoweringBase {
- TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION;
- void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION;
+ TargetLowering(const TargetLowering&) = delete;
+ void operator=(const TargetLowering&) = delete;
public:
/// NOTE: The TargetMachine owns TLOF.
@@ -2112,8 +2044,7 @@ public:
void AddToWorklist(SDNode *N);
void RemoveFromWorklist(SDNode *N);
- SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
- bool AddTo = true);
+ SDValue CombineTo(SDNode *N, ArrayRef<SDValue> To, bool AddTo = true);
SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true);
SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true);
@@ -2252,6 +2183,7 @@ public:
SelectionDAG &DAG;
SDLoc DL;
ImmutableCallSite *CS;
+ bool IsPatchPoint;
SmallVector<ISD::OutputArg, 32> Outs;
SmallVector<SDValue, 32> OutVals;
SmallVector<ISD::InputArg, 32> Ins;
@@ -2260,7 +2192,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;
@@ -2342,6 +2274,11 @@ public:
return *this;
}
+ CallLoweringInfo &setIsPatchPoint(bool Value = true) {
+ IsPatchPoint = Value;
+ return *this;
+ }
+
ArgListTy &getArgs() {
return Args;
}
@@ -2588,7 +2525,8 @@ public:
/// specific constraints and their prefixes, and also tie in the associated
/// operand values. If this returns an empty vector, and if the constraint
/// string itself isn't empty, there was an error parsing.
- virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const;
+ virtual AsmOperandInfoVector ParseConstraints(const TargetRegisterInfo *TRI,
+ ImmutableCallSite CS) const;
/// Examine constraint type and operand type and determine a weight value.
/// The operand object must already have been set up with the operand type.
@@ -2619,10 +2557,10 @@ public:
/// pointer.
///
/// This should only be used for C_Register constraints. On error, this
- /// returns a register number of 0 and a null register class pointer..
- virtual std::pair<unsigned, const TargetRegisterClass*>
- getRegForInlineAsmConstraint(const std::string &Constraint,
- MVT VT) const;
+ /// returns a register number of 0 and a null register class pointer.
+ virtual std::pair<unsigned, const TargetRegisterClass *>
+ getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
+ const std::string &Constraint, MVT VT) const;
/// Try to replace an X constraint, which matches anything, with another that
/// has more specific requirements based on the type of the corresponding
@@ -2652,6 +2590,12 @@ public:
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.
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 7fcb171ab3..57c2606edf 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -38,13 +38,17 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
const DataLayout *DL;
TargetLoweringObjectFile(
- const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION;
- void operator=(const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION;
+ const TargetLoweringObjectFile&) = delete;
+ void operator=(const TargetLoweringObjectFile&) = delete;
+
+protected:
+ bool SupportIndirectSymViaGOTPCRel;
public:
MCContext &getContext() const { return *Ctx; }
- TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(nullptr), DL(nullptr) {}
+ TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(nullptr), DL(nullptr),
+ SupportIndirectSymViaGOTPCRel(false) {}
virtual ~TargetLoweringObjectFile();
@@ -94,6 +98,13 @@ public:
return SectionForGlobal(GV, getKindForGlobal(GV, TM), Mang, TM);
}
+ virtual const MCSection *
+ getSectionForJumpTable(const Function &F, Mangler &Mang,
+ const TargetMachine &TM) const;
+
+ virtual bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
+ const Function &F) const;
+
/// Targets should implement this method to assign a section to globals with
/// an explicit section specfied. The implementation of this method can
/// assume that GV->hasSection() is true.
@@ -151,11 +162,17 @@ 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;
+ /// \brief Target supports replacing a data "PC"-relative access to a symbol
+ /// through another symbol, by accessing the later via a GOT entry instead?
+ bool supportIndirectSymViaGOTPCRel() const {
+ return SupportIndirectSymViaGOTPCRel;
+ }
+
+ /// \brief Get the target specific PC relative GOT entry relocation
+ virtual const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym,
+ int64_t Offset) const {
+ return nullptr;
+ }
protected:
virtual const MCSection *
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index a4f95c0612..cdf643d69e 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -34,14 +34,14 @@ class Target;
class DataLayout;
class TargetLibraryInfo;
class TargetFrameLowering;
+class TargetIRAnalysis;
class TargetIntrinsicInfo;
class TargetLowering;
class TargetPassConfig;
class TargetRegisterInfo;
class TargetSelectionDAGInfo;
class TargetSubtargetInfo;
-class ScalarTargetTransformInfo;
-class VectorTargetTransformInfo;
+class TargetTransformInfo;
class formatted_raw_ostream;
class raw_ostream;
class TargetLoweringObjectFile;
@@ -59,8 +59,8 @@ using legacy::PassManagerBase;
/// through this interface.
///
class TargetMachine {
- TargetMachine(const TargetMachine &) LLVM_DELETED_FUNCTION;
- void operator=(const TargetMachine &) LLVM_DELETED_FUNCTION;
+ TargetMachine(const TargetMachine &) = delete;
+ void operator=(const TargetMachine &) = delete;
protected: // Can only create subclasses.
TargetMachine(const Target &T, StringRef TargetTriple,
StringRef CPU, StringRef FS, const TargetOptions &Options);
@@ -113,10 +113,16 @@ public:
template<typename STC> const STC &getSubtarget() const {
return *static_cast<const STC*>(getSubtargetImpl());
}
- template <typename STC> const STC &getSubtarget(const Function *) const {
+ template <typename STC> const STC &getSubtarget(const Function &) const {
return *static_cast<const STC*>(getSubtargetImpl());
}
+ /// getDataLayout - This method returns a pointer to the DataLayout for
+ /// the target. It should be unchanging for every subtarget.
+ virtual const DataLayout *getDataLayout() const {
+ return nullptr;
+ }
+
/// \brief Reset the target options based on the function's attributes.
// FIXME: Remove TargetOptions that affect per-function code generation
// from TargetMachine.
@@ -159,31 +165,32 @@ public:
bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }
- /// getAsmVerbosityDefault - Returns the default value of asm verbosity.
+ /// Returns the default value of asm verbosity.
///
- bool getAsmVerbosityDefault() const ;
-
- /// setAsmVerbosityDefault - Set the default value of asm verbosity. Default
- /// is false.
- void setAsmVerbosityDefault(bool);
-
- /// getDataSections - Return true if data objects should be emitted into their
- /// own section, corresponds to -fdata-sections.
- bool getDataSections() const;
+ bool getAsmVerbosityDefault() const {
+ return Options.MCOptions.AsmVerbose;
+ }
- /// getFunctionSections - Return true if functions should be emitted into
- /// their own section, corresponding to -ffunction-sections.
- bool getFunctionSections() const;
+ bool getUniqueSectionNames() const { return Options.UniqueSectionNames; }
- /// setDataSections - Set if the data are emit into separate sections.
- void setDataSections(bool);
+ /// Return true if data objects should be emitted into their own section,
+ /// corresponds to -fdata-sections.
+ bool getDataSections() const {
+ return Options.DataSections;
+ }
- /// setFunctionSections - Set if the functions are emit into separate
- /// sections.
- void setFunctionSections(bool);
+ /// Return true if functions should be emitted into their own section,
+ /// corresponding to -ffunction-sections.
+ bool getFunctionSections() const {
+ return Options.FunctionSections;
+ }
- /// \brief Register analysis passes for this target with a pass manager.
- virtual void addAnalysisPasses(PassManagerBase &) {}
+ /// \brief Get a \c TargetIRAnalysis appropriate for the target.
+ ///
+ /// This is used to construct the new pass manager's target IR analysis pass,
+ /// set up appropriately for this target machine. Even the old pass manager
+ /// uses this to answer queries about the IR.
+ virtual TargetIRAnalysis getTargetIRAnalysis();
/// CodeGenFileType - These enums are meant to be passed into
/// addPassesToEmitFile to indicate what type of file to emit, and returned by
@@ -236,10 +243,11 @@ protected: // Can only create subclasses.
void initAsmInfo();
public:
- /// \brief Register analysis passes for this target with a pass manager.
+ /// \brief Get a TargetIRAnalysis implementation for the target.
///
- /// This registers target independent analysis passes.
- void addAnalysisPasses(PassManagerBase &PM) override;
+ /// This analysis will produce a TTI result which uses the common code
+ /// generator to answer queries about the IR.
+ TargetIRAnalysis getTargetIRAnalysis() override;
/// createPassConfig - Create a pass configuration object to be used by
/// addPassToEmitX methods for generating a pipeline of CodeGen passes.
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
index 1fbd2ae09b..afc22365eb 100644
--- a/include/llvm/Target/TargetOpcodes.h
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -110,7 +110,18 @@ enum {
/// 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
+ 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 73014d846f..f447fd6011 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -78,8 +78,8 @@ namespace llvm {
EnableFastISel(false), PositionIndependentExecutable(false),
UseInitArray(false), DisableIntegratedAS(false),
CompressDebugSections(false), FunctionSections(false),
- DataSections(false), TrapUnreachable(false), TrapFuncName(),
- FloatABIType(FloatABI::Default),
+ DataSections(false), UniqueSectionNames(true), TrapUnreachable(false),
+ TrapFuncName(), FloatABIType(FloatABI::Default),
AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single),
FCFI(false), ThreadModel(ThreadModel::POSIX),
CFIType(CFIntegrity::Sub), CFIEnforcing(false), CFIFuncName() {}
@@ -198,6 +198,8 @@ namespace llvm {
/// Emit data into separate sections.
unsigned DataSections : 1;
+ unsigned UniqueSectionNames : 1;
+
/// Emit target-specific trap instruction for 'unreachable' IR instructions.
unsigned TrapUnreachable : 1;
@@ -288,6 +290,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 16b72a98db..fc94a849aa 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -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&);
@@ -190,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
@@ -448,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,
@@ -502,6 +515,15 @@ 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);
@@ -512,6 +534,12 @@ protected:
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.
///
@@ -666,13 +694,13 @@ public:
return false;
}
- /// UpdateRegAllocHint - A callback to allow target a chance to update
+ /// updateRegAllocHint - A callback to allow target a chance to update
/// register allocation hints when a register is "changed" (e.g. coalesced)
/// to another register. e.g. On ARM, some virtual registers should target
/// register pairs, if one of pair is coalesced to another register, the
/// allocation hint of the other half of the pair should be changed to point
/// to the new register.
- virtual void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
+ virtual void updateRegAllocHint(unsigned Reg, unsigned NewReg,
MachineFunction &MF) const {
// Do nothing.
}
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index f63afd7098..d297162a7f 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -188,6 +188,22 @@ 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 SDTMaskedGather: SDTypeProfile<1, 3, [ // masked gather
+ SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisVec<2>
+]>;
+
+def SDTMaskedScatter: SDTypeProfile<1, 3, [ // masked scatter
+ SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<0, 2>
+]>;
+
def SDTVecShuffle : SDTypeProfile<1, 2, [
SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
]>;
@@ -363,6 +379,7 @@ def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>;
def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>;
def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>;
def bitconvert : SDNode<"ISD::BITCAST" , SDTUnaryOp>;
+def addrspacecast : SDNode<"ISD::ADDRSPACECAST", SDTUnaryOp>;
def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>;
def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>;
@@ -372,6 +389,7 @@ def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>;
def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>;
def frem : SDNode<"ISD::FREM" , SDTFPBinOp>;
def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp>;
+def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp>;
def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>;
def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp>;
def fmaxnum : SDNode<"ISD::FMAXNUM" , SDTFPBinOp>;
@@ -454,6 +472,15 @@ 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]>;
+def masked_scatter : SDNode<"ISD::MSCATTER", SDTMaskedScatter,
+ [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+def masked_gather : SDNode<"ISD::MGATHER", SDTMaskedGather,
+ [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 d1a3fcf4a5..bacdd95070 100644
--- a/include/llvm/Target/TargetSelectionDAGInfo.h
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -21,15 +21,14 @@
namespace llvm {
class DataLayout;
-class TargetMachine;
//===----------------------------------------------------------------------===//
/// TargetSelectionDAGInfo - Targets can subclass this to parameterize the
/// SelectionDAG lowering and instruction selection process.
///
class TargetSelectionDAGInfo {
- TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
- void operator=(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
+ TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) = delete;
+ void operator=(const TargetSelectionDAGInfo &) = delete;
const DataLayout *DL;
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index 80ff9e354d..83ab4ec052 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -42,8 +42,8 @@ template <typename T> class SmallVectorImpl;
/// be exposed through a TargetSubtargetInfo-derived class.
///
class TargetSubtargetInfo : public MCSubtargetInfo {
- TargetSubtargetInfo(const TargetSubtargetInfo&) LLVM_DELETED_FUNCTION;
- void operator=(const TargetSubtargetInfo&) LLVM_DELETED_FUNCTION;
+ TargetSubtargetInfo(const TargetSubtargetInfo&) = delete;
+ void operator=(const TargetSubtargetInfo&) = delete;
protected: // Can only create subclasses...
TargetSubtargetInfo();
public:
@@ -71,7 +71,6 @@ public:
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
@@ -168,6 +167,11 @@ public:
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