2017-09-14 18:56:21 +02:00
|
|
|
//===--- InfoByHwMode.h -----------------------------------------*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2017-09-14 18:56:21 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Classes that implement data parameterized by HW modes for instruction
|
|
|
|
// selection. Currently it is ValueTypeByHwMode (parameterized ValueType),
|
|
|
|
// and RegSizeInfoByHwMode (parameterized register/spill size and alignment
|
|
|
|
// data).
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
|
|
|
|
#define LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
|
|
|
|
|
|
|
|
#include "CodeGenHwModes.h"
|
2021-04-18 23:10:06 +02:00
|
|
|
#include "llvm/ADT/SmallSet.h"
|
2018-03-24 00:58:25 +01:00
|
|
|
#include "llvm/Support/MachineValueType.h"
|
2017-09-14 18:56:21 +02:00
|
|
|
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
|
|
|
struct CodeGenHwModes;
|
|
|
|
class Record;
|
2017-09-22 20:29:37 +02:00
|
|
|
class raw_ostream;
|
2017-09-14 18:56:21 +02:00
|
|
|
|
|
|
|
template <typename InfoT> struct InfoByHwMode;
|
|
|
|
|
|
|
|
std::string getModeName(unsigned Mode);
|
|
|
|
|
|
|
|
enum : unsigned {
|
|
|
|
DefaultMode = CodeGenHwModes::DefaultMode,
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename InfoT>
|
2021-04-18 23:10:06 +02:00
|
|
|
void union_modes(const InfoByHwMode<InfoT> &A,
|
|
|
|
const InfoByHwMode<InfoT> &B,
|
|
|
|
SmallVectorImpl<unsigned> &Modes) {
|
|
|
|
SmallSet<unsigned, 4> U;
|
2017-09-14 18:56:21 +02:00
|
|
|
for (const auto &P : A)
|
|
|
|
U.insert(P.first);
|
|
|
|
for (const auto &P : B)
|
|
|
|
U.insert(P.first);
|
|
|
|
// Make sure that the default mode is last on the list.
|
2018-08-17 19:45:15 +02:00
|
|
|
bool HasDefault = false;
|
2017-09-14 18:56:21 +02:00
|
|
|
for (unsigned M : U)
|
|
|
|
if (M != DefaultMode)
|
2021-04-18 23:10:06 +02:00
|
|
|
Modes.push_back(M);
|
2018-08-17 19:45:15 +02:00
|
|
|
else
|
|
|
|
HasDefault = true;
|
2017-09-14 18:56:21 +02:00
|
|
|
if (HasDefault)
|
2021-04-18 23:10:06 +02:00
|
|
|
Modes.push_back(DefaultMode);
|
2017-09-14 18:56:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename InfoT>
|
|
|
|
struct InfoByHwMode {
|
|
|
|
typedef std::map<unsigned,InfoT> MapType;
|
|
|
|
typedef typename MapType::value_type PairType;
|
|
|
|
typedef typename MapType::iterator iterator;
|
|
|
|
typedef typename MapType::const_iterator const_iterator;
|
|
|
|
|
|
|
|
InfoByHwMode() = default;
|
2017-09-19 20:42:34 +02:00
|
|
|
InfoByHwMode(const MapType &M) : Map(M) {}
|
2017-09-14 18:56:21 +02:00
|
|
|
|
2017-09-19 20:42:34 +02:00
|
|
|
LLVM_ATTRIBUTE_ALWAYS_INLINE
|
2017-09-14 18:56:21 +02:00
|
|
|
iterator begin() { return Map.begin(); }
|
2017-09-19 20:42:34 +02:00
|
|
|
LLVM_ATTRIBUTE_ALWAYS_INLINE
|
2017-09-14 18:56:21 +02:00
|
|
|
iterator end() { return Map.end(); }
|
2017-09-19 20:42:34 +02:00
|
|
|
LLVM_ATTRIBUTE_ALWAYS_INLINE
|
2017-09-14 18:56:21 +02:00
|
|
|
const_iterator begin() const { return Map.begin(); }
|
2017-09-19 20:42:34 +02:00
|
|
|
LLVM_ATTRIBUTE_ALWAYS_INLINE
|
2017-09-14 18:56:21 +02:00
|
|
|
const_iterator end() const { return Map.end(); }
|
2017-09-19 20:42:34 +02:00
|
|
|
LLVM_ATTRIBUTE_ALWAYS_INLINE
|
2017-09-14 18:56:21 +02:00
|
|
|
bool empty() const { return Map.empty(); }
|
|
|
|
|
2017-09-19 20:42:34 +02:00
|
|
|
LLVM_ATTRIBUTE_ALWAYS_INLINE
|
2017-09-14 18:56:21 +02:00
|
|
|
bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
|
2017-09-19 20:42:34 +02:00
|
|
|
LLVM_ATTRIBUTE_ALWAYS_INLINE
|
2017-09-14 18:56:21 +02:00
|
|
|
bool hasDefault() const { return hasMode(DefaultMode); }
|
|
|
|
|
|
|
|
InfoT &get(unsigned Mode) {
|
|
|
|
if (!hasMode(Mode)) {
|
|
|
|
assert(hasMode(DefaultMode));
|
2017-09-19 20:42:34 +02:00
|
|
|
Map.insert({Mode, Map.at(DefaultMode)});
|
2017-09-14 18:56:21 +02:00
|
|
|
}
|
2017-09-19 20:42:34 +02:00
|
|
|
return Map.at(Mode);
|
2017-09-14 18:56:21 +02:00
|
|
|
}
|
|
|
|
const InfoT &get(unsigned Mode) const {
|
|
|
|
auto F = Map.find(Mode);
|
|
|
|
if (Mode != DefaultMode && F == Map.end())
|
|
|
|
F = Map.find(DefaultMode);
|
|
|
|
assert(F != Map.end());
|
|
|
|
return F->second;
|
|
|
|
}
|
|
|
|
|
2017-09-19 20:42:34 +02:00
|
|
|
LLVM_ATTRIBUTE_ALWAYS_INLINE
|
2017-09-14 18:56:21 +02:00
|
|
|
bool isSimple() const {
|
|
|
|
return Map.size() == 1 && Map.begin()->first == DefaultMode;
|
|
|
|
}
|
2017-09-19 20:42:34 +02:00
|
|
|
LLVM_ATTRIBUTE_ALWAYS_INLINE
|
2017-09-14 18:56:21 +02:00
|
|
|
InfoT getSimple() const {
|
|
|
|
assert(isSimple());
|
|
|
|
return Map.begin()->second;
|
|
|
|
}
|
|
|
|
void makeSimple(unsigned Mode) {
|
|
|
|
assert(hasMode(Mode) || hasDefault());
|
|
|
|
InfoT I = get(Mode);
|
|
|
|
Map.clear();
|
|
|
|
Map.insert(std::make_pair(DefaultMode, I));
|
|
|
|
}
|
|
|
|
|
2021-02-12 06:02:50 +01:00
|
|
|
protected:
|
2017-09-14 18:56:21 +02:00
|
|
|
MapType Map;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
|
|
|
|
ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH);
|
Add support for pointer types in patterns
Summary:
This adds support for defining patterns for global isel using pointer
types, for example:
def : Pat<(load GPR32:$src),
(p1 (LOAD GPR32:$src))>;
DAGISelEmitter will ignore the pointer information and treat these
types as integers with the same bit-width as the pointer type.
Reviewers: dsanders, rtereshin, arsenm
Reviewed By: arsenm
Subscribers: Petar.Avramovic, wdng, rovka, kristof.beyls, jfb, volkan, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D57065
llvm-svn: 354510
2019-02-20 20:43:47 +01:00
|
|
|
ValueTypeByHwMode(Record *R, MVT T);
|
2017-09-14 18:56:21 +02:00
|
|
|
ValueTypeByHwMode(MVT T) { Map.insert({DefaultMode,T}); }
|
|
|
|
ValueTypeByHwMode() = default;
|
|
|
|
|
|
|
|
bool operator== (const ValueTypeByHwMode &T) const;
|
|
|
|
bool operator< (const ValueTypeByHwMode &T) const;
|
|
|
|
|
|
|
|
bool isValid() const {
|
|
|
|
return !Map.empty();
|
|
|
|
}
|
|
|
|
MVT getType(unsigned Mode) const { return get(Mode); }
|
|
|
|
MVT &getOrCreateTypeForMode(unsigned Mode, MVT Type);
|
|
|
|
|
2017-09-22 15:32:26 +02:00
|
|
|
static StringRef getMVTName(MVT T);
|
2017-09-22 20:29:37 +02:00
|
|
|
void writeToStream(raw_ostream &OS) const;
|
2017-09-14 18:56:21 +02:00
|
|
|
void dump() const;
|
Add support for pointer types in patterns
Summary:
This adds support for defining patterns for global isel using pointer
types, for example:
def : Pat<(load GPR32:$src),
(p1 (LOAD GPR32:$src))>;
DAGISelEmitter will ignore the pointer information and treat these
types as integers with the same bit-width as the pointer type.
Reviewers: dsanders, rtereshin, arsenm
Reviewed By: arsenm
Subscribers: Petar.Avramovic, wdng, rovka, kristof.beyls, jfb, volkan, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D57065
llvm-svn: 354510
2019-02-20 20:43:47 +01:00
|
|
|
|
|
|
|
unsigned PtrAddrSpace = std::numeric_limits<unsigned>::max();
|
|
|
|
bool isPointer() const {
|
|
|
|
return PtrAddrSpace != std::numeric_limits<unsigned>::max();
|
|
|
|
}
|
2017-09-14 18:56:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
ValueTypeByHwMode getValueTypeByHwMode(Record *Rec,
|
|
|
|
const CodeGenHwModes &CGH);
|
|
|
|
|
|
|
|
struct RegSizeInfo {
|
|
|
|
unsigned RegSize;
|
|
|
|
unsigned SpillSize;
|
|
|
|
unsigned SpillAlignment;
|
|
|
|
|
|
|
|
RegSizeInfo(Record *R, const CodeGenHwModes &CGH);
|
|
|
|
RegSizeInfo() = default;
|
|
|
|
bool operator< (const RegSizeInfo &I) const;
|
|
|
|
bool operator== (const RegSizeInfo &I) const {
|
|
|
|
return std::tie(RegSize, SpillSize, SpillAlignment) ==
|
|
|
|
std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
|
|
|
|
}
|
|
|
|
bool operator!= (const RegSizeInfo &I) const {
|
|
|
|
return !(*this == I);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isSubClassOf(const RegSizeInfo &I) const;
|
2017-09-22 20:29:37 +02:00
|
|
|
void writeToStream(raw_ostream &OS) const;
|
2017-09-14 18:56:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> {
|
|
|
|
RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
|
|
|
|
RegSizeInfoByHwMode() = default;
|
|
|
|
bool operator< (const RegSizeInfoByHwMode &VI) const;
|
|
|
|
bool operator== (const RegSizeInfoByHwMode &VI) const;
|
|
|
|
bool operator!= (const RegSizeInfoByHwMode &VI) const {
|
|
|
|
return !(*this == VI);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isSubClassOf(const RegSizeInfoByHwMode &I) const;
|
|
|
|
bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;
|
|
|
|
|
2017-09-22 20:29:37 +02:00
|
|
|
void writeToStream(raw_ostream &OS) const;
|
2021-02-12 06:02:50 +01:00
|
|
|
|
|
|
|
void insertRegSizeForMode(unsigned Mode, RegSizeInfo Info) {
|
|
|
|
Map.insert(std::make_pair(Mode, Info));
|
|
|
|
}
|
2017-09-14 18:56:21 +02:00
|
|
|
};
|
2017-09-22 20:29:37 +02:00
|
|
|
|
|
|
|
raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
|
|
|
|
raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
|
|
|
|
raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);
|
|
|
|
|
2019-09-19 15:39:54 +02:00
|
|
|
struct EncodingInfoByHwMode : public InfoByHwMode<Record*> {
|
|
|
|
EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
|
|
|
|
EncodingInfoByHwMode() = default;
|
|
|
|
};
|
|
|
|
|
2017-09-14 18:56:21 +02:00
|
|
|
} // namespace llvm
|
|
|
|
|
|
|
|
#endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
|