mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
Rework our internal representation of node predicates to expose more
structure and fix some fixmes. We now have a TreePredicateFn class that handles all of the decoding of these things. This is an internal cleanup that has no impact on the code generated by tblgen. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129670 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
461cd70311
commit
543790673c
@ -490,6 +490,18 @@ class SDNodeXForm<SDNode opc, code xformFunction> {
|
||||
|
||||
def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PatPred Subclasses.
|
||||
//
|
||||
// These allow specifying different sorts of predicates that control whether a
|
||||
// node is matched.
|
||||
//
|
||||
class PatPred;
|
||||
|
||||
class CodePatPred<code predicate> : PatPred {
|
||||
code PredicateCode = predicate;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Selection DAG Pattern Fragments.
|
||||
@ -507,7 +519,7 @@ class PatFrag<dag ops, dag frag, code pred = [{}],
|
||||
SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator {
|
||||
dag Operands = ops;
|
||||
dag Fragment = frag;
|
||||
code Predicate = pred;
|
||||
code PredicateCode = pred;
|
||||
SDNodeXForm OperandTransform = xform;
|
||||
}
|
||||
|
||||
|
@ -459,7 +459,7 @@ def CallImmAddr : Predicate<"Subtarget->IsLegalToCallImmediateAddr(TM)">;
|
||||
include "X86InstrFormats.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pattern fragments...
|
||||
// Pattern fragments.
|
||||
//
|
||||
|
||||
// X86 specific condition code. These correspond to CondCode in
|
||||
|
@ -580,34 +580,29 @@ typedef std::map<std::string, int> DepVarMap;
|
||||
/// Const iterator shorthand for DepVarMap
|
||||
typedef DepVarMap::const_iterator DepVarMap_citer;
|
||||
|
||||
namespace {
|
||||
void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) {
|
||||
static void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) {
|
||||
if (N->isLeaf()) {
|
||||
if (dynamic_cast<DefInit*>(N->getLeafValue()) != NULL) {
|
||||
if (dynamic_cast<DefInit*>(N->getLeafValue()) != NULL)
|
||||
DepMap[N->getName()]++;
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0, e = N->getNumChildren(); i != e; ++i)
|
||||
FindDepVarsOf(N->getChild(i), DepMap);
|
||||
}
|
||||
}
|
||||
|
||||
//! Find dependent variables within child patterns
|
||||
/*!
|
||||
*/
|
||||
void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) {
|
||||
/// Find dependent variables within child patterns
|
||||
static void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) {
|
||||
DepVarMap depcounts;
|
||||
FindDepVarsOf(N, depcounts);
|
||||
for (DepVarMap_citer i = depcounts.begin(); i != depcounts.end(); ++i) {
|
||||
if (i->second > 1) { // std::pair<std::string, int>
|
||||
if (i->second > 1) // std::pair<std::string, int>
|
||||
DepVars.insert(i->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Dump the dependent variable set:
|
||||
#ifndef NDEBUG
|
||||
void DumpDepVars(MultipleUseVarSet &DepVars) {
|
||||
/// Dump the dependent variable set:
|
||||
static void DumpDepVars(MultipleUseVarSet &DepVars) {
|
||||
if (DepVars.empty()) {
|
||||
DEBUG(errs() << "<empty set>");
|
||||
} else {
|
||||
@ -621,6 +616,46 @@ void DumpDepVars(MultipleUseVarSet &DepVars) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TreePredicateFn Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
std::string TreePredicateFn::getPredCode() const {
|
||||
return PatFragRec->getRecord()->getValueAsCode("PredicateCode");
|
||||
}
|
||||
|
||||
|
||||
/// isAlwaysTrue - Return true if this is a noop predicate.
|
||||
bool TreePredicateFn::isAlwaysTrue() const {
|
||||
return getPredCode().empty();
|
||||
}
|
||||
|
||||
/// Return the name to use in the generated code to reference this, this is
|
||||
/// "Predicate_foo" if from a pattern fragment "foo".
|
||||
std::string TreePredicateFn::getFnName() const {
|
||||
return "Predicate_" + PatFragRec->getRecord()->getName();
|
||||
}
|
||||
|
||||
/// getCodeToRunOnSDNode - Return the code for the function body that
|
||||
/// evaluates this predicate. The argument is expected to be in "Node",
|
||||
/// not N. This handles casting and conversion to a concrete node type as
|
||||
/// appropriate.
|
||||
std::string TreePredicateFn::getCodeToRunOnSDNode() const {
|
||||
std::string ClassName;
|
||||
if (PatFragRec->getOnlyTree()->isLeaf())
|
||||
ClassName = "SDNode";
|
||||
else {
|
||||
Record *Op = PatFragRec->getOnlyTree()->getOperator();
|
||||
ClassName = PatFragRec->getDAGPatterns().getSDNodeInfo(Op).getSDClassName();
|
||||
}
|
||||
std::string Result;
|
||||
if (ClassName == "SDNode")
|
||||
Result = " SDNode *N = Node;\n";
|
||||
else
|
||||
Result = " " + ClassName + "*N = cast<" + ClassName + ">(Node);\n";
|
||||
|
||||
return Result + getPredCode();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1015,7 +1050,7 @@ void TreePatternNode::print(raw_ostream &OS) const {
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = PredicateFns.size(); i != e; ++i)
|
||||
OS << "<<P:" << PredicateFns[i] << ">>";
|
||||
OS << "<<P:" << PredicateFns[i].getFnName() << ">>";
|
||||
if (TransformFn)
|
||||
OS << "<<X:" << TransformFn->getName() << ">>";
|
||||
if (!getName().empty())
|
||||
@ -1150,9 +1185,9 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
|
||||
|
||||
TreePatternNode *FragTree = Frag->getOnlyTree()->clone();
|
||||
|
||||
std::string Code = Op->getValueAsCode("Predicate");
|
||||
if (!Code.empty())
|
||||
FragTree->addPredicateFn("Predicate_"+Op->getName());
|
||||
TreePredicateFn PredFn(Frag);
|
||||
if (!PredFn.isAlwaysTrue())
|
||||
FragTree->addPredicateFn(PredFn);
|
||||
|
||||
// Resolve formal arguments to their actual value.
|
||||
if (Frag->getNumArgs()) {
|
||||
@ -2063,9 +2098,9 @@ void CodeGenDAGPatterns::ParsePatternFragments() {
|
||||
|
||||
// If there is a code init for this fragment, keep track of the fact that
|
||||
// this fragment uses it.
|
||||
std::string Code = Fragments[i]->getValueAsCode("Predicate");
|
||||
if (!Code.empty())
|
||||
P->getOnlyTree()->addPredicateFn("Predicate_"+Fragments[i]->getName());
|
||||
TreePredicateFn PredFn(P);
|
||||
if (!PredFn.isAlwaysTrue())
|
||||
P->getOnlyTree()->addPredicateFn(PredFn);
|
||||
|
||||
// If there is a node transformation corresponding to this, keep track of
|
||||
// it.
|
||||
|
@ -240,6 +240,45 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// TreePredicateFn - This is an abstraction that represents the predicates on
|
||||
/// a PatFrag node. This is a simple one-word wrapper around a pointer to
|
||||
/// provide nice accessors.
|
||||
class TreePredicateFn {
|
||||
/// PatFragRec - This is the TreePattern for the PatFrag that we
|
||||
/// originally came from.
|
||||
TreePattern *PatFragRec;
|
||||
public:
|
||||
/// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag.
|
||||
TreePredicateFn(TreePattern *N) : PatFragRec(N) {}
|
||||
|
||||
|
||||
TreePattern *getOrigPatFragRecord() const { return PatFragRec; }
|
||||
|
||||
/// isAlwaysTrue - Return true if this is a noop predicate.
|
||||
bool isAlwaysTrue() const;
|
||||
|
||||
|
||||
bool operator==(const TreePredicateFn &RHS) const {
|
||||
return PatFragRec == RHS.PatFragRec;
|
||||
}
|
||||
|
||||
bool operator!=(const TreePredicateFn &RHS) const { return !(*this == RHS); }
|
||||
|
||||
/// Return the name to use in the generated code to reference this, this is
|
||||
/// "Predicate_foo" if from a pattern fragment "foo".
|
||||
std::string getFnName() const;
|
||||
|
||||
/// getCodeToRunOnSDNode - Return the code for the function body that
|
||||
/// evaluates this predicate. The argument is expected to be in "Node",
|
||||
/// not N. This handles casting and conversion to a concrete node type as
|
||||
/// appropriate.
|
||||
std::string getCodeToRunOnSDNode() const;
|
||||
|
||||
private:
|
||||
std::string getPredCode() const;
|
||||
};
|
||||
|
||||
|
||||
/// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped
|
||||
/// patterns), and as such should be ref counted. We currently just leak all
|
||||
/// TreePatternNode objects!
|
||||
@ -263,7 +302,7 @@ class TreePatternNode {
|
||||
|
||||
/// PredicateFns - The predicate functions to execute on this node to check
|
||||
/// for a match. If this list is empty, no predicate is involved.
|
||||
std::vector<std::string> PredicateFns;
|
||||
std::vector<TreePredicateFn> PredicateFns;
|
||||
|
||||
/// TransformFn - The transformation function to execute on this node before
|
||||
/// it can be substituted into the resulting instruction on a pattern match.
|
||||
@ -323,14 +362,18 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::vector<std::string> &getPredicateFns() const {return PredicateFns;}
|
||||
bool hasAnyPredicate() const { return !PredicateFns.empty(); }
|
||||
|
||||
const std::vector<TreePredicateFn> &getPredicateFns() const {
|
||||
return PredicateFns;
|
||||
}
|
||||
void clearPredicateFns() { PredicateFns.clear(); }
|
||||
void setPredicateFns(const std::vector<std::string> &Fns) {
|
||||
void setPredicateFns(const std::vector<TreePredicateFn> &Fns) {
|
||||
assert(PredicateFns.empty() && "Overwriting non-empty predicate list!");
|
||||
PredicateFns = Fns;
|
||||
}
|
||||
void addPredicateFn(const std::string &Fn) {
|
||||
assert(!Fn.empty() && "Empty predicate string!");
|
||||
void addPredicateFn(const TreePredicateFn &Fn) {
|
||||
assert(!Fn.isAlwaysTrue() && "Empty predicate string!");
|
||||
if (std::find(PredicateFns.begin(), PredicateFns.end(), Fn) ==
|
||||
PredicateFns.end())
|
||||
PredicateFns.push_back(Fn);
|
||||
|
@ -83,6 +83,15 @@ ScopeMatcher::~ScopeMatcher() {
|
||||
}
|
||||
|
||||
|
||||
CheckPredicateMatcher::CheckPredicateMatcher(const TreePredicateFn &pred)
|
||||
: Matcher(CheckPredicate), Pred(pred.getOrigPatFragRecord()) {}
|
||||
|
||||
TreePredicateFn CheckPredicateMatcher::getPredicate() const {
|
||||
return TreePredicateFn(Pred);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// printImpl methods.
|
||||
|
||||
void ScopeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
||||
@ -129,7 +138,7 @@ printImpl(raw_ostream &OS, unsigned indent) const {
|
||||
}
|
||||
|
||||
void CheckPredicateMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
||||
OS.indent(indent) << "CheckPredicate " << PredName << '\n';
|
||||
OS.indent(indent) << "CheckPredicate " << getPredicate().getFnName() << '\n';
|
||||
}
|
||||
|
||||
void CheckOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const {
|
||||
@ -263,7 +272,7 @@ unsigned CheckPatternPredicateMatcher::getHashImpl() const {
|
||||
}
|
||||
|
||||
unsigned CheckPredicateMatcher::getHashImpl() const {
|
||||
return HashString(PredName);
|
||||
return HashString(getPredicate().getFnName());
|
||||
}
|
||||
|
||||
unsigned CheckOpcodeMatcher::getHashImpl() const {
|
||||
@ -301,7 +310,6 @@ bool CheckOpcodeMatcher::isEqualImpl(const Matcher *M) const {
|
||||
Opcode.getEnumName();
|
||||
}
|
||||
|
||||
|
||||
bool EmitNodeMatcherCommon::isEqualImpl(const Matcher *m) const {
|
||||
const EmitNodeMatcherCommon *M = cast<EmitNodeMatcherCommon>(m);
|
||||
return M->OpcodeName == OpcodeName && M->VTs == VTs &&
|
||||
|
@ -25,6 +25,8 @@ namespace llvm {
|
||||
class ComplexPattern;
|
||||
class Record;
|
||||
class SDNodeInfo;
|
||||
class TreePredicateFn;
|
||||
class TreePattern;
|
||||
|
||||
Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant,
|
||||
const CodeGenDAGPatterns &CGP);
|
||||
@ -419,12 +421,11 @@ private:
|
||||
/// CheckPredicateMatcher - This checks the target-specific predicate to
|
||||
/// see if the node is acceptable.
|
||||
class CheckPredicateMatcher : public Matcher {
|
||||
StringRef PredName;
|
||||
TreePattern *Pred;
|
||||
public:
|
||||
CheckPredicateMatcher(StringRef predname)
|
||||
: Matcher(CheckPredicate), PredName(predname) {}
|
||||
CheckPredicateMatcher(const TreePredicateFn &pred);
|
||||
|
||||
StringRef getPredicateName() const { return PredName; }
|
||||
TreePredicateFn getPredicate() const;
|
||||
|
||||
static inline bool classof(const Matcher *N) {
|
||||
return N->getKind() == CheckPredicate;
|
||||
@ -436,7 +437,7 @@ public:
|
||||
private:
|
||||
virtual void printImpl(raw_ostream &OS, unsigned indent) const;
|
||||
virtual bool isEqualImpl(const Matcher *M) const {
|
||||
return cast<CheckPredicateMatcher>(M)->PredName == PredName;
|
||||
return cast<CheckPredicateMatcher>(M)->Pred == Pred;
|
||||
}
|
||||
virtual unsigned getHashImpl() const;
|
||||
};
|
||||
|
@ -33,8 +33,12 @@ OmitComments("omit-comments", cl::desc("Do not generate comments"),
|
||||
namespace {
|
||||
class MatcherTableEmitter {
|
||||
const CodeGenDAGPatterns &CGP;
|
||||
StringMap<unsigned> NodePredicateMap, PatternPredicateMap;
|
||||
std::vector<std::string> NodePredicates, PatternPredicates;
|
||||
|
||||
DenseMap<TreePattern *, unsigned> NodePredicateMap;
|
||||
std::vector<TreePredicateFn> NodePredicates;
|
||||
|
||||
StringMap<unsigned> PatternPredicateMap;
|
||||
std::vector<std::string> PatternPredicates;
|
||||
|
||||
DenseMap<const ComplexPattern*, unsigned> ComplexPatternMap;
|
||||
std::vector<const ComplexPattern*> ComplexPatterns;
|
||||
@ -57,14 +61,15 @@ private:
|
||||
unsigned EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
||||
formatted_raw_ostream &OS);
|
||||
|
||||
unsigned getNodePredicate(StringRef PredName) {
|
||||
unsigned &Entry = NodePredicateMap[PredName];
|
||||
unsigned getNodePredicate(TreePredicateFn Pred) {
|
||||
unsigned &Entry = NodePredicateMap[Pred.getOrigPatFragRecord()];
|
||||
if (Entry == 0) {
|
||||
NodePredicates.push_back(PredName.str());
|
||||
NodePredicates.push_back(Pred);
|
||||
Entry = NodePredicates.size();
|
||||
}
|
||||
return Entry-1;
|
||||
}
|
||||
|
||||
unsigned getPatternPredicate(StringRef PredName) {
|
||||
unsigned &Entry = PatternPredicateMap[PredName];
|
||||
if (Entry == 0) {
|
||||
@ -73,7 +78,6 @@ private:
|
||||
}
|
||||
return Entry-1;
|
||||
}
|
||||
|
||||
unsigned getComplexPat(const ComplexPattern &P) {
|
||||
unsigned &Entry = ComplexPatternMap[&P];
|
||||
if (Entry == 0) {
|
||||
@ -239,7 +243,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
||||
return 2;
|
||||
|
||||
case Matcher::CheckPatternPredicate: {
|
||||
StringRef Pred = cast<CheckPatternPredicateMatcher>(N)->getPredicate();
|
||||
StringRef Pred =cast<CheckPatternPredicateMatcher>(N)->getPredicate();
|
||||
OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
|
||||
if (!OmitComments)
|
||||
OS.PadToColumn(CommentIndent) << "// " << Pred;
|
||||
@ -247,10 +251,10 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
||||
return 2;
|
||||
}
|
||||
case Matcher::CheckPredicate: {
|
||||
StringRef Pred = cast<CheckPredicateMatcher>(N)->getPredicateName();
|
||||
TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate();
|
||||
OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
|
||||
if (!OmitComments)
|
||||
OS.PadToColumn(CommentIndent) << "// " << Pred;
|
||||
OS.PadToColumn(CommentIndent) << "// " << Pred.getFnName();
|
||||
OS << '\n';
|
||||
return 2;
|
||||
}
|
||||
@ -617,25 +621,13 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) {
|
||||
OS << " switch (PredNo) {\n";
|
||||
OS << " default: assert(0 && \"Invalid predicate in table?\");\n";
|
||||
for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) {
|
||||
// FIXME: Storing this by name is horrible.
|
||||
TreePattern *P =PFsByName[NodePredicates[i].substr(strlen("Predicate_"))];
|
||||
assert(P && "Unknown name?");
|
||||
|
||||
// Emit the predicate code corresponding to this pattern.
|
||||
std::string Code = P->getRecord()->getValueAsCode("Predicate");
|
||||
assert(!Code.empty() && "No code in this predicate");
|
||||
OS << " case " << i << ": { // " << NodePredicates[i] << '\n';
|
||||
std::string ClassName;
|
||||
if (P->getOnlyTree()->isLeaf())
|
||||
ClassName = "SDNode";
|
||||
else
|
||||
ClassName =
|
||||
CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName();
|
||||
if (ClassName == "SDNode")
|
||||
OS << " SDNode *N = Node;\n";
|
||||
else
|
||||
OS << " " << ClassName << "*N = cast<" << ClassName << ">(Node);\n";
|
||||
OS << Code << "\n }\n";
|
||||
TreePredicateFn PredFn = NodePredicates[i];
|
||||
|
||||
assert(!PredFn.isAlwaysTrue() && "No code in this predicate");
|
||||
OS << " case " << i << ": { // " << NodePredicates[i].getFnName() <<'\n';
|
||||
|
||||
OS << PredFn.getCodeToRunOnSDNode() << "\n }\n";
|
||||
}
|
||||
OS << " }\n";
|
||||
OS << "}\n\n";
|
||||
|
Loading…
x
Reference in New Issue
Block a user