Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304222, and update

build glue.
This commit is contained in:
Dimitry Andric 2017-05-30 19:24:09 +00:00
commit 89cb50c933
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/clang500-import/; revision=319250
133 changed files with 4230 additions and 1966 deletions

View File

@ -145,6 +145,19 @@ public:
return __tmp;
}
// FIXME: Should from_address(nullptr) be allowed?
_LIBCPP_ALWAYS_INLINE
static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
return coroutine_handle(nullptr);
}
template <class _Tp, bool _CallIsValid = false>
static coroutine_handle from_address(_Tp*) {
static_assert(_CallIsValid,
"coroutine_handle<void>::from_address cannot be called with "
"non-void pointers");
}
private:
bool __is_suspended() const _NOEXCEPT {
// FIXME actually implement a check for if the coro is suspended.
@ -218,11 +231,22 @@ public:
// FIXME: should from_address work with nullptr?
_LIBCPP_ALWAYS_INLINE
static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
return {};
return coroutine_handle(nullptr);
}
// from_address cannot be used with the coroutines promise type.
static coroutine_handle from_address(_Promise*) = delete;
template <class _Tp, bool _CallIsValid = false>
static coroutine_handle from_address(_Tp*) {
static_assert(_CallIsValid,
"coroutine_handle<promise_type>::from_address cannot be called with "
"non-void pointers");
}
template <bool _CallIsValid = false>
static coroutine_handle from_address(_Promise*) {
static_assert(_CallIsValid,
"coroutine_handle<promise_type>::from_address cannot be used with "
"pointers to the coroutine's promise type; use 'from_promise' instead");
}
_LIBCPP_ALWAYS_INLINE
static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {

View File

@ -502,6 +502,7 @@ module std [system] {
export *
}
module coroutine {
requires coroutines
header "experimental/coroutine"
export *
}

View File

@ -1536,8 +1536,7 @@ class ScalarEvolution {
/// Determine if the SCEV can be evaluated at loop's entry. It is true if it
/// doesn't depend on a SCEVUnknown of an instruction which is dominated by
/// the header of loop L.
bool isAvailableAtLoopEntry(const SCEV *S, const Loop *L, DominatorTree &DT,
LoopInfo &LI);
bool isAvailableAtLoopEntry(const SCEV *S, const Loop *L);
/// Return true if the given SCEV changes value in a known way in the
/// specified loop. This property being true implies that the value is

View File

@ -383,11 +383,11 @@ class DIEValue {
return;
#define HANDLE_DIEVALUE_SMALL(T) \
case is##T: \
destruct<DIE##T>();
destruct<DIE##T>(); \
return;
#define HANDLE_DIEVALUE_LARGE(T) \
case is##T: \
destruct<const DIE##T *>();
destruct<const DIE##T *>(); \
return;
#include "llvm/CodeGen/DIEValue.def"
}

View File

@ -13,6 +13,8 @@
#include <cinttypes>
#include <type_traits>
#include "llvm/Support/Endian.h"
namespace llvm {
namespace codeview {
@ -291,7 +293,7 @@ enum class ModifierOptions : uint16_t {
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions)
enum class ModuleDebugFragmentKind : uint32_t {
enum class DebugSubsectionKind : uint32_t {
None = 0,
Symbols = 0xf1,
Lines = 0xf2,
@ -550,6 +552,24 @@ enum LineFlags : uint16_t {
LF_None = 0,
LF_HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
};
/// Data in the the SUBSEC_FRAMEDATA subection.
struct FrameData {
support::ulittle32_t RvaStart;
support::ulittle32_t CodeSize;
support::ulittle32_t LocalSize;
support::ulittle32_t ParamsSize;
support::ulittle32_t MaxStackSize;
support::ulittle32_t FrameFunc;
support::ulittle16_t PrologSize;
support::ulittle16_t SavedRegsSize;
support::ulittle32_t Flags;
enum : uint32_t {
HasSEH = 1 << 0,
HasEH = 1 << 1,
IsFunctionStart = 1 << 2,
};
};
}
}

View File

@ -1,4 +1,4 @@
//===- ModuleDebugFileChecksumFragment.h ------------------------*- C++ -*-===//
//===- DebugChecksumsSubsection.h -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFILECHECKSUMFRAGMENT_H
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFILECHECKSUMFRAGMENT_H
#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGCHECKSUMSSUBSECTION_H
#define LLVM_DEBUGINFO_CODEVIEW_DEBUGCHECKSUMSSUBSECTION_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
@ -21,7 +21,7 @@
namespace llvm {
namespace codeview {
class StringTable;
class DebugStringTableSubsection;
struct FileChecksumEntry {
uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
@ -43,19 +43,22 @@ template <> struct VarStreamArrayExtractor<codeview::FileChecksumEntry> {
namespace llvm {
namespace codeview {
class ModuleDebugFileChecksumFragmentRef final : public ModuleDebugFragmentRef {
class DebugChecksumsSubsectionRef final : public DebugSubsectionRef {
typedef VarStreamArray<codeview::FileChecksumEntry> FileChecksumArray;
typedef FileChecksumArray::Iterator Iterator;
public:
ModuleDebugFileChecksumFragmentRef()
: ModuleDebugFragmentRef(ModuleDebugFragmentKind::FileChecksums) {}
DebugChecksumsSubsectionRef()
: DebugSubsectionRef(DebugSubsectionKind::FileChecksums) {}
static bool classof(const ModuleDebugFragmentRef *S) {
return S->kind() == ModuleDebugFragmentKind::FileChecksums;
static bool classof(const DebugSubsectionRef *S) {
return S->kind() == DebugSubsectionKind::FileChecksums;
}
bool valid() const { return Checksums.valid(); }
Error initialize(BinaryStreamReader Reader);
Error initialize(BinaryStreamRef Stream);
Iterator begin() { return Checksums.begin(); }
Iterator end() { return Checksums.end(); }
@ -66,23 +69,23 @@ class ModuleDebugFileChecksumFragmentRef final : public ModuleDebugFragmentRef {
FileChecksumArray Checksums;
};
class ModuleDebugFileChecksumFragment final : public ModuleDebugFragment {
class DebugChecksumsSubsection final : public DebugSubsection {
public:
explicit ModuleDebugFileChecksumFragment(StringTable &Strings);
explicit DebugChecksumsSubsection(DebugStringTableSubsection &Strings);
static bool classof(const ModuleDebugFragment *S) {
return S->kind() == ModuleDebugFragmentKind::FileChecksums;
static bool classof(const DebugSubsection *S) {
return S->kind() == DebugSubsectionKind::FileChecksums;
}
void addChecksum(StringRef FileName, FileChecksumKind Kind,
ArrayRef<uint8_t> Bytes);
uint32_t calculateSerializedLength() override;
Error commit(BinaryStreamWriter &Writer) override;
uint32_t calculateSerializedSize() const override;
Error commit(BinaryStreamWriter &Writer) const override;
uint32_t mapChecksumOffset(StringRef FileName) const;
private:
StringTable &Strings;
DebugStringTableSubsection &Strings;
DenseMap<uint32_t, uint32_t> OffsetMap;
uint32_t SerializedSize = 0;

View File

@ -0,0 +1,59 @@
//===- DebugFrameDataSubsection.h ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGFRAMEDATASUBSECTION_H
#define LLVM_DEBUGINFO_CODEVIEW_DEBUGFRAMEDATASUBSECTION_H
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
class DebugFrameDataSubsectionRef final : public DebugSubsectionRef {
public:
DebugFrameDataSubsectionRef()
: DebugSubsectionRef(DebugSubsectionKind::FrameData) {}
static bool classof(const DebugSubsection *S) {
return S->kind() == DebugSubsectionKind::FrameData;
}
Error initialize(BinaryStreamReader Reader);
FixedStreamArray<FrameData>::Iterator begin() const { return Frames.begin(); }
FixedStreamArray<FrameData>::Iterator end() const { return Frames.end(); }
const void *getRelocPtr() const { return RelocPtr; }
private:
const uint32_t *RelocPtr = nullptr;
FixedStreamArray<FrameData> Frames;
};
class DebugFrameDataSubsection final : public DebugSubsection {
public:
DebugFrameDataSubsection()
: DebugSubsection(DebugSubsectionKind::FrameData) {}
static bool classof(const DebugSubsection *S) {
return S->kind() == DebugSubsectionKind::FrameData;
}
uint32_t calculateSerializedSize() const override;
Error commit(BinaryStreamWriter &Writer) const override;
void addFrameData(const FrameData &Frame);
private:
std::vector<FrameData> Frames;
};
}
}
#endif

View File

@ -1,4 +1,4 @@
//===- ModuleDebugInlineeLinesFragment.h ------------------------*- C++ -*-===//
//===- DebugInlineeLinesSubsection.h ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGINLINEELINESFRAGMENT_H
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGINLINEELINESFRAGMENT_H
#ifndef LLVM_DEBUGINFO_CODEVIEW_BUGINLINEELINESSUBSECTION_H
#define LLVM_DEBUGINFO_CODEVIEW_BUGINLINEELINESSUBSECTION_H
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
@ -19,9 +19,8 @@
namespace llvm {
namespace codeview {
class ModuleDebugInlineeLineFragmentRef;
class ModuleDebugFileChecksumFragment;
class StringTable;
class DebugInlineeLinesSubsectionsRef;
class DebugChecksumsSubsection;
enum class InlineeLinesSignature : uint32_t {
Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
@ -51,15 +50,15 @@ template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> {
};
namespace codeview {
class ModuleDebugInlineeLineFragmentRef final : public ModuleDebugFragmentRef {
class DebugInlineeLinesSubsectionRef final : public DebugSubsectionRef {
typedef VarStreamArray<InlineeSourceLine> LinesArray;
typedef LinesArray::Iterator Iterator;
public:
ModuleDebugInlineeLineFragmentRef();
DebugInlineeLinesSubsectionRef();
static bool classof(const ModuleDebugFragmentRef *S) {
return S->kind() == ModuleDebugFragmentKind::InlineeLines;
static bool classof(const DebugSubsectionRef *S) {
return S->kind() == DebugSubsectionKind::InlineeLines;
}
Error initialize(BinaryStreamReader Reader);
@ -73,23 +72,23 @@ class ModuleDebugInlineeLineFragmentRef final : public ModuleDebugFragmentRef {
VarStreamArray<InlineeSourceLine> Lines;
};
class ModuleDebugInlineeLineFragment final : public ModuleDebugFragment {
class DebugInlineeLinesSubsection final : public DebugSubsection {
public:
ModuleDebugInlineeLineFragment(ModuleDebugFileChecksumFragment &Checksums,
bool HasExtraFiles);
DebugInlineeLinesSubsection(DebugChecksumsSubsection &Checksums,
bool HasExtraFiles);
static bool classof(const ModuleDebugFragment *S) {
return S->kind() == ModuleDebugFragmentKind::InlineeLines;
static bool classof(const DebugSubsection *S) {
return S->kind() == DebugSubsectionKind::InlineeLines;
}
Error commit(BinaryStreamWriter &Writer) override;
uint32_t calculateSerializedLength() override;
Error commit(BinaryStreamWriter &Writer) const override;
uint32_t calculateSerializedSize() const override;
void addInlineSite(TypeIndex FuncId, StringRef FileName, uint32_t SourceLine);
void addExtraFile(StringRef FileName);
private:
ModuleDebugFileChecksumFragment &Checksums;
DebugChecksumsSubsection &Checksums;
bool HasExtraFiles = false;
uint32_t ExtraFileCount = 0;

View File

@ -1,4 +1,4 @@
//===- ModuleDebugLineFragment.h --------------------------------*- C++ -*-===//
//===- DebugLinesSubsection.h --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -10,8 +10,8 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
@ -19,8 +19,8 @@
namespace llvm {
namespace codeview {
class ModuleDebugFileChecksumFragment;
class StringTable;
class DebugChecksumsSubsection;
class DebugStringTableSubsection;
// Corresponds to the `CV_DebugSLinesHeader_t` structure.
struct LineFragmentHeader {
@ -70,16 +70,16 @@ class LineColumnExtractor {
LineColumnEntry &Item, const LineFragmentHeader *Ctx);
};
class ModuleDebugLineFragmentRef final : public ModuleDebugFragmentRef {
class DebugLinesSubsectionRef final : public DebugSubsectionRef {
friend class LineColumnExtractor;
typedef VarStreamArray<LineColumnEntry, LineColumnExtractor> LineInfoArray;
typedef LineInfoArray::Iterator Iterator;
public:
ModuleDebugLineFragmentRef();
DebugLinesSubsectionRef();
static bool classof(const ModuleDebugFragmentRef *S) {
return S->kind() == ModuleDebugFragmentKind::Lines;
static bool classof(const DebugSubsectionRef *S) {
return S->kind() == DebugSubsectionKind::Lines;
}
Error initialize(BinaryStreamReader Reader);
@ -96,7 +96,7 @@ class ModuleDebugLineFragmentRef final : public ModuleDebugFragmentRef {
LineInfoArray LinesAndColumns;
};
class ModuleDebugLineFragment final : public ModuleDebugFragment {
class DebugLinesSubsection final : public DebugSubsection {
struct Block {
Block(uint32_t ChecksumBufferOffset)
: ChecksumBufferOffset(ChecksumBufferOffset) {}
@ -107,11 +107,11 @@ class ModuleDebugLineFragment final : public ModuleDebugFragment {
};
public:
ModuleDebugLineFragment(ModuleDebugFileChecksumFragment &Checksums,
StringTable &Strings);
DebugLinesSubsection(DebugChecksumsSubsection &Checksums,
DebugStringTableSubsection &Strings);
static bool classof(const ModuleDebugFragment *S) {
return S->kind() == ModuleDebugFragmentKind::Lines;
static bool classof(const DebugSubsection *S) {
return S->kind() == DebugSubsectionKind::Lines;
}
void createBlock(StringRef FileName);
@ -119,8 +119,8 @@ class ModuleDebugLineFragment final : public ModuleDebugFragment {
void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line,
uint32_t ColStart, uint32_t ColEnd);
uint32_t calculateSerializedLength() override;
Error commit(BinaryStreamWriter &Writer) override;
uint32_t calculateSerializedSize() const override;
Error commit(BinaryStreamWriter &Writer) const override;
void setRelocationAddress(uint16_t Segment, uint16_t Offset);
void setCodeSize(uint32_t Size);
@ -129,7 +129,7 @@ class ModuleDebugLineFragment final : public ModuleDebugFragment {
bool hasColumnInfo() const;
private:
ModuleDebugFileChecksumFragment &Checksums;
DebugChecksumsSubsection &Checksums;
uint16_t RelocOffset = 0;
uint16_t RelocSegment = 0;

View File

@ -1,4 +1,4 @@
//===- StringTable.h - CodeView String Table Reader/Writer ------*- C++ -*-===//
//===- DebugStringTableSubsection.h - CodeView String Table -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_STRINGTABLE_H
#define LLVM_DEBUGINFO_CODEVIEW_STRINGTABLE_H
#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H
#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Error.h"
@ -28,11 +28,15 @@ namespace codeview {
/// Represents a read-only view of a CodeView string table. This is a very
/// simple flat buffer consisting of null-terminated strings, where strings
/// are retrieved by their offset in the buffer. StringTableRef does not own
/// the underlying storage for the buffer.
class StringTableRef {
/// are retrieved by their offset in the buffer. DebugStringTableSubsectionRef
/// does not own the underlying storage for the buffer.
class DebugStringTableSubsectionRef : public DebugSubsectionRef {
public:
StringTableRef();
DebugStringTableSubsectionRef();
static bool classof(const DebugSubsectionRef *S) {
return S->kind() == DebugSubsectionKind::StringTable;
}
Error initialize(BinaryStreamRef Contents);
@ -44,11 +48,18 @@ class StringTableRef {
BinaryStreamRef Stream;
};
/// Represents a read-write view of a CodeView string table. StringTable owns
/// the underlying storage for the table, and is capable of serializing the
/// string table into a format understood by StringTableRef.
class StringTable {
/// Represents a read-write view of a CodeView string table.
/// DebugStringTableSubsection owns the underlying storage for the table, and is
/// capable of serializing the string table into a format understood by
/// DebugStringTableSubsectionRef.
class DebugStringTableSubsection : public DebugSubsection {
public:
DebugStringTableSubsection();
static bool classof(const DebugSubsection *S) {
return S->kind() == DebugSubsectionKind::StringTable;
}
// If string S does not exist in the string table, insert it.
// Returns the ID for S.
uint32_t insert(StringRef S);
@ -56,8 +67,8 @@ class StringTable {
// Return the ID for string S. Assumes S exists in the table.
uint32_t getStringId(StringRef S) const;
uint32_t calculateSerializedSize() const;
Error commit(BinaryStreamWriter &Writer) const;
uint32_t calculateSerializedSize() const override;
Error commit(BinaryStreamWriter &Writer) const override;
uint32_t size() const;

View File

@ -0,0 +1,52 @@
//===- DebugSubsection.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Casting.h"
namespace llvm {
namespace codeview {
class DebugSubsectionRef {
public:
explicit DebugSubsectionRef(DebugSubsectionKind Kind) : Kind(Kind) {}
virtual ~DebugSubsectionRef();
static bool classof(const DebugSubsectionRef *S) { return true; }
DebugSubsectionKind kind() const { return Kind; }
protected:
DebugSubsectionKind Kind;
};
class DebugSubsection {
public:
explicit DebugSubsection(DebugSubsectionKind Kind) : Kind(Kind) {}
virtual ~DebugSubsection();
static bool classof(const DebugSubsection *S) { return true; }
DebugSubsectionKind kind() const { return Kind; }
virtual Error commit(BinaryStreamWriter &Writer) const = 0;
virtual uint32_t calculateSerializedSize() const = 0;
protected:
DebugSubsectionKind Kind;
};
} // namespace codeview
} // namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H

View File

@ -1,4 +1,4 @@
//===- ModuleDebugFragment.h ------------------------------------*- C++ -*-===//
//===- DebugSubsection.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -20,52 +20,49 @@
namespace llvm {
namespace codeview {
class ModuleDebugFragment;
class DebugSubsection;
// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
struct ModuleDebugFragmentHeader {
support::ulittle32_t Kind; // codeview::ModuleDebugFragmentKind enum
struct DebugSubsectionHeader {
support::ulittle32_t Kind; // codeview::DebugSubsectionKind enum
support::ulittle32_t Length; // number of bytes occupied by this record.
};
class ModuleDebugFragmentRecord {
class DebugSubsectionRecord {
public:
ModuleDebugFragmentRecord();
ModuleDebugFragmentRecord(ModuleDebugFragmentKind Kind, BinaryStreamRef Data);
DebugSubsectionRecord();
DebugSubsectionRecord(DebugSubsectionKind Kind, BinaryStreamRef Data);
static Error initialize(BinaryStreamRef Stream,
ModuleDebugFragmentRecord &Info);
static Error initialize(BinaryStreamRef Stream, DebugSubsectionRecord &Info);
uint32_t getRecordLength() const;
ModuleDebugFragmentKind kind() const;
DebugSubsectionKind kind() const;
BinaryStreamRef getRecordData() const;
private:
ModuleDebugFragmentKind Kind;
DebugSubsectionKind Kind;
BinaryStreamRef Data;
};
class ModuleDebugFragmentRecordBuilder {
class DebugSubsectionRecordBuilder {
public:
ModuleDebugFragmentRecordBuilder(ModuleDebugFragmentKind Kind,
ModuleDebugFragment &Frag);
DebugSubsectionRecordBuilder(DebugSubsectionKind Kind, DebugSubsection &Frag);
uint32_t calculateSerializedLength();
Error commit(BinaryStreamWriter &Writer);
private:
ModuleDebugFragmentKind Kind;
ModuleDebugFragment &Frag;
DebugSubsectionKind Kind;
DebugSubsection &Frag;
};
} // namespace codeview
template <>
struct VarStreamArrayExtractor<codeview::ModuleDebugFragmentRecord> {
template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
typedef void ContextType;
static Error extract(BinaryStreamRef Stream, uint32_t &Length,
codeview::ModuleDebugFragmentRecord &Info) {
if (auto EC = codeview::ModuleDebugFragmentRecord::initialize(Stream, Info))
codeview::DebugSubsectionRecord &Info) {
if (auto EC = codeview::DebugSubsectionRecord::initialize(Stream, Info))
return EC;
Length = Info.getRecordLength();
return Error::success();
@ -73,7 +70,7 @@ struct VarStreamArrayExtractor<codeview::ModuleDebugFragmentRecord> {
};
namespace codeview {
typedef VarStreamArray<ModuleDebugFragmentRecord> ModuleDebugFragmentArray;
typedef VarStreamArray<DebugSubsectionRecord> DebugSubsectionArray;
}
} // namespace llvm

View File

@ -1,4 +1,4 @@
//===- ModuleDebugFragmentVisitor.h -----------------------------*- C++ -*-===//
//===- DebugSubsectionVisitor.h -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -17,43 +17,41 @@ namespace llvm {
namespace codeview {
class ModuleDebugFileChecksumFragmentRef;
class ModuleDebugFragmentRecord;
class ModuleDebugInlineeLineFragmentRef;
class ModuleDebugLineFragmentRef;
class ModuleDebugUnknownFragmentRef;
class DebugChecksumsSubsectionRef;
class DebugSubsectionRecord;
class DebugInlineeLinesSubsectionRef;
class DebugLinesSubsectionRef;
class DebugUnknownSubsectionRef;
class ModuleDebugFragmentVisitor {
class DebugSubsectionVisitor {
public:
virtual ~ModuleDebugFragmentVisitor() = default;
virtual ~DebugSubsectionVisitor() = default;
virtual Error visitUnknown(ModuleDebugUnknownFragmentRef &Unknown) {
virtual Error visitUnknown(DebugUnknownSubsectionRef &Unknown) {
return Error::success();
}
virtual Error visitLines(ModuleDebugLineFragmentRef &Lines) {
virtual Error visitLines(DebugLinesSubsectionRef &Lines) {
return Error::success();
}
virtual Error
visitFileChecksums(ModuleDebugFileChecksumFragmentRef &Checksums) {
virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums) {
return Error::success();
}
virtual Error visitInlineeLines(ModuleDebugInlineeLineFragmentRef &Inlinees) {
virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees) {
return Error::success();
}
virtual Error finished() { return Error::success(); }
};
Error visitModuleDebugFragment(const ModuleDebugFragmentRecord &R,
ModuleDebugFragmentVisitor &V);
Error visitDebugSubsection(const DebugSubsectionRecord &R,
DebugSubsectionVisitor &V);
template <typename T>
Error visitModuleDebugFragments(T &&FragmentRange,
ModuleDebugFragmentVisitor &V) {
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
for (const auto &L : FragmentRange) {
if (auto EC = visitModuleDebugFragment(L, V))
if (auto EC = visitDebugSubsection(L, V))
return EC;
}
if (auto EC = V.finished())

View File

@ -0,0 +1,53 @@
//===- DebugSymbolsSubsection.h --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLSSUBSECTION_H
#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLSSUBSECTION_H
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
class DebugSymbolsSubsectionRef final : public DebugSubsectionRef {
public:
DebugSymbolsSubsectionRef()
: DebugSubsectionRef(DebugSubsectionKind::Symbols) {}
static bool classof(const DebugSubsectionRef *S) {
return S->kind() == DebugSubsectionKind::Symbols;
}
Error initialize(BinaryStreamReader Reader);
private:
CVSymbolArray Records;
};
class DebugSymbolsSubsection final : public DebugSubsection {
public:
DebugSymbolsSubsection() : DebugSubsection(DebugSubsectionKind::Symbols) {}
static bool classof(const DebugSubsection *S) {
return S->kind() == DebugSubsectionKind::Symbols;
}
uint32_t calculateSerializedSize() const override;
Error commit(BinaryStreamWriter &Writer) const override;
void addSymbol(CVSymbol Symbol);
private:
uint32_t Length = 0;
std::vector<CVSymbol> Records;
};
}
}
#endif

View File

@ -1,4 +1,4 @@
//===- ModuleDebugUnknownFragment.h -----------------------------*- C++ -*-===//
//===- DebugUnknownSubsection.h -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -10,17 +10,16 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/Support/BinaryStreamRef.h"
namespace llvm {
namespace codeview {
class ModuleDebugUnknownFragmentRef final : public ModuleDebugFragmentRef {
class DebugUnknownSubsectionRef final : public DebugSubsectionRef {
public:
ModuleDebugUnknownFragmentRef(ModuleDebugFragmentKind Kind,
BinaryStreamRef Data)
: ModuleDebugFragmentRef(Kind), Data(Data) {}
DebugUnknownSubsectionRef(DebugSubsectionKind Kind, BinaryStreamRef Data)
: DebugSubsectionRef(Kind), Data(Data) {}
BinaryStreamRef getData() const { return Data; }

View File

@ -1,48 +0,0 @@
//===- ModuleDebugFragment.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Casting.h"
namespace llvm {
namespace codeview {
class ModuleDebugFragmentRef {
public:
explicit ModuleDebugFragmentRef(ModuleDebugFragmentKind Kind) : Kind(Kind) {}
virtual ~ModuleDebugFragmentRef();
ModuleDebugFragmentKind kind() const { return Kind; }
protected:
ModuleDebugFragmentKind Kind;
};
class ModuleDebugFragment {
public:
explicit ModuleDebugFragment(ModuleDebugFragmentKind Kind) : Kind(Kind) {}
virtual ~ModuleDebugFragment();
ModuleDebugFragmentKind kind() const { return Kind; }
virtual Error commit(BinaryStreamWriter &Writer) = 0;
virtual uint32_t calculateSerializedLength() = 0;
protected:
ModuleDebugFragmentKind Kind;
};
} // namespace codeview
} // namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H

View File

@ -19,7 +19,7 @@ class BinaryStreamReader;
namespace codeview {
class StringTableRef;
class DebugStringTableSubsectionRef;
class SymbolVisitorDelegate {
public:
@ -27,7 +27,7 @@ class SymbolVisitorDelegate {
virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0;
virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0;
virtual StringTableRef getStringTable() = 0;
virtual DebugStringTableSubsectionRef getStringTable() = 0;
};
} // end namespace codeview

View File

@ -11,9 +11,9 @@
#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTORBUILDER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/Error.h"
@ -25,7 +25,7 @@ namespace llvm {
class BinaryStreamWriter;
namespace codeview {
class ModuleDebugFragmentRecordBuilder;
class DebugSubsectionRecordBuilder;
}
namespace msf {
@ -49,11 +49,11 @@ class DbiModuleDescriptorBuilder {
void setObjFileName(StringRef Name);
void addSymbol(codeview::CVSymbol Symbol);
void addC13Fragment(std::unique_ptr<codeview::ModuleDebugLineFragment> Lines);
void addC13Fragment(std::unique_ptr<codeview::DebugLinesSubsection> Lines);
void addC13Fragment(
std::unique_ptr<codeview::ModuleDebugInlineeLineFragment> Inlinees);
std::unique_ptr<codeview::DebugInlineeLinesSubsection> Inlinees);
void setC13FileChecksums(
std::unique_ptr<codeview::ModuleDebugFileChecksumFragment> Checksums);
std::unique_ptr<codeview::DebugChecksumsSubsection> Checksums);
uint16_t getStreamIndex() const;
StringRef getModuleName() const { return ModuleName; }
@ -83,12 +83,11 @@ class DbiModuleDescriptorBuilder {
std::vector<std::string> SourceFiles;
std::vector<codeview::CVSymbol> Symbols;
std::unique_ptr<codeview::ModuleDebugFileChecksumFragment> ChecksumInfo;
std::vector<std::unique_ptr<codeview::ModuleDebugLineFragment>> LineInfo;
std::vector<std::unique_ptr<codeview::ModuleDebugInlineeLineFragment>>
Inlinees;
std::unique_ptr<codeview::DebugChecksumsSubsection> ChecksumInfo;
std::vector<std::unique_ptr<codeview::DebugLinesSubsection>> LineInfo;
std::vector<std::unique_ptr<codeview::DebugInlineeLinesSubsection>> Inlinees;
std::vector<std::unique_ptr<codeview::ModuleDebugFragmentRecordBuilder>>
std::vector<std::unique_ptr<codeview::DebugSubsectionRecordBuilder>>
C13Builders;
ModuleInfoHeader Layout;

View File

@ -10,7 +10,7 @@
#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
#define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
@ -19,8 +19,6 @@
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"

View File

@ -12,7 +12,7 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/Support/BinaryStreamArray.h"
@ -25,8 +25,7 @@ class PDBFile;
class DbiModuleDescriptor;
class ModuleDebugStreamRef {
typedef codeview::ModuleDebugFragmentArray::Iterator
LinesAndChecksumsIterator;
typedef codeview::DebugSubsectionArray::Iterator LinesAndChecksumsIterator;
public:
ModuleDebugStreamRef(const DbiModuleDescriptor &Module,
@ -58,7 +57,7 @@ class ModuleDebugStreamRef {
BinaryStreamRef C13LinesSubstream;
BinaryStreamRef GlobalRefsSubstream;
codeview::ModuleDebugFragmentArray LinesAndChecksums;
codeview::DebugSubsectionArray LinesAndChecksums;
};
}
}

View File

@ -12,7 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/StringTable.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
@ -52,7 +52,7 @@ class PDBStringTable {
Error readEpilogue(BinaryStreamReader &Reader);
const PDBStringTableHeader *Header = nullptr;
codeview::StringTableRef Strings;
codeview::DebugStringTableSubsectionRef Strings;
FixedStreamArray<support::ulittle32_t> IDs;
uint32_t ByteSize = 0;
uint32_t NameCount = 0;

View File

@ -16,7 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/StringTable.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/Support/Error.h"
#include <vector>
@ -41,8 +41,10 @@ class PDBStringTableBuilder {
uint32_t calculateSerializedSize() const;
Error commit(BinaryStreamWriter &Writer) const;
codeview::StringTable &getStrings() { return Strings; }
const codeview::StringTable &getStrings() const { return Strings; }
codeview::DebugStringTableSubsection &getStrings() { return Strings; }
const codeview::DebugStringTableSubsection &getStrings() const {
return Strings;
}
private:
uint32_t calculateHashTableSize() const;
@ -51,7 +53,7 @@ class PDBStringTableBuilder {
Error writeHashTable(BinaryStreamWriter &Writer) const;
Error writeEpilogue(BinaryStreamWriter &Writer) const;
codeview::StringTable Strings;
codeview::DebugStringTableSubsection Strings;
};
} // end namespace pdb

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/SMLoc.h"
#include <cstdint>
#include <map>
namespace llvm {
@ -44,7 +45,7 @@ struct ConstantPoolEntry {
class ConstantPool {
using EntryVecTy = SmallVector<ConstantPoolEntry, 4>;
EntryVecTy Entries;
DenseMap<int64_t, const MCSymbolRefExpr *> CachedEntries;
std::map<int64_t, const MCSymbolRefExpr *> CachedEntries;
public:
// Initialize a new empty constant pool

View File

@ -14,25 +14,22 @@
#ifndef LLVM_SUPPORT_MANAGEDSTATIC_H
#define LLVM_SUPPORT_MANAGEDSTATIC_H
#include "llvm/Support/Compiler.h"
#include <atomic>
#include <cstddef>
namespace llvm {
/// object_creator - Helper method for ManagedStatic.
template<class C>
LLVM_LIBRARY_VISIBILITY void* object_creator() {
return new C();
}
template <class C> struct object_creator {
static void *call() { return new C(); }
};
/// object_deleter - Helper method for ManagedStatic.
///
template <typename T> struct LLVM_LIBRARY_VISIBILITY object_deleter {
template <typename T> struct object_deleter {
static void call(void *Ptr) { delete (T *)Ptr; }
};
template <typename T, size_t N>
struct LLVM_LIBRARY_VISIBILITY object_deleter<T[N]> {
template <typename T, size_t N> struct object_deleter<T[N]> {
static void call(void *Ptr) { delete[](T *)Ptr; }
};
@ -59,14 +56,15 @@ class ManagedStaticBase {
/// libraries that link in LLVM components) and for making destruction be
/// explicit through the llvm_shutdown() function call.
///
template<class C>
template <class C, class Creator = object_creator<C>,
class Deleter = object_deleter<C>>
class ManagedStatic : public ManagedStaticBase {
public:
// Accessors.
C &operator*() {
void *Tmp = Ptr.load(std::memory_order_acquire);
if (!Tmp)
RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
RegisterManagedStatic(Creator::call, Deleter::call);
return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}
@ -76,7 +74,7 @@ class ManagedStatic : public ManagedStaticBase {
const C &operator*() const {
void *Tmp = Ptr.load(std::memory_order_acquire);
if (!Tmp)
RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
RegisterManagedStatic(Creator::call, Deleter::call);
return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}

View File

@ -1189,6 +1189,9 @@ class DagInit final : public TypedInit, public FoldingSetNode,
return Init ? Init->getValue() : StringRef();
}
ArrayRef<Init *> getArgs() const {
return makeArrayRef(getTrailingObjects<Init *>(), NumArgs);
}
ArrayRef<StringInit *> getArgNames() const {
return makeArrayRef(getTrailingObjects<StringInit *>(), NumArgNames);
}
@ -1200,19 +1203,16 @@ class DagInit final : public TypedInit, public FoldingSetNode,
typedef SmallVectorImpl<Init*>::const_iterator const_arg_iterator;
typedef SmallVectorImpl<StringInit*>::const_iterator const_name_iterator;
inline const_arg_iterator arg_begin() const { return getTrailingObjects<Init *>(); }
inline const_arg_iterator arg_end () const { return arg_begin() + NumArgs; }
inline iterator_range<const_arg_iterator> args() const {
return llvm::make_range(arg_begin(), arg_end());
}
inline const_arg_iterator arg_begin() const { return getArgs().begin(); }
inline const_arg_iterator arg_end () const { return getArgs().end(); }
inline size_t arg_size () const { return NumArgs; }
inline size_t arg_size () const { return NumArgs; }
inline bool arg_empty() const { return NumArgs == 0; }
inline const_name_iterator name_begin() const { return getTrailingObjects<StringInit *>(); }
inline const_name_iterator name_end () const { return name_begin() + NumArgNames; }
inline const_name_iterator name_begin() const { return getArgNames().begin();}
inline const_name_iterator name_end () const { return getArgNames().end(); }
inline size_t name_size () const { return NumArgNames; }
inline size_t name_size () const { return NumArgNames; }
inline bool name_empty() const { return NumArgNames == 0; }
Init *getBit(unsigned Bit) const override {

View File

@ -58,10 +58,11 @@ class Expression {
private:
ExpressionType EType;
unsigned Opcode;
mutable hash_code HashVal;
public:
Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
: EType(ET), Opcode(O) {}
: EType(ET), Opcode(O), HashVal(0) {}
Expression(const Expression &) = delete;
Expression &operator=(const Expression &) = delete;
virtual ~Expression();
@ -82,6 +83,14 @@ class Expression {
return equals(Other);
}
hash_code getComputedHash() const {
// It's theoretically possible for a thing to hash to zero. In that case,
// we will just compute the hash a few extra times, which is no worse that
// we did before, which was to compute it always.
if (static_cast<unsigned>(HashVal) == 0)
HashVal = getHashValue();
return HashVal;
}
virtual bool equals(const Expression &Other) const { return true; }

View File

@ -2178,8 +2178,7 @@ StrengthenNoWrapFlags(ScalarEvolution *SE, SCEVTypes Type,
return Flags;
}
bool ScalarEvolution::isAvailableAtLoopEntry(const SCEV *S, const Loop *L,
DominatorTree &DT, LoopInfo &LI) {
bool ScalarEvolution::isAvailableAtLoopEntry(const SCEV *S, const Loop *L) {
if (!isLoopInvariant(S, L))
return false;
// If a value depends on a SCEVUnknown which is defined after the loop, we
@ -2516,7 +2515,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
const SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(Ops[Idx]);
const Loop *AddRecLoop = AddRec->getLoop();
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
if (isAvailableAtLoopEntry(Ops[i], AddRecLoop, DT, LI)) {
if (isAvailableAtLoopEntry(Ops[i], AddRecLoop)) {
LIOps.push_back(Ops[i]);
Ops.erase(Ops.begin()+i);
--i; --e;
@ -2791,7 +2790,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
const SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(Ops[Idx]);
const Loop *AddRecLoop = AddRec->getLoop();
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
if (isAvailableAtLoopEntry(Ops[i], AddRecLoop, DT, LI)) {
if (isAvailableAtLoopEntry(Ops[i], AddRecLoop)) {
LIOps.push_back(Ops[i]);
Ops.erase(Ops.begin()+i);
--i; --e;

View File

@ -15,8 +15,8 @@
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
@ -393,7 +393,7 @@ void CodeViewDebug::endModule() {
// subprograms.
switchToDebugSectionForSymbol(nullptr);
MCSymbol *CompilerInfo = beginCVSubsection(ModuleDebugFragmentKind::Symbols);
MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols);
emitCompilerInformation();
endCVSubsection(CompilerInfo);
@ -417,7 +417,7 @@ void CodeViewDebug::endModule() {
// Emit UDT records for any types used by global variables.
if (!GlobalUDTs.empty()) {
MCSymbol *SymbolsEnd = beginCVSubsection(ModuleDebugFragmentKind::Symbols);
MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
emitDebugInfoForUDTs(GlobalUDTs);
endCVSubsection(SymbolsEnd);
}
@ -630,8 +630,7 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
return;
OS.AddComment("Inlinee lines subsection");
MCSymbol *InlineEnd =
beginCVSubsection(ModuleDebugFragmentKind::InlineeLines);
MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);
// We don't provide any extra file info.
// FIXME: Find out if debuggers use this info.
@ -756,7 +755,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
// Emit a symbol subsection, required by VS2012+ to find function boundaries.
OS.AddComment("Symbol subsection for " + Twine(FuncName));
MCSymbol *SymbolsEnd = beginCVSubsection(ModuleDebugFragmentKind::Symbols);
MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
{
MCSymbol *ProcRecordBegin = MMI->getContext().createTempSymbol(),
*ProcRecordEnd = MMI->getContext().createTempSymbol();
@ -2111,7 +2110,7 @@ void CodeViewDebug::beginInstruction(const MachineInstr *MI) {
maybeRecordLocation(DL, Asm->MF);
}
MCSymbol *CodeViewDebug::beginCVSubsection(ModuleDebugFragmentKind Kind) {
MCSymbol *CodeViewDebug::beginCVSubsection(DebugSubsectionKind Kind) {
MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(),
*EndLabel = MMI->getContext().createTempSymbol();
OS.EmitIntValue(unsigned(Kind), 4);
@ -2171,7 +2170,7 @@ void CodeViewDebug::emitDebugInfoForGlobals() {
if (!GV->hasComdat() && !GV->isDeclarationForLinker()) {
if (!EndLabel) {
OS.AddComment("Symbol subsection for globals");
EndLabel = beginCVSubsection(ModuleDebugFragmentKind::Symbols);
EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
}
// FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.
emitDebugInfoForGlobal(GVE->getVariable(), GV, Asm->getSymbol(GV));
@ -2189,7 +2188,7 @@ void CodeViewDebug::emitDebugInfoForGlobals() {
OS.AddComment("Symbol subsection for " +
Twine(GlobalValue::dropLLVMManglingEscape(GV->getName())));
switchToDebugSectionForSymbol(GVSym);
EndLabel = beginCVSubsection(ModuleDebugFragmentKind::Symbols);
EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
// FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.
emitDebugInfoForGlobal(GVE->getVariable(), GV, GVSym);
endCVSubsection(EndLabel);

View File

@ -216,7 +216,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
/// Opens a subsection of the given kind in a .debug$S codeview section.
/// Returns an end label for use with endCVSubsection when the subsection is
/// finished.
MCSymbol *beginCVSubsection(codeview::ModuleDebugFragmentKind Kind);
MCSymbol *beginCVSubsection(codeview::DebugSubsectionKind Kind);
void endCVSubsection(MCSymbol *EndLabel);

View File

@ -23,7 +23,7 @@ using namespace llvm;
char Localizer::ID = 0;
INITIALIZE_PASS(Localizer, DEBUG_TYPE,
"Move/duplicate certain instructions close to their use", false,
false);
false)
Localizer::Localizer() : MachineFunctionPass(ID) {
initializeLocalizerPass(*PassRegistry::getPassRegistry());

View File

@ -14567,7 +14567,8 @@ static SDValue narrowExtractedVectorLoad(SDNode *Extract, SelectionDAG &DAG) {
// extract instead or remove that condition entirely.
auto *Ld = dyn_cast<LoadSDNode>(Extract->getOperand(0));
auto *ExtIdx = dyn_cast<ConstantSDNode>(Extract->getOperand(1));
if (!Ld || !Ld->hasOneUse() || Ld->isVolatile() || !ExtIdx)
if (!Ld || !Ld->hasOneUse() || Ld->getExtensionType() || Ld->isVolatile() ||
!ExtIdx)
return SDValue();
// The narrow load will be offset from the base address of the old load if

View File

@ -925,10 +925,6 @@ getStrictFPOpcodeAction(const TargetLowering &TLI, unsigned Opcode, EVT VT) {
if (Action != TargetLowering::Legal)
Action = TargetLowering::Expand;
// ISD::FPOWI returns 'Legal' even though it should be expanded.
if (Opcode == ISD::STRICT_FPOWI && Action == TargetLowering::Legal)
Action = TargetLowering::Expand;
return Action;
}
@ -1027,7 +1023,6 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
break;
case ISD::EXTRACT_ELEMENT:
case ISD::FLT_ROUNDS_:
case ISD::FPOWI:
case ISD::MERGE_VALUES:
case ISD::EH_RETURN:
case ISD::FRAME_TO_ARGS_OFFSET:

View File

@ -935,6 +935,7 @@ void TargetLoweringBase::initActions() {
// These library functions default to expand.
setOperationAction(ISD::FROUND, VT, Expand);
setOperationAction(ISD::FPOWI, VT, Expand);
// These operations default to expand for vector types.
if (VT.isVector()) {

View File

@ -1,4 +1,4 @@
//===- ModuleDebugFileChecksumFragment.cpp ----------------------*- C++ -*-===//
//===- DebugChecksumsSubsection.cpp ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/StringTable.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/Support/BinaryStreamReader.h"
using namespace llvm;
@ -42,22 +42,24 @@ Error llvm::VarStreamArrayExtractor<FileChecksumEntry>::extract(
return Error::success();
}
Error ModuleDebugFileChecksumFragmentRef::initialize(
BinaryStreamReader Reader) {
Error DebugChecksumsSubsectionRef::initialize(BinaryStreamReader Reader) {
if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining()))
return EC;
return Error::success();
}
Error DebugChecksumsSubsectionRef::initialize(BinaryStreamRef Section) {
BinaryStreamReader Reader(Section);
return initialize(Reader);
}
ModuleDebugFileChecksumFragment::ModuleDebugFileChecksumFragment(
StringTable &Strings)
: ModuleDebugFragment(ModuleDebugFragmentKind::FileChecksums),
Strings(Strings) {}
DebugChecksumsSubsection::DebugChecksumsSubsection(
DebugStringTableSubsection &Strings)
: DebugSubsection(DebugSubsectionKind::FileChecksums), Strings(Strings) {}
void ModuleDebugFileChecksumFragment::addChecksum(StringRef FileName,
FileChecksumKind Kind,
ArrayRef<uint8_t> Bytes) {
void DebugChecksumsSubsection::addChecksum(StringRef FileName,
FileChecksumKind Kind,
ArrayRef<uint8_t> Bytes) {
FileChecksumEntry Entry;
if (!Bytes.empty()) {
uint8_t *Copy = Storage.Allocate<uint8_t>(Bytes.size());
@ -78,11 +80,11 @@ void ModuleDebugFileChecksumFragment::addChecksum(StringRef FileName,
SerializedSize += Len;
}
uint32_t ModuleDebugFileChecksumFragment::calculateSerializedLength() {
uint32_t DebugChecksumsSubsection::calculateSerializedSize() const {
return SerializedSize;
}
Error ModuleDebugFileChecksumFragment::commit(BinaryStreamWriter &Writer) {
Error DebugChecksumsSubsection::commit(BinaryStreamWriter &Writer) const {
for (const auto &FC : Checksums) {
FileChecksumEntryHeader Header;
Header.ChecksumKind = uint8_t(FC.Kind);
@ -98,8 +100,7 @@ Error ModuleDebugFileChecksumFragment::commit(BinaryStreamWriter &Writer) {
return Error::success();
}
uint32_t
ModuleDebugFileChecksumFragment::mapChecksumOffset(StringRef FileName) const {
uint32_t DebugChecksumsSubsection::mapChecksumOffset(StringRef FileName) const {
uint32_t Offset = Strings.getStringId(FileName);
auto Iter = OffsetMap.find(Offset);
assert(Iter != OffsetMap.end());

View File

@ -0,0 +1,44 @@
//===- DebugFrameDataSubsection.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
using namespace llvm;
using namespace llvm::codeview;
Error DebugFrameDataSubsectionRef::initialize(BinaryStreamReader Reader) {
if (auto EC = Reader.readObject(RelocPtr))
return EC;
if (Reader.bytesRemaining() % sizeof(FrameData) != 0)
return make_error<CodeViewError>(cv_error_code::corrupt_record,
"Invalid frame data record format!");
uint32_t Count = Reader.bytesRemaining() / sizeof(FrameData);
if (auto EC = Reader.readArray(Frames, Count))
return EC;
return Error::success();
}
uint32_t DebugFrameDataSubsection::calculateSerializedSize() const {
return 4 + sizeof(FrameData) * Frames.size();
}
Error DebugFrameDataSubsection::commit(BinaryStreamWriter &Writer) const {
if (auto EC = Writer.writeInteger<uint32_t>(0))
return EC;
if (auto EC = Writer.writeArray(makeArrayRef(Frames)))
return EC;
return Error::success();
}
void DebugFrameDataSubsection::addFrameData(const FrameData &Frame) {
Frames.push_back(Frame);
}

View File

@ -1,4 +1,4 @@
//===- ModuleDebugInlineeLineFragment.cpp ------------------------*- C++-*-===//
//===- DebugInlineeLinesSubsection.cpp ------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
#include "llvm/DebugInfo/CodeView/StringTable.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
using namespace llvm;
using namespace llvm::codeview;
@ -37,10 +37,10 @@ Error VarStreamArrayExtractor<InlineeSourceLine>::extract(
return Error::success();
}
ModuleDebugInlineeLineFragmentRef::ModuleDebugInlineeLineFragmentRef()
: ModuleDebugFragmentRef(ModuleDebugFragmentKind::InlineeLines) {}
DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
: DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
Error ModuleDebugInlineeLineFragmentRef::initialize(BinaryStreamReader Reader) {
Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
if (auto EC = Reader.readEnum(Signature))
return EC;
@ -52,16 +52,16 @@ Error ModuleDebugInlineeLineFragmentRef::initialize(BinaryStreamReader Reader) {
return Error::success();
}
bool ModuleDebugInlineeLineFragmentRef::hasExtraFiles() const {
bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
return Signature == InlineeLinesSignature::ExtraFiles;
}
ModuleDebugInlineeLineFragment::ModuleDebugInlineeLineFragment(
ModuleDebugFileChecksumFragment &Checksums, bool HasExtraFiles)
: ModuleDebugFragment(ModuleDebugFragmentKind::InlineeLines),
Checksums(Checksums), HasExtraFiles(HasExtraFiles) {}
DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
: DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
HasExtraFiles(HasExtraFiles) {}
uint32_t ModuleDebugInlineeLineFragment::calculateSerializedLength() {
uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const {
// 4 bytes for the signature
uint32_t Size = sizeof(InlineeLinesSignature);
@ -78,7 +78,7 @@ uint32_t ModuleDebugInlineeLineFragment::calculateSerializedLength() {
return Size;
}
Error ModuleDebugInlineeLineFragment::commit(BinaryStreamWriter &Writer) {
Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const {
InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
if (HasExtraFiles)
Sig = InlineeLinesSignature::ExtraFiles;
@ -102,7 +102,7 @@ Error ModuleDebugInlineeLineFragment::commit(BinaryStreamWriter &Writer) {
return Error::success();
}
void ModuleDebugInlineeLineFragment::addExtraFile(StringRef FileName) {
void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
uint32_t Offset = Checksums.mapChecksumOffset(FileName);
auto &Entry = Entries.back();
@ -110,9 +110,9 @@ void ModuleDebugInlineeLineFragment::addExtraFile(StringRef FileName) {
++ExtraFileCount;
}
void ModuleDebugInlineeLineFragment::addInlineSite(TypeIndex FuncId,
StringRef FileName,
uint32_t SourceLine) {
void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
StringRef FileName,
uint32_t SourceLine) {
uint32_t Offset = Checksums.mapChecksumOffset(FileName);
Entries.emplace_back();

View File

@ -1,4 +1,4 @@
//===- ModuleDebugLineFragment.cpp -------------------------------*- C++-*-===//
//===- DebugLinesSubsection.cpp -------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
#include "llvm/DebugInfo/CodeView/StringTable.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
using namespace llvm;
using namespace llvm::codeview;
@ -49,10 +49,10 @@ Error LineColumnExtractor::extract(BinaryStreamRef Stream, uint32_t &Len,
return Error::success();
}
ModuleDebugLineFragmentRef::ModuleDebugLineFragmentRef()
: ModuleDebugFragmentRef(ModuleDebugFragmentKind::Lines) {}
DebugLinesSubsectionRef::DebugLinesSubsectionRef()
: DebugSubsectionRef(DebugSubsectionKind::Lines) {}
Error ModuleDebugLineFragmentRef::initialize(BinaryStreamReader Reader) {
Error DebugLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
if (auto EC = Reader.readObject(Header))
return EC;
@ -63,23 +63,21 @@ Error ModuleDebugLineFragmentRef::initialize(BinaryStreamReader Reader) {
return Error::success();
}
bool ModuleDebugLineFragmentRef::hasColumnInfo() const {
bool DebugLinesSubsectionRef::hasColumnInfo() const {
return !!(Header->Flags & LF_HaveColumns);
}
ModuleDebugLineFragment::ModuleDebugLineFragment(
ModuleDebugFileChecksumFragment &Checksums, StringTable &Strings)
: ModuleDebugFragment(ModuleDebugFragmentKind::Lines),
Checksums(Checksums) {}
DebugLinesSubsection::DebugLinesSubsection(DebugChecksumsSubsection &Checksums,
DebugStringTableSubsection &Strings)
: DebugSubsection(DebugSubsectionKind::Lines), Checksums(Checksums) {}
void ModuleDebugLineFragment::createBlock(StringRef FileName) {
void DebugLinesSubsection::createBlock(StringRef FileName) {
uint32_t Offset = Checksums.mapChecksumOffset(FileName);
Blocks.emplace_back(Offset);
}
void ModuleDebugLineFragment::addLineInfo(uint32_t Offset,
const LineInfo &Line) {
void DebugLinesSubsection::addLineInfo(uint32_t Offset, const LineInfo &Line) {
Block &B = Blocks.back();
LineNumberEntry LNE;
LNE.Flags = Line.getRawData();
@ -87,10 +85,10 @@ void ModuleDebugLineFragment::addLineInfo(uint32_t Offset,
B.Lines.push_back(LNE);
}
void ModuleDebugLineFragment::addLineAndColumnInfo(uint32_t Offset,
const LineInfo &Line,
uint32_t ColStart,
uint32_t ColEnd) {
void DebugLinesSubsection::addLineAndColumnInfo(uint32_t Offset,
const LineInfo &Line,
uint32_t ColStart,
uint32_t ColEnd) {
Block &B = Blocks.back();
assert(B.Lines.size() == B.Columns.size());
@ -101,7 +99,7 @@ void ModuleDebugLineFragment::addLineAndColumnInfo(uint32_t Offset,
B.Columns.push_back(CNE);
}
Error ModuleDebugLineFragment::commit(BinaryStreamWriter &Writer) {
Error DebugLinesSubsection::commit(BinaryStreamWriter &Writer) const {
LineFragmentHeader Header;
Header.CodeSize = CodeSize;
Header.Flags = hasColumnInfo() ? LF_HaveColumns : 0;
@ -135,7 +133,7 @@ Error ModuleDebugLineFragment::commit(BinaryStreamWriter &Writer) {
return Error::success();
}
uint32_t ModuleDebugLineFragment::calculateSerializedLength() {
uint32_t DebugLinesSubsection::calculateSerializedSize() const {
uint32_t Size = sizeof(LineFragmentHeader);
for (const auto &B : Blocks) {
Size += sizeof(LineBlockFragmentHeader);
@ -146,16 +144,16 @@ uint32_t ModuleDebugLineFragment::calculateSerializedLength() {
return Size;
}
void ModuleDebugLineFragment::setRelocationAddress(uint16_t Segment,
uint16_t Offset) {
void DebugLinesSubsection::setRelocationAddress(uint16_t Segment,
uint16_t Offset) {
RelocOffset = Offset;
RelocSegment = Segment;
}
void ModuleDebugLineFragment::setCodeSize(uint32_t Size) { CodeSize = Size; }
void DebugLinesSubsection::setCodeSize(uint32_t Size) { CodeSize = Size; }
void ModuleDebugLineFragment::setFlags(LineFlags Flags) { this->Flags = Flags; }
void DebugLinesSubsection::setFlags(LineFlags Flags) { this->Flags = Flags; }
bool ModuleDebugLineFragment::hasColumnInfo() const {
bool DebugLinesSubsection::hasColumnInfo() const {
return Flags & LF_HaveColumns;
}

View File

@ -1,4 +1,4 @@
//===- StringTable.cpp - CodeView String Table Reader/Writer ----*- C++ -*-===//
//===- DebugStringTableSubsection.cpp - CodeView String Table ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/StringTable.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/Support/BinaryStream.h"
#include "llvm/Support/BinaryStreamReader.h"
@ -16,14 +16,16 @@
using namespace llvm;
using namespace llvm::codeview;
StringTableRef::StringTableRef() {}
DebugStringTableSubsectionRef::DebugStringTableSubsectionRef()
: DebugSubsectionRef(DebugSubsectionKind::StringTable) {}
Error StringTableRef::initialize(BinaryStreamRef Contents) {
Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) {
Stream = Contents;
return Error::success();
}
Expected<StringRef> StringTableRef::getString(uint32_t Offset) const {
Expected<StringRef>
DebugStringTableSubsectionRef::getString(uint32_t Offset) const {
BinaryStreamReader Reader(Stream);
Reader.setOffset(Offset);
StringRef Result;
@ -32,7 +34,10 @@ Expected<StringRef> StringTableRef::getString(uint32_t Offset) const {
return Result;
}
uint32_t StringTable::insert(StringRef S) {
DebugStringTableSubsection::DebugStringTableSubsection()
: DebugSubsection(DebugSubsectionKind::StringTable) {}
uint32_t DebugStringTableSubsection::insert(StringRef S) {
auto P = Strings.insert({S, StringSize});
// If a given string didn't exist in the string table, we want to increment
@ -42,9 +47,11 @@ uint32_t StringTable::insert(StringRef S) {
return P.first->second;
}
uint32_t StringTable::calculateSerializedSize() const { return StringSize; }
uint32_t DebugStringTableSubsection::calculateSerializedSize() const {
return StringSize;
}
Error StringTable::commit(BinaryStreamWriter &Writer) const {
Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
assert(Writer.bytesRemaining() == StringSize);
uint32_t MaxOffset = 1;
@ -62,9 +69,9 @@ Error StringTable::commit(BinaryStreamWriter &Writer) const {
return Error::success();
}
uint32_t StringTable::size() const { return Strings.size(); }
uint32_t DebugStringTableSubsection::size() const { return Strings.size(); }
uint32_t StringTable::getStringId(StringRef S) const {
uint32_t DebugStringTableSubsection::getStringId(StringRef S) const {
auto P = Strings.find(S);
assert(P != Strings.end());
return P->second;

View File

@ -1,4 +1,4 @@
//===- ModuleDebugFragment.cpp -----------------------------------*- C++-*-===//
//===- DebugSubsection.cpp -----------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
using namespace llvm::codeview;
ModuleDebugFragmentRef::~ModuleDebugFragmentRef() {}
DebugSubsectionRef::~DebugSubsectionRef() {}
ModuleDebugFragment::~ModuleDebugFragment() {}
DebugSubsection::~DebugSubsection() {}

View File

@ -0,0 +1,81 @@
//===- DebugSubsectionRecord.cpp -----------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/Support/BinaryStreamReader.h"
using namespace llvm;
using namespace llvm::codeview;
DebugSubsectionRecord::DebugSubsectionRecord()
: Kind(DebugSubsectionKind::None) {}
DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind,
BinaryStreamRef Data)
: Kind(Kind), Data(Data) {}
Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream,
DebugSubsectionRecord &Info) {
const DebugSubsectionHeader *Header;
BinaryStreamReader Reader(Stream);
if (auto EC = Reader.readObject(Header))
return EC;
DebugSubsectionKind Kind =
static_cast<DebugSubsectionKind>(uint32_t(Header->Kind));
switch (Kind) {
case DebugSubsectionKind::FileChecksums:
case DebugSubsectionKind::Lines:
case DebugSubsectionKind::InlineeLines:
break;
default:
llvm_unreachable("Unexpected debug fragment kind!");
}
if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))
return EC;
Info.Kind = Kind;
return Error::success();
}
uint32_t DebugSubsectionRecord::getRecordLength() const {
uint32_t Result = sizeof(DebugSubsectionHeader) + Data.getLength();
assert(Result % 4 == 0);
return Result;
}
DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; }
BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; }
DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
DebugSubsectionKind Kind, DebugSubsection &Frag)
: Kind(Kind), Frag(Frag) {}
uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() {
uint32_t Size = sizeof(DebugSubsectionHeader) +
alignTo(Frag.calculateSerializedSize(), 4);
return Size;
}
Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) {
DebugSubsectionHeader Header;
Header.Kind = uint32_t(Kind);
Header.Length = calculateSerializedLength() - sizeof(DebugSubsectionHeader);
if (auto EC = Writer.writeObject(Header))
return EC;
if (auto EC = Frag.commit(Writer))
return EC;
if (auto EC = Writer.padToAlignment(4))
return EC;
return Error::success();
}

View File

@ -0,0 +1,52 @@
//===- DebugSubsectionVisitor.cpp ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamRef.h"
using namespace llvm;
using namespace llvm::codeview;
Error llvm::codeview::visitDebugSubsection(const DebugSubsectionRecord &R,
DebugSubsectionVisitor &V) {
BinaryStreamReader Reader(R.getRecordData());
switch (R.kind()) {
case DebugSubsectionKind::Lines: {
DebugLinesSubsectionRef Fragment;
if (auto EC = Fragment.initialize(Reader))
return EC;
return V.visitLines(Fragment);
}
case DebugSubsectionKind::FileChecksums: {
DebugChecksumsSubsectionRef Fragment;
if (auto EC = Fragment.initialize(Reader))
return EC;
return V.visitFileChecksums(Fragment);
}
case DebugSubsectionKind::InlineeLines: {
DebugInlineeLinesSubsectionRef Fragment;
if (auto EC = Fragment.initialize(Reader))
return EC;
return V.visitInlineeLines(Fragment);
}
default: {
DebugUnknownSubsectionRef Fragment(R.kind(), R.getRecordData());
return V.visitUnknown(Fragment);
}
}
}

View File

@ -0,0 +1,34 @@
//===- DebugSymbolsSubsection.cpp -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
using namespace llvm;
using namespace llvm::codeview;
Error DebugSymbolsSubsectionRef::initialize(BinaryStreamReader Reader) {
return Reader.readArray(Records, Reader.getLength());
}
uint32_t DebugSymbolsSubsection::calculateSerializedSize() const {
return Length;
}
Error DebugSymbolsSubsection::commit(BinaryStreamWriter &Writer) const {
for (const auto &Record : Records) {
if (auto EC = Writer.writeBytes(Record.RecordData))
return EC;
}
return Error::success();
}
void DebugSymbolsSubsection::addSymbol(CVSymbol Symbol) {
Records.push_back(Symbol);
Length += Symbol.length();
}

View File

@ -245,20 +245,20 @@ static const EnumEntry<uint32_t> FrameProcSymFlagNames[] = {
};
static const EnumEntry<uint32_t> ModuleSubstreamKindNames[] = {
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, None),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, Symbols),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, Lines),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, StringTable),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, FileChecksums),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, FrameData),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, InlineeLines),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, CrossScopeImports),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, CrossScopeExports),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, ILLines),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, FuncMDTokenMap),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, TypeMDTokenMap),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, MergedAssemblyInput),
CV_ENUM_CLASS_ENT(ModuleDebugFragmentKind, CoffSymbolRVA),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, None),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, Symbols),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, Lines),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, StringTable),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, FileChecksums),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, FrameData),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, InlineeLines),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeImports),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeExports),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, ILLines),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, FuncMDTokenMap),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, TypeMDTokenMap),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, MergedAssemblyInput),
CV_ENUM_CLASS_ENT(DebugSubsectionKind, CoffSymbolRVA),
};
static const EnumEntry<uint16_t> ExportSymFlagNames[] = {

View File

@ -1,84 +0,0 @@
//===- ModuleDebugFragmentRecord.cpp -----------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/Support/BinaryStreamReader.h"
using namespace llvm;
using namespace llvm::codeview;
ModuleDebugFragmentRecord::ModuleDebugFragmentRecord()
: Kind(ModuleDebugFragmentKind::None) {}
ModuleDebugFragmentRecord::ModuleDebugFragmentRecord(
ModuleDebugFragmentKind Kind, BinaryStreamRef Data)
: Kind(Kind), Data(Data) {}
Error ModuleDebugFragmentRecord::initialize(BinaryStreamRef Stream,
ModuleDebugFragmentRecord &Info) {
const ModuleDebugFragmentHeader *Header;
BinaryStreamReader Reader(Stream);
if (auto EC = Reader.readObject(Header))
return EC;
ModuleDebugFragmentKind Kind =
static_cast<ModuleDebugFragmentKind>(uint32_t(Header->Kind));
switch (Kind) {
case ModuleDebugFragmentKind::FileChecksums:
case ModuleDebugFragmentKind::Lines:
case ModuleDebugFragmentKind::InlineeLines:
break;
default:
llvm_unreachable("Unexpected debug fragment kind!");
}
if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))
return EC;
Info.Kind = Kind;
return Error::success();
}
uint32_t ModuleDebugFragmentRecord::getRecordLength() const {
uint32_t Result = sizeof(ModuleDebugFragmentHeader) + Data.getLength();
assert(Result % 4 == 0);
return Result;
}
ModuleDebugFragmentKind ModuleDebugFragmentRecord::kind() const { return Kind; }
BinaryStreamRef ModuleDebugFragmentRecord::getRecordData() const {
return Data;
}
ModuleDebugFragmentRecordBuilder::ModuleDebugFragmentRecordBuilder(
ModuleDebugFragmentKind Kind, ModuleDebugFragment &Frag)
: Kind(Kind), Frag(Frag) {}
uint32_t ModuleDebugFragmentRecordBuilder::calculateSerializedLength() {
uint32_t Size = sizeof(ModuleDebugFragmentHeader) +
alignTo(Frag.calculateSerializedLength(), 4);
return Size;
}
Error ModuleDebugFragmentRecordBuilder::commit(BinaryStreamWriter &Writer) {
ModuleDebugFragmentHeader Header;
Header.Kind = uint32_t(Kind);
Header.Length =
calculateSerializedLength() - sizeof(ModuleDebugFragmentHeader);
if (auto EC = Writer.writeObject(Header))
return EC;
if (auto EC = Frag.commit(Writer))
return EC;
if (auto EC = Writer.padToAlignment(4))
return EC;
return Error::success();
}

View File

@ -1,52 +0,0 @@
//===- ModuleDebugFragmentVisitor.cpp ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamRef.h"
using namespace llvm;
using namespace llvm::codeview;
Error llvm::codeview::visitModuleDebugFragment(
const ModuleDebugFragmentRecord &R, ModuleDebugFragmentVisitor &V) {
BinaryStreamReader Reader(R.getRecordData());
switch (R.kind()) {
case ModuleDebugFragmentKind::Lines: {
ModuleDebugLineFragmentRef Fragment;
if (auto EC = Fragment.initialize(Reader))
return EC;
return V.visitLines(Fragment);
}
case ModuleDebugFragmentKind::FileChecksums: {
ModuleDebugFileChecksumFragmentRef Fragment;
if (auto EC = Fragment.initialize(Reader))
return EC;
return V.visitFileChecksums(Fragment);
}
case ModuleDebugFragmentKind::InlineeLines: {
ModuleDebugInlineeLineFragmentRef Fragment;
if (auto EC = Fragment.initialize(Reader))
return EC;
return V.visitInlineeLines(Fragment);
}
default: {
ModuleDebugUnknownFragmentRef Fragment(R.kind(), R.getRecordData());
return V.visitUnknown(Fragment);
}
}
}

View File

@ -11,8 +11,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/DebugInfo/CodeView/StringTable.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
@ -369,7 +369,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(
DictScope S(W, "DefRangeSubfield");
if (ObjDelegate) {
StringTableRef Strings = ObjDelegate->getStringTable();
DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
if (!ExpectedProgram) {
consumeError(ExpectedProgram.takeError());
@ -390,7 +390,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
DictScope S(W, "DefRange");
if (ObjDelegate) {
StringTableRef Strings = ObjDelegate->getStringTable();
DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
auto ExpectedProgram = Strings.getString(DefRange.Program);
if (!ExpectedProgram) {
consumeError(ExpectedProgram.takeError());

View File

@ -10,7 +10,7 @@
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
@ -170,8 +170,8 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
}
void DbiModuleDescriptorBuilder::addC13Fragment(
std::unique_ptr<ModuleDebugLineFragment> Lines) {
ModuleDebugLineFragment &Frag = *Lines;
std::unique_ptr<DebugLinesSubsection> Lines) {
DebugLinesSubsection &Frag = *Lines;
// File Checksums have to come first, so push an empty entry on if this
// is the first.
@ -180,12 +180,12 @@ void DbiModuleDescriptorBuilder::addC13Fragment(
this->LineInfo.push_back(std::move(Lines));
C13Builders.push_back(
llvm::make_unique<ModuleDebugFragmentRecordBuilder>(Frag.kind(), Frag));
llvm::make_unique<DebugSubsectionRecordBuilder>(Frag.kind(), Frag));
}
void DbiModuleDescriptorBuilder::addC13Fragment(
std::unique_ptr<codeview::ModuleDebugInlineeLineFragment> Inlinees) {
ModuleDebugInlineeLineFragment &Frag = *Inlinees;
std::unique_ptr<codeview::DebugInlineeLinesSubsection> Inlinees) {
DebugInlineeLinesSubsection &Frag = *Inlinees;
// File Checksums have to come first, so push an empty entry on if this
// is the first.
@ -194,17 +194,17 @@ void DbiModuleDescriptorBuilder::addC13Fragment(
this->Inlinees.push_back(std::move(Inlinees));
C13Builders.push_back(
llvm::make_unique<ModuleDebugFragmentRecordBuilder>(Frag.kind(), Frag));
llvm::make_unique<DebugSubsectionRecordBuilder>(Frag.kind(), Frag));
}
void DbiModuleDescriptorBuilder::setC13FileChecksums(
std::unique_ptr<ModuleDebugFileChecksumFragment> Checksums) {
std::unique_ptr<DebugChecksumsSubsection> Checksums) {
assert(!ChecksumInfo && "Can't have more than one checksum info!");
if (C13Builders.empty())
C13Builders.push_back(nullptr);
ChecksumInfo = std::move(Checksums);
C13Builders[0] = llvm::make_unique<ModuleDebugFragmentRecordBuilder>(
C13Builders[0] = llvm::make_unique<DebugSubsectionRecordBuilder>(
ChecksumInfo->kind(), *ChecksumInfo);
}

View File

@ -145,7 +145,7 @@ void CodeViewContext::emitStringTable(MCObjectStreamer &OS) {
MCSymbol *StringBegin = Ctx.createTempSymbol("strtab_begin", false),
*StringEnd = Ctx.createTempSymbol("strtab_end", false);
OS.EmitIntValue(unsigned(ModuleDebugFragmentKind::StringTable), 4);
OS.EmitIntValue(unsigned(DebugSubsectionKind::StringTable), 4);
OS.emitAbsoluteSymbolDiff(StringEnd, StringBegin, 4);
OS.EmitLabel(StringBegin);
@ -172,7 +172,7 @@ void CodeViewContext::emitFileChecksums(MCObjectStreamer &OS) {
MCSymbol *FileBegin = Ctx.createTempSymbol("filechecksums_begin", false),
*FileEnd = Ctx.createTempSymbol("filechecksums_end", false);
OS.EmitIntValue(unsigned(ModuleDebugFragmentKind::FileChecksums), 4);
OS.EmitIntValue(unsigned(DebugSubsectionKind::FileChecksums), 4);
OS.emitAbsoluteSymbolDiff(FileEnd, FileBegin, 4);
OS.EmitLabel(FileBegin);
@ -197,7 +197,7 @@ void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
MCSymbol *LineBegin = Ctx.createTempSymbol("linetable_begin", false),
*LineEnd = Ctx.createTempSymbol("linetable_end", false);
OS.EmitIntValue(unsigned(ModuleDebugFragmentKind::Lines), 4);
OS.EmitIntValue(unsigned(DebugSubsectionKind::Lines), 4);
OS.emitAbsoluteSymbolDiff(LineEnd, LineBegin, 4);
OS.EmitLabel(LineBegin);
OS.EmitCOFFSecRel32(FuncBegin, /*Offset=*/0);

View File

@ -1559,11 +1559,13 @@ IEEEFloat::opStatus IEEEFloat::divideSpecials(const IEEEFloat &rhs) {
case PackCategoriesIntoKey(fcInfinity, fcNaN):
category = fcNaN;
copySignificand(rhs);
LLVM_FALLTHROUGH;
case PackCategoriesIntoKey(fcNaN, fcZero):
case PackCategoriesIntoKey(fcNaN, fcNormal):
case PackCategoriesIntoKey(fcNaN, fcInfinity):
case PackCategoriesIntoKey(fcNaN, fcNaN):
sign = false;
LLVM_FALLTHROUGH;
case PackCategoriesIntoKey(fcInfinity, fcZero):
case PackCategoriesIntoKey(fcInfinity, fcNormal):
case PackCategoriesIntoKey(fcZero, fcInfinity):

View File

@ -72,10 +72,15 @@ std::unique_ptr<raw_fd_ostream> llvm::CreateInfoOutputFile() {
return llvm::make_unique<raw_fd_ostream>(2, false); // stderr.
}
static TimerGroup *getDefaultTimerGroup() {
static TimerGroup DefaultTimerGroup("misc", "Miscellaneous Ungrouped Timers");
return &DefaultTimerGroup;
}
namespace {
struct CreateDefaultTimerGroup {
static void *call() {
return new TimerGroup("misc", "Miscellaneous Ungrouped Timers");
}
};
} // namespace
static ManagedStatic<TimerGroup, CreateDefaultTimerGroup> DefaultTimerGroup;
static TimerGroup *getDefaultTimerGroup() { return &*DefaultTimerGroup; }
//===----------------------------------------------------------------------===//
// Timer Implementation

View File

@ -405,27 +405,21 @@ IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
}
CodeInit *CodeInit::get(StringRef V) {
static DenseMap<StringRef, CodeInit*> ThePool;
static StringMap<CodeInit*, BumpPtrAllocator &> ThePool(Allocator);
auto I = ThePool.insert(std::make_pair(V, nullptr));
if (I.second) {
StringRef VCopy = V.copy(Allocator);
I.first->first = VCopy;
I.first->second = new(Allocator) CodeInit(VCopy);
}
return I.first->second;
auto &Entry = *ThePool.insert(std::make_pair(V, nullptr)).first;
if (!Entry.second)
Entry.second = new(Allocator) CodeInit(Entry.getKey());
return Entry.second;
}
StringInit *StringInit::get(StringRef V) {
static DenseMap<StringRef, StringInit*> ThePool;
static StringMap<StringInit*, BumpPtrAllocator &> ThePool(Allocator);
auto I = ThePool.insert(std::make_pair(V, nullptr));
if (I.second) {
StringRef VCopy = V.copy(Allocator);
I.first->first = VCopy;
I.first->second = new(Allocator) StringInit(VCopy);
}
return I.first->second;
auto &Entry = *ThePool.insert(std::make_pair(V, nullptr)).first;
if (!Entry.second)
Entry.second = new(Allocator) StringInit(Entry.getKey());
return Entry.second;
}
Init *StringInit::convertInitializerTo(RecTy *Ty) const {
@ -1540,7 +1534,7 @@ Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) const {
SmallVector<Init*, 8> NewArgs;
NewArgs.reserve(arg_size());
bool ArgsChanged = false;
for (const Init *Arg : args()) {
for (const Init *Arg : getArgs()) {
Init *NewArg = Arg->resolveReferences(R, RV);
NewArgs.push_back(NewArg);
ArgsChanged |= NewArg != Arg;

View File

@ -137,6 +137,34 @@ static cl::opt<bool> EnableRedZone("aarch64-redzone",
STATISTIC(NumRedZoneFunctions, "Number of functions using red zone");
/// Look at each instruction that references stack frames and return the stack
/// size limit beyond which some of these instructions will require a scratch
/// register during their expansion later.
static unsigned estimateRSStackSizeLimit(MachineFunction &MF) {
// FIXME: For now, just conservatively guestimate based on unscaled indexing
// range. We'll end up allocating an unnecessary spill slot a lot, but
// realistically that's not a big deal at this stage of the game.
for (MachineBasicBlock &MBB : MF) {
for (MachineInstr &MI : MBB) {
if (MI.isDebugValue() || MI.isPseudo() ||
MI.getOpcode() == AArch64::ADDXri ||
MI.getOpcode() == AArch64::ADDSXri)
continue;
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
if (!MI.getOperand(i).isFI())
continue;
int Offset = 0;
if (isAArch64FrameOffsetLegal(MI, Offset, nullptr, nullptr, nullptr) ==
AArch64FrameOffsetCannotUpdate)
return 0;
}
}
}
return 255;
}
bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
if (!EnableRedZone)
return false;
@ -1169,16 +1197,13 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF,
unsigned NumRegsSpilled = SavedRegs.count();
bool CanEliminateFrame = NumRegsSpilled == 0;
// FIXME: Set BigStack if any stack slot references may be out of range.
// For now, just conservatively guestimate based on unscaled indexing
// range. We'll end up allocating an unnecessary spill slot a lot, but
// realistically that's not a big deal at this stage of the game.
// The CSR spill slots have not been allocated yet, so estimateStackSize
// won't include them.
MachineFrameInfo &MFI = MF.getFrameInfo();
unsigned CFSize = MFI.estimateStackSize(MF) + 8 * NumRegsSpilled;
DEBUG(dbgs() << "Estimated stack frame size: " << CFSize << " bytes.\n");
bool BigStack = (CFSize >= 256);
unsigned EstimatedStackSizeLimit = estimateRSStackSizeLimit(MF);
bool BigStack = (CFSize > EstimatedStackSizeLimit);
if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF))
AFI->setHasStackFrame(true);

View File

@ -381,7 +381,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FNEARBYINT, MVT::v4f16, Expand);
setOperationAction(ISD::FNEG, MVT::v4f16, Expand);
setOperationAction(ISD::FPOW, MVT::v4f16, Expand);
setOperationAction(ISD::FPOWI, MVT::v4f16, Expand);
setOperationAction(ISD::FREM, MVT::v4f16, Expand);
setOperationAction(ISD::FROUND, MVT::v4f16, Expand);
setOperationAction(ISD::FRINT, MVT::v4f16, Expand);
@ -413,7 +412,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FNEARBYINT, MVT::v8f16, Expand);
setOperationAction(ISD::FNEG, MVT::v8f16, Expand);
setOperationAction(ISD::FPOW, MVT::v8f16, Expand);
setOperationAction(ISD::FPOWI, MVT::v8f16, Expand);
setOperationAction(ISD::FREM, MVT::v8f16, Expand);
setOperationAction(ISD::FROUND, MVT::v8f16, Expand);
setOperationAction(ISD::FRINT, MVT::v8f16, Expand);
@ -726,7 +724,6 @@ void AArch64TargetLowering::addTypeForNEON(MVT VT, MVT PromotedBitwiseVT) {
if (VT == MVT::v2f32 || VT == MVT::v4f32 || VT == MVT::v2f64) {
setOperationAction(ISD::FSIN, VT, Expand);
setOperationAction(ISD::FCOS, VT, Expand);
setOperationAction(ISD::FPOWI, VT, Expand);
setOperationAction(ISD::FPOW, VT, Expand);
setOperationAction(ISD::FLOG, VT, Expand);
setOperationAction(ISD::FLOG2, VT, Expand);

View File

@ -730,7 +730,7 @@ class SISubtarget final : public AMDGPUSubtarget {
/// \returns True if waitcnt instruction is needed before barrier instruction,
/// false otherwise.
bool needWaitcntBeforeBarrier() const {
return getGeneration() < GFX9;
return true;
}
/// \returns true if the flat_scratch register should be initialized with the

View File

@ -736,6 +736,9 @@ void GCNPassConfig::addMachineSSAOptimization() {
addPass(createSIShrinkInstructionsPass());
if (EnableSDWAPeephole) {
addPass(&SIPeepholeSDWAID);
addPass(&MachineLICMID);
addPass(&MachineCSEID);
addPass(&SIFoldOperandsID);
addPass(&DeadMachineInstructionElimID);
}
}

View File

@ -247,9 +247,10 @@ static bool tryAddToFoldList(SmallVectorImpl<FoldCandidate> &FoldList,
// If the use operand doesn't care about the value, this may be an operand only
// used for register indexing, in which case it is unsafe to fold.
static bool isUseSafeToFold(const MachineInstr &MI,
static bool isUseSafeToFold(const SIInstrInfo *TII,
const MachineInstr &MI,
const MachineOperand &UseMO) {
return !UseMO.isUndef();
return !UseMO.isUndef() && !TII->isSDWA(MI);
//return !MI.hasRegisterImplicitUseOperand(UseMO.getReg());
}
@ -261,7 +262,7 @@ void SIFoldOperands::foldOperand(
SmallVectorImpl<MachineInstr *> &CopiesToReplace) const {
const MachineOperand &UseOp = UseMI->getOperand(UseOpIdx);
if (!isUseSafeToFold(*UseMI, UseOp))
if (!isUseSafeToFold(TII, *UseMI, UseOp))
return;
// FIXME: Fold operands with subregs.

View File

@ -55,6 +55,7 @@ class SIPeepholeSDWA : public MachineFunctionPass {
std::unordered_map<MachineInstr *, std::unique_ptr<SDWAOperand>> SDWAOperands;
std::unordered_map<MachineInstr *, SDWAOperandsVector> PotentialMatches;
SmallVector<MachineInstr *, 8> ConvertedInstructions;
Optional<int64_t> foldToImm(const MachineOperand &Op) const;
@ -69,6 +70,7 @@ class SIPeepholeSDWA : public MachineFunctionPass {
void matchSDWAOperands(MachineFunction &MF);
bool isConvertibleToSDWA(const MachineInstr &MI) const;
bool convertToSDWA(MachineInstr &MI, const SDWAOperandsVector &SDWAOperands);
void legalizeScalarOperands(MachineInstr &MI) const;
StringRef getPassName() const override { return "SI Peephole SDWA"; }
@ -289,7 +291,7 @@ bool SDWASrcOperand::convertToSDWA(MachineInstr &MI, const SIInstrInfo *TII) {
MachineOperand *SrcSel = TII->getNamedOperand(MI, AMDGPU::OpName::src0_sel);
MachineOperand *SrcMods =
TII->getNamedOperand(MI, AMDGPU::OpName::src0_modifiers);
assert(Src && Src->isReg());
assert(Src && (Src->isReg() || Src->isImm()));
if (!isSameReg(*Src, *getReplacedOperand())) {
// If this is not src0 then it should be src1
Src = TII->getNamedOperand(MI, AMDGPU::OpName::src1);
@ -580,18 +582,8 @@ void SIPeepholeSDWA::matchSDWAOperands(MachineFunction &MF) {
}
bool SIPeepholeSDWA::isConvertibleToSDWA(const MachineInstr &MI) const {
// Check if this instruction can be converted to SDWA:
// 1. Does this opcode support SDWA
if (AMDGPU::getSDWAOp(MI.getOpcode()) == -1)
return false;
// 2. Are all operands - VGPRs
for (const MachineOperand &Operand : MI.explicit_operands()) {
if (!Operand.isReg() || !TRI->isVGPR(*MRI, Operand.getReg()))
return false;
}
return true;
// Check if this instruction has opcode that supports SDWA
return AMDGPU::getSDWAOp(MI.getOpcode()) != -1;
}
bool SIPeepholeSDWA::convertToSDWA(MachineInstr &MI,
@ -685,7 +677,9 @@ bool SIPeepholeSDWA::convertToSDWA(MachineInstr &MI,
if (PotentialMatches.count(Operand->getParentInst()) == 0)
Converted |= Operand->convertToSDWA(*SDWAInst, TII);
}
if (!Converted) {
if (Converted) {
ConvertedInstructions.push_back(SDWAInst);
} else {
SDWAInst->eraseFromParent();
return false;
}
@ -698,6 +692,29 @@ bool SIPeepholeSDWA::convertToSDWA(MachineInstr &MI,
return true;
}
// If an instruction was converted to SDWA it should not have immediates or SGPR
// operands. Copy its scalar operands into VGPRs.
void SIPeepholeSDWA::legalizeScalarOperands(MachineInstr &MI) const {
const MCInstrDesc &Desc = TII->get(MI.getOpcode());
for (unsigned I = 0, E = MI.getNumExplicitOperands(); I != E; ++I) {
MachineOperand &Op = MI.getOperand(I);
if (!Op.isImm() && !(Op.isReg() && !TRI->isVGPR(*MRI, Op.getReg())))
continue;
if (Desc.OpInfo[I].RegClass == -1 ||
!TRI->hasVGPRs(TRI->getRegClass(Desc.OpInfo[I].RegClass)))
continue;
unsigned VGPR = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
auto Copy = BuildMI(*MI.getParent(), MI.getIterator(), MI.getDebugLoc(),
TII->get(AMDGPU::V_MOV_B32_e32), VGPR);
if (Op.isImm())
Copy.addImm(Op.getImm());
else if (Op.isReg())
Copy.addReg(Op.getReg(), Op.isKill() ? RegState::Kill : 0,
Op.getSubReg());
Op.ChangeToRegister(VGPR, false);
}
}
bool SIPeepholeSDWA::runOnMachineFunction(MachineFunction &MF) {
const SISubtarget &ST = MF.getSubtarget<SISubtarget>();
@ -728,5 +745,9 @@ bool SIPeepholeSDWA::runOnMachineFunction(MachineFunction &MF) {
PotentialMatches.clear();
SDWAOperands.clear();
while (!ConvertedInstructions.empty())
legalizeScalarOperands(*ConvertedInstructions.pop_back_val());
return false;
}

View File

@ -585,7 +585,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FSQRT, MVT::v2f64, Expand);
setOperationAction(ISD::FSIN, MVT::v2f64, Expand);
setOperationAction(ISD::FCOS, MVT::v2f64, Expand);
setOperationAction(ISD::FPOWI, MVT::v2f64, Expand);
setOperationAction(ISD::FPOW, MVT::v2f64, Expand);
setOperationAction(ISD::FLOG, MVT::v2f64, Expand);
setOperationAction(ISD::FLOG2, MVT::v2f64, Expand);
@ -603,7 +602,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FSQRT, MVT::v4f32, Expand);
setOperationAction(ISD::FSIN, MVT::v4f32, Expand);
setOperationAction(ISD::FCOS, MVT::v4f32, Expand);
setOperationAction(ISD::FPOWI, MVT::v4f32, Expand);
setOperationAction(ISD::FPOW, MVT::v4f32, Expand);
setOperationAction(ISD::FLOG, MVT::v4f32, Expand);
setOperationAction(ISD::FLOG2, MVT::v4f32, Expand);
@ -620,7 +618,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FSQRT, MVT::v2f32, Expand);
setOperationAction(ISD::FSIN, MVT::v2f32, Expand);
setOperationAction(ISD::FCOS, MVT::v2f32, Expand);
setOperationAction(ISD::FPOWI, MVT::v2f32, Expand);
setOperationAction(ISD::FPOW, MVT::v2f32, Expand);
setOperationAction(ISD::FLOG, MVT::v2f32, Expand);
setOperationAction(ISD::FLOG2, MVT::v2f32, Expand);
@ -743,7 +740,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FSQRT, MVT::f64, Expand);
setOperationAction(ISD::FSIN, MVT::f64, Expand);
setOperationAction(ISD::FCOS, MVT::f64, Expand);
setOperationAction(ISD::FPOWI, MVT::f64, Expand);
setOperationAction(ISD::FPOW, MVT::f64, Expand);
setOperationAction(ISD::FLOG, MVT::f64, Expand);
setOperationAction(ISD::FLOG2, MVT::f64, Expand);

View File

@ -2003,7 +2003,7 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
// Floating point arithmetic/math functions:
ISD::FADD, ISD::FSUB, ISD::FMUL, ISD::FMA, ISD::FDIV,
ISD::FREM, ISD::FNEG, ISD::FABS, ISD::FSQRT, ISD::FSIN,
ISD::FCOS, ISD::FPOWI, ISD::FPOW, ISD::FLOG, ISD::FLOG2,
ISD::FCOS, ISD::FPOW, ISD::FLOG, ISD::FLOG2,
ISD::FLOG10, ISD::FEXP, ISD::FEXP2, ISD::FCEIL, ISD::FTRUNC,
ISD::FRINT, ISD::FNEARBYINT, ISD::FROUND, ISD::FFLOOR,
ISD::FMINNUM, ISD::FMAXNUM, ISD::FSINCOS,

View File

@ -13,6 +13,7 @@
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "MipsTargetStreamer.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
@ -216,9 +217,15 @@ class MipsAsmParser : public MCTargetAsmParser {
unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
MCStreamer &Out, const MCSubtargetInfo *STI);
bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
MCStreamer &Out, const MCSubtargetInfo *STI);
bool expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR, bool Is64FPU,
SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
const MCOperand &Offset, bool Is32BitAddress,
SMLoc IDLoc, MCStreamer &Out,
@ -1011,6 +1018,16 @@ class MipsOperand : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
}
void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
}
void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
}
void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
@ -1027,6 +1044,15 @@ class MipsOperand : public MCParsedAsmOperand {
"registers");
}
void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
// FIXME: We ought to do this for -integrated-as without -via-file-asm too.
if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
"registers");
}
void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
@ -1574,6 +1600,11 @@ class MipsOperand : public MCParsedAsmOperand {
return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
}
bool isStrictlyFGRAsmReg() const {
// AFGR64 is $0-$15 but we handle this in getAFGR64()
return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
}
bool isHWRegsAsmReg() const {
return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
}
@ -2368,6 +2399,27 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
case Mips::PseudoTRUNC_W_D:
return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
: MER_Success;
case Mips::LoadImmSingleGPR:
return expandLoadImmReal(Inst, true, true, false, IDLoc, Out, STI)
? MER_Fail
: MER_Success;
case Mips::LoadImmSingleFGR:
return expandLoadImmReal(Inst, true, false, false, IDLoc, Out, STI)
? MER_Fail
: MER_Success;
case Mips::LoadImmDoubleGPR:
return expandLoadImmReal(Inst, false, true, false, IDLoc, Out, STI)
? MER_Fail
: MER_Success;
case Mips::LoadImmDoubleFGR:
return expandLoadImmReal(Inst, false, false, true, IDLoc, Out, STI)
? MER_Fail
: MER_Success;
case Mips::LoadImmDoubleFGR_32:
return expandLoadImmReal(Inst, false, false, false, IDLoc, Out, STI)
? MER_Fail
: MER_Success;
case Mips::Ulh:
return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::Ulhu:
@ -2952,6 +3004,302 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
return false;
}
// Each double-precision register DO-D15 overlaps with two of the single
// precision registers F0-F31. As an example, all of the following hold true:
// D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
static unsigned nextReg(unsigned Reg) {
if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
switch (Reg) {
default: llvm_unreachable("Unknown register in assembly macro expansion!");
case Mips::ZERO: return Mips::AT;
case Mips::AT: return Mips::V0;
case Mips::V0: return Mips::V1;
case Mips::V1: return Mips::A0;
case Mips::A0: return Mips::A1;
case Mips::A1: return Mips::A2;
case Mips::A2: return Mips::A3;
case Mips::A3: return Mips::T0;
case Mips::T0: return Mips::T1;
case Mips::T1: return Mips::T2;
case Mips::T2: return Mips::T3;
case Mips::T3: return Mips::T4;
case Mips::T4: return Mips::T5;
case Mips::T5: return Mips::T6;
case Mips::T6: return Mips::T7;
case Mips::T7: return Mips::S0;
case Mips::S0: return Mips::S1;
case Mips::S1: return Mips::S2;
case Mips::S2: return Mips::S3;
case Mips::S3: return Mips::S4;
case Mips::S4: return Mips::S5;
case Mips::S5: return Mips::S6;
case Mips::S6: return Mips::S7;
case Mips::S7: return Mips::T8;
case Mips::T8: return Mips::T9;
case Mips::T9: return Mips::K0;
case Mips::K0: return Mips::K1;
case Mips::K1: return Mips::GP;
case Mips::GP: return Mips::SP;
case Mips::SP: return Mips::FP;
case Mips::FP: return Mips::RA;
case Mips::RA: return Mips::ZERO;
case Mips::D0: return Mips::F1;
case Mips::D1: return Mips::F3;
case Mips::D2: return Mips::F5;
case Mips::D3: return Mips::F7;
case Mips::D4: return Mips::F9;
case Mips::D5: return Mips::F11;
case Mips::D6: return Mips::F13;
case Mips::D7: return Mips::F15;
case Mips::D8: return Mips::F17;
case Mips::D9: return Mips::F19;
case Mips::D10: return Mips::F21;
case Mips::D11: return Mips::F23;
case Mips::D12: return Mips::F25;
case Mips::D13: return Mips::F27;
case Mips::D14: return Mips::F29;
case Mips::D15: return Mips::F31;
}
}
// FIXME: This method is too general. In principle we should compute the number
// of instructions required to synthesize the immediate inline compared to
// synthesizing the address inline and relying on non .text sections.
// For static O32 and N32 this may yield a small benefit, for static N64 this is
// likely to yield a much larger benefit as we have to synthesize a 64bit
// address to load a 64 bit value.
bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
MCSymbol *Sym) {
unsigned ATReg = getATReg(IDLoc);
if (!ATReg)
return true;
if(IsPicEnabled) {
const MCExpr *GotSym =
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
const MipsMCExpr *GotExpr =
MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
if(isABI_O32() || isABI_N32()) {
TOut.emitRRX(Mips::LW, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
IDLoc, STI);
} else { //isABI_N64()
TOut.emitRRX(Mips::LD, ATReg, Mips::GP, MCOperand::createExpr(GotExpr),
IDLoc, STI);
}
} else { //!IsPicEnabled
const MCExpr *HiSym =
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
const MipsMCExpr *HiExpr =
MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
// FIXME: This is technically correct but gives a different result to gas,
// but gas is incomplete there (it has a fixme noting it doesn't work with
// 64-bit addresses).
// FIXME: With -msym32 option, the address expansion for N64 should probably
// use the O32 / N32 case. It's safe to use the 64 address expansion as the
// symbol's value is considered sign extended.
if(isABI_O32() || isABI_N32()) {
TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
} else { //isABI_N64()
const MCExpr *HighestSym =
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
const MipsMCExpr *HighestExpr =
MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
const MCExpr *HigherSym =
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
const MipsMCExpr *HigherExpr =
MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
STI);
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
MCOperand::createExpr(HigherExpr), IDLoc, STI);
TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
IDLoc, STI);
TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
}
}
return false;
}
bool MipsAsmParser::expandLoadImmReal(MCInst &Inst, bool IsSingle, bool IsGPR,
bool Is64FPU, SMLoc IDLoc,
MCStreamer &Out,
const MCSubtargetInfo *STI) {
MipsTargetStreamer &TOut = getTargetStreamer();
assert(Inst.getNumOperands() == 2 && "Invalid operand count");
assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
"Invalid instruction operand.");
unsigned FirstReg = Inst.getOperand(0).getReg();
uint64_t ImmOp64 = Inst.getOperand(1).getImm();
uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
// If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
// exponent field), convert it to double (e.g. 1 to 1.0)
if ((HiImmOp64 & 0x7ff00000) == 0) {
APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
}
uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
if (IsSingle) {
// Conversion of a double in an uint64_t to a float in a uint32_t,
// retaining the bit pattern of a float.
uint32_t ImmOp32;
double doubleImm = BitsToDouble(ImmOp64);
float tmp_float = static_cast<float>(doubleImm);
ImmOp32 = FloatToBits(tmp_float);
if (IsGPR) {
if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, true, IDLoc,
Out, STI))
return true;
return false;
} else {
unsigned ATReg = getATReg(IDLoc);
if (!ATReg)
return true;
if (LoImmOp64 == 0) {
if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister, true, true, IDLoc,
Out, STI))
return true;
TOut.emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
return false;
}
MCSection *CS = getStreamer().getCurrentSectionOnly();
// FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
// where appropriate.
MCSection *ReadOnlySection = getContext().getELFSection(
".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
MCSymbol *Sym = getContext().createTempSymbol();
const MCExpr *LoSym =
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
const MipsMCExpr *LoExpr =
MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
getStreamer().SwitchSection(ReadOnlySection);
getStreamer().EmitLabel(Sym, IDLoc);
getStreamer().EmitIntValue(ImmOp32, 4);
getStreamer().SwitchSection(CS);
if(emitPartialAddress(TOut, IDLoc, Sym))
return true;
TOut.emitRRX(Mips::LWC1, FirstReg, ATReg,
MCOperand::createExpr(LoExpr), IDLoc, STI);
}
return false;
}
// if(!IsSingle)
unsigned ATReg = getATReg(IDLoc);
if (!ATReg)
return true;
if (IsGPR) {
if (LoImmOp64 == 0) {
if(isABI_N32() || isABI_N64()) {
if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, false, true,
IDLoc, Out, STI))
return true;
return false;
} else {
if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister, true, true,
IDLoc, Out, STI))
return true;
if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, true,
IDLoc, Out, STI))
return true;
return false;
}
}
MCSection *CS = getStreamer().getCurrentSectionOnly();
MCSection *ReadOnlySection = getContext().getELFSection(
".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
MCSymbol *Sym = getContext().createTempSymbol();
const MCExpr *LoSym =
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
const MipsMCExpr *LoExpr =
MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
getStreamer().SwitchSection(ReadOnlySection);
getStreamer().EmitLabel(Sym, IDLoc);
getStreamer().EmitIntValue(HiImmOp64, 4);
getStreamer().EmitIntValue(LoImmOp64, 4);
getStreamer().SwitchSection(CS);
if(emitPartialAddress(TOut, IDLoc, Sym))
return true;
if(isABI_N64())
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
MCOperand::createExpr(LoExpr), IDLoc, STI);
else
TOut.emitRRX(Mips::ADDiu, ATReg, ATReg,
MCOperand::createExpr(LoExpr), IDLoc, STI);
if(isABI_N32() || isABI_N64())
TOut.emitRRI(Mips::LD, FirstReg, ATReg, 0, IDLoc, STI);
else {
TOut.emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
TOut.emitRRI(Mips::LW, nextReg(FirstReg), ATReg, 4, IDLoc, STI);
}
return false;
} else { // if(!IsGPR && !IsSingle)
if ((LoImmOp64 == 0) &&
!((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
// FIXME: In the case where the constant is zero, we can load the
// register directly from the zero register.
if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister, true, true, IDLoc,
Out, STI))
return true;
if (isABI_N32() || isABI_N64())
TOut.emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
else if (hasMips32r2()) {
TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
} else {
TOut.emitRR(Mips::MTC1, nextReg(FirstReg), ATReg, IDLoc, STI);
TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
}
return false;
}
MCSection *CS = getStreamer().getCurrentSectionOnly();
// FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
// where appropriate.
MCSection *ReadOnlySection = getContext().getELFSection(
".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
MCSymbol *Sym = getContext().createTempSymbol();
const MCExpr *LoSym =
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
const MipsMCExpr *LoExpr =
MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
getStreamer().SwitchSection(ReadOnlySection);
getStreamer().EmitLabel(Sym, IDLoc);
getStreamer().EmitIntValue(HiImmOp64, 4);
getStreamer().EmitIntValue(LoImmOp64, 4);
getStreamer().SwitchSection(CS);
if(emitPartialAddress(TOut, IDLoc, Sym))
return true;
TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
MCOperand::createExpr(LoExpr), IDLoc, STI);
}
return false;
}
bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
MCStreamer &Out,
const MCSubtargetInfo *STI) {
@ -4318,45 +4666,6 @@ bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return false;
}
static unsigned nextReg(unsigned Reg) {
switch (Reg) {
case Mips::ZERO: return Mips::AT;
case Mips::AT: return Mips::V0;
case Mips::V0: return Mips::V1;
case Mips::V1: return Mips::A0;
case Mips::A0: return Mips::A1;
case Mips::A1: return Mips::A2;
case Mips::A2: return Mips::A3;
case Mips::A3: return Mips::T0;
case Mips::T0: return Mips::T1;
case Mips::T1: return Mips::T2;
case Mips::T2: return Mips::T3;
case Mips::T3: return Mips::T4;
case Mips::T4: return Mips::T5;
case Mips::T5: return Mips::T6;
case Mips::T6: return Mips::T7;
case Mips::T7: return Mips::S0;
case Mips::S0: return Mips::S1;
case Mips::S1: return Mips::S2;
case Mips::S2: return Mips::S3;
case Mips::S3: return Mips::S4;
case Mips::S4: return Mips::S5;
case Mips::S5: return Mips::S6;
case Mips::S6: return Mips::S7;
case Mips::S7: return Mips::T8;
case Mips::T8: return Mips::T9;
case Mips::T9: return Mips::K0;
case Mips::K0: return Mips::K1;
case Mips::K1: return Mips::GP;
case Mips::GP: return Mips::SP;
case Mips::SP: return Mips::FP;
case Mips::FP: return Mips::RA;
case Mips::RA: return Mips::ZERO;
default: return 0;
}
}
// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
// lw $<reg+1>>, offset+4($reg2)'
// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);

View File

@ -362,7 +362,6 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::FCOS, MVT::f64, Expand);
setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
setOperationAction(ISD::FPOWI, MVT::f32, Expand);
setOperationAction(ISD::FPOW, MVT::f32, Expand);
setOperationAction(ISD::FPOW, MVT::f64, Expand);
setOperationAction(ISD::FLOG, MVT::f32, Expand);

View File

@ -681,6 +681,29 @@ def PseudoTRUNC_W_D : MipsAsmPseudoInst<(outs FGR32Opnd:$fd),
"trunc.w.d\t$fd, $fs, $rs">,
FGR_64, HARDFLOAT;
def LoadImmSingleGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
(ins imm64:$fpimm),
"li.s\t$rd, $fpimm">;
def LoadImmSingleFGR : MipsAsmPseudoInst<(outs StrictlyFGR32Opnd:$rd),
(ins imm64:$fpimm),
"li.s\t$rd, $fpimm">,
HARDFLOAT;
def LoadImmDoubleGPR : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
(ins imm64:$fpimm),
"li.d\t$rd, $fpimm">;
def LoadImmDoubleFGR_32 : MipsAsmPseudoInst<(outs StrictlyAFGR64Opnd:$rd),
(ins imm64:$fpimm),
"li.d\t$rd, $fpimm">,
FGR_32, HARDFLOAT;
def LoadImmDoubleFGR : MipsAsmPseudoInst<(outs StrictlyFGR64Opnd:$rd),
(ins imm64:$fpimm),
"li.d\t$rd, $fpimm">,
FGR_64, HARDFLOAT;
//===----------------------------------------------------------------------===//
// InstAliases.
//===----------------------------------------------------------------------===//

View File

@ -552,16 +552,31 @@ def AFGR64AsmOperand : MipsAsmRegOperand {
let PredicateMethod = "isFGRAsmReg";
}
def StrictlyAFGR64AsmOperand : MipsAsmRegOperand {
let Name = "StrictlyAFGR64AsmReg";
let PredicateMethod = "isStrictlyFGRAsmReg";
}
def FGR64AsmOperand : MipsAsmRegOperand {
let Name = "FGR64AsmReg";
let PredicateMethod = "isFGRAsmReg";
}
def StrictlyFGR64AsmOperand : MipsAsmRegOperand {
let Name = "StrictlyFGR64AsmReg";
let PredicateMethod = "isStrictlyFGRAsmReg";
}
def FGR32AsmOperand : MipsAsmRegOperand {
let Name = "FGR32AsmReg";
let PredicateMethod = "isFGRAsmReg";
}
def StrictlyFGR32AsmOperand : MipsAsmRegOperand {
let Name = "StrictlyFGR32AsmReg";
let PredicateMethod = "isStrictlyFGRAsmReg";
}
def FGRH32AsmOperand : MipsAsmRegOperand {
let Name = "FGRH32AsmReg";
let PredicateMethod = "isFGRAsmReg";
@ -639,14 +654,26 @@ def AFGR64Opnd : RegisterOperand<AFGR64> {
let ParserMatchClass = AFGR64AsmOperand;
}
def StrictlyAFGR64Opnd : RegisterOperand<AFGR64> {
let ParserMatchClass = StrictlyAFGR64AsmOperand;
}
def FGR64Opnd : RegisterOperand<FGR64> {
let ParserMatchClass = FGR64AsmOperand;
}
def StrictlyFGR64Opnd : RegisterOperand<FGR64> {
let ParserMatchClass = StrictlyFGR64AsmOperand;
}
def FGR32Opnd : RegisterOperand<FGR32> {
let ParserMatchClass = FGR32AsmOperand;
}
def StrictlyFGR32Opnd : RegisterOperand<FGR32> {
let ParserMatchClass = StrictlyFGR32AsmOperand;
}
def FGRCCOpnd : RegisterOperand<FGRCC> {
// The assembler doesn't use register classes so we can re-use
// FGR32AsmOperand.

View File

@ -539,7 +539,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::FSIN, VT, Expand);
setOperationAction(ISD::FCOS, VT, Expand);
setOperationAction(ISD::FABS, VT, Expand);
setOperationAction(ISD::FPOWI, VT, Expand);
setOperationAction(ISD::FFLOOR, VT, Expand);
setOperationAction(ISD::FCEIL, VT, Expand);
setOperationAction(ISD::FTRUNC, VT, Expand);
@ -798,7 +797,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::FABS , MVT::v4f64, Legal);
setOperationAction(ISD::FSIN , MVT::v4f64, Expand);
setOperationAction(ISD::FCOS , MVT::v4f64, Expand);
setOperationAction(ISD::FPOWI , MVT::v4f64, Expand);
setOperationAction(ISD::FPOW , MVT::v4f64, Expand);
setOperationAction(ISD::FLOG , MVT::v4f64, Expand);
setOperationAction(ISD::FLOG2 , MVT::v4f64, Expand);
@ -844,7 +842,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::FABS , MVT::v4f32, Legal);
setOperationAction(ISD::FSIN , MVT::v4f32, Expand);
setOperationAction(ISD::FCOS , MVT::v4f32, Expand);
setOperationAction(ISD::FPOWI , MVT::v4f32, Expand);
setOperationAction(ISD::FPOW , MVT::v4f32, Expand);
setOperationAction(ISD::FLOG , MVT::v4f32, Expand);
setOperationAction(ISD::FLOG2 , MVT::v4f32, Expand);

View File

@ -54,6 +54,8 @@ include "SystemZInstrFormats.td"
include "SystemZInstrInfo.td"
include "SystemZInstrVector.td"
include "SystemZInstrFP.td"
include "SystemZInstrHFP.td"
include "SystemZInstrDFP.td"
def SystemZInstrInfo : InstrInfo {}

View File

@ -115,12 +115,18 @@ def FeatureTransactionalExecution : SystemZFeature<
"Assume that the transactional-execution facility is installed"
>;
def FeatureDFPZonedConversion : SystemZFeature<
"dfp-zoned-conversion", "DFPZonedConversion",
"Assume that the DFP zoned-conversion facility is installed"
>;
def Arch10NewFeatures : SystemZFeatureList<[
FeatureExecutionHint,
FeatureLoadAndTrap,
FeatureMiscellaneousExtensions,
FeatureProcessorAssist,
FeatureTransactionalExecution
FeatureTransactionalExecution,
FeatureDFPZonedConversion
]>;
//===----------------------------------------------------------------------===//
@ -144,6 +150,11 @@ def FeatureMessageSecurityAssist5 : SystemZFeature<
"Assume that the message-security-assist extension facility 5 is installed"
>;
def FeatureDFPPackedConversion : SystemZFeature<
"dfp-packed-conversion", "DFPPackedConversion",
"Assume that the DFP packed-conversion facility is installed"
>;
def FeatureVector : SystemZFeature<
"vector", "Vector",
"Assume that the vectory facility is installed"
@ -154,6 +165,7 @@ def Arch11NewFeatures : SystemZFeatureList<[
FeatureLoadAndZeroRightmostByte,
FeatureLoadStoreOnCond2,
FeatureMessageSecurityAssist5,
FeatureDFPPackedConversion,
FeatureVector
]>;

View File

@ -4189,12 +4189,20 @@ static SDValue buildVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
if (Single.getNode() && (Count > 1 || Single.getOpcode() == ISD::LOAD))
return DAG.getNode(SystemZISD::REPLICATE, DL, VT, Single);
// If all elements are loads, use VLREP/VLEs (below).
bool AllLoads = true;
for (auto Elem : Elems)
if (Elem.getOpcode() != ISD::LOAD || cast<LoadSDNode>(Elem)->isIndexed()) {
AllLoads = false;
break;
}
// The best way of building a v2i64 from two i64s is to use VLVGP.
if (VT == MVT::v2i64)
if (VT == MVT::v2i64 && !AllLoads)
return joinDwords(DAG, DL, Elems[0], Elems[1]);
// Use a 64-bit merge high to combine two doubles.
if (VT == MVT::v2f64)
if (VT == MVT::v2f64 && !AllLoads)
return buildMergeScalars(DAG, DL, VT, Elems[0], Elems[1]);
// Build v4f32 values directly from the FPRs:
@ -4204,7 +4212,7 @@ static SDValue buildVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
// <ABxx> <CDxx>
// V VMRHG
// <ABCD>
if (VT == MVT::v4f32) {
if (VT == MVT::v4f32 && !AllLoads) {
SDValue Op01 = buildMergeScalars(DAG, DL, VT, Elems[0], Elems[1]);
SDValue Op23 = buildMergeScalars(DAG, DL, VT, Elems[2], Elems[3]);
// Avoid unnecessary undefs by reusing the other operand.
@ -4246,23 +4254,37 @@ static SDValue buildVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
Constants[I] = DAG.getUNDEF(Elems[I].getValueType());
Result = DAG.getBuildVector(VT, DL, Constants);
} else {
// Otherwise try to use VLVGP to start the sequence in order to
// Otherwise try to use VLREP or VLVGP to start the sequence in order to
// avoid a false dependency on any previous contents of the vector
// register. This only makes sense if one of the associated elements
// is defined.
unsigned I1 = NumElements / 2 - 1;
unsigned I2 = NumElements - 1;
bool Def1 = !Elems[I1].isUndef();
bool Def2 = !Elems[I2].isUndef();
if (Def1 || Def2) {
SDValue Elem1 = Elems[Def1 ? I1 : I2];
SDValue Elem2 = Elems[Def2 ? I2 : I1];
Result = DAG.getNode(ISD::BITCAST, DL, VT,
joinDwords(DAG, DL, Elem1, Elem2));
Done[I1] = true;
Done[I2] = true;
} else
Result = DAG.getUNDEF(VT);
// register.
// Use a VLREP if at least one element is a load.
unsigned LoadElIdx = UINT_MAX;
for (unsigned I = 0; I < NumElements; ++I)
if (Elems[I].getOpcode() == ISD::LOAD &&
cast<LoadSDNode>(Elems[I])->isUnindexed()) {
LoadElIdx = I;
break;
}
if (LoadElIdx != UINT_MAX) {
Result = DAG.getNode(SystemZISD::REPLICATE, DL, VT, Elems[LoadElIdx]);
Done[LoadElIdx] = true;
} else {
// Try to use VLVGP.
unsigned I1 = NumElements / 2 - 1;
unsigned I2 = NumElements - 1;
bool Def1 = !Elems[I1].isUndef();
bool Def2 = !Elems[I2].isUndef();
if (Def1 || Def2) {
SDValue Elem1 = Elems[Def1 ? I1 : I2];
SDValue Elem2 = Elems[Def2 ? I2 : I1];
Result = DAG.getNode(ISD::BITCAST, DL, VT,
joinDwords(DAG, DL, Elem1, Elem2));
Done[I1] = true;
Done[I2] = true;
} else
Result = DAG.getUNDEF(VT);
}
}
// Use VLVGx to insert the other elements.

View File

@ -0,0 +1,231 @@
//==- SystemZInstrDFP.td - Floating-point SystemZ instructions -*- tblgen-*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The instructions in this file implement SystemZ decimal floating-point
// arithmetic. These instructions are inot currently used for code generation,
// are provided for use with the assembler and disassembler only. If LLVM
// ever supports decimal floating-point types (_Decimal64 etc.), they can
// also be used for code generation for those types.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Move instructions
//===----------------------------------------------------------------------===//
// Load and test.
let Defs = [CC] in {
def LTDTR : UnaryRRE<"ltdtr", 0xB3D6, null_frag, FP64, FP64>;
def LTXTR : UnaryRRE<"ltxtr", 0xB3DE, null_frag, FP128, FP128>;
}
//===----------------------------------------------------------------------===//
// Conversion instructions
//===----------------------------------------------------------------------===//
// Convert floating-point values to narrower representations. The destination
// of LDXTR is a 128-bit value, but only the first register of the pair is used.
def LEDTR : TernaryRRFe<"ledtr", 0xB3D5, FP32, FP64>;
def LDXTR : TernaryRRFe<"ldxtr", 0xB3DD, FP128, FP128>;
// Extend floating-point values to wider representations.
def LDETR : BinaryRRFd<"ldetr", 0xB3D4, FP64, FP32>;
def LXDTR : BinaryRRFd<"lxdtr", 0xB3DC, FP128, FP64>;
// Convert a signed integer value to a floating-point one.
def CDGTR : UnaryRRE<"cdgtr", 0xB3F1, null_frag, FP64, GR64>;
def CXGTR : UnaryRRE<"cxgtr", 0xB3F9, null_frag, FP128, GR64>;
let Predicates = [FeatureFPExtension] in {
def CDGTRA : TernaryRRFe<"cdgtra", 0xB3F1, FP64, GR64>;
def CXGTRA : TernaryRRFe<"cxgtra", 0xB3F9, FP128, GR64>;
def CDFTR : TernaryRRFe<"cdftr", 0xB951, FP64, GR32>;
def CXFTR : TernaryRRFe<"cxftr", 0xB959, FP128, GR32>;
}
// Convert an unsigned integer value to a floating-point one.
let Predicates = [FeatureFPExtension] in {
def CDLGTR : TernaryRRFe<"cdlgtr", 0xB952, FP64, GR64>;
def CXLGTR : TernaryRRFe<"cxlgtr", 0xB95A, FP128, GR64>;
def CDLFTR : TernaryRRFe<"cdlftr", 0xB953, FP64, GR32>;
def CXLFTR : TernaryRRFe<"cxlftr", 0xB95B, FP128, GR32>;
}
// Convert a floating-point value to a signed integer value.
let Defs = [CC] in {
def CGDTR : BinaryRRFe<"cgdtr", 0xB3E1, GR64, FP64>;
def CGXTR : BinaryRRFe<"cgxtr", 0xB3E9, GR64, FP128>;
let Predicates = [FeatureFPExtension] in {
def CGDTRA : TernaryRRFe<"cgdtra", 0xB3E1, GR64, FP64>;
def CGXTRA : TernaryRRFe<"cgxtra", 0xB3E9, GR64, FP128>;
def CFDTR : TernaryRRFe<"cfdtr", 0xB941, GR32, FP64>;
def CFXTR : TernaryRRFe<"cfxtr", 0xB949, GR32, FP128>;
}
}
// Convert a floating-point value to an unsigned integer value.
let Defs = [CC] in {
let Predicates = [FeatureFPExtension] in {
def CLGDTR : TernaryRRFe<"clgdtr", 0xB942, GR64, FP64>;
def CLGXTR : TernaryRRFe<"clgxtr", 0xB94A, GR64, FP128>;
def CLFDTR : TernaryRRFe<"clfdtr", 0xB943, GR32, FP64>;
def CLFXTR : TernaryRRFe<"clfxtr", 0xB94B, GR32, FP128>;
}
}
// Convert a packed value to a floating-point one.
def CDSTR : UnaryRRE<"cdstr", 0xB3F3, null_frag, FP64, GR64>;
def CXSTR : UnaryRRE<"cxstr", 0xB3FB, null_frag, FP128, GR128>;
def CDUTR : UnaryRRE<"cdutr", 0xB3F2, null_frag, FP64, GR64>;
def CXUTR : UnaryRRE<"cxutr", 0xB3FA, null_frag, FP128, GR128>;
// Convert a floating-point value to a packed value.
def CSDTR : BinaryRRFd<"csdtr", 0xB3E3, GR64, FP64>;
def CSXTR : BinaryRRFd<"csxtr", 0xB3EB, GR128, FP128>;
def CUDTR : UnaryRRE<"cudtr", 0xB3E2, null_frag, GR64, FP64>;
def CUXTR : UnaryRRE<"cuxtr", 0xB3EA, null_frag, GR128, FP128>;
// Convert from/to memory values in the zoned format.
let Predicates = [FeatureDFPZonedConversion] in {
def CDZT : BinaryRSL<"cdzt", 0xEDAA, FP64>;
def CXZT : BinaryRSL<"cxzt", 0xEDAB, FP128>;
def CZDT : StoreBinaryRSL<"czdt", 0xEDA8, FP64>;
def CZXT : StoreBinaryRSL<"czxt", 0xEDA9, FP128>;
}
// Convert from/to memory values in the packed format.
let Predicates = [FeatureDFPPackedConversion] in {
def CDPT : BinaryRSL<"cdpt", 0xEDAE, FP64>;
def CXPT : BinaryRSL<"cxpt", 0xEDAF, FP128>;
def CPDT : StoreBinaryRSL<"cpdt", 0xEDAC, FP64>;
def CPXT : StoreBinaryRSL<"cpxt", 0xEDAD, FP128>;
}
// Perform floating-point operation.
let Defs = [CC, R1L, F0Q], Uses = [R0L, F4Q] in
def PFPO : SideEffectInherentE<"pfpo", 0x010A>;
//===----------------------------------------------------------------------===//
// Unary arithmetic
//===----------------------------------------------------------------------===//
// Round to an integer, with the second operand (M3) specifying the rounding
// mode. M4 can be set to 4 to suppress detection of inexact conditions.
def FIDTR : TernaryRRFe<"fidtr", 0xB3D7, FP64, FP64>;
def FIXTR : TernaryRRFe<"fixtr", 0xB3DF, FP128, FP128>;
// Extract biased exponent.
def EEDTR : UnaryRRE<"eedtr", 0xB3E5, null_frag, FP64, FP64>;
def EEXTR : UnaryRRE<"eextr", 0xB3ED, null_frag, FP128, FP128>;
// Extract significance.
def ESDTR : UnaryRRE<"esdtr", 0xB3E7, null_frag, FP64, FP64>;
def ESXTR : UnaryRRE<"esxtr", 0xB3EF, null_frag, FP128, FP128>;
//===----------------------------------------------------------------------===//
// Binary arithmetic
//===----------------------------------------------------------------------===//
// Addition.
let Defs = [CC] in {
let isCommutable = 1 in {
def ADTR : BinaryRRFa<"adtr", 0xB3D2, null_frag, FP64, FP64, FP64>;
def AXTR : BinaryRRFa<"axtr", 0xB3DA, null_frag, FP128, FP128, FP128>;
}
let Predicates = [FeatureFPExtension] in {
def ADTRA : TernaryRRFa<"adtra", 0xB3D2, FP64, FP64, FP64>;
def AXTRA : TernaryRRFa<"axtra", 0xB3DA, FP128, FP128, FP128>;
}
}
// Subtraction.
let Defs = [CC] in {
def SDTR : BinaryRRFa<"sdtr", 0xB3D3, null_frag, FP64, FP64, FP64>;
def SXTR : BinaryRRFa<"sxtr", 0xB3DB, null_frag, FP128, FP128, FP128>;
let Predicates = [FeatureFPExtension] in {
def SDTRA : TernaryRRFa<"sdtra", 0xB3D3, FP64, FP64, FP64>;
def SXTRA : TernaryRRFa<"sxtra", 0xB3DB, FP128, FP128, FP128>;
}
}
// Multiplication.
let isCommutable = 1 in {
def MDTR : BinaryRRFa<"mdtr", 0xB3D0, null_frag, FP64, FP64, FP64>;
def MXTR : BinaryRRFa<"mxtr", 0xB3D8, null_frag, FP128, FP128, FP128>;
}
let Predicates = [FeatureFPExtension] in {
def MDTRA : TernaryRRFa<"mdtra", 0xB3D0, FP64, FP64, FP64>;
def MXTRA : TernaryRRFa<"mxtra", 0xB3D8, FP128, FP128, FP128>;
}
// Division.
def DDTR : BinaryRRFa<"ddtr", 0xB3D1, null_frag, FP64, FP64, FP64>;
def DXTR : BinaryRRFa<"dxtr", 0xB3D9, null_frag, FP128, FP128, FP128>;
let Predicates = [FeatureFPExtension] in {
def DDTRA : TernaryRRFa<"ddtra", 0xB3D1, FP64, FP64, FP64>;
def DXTRA : TernaryRRFa<"dxtra", 0xB3D9, FP128, FP128, FP128>;
}
// Quantize.
def QADTR : TernaryRRFb<"qadtr", 0xB3F5, FP64, FP64, FP64>;
def QAXTR : TernaryRRFb<"qaxtr", 0xB3FD, FP128, FP128, FP128>;
// Reround.
def RRDTR : TernaryRRFb<"rrdtr", 0xB3F7, FP64, FP64, FP64>;
def RRXTR : TernaryRRFb<"rrxtr", 0xB3FF, FP128, FP128, FP128>;
// Shift significand left/right.
def SLDT : BinaryRXF<"sldt", 0xED40, null_frag, FP64, FP64, null_frag, 0>;
def SLXT : BinaryRXF<"slxt", 0xED48, null_frag, FP128, FP128, null_frag, 0>;
def SRDT : BinaryRXF<"srdt", 0xED41, null_frag, FP64, FP64, null_frag, 0>;
def SRXT : BinaryRXF<"srxt", 0xED49, null_frag, FP128, FP128, null_frag, 0>;
// Insert biased exponent.
def IEDTR : BinaryRRFb<"iedtr", 0xB3F6, null_frag, FP64, FP64, FP64>;
def IEXTR : BinaryRRFb<"iextr", 0xB3FE, null_frag, FP128, FP128, FP128>;
//===----------------------------------------------------------------------===//
// Comparisons
//===----------------------------------------------------------------------===//
// Compare.
let Defs = [CC] in {
def CDTR : CompareRRE<"cdtr", 0xB3E4, null_frag, FP64, FP64>;
def CXTR : CompareRRE<"cxtr", 0xB3EC, null_frag, FP128, FP128>;
}
// Compare and signal.
let Defs = [CC] in {
def KDTR : CompareRRE<"kdtr", 0xB3E0, null_frag, FP64, FP64>;
def KXTR : CompareRRE<"kxtr", 0xB3E8, null_frag, FP128, FP128>;
}
// Compare biased exponent.
let Defs = [CC] in {
def CEDTR : CompareRRE<"cedtr", 0xB3F4, null_frag, FP64, FP64>;
def CEXTR : CompareRRE<"cextr", 0xB3FC, null_frag, FP128, FP128>;
}
// Test Data Class.
let Defs = [CC] in {
def TDCET : TestRXE<"tdcet", 0xED50, null_frag, FP32>;
def TDCDT : TestRXE<"tdcdt", 0xED54, null_frag, FP64>;
def TDCXT : TestRXE<"tdcxt", 0xED58, null_frag, FP128>;
}
// Test Data Group.
let Defs = [CC] in {
def TDGET : TestRXE<"tdget", 0xED51, null_frag, FP32>;
def TDGDT : TestRXE<"tdgdt", 0xED55, null_frag, FP64>;
def TDGXT : TestRXE<"tdgxt", 0xED59, null_frag, FP128>;
}

View File

@ -121,7 +121,8 @@ let canFoldAsLoad = 1, SimpleBDXLoad = 1 in {
defm LD : UnaryRXPair<"ld", 0x68, 0xED65, load, FP64, 8>;
// For z13 we prefer LDE over LE to avoid partial register dependencies.
def LDE32 : UnaryRXE<"lde", 0xED24, null_frag, FP32, 4>;
let isCodeGenOnly = 1 in
def LDE32 : UnaryRXE<"lde", 0xED24, null_frag, FP32, 4>;
// These instructions are split after register allocation, so we don't
// want a custom inserter.
@ -437,18 +438,18 @@ def : Pat<(fmul (f128 (fpextend FP64:$src1)),
bdxaddr12only:$addr)>;
// Fused multiply-add.
def MAEBR : TernaryRRD<"maebr", 0xB30E, z_fma, FP32>;
def MADBR : TernaryRRD<"madbr", 0xB31E, z_fma, FP64>;
def MAEBR : TernaryRRD<"maebr", 0xB30E, z_fma, FP32, FP32>;
def MADBR : TernaryRRD<"madbr", 0xB31E, z_fma, FP64, FP64>;
def MAEB : TernaryRXF<"maeb", 0xED0E, z_fma, FP32, load, 4>;
def MADB : TernaryRXF<"madb", 0xED1E, z_fma, FP64, load, 8>;
def MAEB : TernaryRXF<"maeb", 0xED0E, z_fma, FP32, FP32, load, 4>;
def MADB : TernaryRXF<"madb", 0xED1E, z_fma, FP64, FP64, load, 8>;
// Fused multiply-subtract.
def MSEBR : TernaryRRD<"msebr", 0xB30F, z_fms, FP32>;
def MSDBR : TernaryRRD<"msdbr", 0xB31F, z_fms, FP64>;
def MSEBR : TernaryRRD<"msebr", 0xB30F, z_fms, FP32, FP32>;
def MSDBR : TernaryRRD<"msdbr", 0xB31F, z_fms, FP64, FP64>;
def MSEB : TernaryRXF<"mseb", 0xED0F, z_fms, FP32, load, 4>;
def MSDB : TernaryRXF<"msdb", 0xED1F, z_fms, FP64, load, 8>;
def MSEB : TernaryRXF<"mseb", 0xED0F, z_fms, FP32, FP32, load, 4>;
def MSDB : TernaryRXF<"msdb", 0xED1F, z_fms, FP64, FP64, load, 8>;
// Division.
def DEBR : BinaryRRE<"debr", 0xB30D, fdiv, FP32, FP32>;

View File

@ -527,6 +527,22 @@ class InstRRFc<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
let Inst{3-0} = R2;
}
class InstRRFd<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<4, outs, ins, asmstr, pattern> {
field bits<32> Inst;
field bits<32> SoftFail = 0;
bits<4> R1;
bits<4> R2;
bits<4> M4;
let Inst{31-16} = op;
let Inst{15-12} = 0;
let Inst{11-8} = M4;
let Inst{7-4} = R1;
let Inst{3-0} = R2;
}
class InstRRFe<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<4, outs, ins, asmstr, pattern> {
field bits<32> Inst;
@ -725,6 +741,22 @@ class InstRSLa<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
let Inst{7-0} = op{7-0};
}
class InstRSLb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
field bits<48> SoftFail = 0;
bits<4> R1;
bits<24> BDL2;
bits<4> M3;
let Inst{47-40} = op{15-8};
let Inst{39-16} = BDL2;
let Inst{15-12} = R1;
let Inst{11-8} = M3;
let Inst{7-0} = op{7-0};
}
class InstRSYa<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSystemZ<6, outs, ins, asmstr, pattern> {
field bits<48> Inst;
@ -2752,6 +2784,15 @@ class BinaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
let DisableEncoding = "$R1src";
}
class BinaryRRD<string mnemonic, bits<16> opcode, SDPatternOperator operator,
RegisterOperand cls1, RegisterOperand cls2>
: InstRRD<opcode, (outs cls1:$R1), (ins cls2:$R3, cls2:$R2),
mnemonic#"\t$R1, $R3, $R2",
[(set cls1:$R1, (operator cls2:$R3, cls2:$R2))]> {
let OpKey = mnemonic#cls;
let OpType = "reg";
}
class BinaryRRFa<string mnemonic, bits<16> opcode, SDPatternOperator operator,
RegisterOperand cls1, RegisterOperand cls2,
RegisterOperand cls3>
@ -2808,6 +2849,11 @@ multiclass BinaryMemRRFcOpt<string mnemonic, bits<16> opcode,
def Opt : UnaryMemRRFc<mnemonic, opcode, cls1, cls2>;
}
class BinaryRRFd<string mnemonic, bits<16> opcode, RegisterOperand cls1,
RegisterOperand cls2>
: InstRRFd<opcode, (outs cls1:$R1), (ins cls2:$R2, imm32zx4:$M4),
mnemonic#"\t$R1, $R2, $M4", []>;
class BinaryRRFe<string mnemonic, bits<16> opcode, RegisterOperand cls1,
RegisterOperand cls2>
: InstRRFe<opcode, (outs cls1:$R1), (ins imm32zx4:$M3, cls2:$R2),
@ -2958,6 +3004,13 @@ multiclass BinaryRSAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
}
}
class BinaryRSL<string mnemonic, bits<16> opcode, RegisterOperand cls>
: InstRSLb<opcode, (outs cls:$R1),
(ins bdladdr12onlylen8:$BDL2, imm32zx4:$M3),
mnemonic#"\t$R1, $BDL2, $M3", []> {
let mayLoad = 1;
}
class BinaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
AddressingMode mode = bdxaddr12only>
@ -2987,6 +3040,18 @@ class BinaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
let M3 = 0;
}
class BinaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
RegisterOperand cls1, RegisterOperand cls2,
SDPatternOperator load, bits<5> bytes>
: InstRXF<opcode, (outs cls1:$R1), (ins cls2:$R3, bdxaddr12only:$XBD2),
mnemonic#"\t$R1, $R3, $XBD2",
[(set cls1:$R1, (operator cls2:$R3, (load bdxaddr12only:$XBD2)))]> {
let OpKey = mnemonic#"r"#cls;
let OpType = "mem";
let mayLoad = 1;
let AccessBytes = bytes;
}
class BinaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
AddressingMode mode = bdxaddr20only>
@ -3294,6 +3359,13 @@ multiclass StoreBinaryRSPair<string mnemonic, bits<8> rsOpcode,
}
}
class StoreBinaryRSL<string mnemonic, bits<16> opcode, RegisterOperand cls>
: InstRSLb<opcode, (outs),
(ins cls:$R1, bdladdr12onlylen8:$BDL2, imm32zx4:$M3),
mnemonic#"\t$R1, $BDL2, $M3", []> {
let mayStore = 1;
}
class StoreBinaryVRV<string mnemonic, bits<16> opcode, bits<5> bytes,
Immediate index>
: InstVRV<opcode, (outs), (ins VR128:$V1, bdvaddr12only:$VBD2, index:$M3),
@ -3581,6 +3653,12 @@ class SideEffectTernarySSF<string mnemonic, bits<12> opcode,
(ins bdaddr12only:$BD1, bdaddr12only:$BD2, cls:$R3),
mnemonic#"\t$BD1, $BD2, $R3", []>;
class TernaryRRFa<string mnemonic, bits<16> opcode,
RegisterOperand cls1, RegisterOperand cls2,
RegisterOperand cls3>
: InstRRFa<opcode, (outs cls1:$R1), (ins cls2:$R2, cls3:$R3, imm32zx4:$M4),
mnemonic#"\t$R1, $R2, $R3, $M4", []>;
class TernaryRRFb<string mnemonic, bits<16> opcode,
RegisterOperand cls1, RegisterOperand cls2,
RegisterOperand cls3>
@ -3597,11 +3675,11 @@ class TernaryRRFe<string mnemonic, bits<16> opcode, RegisterOperand cls1,
(ins imm32zx4:$M3, cls2:$R2, imm32zx4:$M4),
mnemonic#"\t$R1, $M3, $R2, $M4", []>;
class TernaryRRD<string mnemonic, bits<16> opcode,
SDPatternOperator operator, RegisterOperand cls>
: InstRRD<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, cls:$R2),
class TernaryRRD<string mnemonic, bits<16> opcode, SDPatternOperator operator,
RegisterOperand cls1, RegisterOperand cls2>
: InstRRD<opcode, (outs cls1:$R1), (ins cls2:$R1src, cls2:$R3, cls2:$R2),
mnemonic#"\t$R1, $R3, $R2",
[(set cls:$R1, (operator cls:$R1src, cls:$R3, cls:$R2))]> {
[(set cls1:$R1, (operator cls2:$R1src, cls2:$R3, cls2:$R2))]> {
let OpKey = mnemonic#cls;
let OpType = "reg";
let Constraints = "$R1 = $R1src";
@ -3661,12 +3739,13 @@ class SideEffectTernaryMemMemRSY<string mnemonic, bits<16> opcode,
}
class TernaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
: InstRXF<opcode, (outs cls:$R1),
(ins cls:$R1src, cls:$R3, bdxaddr12only:$XBD2),
RegisterOperand cls1, RegisterOperand cls2,
SDPatternOperator load, bits<5> bytes>
: InstRXF<opcode, (outs cls1:$R1),
(ins cls2:$R1src, cls2:$R3, bdxaddr12only:$XBD2),
mnemonic#"\t$R1, $R3, $XBD2",
[(set cls:$R1, (operator cls:$R1src, cls:$R3,
(load bdxaddr12only:$XBD2)))]> {
[(set cls1:$R1, (operator cls2:$R1src, cls2:$R3,
(load bdxaddr12only:$XBD2)))]> {
let OpKey = mnemonic#"r"#cls;
let OpType = "mem";
let Constraints = "$R1 = $R1src";

View File

@ -0,0 +1,240 @@
//==- SystemZInstrHFP.td - Floating-point SystemZ instructions -*- tblgen-*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The instructions in this file implement SystemZ hexadecimal floating-point
// arithmetic. Since this format is not mapped to any source-language data
// type, these instructions are not used for code generation, but are provided
// for use with the assembler and disassembler only.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Move instructions
//===----------------------------------------------------------------------===//
// Load and test.
let Defs = [CC] in {
def LTER : UnaryRR <"lter", 0x32, null_frag, FP32, FP32>;
def LTDR : UnaryRR <"ltdr", 0x22, null_frag, FP64, FP64>;
def LTXR : UnaryRRE<"ltxr", 0xB362, null_frag, FP128, FP128>;
}
//===----------------------------------------------------------------------===//
// Conversion instructions
//===----------------------------------------------------------------------===//
// Convert floating-point values to narrower representations.
def LEDR : UnaryRR <"ledr", 0x35, null_frag, FP32, FP64>;
def LEXR : UnaryRRE<"lexr", 0xB366, null_frag, FP32, FP128>;
def LDXR : UnaryRR <"ldxr", 0x25, null_frag, FP64, FP128>;
let isAsmParserOnly = 1 in {
def LRER : UnaryRR <"lrer", 0x35, null_frag, FP32, FP64>;
def LRDR : UnaryRR <"lrdr", 0x25, null_frag, FP64, FP128>;
}
// Extend floating-point values to wider representations.
def LDER : UnaryRRE<"lder", 0xB324, null_frag, FP64, FP32>;
def LXER : UnaryRRE<"lxer", 0xB326, null_frag, FP128, FP32>;
def LXDR : UnaryRRE<"lxdr", 0xB325, null_frag, FP128, FP64>;
def LDE : UnaryRXE<"lde", 0xED24, null_frag, FP64, 4>;
def LXE : UnaryRXE<"lxe", 0xED26, null_frag, FP128, 4>;
def LXD : UnaryRXE<"lxd", 0xED25, null_frag, FP128, 8>;
// Convert a signed integer register value to a floating-point one.
def CEFR : UnaryRRE<"cefr", 0xB3B4, null_frag, FP32, GR32>;
def CDFR : UnaryRRE<"cdfr", 0xB3B5, null_frag, FP64, GR32>;
def CXFR : UnaryRRE<"cxfr", 0xB3B6, null_frag, FP128, GR32>;
def CEGR : UnaryRRE<"cegr", 0xB3C4, null_frag, FP32, GR64>;
def CDGR : UnaryRRE<"cdgr", 0xB3C5, null_frag, FP64, GR64>;
def CXGR : UnaryRRE<"cxgr", 0xB3C6, null_frag, FP128, GR64>;
// Convert a floating-point register value to a signed integer value,
// with the second operand (modifier M3) specifying the rounding mode.
let Defs = [CC] in {
def CFER : BinaryRRFe<"cfer", 0xB3B8, GR32, FP32>;
def CFDR : BinaryRRFe<"cfdr", 0xB3B9, GR32, FP64>;
def CFXR : BinaryRRFe<"cfxr", 0xB3BA, GR32, FP128>;
def CGER : BinaryRRFe<"cger", 0xB3C8, GR64, FP32>;
def CGDR : BinaryRRFe<"cgdr", 0xB3C9, GR64, FP64>;
def CGXR : BinaryRRFe<"cgxr", 0xB3CA, GR64, FP128>;
}
// Convert BFP to HFP.
let Defs = [CC] in {
def THDER : UnaryRRE<"thder", 0xB358, null_frag, FP64, FP32>;
def THDR : UnaryRRE<"thdr", 0xB359, null_frag, FP64, FP64>;
}
// Convert HFP to BFP.
let Defs = [CC] in {
def TBEDR : BinaryRRFe<"tbedr", 0xB350, FP32, FP64>;
def TBDR : BinaryRRFe<"tbdr", 0xB351, FP64, FP64>;
}
//===----------------------------------------------------------------------===//
// Unary arithmetic
//===----------------------------------------------------------------------===//
// Negation (Load Complement).
let Defs = [CC] in {
def LCER : UnaryRR <"lcer", 0x33, null_frag, FP32, FP32>;
def LCDR : UnaryRR <"lcdr", 0x23, null_frag, FP64, FP64>;
def LCXR : UnaryRRE<"lcxr", 0xB363, null_frag, FP128, FP128>;
}
// Absolute value (Load Positive).
let Defs = [CC] in {
def LPER : UnaryRR <"lper", 0x30, null_frag, FP32, FP32>;
def LPDR : UnaryRR <"lpdr", 0x20, null_frag, FP64, FP64>;
def LPXR : UnaryRRE<"lpxr", 0xB360, null_frag, FP128, FP128>;
}
// Negative absolute value (Load Negative).
let Defs = [CC] in {
def LNER : UnaryRR <"lner", 0x31, null_frag, FP32, FP32>;
def LNDR : UnaryRR <"lndr", 0x21, null_frag, FP64, FP64>;
def LNXR : UnaryRRE<"lnxr", 0xB361, null_frag, FP128, FP128>;
}
// Halve.
def HER : UnaryRR <"her", 0x34, null_frag, FP32, FP32>;
def HDR : UnaryRR <"hdr", 0x24, null_frag, FP64, FP64>;
// Square root.
def SQER : UnaryRRE<"sqer", 0xB245, null_frag, FP32, FP32>;
def SQDR : UnaryRRE<"sqdr", 0xB244, null_frag, FP64, FP64>;
def SQXR : UnaryRRE<"sqxr", 0xB336, null_frag, FP128, FP128>;
def SQE : UnaryRXE<"sqe", 0xED34, null_frag, FP32, 4>;
def SQD : UnaryRXE<"sqd", 0xED35, null_frag, FP64, 8>;
// Round to an integer (rounding towards zero).
def FIER : UnaryRRE<"fier", 0xB377, null_frag, FP32, FP32>;
def FIDR : UnaryRRE<"fidr", 0xB37F, null_frag, FP64, FP64>;
def FIXR : UnaryRRE<"fixr", 0xB367, null_frag, FP128, FP128>;
//===----------------------------------------------------------------------===//
// Binary arithmetic
//===----------------------------------------------------------------------===//
// Addition.
let Defs = [CC] in {
let isCommutable = 1 in {
def AER : BinaryRR<"aer", 0x3A, null_frag, FP32, FP32>;
def ADR : BinaryRR<"adr", 0x2A, null_frag, FP64, FP64>;
def AXR : BinaryRR<"axr", 0x36, null_frag, FP128, FP128>;
}
def AE : BinaryRX<"ae", 0x7A, null_frag, FP32, load, 4>;
def AD : BinaryRX<"ad", 0x6A, null_frag, FP64, load, 8>;
}
// Addition (unnormalized).
let Defs = [CC] in {
let isCommutable = 1 in {
def AUR : BinaryRR<"aur", 0x3E, null_frag, FP32, FP32>;
def AWR : BinaryRR<"awr", 0x2E, null_frag, FP64, FP64>;
}
def AU : BinaryRX<"au", 0x7E, null_frag, FP32, load, 4>;
def AW : BinaryRX<"aw", 0x6E, null_frag, FP64, load, 8>;
}
// Subtraction.
let Defs = [CC] in {
def SER : BinaryRR<"ser", 0x3B, null_frag, FP32, FP32>;
def SDR : BinaryRR<"sdr", 0x2B, null_frag, FP64, FP64>;
def SXR : BinaryRR<"sxr", 0x37, null_frag, FP128, FP128>;
def SE : BinaryRX<"se", 0x7B, null_frag, FP32, load, 4>;
def SD : BinaryRX<"sd", 0x6B, null_frag, FP64, load, 8>;
}
// Subtraction (unnormalized).
let Defs = [CC] in {
def SUR : BinaryRR<"sur", 0x3F, null_frag, FP32, FP32>;
def SWR : BinaryRR<"swr", 0x2F, null_frag, FP64, FP64>;
def SU : BinaryRX<"su", 0x7F, null_frag, FP32, load, 4>;
def SW : BinaryRX<"sw", 0x6F, null_frag, FP64, load, 8>;
}
// Multiplication.
let isCommutable = 1 in {
def MEER : BinaryRRE<"meer", 0xB337, null_frag, FP32, FP32>;
def MDR : BinaryRR <"mdr", 0x2C, null_frag, FP64, FP64>;
def MXR : BinaryRR <"mxr", 0x26, null_frag, FP128, FP128>;
}
def MEE : BinaryRXE<"mee", 0xED37, null_frag, FP32, load, 4>;
def MD : BinaryRX <"md", 0x6C, null_frag, FP64, load, 8>;
// Extending multiplication (f32 x f32 -> f64).
def MDER : BinaryRR<"mder", 0x3C, null_frag, FP64, FP32>;
def MDE : BinaryRX<"mde", 0x7C, null_frag, FP64, load, 4>;
let isAsmParserOnly = 1 in {
def MER : BinaryRR<"mer", 0x3C, null_frag, FP64, FP32>;
def ME : BinaryRX<"me", 0x7C, null_frag, FP64, load, 4>;
}
// Extending multiplication (f64 x f64 -> f128).
def MXDR : BinaryRR<"mxdr", 0x27, null_frag, FP128, FP64>;
def MXD : BinaryRX<"mxd", 0x67, null_frag, FP128, load, 8>;
// Fused multiply-add.
def MAER : TernaryRRD<"maer", 0xB32E, null_frag, FP32, FP32>;
def MADR : TernaryRRD<"madr", 0xB33E, null_frag, FP64, FP64>;
def MAE : TernaryRXF<"mae", 0xED2E, null_frag, FP32, FP32, load, 4>;
def MAD : TernaryRXF<"mad", 0xED3E, null_frag, FP64, FP64, load, 8>;
// Fused multiply-subtract.
def MSER : TernaryRRD<"mser", 0xB32F, null_frag, FP32, FP32>;
def MSDR : TernaryRRD<"msdr", 0xB33F, null_frag, FP64, FP64>;
def MSE : TernaryRXF<"mse", 0xED2F, null_frag, FP32, FP32, load, 4>;
def MSD : TernaryRXF<"msd", 0xED3F, null_frag, FP64, FP64, load, 8>;
// Multiplication (unnormalized).
def MYR : BinaryRRD<"myr", 0xB33B, null_frag, FP128, FP64>;
def MYHR : BinaryRRD<"myhr", 0xB33D, null_frag, FP64, FP64>;
def MYLR : BinaryRRD<"mylr", 0xB339, null_frag, FP64, FP64>;
def MY : BinaryRXF<"my", 0xED3B, null_frag, FP128, FP64, load, 8>;
def MYH : BinaryRXF<"myh", 0xED3D, null_frag, FP64, FP64, load, 8>;
def MYL : BinaryRXF<"myl", 0xED39, null_frag, FP64, FP64, load, 8>;
// Fused multiply-add (unnormalized).
def MAYR : TernaryRRD<"mayr", 0xB33A, null_frag, FP128, FP64>;
def MAYHR : TernaryRRD<"mayhr", 0xB33C, null_frag, FP64, FP64>;
def MAYLR : TernaryRRD<"maylr", 0xB338, null_frag, FP64, FP64>;
def MAY : TernaryRXF<"may", 0xED3A, null_frag, FP128, FP64, load, 8>;
def MAYH : TernaryRXF<"mayh", 0xED3C, null_frag, FP64, FP64, load, 8>;
def MAYL : TernaryRXF<"mayl", 0xED38, null_frag, FP64, FP64, load, 8>;
// Division.
def DER : BinaryRR <"der", 0x3D, null_frag, FP32, FP32>;
def DDR : BinaryRR <"ddr", 0x2D, null_frag, FP64, FP64>;
def DXR : BinaryRRE<"dxr", 0xB22D, null_frag, FP128, FP128>;
def DE : BinaryRX <"de", 0x7D, null_frag, FP32, load, 4>;
def DD : BinaryRX <"dd", 0x6D, null_frag, FP64, load, 8>;
//===----------------------------------------------------------------------===//
// Comparisons
//===----------------------------------------------------------------------===//
let Defs = [CC] in {
def CER : CompareRR <"cer", 0x39, null_frag, FP32, FP32>;
def CDR : CompareRR <"cdr", 0x29, null_frag, FP64, FP64>;
def CXR : CompareRRE<"cxr", 0xB369, null_frag, FP128, FP128>;
def CE : CompareRX<"ce", 0x79, null_frag, FP32, load, 4>;
def CD : CompareRX<"cd", 0x69, null_frag, FP64, load, 8>;
}

View File

@ -908,6 +908,238 @@ def : InstRW<[FXa, Lat30, GroupAlone], (instregex "SFASR$")>;
def : InstRW<[FXa, LSU, Lat30, GroupAlone], (instregex "LFAS$")>;
def : InstRW<[FXb, Lat3, GroupAlone], (instregex "SRNM(B|T)?$")>;
// --------------------- Hexadecimal floating point ------------------------- //
//===----------------------------------------------------------------------===//
// HFP: Move instructions
//===----------------------------------------------------------------------===//
// Load and Test
def : InstRW<[VecXsPm, Lat4], (instregex "LT(D|E)R$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "LTXR$")>;
//===----------------------------------------------------------------------===//
// HFP: Conversion instructions
//===----------------------------------------------------------------------===//
// Load rounded
def : InstRW<[VecBF], (instregex "(LEDR|LRER)$")>;
def : InstRW<[VecBF], (instregex "LEXR$")>;
def : InstRW<[VecDF2, VecDF2], (instregex "(LDXR|LRDR)$")>;
// Load lengthened
def : InstRW<[LSU], (instregex "LDE$")>;
def : InstRW<[FXb], (instregex "LDER$")>;
def : InstRW<[VecBF2, VecBF2, LSU, Lat12, GroupAlone], (instregex "LX(D|E)$")>;
def : InstRW<[VecBF2, VecBF2, GroupAlone], (instregex "LX(D|E)R$")>;
// Convert from fixed
def : InstRW<[FXb, VecBF, Lat9, BeginGroup], (instregex "CE(F|G)R$")>;
def : InstRW<[FXb, VecBF, Lat9, BeginGroup], (instregex "CD(F|G)R$")>;
def : InstRW<[FXb, VecDF2, VecDF2, Lat12, GroupAlone], (instregex "CX(F|G)R$")>;
// Convert to fixed
def : InstRW<[FXb, VecBF, Lat11, BeginGroup], (instregex "CF(E|D)R$")>;
def : InstRW<[FXb, VecBF, Lat11, BeginGroup], (instregex "CG(E|D)R$")>;
def : InstRW<[FXb, VecDF, VecDF, Lat20, BeginGroup], (instregex "C(F|G)XR$")>;
// Convert BFP to HFP / HFP to BFP.
def : InstRW<[VecBF], (instregex "THD(E)?R$")>;
def : InstRW<[VecBF], (instregex "TB(E)?DR$")>;
//===----------------------------------------------------------------------===//
// HFP: Unary arithmetic
//===----------------------------------------------------------------------===//
// Load Complement / Negative / Positive
def : InstRW<[VecXsPm, Lat4], (instregex "L(C|N|P)DR$")>;
def : InstRW<[VecXsPm, Lat4], (instregex "L(C|N|P)ER$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "L(C|N|P)XR$")>;
// Halve
def : InstRW<[VecBF], (instregex "H(E|D)R$")>;
// Square root
def : InstRW<[VecFPd, LSU], (instregex "SQ(E|D)$")>;
def : InstRW<[VecFPd], (instregex "SQ(E|D)R$")>;
def : InstRW<[VecFPd, VecFPd, GroupAlone], (instregex "SQXR$")>;
// Load FP integer
def : InstRW<[VecBF], (instregex "FIER$")>;
def : InstRW<[VecBF], (instregex "FIDR$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "FIXR$")>;
//===----------------------------------------------------------------------===//
// HFP: Binary arithmetic
//===----------------------------------------------------------------------===//
// Addition
def : InstRW<[VecBF, LSU, Lat12], (instregex "A(E|D|U|W)$")>;
def : InstRW<[VecBF], (instregex "A(E|D|U|W)R$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "AXR$")>;
// Subtraction
def : InstRW<[VecBF, LSU, Lat12], (instregex "S(E|D|U|W)$")>;
def : InstRW<[VecBF], (instregex "S(E|D|U|W)R$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "SXR$")>;
// Multiply
def : InstRW<[VecBF, LSU, Lat12], (instregex "M(D|DE|E|EE)$")>;
def : InstRW<[VecBF], (instregex "M(D|DE|E|EE)R$")>;
def : InstRW<[VecBF2, VecBF2, LSU, Lat12, GroupAlone], (instregex "MXD$")>;
def : InstRW<[VecBF2, VecBF2, GroupAlone], (instregex "MXDR$")>;
def : InstRW<[VecDF2, VecDF2, Lat20, GroupAlone], (instregex "MXR$")>;
def : InstRW<[VecBF2, VecBF2, LSU, Lat12, GroupAlone], (instregex "MY(H|L)?$")>;
def : InstRW<[VecBF2, VecBF2, GroupAlone], (instregex "MY(H|L)?R$")>;
// Multiply and add / subtract
def : InstRW<[VecBF, LSU, Lat12, GroupAlone], (instregex "M(A|S)E$")>;
def : InstRW<[VecBF, GroupAlone], (instregex "M(A|S)ER$")>;
def : InstRW<[VecBF, LSU, Lat12, GroupAlone], (instregex "M(A|S)D$")>;
def : InstRW<[VecBF], (instregex "M(A|S)DR$")>;
def : InstRW<[VecBF2, VecBF2, LSU, Lat12, GroupAlone], (instregex "MAY(H|L)?$")>;
def : InstRW<[VecBF2, VecBF2, GroupAlone], (instregex "MAY(H|L)?R$")>;
// Division
def : InstRW<[VecFPd, LSU], (instregex "D(E|D)$")>;
def : InstRW<[VecFPd], (instregex "D(E|D)R$")>;
def : InstRW<[VecFPd, VecFPd, GroupAlone], (instregex "DXR$")>;
//===----------------------------------------------------------------------===//
// HFP: Comparisons
//===----------------------------------------------------------------------===//
// Compare
def : InstRW<[VecXsPm, LSU, Lat8], (instregex "C(E|D)$")>;
def : InstRW<[VecXsPm, Lat4], (instregex "C(E|D)R$")>;
def : InstRW<[VecDF, VecDF, Lat20, GroupAlone], (instregex "CXR$")>;
// ------------------------ Decimal floating point -------------------------- //
//===----------------------------------------------------------------------===//
// DFP: Move instructions
//===----------------------------------------------------------------------===//
// Load and Test
def : InstRW<[VecDF], (instregex "LTDTR$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "LTXTR$")>;
//===----------------------------------------------------------------------===//
// DFP: Conversion instructions
//===----------------------------------------------------------------------===//
// Load rounded
def : InstRW<[VecDF, Lat15], (instregex "LEDTR$")>;
def : InstRW<[VecDF, VecDF, Lat20], (instregex "LDXTR$")>;
// Load lengthened
def : InstRW<[VecDF], (instregex "LDETR$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "LXDTR$")>;
// Convert from fixed / logical
def : InstRW<[FXb, VecDF, Lat30, BeginGroup], (instregex "CD(F|G)TR(A)?$")>;
def : InstRW<[FXb, VecDF2, VecDF2, Lat30, GroupAlone], (instregex "CX(F|G)TR(A)?$")>;
def : InstRW<[FXb, VecDF, Lat30, BeginGroup], (instregex "CDL(F|G)TR$")>;
def : InstRW<[FXb, VecDF2, VecDF2, Lat30, GroupAlone], (instregex "CXL(F|G)TR$")>;
// Convert to fixed / logical
def : InstRW<[FXb, VecDF, Lat30, BeginGroup], (instregex "C(F|G)DTR(A)?$")>;
def : InstRW<[FXb, VecDF, VecDF, Lat30, BeginGroup], (instregex "C(F|G)XTR(A)?$")>;
def : InstRW<[FXb, VecDF, Lat30, BeginGroup], (instregex "CL(F|G)DTR$")>;
def : InstRW<[FXb, VecDF, VecDF, Lat30, BeginGroup], (instregex "CL(F|G)XTR$")>;
// Convert from / to signed / unsigned packed
def : InstRW<[FXb, VecDF, Lat9, BeginGroup], (instregex "CD(S|U)TR$")>;
def : InstRW<[FXb, FXb, VecDF2, VecDF2, Lat15, GroupAlone], (instregex "CX(S|U)TR$")>;
def : InstRW<[FXb, VecDF, Lat12, BeginGroup], (instregex "C(S|U)DTR$")>;
def : InstRW<[FXb, FXb, VecDF2, VecDF2, Lat15, BeginGroup], (instregex "C(S|U)XTR$")>;
// Convert from / to zoned
def : InstRW<[LSU, VecDF, Lat11, BeginGroup], (instregex "CDZT$")>;
def : InstRW<[LSU, LSU, VecDF2, VecDF2, Lat15, GroupAlone], (instregex "CXZT$")>;
def : InstRW<[FXb, LSU, VecDF, Lat11, BeginGroup], (instregex "CZDT$")>;
def : InstRW<[FXb, LSU, VecDF, VecDF, Lat15, GroupAlone], (instregex "CZXT$")>;
// Convert from / to packed
def : InstRW<[LSU, VecDF, Lat11, BeginGroup], (instregex "CDPT$")>;
def : InstRW<[LSU, LSU, VecDF2, VecDF2, Lat15, GroupAlone], (instregex "CXPT$")>;
def : InstRW<[FXb, LSU, VecDF, Lat11, BeginGroup], (instregex "CPDT$")>;
def : InstRW<[FXb, LSU, VecDF, VecDF, Lat15, GroupAlone], (instregex "CPXT$")>;
// Perform floating-point operation
def : InstRW<[LSU, Lat30, GroupAlone], (instregex "PFPO$")>;
//===----------------------------------------------------------------------===//
// DFP: Unary arithmetic
//===----------------------------------------------------------------------===//
// Load FP integer
def : InstRW<[VecDF], (instregex "FIDTR$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "FIXTR$")>;
// Extract biased exponent
def : InstRW<[FXb, VecDF, Lat12, BeginGroup], (instregex "EEDTR$")>;
def : InstRW<[FXb, VecDF, Lat12, BeginGroup], (instregex "EEXTR$")>;
// Extract significance
def : InstRW<[FXb, VecDF, Lat12, BeginGroup], (instregex "ESDTR$")>;
def : InstRW<[FXb, VecDF, VecDF, Lat15, BeginGroup], (instregex "ESXTR$")>;
//===----------------------------------------------------------------------===//
// DFP: Binary arithmetic
//===----------------------------------------------------------------------===//
// Addition
def : InstRW<[VecDF], (instregex "ADTR(A)?$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "AXTR(A)?$")>;
// Subtraction
def : InstRW<[VecDF], (instregex "SDTR(A)?$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "SXTR(A)?$")>;
// Multiply
def : InstRW<[VecDF, Lat30], (instregex "MDTR(A)?$")>;
def : InstRW<[VecDF2, VecDF2, Lat30, GroupAlone], (instregex "MXTR(A)?$")>;
// Division
def : InstRW<[VecDF, Lat30], (instregex "DDTR(A)?$")>;
def : InstRW<[VecDF2, VecDF2, Lat30, GroupAlone], (instregex "DXTR(A)?$")>;
// Quantize
def : InstRW<[VecDF], (instregex "QADTR$")>;
def : InstRW<[VecDF2, VecDF2, Lat11, GroupAlone], (instregex "QAXTR$")>;
// Reround
def : InstRW<[FXb, VecDF, Lat11], (instregex "RRDTR$")>;
def : InstRW<[FXb, VecDF2, VecDF2, Lat15, GroupAlone], (instregex "RRXTR$")>;
// Shift significand left/right
def : InstRW<[LSU, VecDF, Lat11], (instregex "S(L|R)DT$")>;
def : InstRW<[LSU, VecDF2, VecDF2, Lat15, GroupAlone], (instregex "S(L|R)XT$")>;
// Insert biased exponent
def : InstRW<[FXb, VecDF, Lat11], (instregex "IEDTR$")>;
def : InstRW<[FXb, VecDF2, VecDF2, Lat15, GroupAlone], (instregex "IEXTR$")>;
//===----------------------------------------------------------------------===//
// DFP: Comparisons
//===----------------------------------------------------------------------===//
// Compare
def : InstRW<[VecDF], (instregex "(K|C)DTR$")>;
def : InstRW<[VecDF, VecDF, Lat11, GroupAlone], (instregex "(K|C)XTR$")>;
// Compare biased exponent
def : InstRW<[VecDF], (instregex "CEDTR$")>;
def : InstRW<[VecDF], (instregex "CEXTR$")>;
// Test Data Class/Group
def : InstRW<[LSU, VecDF, Lat11], (instregex "TD(C|G)(E|D)T$")>;
def : InstRW<[LSU, VecDF2, VecDF2, Lat15, GroupAlone], (instregex "TD(C|G)XT$")>;
// --------------------------------- Vector --------------------------------- //
//===----------------------------------------------------------------------===//

View File

@ -839,5 +839,224 @@ def : InstRW<[FXU, Lat30, GroupAlone], (instregex "SFASR$")>;
def : InstRW<[FXU, LSU, Lat30, GroupAlone], (instregex "LFAS$")>;
def : InstRW<[FXU, Lat2, GroupAlone], (instregex "SRNM(B|T)?$")>;
// --------------------- Hexadecimal floating point ------------------------- //
//===----------------------------------------------------------------------===//
// HFP: Move instructions
//===----------------------------------------------------------------------===//
// Load and Test
def : InstRW<[FPU], (instregex "LT(D|E)R$")>;
def : InstRW<[FPU2, FPU2, Lat9, GroupAlone], (instregex "LTXR$")>;
//===----------------------------------------------------------------------===//
// HFP: Conversion instructions
//===----------------------------------------------------------------------===//
// Load rounded
def : InstRW<[FPU], (instregex "(LEDR|LRER)$")>;
def : InstRW<[FPU], (instregex "LEXR$")>;
def : InstRW<[FPU], (instregex "(LDXR|LRDR)$")>;
// Load lengthened
def : InstRW<[LSU], (instregex "LDE$")>;
def : InstRW<[FXU], (instregex "LDER$")>;
def : InstRW<[FPU2, FPU2, LSU, Lat15, GroupAlone], (instregex "LX(D|E)$")>;
def : InstRW<[FPU2, FPU2, Lat10, GroupAlone], (instregex "LX(D|E)R$")>;
// Convert from fixed
def : InstRW<[FXU, FPU, Lat9, GroupAlone], (instregex "CE(F|G)R$")>;
def : InstRW<[FXU, FPU, Lat9, GroupAlone], (instregex "CD(F|G)R$")>;
def : InstRW<[FXU, FPU2, FPU2, Lat11, GroupAlone], (instregex "CX(F|G)R$")>;
// Convert to fixed
def : InstRW<[FXU, FPU, Lat12, GroupAlone], (instregex "CF(E|D)R$")>;
def : InstRW<[FXU, FPU, Lat12, GroupAlone], (instregex "CG(E|D)R$")>;
def : InstRW<[FXU, FPU, FPU, Lat20, GroupAlone], (instregex "C(F|G)XR$")>;
// Convert BFP to HFP / HFP to BFP.
def : InstRW<[FPU], (instregex "THD(E)?R$")>;
def : InstRW<[FPU], (instregex "TB(E)?DR$")>;
//===----------------------------------------------------------------------===//
// HFP: Unary arithmetic
//===----------------------------------------------------------------------===//
// Load Complement / Negative / Positive
def : InstRW<[FPU], (instregex "L(C|N|P)DR$")>;
def : InstRW<[FPU], (instregex "L(C|N|P)ER$")>;
def : InstRW<[FPU2, FPU2, Lat9, GroupAlone], (instregex "L(C|N|P)XR$")>;
// Halve
def : InstRW<[FPU], (instregex "H(E|D)R$")>;
// Square root
def : InstRW<[FPU, LSU, Lat30], (instregex "SQ(E|D)$")>;
def : InstRW<[FPU, Lat30], (instregex "SQ(E|D)R$")>;
def : InstRW<[FPU2, FPU2, Lat30, GroupAlone], (instregex "SQXR$")>;
// Load FP integer
def : InstRW<[FPU], (instregex "FIER$")>;
def : InstRW<[FPU], (instregex "FIDR$")>;
def : InstRW<[FPU2, FPU2, Lat15, GroupAlone], (instregex "FIXR$")>;
//===----------------------------------------------------------------------===//
// HFP: Binary arithmetic
//===----------------------------------------------------------------------===//
// Addition
def : InstRW<[FPU, LSU, Lat12], (instregex "A(E|D|U|W)$")>;
def : InstRW<[FPU], (instregex "A(E|D|U|W)R$")>;
def : InstRW<[FPU2, FPU2, Lat20, GroupAlone], (instregex "AXR$")>;
// Subtraction
def : InstRW<[FPU, LSU, Lat12], (instregex "S(E|D|U|W)$")>;
def : InstRW<[FPU], (instregex "S(E|D|U|W)R$")>;
def : InstRW<[FPU2, FPU2, Lat20, GroupAlone], (instregex "SXR$")>;
// Multiply
def : InstRW<[FPU, LSU, Lat12], (instregex "M(D|DE|E|EE)$")>;
def : InstRW<[FPU], (instregex "M(D|DE|E|EE)R$")>;
def : InstRW<[FPU2, FPU2, LSU, Lat15, GroupAlone], (instregex "MXD$")>;
def : InstRW<[FPU2, FPU2, Lat10, GroupAlone], (instregex "MXDR$")>;
def : InstRW<[FPU2, FPU2, Lat30, GroupAlone], (instregex "MXR$")>;
def : InstRW<[FPU2, FPU2, LSU, Lat15, GroupAlone], (instregex "MY(H|L)?$")>;
def : InstRW<[FPU2, FPU2, Lat10, GroupAlone], (instregex "MY(H|L)?R$")>;
// Multiply and add / subtract
def : InstRW<[FPU, LSU, Lat12, GroupAlone], (instregex "M(A|S)E$")>;
def : InstRW<[FPU, GroupAlone], (instregex "M(A|S)ER$")>;
def : InstRW<[FPU, LSU, Lat12, GroupAlone], (instregex "M(A|S)D$")>;
def : InstRW<[FPU, GroupAlone], (instregex "M(A|S)DR$")>;
def : InstRW<[FPU2, FPU2, LSU, Lat12, GroupAlone], (instregex "MAY(H|L)?$")>;
def : InstRW<[FPU2, FPU2, GroupAlone], (instregex "MAY(H|L)?R$")>;
// Division
def : InstRW<[FPU, LSU, Lat30], (instregex "D(E|D)$")>;
def : InstRW<[FPU, Lat30], (instregex "D(E|D)R$")>;
def : InstRW<[FPU2, FPU2, Lat30, GroupAlone], (instregex "DXR$")>;
//===----------------------------------------------------------------------===//
// HFP: Comparisons
//===----------------------------------------------------------------------===//
// Compare
def : InstRW<[FPU, LSU, Lat12], (instregex "C(E|D)$")>;
def : InstRW<[FPU], (instregex "C(E|D)R$")>;
def : InstRW<[FPU, FPU, Lat15], (instregex "CXR$")>;
// ------------------------ Decimal floating point -------------------------- //
//===----------------------------------------------------------------------===//
// DFP: Move instructions
//===----------------------------------------------------------------------===//
// Load and Test
def : InstRW<[DFU, Lat20], (instregex "LTDTR$")>;
def : InstRW<[DFU2, DFU2, Lat20, GroupAlone], (instregex "LTXTR$")>;
//===----------------------------------------------------------------------===//
// DFP: Conversion instructions
//===----------------------------------------------------------------------===//
// Load rounded
def : InstRW<[DFU, Lat30], (instregex "LEDTR$")>;
def : InstRW<[DFU, DFU, Lat30], (instregex "LDXTR$")>;
// Load lengthened
def : InstRW<[DFU, Lat20], (instregex "LDETR$")>;
def : InstRW<[DFU2, DFU2, Lat20, GroupAlone], (instregex "LXDTR$")>;
// Convert from fixed / logical
def : InstRW<[FXU, DFU, Lat30, GroupAlone], (instregex "CD(F|G)TR(A)?$")>;
def : InstRW<[FXU, DFU2, DFU2, Lat30, GroupAlone], (instregex "CX(F|G)TR(A)?$")>;
def : InstRW<[FXU, DFU, Lat11, GroupAlone], (instregex "CDL(F|G)TR$")>;
def : InstRW<[FXU, DFU2, DFU2, Lat11, GroupAlone], (instregex "CXL(F|G)TR$")>;
// Convert to fixed / logical
def : InstRW<[FXU, DFU, Lat30, GroupAlone], (instregex "C(F|G)DTR(A)?$")>;
def : InstRW<[FXU, DFU, DFU, Lat30, GroupAlone], (instregex "C(F|G)XTR(A)?$")>;
def : InstRW<[FXU, DFU, Lat30, GroupAlone], (instregex "CL(F|G)DTR$")>;
def : InstRW<[FXU, DFU, DFU, Lat30, GroupAlone], (instregex "CL(F|G)XTR$")>;
// Convert from / to signed / unsigned packed
def : InstRW<[FXU, DFU, Lat12, GroupAlone], (instregex "CD(S|U)TR$")>;
def : InstRW<[FXU, FXU, DFU2, DFU2, Lat20, GroupAlone], (instregex "CX(S|U)TR$")>;
def : InstRW<[FXU, DFU, Lat12, GroupAlone], (instregex "C(S|U)DTR$")>;
def : InstRW<[FXU, FXU, DFU2, DFU2, Lat20, GroupAlone], (instregex "C(S|U)XTR$")>;
// Perform floating-point operation
def : InstRW<[LSU, Lat30, GroupAlone], (instregex "PFPO$")>;
//===----------------------------------------------------------------------===//
// DFP: Unary arithmetic
//===----------------------------------------------------------------------===//
// Load FP integer
def : InstRW<[DFU, Lat20], (instregex "FIDTR$")>;
def : InstRW<[DFU2, DFU2, Lat20, GroupAlone], (instregex "FIXTR$")>;
// Extract biased exponent
def : InstRW<[FXU, DFU, Lat15, GroupAlone], (instregex "EEDTR$")>;
def : InstRW<[FXU, DFU, Lat15, GroupAlone], (instregex "EEXTR$")>;
// Extract significance
def : InstRW<[FXU, DFU, Lat15, GroupAlone], (instregex "ESDTR$")>;
def : InstRW<[FXU, DFU, DFU, Lat20, GroupAlone], (instregex "ESXTR$")>;
//===----------------------------------------------------------------------===//
// DFP: Binary arithmetic
//===----------------------------------------------------------------------===//
// Addition
def : InstRW<[DFU, Lat30], (instregex "ADTR(A)?$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "AXTR(A)?$")>;
// Subtraction
def : InstRW<[DFU, Lat30], (instregex "SDTR(A)?$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "SXTR(A)?$")>;
// Multiply
def : InstRW<[DFU, Lat30], (instregex "MDTR(A)?$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "MXTR(A)?$")>;
// Division
def : InstRW<[DFU, Lat30], (instregex "DDTR(A)?$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "DXTR(A)?$")>;
// Quantize
def : InstRW<[DFU, Lat30], (instregex "QADTR$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "QAXTR$")>;
// Reround
def : InstRW<[FXU, DFU, Lat30], (instregex "RRDTR$")>;
def : InstRW<[FXU, DFU2, DFU2, Lat30, GroupAlone], (instregex "RRXTR$")>;
// Shift significand left/right
def : InstRW<[LSU, DFU, Lat11], (instregex "S(L|R)DT$")>;
def : InstRW<[LSU, DFU2, DFU2, Lat15, GroupAlone], (instregex "S(L|R)XT$")>;
// Insert biased exponent
def : InstRW<[FXU, DFU, Lat11], (instregex "IEDTR$")>;
def : InstRW<[FXU, DFU2, DFU2, Lat15, GroupAlone], (instregex "IEXTR$")>;
//===----------------------------------------------------------------------===//
// DFP: Comparisons
//===----------------------------------------------------------------------===//
// Compare
def : InstRW<[DFU, Lat11], (instregex "(K|C)DTR$")>;
def : InstRW<[DFU, DFU, Lat15, GroupAlone], (instregex "(K|C)XTR$")>;
// Compare biased exponent
def : InstRW<[DFU, Lat8], (instregex "CEDTR$")>;
def : InstRW<[DFU, Lat9], (instregex "CEXTR$")>;
// Test Data Class/Group
def : InstRW<[LSU, DFU, Lat15], (instregex "TD(C|G)(E|D)T$")>;
def : InstRW<[LSU, DFU2, DFU2, Lat15, GroupAlone], (instregex "TD(C|G)XT$")>;
}

View File

@ -877,5 +877,230 @@ def : InstRW<[FXU, Lat30, GroupAlone], (instregex "SFASR$")>;
def : InstRW<[FXU, LSU, Lat30, GroupAlone], (instregex "LFAS$")>;
def : InstRW<[FXU, Lat2, GroupAlone], (instregex "SRNM(B|T)?$")>;
// --------------------- Hexadecimal floating point ------------------------- //
//===----------------------------------------------------------------------===//
// HFP: Move instructions
//===----------------------------------------------------------------------===//
// Load and Test
def : InstRW<[FPU], (instregex "LT(D|E)R$")>;
def : InstRW<[FPU2, FPU2, Lat9, GroupAlone], (instregex "LTXR$")>;
//===----------------------------------------------------------------------===//
// HFP: Conversion instructions
//===----------------------------------------------------------------------===//
// Load rounded
def : InstRW<[FPU], (instregex "(LEDR|LRER)$")>;
def : InstRW<[FPU], (instregex "LEXR$")>;
def : InstRW<[FPU], (instregex "(LDXR|LRDR)$")>;
// Load lengthened
def : InstRW<[LSU], (instregex "LDE$")>;
def : InstRW<[FXU], (instregex "LDER$")>;
def : InstRW<[FPU2, FPU2, LSU, Lat15, GroupAlone], (instregex "LX(D|E)$")>;
def : InstRW<[FPU2, FPU2, Lat10, GroupAlone], (instregex "LX(D|E)R$")>;
// Convert from fixed
def : InstRW<[FXU, FPU, Lat9, GroupAlone], (instregex "CE(F|G)R$")>;
def : InstRW<[FXU, FPU, Lat9, GroupAlone], (instregex "CD(F|G)R$")>;
def : InstRW<[FXU, FPU2, FPU2, Lat11, GroupAlone], (instregex "CX(F|G)R$")>;
// Convert to fixed
def : InstRW<[FXU, FPU, Lat12, GroupAlone], (instregex "CF(E|D)R$")>;
def : InstRW<[FXU, FPU, Lat12, GroupAlone], (instregex "CG(E|D)R$")>;
def : InstRW<[FXU, FPU, FPU, Lat20, GroupAlone], (instregex "C(F|G)XR$")>;
// Convert BFP to HFP / HFP to BFP.
def : InstRW<[FPU], (instregex "THD(E)?R$")>;
def : InstRW<[FPU], (instregex "TB(E)?DR$")>;
//===----------------------------------------------------------------------===//
// HFP: Unary arithmetic
//===----------------------------------------------------------------------===//
// Load Complement / Negative / Positive
def : InstRW<[FPU], (instregex "L(C|N|P)DR$")>;
def : InstRW<[FPU], (instregex "L(C|N|P)ER$")>;
def : InstRW<[FPU2, FPU2, Lat9, GroupAlone], (instregex "L(C|N|P)XR$")>;
// Halve
def : InstRW<[FPU], (instregex "H(E|D)R$")>;
// Square root
def : InstRW<[FPU, LSU, Lat30], (instregex "SQ(E|D)$")>;
def : InstRW<[FPU, Lat30], (instregex "SQ(E|D)R$")>;
def : InstRW<[FPU2, FPU2, Lat30, GroupAlone], (instregex "SQXR$")>;
// Load FP integer
def : InstRW<[FPU], (instregex "FIER$")>;
def : InstRW<[FPU], (instregex "FIDR$")>;
def : InstRW<[FPU2, FPU2, Lat15, GroupAlone], (instregex "FIXR$")>;
//===----------------------------------------------------------------------===//
// HFP: Binary arithmetic
//===----------------------------------------------------------------------===//
// Addition
def : InstRW<[FPU, LSU, Lat12], (instregex "A(E|D|U|W)$")>;
def : InstRW<[FPU], (instregex "A(E|D|U|W)R$")>;
def : InstRW<[FPU2, FPU2, Lat20, GroupAlone], (instregex "AXR$")>;
// Subtraction
def : InstRW<[FPU, LSU, Lat12], (instregex "S(E|D|U|W)$")>;
def : InstRW<[FPU], (instregex "S(E|D|U|W)R$")>;
def : InstRW<[FPU2, FPU2, Lat20, GroupAlone], (instregex "SXR$")>;
// Multiply
def : InstRW<[FPU, LSU, Lat12], (instregex "M(D|DE|E|EE)$")>;
def : InstRW<[FPU], (instregex "M(D|DE|E|EE)R$")>;
def : InstRW<[FPU2, FPU2, LSU, Lat15, GroupAlone], (instregex "MXD$")>;
def : InstRW<[FPU2, FPU2, Lat10, GroupAlone], (instregex "MXDR$")>;
def : InstRW<[FPU2, FPU2, Lat30, GroupAlone], (instregex "MXR$")>;
def : InstRW<[FPU2, FPU2, LSU, Lat15, GroupAlone], (instregex "MY(H|L)?$")>;
def : InstRW<[FPU2, FPU2, Lat10, GroupAlone], (instregex "MY(H|L)?R$")>;
// Multiply and add / subtract
def : InstRW<[FPU, LSU, Lat12, GroupAlone], (instregex "M(A|S)E$")>;
def : InstRW<[FPU, GroupAlone], (instregex "M(A|S)ER$")>;
def : InstRW<[FPU, LSU, Lat12, GroupAlone], (instregex "M(A|S)D$")>;
def : InstRW<[FPU, GroupAlone], (instregex "M(A|S)DR$")>;
def : InstRW<[FPU2, FPU2, LSU, Lat12, GroupAlone], (instregex "MAY(H|L)?$")>;
def : InstRW<[FPU2, FPU2, GroupAlone], (instregex "MAY(H|L)?R$")>;
// Division
def : InstRW<[FPU, LSU, Lat30], (instregex "D(E|D)$")>;
def : InstRW<[FPU, Lat30], (instregex "D(E|D)R$")>;
def : InstRW<[FPU2, FPU2, Lat30, GroupAlone], (instregex "DXR$")>;
//===----------------------------------------------------------------------===//
// HFP: Comparisons
//===----------------------------------------------------------------------===//
// Compare
def : InstRW<[FPU, LSU, Lat12], (instregex "C(E|D)$")>;
def : InstRW<[FPU], (instregex "C(E|D)R$")>;
def : InstRW<[FPU, FPU, Lat15], (instregex "CXR$")>;
// ------------------------ Decimal floating point -------------------------- //
//===----------------------------------------------------------------------===//
// DFP: Move instructions
//===----------------------------------------------------------------------===//
// Load and Test
def : InstRW<[DFU, Lat20], (instregex "LTDTR$")>;
def : InstRW<[DFU2, DFU2, Lat20, GroupAlone], (instregex "LTXTR$")>;
//===----------------------------------------------------------------------===//
// DFP: Conversion instructions
//===----------------------------------------------------------------------===//
// Load rounded
def : InstRW<[DFU, Lat30], (instregex "LEDTR$")>;
def : InstRW<[DFU, DFU, Lat30], (instregex "LDXTR$")>;
// Load lengthened
def : InstRW<[DFU, Lat20], (instregex "LDETR$")>;
def : InstRW<[DFU2, DFU2, Lat20, GroupAlone], (instregex "LXDTR$")>;
// Convert from fixed / logical
def : InstRW<[FXU, DFU, Lat30, GroupAlone], (instregex "CD(F|G)TR(A)?$")>;
def : InstRW<[FXU, DFU2, DFU2, Lat30, GroupAlone], (instregex "CX(F|G)TR(A)?$")>;
def : InstRW<[FXU, DFU, Lat11, GroupAlone], (instregex "CDL(F|G)TR$")>;
def : InstRW<[FXU, DFU2, DFU2, Lat11, GroupAlone], (instregex "CXL(F|G)TR$")>;
// Convert to fixed / logical
def : InstRW<[FXU, DFU, Lat30, GroupAlone], (instregex "C(F|G)DTR(A)?$")>;
def : InstRW<[FXU, DFU, DFU, Lat30, GroupAlone], (instregex "C(F|G)XTR(A)?$")>;
def : InstRW<[FXU, DFU, Lat30, GroupAlone], (instregex "CL(F|G)DTR$")>;
def : InstRW<[FXU, DFU, DFU, Lat30, GroupAlone], (instregex "CL(F|G)XTR$")>;
// Convert from / to signed / unsigned packed
def : InstRW<[FXU, DFU, Lat12, GroupAlone], (instregex "CD(S|U)TR$")>;
def : InstRW<[FXU, FXU, DFU2, DFU2, Lat20, GroupAlone], (instregex "CX(S|U)TR$")>;
def : InstRW<[FXU, DFU, Lat12, GroupAlone], (instregex "C(S|U)DTR$")>;
def : InstRW<[FXU, FXU, DFU2, DFU2, Lat20, GroupAlone], (instregex "C(S|U)XTR$")>;
// Convert from / to zoned
def : InstRW<[LSU, DFU2, Lat7, GroupAlone], (instregex "CDZT$")>;
def : InstRW<[LSU, LSU, DFU2, DFU2, Lat10, GroupAlone], (instregex "CXZT$")>;
def : InstRW<[FXU, LSU, DFU, Lat11, GroupAlone], (instregex "CZDT$")>;
def : InstRW<[FXU, LSU, DFU, DFU, Lat15, GroupAlone], (instregex "CZXT$")>;
// Perform floating-point operation
def : InstRW<[LSU, Lat30, GroupAlone], (instregex "PFPO$")>;
//===----------------------------------------------------------------------===//
// DFP: Unary arithmetic
//===----------------------------------------------------------------------===//
// Load FP integer
def : InstRW<[DFU, Lat20], (instregex "FIDTR$")>;
def : InstRW<[DFU2, DFU2, Lat20, GroupAlone], (instregex "FIXTR$")>;
// Extract biased exponent
def : InstRW<[FXU, DFU, Lat15, GroupAlone], (instregex "EEDTR$")>;
def : InstRW<[FXU, DFU, Lat15, GroupAlone], (instregex "EEXTR$")>;
// Extract significance
def : InstRW<[FXU, DFU, Lat15, GroupAlone], (instregex "ESDTR$")>;
def : InstRW<[FXU, DFU, DFU, Lat20, GroupAlone], (instregex "ESXTR$")>;
//===----------------------------------------------------------------------===//
// DFP: Binary arithmetic
//===----------------------------------------------------------------------===//
// Addition
def : InstRW<[DFU, Lat30], (instregex "ADTR(A)?$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "AXTR(A)?$")>;
// Subtraction
def : InstRW<[DFU, Lat30], (instregex "SDTR(A)?$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "SXTR(A)?$")>;
// Multiply
def : InstRW<[DFU, Lat30], (instregex "MDTR(A)?$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "MXTR(A)?$")>;
// Division
def : InstRW<[DFU, Lat30], (instregex "DDTR(A)?$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "DXTR(A)?$")>;
// Quantize
def : InstRW<[DFU, Lat30], (instregex "QADTR$")>;
def : InstRW<[DFU2, DFU2, Lat30, GroupAlone], (instregex "QAXTR$")>;
// Reround
def : InstRW<[FXU, DFU, Lat30], (instregex "RRDTR$")>;
def : InstRW<[FXU, DFU2, DFU2, Lat30, GroupAlone], (instregex "RRXTR$")>;
// Shift significand left/right
def : InstRW<[LSU, DFU, Lat11], (instregex "S(L|R)DT$")>;
def : InstRW<[LSU, DFU2, DFU2, Lat15, GroupAlone], (instregex "S(L|R)XT$")>;
// Insert biased exponent
def : InstRW<[FXU, DFU, Lat11], (instregex "IEDTR$")>;
def : InstRW<[FXU, DFU2, DFU2, Lat15, GroupAlone], (instregex "IEXTR$")>;
//===----------------------------------------------------------------------===//
// DFP: Comparisons
//===----------------------------------------------------------------------===//
// Compare
def : InstRW<[DFU, Lat11], (instregex "(K|C)DTR$")>;
def : InstRW<[DFU, DFU, Lat15, GroupAlone], (instregex "(K|C)XTR$")>;
// Compare biased exponent
def : InstRW<[DFU, Lat8], (instregex "CEDTR$")>;
def : InstRW<[DFU, Lat9], (instregex "CEXTR$")>;
// Test Data Class/Group
def : InstRW<[LSU, DFU, Lat15], (instregex "TD(C|G)(E|D)T$")>;
def : InstRW<[LSU, DFU2, DFU2, Lat15, GroupAlone], (instregex "TD(C|G)XT$")>;
}

View File

@ -42,8 +42,10 @@ SystemZSubtarget::SystemZSubtarget(const Triple &TT, const std::string &CPU,
HasMiscellaneousExtensions(false),
HasExecutionHint(false), HasLoadAndTrap(false),
HasTransactionalExecution(false), HasProcessorAssist(false),
HasDFPZonedConversion(false),
HasVector(false), HasLoadStoreOnCond2(false),
HasLoadAndZeroRightmostByte(false), HasMessageSecurityAssist5(false),
HasDFPPackedConversion(false),
TargetTriple(TT), InstrInfo(initializeSubtargetDependencies(CPU, FS)),
TLInfo(TM, *this), TSInfo(), FrameLowering() {}

View File

@ -47,10 +47,12 @@ class SystemZSubtarget : public SystemZGenSubtargetInfo {
bool HasLoadAndTrap;
bool HasTransactionalExecution;
bool HasProcessorAssist;
bool HasDFPZonedConversion;
bool HasVector;
bool HasLoadStoreOnCond2;
bool HasLoadAndZeroRightmostByte;
bool HasMessageSecurityAssist5;
bool HasDFPPackedConversion;
private:
Triple TargetTriple;
@ -133,6 +135,9 @@ class SystemZSubtarget : public SystemZGenSubtargetInfo {
// Return true if the target has the processor-assist facility.
bool hasProcessorAssist() const { return HasProcessorAssist; }
// Return true if the target has the DFP zoned-conversion facility.
bool hasDFPZonedConversion() const { return HasDFPZonedConversion; }
// Return true if the target has the load-and-zero-rightmost-byte facility.
bool hasLoadAndZeroRightmostByte() const {
return HasLoadAndZeroRightmostByte;
@ -142,6 +147,9 @@ class SystemZSubtarget : public SystemZGenSubtargetInfo {
// extension facility 5.
bool hasMessageSecurityAssist5() const { return HasMessageSecurityAssist5; }
// Return true if the target has the DFP packed-conversion facility.
bool hasDFPPackedConversion() const { return HasDFPPackedConversion; }
// Return true if the target has the vector facility.
bool hasVector() const { return HasVector; }

View File

@ -84,8 +84,8 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
ISD::SETULT, ISD::SETULE, ISD::SETUGT, ISD::SETUGE})
setCondCodeAction(CC, T, Expand);
// Expand floating-point library function operators.
for (auto Op : {ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOWI, ISD::FPOW,
ISD::FREM, ISD::FMA})
for (auto Op : {ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOW, ISD::FREM,
ISD::FMA})
setOperationAction(Op, T, Expand);
// Note supported floating-point library function operators that otherwise
// default to expand.

View File

@ -80,6 +80,12 @@ static cl::opt<int> ExperimentalPrefLoopAlignment(
" of the loop header PC will be 0)."),
cl::Hidden);
static cl::opt<bool> MulConstantOptimization(
"mul-constant-optimization", cl::init(true),
cl::desc("Replace 'mul x, Const' with more effective instructions like "
"SHIFT, LEA, etc."),
cl::Hidden);
/// Call this when the user attempts to do something unsupported, like
/// returning a double without SSE2 enabled on x86_64. This is not fatal, unlike
/// report_fatal_error, so calling code should attempt to recover without
@ -670,7 +676,6 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::FSINCOS, VT, Expand);
setOperationAction(ISD::FCOS, VT, Expand);
setOperationAction(ISD::FREM, VT, Expand);
setOperationAction(ISD::FPOWI, VT, Expand);
setOperationAction(ISD::FCOPYSIGN, VT, Expand);
setOperationAction(ISD::FPOW, VT, Expand);
setOperationAction(ISD::FLOG, VT, Expand);
@ -30928,6 +30933,75 @@ static SDValue reduceVMULWidth(SDNode *N, SelectionDAG &DAG,
}
}
static SDValue combineMulSpecial(uint64_t MulAmt, SDNode *N, SelectionDAG &DAG,
EVT VT, SDLoc DL) {
auto combineMulShlAddOrSub = [&](int Mult, int Shift, bool isAdd) {
SDValue Result = DAG.getNode(X86ISD::MUL_IMM, DL, VT, N->getOperand(0),
DAG.getConstant(Mult, DL, VT));
Result = DAG.getNode(ISD::SHL, DL, VT, Result,
DAG.getConstant(Shift, DL, MVT::i8));
Result = DAG.getNode(isAdd ? ISD::ADD : ISD::SUB, DL, VT, N->getOperand(0),
Result);
return Result;
};
auto combineMulMulAddOrSub = [&](bool isAdd) {
SDValue Result = DAG.getNode(X86ISD::MUL_IMM, DL, VT, N->getOperand(0),
DAG.getConstant(9, DL, VT));
Result = DAG.getNode(ISD::MUL, DL, VT, Result, DAG.getConstant(3, DL, VT));
Result = DAG.getNode(isAdd ? ISD::ADD : ISD::SUB, DL, VT, N->getOperand(0),
Result);
return Result;
};
switch (MulAmt) {
default:
break;
case 11:
// mul x, 11 => add ((shl (mul x, 5), 1), x)
return combineMulShlAddOrSub(5, 1, /*isAdd*/ true);
case 21:
// mul x, 21 => add ((shl (mul x, 5), 2), x)
return combineMulShlAddOrSub(5, 2, /*isAdd*/ true);
case 22:
// mul x, 22 => add (add ((shl (mul x, 5), 2), x), x)
return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
combineMulShlAddOrSub(5, 2, /*isAdd*/ true));
case 19:
// mul x, 19 => sub ((shl (mul x, 5), 2), x)
return combineMulShlAddOrSub(5, 2, /*isAdd*/ false);
case 13:
// mul x, 13 => add ((shl (mul x, 3), 2), x)
return combineMulShlAddOrSub(3, 2, /*isAdd*/ true);
case 23:
// mul x, 13 => sub ((shl (mul x, 3), 3), x)
return combineMulShlAddOrSub(3, 3, /*isAdd*/ false);
case 14:
// mul x, 14 => add (add ((shl (mul x, 3), 2), x), x)
return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
combineMulShlAddOrSub(3, 2, /*isAdd*/ true));
case 26:
// mul x, 26 => sub ((mul (mul x, 9), 3), x)
return combineMulMulAddOrSub(/*isAdd*/ false);
case 28:
// mul x, 28 => add ((mul (mul x, 9), 3), x)
return combineMulMulAddOrSub(/*isAdd*/ true);
case 29:
// mul x, 29 => add (add ((mul (mul x, 9), 3), x), x)
return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0),
combineMulMulAddOrSub(/*isAdd*/ true));
case 30:
// mul x, 30 => sub (sub ((shl x, 5), x), x)
return DAG.getNode(
ISD::SUB, DL, VT, N->getOperand(0),
DAG.getNode(ISD::SUB, DL, VT, N->getOperand(0),
DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
DAG.getConstant(5, DL, MVT::i8))));
}
return SDValue();
}
/// Optimize a single multiply with constant into two operations in order to
/// implement it with two cheaper instructions, e.g. LEA + SHL, LEA + LEA.
static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
@ -30937,6 +31011,8 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
if (DCI.isBeforeLegalize() && VT.isVector())
return reduceVMULWidth(N, DAG, Subtarget);
if (!MulConstantOptimization)
return SDValue();
// An imul is usually smaller than the alternative sequence.
if (DAG.getMachineFunction().getFunction()->optForMinSize())
return SDValue();
@ -30992,7 +31068,8 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
else
NewMul = DAG.getNode(X86ISD::MUL_IMM, DL, VT, NewMul,
DAG.getConstant(MulAmt2, DL, VT));
}
} else if (!Subtarget.slowLEA())
NewMul = combineMulSpecial(MulAmt, N, DAG, VT, DL);
if (!NewMul) {
assert(MulAmt != 0 &&

View File

@ -377,7 +377,6 @@ class CongruenceClass {
int StoreCount = 0;
};
struct HashedExpression;
namespace llvm {
template <> struct DenseMapInfo<const Expression *> {
static const Expression *getEmptyKey() {
@ -391,41 +390,25 @@ template <> struct DenseMapInfo<const Expression *> {
return reinterpret_cast<const Expression *>(Val);
}
static unsigned getHashValue(const Expression *E) {
return static_cast<unsigned>(E->getHashValue());
return static_cast<unsigned>(E->getComputedHash());
}
static unsigned getHashValue(const HashedExpression &HE);
static bool isEqual(const HashedExpression &LHS, const Expression *RHS);
static bool isEqual(const Expression *LHS, const Expression *RHS) {
if (LHS == RHS)
return true;
if (LHS == getTombstoneKey() || RHS == getTombstoneKey() ||
LHS == getEmptyKey() || RHS == getEmptyKey())
return false;
// Compare hashes before equality. This is *not* what the hashtable does,
// since it is computing it modulo the number of buckets, whereas we are
// using the full hash keyspace. Since the hashes are precomputed, this
// check is *much* faster than equality.
if (LHS->getComputedHash() != RHS->getComputedHash())
return false;
return *LHS == *RHS;
}
};
} // end namespace llvm
// This is just a wrapper around Expression that computes the hash value once at
// creation time. Hash values for an Expression can't change once they are
// inserted into the DenseMap (it breaks DenseMap), so they must be immutable at
// that point anyway.
struct HashedExpression {
const Expression *E;
unsigned HashVal;
HashedExpression(const Expression *E)
: E(E), HashVal(DenseMapInfo<const Expression *>::getHashValue(E)) {}
};
unsigned
DenseMapInfo<const Expression *>::getHashValue(const HashedExpression &HE) {
return HE.HashVal;
}
bool DenseMapInfo<const Expression *>::isEqual(const HashedExpression &LHS,
const Expression *RHS) {
return isEqual(LHS.E, RHS);
}
namespace {
class NewGVN {
Function &F;
@ -707,7 +690,7 @@ class NewGVN {
void markPredicateUsersTouched(Instruction *);
void markValueLeaderChangeTouched(CongruenceClass *CC);
void markMemoryLeaderChangeTouched(CongruenceClass *CC);
void markPhiOfOpsChanged(const HashedExpression &HE);
void markPhiOfOpsChanged(const Expression *E);
void addPredicateUsers(const PredicateBase *, Instruction *) const;
void addMemoryUsers(const MemoryAccess *To, MemoryAccess *U) const;
void addAdditionalUsers(Value *To, Value *User) const;
@ -956,8 +939,12 @@ const Expression *NewGVN::checkSimplificationResults(Expression *E,
if (CC && CC->getDefiningExpr()) {
// If we simplified to something else, we need to communicate
// that we're users of the value we simplified to.
if (I != V)
addAdditionalUsers(V, I);
if (I != V) {
// Don't add temporary instructions to the user lists.
if (!AllTempInstructions.count(I))
addAdditionalUsers(V, I);
}
if (I)
DEBUG(dbgs() << "Simplified " << *I << " to "
<< " expression " << *CC->getDefiningExpr() << "\n");
@ -2195,8 +2182,8 @@ void NewGVN::moveValueToNewCongruenceClass(Instruction *I, const Expression *E,
// For a given expression, mark the phi of ops instructions that could have
// changed as a result.
void NewGVN::markPhiOfOpsChanged(const HashedExpression &HE) {
touchAndErase(ExpressionToPhiOfOps, HE);
void NewGVN::markPhiOfOpsChanged(const Expression *E) {
touchAndErase(ExpressionToPhiOfOps, E);
}
// Perform congruence finding on a given value numbering expression.
@ -2210,14 +2197,13 @@ void NewGVN::performCongruenceFinding(Instruction *I, const Expression *E) {
assert(!IClass->isDead() && "Found a dead class");
CongruenceClass *EClass = nullptr;
HashedExpression HE(E);
if (const auto *VE = dyn_cast<VariableExpression>(E)) {
EClass = ValueToClass.lookup(VE->getVariableValue());
} else if (isa<DeadExpression>(E)) {
EClass = TOPClass;
}
if (!EClass) {
auto lookupResult = ExpressionToClass.insert_as({E, nullptr}, HE);
auto lookupResult = ExpressionToClass.insert({E, nullptr});
// If it's not in the value table, create a new congruence class.
if (lookupResult.second) {
@ -2268,7 +2254,7 @@ void NewGVN::performCongruenceFinding(Instruction *I, const Expression *E) {
<< "\n");
if (ClassChanged) {
moveValueToNewCongruenceClass(I, E, IClass, EClass);
markPhiOfOpsChanged(HE);
markPhiOfOpsChanged(E);
}
markUsersTouched(I);
@ -2502,9 +2488,8 @@ NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge,
// Clone the instruction, create an expression from it, and see if we
// have a leader.
Instruction *ValueOp = I->clone();
auto Iter = TempToMemory.end();
if (MemAccess)
Iter = TempToMemory.insert({ValueOp, MemAccess}).first;
TempToMemory.insert({ValueOp, MemAccess});
for (auto &Op : ValueOp->operands()) {
Op = Op->DoPHITranslation(PHIBlock, PredBB);
@ -2523,7 +2508,7 @@ NewGVN::makePossiblePhiOfOps(Instruction *I, bool HasBackedge,
AllTempInstructions.erase(ValueOp);
ValueOp->deleteValue();
if (MemAccess)
TempToMemory.erase(Iter);
TempToMemory.erase(ValueOp);
if (!E)
return nullptr;
FoundVal = findPhiOfOpsLeader(E, PredBB);

View File

@ -7173,7 +7173,7 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, unsigned VF) {
// Note: Even if all instructions are scalarized, return true if any memory
// accesses appear in the loop to get benefits from address folding etc.
bool TypeNotScalarized =
VF > 1 && VectorTy->isVectorTy() && TTI.getNumberOfParts(VectorTy) < VF;
VF > 1 && !VectorTy->isVoidTy() && TTI.getNumberOfParts(VectorTy) < VF;
return VectorizationCostTy(C, TypeNotScalarized);
}
@ -7312,7 +7312,7 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I,
Type *RetTy = I->getType();
if (canTruncateToMinimalBitwidth(I, VF))
RetTy = IntegerType::get(RetTy->getContext(), MinBWs[I]);
VectorTy = isScalarAfterVectorization(I, VF) ? RetTy : ToVectorTy(RetTy, VF);
VectorTy = ToVectorTy(RetTy, VF);
auto SE = PSE.getSE();
// TODO: We need to estimate the cost of intrinsic calls.
@ -7445,10 +7445,9 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I,
} else if (Legal->isUniform(Op2)) {
Op2VK = TargetTransformInfo::OK_UniformValue;
}
SmallVector<const Value *, 4> Operands(I->operand_values());
unsigned N = isScalarAfterVectorization(I, VF) ? VF : 1;
return N * TTI.getArithmeticInstrCost(I->getOpcode(), VectorTy, Op1VK,
Op2VK, Op1VP, Op2VP, Operands);
SmallVector<const Value *, 4> Operands(I->operand_values());
return TTI.getArithmeticInstrCost(I->getOpcode(), VectorTy, Op1VK,
Op2VK, Op1VP, Op2VP, Operands);
}
case Instruction::Select: {
SelectInst *SI = cast<SelectInst>(I);
@ -7471,15 +7470,7 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I,
}
case Instruction::Store:
case Instruction::Load: {
unsigned Width = VF;
if (Width > 1) {
InstWidening Decision = getWideningDecision(I, Width);
assert(Decision != CM_Unknown &&
"CM decision should be taken at this point");
if (Decision == CM_Scalarize)
Width = 1;
}
VectorTy = ToVectorTy(getMemInstValueType(I), Width);
VectorTy = ToVectorTy(getMemInstValueType(I), VF);
return getMemoryInstructionCost(I, VF);
}
case Instruction::ZExt:

View File

@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
#define CINDEX_VERSION_MINOR 40
#define CINDEX_VERSION_MINOR 41
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@ -1418,6 +1418,15 @@ CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU,
const char *FileName,
unsigned options);
/**
* \brief Suspend a translation unit in order to free memory associated with it.
*
* A suspended translation unit uses significantly less memory but on the other
* side does not support any other calls than \c clang_reparseTranslationUnit
* to resume it or \c clang_disposeTranslationUnit to dispose it completely.
*/
CINDEX_LINKAGE unsigned clang_suspendTranslationUnit(CXTranslationUnit);
/**
* \brief Destroy the specified CXTranslationUnit object.
*/

View File

@ -525,6 +525,8 @@ def err_pp_module_begin_without_module_end : Error<
def err_pp_module_end_without_module_begin : Error<
"no matching '#pragma clang module begin' for this "
"'#pragma clang module end'">;
def note_pp_module_begin_here : Note<
"entering module '%0' due to this pragma">;
def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
def err_paste_at_start : Error<

View File

@ -8312,8 +8312,13 @@ def err_opencl_bitfields : Error<
"bit-fields are not supported in OpenCL">;
def err_opencl_vla : Error<
"variable length arrays are not supported in OpenCL">;
def err_opencl_scalar_type_rank_greater_than_vector_type : Error<
"scalar operand type has greater rank than the type of the vector "
"element. (%0 and %1)">;
def err_bad_kernel_param_type : Error<
"%0 cannot be used as the type of a kernel parameter">;
def err_opencl_implicit_function_decl : Error<
"implicit declaration of function %0 is invalid in OpenCL">;
def err_record_with_pointers_kernel_param : Error<
"%select{struct|union}0 kernel parameters may not contain pointers">;
def note_within_field_of_type : Note<
@ -8744,8 +8749,8 @@ def err_omp_not_mappable_type : Error<
"type %0 is not mappable to target">;
def err_omp_invalid_map_type_for_directive : Error<
"%select{map type '%1' is not allowed|map type must be specified}0 for '#pragma omp %2'">;
def err_omp_no_map_for_directive : Error<
"expected at least one map clause for '#pragma omp %0'">;
def err_omp_no_clause_for_directive : Error<
"expected at least one %0 clause for '#pragma omp %1'">;
def note_omp_polymorphic_in_target : Note<
"mappable type cannot be polymorphic">;
def note_omp_static_member_in_target : Note<

View File

@ -878,6 +878,11 @@ class ASTUnit : public ModuleLoader {
ArrayRef<RemappedFile> RemappedFiles = None,
IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr);
/// \brief Free data that will be re-generated on the next parse.
///
/// Preamble-related data is not affected.
void ResetForParse();
/// \brief Perform code completion at the given file, line, and
/// column within this translation unit.
///

View File

@ -283,6 +283,44 @@ class Preprocessor {
/// This is used when loading a precompiled preamble.
std::pair<int, bool> SkipMainFilePreamble;
class PreambleConditionalStackStore {
enum State {
Off = 0,
Recording = 1,
Replaying = 2,
};
public:
PreambleConditionalStackStore() : ConditionalStackState(Off) {}
void startRecording() { ConditionalStackState = Recording; }
void startReplaying() { ConditionalStackState = Replaying; }
bool isRecording() const { return ConditionalStackState == Recording; }
bool isReplaying() const { return ConditionalStackState == Replaying; }
ArrayRef<PPConditionalInfo> getStack() const {
return ConditionalStack;
}
void doneReplaying() {
ConditionalStack.clear();
ConditionalStackState = Off;
}
void setStack(ArrayRef<PPConditionalInfo> s) {
if (!isRecording() && !isReplaying())
return;
ConditionalStack.clear();
ConditionalStack.append(s.begin(), s.end());
}
bool hasRecordedPreamble() const { return !ConditionalStack.empty(); }
private:
SmallVector<PPConditionalInfo, 4> ConditionalStack;
State ConditionalStackState;
} PreambleConditionalStack;
/// \brief The current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
///
@ -1695,6 +1733,11 @@ class Preprocessor {
/// \brief Return true if we're in the top-level file, not in a \#include.
bool isInPrimaryFile() const;
/// \brief Return true if we're in the main file (specifically, if we are 0
/// (zero) levels deep \#include. This is used by the lexer to determine if
/// it needs to generate errors about unterminated \#if directives.
bool isInMainFile() const;
/// \brief Handle cases where the \#include name is expanded
/// from a macro as multiple tokens, which need to be glued together.
///
@ -1932,6 +1975,27 @@ class Preprocessor {
Module *M,
SourceLocation MLoc);
bool isRecordingPreamble() const {
return PreambleConditionalStack.isRecording();
}
bool hasRecordedPreamble() const {
return PreambleConditionalStack.hasRecordedPreamble();
}
ArrayRef<PPConditionalInfo> getPreambleConditionalStack() const {
return PreambleConditionalStack.getStack();
}
void setRecordedPreambleConditionalStack(ArrayRef<PPConditionalInfo> s) {
PreambleConditionalStack.setStack(s);
}
void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s) {
PreambleConditionalStack.startReplaying();
PreambleConditionalStack.setStack(s);
}
private:
// Macro handling.
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);

View File

@ -17,6 +17,7 @@
#include "clang/Lex/MultipleIncludeOpt.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
@ -176,6 +177,11 @@ class PreprocessorLexer {
conditional_iterator conditional_end() const {
return ConditionalStack.end();
}
void setConditionalLevels(ArrayRef<PPConditionalInfo> CL) {
ConditionalStack.clear();
ConditionalStack.append(CL.begin(), CL.end());
}
};
} // end namespace clang

View File

@ -80,7 +80,14 @@ class PreprocessorOptions {
/// The boolean indicates whether the preamble ends at the start of a new
/// line.
std::pair<unsigned, bool> PrecompiledPreambleBytes;
/// \brief True indicates that a preamble is being generated.
///
/// When the lexer is done, one of the things that need to be preserved is the
/// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when
/// processing the rest of the file.
bool GeneratePreamble;
/// The implicit PTH input included at the start of the translation unit, or
/// empty.
std::string ImplicitPTHInclude;
@ -144,6 +151,7 @@ class PreprocessorOptions {
AllowPCHWithCompilerErrors(false),
DumpDeserializedPCHDecls(false),
PrecompiledPreambleBytes(0, true),
GeneratePreamble(false),
RemappedFilesKeepOriginalName(true),
RetainRemappedFileBuffers(false),
ObjCXXARCStandardLibrary(ARCXX_nolib) { }

View File

@ -607,6 +607,9 @@ namespace clang {
/// \brief Record code for \#pragma pack options.
PACK_PRAGMA_OPTIONS = 61,
/// \brief The stack of open #ifs/#ifdefs recorded in a preamble.
PP_CONDITIONAL_STACK = 62,
};
/// \brief Record types used within a source manager block.

View File

@ -279,15 +279,15 @@ def VirtualCallChecker : Checker<"VirtualCall">,
let ParentPackage = CplusplusAlpha in {
def IteratorRangeChecker : Checker<"IteratorRange">,
HelpText<"Check for iterators used outside their valid ranges">,
DescFile<"IteratorChecker.cpp">;
def MisusedMovedObjectChecker: Checker<"MisusedMovedObject">,
HelpText<"Method calls on a moved-from object and copying a moved-from "
"object will be reported">,
DescFile<"MisusedMovedObjectChecker.cpp">;
def IteratorPastEndChecker : Checker<"IteratorPastEnd">,
HelpText<"Check iterators used past end">,
DescFile<"IteratorPastEndChecker.cpp">;
} // end: "alpha.cplusplus"

View File

@ -43,6 +43,7 @@ typedef std::unique_ptr<ConstraintManager>(*ConstraintManagerCreator)(
ProgramStateManager &, SubEngine *);
typedef std::unique_ptr<StoreManager>(*StoreManagerCreator)(
ProgramStateManager &);
typedef llvm::ImmutableMap<const SubRegion*, TaintTagType> TaintedSubRegions;
//===----------------------------------------------------------------------===//
// ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState.
@ -343,6 +344,9 @@ class ProgramState : public llvm::FoldingSetNode {
ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric) const;
/// Create a new state in which the value is marked as tainted.
ProgramStateRef addTaint(SVal V, TaintTagType Kind = TaintTagGeneric) const;
/// Create a new state in which the symbol is marked as tainted.
ProgramStateRef addTaint(SymbolRef S,
TaintTagType Kind = TaintTagGeneric) const;
@ -351,6 +355,14 @@ class ProgramState : public llvm::FoldingSetNode {
ProgramStateRef addTaint(const MemRegion *R,
TaintTagType Kind = TaintTagGeneric) const;
/// Create a new state in a which a sub-region of a given symbol is tainted.
/// This might be necessary when referring to regions that can not have an
/// individual symbol, e.g. if they are represented by the default binding of
/// a LazyCompoundVal.
ProgramStateRef addPartialTaint(SymbolRef ParentSym,
const SubRegion *SubRegion,
TaintTagType Kind = TaintTagGeneric) const;
/// Check if the statement is tainted in the current state.
bool isTainted(const Stmt *S, const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric) const;
@ -453,6 +465,7 @@ class ProgramStateManager {
std::unique_ptr<ConstraintManager> ConstraintMgr;
ProgramState::GenericDataMap::Factory GDMFactory;
TaintedSubRegions::Factory TSRFactory;
typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
GDMContextsTy GDMContexts;

View File

@ -35,6 +35,16 @@ template<> struct ProgramStateTrait<TaintMap>
static void *GDMIndex() { static int index = 0; return &index; }
};
/// The GDM component mapping derived symbols' parent symbols to their
/// underlying regions. This is used to efficiently check whether a symbol is
/// tainted when it represents a sub-region of a tainted symbol.
struct DerivedSymTaint {};
typedef llvm::ImmutableMap<SymbolRef, TaintedSubRegions> DerivedSymTaintImpl;
template<> struct ProgramStateTrait<DerivedSymTaint>
: public ProgramStatePartialTrait<DerivedSymTaintImpl> {
static void *GDMIndex() { static int index; return &index; }
};
class TaintManager {
TaintManager() {}

View File

@ -578,8 +578,7 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) {
EmitBlock(FinalBB);
CurCoro.Data->CurrentAwaitKind = AwaitKind::Final;
EmitStmt(S.getFinalSuspendStmt());
}
else {
} else {
// We don't need FinalBB. Emit it to make sure the block is deleted.
EmitBlock(FinalBB, /*IsFinished=*/true);
}

View File

@ -1036,8 +1036,6 @@ static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> &
bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
SavedMainFileBuffer.reset();
if (!Invocation)
return true;
@ -1090,17 +1088,11 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
Clang->createFileManager();
FileMgr = &Clang->getFileManager();
}
ResetForParse();
SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,
UserFilesAreVolatile);
TheSema.reset();
Ctx = nullptr;
PP = nullptr;
Reader = nullptr;
// Clear out old caches and data.
TopLevelDecls.clear();
clearFileLevelDecls();
if (!OverrideMainBuffer) {
checkAndRemoveNonDriverDiags(StoredDiagnostics);
TopLevelDeclsInPreamble.clear();
@ -1999,6 +1991,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
PPOpts.GeneratePreamble = PrecompilePreambleAfterNParses != 0;
// Override the resources path.
CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
@ -2115,6 +2108,19 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
return Result;
}
void ASTUnit::ResetForParse() {
SavedMainFileBuffer.reset();
SourceMgr.reset();
TheSema.reset();
Ctx.reset();
PP.reset();
Reader.reset();
TopLevelDecls.clear();
clearFileLevelDecls();
}
//----------------------------------------------------------------------------//
// Code completion
//----------------------------------------------------------------------------//

View File

@ -506,7 +506,7 @@ void SDiagsWriter::EmitBlockInfoBlock() {
Abbrev->Add(BitCodeAbbrevOp(RECORD_FILENAME));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Mapped file ID.
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Size.
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Modifcation time.
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Modification time.
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Text size.
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name text.
Abbrevs.set(RECORD_FILENAME, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG,

View File

@ -2887,87 +2887,79 @@ static __inline__ vector double __ATTRS_o_ai vec_cpsgn(vector double __a,
/* vec_ctf */
static __inline__ vector float __ATTRS_o_ai vec_ctf(vector int __a, int __b) {
return __builtin_altivec_vcfsx(__a, __b);
}
static __inline__ vector float __ATTRS_o_ai vec_ctf(vector unsigned int __a,
int __b) {
return __builtin_altivec_vcfux((vector int)__a, __b);
}
#ifdef __VSX__
static __inline__ vector double __ATTRS_o_ai
vec_ctf(vector unsigned long long __a, int __b) {
vector double __ret = __builtin_convertvector(__a, vector double);
__ret *= (vector double)(vector unsigned long long)((0x3ffULL - __b) << 52);
return __ret;
}
static __inline__ vector double __ATTRS_o_ai
vec_ctf(vector signed long long __a, int __b) {
vector double __ret = __builtin_convertvector(__a, vector double);
__ret *= (vector double)(vector unsigned long long)((0x3ffULL - __b) << 52);
return __ret;
}
#define vec_ctf(__a, __b) \
_Generic((__a), vector int \
: (vector float)__builtin_altivec_vcfsx((__a), (__b)), \
vector unsigned int \
: (vector float)__builtin_altivec_vcfux((vector int)(__a), (__b)), \
vector unsigned long long \
: (__builtin_convertvector((vector unsigned long long)(__a), \
vector double) * \
(vector double)(vector unsigned long long)((0x3ffULL - (__b)) \
<< 52)), \
vector signed long long \
: (__builtin_convertvector((vector signed long long)(__a), \
vector double) * \
(vector double)(vector unsigned long long)((0x3ffULL - (__b)) \
<< 52)))
#else
#define vec_ctf(__a, __b) \
_Generic((__a), vector int \
: (vector float)__builtin_altivec_vcfsx((__a), (__b)), \
vector unsigned int \
: (vector float)__builtin_altivec_vcfux((vector int)(__a), (__b)))
#endif
/* vec_vcfsx */
static __inline__ vector float __attribute__((__always_inline__))
vec_vcfsx(vector int __a, int __b) {
return __builtin_altivec_vcfsx(__a, __b);
}
#define vec_vcfux __builtin_altivec_vcfux
/* vec_vcfux */
static __inline__ vector float __attribute__((__always_inline__))
vec_vcfux(vector unsigned int __a, int __b) {
return __builtin_altivec_vcfux((vector int)__a, __b);
}
#define vec_vcfsx(__a, __b) __builtin_altivec_vcfsx((vector int)(__a), (__b))
/* vec_cts */
static __inline__ vector int __ATTRS_o_ai vec_cts(vector float __a, int __b) {
return __builtin_altivec_vctsxs(__a, __b);
}
#ifdef __VSX__
static __inline__ vector signed long long __ATTRS_o_ai
vec_cts(vector double __a, int __b) {
__a *= (vector double)(vector unsigned long long)((0x3ffULL + __b) << 52);
return __builtin_convertvector(__a, vector signed long long);
}
#define vec_cts(__a, __b) \
_Generic((__a), vector float \
: __builtin_altivec_vctsxs((__a), (__b)), vector double \
: __extension__({ \
vector double __ret = \
(__a) * \
(vector double)(vector unsigned long long)((0x3ffULL + (__b)) \
<< 52); \
__builtin_convertvector(__ret, vector signed long long); \
}))
#else
#define vec_cts __builtin_altivec_vctsxs
#endif
/* vec_vctsxs */
static __inline__ vector int __attribute__((__always_inline__))
vec_vctsxs(vector float __a, int __b) {
return __builtin_altivec_vctsxs(__a, __b);
}
#define vec_vctsxs __builtin_altivec_vctsxs
/* vec_ctu */
static __inline__ vector unsigned int __ATTRS_o_ai vec_ctu(vector float __a,
int __b) {
return __builtin_altivec_vctuxs(__a, __b);
}
#ifdef __VSX__
static __inline__ vector unsigned long long __ATTRS_o_ai
vec_ctu(vector double __a, int __b) {
__a *= (vector double)(vector unsigned long long)((0x3ffULL + __b) << 52);
return __builtin_convertvector(__a, vector unsigned long long);
}
#define vec_ctu(__a, __b) \
_Generic((__a), vector float \
: __builtin_altivec_vctuxs((__a), (__b)), vector double \
: __extension__({ \
vector double __ret = \
(__a) * \
(vector double)(vector unsigned long long)((0x3ffULL + __b) \
<< 52); \
__builtin_convertvector(__ret, vector unsigned long long); \
}))
#else
#define vec_ctu __builtin_altivec_vctuxs
#endif
/* vec_vctuxs */
static __inline__ vector unsigned int __attribute__((__always_inline__))
vec_vctuxs(vector float __a, int __b) {
return __builtin_altivec_vctuxs(__a, __b);
}
#define vec_vctuxs __builtin_altivec_vctuxs
/* vec_signed */

View File

@ -550,8 +550,6 @@ namespace {
enum PreambleDirectiveKind {
PDK_Skipped,
PDK_StartIf,
PDK_EndIf,
PDK_Unknown
};
@ -574,8 +572,6 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer,
bool InPreprocessorDirective = false;
Token TheTok;
Token IfStartTok;
unsigned IfCount = 0;
SourceLocation ActiveCommentLoc;
unsigned MaxLineOffset = 0;
@ -658,33 +654,18 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer,
.Case("sccs", PDK_Skipped)
.Case("assert", PDK_Skipped)
.Case("unassert", PDK_Skipped)
.Case("if", PDK_StartIf)
.Case("ifdef", PDK_StartIf)
.Case("ifndef", PDK_StartIf)
.Case("if", PDK_Skipped)
.Case("ifdef", PDK_Skipped)
.Case("ifndef", PDK_Skipped)
.Case("elif", PDK_Skipped)
.Case("else", PDK_Skipped)
.Case("endif", PDK_EndIf)
.Case("endif", PDK_Skipped)
.Default(PDK_Unknown);
switch (PDK) {
case PDK_Skipped:
continue;
case PDK_StartIf:
if (IfCount == 0)
IfStartTok = HashTok;
++IfCount;
continue;
case PDK_EndIf:
// Mismatched #endif. The preamble ends here.
if (IfCount == 0)
break;
--IfCount;
continue;
case PDK_Unknown:
// We don't know what this directive is; stop at the '#'.
break;
@ -705,16 +686,13 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer,
} while (true);
SourceLocation End;
if (IfCount)
End = IfStartTok.getLocation();
else if (ActiveCommentLoc.isValid())
if (ActiveCommentLoc.isValid())
End = ActiveCommentLoc; // don't truncate a decl comment.
else
End = TheTok.getLocation();
return std::make_pair(End.getRawEncoding() - StartLoc.getRawEncoding(),
IfCount? IfStartTok.isAtStartOfLine()
: TheTok.isAtStartOfLine());
TheTok.isAtStartOfLine());
}
/// AdvanceToTokenCharacter - Given a location that specifies the start of a
@ -2570,6 +2548,11 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
return true;
}
if (PP->isRecordingPreamble() && !PP->isInMainFile()) {
PP->setRecordedPreambleConditionalStack(ConditionalStack);
ConditionalStack.clear();
}
// Issue diagnostics for unterminated #if and missing newline.
// If we are in a #if directive, emit an error.

View File

@ -1906,6 +1906,25 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
}
}
// The #included file will be considered to be a system header if either it is
// in a system include directory, or if the #includer is a system include
// header.
SrcMgr::CharacteristicKind FileCharacter =
SourceMgr.getFileCharacteristic(FilenameTok.getLocation());
if (File)
FileCharacter = std::max(HeaderInfo.getFileDirFlavor(File), FileCharacter);
// Ask HeaderInfo if we should enter this #include file. If not, #including
// this file will have no effect.
bool SkipHeader = false;
if (ShouldEnter && File &&
!HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
getLangOpts().Modules,
SuggestedModule.getModule())) {
ShouldEnter = false;
SkipHeader = true;
}
if (Callbacks) {
// Notify the callback object that we've seen an inclusion directive.
Callbacks->InclusionDirective(
@ -1913,18 +1932,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
FilenameRange, File, SearchPath, RelativePath,
ShouldEnter ? nullptr : SuggestedModule.getModule());
if (SkipHeader && !SuggestedModule.getModule())
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
}
if (!File)
return;
// The #included file will be considered to be a system header if either it is
// in a system include directory, or if the #includer is a system include
// header.
SrcMgr::CharacteristicKind FileCharacter =
std::max(HeaderInfo.getFileDirFlavor(File),
SourceMgr.getFileCharacteristic(FilenameTok.getLocation()));
// FIXME: If we have a suggested module, and we've already visited this file,
// don't bother entering it again. We know it has no further effect.
@ -1964,19 +1978,6 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
}
}
// Ask HeaderInfo if we should enter this #include file. If not, #including
// this file will have no effect.
bool SkipHeader = false;
if (ShouldEnter &&
!HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
getLangOpts().Modules,
SuggestedModule.getModule())) {
ShouldEnter = false;
SkipHeader = true;
if (Callbacks)
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
}
// If we don't need to enter the file, stop now.
if (!ShouldEnter) {
// If this is a module import, make it visible if needed.

View File

@ -46,6 +46,12 @@ bool Preprocessor::isInPrimaryFile() const {
});
}
bool Preprocessor::isInMainFile() const {
if (IsFileLexer())
return IncludeMacroStack.size() == 0;
return true;
}
/// getCurrentLexer - Return the current file lexer being lexed from. Note
/// that this ignores any potentially active macro expansions and _Pragma
/// expansions going on at the time.

View File

@ -1407,6 +1407,24 @@ struct PragmaModuleBeginHandler : public PragmaHandler {
M = NewM;
}
// If the module isn't available, it doesn't make sense to enter it.
if (!M->isAvailable()) {
Module::Requirement Requirement;
Module::UnresolvedHeaderDirective MissingHeader;
(void)M->isAvailable(PP.getLangOpts(), PP.getTargetInfo(),
Requirement, MissingHeader);
if (MissingHeader.FileNameLoc.isValid()) {
PP.Diag(MissingHeader.FileNameLoc, diag::err_module_header_missing)
<< MissingHeader.IsUmbrella << MissingHeader.FileName;
} else {
PP.Diag(M->DefinitionLoc, diag::err_module_unavailable)
<< M->getFullModuleName() << Requirement.second << Requirement.first;
}
PP.Diag(BeginLoc, diag::note_pp_module_begin_here)
<< M->getTopLevelModuleName();
return;
}
// Enter the scope of the submodule.
PP.EnterSubmodule(M, BeginLoc, /*ForPragma*/true);
PP.EnterAnnotationToken(SourceRange(BeginLoc, ModuleName.back().second),

View File

@ -150,6 +150,9 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr;
Ident_AbnormalTermination = nullptr;
}
if (this->PPOpts->GeneratePreamble)
PreambleConditionalStack.startRecording();
}
Preprocessor::~Preprocessor() {
@ -532,6 +535,12 @@ void Preprocessor::EnterMainSourceFile() {
// Start parsing the predefines.
EnterSourceFile(FID, nullptr, SourceLocation());
// Restore the conditional stack from the preamble, if there is one.
if (PreambleConditionalStack.isReplaying()) {
CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack());
PreambleConditionalStack.doneReplaying();
}
}
void Preprocessor::EndSourceFile() {

Some files were not shown because too many files have changed in this diff Show More