diff options
author | Stephen Hines <srhines@google.com> | 2015-03-23 12:10:34 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2015-03-23 12:10:34 -0700 |
commit | ebe69fe11e48d322045d5949c83283927a0d790b (patch) | |
tree | c92f1907a6b8006628a4b01615f38264d29834ea /include/llvm/Target | |
parent | b7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff) | |
download | external_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.td | 55 | ||||
-rw-r--r-- | include/llvm/Target/TargetCallingConv.h | 11 | ||||
-rw-r--r-- | include/llvm/Target/TargetFrameLowering.h | 19 | ||||
-rw-r--r-- | include/llvm/Target/TargetInstrInfo.h | 17 | ||||
-rw-r--r-- | include/llvm/Target/TargetIntrinsicInfo.h | 4 | ||||
-rw-r--r-- | include/llvm/Target/TargetLibraryInfo.h | 813 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 312 | ||||
-rw-r--r-- | include/llvm/Target/TargetLoweringObjectFile.h | 33 | ||||
-rw-r--r-- | include/llvm/Target/TargetMachine.h | 64 | ||||
-rw-r--r-- | include/llvm/Target/TargetOpcodes.h | 13 | ||||
-rw-r--r-- | include/llvm/Target/TargetOptions.h | 12 | ||||
-rw-r--r-- | include/llvm/Target/TargetRegisterInfo.h | 32 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAG.td | 27 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAGInfo.h | 5 | ||||
-rw-r--r-- | include/llvm/Target/TargetSubtargetInfo.h | 10 |
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 |