#include "CodeGenDAGPatterns.h"
#include "CodeGenInstruction.h"
#include "CodeGenRegisters.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TypeSize.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include <algorithm>
#include <cstdio>
#include <iterator>
#include <set>
usingnamespacellvm;
#define DEBUG_TYPE …
static inline bool isIntegerOrPtr(MVT VT) { … }
static inline bool isFloatingPoint(MVT VT) { … }
static inline bool isVector(MVT VT) { … }
static inline bool isScalar(MVT VT) { … }
template <typename Predicate>
static bool berase_if(MachineValueTypeSet &S, Predicate P) { … }
void MachineValueTypeSet::writeToStream(raw_ostream &OS) const { … }
TypeSetByHwMode::TypeSetByHwMode(ArrayRef<ValueTypeByHwMode> VTList) { … }
bool TypeSetByHwMode::isValueTypeByHwMode(bool AllowEmpty) const { … }
ValueTypeByHwMode TypeSetByHwMode::getValueTypeByHwMode() const { … }
bool TypeSetByHwMode::isPossible() const { … }
bool TypeSetByHwMode::insert(const ValueTypeByHwMode &VVT) { … }
bool TypeSetByHwMode::constrain(const TypeSetByHwMode &VTS) { … }
template <typename Predicate> bool TypeSetByHwMode::constrain(Predicate P) { … }
template <typename Predicate>
bool TypeSetByHwMode::assign_if(const TypeSetByHwMode &VTS, Predicate P) { … }
void TypeSetByHwMode::writeToStream(raw_ostream &OS) const { … }
bool TypeSetByHwMode::operator==(const TypeSetByHwMode &VTS) const { … }
namespace llvm {
raw_ostream &operator<<(raw_ostream &OS, const MachineValueTypeSet &T) { … }
raw_ostream &operator<<(raw_ostream &OS, const TypeSetByHwMode &T) { … }
}
LLVM_DUMP_METHOD
void TypeSetByHwMode::dump() const { … }
bool TypeSetByHwMode::intersect(SetType &Out, const SetType &In) { … }
bool TypeSetByHwMode::validate() const { … }
bool TypeInfer::MergeInTypeInfo(TypeSetByHwMode &Out,
const TypeSetByHwMode &In) const { … }
bool TypeInfer::forceArbitrary(TypeSetByHwMode &Out) { … }
bool TypeInfer::EnforceInteger(TypeSetByHwMode &Out) { … }
bool TypeInfer::EnforceFloatingPoint(TypeSetByHwMode &Out) { … }
bool TypeInfer::EnforceScalar(TypeSetByHwMode &Out) { … }
bool TypeInfer::EnforceVector(TypeSetByHwMode &Out) { … }
bool TypeInfer::EnforceAny(TypeSetByHwMode &Out) { … }
template <typename Iter, typename Pred, typename Less>
static Iter min_if(Iter B, Iter E, Pred P, Less L) { … }
template <typename Iter, typename Pred, typename Less>
static Iter max_if(Iter B, Iter E, Pred P, Less L) { … }
bool TypeInfer::EnforceSmallerThan(TypeSetByHwMode &Small, TypeSetByHwMode &Big,
bool SmallIsVT) { … }
bool TypeInfer::EnforceVectorEltTypeIs(TypeSetByHwMode &Vec,
TypeSetByHwMode &Elem) { … }
bool TypeInfer::EnforceVectorEltTypeIs(TypeSetByHwMode &Vec,
const ValueTypeByHwMode &VVT) { … }
bool TypeInfer::EnforceVectorSubVectorTypeIs(TypeSetByHwMode &Vec,
TypeSetByHwMode &Sub) { … }
bool TypeInfer::EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W) { … }
namespace {
struct TypeSizeComparator { … };
}
bool TypeInfer::EnforceSameSize(TypeSetByHwMode &A, TypeSetByHwMode &B) { … }
void TypeInfer::expandOverloads(TypeSetByHwMode &VTS) const { … }
void TypeInfer::expandOverloads(TypeSetByHwMode::SetType &Out,
const TypeSetByHwMode::SetType &Legal) const { … }
const TypeSetByHwMode &TypeInfer::getLegalTypes() const { … }
TypeInfer::ValidateOnExit::~ValidateOnExit() { … }
bool ScopedName::operator==(const ScopedName &o) const { … }
bool ScopedName::operator!=(const ScopedName &o) const { … }
TreePredicateFn::TreePredicateFn(TreePattern *N) : … { … }
bool TreePredicateFn::hasPredCode() const { … }
std::string TreePredicateFn::getPredCode() const { … }
bool TreePredicateFn::hasImmCode() const { … }
std::string TreePredicateFn::getImmCode() const { … }
bool TreePredicateFn::immCodeUsesAPInt() const { … }
bool TreePredicateFn::immCodeUsesAPFloat() const { … }
bool TreePredicateFn::isPredefinedPredicateEqualTo(StringRef Field,
bool Value) const { … }
bool TreePredicateFn::usesOperands() const { … }
bool TreePredicateFn::hasNoUse() const { … }
bool TreePredicateFn::hasOneUse() const { … }
bool TreePredicateFn::isLoad() const { … }
bool TreePredicateFn::isStore() const { … }
bool TreePredicateFn::isAtomic() const { … }
bool TreePredicateFn::isUnindexed() const { … }
bool TreePredicateFn::isNonExtLoad() const { … }
bool TreePredicateFn::isAnyExtLoad() const { … }
bool TreePredicateFn::isSignExtLoad() const { … }
bool TreePredicateFn::isZeroExtLoad() const { … }
bool TreePredicateFn::isNonTruncStore() const { … }
bool TreePredicateFn::isTruncStore() const { … }
bool TreePredicateFn::isAtomicOrderingMonotonic() const { … }
bool TreePredicateFn::isAtomicOrderingAcquire() const { … }
bool TreePredicateFn::isAtomicOrderingRelease() const { … }
bool TreePredicateFn::isAtomicOrderingAcquireRelease() const { … }
bool TreePredicateFn::isAtomicOrderingSequentiallyConsistent() const { … }
bool TreePredicateFn::isAtomicOrderingAcquireOrStronger() const { … }
bool TreePredicateFn::isAtomicOrderingWeakerThanAcquire() const { … }
bool TreePredicateFn::isAtomicOrderingReleaseOrStronger() const { … }
bool TreePredicateFn::isAtomicOrderingWeakerThanRelease() const { … }
const Record *TreePredicateFn::getMemoryVT() const { … }
const ListInit *TreePredicateFn::getAddressSpaces() const { … }
int64_t TreePredicateFn::getMinAlignment() const { … }
const Record *TreePredicateFn::getScalarMemoryVT() const { … }
bool TreePredicateFn::hasGISelPredicateCode() const { … }
std::string TreePredicateFn::getGISelPredicateCode() const { … }
StringRef TreePredicateFn::getImmType() const { … }
StringRef TreePredicateFn::getImmTypeIdentifier() const { … }
bool TreePredicateFn::isAlwaysTrue() const { … }
std::string TreePredicateFn::getFnName() const { … }
std::string TreePredicateFn::getCodeToRunOnSDNode() const { … }
static bool isImmAllOnesAllZerosMatch(const TreePatternNode &P) { … }
static unsigned getPatternSize(const TreePatternNode &P,
const CodeGenDAGPatterns &CGP) { … }
int PatternToMatch::getPatternComplexity(const CodeGenDAGPatterns &CGP) const { … }
void PatternToMatch::getPredicateRecords(
SmallVectorImpl<const Record *> &PredicateRecs) const { … }
std::string PatternToMatch::getPredicateCheck() const { … }
SDTypeConstraint::SDTypeConstraint(const Record *R, const CodeGenHwModes &CGH) { … }
static TreePatternNode &getOperandNum(unsigned OpNo, TreePatternNode &N,
const SDNodeInfo &NodeInfo,
unsigned &ResNo) { … }
bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode &N,
const SDNodeInfo &NodeInfo,
TreePattern &TP) const { … }
bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo,
const Record *Operand,
TreePattern &TP) { … }
bool TreePatternNode::ContainsUnresolvedType(TreePattern &TP) const { … }
bool TreePatternNode::hasProperTypeByHwMode() const { … }
bool TreePatternNode::hasPossibleType() const { … }
bool TreePatternNode::setDefaultMode(unsigned Mode) { … }
SDNodeInfo::SDNodeInfo(const Record *R, const CodeGenHwModes &CGH) : … { … }
MVT::SimpleValueType SDNodeInfo::getKnownType(unsigned ResNo) const { … }
static unsigned GetNumNodeResults(const Record *Operator,
CodeGenDAGPatterns &CDP) { … }
void TreePatternNode::print(raw_ostream &OS) const { … }
void TreePatternNode::dump() const { … }
bool TreePatternNode::isIsomorphicTo(const TreePatternNode &N,
const MultipleUseVarSet &DepVars) const { … }
TreePatternNodePtr TreePatternNode::clone() const { … }
void TreePatternNode::RemoveAllTypes() { … }
void TreePatternNode::SubstituteFormalArguments(
std::map<std::string, TreePatternNodePtr> &ArgMap) { … }
void TreePatternNode::InlinePatternFragments(
TreePattern &TP, std::vector<TreePatternNodePtr> &OutAlternatives) { … }
static TypeSetByHwMode getImplicitType(const Record *R, unsigned ResNo,
bool NotRegisters, bool Unnamed,
TreePattern &TP) { … }
const CodeGenIntrinsic *
TreePatternNode::getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const { … }
const ComplexPattern *
TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const { … }
unsigned TreePatternNode::getNumMIResults(const CodeGenDAGPatterns &CGP) const { … }
bool TreePatternNode::NodeHasProperty(SDNP Property,
const CodeGenDAGPatterns &CGP) const { … }
bool TreePatternNode::TreeHasProperty(SDNP Property,
const CodeGenDAGPatterns &CGP) const { … }
bool TreePatternNode::isCommutativeIntrinsic(
const CodeGenDAGPatterns &CDP) const { … }
static bool isOperandClass(const TreePatternNode &N, StringRef Class) { … }
static void emitTooManyOperandsError(TreePattern &TP, StringRef InstName,
unsigned Expected, unsigned Actual) { … }
static void emitTooFewOperandsError(TreePattern &TP, StringRef InstName,
unsigned Actual) { … }
bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { … }
static bool OnlyOnRHSOfCommutative(TreePatternNode &N) { … }
bool TreePatternNode::canPatternMatch(std::string &Reason,
const CodeGenDAGPatterns &CDP) { … }
TreePattern::TreePattern(const Record *TheRec, const ListInit *RawPat,
bool isInput, CodeGenDAGPatterns &cdp)
: … { … }
TreePattern::TreePattern(const Record *TheRec, DagInit *Pat, bool isInput,
CodeGenDAGPatterns &cdp)
: … { … }
TreePattern::TreePattern(const Record *TheRec, TreePatternNodePtr Pat,
bool isInput, CodeGenDAGPatterns &cdp)
: … { … }
void TreePattern::error(const Twine &Msg) { … }
void TreePattern::ComputeNamedNodes() { … }
void TreePattern::ComputeNamedNodes(TreePatternNode &N) { … }
TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
StringRef OpName) { … }
static bool SimplifyTree(TreePatternNodePtr &N) { … }
bool TreePattern::InferAllTypes(
const StringMap<SmallVector<TreePatternNode *, 1>> *InNamedTypes) { … }
void TreePattern::print(raw_ostream &OS) const { … }
void TreePattern::dump() const { … }
CodeGenDAGPatterns::CodeGenDAGPatterns(const RecordKeeper &R,
PatternRewriterFn PatternRewriter)
: … { … }
const Record *CodeGenDAGPatterns::getSDNodeNamed(StringRef Name) const { … }
void CodeGenDAGPatterns::ParseNodeInfo() { … }
void CodeGenDAGPatterns::ParseNodeTransforms() { … }
void CodeGenDAGPatterns::ParseComplexPatterns() { … }
void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) { … }
void CodeGenDAGPatterns::ParseDefaultOperands() { … }
static bool HandleUse(TreePattern &I, TreePatternNodePtr Pat,
std::map<std::string, TreePatternNodePtr> &InstInputs) { … }
void CodeGenDAGPatterns::FindPatternInputsAndOutputs(
TreePattern &I, TreePatternNodePtr Pat,
std::map<std::string, TreePatternNodePtr> &InstInputs,
MapVector<std::string, TreePatternNodePtr, std::map<std::string, unsigned>>
&InstResults,
std::vector<const Record *> &InstImpResults) { … }
class InstAnalyzer { … };
static bool InferFromPattern(CodeGenInstruction &InstInfo,
const InstAnalyzer &PatInfo,
const Record *PatDef) { … }
static bool hasNullFragReference(DagInit *DI) { … }
static bool hasNullFragReference(ListInit *LI) { … }
static void getInstructionsInTree(TreePatternNode &Tree,
SmallVectorImpl<const Record *> &Instrs) { … }
static bool checkOperandClass(CGIOperandList::OperandInfo &OI,
const Record *Leaf) { … }
void CodeGenDAGPatterns::parseInstructionPattern(CodeGenInstruction &CGI,
const ListInit *Pat,
DAGInstMap &DAGInsts) { … }
void CodeGenDAGPatterns::ParseInstructions() { … }
NameRecord;
static void FindNames(TreePatternNode &P,
std::map<std::string, NameRecord> &Names,
TreePattern *PatternTop) { … }
void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern,
PatternToMatch &&PTM) { … }
void CodeGenDAGPatterns::InferInstructionFlags() { … }
void CodeGenDAGPatterns::VerifyInstructionFlags() { … }
static bool ForceArbitraryInstResultType(TreePatternNode &N, TreePattern &TP) { … }
static TreePatternNodePtr PromoteXForms(TreePatternNodePtr N) { … }
void CodeGenDAGPatterns::ParseOnePattern(
const Record *TheDef, TreePattern &Pattern, TreePattern &Result,
ArrayRef<const Record *> InstImpResults, bool ShouldIgnore) { … }
void CodeGenDAGPatterns::ParsePatterns() { … }
static void collectModes(std::set<unsigned> &Modes, const TreePatternNode &N) { … }
void CodeGenDAGPatterns::ExpandHwModeBasedTypes() { … }
DepVarMap;
static void FindDepVarsOf(TreePatternNode &N, DepVarMap &DepMap) { … }
static void FindDepVars(TreePatternNode &N, MultipleUseVarSet &DepVars) { … }
#ifndef NDEBUG
static void DumpDepVars(MultipleUseVarSet &DepVars) {
if (DepVars.empty()) {
LLVM_DEBUG(errs() << "<empty set>");
} else {
LLVM_DEBUG(errs() << "[ ");
for (const auto &DepVar : DepVars) {
LLVM_DEBUG(errs() << DepVar.getKey() << " ");
}
LLVM_DEBUG(errs() << "]");
}
}
#endif
static void CombineChildVariants(
TreePatternNodePtr Orig,
const std::vector<std::vector<TreePatternNodePtr>> &ChildVariants,
std::vector<TreePatternNodePtr> &OutVariants, CodeGenDAGPatterns &CDP,
const MultipleUseVarSet &DepVars) { … }
static void CombineChildVariants(TreePatternNodePtr Orig,
const std::vector<TreePatternNodePtr> &LHS,
const std::vector<TreePatternNodePtr> &RHS,
std::vector<TreePatternNodePtr> &OutVariants,
CodeGenDAGPatterns &CDP,
const MultipleUseVarSet &DepVars) { … }
static void
GatherChildrenOfAssociativeOpcode(TreePatternNodePtr N,
std::vector<TreePatternNodePtr> &Children) { … }
static void GenerateVariantsOf(TreePatternNodePtr N,
std::vector<TreePatternNodePtr> &OutVariants,
CodeGenDAGPatterns &CDP,
const MultipleUseVarSet &DepVars) { … }
void CodeGenDAGPatterns::GenerateVariants() { … }
unsigned CodeGenDAGPatterns::getNewUID() { … }