diff options
author | Derek Schuff <dschuff@chromium.org> | 2013-01-31 10:07:41 -0800 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2013-01-31 10:07:41 -0800 |
commit | 3d5de9e56f3e5af59772bdf2cbedb0903d938bb8 (patch) | |
tree | 300b7a72c61b009f0122ec1d8a155672c74459fd | |
parent | 659ebb8c18832df528effd5c970bfde7662ea368 (diff) | |
parent | 9ccb76998f741a7d3f0f217392a783dfb99c6e87 (diff) |
Cherry-pick r174067
54 files changed, 3063 insertions, 1783 deletions
diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT index c02e71c6d5..de944363a0 100644 --- a/CODE_OWNERS.TXT +++ b/CODE_OWNERS.TXT @@ -109,6 +109,10 @@ N: Duncan Sands E: baldrick@free.fr D: DragonEgg +N: Michael Spencer +E: bigcheesegs@gmail.com +D: Windows parts of Support, Object, ar, nm, objdump, ranlib, size + N: Tom Stellard E: thomas.stellard@amd.com E: mesa-dev@lists.freedesktop.org diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 2a0fca571b..c46cb0d44a 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -1274,8 +1274,23 @@ then then CXX_FLAG_CHECK(NO_UNINITIALIZED, [-Wno-uninitialized]) else - dnl AC_SUBST doesn't work with empty strings. - NO_UNINITIALIZED= + dnl Some versions of gcc accept unsupported -W flags if there is + dnl no warning but stop with an error when a warning is + dnl encountered. If this gcc is earlier than 4.7, just use + dnl -Wno-uninitialized. + gxx_version=`$CXX -dumpversion` + gxx_version_major=`echo $gxx_version | cut -d'.' -f1` + gxx_version_minor=`echo $gxx_version | cut -d'.' -f2` + gxx_version_patch=`echo $gxx_version | cut -d'.' -f3` + + if test "$gxx_version_major" -ge "4" \ + && test "$gxx_version_minor" -ge "7"; then + dnl AC_SUBST doesn't work with empty strings. + NO_UNINITIALIZED= + else + NO_MAYBE_UNINITIALIZED= + CXX_FLAG_CHECK(NO_UNINITIALIZED, [-Wno-uninitialized]) + fi fi else NO_UNINITIALIZED= @@ -12262,7 +12262,19 @@ then NO_UNINITIALIZED=`$CXX -Werror -Wno-uninitialized -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-uninitialized` else - NO_UNINITIALIZED= + gxx_version=`$CXX -dumpversion` + gxx_version_major=`echo $gxx_version | cut -d'.' -f1` + gxx_version_minor=`echo $gxx_version | cut -d'.' -f2` + gxx_version_patch=`echo $gxx_version | cut -d'.' -f3` + + if test "$gxx_version_major" -ge "4" \ + && test "$gxx_version_minor" -ge "7"; then + NO_UNINITIALIZED= + else + NO_MAYBE_UNINITIALIZED= + NO_UNINITIALIZED=`$CXX -Werror -Wno-uninitialized -fsyntax-only -xc /dev/null 2>/dev/null && echo -Wno-uninitialized` + + fi fi else NO_UNINITIALIZED= diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 3c49ed0a87..7d9fe41744 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -2462,14 +2462,16 @@ Each triplet has the following form: (or more) metadata with the same ID. The supported behaviors are described below. - The second element is a metadata string that is a unique ID for the - metadata. How each ID is interpreted is documented below. + metadata. Each module may only have one flag entry for each unique ID (not + including entries with the **Require** behavior). - The third element is the value of the flag. When two (or more) modules are merged together, the resulting -``llvm.module.flags`` metadata is the union of the modules' -``llvm.module.flags`` metadata. The only exception being a flag with the -*Override* behavior, which may override another flag's value (see -below). +``llvm.module.flags`` metadata is the union of the modules' flags. That is, for +each unique metadata ID string, there will be exactly one entry in the merged +modules ``llvm.module.flags`` metadata table, and the value for that entry will +be determined by the merge behavior flag, as described below. The only exception +is that entries with the *Require* behavior are always preserved. The following behaviors are supported: @@ -2482,25 +2484,33 @@ The following behaviors are supported: * - 1 - **Error** - Emits an error if two values disagree. It is an error to have an - ID with both an Error and a Warning behavior. + Emits an error if two values disagree, otherwise the resulting value + is that of the operands. * - 2 - **Warning** - Emits a warning if two values disagree. + Emits a warning if two values disagree. The result value will be the + operand for the flag from the first module being linked. * - 3 - **Require** - Emits an error when the specified value is not present or doesn't - have the specified value. It is an error for two (or more) - ``llvm.module.flags`` with the same ID to have the Require behavior - but different values. There may be multiple Require flags per ID. + Adds a requirement that another module flag be present and have a + specified value after linking is performed. The value must be a + metadata pair, where the first element of the pair is the ID of the + module flag to be restricted, and the second element of the pair is + the value the module flag should be restricted to. This behavior can + be used to restrict the allowable results (via triggering of an + error) of linking IDs with the **Override** behavior. * - 4 - **Override** - Uses the specified value if the two values disagree. It is an - error for two (or more) ``llvm.module.flags`` with the same ID - to have the Override behavior but different values. + Uses the specified value, regardless of the behavior or value of the + other module. If both modules specify **Override**, but the values + differ, an error will be emitted. + +It is an error for a particular unique flag ID to have multiple behaviors, +except in the case of **Require** (which adds restrictions on another metadata +value) or **Override**. An example of module flags: @@ -2522,7 +2532,7 @@ An example of module flags: - Metadata ``!1`` has the ID ``!"bar"`` and the value '37'. The behavior if two or more ``!"bar"`` flags are seen is to use the value - '37' if their values are not equal. + '37'. - Metadata ``!2`` has the ID ``!"qux"`` and the value '42'. The behavior if two or more ``!"qux"`` flags are seen is to emit a @@ -2534,10 +2544,9 @@ An example of module flags: metadata !{ metadata !"foo", i32 1 } - The behavior is to emit an error if the ``llvm.module.flags`` does - not contain a flag with the ID ``!"foo"`` that has the value '1'. If - two or more ``!"qux"`` flags exist, then they must have the same - value or an error will be issued. + The behavior is to emit an error if the ``llvm.module.flags`` does not + contain a flag with the ID ``!"foo"`` that has the value '1' after linking is + performed. Objective-C Garbage Collection Module Flags Metadata ---------------------------------------------------- diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index 0d68d11a12..7e40a075ed 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -237,6 +237,10 @@ public: explicit StringMap(AllocatorTy A) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {} + StringMap(unsigned InitialSize, AllocatorTy A) + : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))), + Allocator(A) {} + StringMap(const StringMap &RHS) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) { assert(RHS.empty() && diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 1708cccf33..00779fc329 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -40,8 +40,10 @@ namespace llvm { // New instructions receive a name to identifies them with the current pass. const char* IVName; - std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > + // InsertedExpressions caches Values for reuse, so must track RAUW. + std::map<std::pair<const SCEV *, Instruction *>, TrackingVH<Value> > InsertedExpressions; + // InsertedValues only flags inserted instructions so needs no RAUW. std::set<AssertingVH<Value> > InsertedValues; std::set<AssertingVH<Value> > InsertedPostIncValues; diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 84ae516552..324a646bc1 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -953,7 +953,7 @@ public: "Both operands to ICmp instruction are not of the same type!"); // Check that the operands are the right type assert((getOperand(0)->getType()->isIntOrIntVectorTy() || - getOperand(0)->getType()->isPointerTy()) && + getOperand(0)->getType()->getScalarType()->isPointerTy()) && "Invalid operand types for ICmp instruction"); } diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 57aa08a2d0..8269f08c44 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -47,6 +47,7 @@ public: enum FragmentType { FT_Align, FT_Data, + FT_CompactEncodedInst, FT_Fill, FT_Relaxable, FT_Org, @@ -105,6 +106,7 @@ public: /// \brief Should this fragment be placed at the end of an aligned bundle? virtual bool alignToBundleEnd() const { return false; } + virtual void setAlignToBundleEnd(bool V) { } /// \brief Get the padding size that must be inserted before this fragment. /// Used for bundling. By default, no padding is inserted. @@ -120,9 +122,16 @@ public: virtual void setBundlePadding(uint8_t N) { } + virtual bool hasFixups() const { + return false; + } + void dump(); }; +/// Interface implemented by fragments that contain encoded instructions and/or +/// data. +/// class MCEncodedFragment : public MCFragment { virtual void anchor(); @@ -134,20 +143,9 @@ public: } virtual ~MCEncodedFragment(); - typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; - typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; - virtual SmallVectorImpl<char> &getContents() = 0; virtual const SmallVectorImpl<char> &getContents() const = 0; - virtual SmallVectorImpl<MCFixup> &getFixups() = 0; - virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; - - virtual fixup_iterator fixup_begin() = 0; - virtual const_fixup_iterator fixup_begin() const = 0; - virtual fixup_iterator fixup_end() = 0; - virtual const_fixup_iterator fixup_end() const = 0; - virtual uint8_t getBundlePadding() const { return BundlePadding; } @@ -158,13 +156,55 @@ public: static bool classof(const MCFragment *F) { MCFragment::FragmentType Kind = F->getKind(); - return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; + switch (Kind) { + default: + return false; + case MCFragment::FT_Relaxable: + case MCFragment::FT_CompactEncodedInst: + case MCFragment::FT_Data: + return true; + } + } +}; + +/// Interface implemented by fragments that contain encoded instructions and/or +/// data and also have fixups registered. +/// +class MCEncodedFragmentWithFixups : public MCEncodedFragment { + virtual void anchor(); + +public: + MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, + MCSectionData *SD = 0) + : MCEncodedFragment(FType, SD) + { + } + + virtual ~MCEncodedFragmentWithFixups(); + + virtual bool hasFixups() const { + return true; + } + + typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; + typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; + + virtual SmallVectorImpl<MCFixup> &getFixups() = 0; + virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; + + virtual fixup_iterator fixup_begin() = 0; + virtual const_fixup_iterator fixup_begin() const = 0; + virtual fixup_iterator fixup_end() = 0; + virtual const_fixup_iterator fixup_end() const = 0; + + static bool classof(const MCFragment *F) { + return isa<MCEncodedFragment>(F) && F->hasFixups(); } }; /// Fragment for data and encoded instructions. /// -class MCDataFragment : public MCEncodedFragment { +class MCDataFragment : public MCEncodedFragmentWithFixups { virtual void anchor(); /// \brief Does this fragment contain encoded instructions anywhere in it? @@ -179,7 +219,7 @@ class MCDataFragment : public MCEncodedFragment { SmallVector<MCFixup, 4> Fixups; public: MCDataFragment(MCSectionData *SD = 0) - : MCEncodedFragment(FT_Data, SD), + : MCEncodedFragmentWithFixups(FT_Data, SD), HasInstructions(false), AlignToBundleEnd(false) { } @@ -212,10 +252,43 @@ public: } }; +/// This is a compact (memory-size-wise) fragment for holding an encoded +/// instruction (non-relaxable) that has no fixups registered. When applicable, +/// it can be used instead of MCDataFragment and lead to lower memory +/// consumption. +/// +class MCCompactEncodedInstFragment : public MCEncodedFragment { + virtual void anchor(); + + /// \brief Should this fragment be aligned to the end of a bundle? + bool AlignToBundleEnd; + + SmallVector<char, 4> Contents; +public: + MCCompactEncodedInstFragment(MCSectionData *SD = 0) + : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false) + { + } + + virtual bool hasInstructions() const { + return true; + } + + virtual SmallVectorImpl<char> &getContents() { return Contents; } + virtual const SmallVectorImpl<char> &getContents() const { return Contents; } + + virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } + virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_CompactEncodedInst; + } +}; + /// A relaxable fragment holds on to its MCInst, since it may need to be /// relaxed during the assembler layout and relaxation stage. /// -class MCRelaxableFragment : public MCEncodedFragment { +class MCRelaxableFragment : public MCEncodedFragmentWithFixups { virtual void anchor(); /// Inst - The instruction this is a fragment for. @@ -229,7 +302,7 @@ class MCRelaxableFragment : public MCEncodedFragment { public: MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0) - : MCEncodedFragment(FT_Relaxable, SD), Inst(_Inst) { + : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) { } virtual SmallVectorImpl<char> &getContents() { return Contents; } diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index eeeacbc2fc..a256f85a7c 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -11,6 +11,7 @@ #define LLVM_MC_MCPARSER_MCASMPARSER_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCParser/AsmLexer.h" #include "llvm/Support/DataTypes.h" #include <vector> @@ -43,8 +44,24 @@ public: }; +/// \brief Helper types for tracking macro definitions. typedef std::vector<AsmToken> MCAsmMacroArgument; +typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments; +typedef std::pair<StringRef, MCAsmMacroArgument> MCAsmMacroParameter; +typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters; +struct MCAsmMacro { + StringRef Name; + StringRef Body; + MCAsmMacroParameters Parameters; + +public: + MCAsmMacro(StringRef N, StringRef B, const MCAsmMacroParameters &P) : + Name(N), Body(B), Parameters(P) {} + + MCAsmMacro(const MCAsmMacro& Other) + : Name(Other.Name), Body(Other.Body), Parameters(Other.Parameters) {} +}; /// MCAsmParser - Generic assembler parser interface, for use by target specific /// assembly parsers. @@ -141,10 +158,35 @@ public: /// recovery. virtual void EatToEndOfStatement() = 0; - /// Control a flag in the parser that enables or disables macros. + /// \brief Are macros enabled in the parser? virtual bool MacrosEnabled() = 0; + + /// \brief Control a flag in the parser that enables or disables macros. virtual void SetMacrosEnabled(bool flag) = 0; + /// \brief Lookup a previously defined macro. + /// \param Name Macro name. + /// \returns Pointer to macro. NULL if no such macro was defined. + virtual const MCAsmMacro* LookupMacro(StringRef Name) = 0; + + /// \brief Define a new macro with the given name and information. + virtual void DefineMacro(StringRef Name, const MCAsmMacro& Macro) = 0; + + /// \brief Undefine a macro. If no such macro was defined, it's a no-op. + virtual void UndefineMacro(StringRef Name) = 0; + + /// \brief Are we inside a macro instantiation? + virtual bool InsideMacroInstantiation() = 0; + + /// \brief Handle entry to macro instantiation. + /// + /// \param M The macro. + /// \param NameLoc Instantiation location. + virtual bool HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) = 0; + + /// \brief Handle exit from macro instantiation. + virtual void HandleMacroExit() = 0; + /// ParseMacroArgument - Extract AsmTokens for a macro argument. If the /// argument delimiter is initially unknown, set it to AsmToken::Eof. It will /// be set to the correct delimiter by the method. diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 735accdf7e..c47b9cdf32 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -35,6 +35,15 @@ namespace object { using support::endianness; +template<endianness target_endianness, std::size_t max_alignment, bool is64Bits> +struct ELFType { + enum { + TargetEndianness = target_endianness, + MaxAlignment = max_alignment, + Is64Bits = is64Bits + }; +}; + template<typename T, int max_align> struct MaximumAlignment { enum {value = AlignOf<T>::Alignment > max_align ? max_align @@ -70,59 +79,59 @@ struct ELFDataTypeTypedefHelperCommon { MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword; }; -template<endianness target_endianness, std::size_t max_alignment, bool is64Bits> +template<class ELFT> struct ELFDataTypeTypedefHelper; /// ELF 32bit types. -template<endianness target_endianness, std::size_t max_alignment> -struct ELFDataTypeTypedefHelper<target_endianness, max_alignment, false> - : ELFDataTypeTypedefHelperCommon<target_endianness, max_alignment> { +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, false> > + : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { typedef uint32_t value_type; typedef support::detail::packed_endian_specific_integral - <value_type, target_endianness, - MaximumAlignment<value_type, max_alignment>::value> Elf_Addr; + <value_type, TargetEndianness, + MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; typedef support::detail::packed_endian_specific_integral - <value_type, target_endianness, - MaximumAlignment<value_type, max_alignment>::value> Elf_Off; + <value_type, TargetEndianness, + MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; }; /// ELF 64bit types. -template<endianness target_endianness, std::size_t max_alignment> -struct ELFDataTypeTypedefHelper<target_endianness, max_alignment, true> - : ELFDataTypeTypedefHelperCommon<target_endianness, max_alignment>{ +template<template<endianness, std::size_t, bool> class ELFT, + endianness TargetEndianness, std::size_t MaxAlign> +struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, true> > + : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { typedef uint64_t value_type; typedef support::detail::packed_endian_specific_integral - <value_type, target_endianness, - MaximumAlignment<value_type, max_alignment>::value> Elf_Addr; + <value_type, TargetEndianness, + MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; typedef support::detail::packed_endian_specific_integral - <value_type, target_endianness, - MaximumAlignment<value_type, max_alignment>::value> Elf_Off; + <value_type, TargetEndianness, + MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; }; // I really don't like doing this, but the alternative is copypasta. -#define LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits) \ -typedef typename ELFDataTypeTypedefHelper \ - <target_endianness, max_alignment, is64Bits>::Elf_Addr Elf_Addr; \ -typedef typename ELFDataTypeTypedefHelper \ - <target_endianness, max_alignment, is64Bits>::Elf_Off Elf_Off; \ -typedef typename ELFDataTypeTypedefHelper \ |