diff options
Diffstat (limited to 'include/llvm')
26 files changed, 507 insertions, 143 deletions
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index b9f2d83..3a86b0d 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -329,7 +329,8 @@ public: Size = RHS.size(); unsigned RHSWords = NumBitWords(Size); if (Size <= Capacity * BITWORD_SIZE) { - std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits); + if (Size) + std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits); clear_unused_bits(); return *this; } diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h index f5f3d49..5f89823 100644 --- a/include/llvm/ADT/EquivalenceClasses.h +++ b/include/llvm/ADT/EquivalenceClasses.h @@ -16,6 +16,7 @@ #define LLVM_ADT_EQUIVALENCECLASSES_H #include "llvm/System/DataTypes.h" +#include <cassert> #include <set> namespace llvm { diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index 81dc469..e8979bb 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -23,6 +23,7 @@ namespace llvm { class APFloat; class APInt; + class BumpPtrAllocator; /// This folding set used for two purposes: /// 1. Given information about a node we want to create, look up the unique @@ -198,6 +199,23 @@ template<typename T> struct FoldingSetTrait { }; //===--------------------------------------------------------------------===// +/// FoldingSetNodeIDRef - This class describes a reference to an interned +/// FoldingSetNodeID, which can be a useful to store node id data rather +/// than using plain FoldingSetNodeIDs, since the 32-element SmallVector +/// is often much larger than necessary, and the possibility of heap +/// allocation means it requires a non-trivial destructor call. +class FoldingSetNodeIDRef { + unsigned* Data; + size_t Size; +public: + FoldingSetNodeIDRef() : Data(0), Size(0) {} + FoldingSetNodeIDRef(unsigned *D, size_t S) : Data(D), Size(S) {} + + unsigned *getData() const { return Data; } + size_t getSize() const { return Size; } +}; + +//===--------------------------------------------------------------------===// /// FoldingSetNodeID - This class is used to gather all the unique data bits of /// a node. When all the bits are gathered this class is used to produce a /// hash value for the node. @@ -210,11 +228,8 @@ class FoldingSetNodeID { public: FoldingSetNodeID() {} - /// getRawData - Return the ith entry in the Bits data. - /// - unsigned getRawData(unsigned i) const { - return Bits[i]; - } + FoldingSetNodeID(FoldingSetNodeIDRef Ref) + : Bits(Ref.getData(), Ref.getData() + Ref.getSize()) {} /// Add* - Add various data types to Bit data. /// @@ -242,6 +257,11 @@ public: /// operator== - Used to compare two nodes to each other. /// bool operator==(const FoldingSetNodeID &RHS) const; + + /// Intern - Copy this node's data to a memory region allocated from the + /// given allocator and return a FoldingSetNodeIDRef describing the + /// interned data. + FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const; }; // Convenience type to hide the implementation of the folding set. diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 89acefd..c2afb7e 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -57,17 +57,18 @@ protected: // something else. An array of char would work great, but might not be // aligned sufficiently. Instead, we either use GCC extensions, or some // number of union instances for the space, which guarantee maximal alignment. + struct U { #ifdef __GNUC__ - typedef char U; - U FirstEl __attribute__((aligned)); + char X __attribute__((aligned)); #else - union U { - double D; - long double LD; - long long L; - void *P; - } FirstEl; + union { + double D; + long double LD; + long long L; + void *P; + } X; #endif + } FirstEl; // Space after 'FirstEl' is clobbered, do not add any instance vars after it. protected: diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 96d29ba..ab13a9d 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -49,7 +49,11 @@ namespace llvm { /// are opaque objects that the client is not allowed to do much with /// directly. /// - class SCEV : public FastFoldingSetNode { + class SCEV : public FoldingSetNode { + /// FastID - A reference to an Interned FoldingSetNodeID for this node. + /// The ScalarEvolution's BumpPtrAllocator holds the data. + FoldingSetNodeIDRef FastID; + // The SCEV baseclass this node corresponds to const unsigned short SCEVType; @@ -64,11 +68,14 @@ namespace llvm { protected: virtual ~SCEV(); public: - explicit SCEV(const FoldingSetNodeID &ID, unsigned SCEVTy) : - FastFoldingSetNode(ID), SCEVType(SCEVTy), SubclassData(0) {} + explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) : + FastID(ID), SCEVType(SCEVTy), SubclassData(0) {} unsigned getSCEVType() const { return SCEVType; } + /// Profile - FoldingSet support. + void Profile(FoldingSetNodeID& ID) { ID = FastID; } + /// isLoopInvariant - Return true if the value of this SCEV is unchanging in /// the specified loop. virtual bool isLoopInvariant(const Loop *L) const = 0; diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 26dc0c4..dc9b73b 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -79,12 +79,7 @@ namespace llvm { /// expandCodeFor - Insert code to directly compute the specified SCEV /// expression into the program. The inserted code is inserted into the /// specified block. - Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *I) { - BasicBlock::iterator IP = I; - while (isInsertedInstruction(IP)) ++IP; - Builder.SetInsertPoint(IP->getParent(), IP); - return expandCodeFor(SH, Ty); - } + Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *I); /// setIVIncInsertPos - Set the current IV increment loop and position. void setIVIncInsertPos(const Loop *L, Instruction *Pos) { @@ -109,6 +104,13 @@ namespace llvm { /// is useful for late optimization passes. void disableCanonicalMode() { CanonicalMode = false; } + /// clearInsertPoint - Clear the current insertion point. This is useful + /// if the instruction that had been serving as the insertion point may + /// have been deleted. + void clearInsertPoint() { + Builder.ClearInsertionPoint(); + } + private: LLVMContext &getContext() const { return SE.getContext(); } diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 0ab3b3f..7424203 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -37,7 +37,7 @@ namespace llvm { friend class ScalarEvolution; ConstantInt *V; - SCEVConstant(const FoldingSetNodeID &ID, ConstantInt *v) : + SCEVConstant(const FoldingSetNodeIDRef ID, ConstantInt *v) : SCEV(ID, scConstant), V(v) {} public: ConstantInt *getValue() const { return V; } @@ -81,7 +81,7 @@ namespace llvm { const SCEV *Op; const Type *Ty; - SCEVCastExpr(const FoldingSetNodeID &ID, + SCEVCastExpr(const FoldingSetNodeIDRef ID, unsigned SCEVTy, const SCEV *op, const Type *ty); public: @@ -120,7 +120,7 @@ namespace llvm { class SCEVTruncateExpr : public SCEVCastExpr { friend class ScalarEvolution; - SCEVTruncateExpr(const FoldingSetNodeID &ID, + SCEVTruncateExpr(const FoldingSetNodeIDRef ID, const SCEV *op, const Type *ty); public: @@ -140,7 +140,7 @@ namespace llvm { class SCEVZeroExtendExpr : public SCEVCastExpr { friend class ScalarEvolution; - SCEVZeroExtendExpr(const FoldingSetNodeID &ID, + SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID, const SCEV *op, const Type *ty); public: @@ -160,7 +160,7 @@ namespace llvm { class SCEVSignExtendExpr : public SCEVCastExpr { friend class ScalarEvolution; - SCEVSignExtendExpr(const FoldingSetNodeID &ID, + SCEVSignExtendExpr(const FoldingSetNodeIDRef ID, const SCEV *op, const Type *ty); public: @@ -180,25 +180,27 @@ namespace llvm { /// class SCEVNAryExpr : public SCEV { protected: - SmallVector<const SCEV *, 8> Operands; + // Since SCEVs are immutable, ScalarEvolution allocates operand + // arrays with its SCEVAllocator, so this class just needs a simple + // pointer rather than a more elaborate vector-like data structure. + // This also avoids the need for a non-trivial destructor. + const SCEV *const *Operands; + size_t NumOperands; - SCEVNAryExpr(const FoldingSetNodeID &ID, - enum SCEVTypes T, const SmallVectorImpl<const SCEV *> &ops) - : SCEV(ID, T), Operands(ops.begin(), ops.end()) {} + SCEVNAryExpr(const FoldingSetNodeIDRef ID, + enum SCEVTypes T, const SCEV *const *O, size_t N) + : SCEV(ID, T), Operands(O), NumOperands(N) {} public: - unsigned getNumOperands() const { return (unsigned)Operands.size(); } + size_t getNumOperands() const { return NumOperands; } const SCEV *getOperand(unsigned i) const { - assert(i < Operands.size() && "Operand index out of range!"); + assert(i < NumOperands && "Operand index out of range!"); return Operands[i]; } - const SmallVectorImpl<const SCEV *> &getOperands() const { - return Operands; - } - typedef SmallVectorImpl<const SCEV *>::const_iterator op_iterator; - op_iterator op_begin() const { return Operands.begin(); } - op_iterator op_end() const { return Operands.end(); } + typedef const SCEV *const *op_iterator; + op_iterator op_begin() const { return Operands; } + op_iterator op_end() const { return Operands + NumOperands; } virtual bool isLoopInvariant(const Loop *L) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) @@ -260,10 +262,9 @@ namespace llvm { /// class SCEVCommutativeExpr : public SCEVNAryExpr { protected: - SCEVCommutativeExpr(const FoldingSetNodeID &ID, - enum SCEVTypes T, - const SmallVectorImpl<const SCEV *> &ops) - : SCEVNAryExpr(ID, T, ops) {} + SCEVCommutativeExpr(const FoldingSetNodeIDRef ID, + enum SCEVTypes T, const SCEV *const *O, size_t N) + : SCEVNAryExpr(ID, T, O, N) {} public: virtual const char *getOperationStr() const = 0; @@ -287,9 +288,9 @@ namespace llvm { class SCEVAddExpr : public SCEVCommutativeExpr { friend class ScalarEvolution; - SCEVAddExpr(const FoldingSetNodeID &ID, - const SmallVectorImpl<const SCEV *> &ops) - : SCEVCommutativeExpr(ID, scAddExpr, ops) { + SCEVAddExpr(const FoldingSetNodeIDRef ID, + const SCEV *const *O, size_t N) + : SCEVCommutativeExpr(ID, scAddExpr, O, N) { } public: @@ -315,9 +316,9 @@ namespace llvm { class SCEVMulExpr : public SCEVCommutativeExpr { friend class ScalarEvolution; - SCEVMulExpr(const FoldingSetNodeID &ID, - const SmallVectorImpl<const SCEV *> &ops) - : SCEVCommutativeExpr(ID, scMulExpr, ops) { + SCEVMulExpr(const FoldingSetNodeIDRef ID, + const SCEV *const *O, size_t N) + : SCEVCommutativeExpr(ID, scMulExpr, O, N) { } public: @@ -339,7 +340,7 @@ namespace llvm { const SCEV *LHS; const SCEV *RHS; - SCEVUDivExpr(const FoldingSetNodeID &ID, const SCEV *lhs, const SCEV *rhs) + SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs) : SCEV(ID, scUDivExpr), LHS(lhs), RHS(rhs) {} public: @@ -389,10 +390,10 @@ namespace llvm { const Loop *L; - SCEVAddRecExpr(const FoldingSetNodeID &ID, - const SmallVectorImpl<const SCEV *> &ops, const Loop *l) - : SCEVNAryExpr(ID, scAddRecExpr, ops), L(l) { - for (size_t i = 0, e = Operands.size(); i != e; ++i) + SCEVAddRecExpr(const FoldingSetNodeIDRef ID, + const SCEV *const *O, size_t N, const Loop *l) + : SCEVNAryExpr(ID, scAddRecExpr, O, N), L(l) { + for (size_t i = 0, e = NumOperands; i != e; ++i) assert(Operands[i]->isLoopInvariant(l) && "Operands of AddRec must be loop-invariant!"); } @@ -471,9 +472,9 @@ namespace llvm { class SCEVSMaxExpr : public SCEVCommutativeExpr { friend class ScalarEvolution; - SCEVSMaxExpr(const FoldingSetNodeID &ID, - const SmallVectorImpl<const SCEV *> &ops) - : SCEVCommutativeExpr(ID, scSMaxExpr, ops) { + SCEVSMaxExpr(const FoldingSetNodeIDRef ID, + const SCEV *const *O, size_t N) + : SCEVCommutativeExpr(ID, scSMaxExpr, O, N) { // Max never overflows. setHasNoUnsignedWrap(true); setHasNoSignedWrap(true); @@ -496,9 +497,9 @@ namespace llvm { class SCEVUMaxExpr : public SCEVCommutativeExpr { friend class ScalarEvolution; - SCEVUMaxExpr(const FoldingSetNodeID &ID, - const SmallVectorImpl<const SCEV *> &ops) - : SCEVCommutativeExpr(ID, scUMaxExpr, ops) { + SCEVUMaxExpr(const FoldingSetNodeIDRef ID, + const SCEV *const *O, size_t N) + : SCEVCommutativeExpr(ID, scUMaxExpr, O, N) { // Max never overflows. setHasNoUnsignedWrap(true); setHasNoSignedWrap(true); @@ -523,7 +524,7 @@ namespace llvm { friend class ScalarEvolution; Value *V; - SCEVUnknown(const FoldingSetNodeID &ID, Value *v) : + SCEVUnknown(const FoldingSetNodeIDRef ID, Value *v) : SCEV(ID, scUnknown), V(v) {} public: diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h index b8d04bf..1b6ab2c 100644 --- a/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -83,9 +83,9 @@ public: /// getEntryAlignment - Return the alignment of each entry in the jump table. unsigned getEntryAlignment(const TargetData &TD) const; - /// getJumpTableIndex - Create a new jump table or return an existing one. + /// createJumpTableIndex - Create a new jump table. /// - unsigned getJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs); + unsigned createJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs); /// isEmpty - Return true if there are no jump tables. /// diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 80b7ca4..b1f1996 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -2516,6 +2516,11 @@ public: const Value *getCalledValue() const { return getOperand(0); } Value *getCalledValue() { return getOperand(0); } + /// setCalledFunction - Set the function called. + void setCalledFunction(Value* Fn) { + Op<0>() = Fn; + } + // get*Dest - Return the destination basic blocks... BasicBlock *getNormalDest() const { return cast<BasicBlock>(getOperand(1)); diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td index 50ee358..67abd95 100644 --- a/include/llvm/IntrinsicsX86.td +++ b/include/llvm/IntrinsicsX86.td @@ -892,7 +892,10 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse42_crc32_32 : GCCBuiltin<"__builtin_ia32_crc32si">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; - def int_x86_sse42_crc32_64 : GCCBuiltin<"__builtin_ia32_crc32di">, + def int_x86_sse42_crc64_8 : + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i8_ty], + [IntrNoMem]>; + def int_x86_sse42_crc64_64 : GCCBuiltin<"__builtin_ia32_crc32di">, Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; } diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 1d8051f..363c7d9 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -24,8 +24,10 @@ class raw_ostream; class MCAsmLayout; class MCAssembler; class MCContext; +class MCCodeEmitter; class MCExpr; class MCFragment; +class MCObjectWriter; class MCSection; class MCSectionData; class MCSymbol; @@ -35,7 +37,8 @@ class TargetAsmBackend; /// MCAsmFixup - Represent a fixed size region of bytes inside some fragment /// which needs to be rewritten. This region will either be rewritten by the /// assembler or cause a relocation entry to be generated. -struct MCAsmFixup { +class MCAsmFixup { +public: /// Offset - The offset inside the fragment which needs to be rewritten. uint64_t Offset; @@ -45,14 +48,9 @@ struct MCAsmFixup { /// Kind - The fixup kind. MCFixupKind Kind; - /// FixedValue - The value to replace the fix up by. - // - // FIXME: This should not be here. - uint64_t FixedValue; - public: MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind) - : Offset(_Offset), Value(&_Value), Kind(_Kind), FixedValue(0) {} + : Offset(_Offset), Value(&_Value), Kind(_Kind) {} }; class MCFragment : public ilist_node<MCFragment> { @@ -590,6 +588,8 @@ public: typedef SymbolDataListType::const_iterator const_symbol_iterator; typedef SymbolDataListType::iterator symbol_iterator; + typedef std::vector<IndirectSymbolData>::const_iterator + const_indirect_symbol_iterator; typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; private: @@ -600,6 +600,8 @@ private: TargetAsmBackend &Backend; + MCCodeEmitter &Emitter; + raw_ostream &OS; iplist<MCSectionData> Sections; @@ -621,21 +623,6 @@ private: unsigned SubsectionsViaSymbols : 1; private: - /// Check whether a fixup can be satisfied, or whether it needs to be relaxed - /// (increased in size, in order to hold its value correctly). - bool FixupNeedsRelaxation(MCAsmFixup &Fixup, MCDataFragment *DF); - - /// LayoutSection - Assign offsets and sizes to the fragments in the section - /// \arg SD, and update the section size. The section file offset should - /// already have been computed. - void LayoutSection(MCSectionData &SD); - - /// LayoutOnce - Perform one layout iteration and return true if any offsets - /// were adjusted. - bool LayoutOnce(); - - // FIXME: Make protected once we factor out object writer classes. -public: /// Evaluate a fixup to a relocatable expression and the value which should be /// placed into the fixup. /// @@ -653,6 +640,44 @@ public: MCAsmFixup &Fixup, MCDataFragment *DF, MCValue &Target, uint64_t &Value) const; + /// Check whether a fixup can be satisfied, or whether it needs to be relaxed + /// (increased in size, in order to hold its value correctly). + bool FixupNeedsRelaxation(MCAsmFixup &Fixup, MCDataFragment *DF); + + /// LayoutSection - Assign offsets and sizes to the fragments in the section + /// \arg SD, and update the section size. The section file offset should + /// already have been computed. + void LayoutSection(MCSectionData &SD); + + /// LayoutOnce - Perform one layout iteration and return true if any offsets + /// were adjusted. + bool LayoutOnce(); + +public: + /// Find the symbol which defines the atom containing given address, inside + /// the given section, or null if there is no such symbol. + // + // FIXME: Eliminate this, it is very slow. + const MCSymbolData *getAtomForAddress(const MCSectionData *Section, + uint64_t Address) const; + + /// Find the symbol which defines the atom containing the given symbol, or + /// null if there is no such symbol. + // + // FIXME: Eliminate this, it is very slow. + const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; + + /// Check whether a particular symbol is visible to the linker and is required + /// in the symbol table, or whether it can be discarded by the assembler. This + /// also effects whether the assembler treats the label as potentially + /// defining a separate atom. + bool isSymbolLinkerVisible(const MCSymbolData *SD) const; + + /// Emit the section contents using the given object writer. + // + // FIXME: Should MCAssembler always have a reference to the object writer? + void WriteSectionData(const MCSectionData *Section, MCObjectWriter *OW) const; + public: /// Construct a new assembler instance. /// @@ -662,13 +687,16 @@ public: // concrete and require clients to pass in a target like object. The other // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. - MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, raw_ostream &OS); + MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, + MCCodeEmitter &_Emitter, raw_ostream &OS); ~MCAssembler(); MCContext &getContext() const { return Context; } TargetAsmBackend &getBackend() const { return Backend; } + MCCodeEmitter &getEmitter() const { return Emitter; } + /// Finish - Do final processing and write the object to the output stream. void Finish(); @@ -723,10 +751,16 @@ public: indirect_symbol_iterator indirect_symbol_begin() { return IndirectSymbols.begin(); } + const_indirect_symbol_iterator indirect_symbol_begin() const { + return IndirectSymbols.begin(); + } indirect_symbol_iterator indirect_symbol_end() { return IndirectSymbols.end(); } + const_indirect_symbol_iterator indirect_symbol_end() const { + return IndirectSymbols.end(); + } size_t indirect_symbol_size() const { return IndirectSymbols.size(); } diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index fe1aff4..010a2e5 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -22,6 +22,12 @@ template<typename T> class SmallVectorImpl; /// MCFixupKindInfo - Target independent information on a fixup kind. struct MCFixupKindInfo { + enum FixupKindFlags { + /// Is this fixup kind PCrelative. This is used by the assembler backend to + /// evaluate fixup values in a target independent manner when possible. + FKF_IsPCRel = (1 << 0) + }; + /// A target specific name for the fixup kind. The names will be unique for /// distinct kinds on any given target. const char *Name; @@ -36,6 +42,9 @@ struct MCFixupKindInfo { /// The number of bits written by this fixup. The bits are assumed to be /// contiguous. unsigned TargetSize; + + /// Flags describing additional information on this fixup kind. + unsigned Flags; }; /// MCCodeEmitter - Generic instruction encoding interface. diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 85114e3..c5814b3 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -73,9 +73,10 @@ namespace llvm { /// one if it does. /// /// @param Name - The symbol name, for debugging purposes only, temporary - /// symbols do not surive assembly. If non-empty the name must be unique - /// across all symbols. - MCSymbol *GetOrCreateTemporarySymbol(StringRef Name = ""); + /// symbols do not surive assembly. + MCSymbol *GetOrCreateTemporarySymbol(StringRef Name) { + return GetOrCreateSymbol(Name, true); + } MCSymbol *GetOrCreateTemporarySymbol(const Twine &Name); /// LookupSymbol - Get the symbol for \p Name, or null. diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h new file mode 100644 index 0000000..d4fab0e --- /dev/null +++ b/include/llvm/MC/MCObjectWriter.h @@ -0,0 +1,162 @@ +//===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCOBJECTWRITER_H +#define LLVM_MC_MCOBJECTWRITER_H + +#include "llvm/Support/raw_ostream.h" +#include "llvm/System/DataTypes.h" +#include <cassert> + +namespace llvm { +class MCAsmFixup; +class MCAssembler; +class MCDataFragment; +class MCValue; +class raw_ostream; + +/// MCObjectWriter - Defines the object file and target independent interfaces +/// used by the assembler backend to write native file format object files. +/// +/// The object writer contains a few callbacks used by the assembler to allow +/// the object writer to modify the assembler data structures at appropriate +/// points. Once assembly is complete, the object writer is given the +/// MCAssembler instance, which contains all the symbol and section data which +/// should be emitted as part of WriteObject(). +/// +/// The object writer also contains a number of helper methods for writing +/// binary data to the output stream. +class MCObjectWriter { + MCObjectWriter(const MCObjectWriter &); // DO NOT IMPLEMENT + void operator=(const MCObjectWriter &); // DO NOT IMPLEMENT + +protected: + raw_ostream &OS; + + unsigned IsLittleEndian : 1; + +protected: // Can only create subclasses. + MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian) + : OS(_OS), IsLittleEndian(_IsLittleEndian) {} + +public: + virtual ~MCObjectWriter(); + + bool isLittleEndian() { return IsLittleEndian; } + + raw_ostream &getStream() { return OS; } + + /// @name High-Level API + /// @{ + + /// Perform any late binding of symbols (for example, to assign symbol indices + /// for use when generating relocations). + /// + /// This routine is called by the assembler after layout and relaxation is + /// complete. + virtual void ExecutePostLayoutBinding(MCAssembler &Asm) = 0; + + /// Record a relocation entry. + /// + /// This routine is called by the assembler after layout and relaxation, and + /// post layout binding. The implementation is responsible for storing + /// information about the relocation so that it can be emitted during + /// WriteObject(). + virtual void RecordRelocation(const MCAssembler &Asm, + const MCDataFragment &Fragment, + const MCAsmFixup &Fixup, MCValue Target, + uint64_t &FixedValue) = 0; + + /// Write the object file. + /// + /// This routine is called by the assembler after layout and relaxation is + /// complete, fixups have been evaluate and applied, and relocations + /// generated. + virtual void WriteObject(const MCAssembler &Asm) = 0; + + /// @} + /// @name Binary Output + /// @{ + + void Write8(uint8_t Value) { + OS << char(Value); + } + + void WriteLE16(uint16_t Value) { + Write8(uint8_t(Value >> 0)); + Write8(uint8_t(Value >> 8)); + } + + void WriteLE32(uint32_t Value) { + WriteLE16(uint16_t(Value >> 0)); + WriteLE16(uint16_t(Value >> 16)); + } + + void WriteLE64(uint64_t Value) { + WriteLE32(uint32_t(Value >> 0)); + WriteLE32(uint32_t(Value >> 32)); + } + + void WriteBE16(uint16_t Value) { + Write8(uint8_t(Value >> 8)); + Write8(uint8_t(Value >> 0)); + } + + void WriteBE32(uint32_t Value) { + WriteBE16(uint16_t(Value >> 16)); + WriteBE16(uint16_t(Value >> 0)); + } + + void WriteBE64(uint64_t Value) { + WriteBE32(uint32_t(Value >> 32)); + WriteBE32(uint32_t(Value >> 0)); + } + + void Write16(uint16_t Value) { + if (IsLittleEndian) + WriteLE16(Value); + else + WriteBE16(Value); + } + + void Write32(uint32_t Value) { + if (IsLittleEndian) + WriteLE32(Value); + else + WriteBE32(Value); + } + + void Write64(uint64_t Value) { + if (IsLittleEndian) + WriteLE64(Value); + else + WriteBE64(Value); + } + + void WriteZeros(unsigned N) { + const char Zeros[16] = { 0 }; + + for (unsigned i = 0, e = N / 16; i != e; ++i) + OS << StringRef(Zeros, 16); + + OS << StringRef(Zeros, N % 16); + } + + void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { + OS << Str; + if (ZeroFillSize) + WriteZeros(ZeroFillSize - Str.size()); + } + + /// @} +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 47befca..4b088a5 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -291,7 +291,8 @@ class TargetAsmBackend; /// assembler. /// /// \param InstPrint - If given, the instruction printer to use. If not given - /// the MCInst representation will be printed. + /// the MCInst representation will be printed. This method takes ownership of + /// InstPrint. /// /// \param CE - If given, a code emitter to use to show the instruction /// encoding inline with the assembly. diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index e41eb2a..fb96506 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -28,8 +28,7 @@ namespace llvm { /// /// If the symbol is defined/emitted into the current translation unit, the /// Section member is set to indicate what section it lives in. Otherwise, if - /// it is a reference to an external entity, it has a null section. - /// + /// it is a reference to an external entity, it has a null section. class MCSymbol { // Special sentinal value for the absolute pseudo section. // @@ -52,7 +51,7 @@ namespace llvm { /// typically does not survive in the .o file's symbol table. Usually /// "Lfoo" or ".foo". unsigned IsTemporary : 1; - + private: // MCContext creates and uniques these. friend class MCContext; MCSymbol(StringRef name, bool isTemporary) @@ -83,6 +82,12 @@ namespace llvm { return Section != 0; } + /// isInSection - Check if this symbol is defined in some section (i.e., it + /// is defined but not absolute). + bool isInSection() const { + return isDefined() && !isAbsolute(); + } + /// isUndefined - Check if this symbol undefined (i.e., implicitly defined). bool isUndefined() const { return !isDefined(); @@ -96,7 +101,7 @@ namespace llvm { /// getSection - Get the section associated with a defined, non-absolute /// symbol. const MCSection &getSection() const { - assert(!isUndefined() && !isAbsolute() && "Invalid accessor!"); + assert(isInSection() && "Invalid accessor!"); return *Section; } diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index 8aa73f3..11b6c2a 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -19,8 +19,9 @@ #include <cassert> namespace llvm { -class MCSymbol; class MCAsmInfo; +class MCSymbol; +class MCSymbolRefExpr; class raw_ostream; /// MCValue - This represents an "assembler immediate". In its most general @@ -34,13 +35,13 @@ class raw_ostream; /// Note that this class must remain a simple POD value class, because we need /// it to live in unions etc. class MCValue { - const MCSymbol *SymA, *SymB; + const MCSymbolRefExpr *SymA, *SymB; int64_t Cst; public: int64_t getConstant() const { return Cst; } - const MCSymbol *getSymA() const { return SymA; } - const MCSymbol *getSymB() const { return SymB; } + const MCSymbolRefExpr *getSymA() const { return SymA; } + const MCSymbolRefExpr *getSymB() const { return SymB; } /// isAbsolute - Is this an absolute (as opposed to relocatable) value. bool isAbsolute() const { return !SymA && !SymB; } @@ -57,11 +58,11 @@ public: /// print - Print the value to the stream \arg OS. void print(raw_ostream &OS, const MCAsmInfo *MAI) const; - + /// dump - Print the value to stderr. void dump() const; - static MCValue get(const MCSymbol *SymA, const MCSymbol *SymB = 0, + static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=0, int64_t Val = 0) { MCValue R; assert((!SymB || SymA) && "Invalid relocatable MCValue!"); @@ -70,7 +71,7 @@ public: R.SymB = SymB; return R; } - + static MCValue get(int64_t Val) { MCValue R; R.Cst = Val; @@ -78,7 +79,7 @@ public: R.SymB = 0; return R; } - + }; } // end namespace llvm diff --git a/include/llvm/MC/MachObjectWriter.h b/include/llvm/MC/MachObjectWriter.h new file mode 100644 index 0000000..3e3305f --- /dev/null +++ b/include/llvm/MC/MachObjectWriter.h @@ -0,0 +1,43 @@ +//===-- llvm/MC/MachObjectWriter.h - Mach-O File Writer ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MACHOBJECTWRITER_H +#define LLVM_MC_MACHOBJECTWRITER_H + +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/raw_ostream.h" +#include <cassert> + +namespace llvm { +class MCAsmFixup; +class MCAssembler; +class MCDataFragment; +class MCValue; +class raw_ostream; + +class MachObjectWriter : public MCObjectWriter { + void *Impl; + +public: + MachObjectWriter(raw_ostream &OS, bool Is64Bit, bool IsLittleEndian = true); + virtual ~MachObjectWriter(); + + virtual void ExecutePostLayoutBinding(MCAssembler &Asm); + + virtual void RecordRelocation(const MCAssembler &Asm, + const MCDataFragment &Fragment, + const MCAsmFixup &Fixup, MCValue Target, + uint64_t &FixedValue); + + virtual void WriteObject(const MCAssembler &Asm); +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index b0ed33d..b1f59dc 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -15,9 +15,12 @@ #define LLVM_SUPPORT_ALLOCATOR_H #include "llvm/Support/AlignOf.h" +#include "llvm/Support/MathExtras.h" #include "llvm/System/DataTypes.h" +#include <algorithm> #include <cassert> #include <cstdlib> +#include <cstddef> namespace llvm { @@ -175,4 +178,22 @@ public: } // end namespace llvm +inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) { + struct S { + char c; +#ifdef __GNUC__ + char x __attribute__((aligned)); +#else + union { + double D; + long double LD; + long long L; + void *P; + } x; +#endif + }; + return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size), + offsetof(S, x))); +} + #endif // LLVM_SUPPORT_ALLOCATOR_H diff --git a/include/llvm/Support/RecyclingAllocator.h b/include/llvm/Support/RecyclingAllocator.h index 609193f..49f7753 100644 --- a/include/llvm/Support/RecyclingAllocator.h +++ b/include/llvm/Support/RecyclingAllocator.h @@ -56,4 +56,11 @@ public: } +template<class AllocatorType, class T, size_t Size, size_t Align> +inline void *operator new(size_t, + llvm::RecyclingAllocator<AllocatorType, + T, Size, Align> &Allocator) { + return Allocator.Allocate(); +} + #endif diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 0cffffb..0a7f549 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -389,66 +389,66 @@ class InstrInfo { // Standard Pseudo Instructions. let isCodeGenOnly = 1 in { def PHI : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops variable_ops); + let OutOperandList = (outs); + let InOperandList = (ins variable_ops); let AsmString = "PHINODE"; let Namespace = "TargetOpcode"; } def INLINEASM : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops variable_ops); + let OutOperandList = (outs); + let InOperandList = (ins variable_ops); let AsmString = ""; let Namespace = "TargetOpcode"; } def DBG_LABEL : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops i32imm:$id); + let OutOperandList = (outs); + let InOperandList = (ins i32imm:$id); let AsmString = ""; let Namespace = "TargetOpcode"; let hasCtrlDep = 1; let isNotDuplicable = 1; } def EH_LABEL : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops i32imm:$id); + let OutOperandList = (outs); + let InOperandList = (ins i32imm:$id); let AsmString = ""; let Namespace = "TargetOpcode"; let hasCtrlDep = 1; let isNotDuplicable = 1; } def GC_LABEL : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops i32imm:$id); + let OutOperandList = (outs); + let InOperandList = (ins i32imm:$id); let AsmString = ""; let Namespace = "TargetOpcode"; let hasCtrlDep = 1; let isNotDuplicable = 1; } def KILL : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops variable_ops); + let OutOperandList = (outs); + let InOperandList = (ins variable_ops); let AsmString = ""; let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; } def EXTRACT_SUBREG : Instruction { - let OutOperandList = (ops unknown:$dst); - let InOperandList = (ops unknown:$supersrc, i32imm:$subidx); + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$supersrc, i32imm:$subidx); let AsmString = ""; let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; } def INSERT_SUBREG : Instruction { - let OutOperandList = (ops unknown:$dst); - let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx); + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$supersrc, unknown:$subsrc, i32imm:$subidx); let AsmString = ""; let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; let Constraints = "$supersrc = $dst"; } def IMPLICIT_DEF : Instruction { - let OutOperandList = (ops unknown:$dst); - let InOperandList = (ops); + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins); let AsmString = ""; let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; @@ -456,23 +456,23 @@ def IMPLICIT_DEF : Instruction { let isAsCheapAsAMove = 1; } def SUBREG_TO_REG : Instruction { - let OutOperandList = (ops unknown:$dst); - let InOperandList = (ops unknown:$implsrc, unknown:$subsrc, i32imm:$subidx); + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$implsrc, unknown:$subsrc, i32imm:$subidx); let AsmString = ""; let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; } def COPY_TO_REGCLASS : Instruction { - let OutOperandList = (ops unknown:$dst); - let InOperandList = (ops unknown:$src, i32imm:$regclass); + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src, i32imm:$regclass); let AsmString = ""; let Namespace = "TargetOpcode"; let neverHasSideEffects = 1; let isAsCheapAsAMove = 1; } def DBG_VALUE : Instruction { - let OutOperandList = (ops); - let InOperandList = (ops variable_ops); + let OutOperandList = (outs); + let InOperandList = (ins variable_ops); let AsmString = "DBG_VALUE"; let Namespace = "TargetOpcode"; let isAsCheapAsAMove = 1; @@ -491,6 +491,11 @@ class AsmParser { // class. Generated AsmParser classes are always prefixed with the target // name. string AsmParserClassName = "AsmParser"; + + // AsmParserInstCleanup - If non-empty, this is the name of a custom function on the + // AsmParser class to call on every matched instruction. This can be used to + // perform target specific instruction post-processing. + string AsmParserInstCleanup = ""; // Variant - AsmParsers can be of multiple different variants. Variants are // used to support targets that need to parser multiple formats for the diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/Target/TargetAsmBackend.h index 35a995f..bb501cc 100644 --- a/include/llvm/Target/TargetAsmBackend.h +++ b/include/llvm/Target/TargetAsmBackend.h @@ -10,9 +10,15 @@ #ifndef LLVM_TARGET_TARGETASMBACKEND_H #define LLVM_TARGET_TARGETASMBACKEND_H +#include "llvm/System/DataTypes.h" + namespace llvm { +class MCAsmFixup; +class MCDataFragment; +class MCObjectWriter; class MCSection; class Target; +class raw_ostream; /// TargetAsmBackend - Generic interface to target specific assembler backends. class TargetAsmBackend { @@ -24,11 +30,19 @@ protected: // Can only create subclasses. /// TheTarget - The Target that this machine was created for. const Target &TheTarget; + unsigned HasAbsolutizedSet : 1; + unsigned HasReliableSymbolDifference : 1; + unsigned HasScatteredSymbols : 1; + public: virtual ~TargetAsmBackend(); const Target &getTarget() const { return TheTarget; } + /// createObjectWriter - Create a new MCObjectWriter instance for use by the + /// assembler backend to emit the final object file. + virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0; + /// hasAbsolutizedSet - Check whether this target "absolutizes" /// assignments. That is, given code like: /// a: @@ -40,7 +54,21 @@ public: /// value of L0 - L1. This distinction is only relevant for platforms that /// support scattered symbols, since in the absence of scattered symbols (a - /// b) cannot change after assembly. - virtual bool hasAbsolutizedSet() const { return false; } + bool hasAbsolutizedSet() const { return HasAbsolutizedSet; } + + /// hasReliableSymbolDifference - Check whether this target implements + /// accurate relocations for differences between symbols. If not, differences + /// between symbols will always be relocatable expressions and any references + /// to temporary symbols will be assumed to be in the same atom, unless they + /// reside in a different section. + /// + /// This should always be true (since it results in fewer relocations with no + /// loss of functionality), but is currently supported as a way to maintain + /// exact object compatibility with Darwin 'as' (on non-x86_64). It should + /// eventually should be eliminated. See also \see hasAbsolutizedSet. + bool hasReliableSymbolDifference() const { + return HasReliableSymbolDifference; + } /// hasScatteredSymbols - Check whether this target supports scattered /// symbols. If so, the assembler should assume that atoms can be scattered by @@ -50,13 +78,23 @@ public: /// /// Note that the assembler currently does not reason about atoms, instead it /// assumes all temporary symbols reside in the "current atom". - virtual bool hasScatteredSymbols() const { return false; } + bool hasScatteredSymbols() const { return HasScatteredSymbols; } /// doesSectionRequireSymbols - Check whether the given section requires that /// all symbols (even temporaries) have symbol table entries. virtual bool doesSectionRequireSymbols(const MCSection &Section) const { return false; } + + /// isVirtualSection - Check whether the given section is "virtual", that is + /// has no actual object file contents. + virtual bool isVirtualSection(const MCSection &Section) const = 0; + + /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided + /// data fragment, at the offset specified by the fixup and following the + /// fixup kind as appropriate. + virtual void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &Fragment, + uint64_t Value) const = 0; }; } // End llvm namespace diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index b19c20a..da0f686 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -307,7 +307,7 @@ public: /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If /// this is the case, it returns true and store the intrinsic /// information into the IntrinsicInfo that was passed to the function. - typedef struct IntrinsicInfo { + struct IntrinsicInfo { unsigned opc; // target opcode EVT memVT; // memory VT const Value* ptrVal; // value representing memory location @@ -316,9 +316,9 @@ public: bool vol; // is volatile? bool readMem; // reads memory? bool writeMem; // writes memory? - } IntrinisicInfo; + }; - virtual bool getTgtMemIntrinsic(IntrinsicInfo& Info, + virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info, CallInst &I, unsigned Intrinsic) { return false; } diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index b63c2bf..a01a67f 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -144,11 +144,6 @@ namespace llvm { /// wth earlier copy coalescing. extern bool StrongPHIElim; - /// DisableScheduling - This flag disables instruction scheduling. In - /// particular, it assigns an ordering to the SDNodes, which the scheduler - /// uses instead of its normal heuristics to perform scheduling. - extern bool DisableScheduling; - } // End llvm namespace #endif diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index 4373863..6b6dad8 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -55,7 +55,7 @@ namespace llvm { typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); - typedef const MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T, + typedef MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T, StringRef TT); typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T, const std::string &TT, @@ -68,7 +68,7 @@ namespace llvm { typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T, const MCAsmInfo &MAI); typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P); - typedef const MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); + typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, @@ -184,7 +184,7 @@ namespace llvm { /// feature set; it should always be provided. Generally this should be /// either the target triple from the module, or the target triple of the /// host if that does not exist. - const MCAsmInfo *createAsmInfo(StringRef Triple) const { + MCAsmInfo *createAsmInfo(StringRef Triple) const { if (!AsmInfoCtorFn) return 0; return AsmInfoCtorFn(*this, Triple); @@ -241,7 +241,7 @@ namespace llvm { return AsmPrinterCtorFn(OS, TM, Streamer); } - const MCDisassembler *createMCDisassembler() const { + MCDisassembler *createMCDisassembler() const { if (!MCDisassemblerCtorFn) return 0; return MCDisassemblerCtorFn(*this); @@ -529,7 +529,7 @@ namespace llvm { TargetRegistry::RegisterAsmInfo(T, &Allocator); } private: - static const MCAsmInfo *Allocator(const Target &T, StringRef TT) { + static MCAsmInfo *Allocator(const Target &T, StringRef TT) { return new MCAsmInfoImpl(T, TT); } diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index c718c86..e56d886 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -219,6 +219,7 @@ def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand +def SDNPVariadic : SDNodeProperty; // Node has variable arguments. //===----------------------------------------------------------------------===// // Selection DAG Node definitions. |