diff options
| author | Stephen Hines <srhines@google.com> | 2012-09-05 22:31:59 -0700 |
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2012-09-05 22:31:59 -0700 |
| commit | cbbf0ced2c07892c0df3dd17def157ecb5e58b95 (patch) | |
| tree | c1970fcebc736d4f731db0559a79a7ac5cb0f8bf /include/llvm/Target | |
| parent | a81c41dc02ccbc654a9c2f638f9fbf2b599f5dfd (diff) | |
| parent | 31675153bd2d7617db8cb6aeb58054934c7b9f73 (diff) | |
| download | external_llvm-cbbf0ced2c07892c0df3dd17def157ecb5e58b95.zip external_llvm-cbbf0ced2c07892c0df3dd17def157ecb5e58b95.tar.gz external_llvm-cbbf0ced2c07892c0df3dd17def157ecb5e58b95.tar.bz2 | |
am 31675153: Merge branch \'upstream\' into merge_2
* commit '31675153bd2d7617db8cb6aeb58054934c7b9f73': (542 commits)
MaximumSpanningTree::EdgeWeightCompare: Make this comparator actually be a strict weak ordering, and don't pass possibly-null pointers to dyn_cast.
Fix misaligned access in MachO object file reader: despite containing an int64_t, Symbol64TableEntry is actually only stored with 4-byte alignment within the file.
Fix unaligned memory accesses when performing relocations in X86 JIT. There's no cost to using memcpy here: the fixed code is optimized by LLVM to perfect machine code.
Don't pass a null pointer to cast<> in its unit tests.
Don't bind a reference to a dereferenced null pointer (for return value of WeakVH::operator*).
[ms-inline asm] Do not report a Parser error when matching inline assembly.
Ignore the documentation-suggested location for compile_commands.json
The presence of the empty file "foo" unfortunately does not improve LLVM in any way.
Remove unnecessary cast that was also unnecessarily casting away constness.
Provide a portability macro for __builtin_trap.
Fix macros arguments with an underscore, dot or dollar in them. This is based on a patch by Andy/PaX. I added the support for dot and dollar.
[ms-inline asm] Expose the ErrorInfo from the MatchInstructionImpl. In general, this is the index of the operand that failed to match.
Formatting. No functional change.
Make the wording in of the "expected identifier" error in the .macro directive consistent with the other "expected identifier" errors. Extracted from the Andy/PaX patch. I added the test.
Pacify PVS-Studio by changing the type rather than doing a cast, a tweak suggested by David Blaikie.
Add support for the --param ssp-buffer-size= driver option. PR9673
Use typedefs. Fix indentation. Extracted from the Andy/PaX patch.
Remove unused variable. Extracted from the Andy/PaX patch.
Fix typo. Extracted from the Andy/PaX patch.
MCJIT: Tidy up the constructor.
...
Diffstat (limited to 'include/llvm/Target')
| -rw-r--r-- | include/llvm/Target/Target.td | 38 | ||||
| -rw-r--r-- | include/llvm/Target/TargetInstrInfo.h | 71 | ||||
| -rw-r--r-- | include/llvm/Target/TargetLibraryInfo.h | 187 | ||||
| -rw-r--r-- | include/llvm/Target/TargetLowering.h | 8 | ||||
| -rw-r--r-- | include/llvm/Target/TargetOptions.h | 4 | ||||
| -rw-r--r-- | include/llvm/Target/TargetRegisterInfo.h | 10 | ||||
| -rw-r--r-- | include/llvm/Target/TargetSchedule.td | 1 | ||||
| -rw-r--r-- | include/llvm/Target/TargetSelectionDAG.td | 3 |
8 files changed, 230 insertions, 92 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 03adcce..c406bca 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -28,6 +28,24 @@ class SubRegIndex<list<SubRegIndex> comps = []> { // ComposedOf - A list of two SubRegIndex instances, [A, B]. // This indicates that this SubRegIndex is the result of composing A and B. list<SubRegIndex> ComposedOf = comps; + + // CoveringSubRegIndices - A list of two or more sub-register indexes that + // cover this sub-register. + // + // This field should normally be left blank as TableGen can infer it. + // + // TableGen automatically detects sub-registers that straddle the registers + // in the SubRegs field of a Register definition. For example: + // + // Q0 = dsub_0 -> D0, dsub_1 -> D1 + // Q1 = dsub_0 -> D2, dsub_1 -> D3 + // D1_D2 = dsub_0 -> D1, dsub_1 -> D2 + // QQ0 = qsub_0 -> Q0, qsub_1 -> Q1 + // + // TableGen will infer that D1_D2 is a sub-register of QQ0. It will be given + // the synthetic index dsub_1_dsub_2 unless some SubRegIndex is defined with + // CoveringSubRegIndices = [dsub_1, dsub_2]. + list<SubRegIndex> CoveringSubRegIndices = []; } // RegAltNameIndex - The alternate name set to use for register operands of @@ -64,18 +82,6 @@ class Register<string n, list<string> altNames = []> { // register. list<RegAltNameIndex> RegAltNameIndices = []; - // CompositeIndices - Specify subreg indices that don't correspond directly to - // a register in SubRegs and are not inherited. The following formats are - // supported: - // - // (a) Identity - Reg:a == Reg - // (a b) Alias - Reg:a == Reg:b - // (a b,c) Composite - Reg:a == (Reg:b):c - // - // This can be used to disambiguate a sub-sub-register that exists in more - // than one subregister and other weird stuff. - list<dag> CompositeIndices = []; - // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register. // These values can be determined by locating the <target>.h file in the // directory llvmgcc/gcc/config/<target>/ and looking for REGISTER_NAMES. The @@ -252,9 +258,6 @@ class RegisterTuples<list<SubRegIndex> Indices, list<dag> Regs> { // SubRegIndices - N SubRegIndex instances. This provides the names of the // sub-registers in the synthesized super-registers. list<SubRegIndex> SubRegIndices = Indices; - - // Compose sub-register indices like in a normal Register. - list<dag> CompositeIndices = []; } @@ -336,6 +339,7 @@ class Instruction { bit isCompare = 0; // Is this instruction a comparison instruction? bit isMoveImm = 0; // Is this instruction a move immediate instruction? bit isBitcast = 0; // Is this instruction a bitcast instruction? + bit isSelect = 0; // Is this instruction a select instruction? bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand? @@ -749,6 +753,10 @@ class AsmParser { // function of the AsmParser class to call on every matched instruction. // This can be used to perform target specific instruction post-processing. string AsmParserInstCleanup = ""; + + //ShouldEmitMatchRegisterName - Set to false if the target needs a hand + //written register name matcher + bit ShouldEmitMatchRegisterName = 1; } def DefaultAsmParser : AsmParser; diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 73efc50..da30ab8 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_TARGET_TARGETINSTRINFO_H #define LLVM_TARGET_TARGETINSTRINFO_H +#include "llvm/ADT/SmallSet.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/CodeGen/DFAPacketizer.h" #include "llvm/CodeGen/MachineFunction.h" @@ -27,6 +28,7 @@ class MachineMemOperand; class MachineRegisterInfo; class MDNode; class MCInst; +class MCSchedModel; class SDNode; class ScheduleHazardRecognizer; class SelectionDAG; @@ -186,14 +188,6 @@ public: const MachineInstr *Orig, const TargetRegisterInfo &TRI) const = 0; - /// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the - /// two-addrss instruction inserted by two-address pass. - virtual void scheduleTwoAddrSource(MachineInstr *SrcMI, - MachineInstr *UseMI, - const TargetRegisterInfo &TRI) const { - // Do nothing. - } - /// duplicate - Create a duplicate of the Orig instruction in MF. This is like /// MachineFunction::CloneMachineInstr(), but the target may update operands /// that are required to be unique. @@ -419,6 +413,51 @@ public: llvm_unreachable("Target didn't implement TargetInstrInfo::insertSelect!"); } + /// analyzeSelect - Analyze the given select instruction, returning true if + /// it cannot be understood. It is assumed that MI->isSelect() is true. + /// + /// When successful, return the controlling condition and the operands that + /// determine the true and false result values. + /// + /// Result = SELECT Cond, TrueOp, FalseOp + /// + /// Some targets can optimize select instructions, for example by predicating + /// the instruction defining one of the operands. Such targets should set + /// Optimizable. + /// + /// @param MI Select instruction to analyze. + /// @param Cond Condition controlling the select. + /// @param TrueOp Operand number of the value selected when Cond is true. + /// @param FalseOp Operand number of the value selected when Cond is false. + /// @param Optimizable Returned as true if MI is optimizable. + /// @returns False on success. + virtual bool analyzeSelect(const MachineInstr *MI, + SmallVectorImpl<MachineOperand> &Cond, + unsigned &TrueOp, unsigned &FalseOp, + bool &Optimizable) const { + assert(MI && MI->isSelect() && "MI must be a select instruction"); + return true; + } + + /// optimizeSelect - Given a select instruction that was understood by + /// analyzeSelect and returned Optimizable = true, attempt to optimize MI by + /// merging it with one of its operands. Returns NULL on failure. + /// + /// When successful, returns the new select instruction. The client is + /// responsible for deleting MI. + /// + /// If both sides of the select can be optimized, PreferFalse is used to pick + /// a side. + /// + /// @param MI Optimizable select instruction. + /// @param PreferFalse Try to optimize FalseOp instead of TrueOp. + /// @returns Optimized instruction or NULL. + virtual MachineInstr *optimizeSelect(MachineInstr *MI, + bool PreferFalse = false) const { + // This function must be implemented if Optimizable is ever set. + llvm_unreachable("Target must implement TargetInstrInfo::optimizeSelect!"); + } + /// copyPhysReg - Emit instructions to copy a pair of physical registers. virtual void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL, @@ -693,6 +732,20 @@ public: return false; } + /// optimizeLoadInstr - Try to remove the load by folding it to a register + /// operand at the use. We fold the load instructions if and only if the + /// def and use are in the same BB. We only look at one load and see + /// whether it can be folded into MI. FoldAsLoadDefReg is the virtual register + /// defined by the load we are trying to fold. DefMI returns the machine + /// instruction that defines FoldAsLoadDefReg, and the function returns + /// the machine instruction generated due to folding. + virtual MachineInstr* optimizeLoadInstr(MachineInstr *MI, + const MachineRegisterInfo *MRI, + unsigned &FoldAsLoadDefReg, + MachineInstr *&DefMI) const { + return 0; + } + /// FoldImmediate - 'Reg' is known to be defined by a move immediate /// instruction, try to fold the immediate into the use instruction. virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, @@ -775,7 +828,7 @@ public: SDNode *Node) const = 0; /// Return the default expected latency for a def based on it's opcode. - unsigned defaultDefLatency(const InstrItineraryData *ItinData, + unsigned defaultDefLatency(const MCSchedModel *SchedModel, const MachineInstr *DefMI) const; /// isHighLatencyDef - Return true if this opcode has high latency to its diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h index c8cacf2..ea2874f 100644 --- a/include/llvm/Target/TargetLibraryInfo.h +++ b/include/llvm/Target/TargetLibraryInfo.h @@ -18,36 +18,47 @@ namespace llvm { namespace LibFunc { enum Func { + /// 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, + /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size); + memcpy_chk, /// double acos(double x); acos, - /// long double acosl(long double x); - acosl, /// float acosf(float x); acosf, + /// long double acosl(long double x); + acosl, /// double asin(double x); asin, - /// long double asinl(long double x); - asinl, /// float asinf(float x); asinf, + /// long double asinl(long double x); + asinl, /// double atan(double x); atan, - /// long double atanl(long double x); - atanl, - /// float atanf(float x); - atanf, /// double atan2(double y, double x); atan2, - /// long double atan2l(long double y, long double x); - atan2l, /// float atan2f(float y, float x); atan2f, + /// long double atan2l(long double y, long double x); + atan2l, + /// float atanf(float x); + atanf, + /// long double atanl(long double x); + atanl, /// double ceil(double x); ceil, - /// long double ceill(long double x); - ceill, /// float ceilf(float x); ceilf, + /// long double ceill(long double x); + ceill, /// double copysign(double x, double y); copysign, /// float copysignf(float x, float y); @@ -56,54 +67,56 @@ namespace llvm { copysignl, /// double cos(double x); cos, - /// long double cosl(long double x); - cosl, /// float cosf(float x); cosf, /// double cosh(double x); cosh, - /// long double coshl(long double x); - coshl, /// float coshf(float x); coshf, + /// long double coshl(long double x); + coshl, + /// long double cosl(long double x); + cosl, /// double exp(double x); exp, - /// long double expl(long double x); - expl, - /// float expf(float x); - expf, /// double exp2(double x); exp2, - /// long double exp2l(long double x); - exp2l, /// 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, - /// long double expm1l(long double x); - expm1l, /// float expm1f(float x); expm1f, + /// long double expm1l(long double x); + expm1l, /// double fabs(double x); fabs, - /// long double fabsl(long double x); - fabsl, /// float fabsf(float x); fabsf, + /// long double fabsl(long double x); + fabsl, + /// int fiprintf(FILE *stream, const char *format, ...); + fiprintf, /// double floor(double x); floor, - /// long double floorl(long double x); - floorl, /// float floorf(float x); floorf, - /// int fiprintf(FILE *stream, const char *format, ...); - fiprintf, + /// long double floorl(long double x); + floorl, /// double fmod(double x, double y); fmod, - /// long double fmodl(long double x, long double y); - fmodl, /// float fmodf(float x, float y); fmodf, + /// long double fmodl(long double x, long double y); + fmodl, + /// int fputc(int c, FILE *stream); + fputc, /// int fputs(const char *s, FILE *stream); fputs, /// size_t fwrite(const void *ptr, size_t size, size_t nitems, @@ -113,28 +126,32 @@ namespace llvm { iprintf, /// double log(double x); log, - /// long double logl(long double x); - logl, - /// float logf(float x); - logf, - /// double log2(double x); - log2, - /// double long double log2l(long double x); - log2l, - /// float log2f(float x); - log2f, /// double log10(double x); log10, - /// long double log10l(long double x); - log10l, /// float log10f(float x); log10f, + /// long double log10l(long double x); + log10l, /// double log1p(double x); log1p, - /// long double log1pl(long double x); - log1pl, /// 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, + /// float logf(float x); + logf, + /// long double logl(long double x); + logl, + /// 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); @@ -155,6 +172,10 @@ namespace llvm { powf, /// long double powl(long double x, long double y); powl, + /// int putchar(int c); + putchar, + /// int puts(const char *s); + puts, /// double rint(double x); rint, /// float rintf(float x); @@ -169,51 +190,58 @@ namespace llvm { roundl, /// double sin(double x); sin, - /// long double sinl(long double x); - sinl, /// float sinf(float x); sinf, /// double sinh(double x); sinh, - /// long double sinhl(long double x); - sinhl, /// 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, /// double sqrt(double x); sqrt, - /// long double sqrtl(long double x); - sqrtl, /// float sqrtf(float x); sqrtf, + /// long double sqrtl(long double x); + sqrtl, + /// char *strcat(char *s1, const char *s2); + strcat, + /// char *strchr(const char *s, int c); + strchr, + /// char *strcpy(char *s1, const char *s2); + strcpy, + /// size_t strlen(const char *s); + strlen, + /// 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, + /// size_t strnlen(const char *s, size_t maxlen); + strnlen, /// double tan(double x); tan, - /// long double tanl(long double x); - tanl, /// float tanf(float x); tanf, /// double tanh(double x); tanh, - /// long double tanhl(long double x); - tanhl, /// float tanhf(float x); tanhf, + /// long double tanhl(long double x); + tanhl, + /// long double tanl(long double x); + tanl, /// double trunc(double x); trunc, /// float truncf(float x); truncf, /// long double truncl(long double x); truncl, - /// 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, NumLibFuncs }; @@ -247,12 +275,41 @@ public: 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::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::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: + return true; + } + return false; + } + StringRef getName(LibFunc::Func F) const { AvailabilityState State = getState(F); if (State == Unavailable) diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 7ad90ea..acf0419 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -51,6 +51,7 @@ namespace llvm { template<typename T> class SmallVectorImpl; class TargetData; class TargetRegisterClass; + class TargetLibraryInfo; class TargetLoweringObjectFile; class Value; @@ -365,7 +366,9 @@ public: /// for it. LegalizeAction getOperationAction(unsigned Op, EVT VT) const { if (VT.isExtended()) return Expand; - assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!"); + // If a target-specific SDNode requires legalization, require the target + // to provide custom legalization for it. + if (Op > array_lengthof(OpActions[0])) return Custom; unsigned I = (unsigned) VT.getSimpleVT().SimpleTy; return (LegalizeAction)OpActions[I][Op]; } @@ -1413,7 +1416,8 @@ public: /// createFastISel - This method returns a target specific FastISel object, /// or null if the target does not support "fast" ISel. - virtual FastISel *createFastISel(FunctionLoweringInfo &) const { + virtual FastISel *createFastISel(FunctionLoweringInfo &, + const TargetLibraryInfo *) const { return 0; } diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index d1a07d1..68ca567 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -155,6 +155,10 @@ namespace llvm { /// automatically realigned, if needed. unsigned RealignStack : 1; + /// SSPBufferSize - The minimum size of buffers that will receive stack + /// smashing protection when -fstack-protection is used. + unsigned SSPBufferSize; + /// EnableFastISel - This flag enables fast-path instruction selection /// which trades away generated code quality in favor of reducing /// compile time. diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index a5bd7c9..df4d900 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -152,7 +152,7 @@ public: } /// getSuperRegIndices - Returns a 0-terminated list of sub-register indices - /// that projec some super-register class into this register class. The list + /// that project some super-register class into this register class. The list /// has an entry for each Idx such that: /// /// There exists SuperRC where: @@ -349,6 +349,14 @@ public: return false; } + /// hasRegUnit - Returns true if Reg contains RegUnit. + bool hasRegUnit(unsigned Reg, unsigned RegUnit) const { + for (MCRegUnitIterator Units(Reg, this); Units.isValid(); ++Units) + if (*Units == RegUnit) + return true; + return false; + } + /// isSubRegister - Returns true if regB is a sub-register of regA. /// bool isSubRegister(unsigned regA, unsigned regB) const { diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index 5bbed58..4dc488d 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -27,6 +27,7 @@ class SchedMachineModel { // (-1) inorder (0) ooo, (1): inorder +var latencies. int LoadLatency = -1; // Cycles for loads to access the cache. int HighLatency = -1; // Approximation of cycles for "high latency" ops. + int MispredictPenalty = -1; // Extra cycles for a mispredicted branch. ProcessorItineraries Itineraries = NoItineraries; diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index ff006b6..3f81c06 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -411,6 +411,9 @@ def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch, [SDNPHasChain, SDNPMayLoad, SDNPMayStore, SDNPMemOperand]>; +def readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf, + [SDNPHasChain, SDNPSideEffect]>; + def membarrier : SDNode<"ISD::MEMBARRIER" , SDTMemBarrier, [SDNPHasChain, SDNPSideEffect]>; |
