forked from OSchip/llvm-project
parent
6aade28fd3
commit
2c3f6492b0
|
@ -1945,7 +1945,7 @@ void DAGISelEmitter::run(raw_ostream &OS) {
|
|||
}
|
||||
|
||||
#ifdef ENABLE_NEW_ISEL
|
||||
MatcherNode *Matcher = 0;
|
||||
Matcher *TheMatcher = 0;
|
||||
|
||||
// Add all the patterns to a temporary list so we can sort them.
|
||||
std::vector<const PatternToMatch*> Patterns;
|
||||
|
@ -1967,18 +1967,18 @@ void DAGISelEmitter::run(raw_ostream &OS) {
|
|||
const PatternToMatch &Pattern = *Patterns.back();
|
||||
Patterns.pop_back();
|
||||
|
||||
MatcherNode *N = ConvertPatternToMatcher(Pattern, CGP);
|
||||
Matcher *N = ConvertPatternToMatcher(Pattern, CGP);
|
||||
|
||||
if (Matcher == 0)
|
||||
Matcher = N;
|
||||
if (TheMatcher == 0)
|
||||
TheMatcher = N;
|
||||
else
|
||||
Matcher = new ScopeMatcherNode(N, Matcher);
|
||||
TheMatcher = new ScopeMatcher(N, TheMatcher);
|
||||
}
|
||||
|
||||
Matcher = OptimizeMatcher(Matcher);
|
||||
TheMatcher = OptimizeMatcher(TheMatcher);
|
||||
//Matcher->dump();
|
||||
EmitMatcherTable(Matcher, OS);
|
||||
delete Matcher;
|
||||
EmitMatcherTable(TheMatcher, OS);
|
||||
delete TheMatcher;
|
||||
|
||||
#else
|
||||
// At this point, we have full information about the 'Patterns' we need to
|
||||
|
|
|
@ -14,144 +14,144 @@
|
|||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
void MatcherNode::dump() const {
|
||||
void Matcher::dump() const {
|
||||
print(errs());
|
||||
}
|
||||
|
||||
void MatcherNode::printNext(raw_ostream &OS, unsigned indent) const {
|
||||
void Matcher::printNext(raw_ostream &OS, unsigned indent) const {
|
||||
if (Next)
|
||||
return Next->print(OS, indent);
|
||||
}
|
||||
|
||||
|
||||
void ScopeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void ScopeMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "Scope\n";
|
||||
Check->print(OS, indent+2);
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void RecordMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void RecordMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "Record\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void RecordChildMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void RecordChildMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "RecordChild: " << ChildNo << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void RecordMemRefMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void RecordMemRefMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "RecordMemRef\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CaptureFlagInputMatcherNode::print(raw_ostream &OS, unsigned indent) const{
|
||||
void CaptureFlagInputMatcher::print(raw_ostream &OS, unsigned indent) const{
|
||||
OS.indent(indent) << "CaptureFlagInput\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void MoveChildMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void MoveChildMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "MoveChild " << ChildNo << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void MoveParentMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void MoveParentMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "MoveParent\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckSameMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckSameMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckSame " << MatchNumber << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckPatternPredicateMatcherNode::
|
||||
void CheckPatternPredicateMatcher::
|
||||
print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckPatternPredicate " << Predicate << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckPredicateMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckPredicateMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckPredicate " << PredName << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckOpcodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckOpcodeMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckOpcode " << OpcodeName << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckMultiOpcodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckMultiOpcodeMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckMultiOpcode <todo args>\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckTypeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckTypeMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckType " << getEnumName(Type) << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckChildTypeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckChildTypeMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckChildType " << ChildNo << " "
|
||||
<< getEnumName(Type) << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
|
||||
void CheckIntegerMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckIntegerMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckInteger " << Value << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckCondCodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckCondCodeMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckCondCode ISD::" << CondCodeName << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckValueTypeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckValueTypeMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckValueType MVT::" << TypeName << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckComplexPatMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckComplexPatMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckComplexPat " << Pattern.getSelectFunc() << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckAndImmMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckAndImmMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckAndImm " << Value << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckOrImmMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CheckOrImmMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckOrImm " << Value << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckFoldableChainNodeMatcherNode::print(raw_ostream &OS,
|
||||
void CheckFoldableChainNodeMatcher::print(raw_ostream &OS,
|
||||
unsigned indent) const {
|
||||
OS.indent(indent) << "CheckFoldableChainNode\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CheckChainCompatibleMatcherNode::print(raw_ostream &OS,
|
||||
void CheckChainCompatibleMatcher::print(raw_ostream &OS,
|
||||
unsigned indent) const {
|
||||
OS.indent(indent) << "CheckChainCompatible " << PreviousOp << "\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void EmitIntegerMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void EmitIntegerMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "EmitInteger " << Val << " VT=" << VT << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void EmitStringIntegerMatcherNode::
|
||||
void EmitStringIntegerMatcher::
|
||||
print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "EmitStringInteger " << Val << " VT=" << VT << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void EmitRegisterMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void EmitRegisterMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "EmitRegister ";
|
||||
if (Reg)
|
||||
OS << Reg->getName();
|
||||
|
@ -161,31 +161,31 @@ void EmitRegisterMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
|||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void EmitConvertToTargetMatcherNode::
|
||||
void EmitConvertToTargetMatcher::
|
||||
print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "EmitConvertToTarget " << Slot << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void EmitMergeInputChainsMatcherNode::
|
||||
void EmitMergeInputChainsMatcher::
|
||||
print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "EmitMergeInputChains <todo: args>\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void EmitCopyToRegMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void EmitCopyToRegMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "EmitCopyToReg <todo: args>\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void EmitNodeXFormMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void EmitNodeXFormMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "EmitNodeXForm " << NodeXForm->getName()
|
||||
<< " Slot=" << Slot << '\n';
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
|
||||
void EmitNodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void EmitNodeMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "EmitNode: " << OpcodeName << ": <todo flags> ";
|
||||
|
||||
for (unsigned i = 0, e = VTs.size(); i != e; ++i)
|
||||
|
@ -197,12 +197,12 @@ void EmitNodeMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
|||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void MarkFlagResultsMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void MarkFlagResultsMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "MarkFlagResults <todo: args>\n";
|
||||
printNext(OS, indent);
|
||||
}
|
||||
|
||||
void CompleteMatchMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||
void CompleteMatchMatcher::print(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CompleteMatch <todo args>\n";
|
||||
OS.indent(indent) << "Src = " << *Pattern.getSrcPattern() << "\n";
|
||||
OS.indent(indent) << "Dst = " << *Pattern.getDstPattern() << "\n";
|
||||
|
|
|
@ -18,24 +18,24 @@
|
|||
|
||||
namespace llvm {
|
||||
class CodeGenDAGPatterns;
|
||||
class MatcherNode;
|
||||
class Matcher;
|
||||
class PatternToMatch;
|
||||
class raw_ostream;
|
||||
class ComplexPattern;
|
||||
class Record;
|
||||
|
||||
MatcherNode *ConvertPatternToMatcher(const PatternToMatch &Pattern,
|
||||
const CodeGenDAGPatterns &CGP);
|
||||
MatcherNode *OptimizeMatcher(MatcherNode *Matcher);
|
||||
void EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &OS);
|
||||
Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,
|
||||
const CodeGenDAGPatterns &CGP);
|
||||
Matcher *OptimizeMatcher(Matcher *Matcher);
|
||||
void EmitMatcherTable(const Matcher *Matcher, raw_ostream &OS);
|
||||
|
||||
|
||||
/// MatcherNode - Base class for all the the DAG ISel Matcher representation
|
||||
/// Matcher - Base class for all the the DAG ISel Matcher representation
|
||||
/// nodes.
|
||||
class MatcherNode {
|
||||
class Matcher {
|
||||
// The next matcher node that is executed after this one. Null if this is the
|
||||
// last stage of a match.
|
||||
OwningPtr<MatcherNode> Next;
|
||||
OwningPtr<Matcher> Next;
|
||||
public:
|
||||
enum KindTy {
|
||||
// Matcher state manipulation.
|
||||
|
@ -79,20 +79,20 @@ public:
|
|||
const KindTy Kind;
|
||||
|
||||
protected:
|
||||
MatcherNode(KindTy K) : Kind(K) {}
|
||||
Matcher(KindTy K) : Kind(K) {}
|
||||
public:
|
||||
virtual ~MatcherNode() {}
|
||||
virtual ~Matcher() {}
|
||||
|
||||
KindTy getKind() const { return Kind; }
|
||||
|
||||
MatcherNode *getNext() { return Next.get(); }
|
||||
const MatcherNode *getNext() const { return Next.get(); }
|
||||
void setNext(MatcherNode *C) { Next.reset(C); }
|
||||
MatcherNode *takeNext() { return Next.take(); }
|
||||
Matcher *getNext() { return Next.get(); }
|
||||
const Matcher *getNext() const { return Next.get(); }
|
||||
void setNext(Matcher *C) { Next.reset(C); }
|
||||
Matcher *takeNext() { return Next.take(); }
|
||||
|
||||
OwningPtr<MatcherNode> &getNextPtr() { return Next; }
|
||||
OwningPtr<Matcher> &getNextPtr() { return Next; }
|
||||
|
||||
static inline bool classof(const MatcherNode *) { return true; }
|
||||
static inline bool classof(const Matcher *) { return true; }
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const = 0;
|
||||
void dump() const;
|
||||
|
@ -100,76 +100,76 @@ protected:
|
|||
void printNext(raw_ostream &OS, unsigned indent) const;
|
||||
};
|
||||
|
||||
/// ScopeMatcherNode - This pushes a failure scope on the stack and evaluates
|
||||
/// ScopeMatcher - This pushes a failure scope on the stack and evaluates
|
||||
/// 'Check'. If 'Check' fails to match, it pops its scope and continues on to
|
||||
/// 'Next'.
|
||||
class ScopeMatcherNode : public MatcherNode {
|
||||
OwningPtr<MatcherNode> Check;
|
||||
class ScopeMatcher : public Matcher {
|
||||
OwningPtr<Matcher> Check;
|
||||
public:
|
||||
ScopeMatcherNode(MatcherNode *check = 0, MatcherNode *next = 0)
|
||||
: MatcherNode(Scope), Check(check) {
|
||||
ScopeMatcher(Matcher *check = 0, Matcher *next = 0)
|
||||
: Matcher(Scope), Check(check) {
|
||||
setNext(next);
|
||||
}
|
||||
|
||||
MatcherNode *getCheck() { return Check.get(); }
|
||||
const MatcherNode *getCheck() const { return Check.get(); }
|
||||
void setCheck(MatcherNode *N) { Check.reset(N); }
|
||||
OwningPtr<MatcherNode> &getCheckPtr() { return Check; }
|
||||
Matcher *getCheck() { return Check.get(); }
|
||||
const Matcher *getCheck() const { return Check.get(); }
|
||||
void setCheck(Matcher *N) { Check.reset(N); }
|
||||
OwningPtr<Matcher> &getCheckPtr() { return Check; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == Scope;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// RecordMatcherNode - Save the current node in the operand list.
|
||||
class RecordMatcherNode : public MatcherNode {
|
||||
/// RecordMatcher - Save the current node in the operand list.
|
||||
class RecordMatcher : public Matcher {
|
||||
/// WhatFor - This is a string indicating why we're recording this. This
|
||||
/// should only be used for comment generation not anything semantic.
|
||||
std::string WhatFor;
|
||||
public:
|
||||
RecordMatcherNode(const std::string &whatfor)
|
||||
: MatcherNode(RecordNode), WhatFor(whatfor) {}
|
||||
RecordMatcher(const std::string &whatfor)
|
||||
: Matcher(RecordNode), WhatFor(whatfor) {}
|
||||
|
||||
const std::string &getWhatFor() const { return WhatFor; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == RecordNode;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// RecordChildMatcherNode - Save a numbered child of the current node, or fail
|
||||
/// RecordChildMatcher - Save a numbered child of the current node, or fail
|
||||
/// the match if it doesn't exist. This is logically equivalent to:
|
||||
/// MoveChild N + RecordNode + MoveParent.
|
||||
class RecordChildMatcherNode : public MatcherNode {
|
||||
class RecordChildMatcher : public Matcher {
|
||||
unsigned ChildNo;
|
||||
|
||||
/// WhatFor - This is a string indicating why we're recording this. This
|
||||
/// should only be used for comment generation not anything semantic.
|
||||
std::string WhatFor;
|
||||
public:
|
||||
RecordChildMatcherNode(unsigned childno, const std::string &whatfor)
|
||||
: MatcherNode(RecordChild), ChildNo(childno), WhatFor(whatfor) {}
|
||||
RecordChildMatcher(unsigned childno, const std::string &whatfor)
|
||||
: Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor) {}
|
||||
|
||||
unsigned getChildNo() const { return ChildNo; }
|
||||
const std::string &getWhatFor() const { return WhatFor; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == RecordChild;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// RecordMemRefMatcherNode - Save the current node's memref.
|
||||
class RecordMemRefMatcherNode : public MatcherNode {
|
||||
/// RecordMemRefMatcher - Save the current node's memref.
|
||||
class RecordMemRefMatcher : public Matcher {
|
||||
public:
|
||||
RecordMemRefMatcherNode() : MatcherNode(RecordMemRef) {}
|
||||
RecordMemRefMatcher() : Matcher(RecordMemRef) {}
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == RecordMemRef;
|
||||
}
|
||||
|
||||
|
@ -177,98 +177,95 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/// CaptureFlagInputMatcherNode - If the current record has a flag input, record
|
||||
/// CaptureFlagInputMatcher - If the current record has a flag input, record
|
||||
/// it so that it is used as an input to the generated code.
|
||||
class CaptureFlagInputMatcherNode : public MatcherNode {
|
||||
class CaptureFlagInputMatcher : public Matcher {
|
||||
public:
|
||||
CaptureFlagInputMatcherNode()
|
||||
: MatcherNode(CaptureFlagInput) {}
|
||||
CaptureFlagInputMatcher() : Matcher(CaptureFlagInput) {}
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CaptureFlagInput;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// MoveChildMatcherNode - This tells the interpreter to move into the
|
||||
/// MoveChildMatcher - This tells the interpreter to move into the
|
||||
/// specified child node.
|
||||
class MoveChildMatcherNode : public MatcherNode {
|
||||
class MoveChildMatcher : public Matcher {
|
||||
unsigned ChildNo;
|
||||
public:
|
||||
MoveChildMatcherNode(unsigned childNo)
|
||||
: MatcherNode(MoveChild), ChildNo(childNo) {}
|
||||
MoveChildMatcher(unsigned childNo) : Matcher(MoveChild), ChildNo(childNo) {}
|
||||
|
||||
unsigned getChildNo() const { return ChildNo; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == MoveChild;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// MoveParentMatcherNode - This tells the interpreter to move to the parent
|
||||
/// MoveParentMatcher - This tells the interpreter to move to the parent
|
||||
/// of the current node.
|
||||
class MoveParentMatcherNode : public MatcherNode {
|
||||
class MoveParentMatcher : public Matcher {
|
||||
public:
|
||||
MoveParentMatcherNode()
|
||||
: MatcherNode(MoveParent) {}
|
||||
MoveParentMatcher() : Matcher(MoveParent) {}
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == MoveParent;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckSameMatcherNode - This checks to see if this node is exactly the same
|
||||
/// CheckSameMatcher - This checks to see if this node is exactly the same
|
||||
/// node as the specified match that was recorded with 'Record'. This is used
|
||||
/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
|
||||
class CheckSameMatcherNode : public MatcherNode {
|
||||
class CheckSameMatcher : public Matcher {
|
||||
unsigned MatchNumber;
|
||||
public:
|
||||
CheckSameMatcherNode(unsigned matchnumber)
|
||||
: MatcherNode(CheckSame), MatchNumber(matchnumber) {}
|
||||
CheckSameMatcher(unsigned matchnumber)
|
||||
: Matcher(CheckSame), MatchNumber(matchnumber) {}
|
||||
|
||||
unsigned getMatchNumber() const { return MatchNumber; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckSame;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckPatternPredicateMatcherNode - This checks the target-specific predicate
|
||||
/// CheckPatternPredicateMatcher - This checks the target-specific predicate
|
||||
/// to see if the entire pattern is capable of matching. This predicate does
|
||||
/// not take a node as input. This is used for subtarget feature checks etc.
|
||||
class CheckPatternPredicateMatcherNode : public MatcherNode {
|
||||
class CheckPatternPredicateMatcher : public Matcher {
|
||||
std::string Predicate;
|
||||
public:
|
||||
CheckPatternPredicateMatcherNode(StringRef predicate)
|
||||
: MatcherNode(CheckPatternPredicate), Predicate(predicate) {}
|
||||
CheckPatternPredicateMatcher(StringRef predicate)
|
||||
: Matcher(CheckPatternPredicate), Predicate(predicate) {}
|
||||
|
||||
StringRef getPredicate() const { return Predicate; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckPatternPredicate;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckPredicateMatcherNode - This checks the target-specific predicate to
|
||||
/// CheckPredicateMatcher - This checks the target-specific predicate to
|
||||
/// see if the node is acceptable.
|
||||
class CheckPredicateMatcherNode : public MatcherNode {
|
||||
class CheckPredicateMatcher : public Matcher {
|
||||
StringRef PredName;
|
||||
public:
|
||||
CheckPredicateMatcherNode(StringRef predname)
|
||||
: MatcherNode(CheckPredicate), PredName(predname) {}
|
||||
CheckPredicateMatcher(StringRef predname)
|
||||
: Matcher(CheckPredicate), PredName(predname) {}
|
||||
|
||||
StringRef getPredicateName() const { return PredName; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckPredicate;
|
||||
}
|
||||
|
||||
|
@ -276,35 +273,35 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/// CheckOpcodeMatcherNode - This checks to see if the current node has the
|
||||
/// CheckOpcodeMatcher - This checks to see if the current node has the
|
||||
/// specified opcode, if not it fails to match.
|
||||
class CheckOpcodeMatcherNode : public MatcherNode {
|
||||
class CheckOpcodeMatcher : public Matcher {
|
||||
StringRef OpcodeName;
|
||||
public:
|
||||
CheckOpcodeMatcherNode(StringRef opcodename)
|
||||
: MatcherNode(CheckOpcode), OpcodeName(opcodename) {}
|
||||
CheckOpcodeMatcher(StringRef opcodename)
|
||||
: Matcher(CheckOpcode), OpcodeName(opcodename) {}
|
||||
|
||||
StringRef getOpcodeName() const { return OpcodeName; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckOpcode;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckMultiOpcodeMatcherNode - This checks to see if the current node has one
|
||||
/// CheckMultiOpcodeMatcher - This checks to see if the current node has one
|
||||
/// of the specified opcode, if not it fails to match.
|
||||
class CheckMultiOpcodeMatcherNode : public MatcherNode {
|
||||
class CheckMultiOpcodeMatcher : public Matcher {
|
||||
SmallVector<StringRef, 4> OpcodeNames;
|
||||
public:
|
||||
CheckMultiOpcodeMatcherNode(const StringRef *opcodes, unsigned numops)
|
||||
: MatcherNode(CheckMultiOpcode), OpcodeNames(opcodes, opcodes+numops) {}
|
||||
CheckMultiOpcodeMatcher(const StringRef *opcodes, unsigned numops)
|
||||
: Matcher(CheckMultiOpcode), OpcodeNames(opcodes, opcodes+numops) {}
|
||||
|
||||
unsigned getNumOpcodeNames() const { return OpcodeNames.size(); }
|
||||
StringRef getOpcodeName(unsigned i) const { return OpcodeNames[i]; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckMultiOpcode;
|
||||
}
|
||||
|
||||
|
@ -313,36 +310,36 @@ public:
|
|||
|
||||
|
||||
|
||||
/// CheckTypeMatcherNode - This checks to see if the current node has the
|
||||
/// CheckTypeMatcher - This checks to see if the current node has the
|
||||
/// specified type, if not it fails to match.
|
||||
class CheckTypeMatcherNode : public MatcherNode {
|
||||
class CheckTypeMatcher : public Matcher {
|
||||
MVT::SimpleValueType Type;
|
||||
public:
|
||||
CheckTypeMatcherNode(MVT::SimpleValueType type)
|
||||
: MatcherNode(CheckType), Type(type) {}
|
||||
CheckTypeMatcher(MVT::SimpleValueType type)
|
||||
: Matcher(CheckType), Type(type) {}
|
||||
|
||||
MVT::SimpleValueType getType() const { return Type; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckType;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckChildTypeMatcherNode - This checks to see if a child node has the
|
||||
/// CheckChildTypeMatcher - This checks to see if a child node has the
|
||||
/// specified type, if not it fails to match.
|
||||
class CheckChildTypeMatcherNode : public MatcherNode {
|
||||
class CheckChildTypeMatcher : public Matcher {
|
||||
unsigned ChildNo;
|
||||
MVT::SimpleValueType Type;
|
||||
public:
|
||||
CheckChildTypeMatcherNode(unsigned childno, MVT::SimpleValueType type)
|
||||
: MatcherNode(CheckChildType), ChildNo(childno), Type(type) {}
|
||||
CheckChildTypeMatcher(unsigned childno, MVT::SimpleValueType type)
|
||||
: Matcher(CheckChildType), ChildNo(childno), Type(type) {}
|
||||
|
||||
unsigned getChildNo() const { return ChildNo; }
|
||||
MVT::SimpleValueType getType() const { return Type; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckChildType;
|
||||
}
|
||||
|
||||
|
@ -350,51 +347,51 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/// CheckIntegerMatcherNode - This checks to see if the current node is a
|
||||
/// CheckIntegerMatcher - This checks to see if the current node is a
|
||||
/// ConstantSDNode with the specified integer value, if not it fails to match.
|
||||
class CheckIntegerMatcherNode : public MatcherNode {
|
||||
class CheckIntegerMatcher : public Matcher {
|
||||
int64_t Value;
|
||||
public:
|
||||
CheckIntegerMatcherNode(int64_t value)
|
||||
: MatcherNode(CheckInteger), Value(value) {}
|
||||
CheckIntegerMatcher(int64_t value)
|
||||
: Matcher(CheckInteger), Value(value) {}
|
||||
|
||||
int64_t getValue() const { return Value; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckInteger;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckCondCodeMatcherNode - This checks to see if the current node is a
|
||||
/// CheckCondCodeMatcher - This checks to see if the current node is a
|
||||
/// CondCodeSDNode with the specified condition, if not it fails to match.
|
||||
class CheckCondCodeMatcherNode : public MatcherNode {
|
||||
class CheckCondCodeMatcher : public Matcher {
|
||||
StringRef CondCodeName;
|
||||
public:
|
||||
CheckCondCodeMatcherNode(StringRef condcodename)
|
||||
: MatcherNode(CheckCondCode), CondCodeName(condcodename) {}
|
||||
CheckCondCodeMatcher(StringRef condcodename)
|
||||
: Matcher(CheckCondCode), CondCodeName(condcodename) {}
|
||||
|
||||
StringRef getCondCodeName() const { return CondCodeName; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckCondCode;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckValueTypeMatcherNode - This checks to see if the current node is a
|
||||
/// CheckValueTypeMatcher - This checks to see if the current node is a
|
||||
/// VTSDNode with the specified type, if not it fails to match.
|
||||
class CheckValueTypeMatcherNode : public MatcherNode {
|
||||
class CheckValueTypeMatcher : public Matcher {
|
||||
StringRef TypeName;
|
||||
public:
|
||||
CheckValueTypeMatcherNode(StringRef type_name)
|
||||
: MatcherNode(CheckValueType), TypeName(type_name) {}
|
||||
CheckValueTypeMatcher(StringRef type_name)
|
||||
: Matcher(CheckValueType), TypeName(type_name) {}
|
||||
|
||||
StringRef getTypeName() const { return TypeName; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckValueType;
|
||||
}
|
||||
|
||||
|
@ -403,172 +400,172 @@ public:
|
|||
|
||||
|
||||
|
||||
/// CheckComplexPatMatcherNode - This node runs the specified ComplexPattern on
|
||||
/// CheckComplexPatMatcher - This node runs the specified ComplexPattern on
|
||||
/// the current node.
|
||||
class CheckComplexPatMatcherNode : public MatcherNode {
|
||||
class CheckComplexPatMatcher : public Matcher {
|
||||
const ComplexPattern &Pattern;
|
||||
public:
|
||||
CheckComplexPatMatcherNode(const ComplexPattern &pattern)
|
||||
: MatcherNode(CheckComplexPat), Pattern(pattern) {}
|
||||
CheckComplexPatMatcher(const ComplexPattern &pattern)
|
||||
: Matcher(CheckComplexPat), Pattern(pattern) {}
|
||||
|
||||
const ComplexPattern &getPattern() const { return Pattern; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckComplexPat;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckAndImmMatcherNode - This checks to see if the current node is an 'and'
|
||||
/// CheckAndImmMatcher - This checks to see if the current node is an 'and'
|
||||
/// with something equivalent to the specified immediate.
|
||||
class CheckAndImmMatcherNode : public MatcherNode {
|
||||
class CheckAndImmMatcher : public Matcher {
|
||||
int64_t Value;
|
||||
public:
|
||||
CheckAndImmMatcherNode(int64_t value)
|
||||
: MatcherNode(CheckAndImm), Value(value) {}
|
||||
CheckAndImmMatcher(int64_t value)
|
||||
: Matcher(CheckAndImm), Value(value) {}
|
||||
|
||||
int64_t getValue() const { return Value; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckAndImm;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckOrImmMatcherNode - This checks to see if the current node is an 'and'
|
||||
/// CheckOrImmMatcher - This checks to see if the current node is an 'and'
|
||||
/// with something equivalent to the specified immediate.
|
||||
class CheckOrImmMatcherNode : public MatcherNode {
|
||||
class CheckOrImmMatcher : public Matcher {
|
||||
int64_t Value;
|
||||
public:
|
||||
CheckOrImmMatcherNode(int64_t value)
|
||||
: MatcherNode(CheckOrImm), Value(value) {}
|
||||
CheckOrImmMatcher(int64_t value)
|
||||
: Matcher(CheckOrImm), Value(value) {}
|
||||
|
||||
int64_t getValue() const { return Value; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckOrImm;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckFoldableChainNodeMatcherNode - This checks to see if the current node
|
||||
/// CheckFoldableChainNodeMatcher - This checks to see if the current node
|
||||
/// (which defines a chain operand) is safe to fold into a larger pattern.
|
||||
class CheckFoldableChainNodeMatcherNode : public MatcherNode {
|
||||
class CheckFoldableChainNodeMatcher : public Matcher {
|
||||
public:
|
||||
CheckFoldableChainNodeMatcherNode()
|
||||
: MatcherNode(CheckFoldableChainNode) {}
|
||||
CheckFoldableChainNodeMatcher()
|
||||
: Matcher(CheckFoldableChainNode) {}
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckFoldableChainNode;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CheckChainCompatibleMatcherNode - Verify that the current node's chain
|
||||
/// CheckChainCompatibleMatcher - Verify that the current node's chain
|
||||
/// operand is 'compatible' with the specified recorded node's.
|
||||
class CheckChainCompatibleMatcherNode : public MatcherNode {
|
||||
class CheckChainCompatibleMatcher : public Matcher {
|
||||
unsigned PreviousOp;
|
||||
public:
|
||||
CheckChainCompatibleMatcherNode(unsigned previousop)
|
||||
: MatcherNode(CheckChainCompatible), PreviousOp(previousop) {}
|
||||
CheckChainCompatibleMatcher(unsigned previousop)
|
||||
: Matcher(CheckChainCompatible), PreviousOp(previousop) {}
|
||||
|
||||
unsigned getPreviousOp() const { return PreviousOp; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckChainCompatible;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// EmitIntegerMatcherNode - This creates a new TargetConstant.
|
||||
class EmitIntegerMatcherNode : public MatcherNode {
|
||||
/// EmitIntegerMatcher - This creates a new TargetConstant.
|
||||
class EmitIntegerMatcher : public Matcher {
|
||||
int64_t Val;
|
||||
MVT::SimpleValueType VT;
|
||||
public:
|
||||
EmitIntegerMatcherNode(int64_t val, MVT::SimpleValueType vt)
|
||||
: MatcherNode(EmitInteger), Val(val), VT(vt) {}
|
||||
EmitIntegerMatcher(int64_t val, MVT::SimpleValueType vt)
|
||||
: Matcher(EmitInteger), Val(val), VT(vt) {}
|
||||
|
||||
int64_t getValue() const { return Val; }
|
||||
MVT::SimpleValueType getVT() const { return VT; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == EmitInteger;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// EmitStringIntegerMatcherNode - A target constant whose value is represented
|
||||
/// EmitStringIntegerMatcher - A target constant whose value is represented
|
||||
/// by a string.
|
||||
class EmitStringIntegerMatcherNode : public MatcherNode {
|
||||
class EmitStringIntegerMatcher : public Matcher {
|
||||
std::string Val;
|
||||
MVT::SimpleValueType VT;
|
||||
public:
|
||||
EmitStringIntegerMatcherNode(const std::string &val, MVT::SimpleValueType vt)
|
||||
: MatcherNode(EmitStringInteger), Val(val), VT(vt) {}
|
||||
EmitStringIntegerMatcher(const std::string &val, MVT::SimpleValueType vt)
|
||||
: Matcher(EmitStringInteger), Val(val), VT(vt) {}
|
||||
|
||||
const std::string &getValue() const { return Val; }
|
||||
MVT::SimpleValueType getVT() const { return VT; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == EmitStringInteger;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// EmitRegisterMatcherNode - This creates a new TargetConstant.
|
||||
class EmitRegisterMatcherNode : public MatcherNode {
|
||||
/// EmitRegisterMatcher - This creates a new TargetConstant.
|
||||
class EmitRegisterMatcher : public Matcher {
|
||||
/// Reg - The def for the register that we're emitting. If this is null, then
|
||||
/// this is a reference to zero_reg.
|
||||
Record *Reg;
|
||||
MVT::SimpleValueType VT;
|
||||
public:
|
||||
EmitRegisterMatcherNode(Record *reg, MVT::SimpleValueType vt)
|
||||
: MatcherNode(EmitRegister), Reg(reg), VT(vt) {}
|
||||
EmitRegisterMatcher(Record *reg, MVT::SimpleValueType vt)
|
||||
: Matcher(EmitRegister), Reg(reg), VT(vt) {}
|
||||
|
||||
Record *getReg() const { return Reg; }
|
||||
MVT::SimpleValueType getVT() const { return VT; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == EmitRegister;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// EmitConvertToTargetMatcherNode - Emit an operation that reads a specified
|
||||
/// EmitConvertToTargetMatcher - Emit an operation that reads a specified
|
||||
/// recorded node and converts it from being a ISD::Constant to
|
||||
/// ISD::TargetConstant, likewise for ConstantFP.
|
||||
class EmitConvertToTargetMatcherNode : public MatcherNode {
|
||||
class EmitConvertToTargetMatcher : public Matcher {
|
||||
unsigned Slot;
|
||||
public:
|
||||
EmitConvertToTargetMatcherNode(unsigned slot)
|
||||
: MatcherNode(EmitConvertToTarget), Slot(slot) {}
|
||||
EmitConvertToTargetMatcher(unsigned slot)
|
||||
: Matcher(EmitConvertToTarget), Slot(slot) {}
|
||||
|
||||
unsigned getSlot() const { return Slot; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == EmitConvertToTarget;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// EmitMergeInputChainsMatcherNode - Emit a node that merges a list of input
|
||||
/// EmitMergeInputChainsMatcher - Emit a node that merges a list of input
|
||||
/// chains together with a token factor. The list of nodes are the nodes in the
|
||||
/// matched pattern that have chain input/outputs. This node adds all input
|
||||
/// chains of these nodes if they are not themselves a node in the pattern.
|
||||
class EmitMergeInputChainsMatcherNode : public MatcherNode {
|
||||
class EmitMergeInputChainsMatcher : public Matcher {
|
||||
SmallVector<unsigned, 3> ChainNodes;
|
||||
public:
|
||||
EmitMergeInputChainsMatcherNode(const unsigned *nodes, unsigned NumNodes)
|
||||
: MatcherNode(EmitMergeInputChains), ChainNodes(nodes, nodes+NumNodes) {}
|
||||
EmitMergeInputChainsMatcher(const unsigned *nodes, unsigned NumNodes)
|
||||
: Matcher(EmitMergeInputChains), ChainNodes(nodes, nodes+NumNodes) {}
|
||||
|
||||
unsigned getNumNodes() const { return ChainNodes.size(); }
|
||||
|
||||
|
@ -577,27 +574,27 @@ public:
|
|||
return ChainNodes[i];
|
||||
}
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == EmitMergeInputChains;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// EmitCopyToRegMatcherNode - Emit a CopyToReg node from a value to a physreg,
|
||||
/// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg,
|
||||
/// pushing the chain and flag results.
|
||||
///
|
||||
class EmitCopyToRegMatcherNode : public MatcherNode {
|
||||
class EmitCopyToRegMatcher : public Matcher {
|
||||
unsigned SrcSlot; // Value to copy into the physreg.
|
||||
Record *DestPhysReg;
|
||||
public:
|
||||
EmitCopyToRegMatcherNode(unsigned srcSlot, Record *destPhysReg)
|
||||
: MatcherNode(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {}
|
||||
EmitCopyToRegMatcher(unsigned srcSlot, Record *destPhysReg)
|
||||
: Matcher(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {}
|
||||
|
||||
unsigned getSrcSlot() const { return SrcSlot; }
|
||||
Record *getDestPhysReg() const { return DestPhysReg; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == EmitCopyToReg;
|
||||
}
|
||||
|
||||
|
@ -606,27 +603,27 @@ public:
|
|||
|
||||
|
||||
|
||||
/// EmitNodeXFormMatcherNode - Emit an operation that runs an SDNodeXForm on a
|
||||
/// EmitNodeXFormMatcher - Emit an operation that runs an SDNodeXForm on a
|
||||
/// recorded node and records the result.
|
||||
class EmitNodeXFormMatcherNode : public MatcherNode {
|
||||
class EmitNodeXFormMatcher : public Matcher {
|
||||
unsigned Slot;
|
||||
Record *NodeXForm;
|
||||
public:
|
||||
EmitNodeXFormMatcherNode(unsigned slot, Record *nodeXForm)
|
||||
: MatcherNode(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {}
|
||||
EmitNodeXFormMatcher(unsigned slot, Record *nodeXForm)
|
||||
: Matcher(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {}
|
||||
|
||||
unsigned getSlot() const { return Slot; }
|
||||
Record *getNodeXForm() const { return NodeXForm; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == EmitNodeXForm;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// EmitNodeMatcherNode - This signals a successful match and generates a node.
|
||||
class EmitNodeMatcherNode : public MatcherNode {
|
||||
/// EmitNodeMatcher - This signals a successful match and generates a node.
|
||||
class EmitNodeMatcher : public Matcher {
|
||||
std::string OpcodeName;
|
||||
const SmallVector<MVT::SimpleValueType, 3> VTs;
|
||||
const SmallVector<unsigned, 6> Operands;
|
||||
|
@ -637,12 +634,12 @@ class EmitNodeMatcherNode : public MatcherNode {
|
|||
/// operands in the root of the pattern. The rest are appended to this node.
|
||||
int NumFixedArityOperands;
|
||||
public:
|
||||
EmitNodeMatcherNode(const std::string &opcodeName,
|
||||
EmitNodeMatcher(const std::string &opcodeName,
|
||||
const MVT::SimpleValueType *vts, unsigned numvts,
|
||||
const unsigned *operands, unsigned numops,
|
||||
bool hasChain, bool hasFlag, bool hasmemrefs,
|
||||
int numfixedarityoperands)
|
||||
: MatcherNode(EmitNode), OpcodeName(opcodeName),
|
||||
: Matcher(EmitNode), OpcodeName(opcodeName),
|
||||
VTs(vts, vts+numvts), Operands(operands, operands+numops),
|
||||
HasChain(hasChain), HasFlag(hasFlag), HasMemRefs(hasmemrefs),
|
||||
NumFixedArityOperands(numfixedarityoperands) {}
|
||||
|
@ -666,21 +663,21 @@ public:
|
|||
bool hasMemRefs() const { return HasMemRefs; }
|
||||
int getNumFixedArityOperands() const { return NumFixedArityOperands; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == EmitNode;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// MarkFlagResultsMatcherNode - This node indicates which non-root nodes in the
|
||||
/// pattern produce flags. This allows CompleteMatchMatcherNode to update them
|
||||
/// MarkFlagResultsMatcher - This node indicates which non-root nodes in the
|
||||
/// pattern produce flags. This allows CompleteMatchMatcher to update them
|
||||
/// with the output flag of the resultant code.
|
||||
class MarkFlagResultsMatcherNode : public MatcherNode {
|
||||
class MarkFlagResultsMatcher : public Matcher {
|
||||
SmallVector<unsigned, 3> FlagResultNodes;
|
||||
public:
|
||||
MarkFlagResultsMatcherNode(const unsigned *nodes, unsigned NumNodes)
|
||||
: MatcherNode(MarkFlagResults), FlagResultNodes(nodes, nodes+NumNodes) {}
|
||||
MarkFlagResultsMatcher(const unsigned *nodes, unsigned NumNodes)
|
||||
: Matcher(MarkFlagResults), FlagResultNodes(nodes, nodes+NumNodes) {}
|
||||
|
||||
unsigned getNumNodes() const { return FlagResultNodes.size(); }
|
||||
|
||||
|
@ -689,30 +686,30 @@ public:
|
|||
return FlagResultNodes[i];
|
||||
}
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == MarkFlagResults;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||
};
|
||||
|
||||
/// CompleteMatchMatcherNode - Complete a match by replacing the results of the
|
||||
/// CompleteMatchMatcher - Complete a match by replacing the results of the
|
||||
/// pattern with the newly generated nodes. This also prints a comment
|
||||
/// indicating the source and dest patterns.
|
||||
class CompleteMatchMatcherNode : public MatcherNode {
|
||||
class CompleteMatchMatcher : public Matcher {
|
||||
SmallVector<unsigned, 2> Results;
|
||||
const PatternToMatch &Pattern;
|
||||
public:
|
||||
CompleteMatchMatcherNode(const unsigned *results, unsigned numresults,
|
||||
CompleteMatchMatcher(const unsigned *results, unsigned numresults,
|
||||
const PatternToMatch &pattern)
|
||||
: MatcherNode(CompleteMatch), Results(results, results+numresults),
|
||||
: Matcher(CompleteMatch), Results(results, results+numresults),
|
||||
Pattern(pattern) {}
|
||||
|
||||
unsigned getNumResults() const { return Results.size(); }
|
||||
unsigned getResult(unsigned R) const { return Results[R]; }
|
||||
const PatternToMatch &getPattern() const { return Pattern; }
|
||||
|
||||
static inline bool classof(const MatcherNode *N) {
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CompleteMatch;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,14 +81,14 @@ class MatcherTableEmitter {
|
|||
public:
|
||||
MatcherTableEmitter() {}
|
||||
|
||||
unsigned EmitMatcherList(const MatcherNode *N, unsigned Indent,
|
||||
unsigned EmitMatcherList(const Matcher *N, unsigned Indent,
|
||||
unsigned StartIdx, formatted_raw_ostream &OS);
|
||||
|
||||
void EmitPredicateFunctions(formatted_raw_ostream &OS);
|
||||
|
||||
void EmitHistogram(formatted_raw_ostream &OS);
|
||||
private:
|
||||
unsigned EmitMatcher(const MatcherNode *N, unsigned Indent,
|
||||
unsigned EmitMatcher(const Matcher *N, unsigned Indent,
|
||||
formatted_raw_ostream &OS);
|
||||
|
||||
unsigned getNodePredicate(StringRef PredName) {
|
||||
|
@ -151,66 +151,65 @@ static unsigned EmitVBRValue(unsigned Val, raw_ostream &OS) {
|
|||
/// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
|
||||
/// the number of bytes emitted.
|
||||
unsigned MatcherTableEmitter::
|
||||
EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) {
|
||||
EmitMatcher(const Matcher *N, unsigned Indent, formatted_raw_ostream &OS) {
|
||||
OS.PadToColumn(Indent*2);
|
||||
|
||||
switch (N->getKind()) {
|
||||
case MatcherNode::Scope: assert(0 && "Should be handled by caller");
|
||||
case MatcherNode::RecordNode:
|
||||
case Matcher::Scope: assert(0 && "Should be handled by caller");
|
||||
case Matcher::RecordNode:
|
||||
OS << "OPC_RecordNode,";
|
||||
OS.PadToColumn(CommentIndent) << "// "
|
||||
<< cast<RecordMatcherNode>(N)->getWhatFor() << '\n';
|
||||
<< cast<RecordMatcher>(N)->getWhatFor() << '\n';
|
||||
return 1;
|
||||
|
||||
case MatcherNode::RecordChild:
|
||||
OS << "OPC_RecordChild" << cast<RecordChildMatcherNode>(N)->getChildNo()
|
||||
case Matcher::RecordChild:
|
||||
OS << "OPC_RecordChild" << cast<RecordChildMatcher>(N)->getChildNo()
|
||||
<< ',';
|
||||
OS.PadToColumn(CommentIndent) << "// "
|
||||
<< cast<RecordChildMatcherNode>(N)->getWhatFor() << '\n';
|
||||
<< cast<RecordChildMatcher>(N)->getWhatFor() << '\n';
|
||||
return 1;
|
||||
|
||||
case MatcherNode::RecordMemRef:
|
||||
case Matcher::RecordMemRef:
|
||||
OS << "OPC_RecordMemRef,\n";
|
||||
return 1;
|
||||
|
||||
case MatcherNode::CaptureFlagInput:
|
||||
case Matcher::CaptureFlagInput:
|
||||
OS << "OPC_CaptureFlagInput,\n";
|
||||
return 1;
|
||||
|
||||
case MatcherNode::MoveChild:
|
||||
OS << "OPC_MoveChild, "
|
||||
<< cast<MoveChildMatcherNode>(N)->getChildNo() << ",\n";
|
||||
case Matcher::MoveChild:
|
||||
OS << "OPC_MoveChild, " << cast<MoveChildMatcher>(N)->getChildNo() << ",\n";
|
||||
return 2;
|
||||
|
||||
case MatcherNode::MoveParent:
|
||||
case Matcher::MoveParent:
|
||||
OS << "OPC_MoveParent,\n";
|
||||
return 1;
|
||||
|
||||
case MatcherNode::CheckSame:
|
||||
case Matcher::CheckSame:
|
||||
OS << "OPC_CheckSame, "
|
||||
<< cast<CheckSameMatcherNode>(N)->getMatchNumber() << ",\n";
|
||||
<< cast<CheckSameMatcher>(N)->getMatchNumber() << ",\n";
|
||||
return 2;
|
||||
|
||||
case MatcherNode::CheckPatternPredicate: {
|
||||
StringRef Pred = cast<CheckPatternPredicateMatcherNode>(N)->getPredicate();
|
||||
case Matcher::CheckPatternPredicate: {
|
||||
StringRef Pred = cast<CheckPatternPredicateMatcher>(N)->getPredicate();
|
||||
OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
|
||||
OS.PadToColumn(CommentIndent) << "// " << Pred << '\n';
|
||||
return 2;
|
||||
}
|
||||
case MatcherNode::CheckPredicate: {
|
||||
StringRef Pred = cast<CheckPredicateMatcherNode>(N)->getPredicateName();
|
||||
case Matcher::CheckPredicate: {
|
||||
StringRef Pred = cast<CheckPredicateMatcher>(N)->getPredicateName();
|
||||
OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
|
||||
OS.PadToColumn(CommentIndent) << "// " << Pred << '\n';
|
||||
return 2;
|
||||
}
|
||||
|
||||
case MatcherNode::CheckOpcode:
|
||||
case Matcher::CheckOpcode:
|
||||
OS << "OPC_CheckOpcode, "
|
||||
<< cast<CheckOpcodeMatcherNode>(N)->getOpcodeName() << ",\n";
|
||||
<< cast<CheckOpcodeMatcher>(N)->getOpcodeName() << ",\n";
|
||||
return 2;
|
||||
|
||||
case MatcherNode::CheckMultiOpcode: {
|
||||
const CheckMultiOpcodeMatcherNode *CMO=cast<CheckMultiOpcodeMatcherNode>(N);
|
||||
case Matcher::CheckMultiOpcode: {
|
||||
const CheckMultiOpcodeMatcher *CMO = cast<CheckMultiOpcodeMatcher>(N);
|
||||
OS << "OPC_CheckMultiOpcode, " << CMO->getNumOpcodeNames() << ", ";
|
||||
for (unsigned i = 0, e = CMO->getNumOpcodeNames(); i != e; ++i)
|
||||
OS << CMO->getOpcodeName(i) << ", ";
|
||||
|
@ -218,34 +217,34 @@ EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) {
|
|||
return 2 + CMO->getNumOpcodeNames();
|
||||
}
|
||||
|
||||
case MatcherNode::CheckType:
|
||||
case Matcher::CheckType:
|
||||
OS << "OPC_CheckType, "
|
||||
<< getEnumName(cast<CheckTypeMatcherNode>(N)->getType()) << ",\n";
|
||||
<< getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
|
||||
return 2;
|
||||
case MatcherNode::CheckChildType:
|
||||
case Matcher::CheckChildType:
|
||||
OS << "OPC_CheckChild"
|
||||
<< cast<CheckChildTypeMatcherNode>(N)->getChildNo() << "Type, "
|
||||
<< getEnumName(cast<CheckChildTypeMatcherNode>(N)->getType()) << ",\n";
|
||||
<< cast<CheckChildTypeMatcher>(N)->getChildNo() << "Type, "
|
||||
<< getEnumName(cast<CheckChildTypeMatcher>(N)->getType()) << ",\n";
|
||||
return 2;
|
||||
|
||||
case MatcherNode::CheckInteger: {
|
||||
int64_t Val = cast<CheckIntegerMatcherNode>(N)->getValue();
|
||||
case Matcher::CheckInteger: {
|
||||
int64_t Val = cast<CheckIntegerMatcher>(N)->getValue();
|
||||
OS << "OPC_CheckInteger" << ClassifyInt(Val) << ", ";
|
||||
return EmitInt(Val, OS)+1;
|
||||
}
|
||||
case MatcherNode::CheckCondCode:
|
||||
case Matcher::CheckCondCode:
|
||||
OS << "OPC_CheckCondCode, ISD::"
|
||||
<< cast<CheckCondCodeMatcherNode>(N)->getCondCodeName() << ",\n";
|
||||
<< cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";
|
||||
return 2;
|
||||
|
||||
case MatcherNode::CheckValueType:
|
||||
case Matcher::CheckValueType:
|
||||
OS << "OPC_CheckValueType, MVT::"
|
||||
<< cast<CheckValueTypeMatcherNode>(N)->getTypeName() << ",\n";
|
||||
<< cast<CheckValueTypeMatcher>(N)->getTypeName() << ",\n";
|
||||
return 2;
|
||||
|
||||
case MatcherNode::CheckComplexPat: {
|
||||
case Matcher::CheckComplexPat: {
|
||||
const ComplexPattern &Pattern =
|
||||
cast<CheckComplexPatMatcherNode>(N)->getPattern();
|
||||
cast<CheckComplexPatMatcher>(N)->getPattern();
|
||||
OS << "OPC_CheckComplexPat, " << getComplexPat(Pattern) << ',';
|
||||
OS.PadToColumn(CommentIndent) << "// " << Pattern.getSelectFunc();
|
||||
OS << ": " << Pattern.getNumOperands() << " operands";
|
||||
|
@ -255,79 +254,79 @@ EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
case MatcherNode::CheckAndImm: {
|
||||
int64_t Val = cast<CheckAndImmMatcherNode>(N)->getValue();
|
||||
case Matcher::CheckAndImm: {
|
||||
int64_t Val = cast<CheckAndImmMatcher>(N)->getValue();
|
||||
OS << "OPC_CheckAndImm" << ClassifyInt(Val) << ", ";
|
||||
return EmitInt(Val, OS)+1;
|
||||
}
|
||||
|
||||
case MatcherNode::CheckOrImm: {
|
||||
int64_t Val = cast<CheckOrImmMatcherNode>(N)->getValue();
|
||||
case Matcher::CheckOrImm: {
|
||||
int64_t Val = cast<CheckOrImmMatcher>(N)->getValue();
|
||||
OS << "OPC_CheckOrImm" << ClassifyInt(Val) << ", ";
|
||||
return EmitInt(Val, OS)+1;
|
||||
}
|
||||
case MatcherNode::CheckFoldableChainNode:
|
||||
case Matcher::CheckFoldableChainNode:
|
||||
OS << "OPC_CheckFoldableChainNode,\n";
|
||||
return 1;
|
||||
case MatcherNode::CheckChainCompatible:
|
||||
case Matcher::CheckChainCompatible:
|
||||
OS << "OPC_CheckChainCompatible, "
|
||||
<< cast<CheckChainCompatibleMatcherNode>(N)->getPreviousOp() << ",\n";
|
||||
<< cast<CheckChainCompatibleMatcher>(N)->getPreviousOp() << ",\n";
|
||||
return 2;
|
||||
|
||||
case MatcherNode::EmitInteger: {
|
||||
int64_t Val = cast<EmitIntegerMatcherNode>(N)->getValue();
|
||||
case Matcher::EmitInteger: {
|
||||
int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();
|
||||
OS << "OPC_EmitInteger" << ClassifyInt(Val) << ", "
|
||||
<< getEnumName(cast<EmitIntegerMatcherNode>(N)->getVT()) << ", ";
|
||||
<< getEnumName(cast<EmitIntegerMatcher>(N)->getVT()) << ", ";
|
||||
return EmitInt(Val, OS)+2;
|
||||
}
|
||||
case MatcherNode::EmitStringInteger: {
|
||||
const std::string &Val = cast<EmitStringIntegerMatcherNode>(N)->getValue();
|
||||
case Matcher::EmitStringInteger: {
|
||||
const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
|
||||
// These should always fit into one byte.
|
||||
OS << "OPC_EmitInteger1, "
|
||||
<< getEnumName(cast<EmitStringIntegerMatcherNode>(N)->getVT()) << ", "
|
||||
<< getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", "
|
||||
<< Val << ",\n";
|
||||
return 3;
|
||||
}
|
||||
|
||||
case MatcherNode::EmitRegister:
|
||||
case Matcher::EmitRegister:
|
||||
OS << "OPC_EmitRegister, "
|
||||
<< getEnumName(cast<EmitRegisterMatcherNode>(N)->getVT()) << ", ";
|
||||
if (Record *R = cast<EmitRegisterMatcherNode>(N)->getReg())
|
||||
<< getEnumName(cast<EmitRegisterMatcher>(N)->getVT()) << ", ";
|
||||
if (Record *R = cast<EmitRegisterMatcher>(N)->getReg())
|
||||
OS << getQualifiedName(R) << ",\n";
|
||||
else
|
||||
OS << "0 /*zero_reg*/,\n";
|
||||
return 3;
|
||||
|
||||
case MatcherNode::EmitConvertToTarget:
|
||||
case Matcher::EmitConvertToTarget:
|
||||
OS << "OPC_EmitConvertToTarget, "
|
||||
<< cast<EmitConvertToTargetMatcherNode>(N)->getSlot() << ",\n";
|
||||
<< cast<EmitConvertToTargetMatcher>(N)->getSlot() << ",\n";
|
||||
return 2;
|
||||
|
||||
case MatcherNode::EmitMergeInputChains: {
|
||||
const EmitMergeInputChainsMatcherNode *MN =
|
||||
cast<EmitMergeInputChainsMatcherNode>(N);
|
||||
case Matcher::EmitMergeInputChains: {
|
||||
const EmitMergeInputChainsMatcher *MN =
|
||||
cast<EmitMergeInputChainsMatcher>(N);
|
||||
OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", ";
|
||||
for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i)
|
||||
OS << MN->getNode(i) << ", ";
|
||||
OS << '\n';
|
||||
return 2+MN->getNumNodes();
|
||||
}
|
||||
case MatcherNode::EmitCopyToReg:
|
||||
case Matcher::EmitCopyToReg:
|
||||
OS << "OPC_EmitCopyToReg, "
|
||||
<< cast<EmitCopyToRegMatcherNode>(N)->getSrcSlot() << ", "
|
||||
<< getQualifiedName(cast<EmitCopyToRegMatcherNode>(N)->getDestPhysReg())
|
||||
<< cast<EmitCopyToRegMatcher>(N)->getSrcSlot() << ", "
|
||||
<< getQualifiedName(cast<EmitCopyToRegMatcher>(N)->getDestPhysReg())
|
||||
<< ",\n";
|
||||
return 3;
|
||||
case MatcherNode::EmitNodeXForm: {
|
||||
const EmitNodeXFormMatcherNode *XF = cast<EmitNodeXFormMatcherNode>(N);
|
||||
case Matcher::EmitNodeXForm: {
|
||||
const EmitNodeXFormMatcher *XF = cast<EmitNodeXFormMatcher>(N);
|
||||
OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", "
|
||||
<< XF->getSlot() << ',';
|
||||
OS.PadToColumn(CommentIndent) << "// "<<XF->getNodeXForm()->getName()<<'\n';
|
||||
return 3;
|
||||
}
|
||||
|
||||
case MatcherNode::EmitNode: {
|
||||
const EmitNodeMatcherNode *EN = cast<EmitNodeMatcherNode>(N);
|
||||
case Matcher::EmitNode: {
|
||||
const EmitNodeMatcher *EN = cast<EmitNodeMatcher>(N);
|
||||
OS << "OPC_EmitNode, TARGET_OPCODE(" << EN->getOpcodeName() << "), 0";
|
||||
|
||||
if (EN->hasChain()) OS << "|OPFL_Chain";
|
||||
|
@ -351,8 +350,8 @@ EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) {
|
|||
OS << '\n';
|
||||
return 6+EN->getNumVTs()+NumOperandBytes;
|
||||
}
|
||||
case MatcherNode::MarkFlagResults: {
|
||||
const MarkFlagResultsMatcherNode *CFR = cast<MarkFlagResultsMatcherNode>(N);
|
||||
case Matcher::MarkFlagResults: {
|
||||
const MarkFlagResultsMatcher *CFR = cast<MarkFlagResultsMatcher>(N);
|
||||
OS << "OPC_MarkFlagResults, " << CFR->getNumNodes() << ", ";
|
||||
unsigned NumOperandBytes = 0;
|
||||
for (unsigned i = 0, e = CFR->getNumNodes(); i != e; ++i)
|
||||
|
@ -360,8 +359,8 @@ EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) {
|
|||
OS << '\n';
|
||||
return 2+NumOperandBytes;
|
||||
}
|
||||
case MatcherNode::CompleteMatch: {
|
||||
const CompleteMatchMatcherNode *CM = cast<CompleteMatchMatcherNode>(N);
|
||||
case Matcher::CompleteMatch: {
|
||||
const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N);
|
||||
OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
|
||||
unsigned NumResultBytes = 0;
|
||||
for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
|
||||
|
@ -380,7 +379,7 @@ EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) {
|
|||
|
||||
/// EmitMatcherList - Emit the bytes for the specified matcher subtree.
|
||||
unsigned MatcherTableEmitter::
|
||||
EmitMatcherList(const MatcherNode *N, unsigned Indent, unsigned CurrentIdx,
|
||||
EmitMatcherList(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
||||
formatted_raw_ostream &OS) {
|
||||
unsigned Size = 0;
|
||||
while (N) {
|
||||
|
@ -389,7 +388,7 @@ EmitMatcherList(const MatcherNode *N, unsigned Indent, unsigned CurrentIdx,
|
|||
Histogram[N->getKind()]++;
|
||||
|
||||
// Scope is a special case since it is binary.
|
||||
if (const ScopeMatcherNode *SMN = dyn_cast<ScopeMatcherNode>(N)) {
|
||||
if (const ScopeMatcher *SMN = dyn_cast<ScopeMatcher>(N)) {
|
||||
// We need to encode the child and the offset of the failure code before
|
||||
// emitting either of them. Handle this by buffering the output into a
|
||||
// string while we get the size.
|
||||
|
@ -398,7 +397,7 @@ EmitMatcherList(const MatcherNode *N, unsigned Indent, unsigned CurrentIdx,
|
|||
{
|
||||
raw_svector_ostream OS(TmpBuf);
|
||||
formatted_raw_ostream FOS(OS);
|
||||
NextSize = EmitMatcherList(cast<ScopeMatcherNode>(N)->getCheck(),
|
||||
NextSize = EmitMatcherList(cast<ScopeMatcher>(N)->getCheck(),
|
||||
Indent+1, CurrentIdx+2, FOS);
|
||||
}
|
||||
|
||||
|
@ -408,7 +407,7 @@ EmitMatcherList(const MatcherNode *N, unsigned Indent, unsigned CurrentIdx,
|
|||
TmpBuf.clear();
|
||||
raw_svector_ostream OS(TmpBuf);
|
||||
formatted_raw_ostream FOS(OS);
|
||||
NextSize = EmitMatcherList(cast<ScopeMatcherNode>(N)->getCheck(),
|
||||
NextSize = EmitMatcherList(cast<ScopeMatcher>(N)->getCheck(),
|
||||
Indent+1, CurrentIdx+3, FOS);
|
||||
if (NextSize > 65535) {
|
||||
errs() <<
|
||||
|
@ -513,44 +512,44 @@ void MatcherTableEmitter::EmitHistogram(formatted_raw_ostream &OS) {
|
|||
OS << " // Opcode Histogram:\n";
|
||||
for (unsigned i = 0, e = Histogram.size(); i != e; ++i) {
|
||||
OS << " // #";
|
||||
switch ((MatcherNode::KindTy)i) {
|
||||
case MatcherNode::Scope: OS << "OPC_Scope"; break;
|
||||
case MatcherNode::RecordNode: OS << "OPC_RecordNode"; break;
|
||||
case MatcherNode::RecordChild: OS << "OPC_RecordChild"; break;
|
||||
case MatcherNode::RecordMemRef: OS << "OPC_RecordMemRef"; break;
|
||||
case MatcherNode::CaptureFlagInput: OS << "OPC_CaptureFlagInput"; break;
|
||||
case MatcherNode::MoveChild: OS << "OPC_MoveChild"; break;
|
||||
case MatcherNode::MoveParent: OS << "OPC_MoveParent"; break;
|
||||
case MatcherNode::CheckSame: OS << "OPC_CheckSame"; break;
|
||||
case MatcherNode::CheckPatternPredicate:
|
||||
switch ((Matcher::KindTy)i) {
|
||||
case Matcher::Scope: OS << "OPC_Scope"; break;
|
||||
case Matcher::RecordNode: OS << "OPC_RecordNode"; break;
|
||||
case Matcher::RecordChild: OS << "OPC_RecordChild"; break;
|
||||
case Matcher::RecordMemRef: OS << "OPC_RecordMemRef"; break;
|
||||
case Matcher::CaptureFlagInput: OS << "OPC_CaptureFlagInput"; break;
|
||||
case Matcher::MoveChild: OS << "OPC_MoveChild"; break;
|
||||
case Matcher::MoveParent: OS << "OPC_MoveParent"; break;
|
||||
case Matcher::CheckSame: OS << "OPC_CheckSame"; break;
|
||||
case Matcher::CheckPatternPredicate:
|
||||
OS << "OPC_CheckPatternPredicate"; break;
|
||||
case MatcherNode::CheckPredicate: OS << "OPC_CheckPredicate"; break;
|
||||
case MatcherNode::CheckOpcode: OS << "OPC_CheckOpcode"; break;
|
||||
case MatcherNode::CheckMultiOpcode: OS << "OPC_CheckMultiOpcode"; break;
|
||||
case MatcherNode::CheckType: OS << "OPC_CheckType"; break;
|
||||
case MatcherNode::CheckChildType: OS << "OPC_CheckChildType"; break;
|
||||
case MatcherNode::CheckInteger: OS << "OPC_CheckInteger"; break;
|
||||
case MatcherNode::CheckCondCode: OS << "OPC_CheckCondCode"; break;
|
||||
case MatcherNode::CheckValueType: OS << "OPC_CheckValueType"; break;
|
||||
case MatcherNode::CheckComplexPat: OS << "OPC_CheckComplexPat"; break;
|
||||
case MatcherNode::CheckAndImm: OS << "OPC_CheckAndImm"; break;
|
||||
case MatcherNode::CheckOrImm: OS << "OPC_CheckOrImm"; break;
|
||||
case MatcherNode::CheckFoldableChainNode:
|
||||
case Matcher::CheckPredicate: OS << "OPC_CheckPredicate"; break;
|
||||
case Matcher::CheckOpcode: OS << "OPC_CheckOpcode"; break;
|
||||
case Matcher::CheckMultiOpcode: OS << "OPC_CheckMultiOpcode"; break;
|
||||
case Matcher::CheckType: OS << "OPC_CheckType"; break;
|
||||
case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
|
||||
case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
|
||||
case Matcher::CheckCondCode: OS << "OPC_CheckCondCode"; break;
|
||||
case Matcher::CheckValueType: OS << "OPC_CheckValueType"; break;
|
||||
case Matcher::CheckComplexPat: OS << "OPC_CheckComplexPat"; break;
|
||||
case Matcher::CheckAndImm: OS << "OPC_CheckAndImm"; break;
|
||||
case Matcher::CheckOrImm: OS << "OPC_CheckOrImm"; break;
|
||||
case Matcher::CheckFoldableChainNode:
|
||||
OS << "OPC_CheckFoldableChainNode"; break;
|
||||
case MatcherNode::CheckChainCompatible:
|
||||
case Matcher::CheckChainCompatible:
|
||||
OS << "OPC_CheckChainCompatible"; break;
|
||||
case MatcherNode::EmitInteger: OS << "OPC_EmitInteger"; break;
|
||||
case MatcherNode::EmitStringInteger: OS << "OPC_EmitStringInteger"; break;
|
||||
case MatcherNode::EmitRegister: OS << "OPC_EmitRegister"; break;
|
||||
case MatcherNode::EmitConvertToTarget:
|
||||
case Matcher::EmitInteger: OS << "OPC_EmitInteger"; break;
|
||||
case Matcher::EmitStringInteger: OS << "OPC_EmitStringInteger"; break;
|
||||
case Matcher::EmitRegister: OS << "OPC_EmitRegister"; break;
|
||||
case Matcher::EmitConvertToTarget:
|
||||
OS << "OPC_EmitConvertToTarget"; break;
|
||||
case MatcherNode::EmitMergeInputChains:
|
||||
case Matcher::EmitMergeInputChains:
|
||||
OS << "OPC_EmitMergeInputChains"; break;
|
||||
case MatcherNode::EmitCopyToReg: OS << "OPC_EmitCopyToReg"; break;
|
||||
case MatcherNode::EmitNode: OS << "OPC_EmitNode"; break;
|
||||
case MatcherNode::EmitNodeXForm: OS << "OPC_EmitNodeXForm"; break;
|
||||
case MatcherNode::MarkFlagResults: OS << "OPC_MarkFlagResults"; break;
|
||||
case MatcherNode::CompleteMatch: OS << "OPC_CompleteMatch"; break;
|
||||
case Matcher::EmitCopyToReg: OS << "OPC_EmitCopyToReg"; break;
|
||||
case Matcher::EmitNode: OS << "OPC_EmitNode"; break;
|
||||
case Matcher::EmitNodeXForm: OS << "OPC_EmitNodeXForm"; break;
|
||||
case Matcher::MarkFlagResults: OS << "OPC_MarkFlagResults"; break;
|
||||
case Matcher::CompleteMatch: OS << "OPC_CompleteMatch"; break;
|
||||
}
|
||||
|
||||
OS.PadToColumn(40) << " = " << Histogram[i] << '\n';
|
||||
|
@ -559,7 +558,7 @@ void MatcherTableEmitter::EmitHistogram(formatted_raw_ostream &OS) {
|
|||
}
|
||||
|
||||
|
||||
void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) {
|
||||
void llvm::EmitMatcherTable(const Matcher *TheMatcher, raw_ostream &O) {
|
||||
formatted_raw_ostream OS(O);
|
||||
|
||||
OS << "// The main instruction selector code.\n";
|
||||
|
@ -570,7 +569,7 @@ void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) {
|
|||
OS << " // Opcodes are emitted as 2 bytes, TARGET_OPCODE handles this.\n";
|
||||
OS << " #define TARGET_OPCODE(X) X & 255, unsigned(X) >> 8\n";
|
||||
OS << " static const unsigned char MatcherTable[] = {\n";
|
||||
unsigned TotalSize = MatcherEmitter.EmitMatcherList(Matcher, 5, 0, OS);
|
||||
unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 5, 0, OS);
|
||||
OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
|
||||
|
||||
MatcherEmitter.EmitHistogram(OS);
|
||||
|
|
|
@ -85,11 +85,11 @@ namespace {
|
|||
bool EmittedMergeInputChains;
|
||||
|
||||
/// Matcher - This is the top level of the generated matcher, the result.
|
||||
MatcherNode *Matcher;
|
||||
Matcher *TheMatcher;
|
||||
|
||||
/// CurPredicate - As we emit matcher nodes, this points to the latest check
|
||||
/// which should have future checks stuck into its Next position.
|
||||
MatcherNode *CurPredicate;
|
||||
Matcher *CurPredicate;
|
||||
public:
|
||||
MatcherGen(const PatternToMatch &pattern, const CodeGenDAGPatterns &cgp);
|
||||
|
||||
|
@ -100,10 +100,10 @@ namespace {
|
|||
void EmitMatcherCode();
|
||||
void EmitResultCode();
|
||||
|
||||
MatcherNode *GetMatcher() const { return Matcher; }
|
||||
MatcherNode *GetCurPredicate() const { return CurPredicate; }
|
||||
Matcher *GetMatcher() const { return TheMatcher; }
|
||||
Matcher *GetCurPredicate() const { return CurPredicate; }
|
||||
private:
|
||||
void AddMatcherNode(MatcherNode *NewNode);
|
||||
void AddMatcher(Matcher *NewNode);
|
||||
void InferPossibleTypes();
|
||||
|
||||
// Matcher Generation.
|
||||
|
@ -141,7 +141,7 @@ namespace {
|
|||
MatcherGen::MatcherGen(const PatternToMatch &pattern,
|
||||
const CodeGenDAGPatterns &cgp)
|
||||
: Pattern(pattern), CGP(cgp), NextRecordedOperandNo(0),
|
||||
EmittedMergeInputChains(false), Matcher(0), CurPredicate(0) {
|
||||
EmittedMergeInputChains(false), TheMatcher(0), CurPredicate(0) {
|
||||
// We need to produce the matcher tree for the patterns source pattern. To do
|
||||
// this we need to match the structure as well as the types. To do the type
|
||||
// matching, we want to figure out the fewest number of type checks we need to
|
||||
|
@ -182,12 +182,12 @@ void MatcherGen::InferPossibleTypes() {
|
|||
}
|
||||
|
||||
|
||||
/// AddMatcherNode - Add a matcher node to the current graph we're building.
|
||||
void MatcherGen::AddMatcherNode(MatcherNode *NewNode) {
|
||||
/// AddMatcher - Add a matcher node to the current graph we're building.
|
||||
void MatcherGen::AddMatcher(Matcher *NewNode) {
|
||||
if (CurPredicate != 0)
|
||||
CurPredicate->setNext(NewNode);
|
||||
else
|
||||
Matcher = NewNode;
|
||||
TheMatcher = NewNode;
|
||||
CurPredicate = NewNode;
|
||||
}
|
||||
|
||||
|
@ -202,11 +202,11 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
|
|||
|
||||
// If there are node predicates for this node, generate their checks.
|
||||
for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
|
||||
AddMatcherNode(new CheckPredicateMatcherNode(N->getPredicateFns()[i]));
|
||||
AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i]));
|
||||
|
||||
// Direct match against an integer constant.
|
||||
if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue()))
|
||||
return AddMatcherNode(new CheckIntegerMatcherNode(II->getValue()));
|
||||
return AddMatcher(new CheckIntegerMatcher(II->getValue()));
|
||||
|
||||
DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue());
|
||||
if (DI == 0) {
|
||||
|
@ -225,16 +225,16 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
|
|||
// If we have a physreg reference like (mul gpr:$src, EAX) then we need to
|
||||
// record the register
|
||||
if (LeafRec->isSubClassOf("Register")) {
|
||||
AddMatcherNode(new RecordMatcherNode("physreg input "+LeafRec->getName()));
|
||||
AddMatcher(new RecordMatcher("physreg input "+LeafRec->getName()));
|
||||
PhysRegInputs.push_back(std::make_pair(LeafRec, NextRecordedOperandNo++));
|
||||
return;
|
||||
}
|
||||
|
||||
if (LeafRec->isSubClassOf("ValueType"))
|
||||
return AddMatcherNode(new CheckValueTypeMatcherNode(LeafRec->getName()));
|
||||
return AddMatcher(new CheckValueTypeMatcher(LeafRec->getName()));
|
||||
|
||||
if (LeafRec->isSubClassOf("CondCode"))
|
||||
return AddMatcherNode(new CheckCondCodeMatcherNode(LeafRec->getName()));
|
||||
return AddMatcher(new CheckCondCodeMatcher(LeafRec->getName()));
|
||||
|
||||
if (LeafRec->isSubClassOf("ComplexPattern")) {
|
||||
// We can't model ComplexPattern uses that don't have their name taken yet.
|
||||
|
@ -253,19 +253,19 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
|
|||
const std::vector<Record*> &OpNodes = CP.getRootNodes();
|
||||
if (OpNodes.size() == 1) {
|
||||
StringRef OpName = CGP.getSDNodeInfo(OpNodes[0]).getEnumName();
|
||||
AddMatcherNode(new CheckOpcodeMatcherNode(OpName));
|
||||
AddMatcher(new CheckOpcodeMatcher(OpName));
|
||||
} else if (!OpNodes.empty()) {
|
||||
SmallVector<StringRef, 4> OpNames;
|
||||
for (unsigned i = 0, e = OpNodes.size(); i != e; i++)
|
||||
OpNames.push_back(CGP.getSDNodeInfo(OpNodes[i]).getEnumName());
|
||||
AddMatcherNode(new CheckMultiOpcodeMatcherNode(OpNames.data(),
|
||||
AddMatcher(new CheckMultiOpcodeMatcher(OpNames.data(),
|
||||
OpNames.size()));
|
||||
}
|
||||
}
|
||||
|
||||
// Emit a CheckComplexPat operation, which does the match (aborting if it
|
||||
// fails) and pushes the matched operands onto the recorded nodes list.
|
||||
AddMatcherNode(new CheckComplexPatMatcherNode(CP));
|
||||
AddMatcher(new CheckComplexPatMatcher(CP));
|
||||
|
||||
// Record the right number of operands.
|
||||
NextRecordedOperandNo += CP.getNumOperands();
|
||||
|
@ -288,7 +288,7 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
|
|||
// but we want to produce the same selections that the old matcher does
|
||||
// for now.
|
||||
unsigned PrevOp = MatchedChainNodes[MatchedChainNodes.size()-2];
|
||||
AddMatcherNode(new CheckChainCompatibleMatcherNode(PrevOp));
|
||||
AddMatcher(new CheckChainCompatibleMatcher(PrevOp));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,38 +323,38 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
|
|||
if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
|
||||
if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits.
|
||||
if (N->getOperator()->getName() == "and")
|
||||
AddMatcherNode(new CheckAndImmMatcherNode(II->getValue()));
|
||||
AddMatcher(new CheckAndImmMatcher(II->getValue()));
|
||||
else
|
||||
AddMatcherNode(new CheckOrImmMatcherNode(II->getValue()));
|
||||
AddMatcher(new CheckOrImmMatcher(II->getValue()));
|
||||
|
||||
// Match the LHS of the AND as appropriate.
|
||||
AddMatcherNode(new MoveChildMatcherNode(0));
|
||||
AddMatcher(new MoveChildMatcher(0));
|
||||
EmitMatchCode(N->getChild(0), NodeNoTypes->getChild(0));
|
||||
AddMatcherNode(new MoveParentMatcherNode());
|
||||
AddMatcher(new MoveParentMatcher());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the current opcode lines up.
|
||||
AddMatcherNode(new CheckOpcodeMatcherNode(CInfo.getEnumName()));
|
||||
AddMatcher(new CheckOpcodeMatcher(CInfo.getEnumName()));
|
||||
|
||||
// If there are node predicates for this node, generate their checks.
|
||||
for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
|
||||
AddMatcherNode(new CheckPredicateMatcherNode(N->getPredicateFns()[i]));
|
||||
AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i]));
|
||||
|
||||
|
||||
// If this node has memory references (i.e. is a load or store), tell the
|
||||
// interpreter to capture them in the memref array.
|
||||
if (N->NodeHasProperty(SDNPMemOperand, CGP))
|
||||
AddMatcherNode(new RecordMemRefMatcherNode());
|
||||
AddMatcher(new RecordMemRefMatcher());
|
||||
|
||||
// If this node has a chain, then the chain is operand #0 is the SDNode, and
|
||||
// the child numbers of the node are all offset by one.
|
||||
unsigned OpNo = 0;
|
||||
if (N->NodeHasProperty(SDNPHasChain, CGP)) {
|
||||
// Record the node and remember it in our chained nodes list.
|
||||
AddMatcherNode(new RecordMatcherNode("'" + N->getOperator()->getName() +
|
||||
AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() +
|
||||
"' chained node"));
|
||||
// Remember all of the input chains our pattern will match.
|
||||
MatchedChainNodes.push_back(NextRecordedOperandNo++);
|
||||
|
@ -369,7 +369,7 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
|
|||
// but we want to produce the same selections that the old matcher does
|
||||
// for now.
|
||||
unsigned PrevOp = MatchedChainNodes[MatchedChainNodes.size()-2];
|
||||
AddMatcherNode(new CheckChainCompatibleMatcherNode(PrevOp));
|
||||
AddMatcher(new CheckChainCompatibleMatcher(PrevOp));
|
||||
}
|
||||
|
||||
// Don't look at the input chain when matching the tree pattern to the
|
||||
|
@ -420,7 +420,7 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
|
|||
}
|
||||
|
||||
if (NeedCheck)
|
||||
AddMatcherNode(new CheckFoldableChainNodeMatcherNode());
|
||||
AddMatcher(new CheckFoldableChainNodeMatcher());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,7 +430,7 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
|
|||
// TODO: This redundantly records nodes with both flags and chains.
|
||||
|
||||
// Record the node and remember it in our chained nodes list.
|
||||
AddMatcherNode(new RecordMatcherNode("'" + N->getOperator()->getName() +
|
||||
AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() +
|
||||
"' flag output node"));
|
||||
// Remember all of the nodes with output flags our pattern will match.
|
||||
MatchedFlagResultNodes.push_back(NextRecordedOperandNo++);
|
||||
|
@ -440,14 +440,14 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
|
|||
// flag, capture it as the flag input of the pattern.
|
||||
if (N->NodeHasProperty(SDNPOptInFlag, CGP) ||
|
||||
N->NodeHasProperty(SDNPInFlag, CGP))
|
||||
AddMatcherNode(new CaptureFlagInputMatcherNode());
|
||||
AddMatcher(new CaptureFlagInputMatcher());
|
||||
|
||||
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
|
||||
// Get the code suitable for matching this child. Move to the child, check
|
||||
// it then move back to the parent.
|
||||
AddMatcherNode(new MoveChildMatcherNode(OpNo));
|
||||
AddMatcher(new MoveChildMatcher(OpNo));
|
||||
EmitMatchCode(N->getChild(i), NodeNoTypes->getChild(i));
|
||||
AddMatcherNode(new MoveParentMatcherNode());
|
||||
AddMatcher(new MoveParentMatcher());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N,
|
|||
// need to do a type check. Emit the check, apply the tyep to NodeNoTypes and
|
||||
// reinfer any correlated types.
|
||||
if (NodeNoTypes->getExtTypes() != N->getExtTypes()) {
|
||||
AddMatcherNode(new CheckTypeMatcherNode(N->getTypeNum(0)));
|
||||
AddMatcher(new CheckTypeMatcher(N->getTypeNum(0)));
|
||||
NodeNoTypes->setTypes(N->getExtTypes());
|
||||
InferPossibleTypes();
|
||||
}
|
||||
|
@ -470,13 +470,13 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N,
|
|||
if (VarMapEntry == 0) {
|
||||
// If it is a named node, we must emit a 'Record' opcode.
|
||||
VarMapEntry = ++NextRecordedOperandNo;
|
||||
AddMatcherNode(new RecordMatcherNode("$" + N->getName()));
|
||||
AddMatcher(new RecordMatcher("$" + N->getName()));
|
||||
} else {
|
||||
// If we get here, this is a second reference to a specific name. Since
|
||||
// we already have checked that the first reference is valid, we don't
|
||||
// have to recursively match it, just check that it's the same as the
|
||||
// previously named thing.
|
||||
AddMatcherNode(new CheckSameMatcherNode(VarMapEntry-1));
|
||||
AddMatcher(new CheckSameMatcher(VarMapEntry-1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -495,8 +495,8 @@ void MatcherGen::EmitMatcherCode() {
|
|||
// dag combine, eliminating the horrible side-effect-full stuff from
|
||||
// X86's MatchAddress.
|
||||
if (!Pattern.getPredicateCheck().empty())
|
||||
AddMatcherNode(new
|
||||
CheckPatternPredicateMatcherNode(Pattern.getPredicateCheck()));
|
||||
AddMatcher(new
|
||||
CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
|
||||
|
||||
// Emit the matcher for the pattern structure and types.
|
||||
EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes);
|
||||
|
@ -529,7 +529,7 @@ void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode *N,
|
|||
if (!N->isLeaf()) {
|
||||
StringRef OperatorName = N->getOperator()->getName();
|
||||
if (OperatorName == "imm" || OperatorName == "fpimm") {
|
||||
AddMatcherNode(new EmitConvertToTargetMatcherNode(SlotNo));
|
||||
AddMatcher(new EmitConvertToTargetMatcher(SlotNo));
|
||||
ResultOps.push_back(NextRecordedOperandNo++);
|
||||
return;
|
||||
}
|
||||
|
@ -543,7 +543,7 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
|
|||
assert(N->isLeaf() && "Must be a leaf");
|
||||
|
||||
if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
|
||||
AddMatcherNode(new EmitIntegerMatcherNode(II->getValue(),N->getTypeNum(0)));
|
||||
AddMatcher(new EmitIntegerMatcher(II->getValue(),N->getTypeNum(0)));
|
||||
ResultOps.push_back(NextRecordedOperandNo++);
|
||||
return;
|
||||
}
|
||||
|
@ -551,14 +551,14 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
|
|||
// If this is an explicit register reference, handle it.
|
||||
if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
|
||||
if (DI->getDef()->isSubClassOf("Register")) {
|
||||
AddMatcherNode(new EmitRegisterMatcherNode(DI->getDef(),
|
||||
AddMatcher(new EmitRegisterMatcher(DI->getDef(),
|
||||
N->getTypeNum(0)));
|
||||
ResultOps.push_back(NextRecordedOperandNo++);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DI->getDef()->getName() == "zero_reg") {
|
||||
AddMatcherNode(new EmitRegisterMatcherNode(0, N->getTypeNum(0)));
|
||||
AddMatcher(new EmitRegisterMatcher(0, N->getTypeNum(0)));
|
||||
ResultOps.push_back(NextRecordedOperandNo++);
|
||||
return;
|
||||
}
|
||||
|
@ -567,7 +567,7 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
|
|||
// in COPY_TO_SUBREG instructions.
|
||||
if (DI->getDef()->isSubClassOf("RegisterClass")) {
|
||||
std::string Value = getQualifiedName(DI->getDef()) + "RegClassID";
|
||||
AddMatcherNode(new EmitStringIntegerMatcherNode(Value, MVT::i32));
|
||||
AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
|
||||
ResultOps.push_back(NextRecordedOperandNo++);
|
||||
return;
|
||||
}
|
||||
|
@ -675,7 +675,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
|||
"How can this node have chain if no inputs do?");
|
||||
// Otherwise, we have to emit an operation to merge the input chains and
|
||||
// set this as the current input chain.
|
||||
AddMatcherNode(new EmitMergeInputChainsMatcherNode
|
||||
AddMatcher(new EmitMergeInputChainsMatcher
|
||||
(MatchedChainNodes.data(), MatchedChainNodes.size()));
|
||||
EmittedMergeInputChains = true;
|
||||
}
|
||||
|
@ -687,7 +687,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
|||
// Emit all of the CopyToReg nodes for the input physical registers. These
|
||||
// occur in patterns like (mul:i8 AL:i8, GR8:i8:$src).
|
||||
for (unsigned i = 0, e = PhysRegInputs.size(); i != e; ++i)
|
||||
AddMatcherNode(new EmitCopyToRegMatcherNode(PhysRegInputs[i].second,
|
||||
AddMatcher(new EmitCopyToRegMatcher(PhysRegInputs[i].second,
|
||||
PhysRegInputs[i].first));
|
||||
// Even if the node has no other flag inputs, the resultant node must be
|
||||
// flagged to the CopyFromReg nodes we just generated.
|
||||
|
@ -747,7 +747,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
|||
// superset of the results of the old node, in the same places. E.g. turning
|
||||
// (add (load)) -> add32rm is ok because result #0 is the result and result #1
|
||||
// is new.
|
||||
AddMatcherNode(new EmitNodeMatcherNode(II.Namespace+"::"+II.TheDef->getName(),
|
||||
AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(),
|
||||
ResultVTs.data(), ResultVTs.size(),
|
||||
InstOps.data(), InstOps.size(),
|
||||
NodeHasChain, TreeHasInFlag,
|
||||
|
@ -780,7 +780,7 @@ EmitResultSDNodeXFormAsOperand(const TreePatternNode *N,
|
|||
// The input currently must have produced exactly one result.
|
||||
assert(InputOps.size() == 1 && "Unexpected input to SDNodeXForm");
|
||||
|
||||
AddMatcherNode(new EmitNodeXFormMatcherNode(InputOps[0], N->getOperator()));
|
||||
AddMatcher(new EmitNodeXFormMatcher(InputOps[0], N->getOperator()));
|
||||
ResultOps.push_back(NextRecordedOperandNo++);
|
||||
}
|
||||
|
||||
|
@ -840,18 +840,18 @@ void MatcherGen::EmitResultCode() {
|
|||
// If the matched pattern covers nodes which define a flag result, emit a node
|
||||
// that tells the matcher about them so that it can update their results.
|
||||
if (!MatchedFlagResultNodes.empty())
|
||||
AddMatcherNode(new MarkFlagResultsMatcherNode(MatchedFlagResultNodes.data(),
|
||||
AddMatcher(new MarkFlagResultsMatcher(MatchedFlagResultNodes.data(),
|
||||
MatchedFlagResultNodes.size()));
|
||||
|
||||
|
||||
// We know that the resulting pattern has exactly one result/
|
||||
// FIXME2: why? what about something like (set a,b,c, (complexpat))
|
||||
// FIXME2: Implicit results should be pushed here I guess?
|
||||
AddMatcherNode(new CompleteMatchMatcherNode(Ops.data(), Ops.size(), Pattern));
|
||||
AddMatcher(new CompleteMatchMatcher(Ops.data(), Ops.size(), Pattern));
|
||||
}
|
||||
|
||||
|
||||
MatcherNode *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
|
||||
Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
|
||||
const CodeGenDAGPatterns &CGP) {
|
||||
MatcherGen Gen(Pattern, CGP);
|
||||
|
||||
|
|
|
@ -14,24 +14,24 @@
|
|||
#include "DAGISelMatcher.h"
|
||||
using namespace llvm;
|
||||
|
||||
static void ContractNodes(OwningPtr<MatcherNode> &MatcherPtr) {
|
||||
static void ContractNodes(OwningPtr<Matcher> &MatcherPtr) {
|
||||
// If we reached the end of the chain, we're done.
|
||||
MatcherNode *N = MatcherPtr.get();
|
||||
Matcher *N = MatcherPtr.get();
|
||||
if (N == 0) return;
|
||||
|
||||
// If we have a scope node, walk down both edges.
|
||||
if (ScopeMatcherNode *Push = dyn_cast<ScopeMatcherNode>(N))
|
||||
if (ScopeMatcher *Push = dyn_cast<ScopeMatcher>(N))
|
||||
ContractNodes(Push->getCheckPtr());
|
||||
|
||||
// If we found a movechild node with a node that comes in a 'foochild' form,
|
||||
// transform it.
|
||||
if (MoveChildMatcherNode *MC = dyn_cast<MoveChildMatcherNode>(N)) {
|
||||
MatcherNode *New = 0;
|
||||
if (RecordMatcherNode *RM = dyn_cast<RecordMatcherNode>(MC->getNext()))
|
||||
New = new RecordChildMatcherNode(MC->getChildNo(), RM->getWhatFor());
|
||||
if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N)) {
|
||||
Matcher *New = 0;
|
||||
if (RecordMatcher *RM = dyn_cast<RecordMatcher>(MC->getNext()))
|
||||
New = new RecordChildMatcher(MC->getChildNo(), RM->getWhatFor());
|
||||
|
||||
if (CheckTypeMatcherNode *CT= dyn_cast<CheckTypeMatcherNode>(MC->getNext()))
|
||||
New = new CheckChildTypeMatcherNode(MC->getChildNo(), CT->getType());
|
||||
if (CheckTypeMatcher *CT= dyn_cast<CheckTypeMatcher>(MC->getNext()))
|
||||
New = new CheckChildTypeMatcher(MC->getChildNo(), CT->getType());
|
||||
|
||||
if (New) {
|
||||
// Insert the new node.
|
||||
|
@ -43,9 +43,9 @@ static void ContractNodes(OwningPtr<MatcherNode> &MatcherPtr) {
|
|||
}
|
||||
}
|
||||
|
||||
if (MoveChildMatcherNode *MC = dyn_cast<MoveChildMatcherNode>(N))
|
||||
if (MoveParentMatcherNode *MP =
|
||||
dyn_cast<MoveParentMatcherNode>(MC->getNext())) {
|
||||
if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N))
|
||||
if (MoveParentMatcher *MP =
|
||||
dyn_cast<MoveParentMatcher>(MC->getNext())) {
|
||||
MatcherPtr.reset(MP->takeNext());
|
||||
return ContractNodes(MatcherPtr);
|
||||
}
|
||||
|
@ -53,21 +53,21 @@ static void ContractNodes(OwningPtr<MatcherNode> &MatcherPtr) {
|
|||
ContractNodes(N->getNextPtr());
|
||||
}
|
||||
|
||||
static void FactorNodes(OwningPtr<MatcherNode> &MatcherPtr) {
|
||||
static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
|
||||
// If we reached the end of the chain, we're done.
|
||||
MatcherNode *N = MatcherPtr.get();
|
||||
Matcher *N = MatcherPtr.get();
|
||||
if (N == 0) return;
|
||||
|
||||
// If this is not a push node, just scan for one.
|
||||
if (!isa<ScopeMatcherNode>(N))
|
||||
if (!isa<ScopeMatcher>(N))
|
||||
return FactorNodes(N->getNextPtr());
|
||||
|
||||
// Okay, pull together the series of linear push nodes into a vector so we can
|
||||
// inspect it more easily.
|
||||
SmallVector<MatcherNode*, 32> OptionsToMatch;
|
||||
SmallVector<Matcher*, 32> OptionsToMatch;
|
||||
|
||||
MatcherNode *CurNode = N;
|
||||
for (; ScopeMatcherNode *PMN = dyn_cast<ScopeMatcherNode>(CurNode);
|
||||
Matcher *CurNode = N;
|
||||
for (; ScopeMatcher *PMN = dyn_cast<ScopeMatcher>(CurNode);
|
||||
CurNode = PMN->getNext())
|
||||
OptionsToMatch.push_back(PMN->getCheck());
|
||||
OptionsToMatch.push_back(CurNode);
|
||||
|
@ -75,8 +75,8 @@ static void FactorNodes(OwningPtr<MatcherNode> &MatcherPtr) {
|
|||
|
||||
}
|
||||
|
||||
MatcherNode *llvm::OptimizeMatcher(MatcherNode *Matcher) {
|
||||
OwningPtr<MatcherNode> MatcherPtr(Matcher);
|
||||
Matcher *llvm::OptimizeMatcher(Matcher *TheMatcher) {
|
||||
OwningPtr<Matcher> MatcherPtr(TheMatcher);
|
||||
ContractNodes(MatcherPtr);
|
||||
FactorNodes(MatcherPtr);
|
||||
return MatcherPtr.take();
|
||||
|
|
Loading…
Reference in New Issue