2010-02-15 16:04:42 +08:00
|
|
|
//===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2010-02-15 16:04:42 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2010-08-06 09:30:54 +08:00
|
|
|
// This file contains code to generate C++ code for a matcher.
|
2010-02-15 16:04:42 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "CodeGenDAGPatterns.h"
|
2017-02-15 02:32:41 +08:00
|
|
|
#include "DAGISelMatcher.h"
|
2010-02-17 08:31:50 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2017-02-15 02:32:41 +08:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
|
|
#include "llvm/ADT/MapVector.h"
|
2010-02-15 16:04:42 +08:00
|
|
|
#include "llvm/ADT/SmallString.h"
|
2010-02-16 15:21:10 +08:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
2015-08-28 04:43:34 +08:00
|
|
|
#include "llvm/ADT/TinyPtrVector.h"
|
2010-03-02 02:49:10 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2017-09-20 05:03:57 +08:00
|
|
|
#include "llvm/Support/Format.h"
|
2017-02-15 02:32:41 +08:00
|
|
|
#include "llvm/Support/SourceMgr.h"
|
|
|
|
#include "llvm/TableGen/Error.h"
|
2012-12-04 18:37:14 +08:00
|
|
|
#include "llvm/TableGen/Record.h"
|
2020-11-17 03:24:25 +08:00
|
|
|
|
2010-02-15 16:04:42 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
enum {
|
2017-09-20 05:03:57 +08:00
|
|
|
IndexWidth = 6,
|
|
|
|
FullIndexWidth = IndexWidth + 4,
|
|
|
|
HistOpcWidth = 40,
|
2010-02-15 16:04:42 +08:00
|
|
|
};
|
|
|
|
|
2017-03-27 21:15:13 +08:00
|
|
|
cl::OptionCategory DAGISelCat("Options for -gen-dag-isel");
|
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
// To reduce generated source code size.
|
2017-03-27 21:15:13 +08:00
|
|
|
static cl::opt<bool> OmitComments("omit-comments",
|
|
|
|
cl::desc("Do not generate comments"),
|
|
|
|
cl::init(false), cl::cat(DAGISelCat));
|
2010-03-02 02:49:10 +08:00
|
|
|
|
2017-02-15 02:32:41 +08:00
|
|
|
static cl::opt<bool> InstrumentCoverage(
|
|
|
|
"instrument-coverage",
|
|
|
|
cl::desc("Generates tables to help identify patterns matched"),
|
2017-03-27 21:15:13 +08:00
|
|
|
cl::init(false), cl::cat(DAGISelCat));
|
2017-02-15 02:32:41 +08:00
|
|
|
|
2010-02-16 14:52:01 +08:00
|
|
|
namespace {
|
|
|
|
class MatcherTableEmitter {
|
2010-03-29 09:40:38 +08:00
|
|
|
const CodeGenDAGPatterns &CGP;
|
2017-10-06 23:33:55 +08:00
|
|
|
|
2020-11-17 03:24:25 +08:00
|
|
|
SmallVector<unsigned, Matcher::HighestKind+1> OpcodeCounts;
|
|
|
|
|
2011-04-18 05:38:24 +08:00
|
|
|
DenseMap<TreePattern *, unsigned> NodePredicateMap;
|
|
|
|
std::vector<TreePredicateFn> NodePredicates;
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
std::vector<TreePredicateFn> NodePredicatesWithOperands;
|
2015-08-28 04:43:34 +08:00
|
|
|
|
|
|
|
// We de-duplicate the predicates by code string, and use this map to track
|
|
|
|
// all the patterns with "identical" predicates.
|
|
|
|
StringMap<TinyPtrVector<TreePattern *>> NodePredicatesByCodeToRun;
|
2017-10-06 23:33:55 +08:00
|
|
|
|
2011-04-18 05:38:24 +08:00
|
|
|
StringMap<unsigned> PatternPredicateMap;
|
|
|
|
std::vector<std::string> PatternPredicates;
|
2010-02-17 08:31:50 +08:00
|
|
|
|
|
|
|
DenseMap<const ComplexPattern*, unsigned> ComplexPatternMap;
|
|
|
|
std::vector<const ComplexPattern*> ComplexPatterns;
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
|
|
|
|
|
|
|
|
DenseMap<Record*, unsigned> NodeXFormMap;
|
2010-03-01 09:54:19 +08:00
|
|
|
std::vector<Record*> NodeXForms;
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
|
2017-02-15 02:32:41 +08:00
|
|
|
std::vector<std::string> VecIncludeStrings;
|
|
|
|
MapVector<std::string, unsigned, StringMap<unsigned> > VecPatterns;
|
|
|
|
|
|
|
|
unsigned getPatternIdxFromTable(std::string &&P, std::string &&include_loc) {
|
|
|
|
const auto It = VecPatterns.find(P);
|
|
|
|
if (It == VecPatterns.end()) {
|
|
|
|
VecPatterns.insert(make_pair(std::move(P), VecPatterns.size()));
|
|
|
|
VecIncludeStrings.push_back(std::move(include_loc));
|
|
|
|
return VecIncludeStrings.size() - 1;
|
|
|
|
}
|
|
|
|
return It->second;
|
|
|
|
}
|
|
|
|
|
2010-02-16 14:52:01 +08:00
|
|
|
public:
|
2020-11-17 03:24:25 +08:00
|
|
|
MatcherTableEmitter(const CodeGenDAGPatterns &cgp) : CGP(cgp) {
|
|
|
|
OpcodeCounts.assign(Matcher::HighestKind+1, 0);
|
|
|
|
}
|
2010-02-16 14:52:01 +08:00
|
|
|
|
2020-11-17 03:24:25 +08:00
|
|
|
unsigned EmitMatcherList(const Matcher *N, const unsigned Indent,
|
2017-09-20 05:03:57 +08:00
|
|
|
unsigned StartIdx, raw_ostream &OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2020-11-17 03:24:25 +08:00
|
|
|
unsigned SizeMatcherList(Matcher *N, raw_ostream &OS);
|
|
|
|
|
2017-09-20 05:03:57 +08:00
|
|
|
void EmitPredicateFunctions(raw_ostream &OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2017-09-20 05:03:57 +08:00
|
|
|
void EmitHistogram(const Matcher *N, raw_ostream &OS);
|
2017-02-15 02:32:41 +08:00
|
|
|
|
|
|
|
void EmitPatternMatchTable(raw_ostream &OS);
|
|
|
|
|
2010-02-16 14:52:01 +08:00
|
|
|
private:
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
void EmitNodePredicatesFunction(const std::vector<TreePredicateFn> &Preds,
|
|
|
|
StringRef Decl, raw_ostream &OS);
|
|
|
|
|
2020-11-17 03:24:25 +08:00
|
|
|
unsigned SizeMatcher(Matcher *N, raw_ostream &OS);
|
|
|
|
|
|
|
|
unsigned EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
|
2017-09-20 05:03:57 +08:00
|
|
|
raw_ostream &OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2011-04-18 05:38:24 +08:00
|
|
|
unsigned getNodePredicate(TreePredicateFn Pred) {
|
2015-08-28 04:43:34 +08:00
|
|
|
TreePattern *TP = Pred.getOrigPatFragRecord();
|
|
|
|
unsigned &Entry = NodePredicateMap[TP];
|
2010-02-16 15:21:10 +08:00
|
|
|
if (Entry == 0) {
|
2015-08-28 04:43:34 +08:00
|
|
|
TinyPtrVector<TreePattern *> &SameCodePreds =
|
|
|
|
NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()];
|
|
|
|
if (SameCodePreds.empty()) {
|
|
|
|
// We've never seen a predicate with the same code: allocate an entry.
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
if (Pred.usesOperands()) {
|
|
|
|
NodePredicatesWithOperands.push_back(Pred);
|
|
|
|
Entry = NodePredicatesWithOperands.size();
|
|
|
|
} else {
|
|
|
|
NodePredicates.push_back(Pred);
|
|
|
|
Entry = NodePredicates.size();
|
|
|
|
}
|
2015-08-28 04:43:34 +08:00
|
|
|
} else {
|
|
|
|
// We did see an identical predicate: re-use it.
|
|
|
|
Entry = NodePredicateMap[SameCodePreds.front()];
|
|
|
|
assert(Entry != 0);
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
assert(TreePredicateFn(SameCodePreds.front()).usesOperands() ==
|
|
|
|
Pred.usesOperands() &&
|
|
|
|
"PatFrags with some code must have same usesOperands setting");
|
2015-08-28 04:43:34 +08:00
|
|
|
}
|
|
|
|
// In both cases, we've never seen this particular predicate before, so
|
|
|
|
// mark it in the list of predicates sharing the same code.
|
|
|
|
SameCodePreds.push_back(TP);
|
2010-02-16 15:21:10 +08:00
|
|
|
}
|
|
|
|
return Entry-1;
|
|
|
|
}
|
2017-10-06 23:33:55 +08:00
|
|
|
|
2010-02-16 15:21:10 +08:00
|
|
|
unsigned getPatternPredicate(StringRef PredName) {
|
|
|
|
unsigned &Entry = PatternPredicateMap[PredName];
|
|
|
|
if (Entry == 0) {
|
|
|
|
PatternPredicates.push_back(PredName.str());
|
|
|
|
Entry = PatternPredicates.size();
|
|
|
|
}
|
|
|
|
return Entry-1;
|
|
|
|
}
|
2010-02-17 08:31:50 +08:00
|
|
|
unsigned getComplexPat(const ComplexPattern &P) {
|
|
|
|
unsigned &Entry = ComplexPatternMap[&P];
|
|
|
|
if (Entry == 0) {
|
|
|
|
ComplexPatterns.push_back(&P);
|
|
|
|
Entry = ComplexPatterns.size();
|
|
|
|
}
|
|
|
|
return Entry-1;
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
unsigned getNodeXFormID(Record *Rec) {
|
|
|
|
unsigned &Entry = NodeXFormMap[Rec];
|
|
|
|
if (Entry == 0) {
|
|
|
|
NodeXForms.push_back(Rec);
|
|
|
|
Entry = NodeXForms.size();
|
|
|
|
}
|
|
|
|
return Entry-1;
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-16 14:52:01 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2017-02-15 02:32:41 +08:00
|
|
|
static std::string GetPatFromTreePatternNode(const TreePatternNode *N) {
|
|
|
|
std::string str;
|
|
|
|
raw_string_ostream Stream(str);
|
|
|
|
Stream << *N;
|
|
|
|
Stream.str();
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2021-02-09 08:25:18 +08:00
|
|
|
static unsigned GetVBRSize(unsigned Val) {
|
2010-02-26 03:00:39 +08:00
|
|
|
if (Val <= 127) return 1;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-26 03:00:39 +08:00
|
|
|
unsigned NumBytes = 0;
|
|
|
|
while (Val >= 128) {
|
|
|
|
Val >>= 7;
|
|
|
|
++NumBytes;
|
|
|
|
}
|
|
|
|
return NumBytes+1;
|
|
|
|
}
|
|
|
|
|
2010-02-23 08:59:59 +08:00
|
|
|
/// EmitVBRValue - Emit the specified value as a VBR, returning the number of
|
|
|
|
/// bytes emitted.
|
2021-02-09 08:25:18 +08:00
|
|
|
static unsigned EmitVBRValue(uint64_t Val, raw_ostream &OS) {
|
2010-02-23 08:59:59 +08:00
|
|
|
if (Val <= 127) {
|
|
|
|
OS << Val << ", ";
|
|
|
|
return 1;
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-01 06:14:32 +08:00
|
|
|
uint64_t InVal = Val;
|
2010-02-23 08:59:59 +08:00
|
|
|
unsigned NumBytes = 0;
|
2010-02-23 09:07:39 +08:00
|
|
|
while (Val >= 128) {
|
2010-02-23 08:59:59 +08:00
|
|
|
OS << (Val&127) << "|128,";
|
|
|
|
Val >>= 7;
|
|
|
|
++NumBytes;
|
|
|
|
}
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << Val;
|
|
|
|
if (!OmitComments)
|
|
|
|
OS << "/*" << InVal << "*/";
|
|
|
|
OS << ", ";
|
2010-02-23 08:59:59 +08:00
|
|
|
return NumBytes+1;
|
|
|
|
}
|
|
|
|
|
2021-02-19 00:45:08 +08:00
|
|
|
/// Emit the specified signed value as a VBR. To improve compression we encode
|
|
|
|
/// positive numbers shifted left by 1 and negative numbers negated and shifted
|
|
|
|
/// left by 1 with bit 0 set.
|
|
|
|
static unsigned EmitSignedVBRValue(uint64_t Val, raw_ostream &OS) {
|
|
|
|
if ((int64_t)Val >= 0)
|
|
|
|
Val = Val << 1;
|
|
|
|
else
|
|
|
|
Val = (-Val << 1) | 1;
|
|
|
|
|
|
|
|
return EmitVBRValue(Val, OS);
|
|
|
|
}
|
|
|
|
|
2017-02-15 02:32:41 +08:00
|
|
|
// This is expensive and slow.
|
|
|
|
static std::string getIncludePath(const Record *R) {
|
|
|
|
std::string str;
|
|
|
|
raw_string_ostream Stream(str);
|
|
|
|
auto Locs = R->getLoc();
|
|
|
|
SMLoc L;
|
|
|
|
if (Locs.size() > 1) {
|
|
|
|
// Get where the pattern prototype was instantiated
|
|
|
|
L = Locs[1];
|
|
|
|
} else if (Locs.size() == 1) {
|
|
|
|
L = Locs[0];
|
|
|
|
}
|
|
|
|
unsigned CurBuf = SrcMgr.FindBufferContainingLoc(L);
|
|
|
|
assert(CurBuf && "Invalid or unspecified location!");
|
|
|
|
|
|
|
|
Stream << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":"
|
|
|
|
<< SrcMgr.FindLineNumber(L, CurBuf);
|
|
|
|
Stream.str();
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2020-11-17 03:24:25 +08:00
|
|
|
/// This function traverses the matcher tree and sizes all the nodes
|
|
|
|
/// that are children of the three kinds of nodes that have them.
|
|
|
|
unsigned MatcherTableEmitter::
|
|
|
|
SizeMatcherList(Matcher *N, raw_ostream &OS) {
|
|
|
|
unsigned Size = 0;
|
|
|
|
while (N) {
|
|
|
|
Size += SizeMatcher(N, OS);
|
|
|
|
N = N->getNext();
|
|
|
|
}
|
|
|
|
return Size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// This function sizes the children of the three kinds of nodes that
|
|
|
|
/// have them. It does so by using special cases for those three
|
|
|
|
/// nodes, but sharing the code in EmitMatcher() for the other kinds.
|
|
|
|
unsigned MatcherTableEmitter::
|
|
|
|
SizeMatcher(Matcher *N, raw_ostream &OS) {
|
|
|
|
unsigned Idx = 0;
|
|
|
|
|
|
|
|
++OpcodeCounts[N->getKind()];
|
|
|
|
switch (N->getKind()) {
|
|
|
|
// The Scope matcher has its kind, a series of child size + child,
|
|
|
|
// and a trailing zero.
|
|
|
|
case Matcher::Scope: {
|
|
|
|
ScopeMatcher *SM = cast<ScopeMatcher>(N);
|
|
|
|
assert(SM->getNext() == nullptr && "Scope matcher should not have next");
|
|
|
|
unsigned Size = 1; // Count the kind.
|
|
|
|
for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
|
2021-02-09 08:25:18 +08:00
|
|
|
const unsigned ChildSize = SizeMatcherList(SM->getChild(i), OS);
|
2020-11-17 03:24:25 +08:00
|
|
|
assert(ChildSize != 0 && "Matcher cannot have child of size 0");
|
|
|
|
SM->getChild(i)->setSize(ChildSize);
|
|
|
|
Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
|
|
|
|
}
|
|
|
|
++Size; // Count the zero sentinel.
|
|
|
|
return Size;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SwitchOpcode and SwitchType have their kind, a series of child size +
|
|
|
|
// opcode/type + child, and a trailing zero.
|
|
|
|
case Matcher::SwitchOpcode:
|
|
|
|
case Matcher::SwitchType: {
|
|
|
|
unsigned Size = 1; // Count the kind.
|
|
|
|
unsigned NumCases;
|
|
|
|
if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
|
|
|
|
NumCases = SOM->getNumCases();
|
|
|
|
else
|
|
|
|
NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
|
|
|
|
for (unsigned i = 0, e = NumCases; i != e; ++i) {
|
|
|
|
Matcher *Child;
|
|
|
|
if (SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
|
|
|
|
Child = SOM->getCaseMatcher(i);
|
|
|
|
Size += 2; // Count the child's opcode.
|
|
|
|
} else {
|
|
|
|
Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
|
|
|
|
++Size; // Count the child's type.
|
|
|
|
}
|
2021-02-09 08:25:18 +08:00
|
|
|
const unsigned ChildSize = SizeMatcherList(Child, OS);
|
2020-11-17 03:24:25 +08:00
|
|
|
assert(ChildSize != 0 && "Matcher cannot have child of size 0");
|
|
|
|
Child->setSize(ChildSize);
|
|
|
|
Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
|
|
|
|
}
|
|
|
|
++Size; // Count the zero sentinel.
|
|
|
|
return Size;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Employ the matcher emitter to size other matchers.
|
|
|
|
return EmitMatcher(N, 0, Idx, OS);
|
|
|
|
}
|
|
|
|
llvm_unreachable("Unreachable");
|
|
|
|
}
|
|
|
|
|
2017-11-11 02:36:04 +08:00
|
|
|
static void BeginEmitFunction(raw_ostream &OS, StringRef RetType,
|
|
|
|
StringRef Decl, bool AddOverride) {
|
|
|
|
OS << "#ifdef GET_DAGISEL_DECL\n";
|
|
|
|
OS << RetType << ' ' << Decl;
|
|
|
|
if (AddOverride)
|
|
|
|
OS << " override";
|
|
|
|
OS << ";\n"
|
|
|
|
"#endif\n"
|
|
|
|
"#if defined(GET_DAGISEL_BODY) || DAGISEL_INLINE\n";
|
|
|
|
OS << RetType << " DAGISEL_CLASS_COLONCOLON " << Decl << "\n";
|
|
|
|
if (AddOverride) {
|
|
|
|
OS << "#if DAGISEL_INLINE\n"
|
|
|
|
" override\n"
|
|
|
|
"#endif\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void EndEmitFunction(raw_ostream &OS) {
|
|
|
|
OS << "#endif // GET_DAGISEL_BODY\n\n";
|
|
|
|
}
|
|
|
|
|
2017-02-15 02:32:41 +08:00
|
|
|
void MatcherTableEmitter::EmitPatternMatchTable(raw_ostream &OS) {
|
|
|
|
|
|
|
|
assert(isUInt<16>(VecPatterns.size()) &&
|
|
|
|
"Using only 16 bits to encode offset into Pattern Table");
|
|
|
|
assert(VecPatterns.size() == VecIncludeStrings.size() &&
|
|
|
|
"The sizes of Pattern and include vectors should be the same");
|
2017-11-11 02:36:04 +08:00
|
|
|
|
|
|
|
BeginEmitFunction(OS, "StringRef", "getPatternForIndex(unsigned Index)",
|
|
|
|
true/*AddOverride*/);
|
|
|
|
OS << "{\n";
|
2020-11-06 22:19:59 +08:00
|
|
|
OS << "static const char *PATTERN_MATCH_TABLE[] = {\n";
|
2017-02-15 02:32:41 +08:00
|
|
|
|
|
|
|
for (const auto &It : VecPatterns) {
|
|
|
|
OS << "\"" << It.first << "\",\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
OS << "\n};";
|
|
|
|
OS << "\nreturn StringRef(PATTERN_MATCH_TABLE[Index]);";
|
2019-02-05 05:06:24 +08:00
|
|
|
OS << "\n}\n";
|
2017-11-11 02:36:04 +08:00
|
|
|
EndEmitFunction(OS);
|
2017-02-15 02:32:41 +08:00
|
|
|
|
2017-11-11 02:36:04 +08:00
|
|
|
BeginEmitFunction(OS, "StringRef", "getIncludePathForIndex(unsigned Index)",
|
|
|
|
true/*AddOverride*/);
|
|
|
|
OS << "{\n";
|
2020-11-06 22:19:59 +08:00
|
|
|
OS << "static const char *INCLUDE_PATH_TABLE[] = {\n";
|
2017-02-15 02:32:41 +08:00
|
|
|
|
|
|
|
for (const auto &It : VecIncludeStrings) {
|
|
|
|
OS << "\"" << It << "\",\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
OS << "\n};";
|
|
|
|
OS << "\nreturn StringRef(INCLUDE_PATH_TABLE[Index]);";
|
2019-02-05 05:06:24 +08:00
|
|
|
OS << "\n}\n";
|
2017-11-11 02:36:04 +08:00
|
|
|
EndEmitFunction(OS);
|
2017-02-15 02:32:41 +08:00
|
|
|
}
|
|
|
|
|
2013-02-06 00:53:11 +08:00
|
|
|
/// EmitMatcher - Emit bytes for the specified matcher and return
|
2010-02-15 16:04:42 +08:00
|
|
|
/// the number of bytes emitted.
|
2010-02-16 14:52:01 +08:00
|
|
|
unsigned MatcherTableEmitter::
|
2020-11-17 03:24:25 +08:00
|
|
|
EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
|
2017-09-20 05:03:57 +08:00
|
|
|
raw_ostream &OS) {
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(Indent);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-15 16:04:42 +08:00
|
|
|
switch (N->getKind()) {
|
2010-02-26 03:00:39 +08:00
|
|
|
case Matcher::Scope: {
|
|
|
|
const ScopeMatcher *SM = cast<ScopeMatcher>(N);
|
|
|
|
unsigned StartIdx = CurrentIdx;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-26 03:00:39 +08:00
|
|
|
// Emit all of the children.
|
|
|
|
for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
|
|
|
|
if (i == 0) {
|
|
|
|
OS << "OPC_Scope, ";
|
|
|
|
++CurrentIdx;
|
2010-03-02 02:49:10 +08:00
|
|
|
} else {
|
|
|
|
if (!OmitComments) {
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(Indent) << "/*Scope*/ ";
|
2010-03-02 02:49:10 +08:00
|
|
|
} else
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(Indent);
|
2010-02-26 03:00:39 +08:00
|
|
|
}
|
|
|
|
|
2021-02-09 08:25:18 +08:00
|
|
|
unsigned ChildSize = SM->getChild(i)->getSize();
|
|
|
|
unsigned VBRSize = EmitVBRValue(ChildSize, OS);
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments) {
|
2020-11-17 03:24:25 +08:00
|
|
|
OS << "/*->" << CurrentIdx + VBRSize + ChildSize << "*/";
|
2010-03-02 02:49:10 +08:00
|
|
|
if (i == 0)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << " // " << SM->getNumChildren() << " children in Scope";
|
2010-03-02 02:49:10 +08:00
|
|
|
}
|
2020-11-17 03:24:25 +08:00
|
|
|
OS << '\n';
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2020-11-17 03:24:25 +08:00
|
|
|
ChildSize = EmitMatcherList(SM->getChild(i), Indent+1,
|
|
|
|
CurrentIdx + VBRSize, OS);
|
|
|
|
assert(ChildSize == SM->getChild(i)->getSize() &&
|
|
|
|
"Emitted child size does not match calculated size");
|
|
|
|
CurrentIdx += VBRSize + ChildSize;
|
2010-02-26 03:00:39 +08:00
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-26 03:00:39 +08:00
|
|
|
// Emit a zero as a sentinel indicating end of 'Scope'.
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(Indent) << "0, ";
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
|
|
|
OS << "/*End of Scope*/";
|
|
|
|
OS << '\n';
|
2010-02-26 03:00:39 +08:00
|
|
|
return CurrentIdx - StartIdx + 1;
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::RecordNode:
|
2010-02-19 06:03:03 +08:00
|
|
|
OS << "OPC_RecordNode,";
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << " // #"
|
|
|
|
<< cast<RecordMatcher>(N)->getResultNo() << " = "
|
|
|
|
<< cast<RecordMatcher>(N)->getWhatFor();
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << '\n';
|
2010-02-15 16:04:42 +08:00
|
|
|
return 1;
|
2010-02-24 15:31:45 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::RecordChild:
|
|
|
|
OS << "OPC_RecordChild" << cast<RecordChildMatcher>(N)->getChildNo()
|
2010-02-24 15:31:45 +08:00
|
|
|
<< ',';
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << " // #"
|
|
|
|
<< cast<RecordChildMatcher>(N)->getResultNo() << " = "
|
|
|
|
<< cast<RecordChildMatcher>(N)->getWhatFor();
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << '\n';
|
2010-02-24 15:31:45 +08:00
|
|
|
return 1;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::RecordMemRef:
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
OS << "OPC_RecordMemRef,\n";
|
|
|
|
return 1;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-12-24 01:03:20 +08:00
|
|
|
case Matcher::CaptureGlueInput:
|
2010-12-24 01:24:32 +08:00
|
|
|
OS << "OPC_CaptureGlueInput,\n";
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
return 1;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2016-05-02 09:53:30 +08:00
|
|
|
case Matcher::MoveChild: {
|
|
|
|
const auto *MCM = cast<MoveChildMatcher>(N);
|
|
|
|
|
|
|
|
OS << "OPC_MoveChild";
|
|
|
|
// Handle the specialized forms.
|
|
|
|
if (MCM->getChildNo() >= 8)
|
|
|
|
OS << ", ";
|
|
|
|
OS << MCM->getChildNo() << ",\n";
|
|
|
|
return (MCM->getChildNo() >= 8) ? 2 : 1;
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::MoveParent:
|
2010-02-15 16:04:42 +08:00
|
|
|
OS << "OPC_MoveParent,\n";
|
|
|
|
return 1;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckSame:
|
2010-02-15 16:04:42 +08:00
|
|
|
OS << "OPC_CheckSame, "
|
2010-02-25 10:04:40 +08:00
|
|
|
<< cast<CheckSameMatcher>(N)->getMatchNumber() << ",\n";
|
2010-02-15 16:04:42 +08:00
|
|
|
return 2;
|
|
|
|
|
2013-10-05 13:38:16 +08:00
|
|
|
case Matcher::CheckChildSame:
|
|
|
|
OS << "OPC_CheckChild"
|
|
|
|
<< cast<CheckChildSameMatcher>(N)->getChildNo() << "Same, "
|
|
|
|
<< cast<CheckChildSameMatcher>(N)->getMatchNumber() << ",\n";
|
|
|
|
return 2;
|
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckPatternPredicate: {
|
2011-04-18 05:38:24 +08:00
|
|
|
StringRef Pred =cast<CheckPatternPredicateMatcher>(N)->getPredicate();
|
2010-02-16 15:21:10 +08:00
|
|
|
OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << " // " << Pred;
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << '\n';
|
2010-02-15 16:04:42 +08:00
|
|
|
return 2;
|
2010-02-16 15:21:10 +08:00
|
|
|
}
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckPredicate: {
|
2011-04-18 05:38:24 +08:00
|
|
|
TreePredicateFn Pred = cast<CheckPredicateMatcher>(N)->getPredicate();
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
unsigned OperandBytes = 0;
|
|
|
|
|
|
|
|
if (Pred.usesOperands()) {
|
|
|
|
unsigned NumOps = cast<CheckPredicateMatcher>(N)->getNumOperands();
|
|
|
|
OS << "OPC_CheckPredicateWithOperands, " << NumOps << "/*#Ops*/, ";
|
|
|
|
for (unsigned i = 0; i < NumOps; ++i)
|
|
|
|
OS << cast<CheckPredicateMatcher>(N)->getOperandNo(i) << ", ";
|
|
|
|
OperandBytes = 1 + NumOps;
|
|
|
|
} else {
|
|
|
|
OS << "OPC_CheckPredicate, ";
|
|
|
|
}
|
|
|
|
|
|
|
|
OS << getNodePredicate(Pred) << ',';
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << " // " << Pred.getFnName();
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << '\n';
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
return 2 + OperandBytes;
|
2010-02-16 15:21:10 +08:00
|
|
|
}
|
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckOpcode:
|
2011-03-01 09:37:19 +08:00
|
|
|
OS << "OPC_CheckOpcode, TARGET_VAL("
|
2010-03-25 14:33:05 +08:00
|
|
|
<< cast<CheckOpcodeMatcher>(N)->getOpcode().getEnumName() << "),\n";
|
|
|
|
return 3;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-03 14:28:15 +08:00
|
|
|
case Matcher::SwitchOpcode:
|
|
|
|
case Matcher::SwitchType: {
|
2010-03-01 14:59:22 +08:00
|
|
|
unsigned StartIdx = CurrentIdx;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-03 14:28:15 +08:00
|
|
|
unsigned NumCases;
|
|
|
|
if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
|
|
|
|
OS << "OPC_SwitchOpcode ";
|
|
|
|
NumCases = SOM->getNumCases();
|
|
|
|
} else {
|
|
|
|
OS << "OPC_SwitchType ";
|
|
|
|
NumCases = cast<SwitchTypeMatcher>(N)->getNumCases();
|
|
|
|
}
|
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2010-03-03 14:28:15 +08:00
|
|
|
OS << "/*" << NumCases << " cases */";
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << ", ";
|
2010-03-01 14:59:22 +08:00
|
|
|
++CurrentIdx;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-01 14:59:22 +08:00
|
|
|
// For each case we emit the size, then the opcode, then the matcher.
|
2010-03-03 14:28:15 +08:00
|
|
|
for (unsigned i = 0, e = NumCases; i != e; ++i) {
|
|
|
|
const Matcher *Child;
|
2010-03-28 02:49:33 +08:00
|
|
|
unsigned IdxSize;
|
|
|
|
if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N)) {
|
2010-03-03 14:28:15 +08:00
|
|
|
Child = SOM->getCaseMatcher(i);
|
2010-03-28 02:49:33 +08:00
|
|
|
IdxSize = 2; // size of opcode in table is 2 bytes.
|
|
|
|
} else {
|
2010-03-03 14:28:15 +08:00
|
|
|
Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
|
2010-03-28 02:49:33 +08:00
|
|
|
IdxSize = 1; // size of type in table is 1 byte.
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
if (i != 0) {
|
2013-09-23 07:18:50 +08:00
|
|
|
if (!OmitComments)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(Indent);
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2013-09-23 07:18:50 +08:00
|
|
|
OS << (isa<SwitchOpcodeMatcher>(N) ?
|
|
|
|
"/*SwitchOpcode*/ " : "/*SwitchType*/ ");
|
2010-03-02 02:49:10 +08:00
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2021-02-09 08:25:18 +08:00
|
|
|
unsigned ChildSize = Child->getSize();
|
2020-11-17 03:24:25 +08:00
|
|
|
CurrentIdx += EmitVBRValue(ChildSize, OS) + IdxSize;
|
2010-03-28 02:49:33 +08:00
|
|
|
if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
|
2011-03-01 09:37:19 +08:00
|
|
|
OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";
|
2010-03-28 02:49:33 +08:00
|
|
|
else
|
2010-03-25 14:33:05 +08:00
|
|
|
OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ',';
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2020-11-17 03:24:25 +08:00
|
|
|
OS << "// ->" << CurrentIdx + ChildSize;
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << '\n';
|
2020-11-17 03:24:25 +08:00
|
|
|
|
|
|
|
ChildSize = EmitMatcherList(Child, Indent+1, CurrentIdx, OS);
|
|
|
|
assert(ChildSize == Child->getSize() &&
|
|
|
|
"Emitted child size does not match calculated size");
|
2010-03-01 14:59:22 +08:00
|
|
|
CurrentIdx += ChildSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Emit the final zero to terminate the switch.
|
2013-09-23 07:18:50 +08:00
|
|
|
if (!OmitComments)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(Indent) << "0,";
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2010-03-03 14:28:15 +08:00
|
|
|
OS << (isa<SwitchOpcodeMatcher>(N) ?
|
2017-09-20 05:03:57 +08:00
|
|
|
" // EndSwitchOpcode" : " // EndSwitchType");
|
2010-03-03 14:28:15 +08:00
|
|
|
|
2010-03-02 03:00:55 +08:00
|
|
|
OS << '\n';
|
2020-11-17 03:24:25 +08:00
|
|
|
return CurrentIdx - StartIdx + 1;
|
2010-03-01 14:59:22 +08:00
|
|
|
}
|
|
|
|
|
2010-03-01 15:17:40 +08:00
|
|
|
case Matcher::CheckType:
|
2017-11-22 15:11:01 +08:00
|
|
|
if (cast<CheckTypeMatcher>(N)->getResNo() == 0) {
|
|
|
|
OS << "OPC_CheckType, "
|
|
|
|
<< getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
OS << "OPC_CheckTypeRes, " << cast<CheckTypeMatcher>(N)->getResNo()
|
|
|
|
<< ", " << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
|
|
|
|
return 3;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckChildType:
|
2010-02-25 04:15:25 +08:00
|
|
|
OS << "OPC_CheckChild"
|
2010-02-25 10:04:40 +08:00
|
|
|
<< cast<CheckChildTypeMatcher>(N)->getChildNo() << "Type, "
|
|
|
|
<< getEnumName(cast<CheckChildTypeMatcher>(N)->getType()) << ",\n";
|
2010-02-25 04:15:25 +08:00
|
|
|
return 2;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-02 08:13:03 +08:00
|
|
|
case Matcher::CheckInteger: {
|
2010-03-01 06:14:32 +08:00
|
|
|
OS << "OPC_CheckInteger, ";
|
2021-02-19 00:45:08 +08:00
|
|
|
unsigned Bytes =
|
|
|
|
1 + EmitSignedVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);
|
2010-03-02 08:13:03 +08:00
|
|
|
OS << '\n';
|
|
|
|
return Bytes;
|
|
|
|
}
|
2014-02-05 13:44:28 +08:00
|
|
|
case Matcher::CheckChildInteger: {
|
|
|
|
OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo()
|
|
|
|
<< "Integer, ";
|
2021-02-19 00:45:08 +08:00
|
|
|
unsigned Bytes = 1 + EmitSignedVBRValue(
|
|
|
|
cast<CheckChildIntegerMatcher>(N)->getValue(), OS);
|
2014-02-05 13:44:28 +08:00
|
|
|
OS << '\n';
|
|
|
|
return Bytes;
|
|
|
|
}
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckCondCode:
|
2010-02-15 16:04:42 +08:00
|
|
|
OS << "OPC_CheckCondCode, ISD::"
|
2010-02-25 10:04:40 +08:00
|
|
|
<< cast<CheckCondCodeMatcher>(N)->getCondCodeName() << ",\n";
|
2010-02-15 16:04:42 +08:00
|
|
|
return 2;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2019-02-25 11:11:44 +08:00
|
|
|
case Matcher::CheckChild2CondCode:
|
|
|
|
OS << "OPC_CheckChild2CondCode, ISD::"
|
|
|
|
<< cast<CheckChild2CondCodeMatcher>(N)->getCondCodeName() << ",\n";
|
|
|
|
return 2;
|
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckValueType:
|
2010-02-15 16:04:42 +08:00
|
|
|
OS << "OPC_CheckValueType, MVT::"
|
2010-02-25 10:04:40 +08:00
|
|
|
<< cast<CheckValueTypeMatcher>(N)->getTypeName() << ",\n";
|
2010-02-15 16:04:42 +08:00
|
|
|
return 2;
|
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckComplexPat: {
|
2010-03-04 09:23:08 +08:00
|
|
|
const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N);
|
|
|
|
const ComplexPattern &Pattern = CCPM->getPattern();
|
|
|
|
OS << "OPC_CheckComplexPat, /*CP*/" << getComplexPat(Pattern) << ", /*#*/"
|
|
|
|
<< CCPM->getMatchNumber() << ',';
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments) {
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << " // " << Pattern.getSelectFunc();
|
2010-03-04 09:23:08 +08:00
|
|
|
OS << ":$" << CCPM->getName();
|
2010-03-04 08:28:05 +08:00
|
|
|
for (unsigned i = 0, e = Pattern.getNumOperands(); i != e; ++i)
|
2010-03-04 09:23:08 +08:00
|
|
|
OS << " #" << CCPM->getFirstResult()+i;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
if (Pattern.hasProperty(SDNPHasChain))
|
2010-03-04 08:28:05 +08:00
|
|
|
OS << " + chain result";
|
2010-03-02 02:49:10 +08:00
|
|
|
}
|
2010-02-17 14:47:35 +08:00
|
|
|
OS << '\n';
|
2010-03-04 09:23:08 +08:00
|
|
|
return 3;
|
2010-02-17 08:39:26 +08:00
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-02 08:13:03 +08:00
|
|
|
case Matcher::CheckAndImm: {
|
2010-03-01 06:14:32 +08:00
|
|
|
OS << "OPC_CheckAndImm, ";
|
2010-03-02 08:13:03 +08:00
|
|
|
unsigned Bytes=1+EmitVBRValue(cast<CheckAndImmMatcher>(N)->getValue(), OS);
|
|
|
|
OS << '\n';
|
|
|
|
return Bytes;
|
|
|
|
}
|
2010-02-15 16:04:42 +08:00
|
|
|
|
2010-03-02 08:13:03 +08:00
|
|
|
case Matcher::CheckOrImm: {
|
2010-03-01 06:14:32 +08:00
|
|
|
OS << "OPC_CheckOrImm, ";
|
2010-03-02 08:13:03 +08:00
|
|
|
unsigned Bytes = 1+EmitVBRValue(cast<CheckOrImmMatcher>(N)->getValue(), OS);
|
|
|
|
OS << '\n';
|
|
|
|
return Bytes;
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckFoldableChainNode:
|
2010-02-17 03:15:55 +08:00
|
|
|
OS << "OPC_CheckFoldableChainNode,\n";
|
2010-02-16 14:10:58 +08:00
|
|
|
return 1;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2019-03-10 13:21:52 +08:00
|
|
|
case Matcher::CheckImmAllOnesV:
|
|
|
|
OS << "OPC_CheckImmAllOnesV,\n";
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
case Matcher::CheckImmAllZerosV:
|
|
|
|
OS << "OPC_CheckImmAllZerosV,\n";
|
|
|
|
return 1;
|
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::EmitInteger: {
|
|
|
|
int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();
|
2010-03-01 06:14:32 +08:00
|
|
|
OS << "OPC_EmitInteger, "
|
2010-02-25 10:04:40 +08:00
|
|
|
<< getEnumName(cast<EmitIntegerMatcher>(N)->getVT()) << ", ";
|
2010-03-02 08:13:03 +08:00
|
|
|
unsigned Bytes = 2+EmitVBRValue(Val, OS);
|
|
|
|
OS << '\n';
|
|
|
|
return Bytes;
|
2010-02-19 15:49:56 +08:00
|
|
|
}
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::EmitStringInteger: {
|
|
|
|
const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
|
2020-02-11 05:37:00 +08:00
|
|
|
// These should always fit into 7 bits.
|
2010-03-01 06:14:32 +08:00
|
|
|
OS << "OPC_EmitInteger, "
|
2010-02-25 10:04:40 +08:00
|
|
|
<< getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", "
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
<< Val << ",\n";
|
|
|
|
return 3;
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2011-03-11 10:19:02 +08:00
|
|
|
case Matcher::EmitRegister: {
|
|
|
|
const EmitRegisterMatcher *Matcher = cast<EmitRegisterMatcher>(N);
|
|
|
|
const CodeGenRegister *Reg = Matcher->getReg();
|
|
|
|
// If the enum value of the register is larger than one byte can handle,
|
|
|
|
// use EmitRegister2.
|
|
|
|
if (Reg && Reg->EnumValue > 255) {
|
|
|
|
OS << "OPC_EmitRegister2, " << getEnumName(Matcher->getVT()) << ", ";
|
|
|
|
OS << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n";
|
2011-03-01 09:37:19 +08:00
|
|
|
return 4;
|
|
|
|
} else {
|
2011-03-11 10:19:02 +08:00
|
|
|
OS << "OPC_EmitRegister, " << getEnumName(Matcher->getVT()) << ", ";
|
|
|
|
if (Reg) {
|
|
|
|
OS << getQualifiedName(Reg->TheDef) << ",\n";
|
|
|
|
} else {
|
2011-03-01 09:37:19 +08:00
|
|
|
OS << "0 ";
|
|
|
|
if (!OmitComments)
|
|
|
|
OS << "/*zero_reg*/";
|
|
|
|
OS << ",\n";
|
|
|
|
}
|
|
|
|
return 3;
|
2010-03-02 02:49:10 +08:00
|
|
|
}
|
2011-03-11 10:19:02 +08:00
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::EmitConvertToTarget:
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
OS << "OPC_EmitConvertToTarget, "
|
2010-02-25 10:04:40 +08:00
|
|
|
<< cast<EmitConvertToTargetMatcher>(N)->getSlot() << ",\n";
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
return 2;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::EmitMergeInputChains: {
|
|
|
|
const EmitMergeInputChainsMatcher *MN =
|
|
|
|
cast<EmitMergeInputChainsMatcher>(N);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2016-03-07 15:29:12 +08:00
|
|
|
// Handle the specialized forms OPC_EmitMergeInputChains1_0, 1_1, and 1_2.
|
|
|
|
if (MN->getNumNodes() == 1 && MN->getNode(0) < 3) {
|
2010-03-28 13:50:16 +08:00
|
|
|
OS << "OPC_EmitMergeInputChains1_" << MN->getNode(0) << ",\n";
|
|
|
|
return 1;
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
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();
|
|
|
|
}
|
2019-07-22 23:02:34 +08:00
|
|
|
case Matcher::EmitCopyToReg: {
|
|
|
|
const auto *C2RMatcher = cast<EmitCopyToRegMatcher>(N);
|
|
|
|
int Bytes = 3;
|
|
|
|
const CodeGenRegister *Reg = C2RMatcher->getDestPhysReg();
|
|
|
|
if (Reg->EnumValue > 255) {
|
|
|
|
assert(isUInt<16>(Reg->EnumValue) && "not handled");
|
|
|
|
OS << "OPC_EmitCopyToReg2, " << C2RMatcher->getSrcSlot() << ", "
|
|
|
|
<< "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n";
|
|
|
|
++Bytes;
|
|
|
|
} else {
|
|
|
|
OS << "OPC_EmitCopyToReg, " << C2RMatcher->getSrcSlot() << ", "
|
|
|
|
<< getQualifiedName(Reg->TheDef) << ",\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
return Bytes;
|
|
|
|
}
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::EmitNodeXForm: {
|
|
|
|
const EmitNodeXFormMatcher *XF = cast<EmitNodeXFormMatcher>(N);
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", "
|
|
|
|
<< XF->getSlot() << ',';
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << " // "<<XF->getNodeXForm()->getName();
|
2010-03-02 02:49:10 +08:00
|
|
|
OS <<'\n';
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
return 3;
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-28 10:31:26 +08:00
|
|
|
case Matcher::EmitNode:
|
2010-03-01 04:55:18 +08:00
|
|
|
case Matcher::MorphNodeTo: {
|
2017-02-15 02:32:41 +08:00
|
|
|
auto NumCoveredBytes = 0;
|
|
|
|
if (InstrumentCoverage) {
|
|
|
|
if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
|
|
|
|
NumCoveredBytes = 3;
|
|
|
|
OS << "OPC_Coverage, ";
|
|
|
|
std::string src =
|
|
|
|
GetPatFromTreePatternNode(SNT->getPattern().getSrcPattern());
|
|
|
|
std::string dst =
|
|
|
|
GetPatFromTreePatternNode(SNT->getPattern().getDstPattern());
|
|
|
|
Record *PatRecord = SNT->getPattern().getSrcRecord();
|
|
|
|
std::string include_src = getIncludePath(PatRecord);
|
|
|
|
unsigned Offset =
|
|
|
|
getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
|
|
|
|
OS << "TARGET_VAL(" << Offset << "),\n";
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(FullIndexWidth + Indent);
|
2017-02-15 02:32:41 +08:00
|
|
|
}
|
|
|
|
}
|
2010-02-28 10:31:26 +08:00
|
|
|
const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N);
|
2010-03-01 04:55:18 +08:00
|
|
|
OS << (isa<EmitNodeMatcher>(EN) ? "OPC_EmitNode" : "OPC_MorphNodeTo");
|
2016-05-03 13:54:13 +08:00
|
|
|
bool CompressVTs = EN->getNumVTs() < 3;
|
|
|
|
if (CompressVTs)
|
|
|
|
OS << EN->getNumVTs();
|
|
|
|
|
2011-03-01 09:37:19 +08:00
|
|
|
OS << ", TARGET_VAL(" << EN->getOpcodeName() << "), 0";
|
2011-03-01 09:39:05 +08:00
|
|
|
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
if (EN->hasChain()) OS << "|OPFL_Chain";
|
2010-12-24 01:13:18 +08:00
|
|
|
if (EN->hasInFlag()) OS << "|OPFL_GlueInput";
|
|
|
|
if (EN->hasOutFlag()) OS << "|OPFL_GlueOutput";
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
if (EN->hasMemRefs()) OS << "|OPFL_MemRefs";
|
|
|
|
if (EN->getNumFixedArityOperands() != -1)
|
|
|
|
OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands();
|
|
|
|
OS << ",\n";
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(FullIndexWidth + Indent+4);
|
2016-05-03 13:54:13 +08:00
|
|
|
if (!CompressVTs) {
|
|
|
|
OS << EN->getNumVTs();
|
|
|
|
if (!OmitComments)
|
|
|
|
OS << "/*#VTs*/";
|
|
|
|
OS << ", ";
|
|
|
|
}
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i)
|
|
|
|
OS << getEnumName(EN->getVT(i)) << ", ";
|
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << EN->getNumOperands();
|
|
|
|
if (!OmitComments)
|
|
|
|
OS << "/*#Ops*/";
|
|
|
|
OS << ", ";
|
2010-02-23 08:59:59 +08:00
|
|
|
unsigned NumOperandBytes = 0;
|
2010-03-02 08:13:03 +08:00
|
|
|
for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i)
|
2010-02-23 08:59:59 +08:00
|
|
|
NumOperandBytes += EmitVBRValue(EN->getOperand(i), OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments) {
|
|
|
|
// Print the result #'s for EmitNode.
|
|
|
|
if (const EmitNodeMatcher *E = dyn_cast<EmitNodeMatcher>(EN)) {
|
|
|
|
if (unsigned NumResults = EN->getNumVTs()) {
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << " // Results =";
|
2010-03-02 02:49:10 +08:00
|
|
|
unsigned First = E->getFirstResultSlot();
|
|
|
|
for (unsigned i = 0; i != NumResults; ++i)
|
2012-07-19 06:41:03 +08:00
|
|
|
OS << " #" << First+i;
|
2010-03-02 02:49:10 +08:00
|
|
|
}
|
2010-02-28 10:41:25 +08:00
|
|
|
}
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << '\n';
|
|
|
|
|
|
|
|
if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(FullIndexWidth + Indent) << "// Src: "
|
2011-03-01 09:39:05 +08:00
|
|
|
<< *SNT->getPattern().getSrcPattern() << " - Complexity = "
|
2010-03-29 09:40:38 +08:00
|
|
|
<< SNT->getPattern().getPatternComplexity(CGP) << '\n';
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(FullIndexWidth + Indent) << "// Dst: "
|
2010-03-02 02:49:10 +08:00
|
|
|
<< *SNT->getPattern().getDstPattern() << '\n';
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
OS << '\n';
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2017-02-15 02:32:41 +08:00
|
|
|
return 5 + !CompressVTs + EN->getNumVTs() + NumOperandBytes +
|
|
|
|
NumCoveredBytes;
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
}
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CompleteMatch: {
|
|
|
|
const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N);
|
2017-02-15 02:32:41 +08:00
|
|
|
auto NumCoveredBytes = 0;
|
|
|
|
if (InstrumentCoverage) {
|
|
|
|
NumCoveredBytes = 3;
|
|
|
|
OS << "OPC_Coverage, ";
|
|
|
|
std::string src =
|
|
|
|
GetPatFromTreePatternNode(CM->getPattern().getSrcPattern());
|
|
|
|
std::string dst =
|
|
|
|
GetPatFromTreePatternNode(CM->getPattern().getDstPattern());
|
|
|
|
Record *PatRecord = CM->getPattern().getSrcRecord();
|
|
|
|
std::string include_src = getIncludePath(PatRecord);
|
|
|
|
unsigned Offset =
|
|
|
|
getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
|
|
|
|
OS << "TARGET_VAL(" << Offset << "),\n";
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(FullIndexWidth + Indent);
|
2017-02-15 02:32:41 +08:00
|
|
|
}
|
2010-02-21 14:03:07 +08:00
|
|
|
OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
|
2010-02-23 08:59:59 +08:00
|
|
|
unsigned NumResultBytes = 0;
|
2010-02-21 14:03:07 +08:00
|
|
|
for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
|
2010-02-23 08:59:59 +08:00
|
|
|
NumResultBytes += EmitVBRValue(CM->getResult(i), OS);
|
2010-02-21 14:03:07 +08:00
|
|
|
OS << '\n';
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments) {
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(FullIndexWidth + Indent) << " // Src: "
|
2011-03-01 09:39:05 +08:00
|
|
|
<< *CM->getPattern().getSrcPattern() << " - Complexity = "
|
2010-03-29 09:40:38 +08:00
|
|
|
<< CM->getPattern().getPatternComplexity(CGP) << '\n';
|
2020-04-26 10:55:26 +08:00
|
|
|
OS.indent(FullIndexWidth + Indent) << " // Dst: "
|
2010-03-02 02:49:10 +08:00
|
|
|
<< *CM->getPattern().getDstPattern();
|
|
|
|
}
|
|
|
|
OS << '\n';
|
2017-02-15 02:32:41 +08:00
|
|
|
return 2 + NumResultBytes + NumCoveredBytes;
|
2010-02-15 16:04:42 +08:00
|
|
|
}
|
2010-02-21 14:03:07 +08:00
|
|
|
}
|
2012-02-05 15:21:30 +08:00
|
|
|
llvm_unreachable("Unreachable");
|
2010-02-15 16:04:42 +08:00
|
|
|
}
|
|
|
|
|
2020-11-17 03:24:25 +08:00
|
|
|
/// This function traverses the matcher tree and emits all the nodes.
|
|
|
|
/// The nodes have already been sized.
|
2010-02-16 14:52:01 +08:00
|
|
|
unsigned MatcherTableEmitter::
|
2020-11-17 03:24:25 +08:00
|
|
|
EmitMatcherList(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
|
2017-09-20 05:03:57 +08:00
|
|
|
raw_ostream &OS) {
|
2010-02-15 16:04:42 +08:00
|
|
|
unsigned Size = 0;
|
2010-02-18 10:49:24 +08:00
|
|
|
while (N) {
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
|
2010-02-26 03:00:39 +08:00
|
|
|
unsigned MatcherSize = EmitMatcher(N, Indent, CurrentIdx, OS);
|
2010-02-21 15:16:41 +08:00
|
|
|
Size += MatcherSize;
|
|
|
|
CurrentIdx += MatcherSize;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-18 10:53:41 +08:00
|
|
|
// If there are other nodes in this list, iterate to them, otherwise we're
|
2010-02-15 16:04:42 +08:00
|
|
|
// done.
|
2010-02-18 10:53:41 +08:00
|
|
|
N = N->getNext();
|
2010-02-15 16:04:42 +08:00
|
|
|
}
|
2010-02-18 10:49:24 +08:00
|
|
|
return Size;
|
2010-02-15 16:04:42 +08:00
|
|
|
}
|
|
|
|
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
void MatcherTableEmitter::EmitNodePredicatesFunction(
|
|
|
|
const std::vector<TreePredicateFn> &Preds, StringRef Decl,
|
|
|
|
raw_ostream &OS) {
|
|
|
|
if (Preds.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
BeginEmitFunction(OS, "bool", Decl, true/*AddOverride*/);
|
|
|
|
OS << "{\n";
|
|
|
|
OS << " switch (PredNo) {\n";
|
|
|
|
OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n";
|
|
|
|
for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
|
|
|
|
// Emit the predicate code corresponding to this pattern.
|
2020-11-17 03:24:25 +08:00
|
|
|
const TreePredicateFn PredFn = Preds[i];
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
|
|
|
|
assert(!PredFn.isAlwaysTrue() && "No code in this predicate");
|
2020-11-06 22:19:59 +08:00
|
|
|
OS << " case " << i << ": {\n";
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
for (auto *SimilarPred :
|
2020-11-17 03:24:25 +08:00
|
|
|
NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()])
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
OS << " // " << TreePredicateFn(SimilarPred).getFnName() <<'\n';
|
|
|
|
|
|
|
|
OS << PredFn.getCodeToRunOnSDNode() << "\n }\n";
|
|
|
|
}
|
|
|
|
OS << " }\n";
|
|
|
|
OS << "}\n";
|
|
|
|
EndEmitFunction(OS);
|
|
|
|
}
|
|
|
|
|
2017-09-20 05:03:57 +08:00
|
|
|
void MatcherTableEmitter::EmitPredicateFunctions(raw_ostream &OS) {
|
2010-02-17 08:31:50 +08:00
|
|
|
// Emit pattern predicates.
|
2010-03-01 06:57:03 +08:00
|
|
|
if (!PatternPredicates.empty()) {
|
2017-11-11 02:36:04 +08:00
|
|
|
BeginEmitFunction(OS, "bool",
|
|
|
|
"CheckPatternPredicate(unsigned PredNo) const", true/*AddOverride*/);
|
|
|
|
OS << "{\n";
|
2010-03-01 06:57:03 +08:00
|
|
|
OS << " switch (PredNo) {\n";
|
2012-02-05 15:21:30 +08:00
|
|
|
OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n";
|
2010-03-01 06:57:03 +08:00
|
|
|
for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i)
|
|
|
|
OS << " case " << i << ": return " << PatternPredicates[i] << ";\n";
|
|
|
|
OS << " }\n";
|
2017-11-11 02:36:04 +08:00
|
|
|
OS << "}\n";
|
|
|
|
EndEmitFunction(OS);
|
2010-03-01 06:57:03 +08:00
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-17 08:31:50 +08:00
|
|
|
// Emit Node predicates.
|
TableGen/ISel: Allow PatFrag predicate code to access captured operands
Summary:
This simplifies writing predicates for pattern fragments that are
automatically re-associated or commuted.
For example, a followup patch adds patterns for fragments of the form
(add (shl $x, $y), $z) to the AMDGPU backend. Such patterns are
automatically commuted to (add $z, (shl $x, $y)), which makes it basically
impossible to refer to $x, $y, and $z generically in the PredicateCode.
With this change, the PredicateCode can refer to $x, $y, and $z simply
as `Operands[i]`.
Test confirmed that there are no changes to any of the generated files
when building all (non-experimental) targets.
Change-Id: I61c00ace7eed42c1d4edc4c5351174b56b77a79c
Reviewers: arsenm, rampitec, RKSimon, craig.topper, hfinkel, uweigand
Subscribers: wdng, tpr, llvm-commits
Differential Revision: https://reviews.llvm.org/D51994
llvm-svn: 347992
2018-11-30 22:15:13 +08:00
|
|
|
EmitNodePredicatesFunction(
|
|
|
|
NodePredicates, "CheckNodePredicate(SDNode *Node, unsigned PredNo) const",
|
|
|
|
OS);
|
|
|
|
EmitNodePredicatesFunction(
|
|
|
|
NodePredicatesWithOperands,
|
|
|
|
"CheckNodePredicateWithOperands(SDNode *Node, unsigned PredNo, "
|
|
|
|
"const SmallVectorImpl<SDValue> &Operands) const",
|
|
|
|
OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-17 08:31:50 +08:00
|
|
|
// Emit CompletePattern matchers.
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
// FIXME: This should be const.
|
2010-03-01 06:57:03 +08:00
|
|
|
if (!ComplexPatterns.empty()) {
|
2017-11-11 02:36:04 +08:00
|
|
|
BeginEmitFunction(OS, "bool",
|
|
|
|
"CheckComplexPattern(SDNode *Root, SDNode *Parent,\n"
|
|
|
|
" SDValue N, unsigned PatternNo,\n"
|
2020-11-06 22:19:59 +08:00
|
|
|
" SmallVectorImpl<std::pair<SDValue, SDNode *>> &Result)",
|
2017-11-11 02:36:04 +08:00
|
|
|
true/*AddOverride*/);
|
|
|
|
OS << "{\n";
|
2010-06-15 06:33:34 +08:00
|
|
|
OS << " unsigned NextRes = Result.size();\n";
|
2010-03-01 06:57:03 +08:00
|
|
|
OS << " switch (PatternNo) {\n";
|
2012-02-05 15:21:30 +08:00
|
|
|
OS << " default: llvm_unreachable(\"Invalid pattern # in table?\");\n";
|
2010-03-01 06:57:03 +08:00
|
|
|
for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) {
|
|
|
|
const ComplexPattern &P = *ComplexPatterns[i];
|
|
|
|
unsigned NumOps = P.getNumOperands();
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
|
2010-03-01 06:57:03 +08:00
|
|
|
if (P.hasProperty(SDNPHasChain))
|
|
|
|
++NumOps; // Get the chained node too.
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-01 06:57:03 +08:00
|
|
|
OS << " case " << i << ":\n";
|
2017-02-15 02:32:41 +08:00
|
|
|
if (InstrumentCoverage)
|
|
|
|
OS << " {\n";
|
2010-06-15 06:33:34 +08:00
|
|
|
OS << " Result.resize(NextRes+" << NumOps << ");\n";
|
2017-02-15 02:32:41 +08:00
|
|
|
if (InstrumentCoverage)
|
|
|
|
OS << " bool Succeeded = " << P.getSelectFunc();
|
|
|
|
else
|
|
|
|
OS << " return " << P.getSelectFunc();
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
|
2010-09-22 04:31:19 +08:00
|
|
|
OS << "(";
|
|
|
|
// If the complex pattern wants the root of the match, pass it in as the
|
|
|
|
// first argument.
|
|
|
|
if (P.hasProperty(SDNPWantRoot))
|
|
|
|
OS << "Root, ";
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-09-22 04:37:12 +08:00
|
|
|
// If the complex pattern wants the parent of the operand being matched,
|
|
|
|
// pass it in as the next argument.
|
|
|
|
if (P.hasProperty(SDNPWantParent))
|
|
|
|
OS << "Parent, ";
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-09-22 04:31:19 +08:00
|
|
|
OS << "N";
|
2010-03-01 06:57:03 +08:00
|
|
|
for (unsigned i = 0; i != NumOps; ++i)
|
2010-09-22 06:00:25 +08:00
|
|
|
OS << ", Result[NextRes+" << i << "].first";
|
2010-03-01 06:57:03 +08:00
|
|
|
OS << ");\n";
|
2017-02-15 02:32:41 +08:00
|
|
|
if (InstrumentCoverage) {
|
|
|
|
OS << " if (Succeeded)\n";
|
|
|
|
OS << " dbgs() << \"\\nCOMPLEX_PATTERN: " << P.getSelectFunc()
|
|
|
|
<< "\\n\" ;\n";
|
|
|
|
OS << " return Succeeded;\n";
|
|
|
|
OS << " }\n";
|
|
|
|
}
|
2010-03-01 06:57:03 +08:00
|
|
|
}
|
|
|
|
OS << " }\n";
|
2017-11-11 02:36:04 +08:00
|
|
|
OS << "}\n";
|
|
|
|
EndEmitFunction(OS);
|
2010-02-17 08:31:50 +08:00
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
|
|
|
|
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just
needs result updating to be done (then testing, optimization
etc).
More specificallly, this adds support for chain and flag handling
on the result nodes, support for sdnodexforms, support for variadic
nodes, memrefs, pinned physreg inputs, and probably lots of other
stuff.
In the old DAGISelEmitter, this deletes the dead code related to
OperatorMap, cleans up a variety of dead stuff handling "implicit
remapping" from things like globaladdr -> targetglobaladdr (which
is no longer used because globaladdr always needs to be legalized),
and some minor formatting fixes.
llvm-svn: 96716
2010-02-21 11:22:59 +08:00
|
|
|
// Emit SDNodeXForm handlers.
|
|
|
|
// FIXME: This should be const.
|
2010-03-01 06:57:03 +08:00
|
|
|
if (!NodeXForms.empty()) {
|
2017-11-11 02:36:04 +08:00
|
|
|
BeginEmitFunction(OS, "SDValue",
|
|
|
|
"RunSDNodeXForm(SDValue V, unsigned XFormNo)", true/*AddOverride*/);
|
|
|
|
OS << "{\n";
|
2010-03-01 06:57:03 +08:00
|
|
|
OS << " switch (XFormNo) {\n";
|
2012-02-05 15:21:30 +08:00
|
|
|
OS << " default: llvm_unreachable(\"Invalid xform # in table?\");\n";
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-01 06:57:03 +08:00
|
|
|
// FIXME: The node xform could take SDValue's instead of SDNode*'s.
|
2010-03-01 09:54:19 +08:00
|
|
|
for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i) {
|
|
|
|
const CodeGenDAGPatterns::NodeXForm &Entry =
|
|
|
|
CGP.getSDNodeTransform(NodeXForms[i]);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-01 09:54:19 +08:00
|
|
|
Record *SDNode = Entry.first;
|
|
|
|
const std::string &Code = Entry.second;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << " case " << i << ": { ";
|
|
|
|
if (!OmitComments)
|
|
|
|
OS << "// " << NodeXForms[i]->getName();
|
|
|
|
OS << '\n';
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2020-01-29 03:23:46 +08:00
|
|
|
std::string ClassName =
|
|
|
|
std::string(CGP.getSDNodeInfo(SDNode).getSDClassName());
|
2010-03-01 09:54:19 +08:00
|
|
|
if (ClassName == "SDNode")
|
|
|
|
OS << " SDNode *N = V.getNode();\n";
|
|
|
|
else
|
|
|
|
OS << " " << ClassName << " *N = cast<" << ClassName
|
|
|
|
<< ">(V.getNode());\n";
|
|
|
|
OS << Code << "\n }\n";
|
|
|
|
}
|
2010-03-01 06:57:03 +08:00
|
|
|
OS << " }\n";
|
2017-11-11 02:36:04 +08:00
|
|
|
OS << "}\n";
|
|
|
|
EndEmitFunction(OS);
|
2010-03-01 06:57:03 +08:00
|
|
|
}
|
2010-02-16 15:21:10 +08:00
|
|
|
}
|
|
|
|
|
2017-09-20 05:03:57 +08:00
|
|
|
static StringRef getOpcodeString(Matcher::KindTy Kind) {
|
|
|
|
switch (Kind) {
|
|
|
|
case Matcher::Scope: return "OPC_Scope"; break;
|
|
|
|
case Matcher::RecordNode: return "OPC_RecordNode"; break;
|
|
|
|
case Matcher::RecordChild: return "OPC_RecordChild"; break;
|
|
|
|
case Matcher::RecordMemRef: return "OPC_RecordMemRef"; break;
|
|
|
|
case Matcher::CaptureGlueInput: return "OPC_CaptureGlueInput"; break;
|
|
|
|
case Matcher::MoveChild: return "OPC_MoveChild"; break;
|
|
|
|
case Matcher::MoveParent: return "OPC_MoveParent"; break;
|
|
|
|
case Matcher::CheckSame: return "OPC_CheckSame"; break;
|
|
|
|
case Matcher::CheckChildSame: return "OPC_CheckChildSame"; break;
|
|
|
|
case Matcher::CheckPatternPredicate:
|
|
|
|
return "OPC_CheckPatternPredicate"; break;
|
|
|
|
case Matcher::CheckPredicate: return "OPC_CheckPredicate"; break;
|
|
|
|
case Matcher::CheckOpcode: return "OPC_CheckOpcode"; break;
|
|
|
|
case Matcher::SwitchOpcode: return "OPC_SwitchOpcode"; break;
|
|
|
|
case Matcher::CheckType: return "OPC_CheckType"; break;
|
|
|
|
case Matcher::SwitchType: return "OPC_SwitchType"; break;
|
|
|
|
case Matcher::CheckChildType: return "OPC_CheckChildType"; break;
|
|
|
|
case Matcher::CheckInteger: return "OPC_CheckInteger"; break;
|
|
|
|
case Matcher::CheckChildInteger: return "OPC_CheckChildInteger"; break;
|
|
|
|
case Matcher::CheckCondCode: return "OPC_CheckCondCode"; break;
|
2019-02-25 11:11:44 +08:00
|
|
|
case Matcher::CheckChild2CondCode: return "OPC_CheckChild2CondCode"; break;
|
2017-09-20 05:03:57 +08:00
|
|
|
case Matcher::CheckValueType: return "OPC_CheckValueType"; break;
|
|
|
|
case Matcher::CheckComplexPat: return "OPC_CheckComplexPat"; break;
|
|
|
|
case Matcher::CheckAndImm: return "OPC_CheckAndImm"; break;
|
|
|
|
case Matcher::CheckOrImm: return "OPC_CheckOrImm"; break;
|
|
|
|
case Matcher::CheckFoldableChainNode:
|
|
|
|
return "OPC_CheckFoldableChainNode"; break;
|
2019-03-10 13:21:52 +08:00
|
|
|
case Matcher::CheckImmAllOnesV: return "OPC_CheckImmAllOnesV"; break;
|
|
|
|
case Matcher::CheckImmAllZerosV: return "OPC_CheckImmAllZerosV"; break;
|
2017-09-20 05:03:57 +08:00
|
|
|
case Matcher::EmitInteger: return "OPC_EmitInteger"; break;
|
|
|
|
case Matcher::EmitStringInteger: return "OPC_EmitStringInteger"; break;
|
|
|
|
case Matcher::EmitRegister: return "OPC_EmitRegister"; break;
|
|
|
|
case Matcher::EmitConvertToTarget: return "OPC_EmitConvertToTarget"; break;
|
|
|
|
case Matcher::EmitMergeInputChains: return "OPC_EmitMergeInputChains"; break;
|
|
|
|
case Matcher::EmitCopyToReg: return "OPC_EmitCopyToReg"; break;
|
|
|
|
case Matcher::EmitNode: return "OPC_EmitNode"; break;
|
|
|
|
case Matcher::MorphNodeTo: return "OPC_MorphNodeTo"; break;
|
|
|
|
case Matcher::EmitNodeXForm: return "OPC_EmitNodeXForm"; break;
|
|
|
|
case Matcher::CompleteMatch: return "OPC_CompleteMatch"; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Unhandled opcode?");
|
|
|
|
}
|
|
|
|
|
2010-03-04 09:34:29 +08:00
|
|
|
void MatcherTableEmitter::EmitHistogram(const Matcher *M,
|
2017-09-20 05:03:57 +08:00
|
|
|
raw_ostream &OS) {
|
2010-03-02 02:49:10 +08:00
|
|
|
if (OmitComments)
|
|
|
|
return;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 03:17:12 +08:00
|
|
|
OS << " // Opcode Histogram:\n";
|
2020-11-17 03:24:25 +08:00
|
|
|
for (unsigned i = 0, e = OpcodeCounts.size(); i != e; ++i) {
|
2017-09-20 05:03:57 +08:00
|
|
|
OS << " // #"
|
|
|
|
<< left_justify(getOpcodeString((Matcher::KindTy)i), HistOpcWidth)
|
2020-11-17 03:24:25 +08:00
|
|
|
<< " = " << OpcodeCounts[i] << '\n';
|
2010-02-25 03:17:12 +08:00
|
|
|
}
|
|
|
|
OS << '\n';
|
|
|
|
}
|
|
|
|
|
2010-02-16 15:21:10 +08:00
|
|
|
|
2020-11-17 03:24:25 +08:00
|
|
|
void llvm::EmitMatcherTable(Matcher *TheMatcher,
|
2011-03-01 09:37:19 +08:00
|
|
|
const CodeGenDAGPatterns &CGP,
|
2017-09-20 05:03:57 +08:00
|
|
|
raw_ostream &OS) {
|
2017-11-11 02:36:04 +08:00
|
|
|
OS << "#if defined(GET_DAGISEL_DECL) && defined(GET_DAGISEL_BODY)\n";
|
|
|
|
OS << "#error GET_DAGISEL_DECL and GET_DAGISEL_BODY cannot be both defined, ";
|
|
|
|
OS << "undef both for inline definitions\n";
|
|
|
|
OS << "#endif\n\n";
|
|
|
|
|
|
|
|
// Emit a check for omitted class name.
|
|
|
|
OS << "#ifdef GET_DAGISEL_BODY\n";
|
|
|
|
OS << "#define LOCAL_DAGISEL_STRINGIZE(X) LOCAL_DAGISEL_STRINGIZE_(X)\n";
|
|
|
|
OS << "#define LOCAL_DAGISEL_STRINGIZE_(X) #X\n";
|
|
|
|
OS << "static_assert(sizeof(LOCAL_DAGISEL_STRINGIZE(GET_DAGISEL_BODY)) > 1,"
|
|
|
|
"\n";
|
|
|
|
OS << " \"GET_DAGISEL_BODY is empty: it should be defined with the class "
|
|
|
|
"name\");\n";
|
|
|
|
OS << "#undef LOCAL_DAGISEL_STRINGIZE_\n";
|
|
|
|
OS << "#undef LOCAL_DAGISEL_STRINGIZE\n";
|
|
|
|
OS << "#endif\n\n";
|
|
|
|
|
|
|
|
OS << "#if !defined(GET_DAGISEL_DECL) && !defined(GET_DAGISEL_BODY)\n";
|
|
|
|
OS << "#define DAGISEL_INLINE 1\n";
|
|
|
|
OS << "#else\n";
|
|
|
|
OS << "#define DAGISEL_INLINE 0\n";
|
|
|
|
OS << "#endif\n\n";
|
|
|
|
|
|
|
|
OS << "#if !DAGISEL_INLINE\n";
|
|
|
|
OS << "#define DAGISEL_CLASS_COLONCOLON GET_DAGISEL_BODY ::\n";
|
|
|
|
OS << "#else\n";
|
|
|
|
OS << "#define DAGISEL_CLASS_COLONCOLON\n";
|
|
|
|
OS << "#endif\n\n";
|
|
|
|
|
|
|
|
BeginEmitFunction(OS, "void", "SelectCode(SDNode *N)", false/*AddOverride*/);
|
2011-03-11 10:19:02 +08:00
|
|
|
MatcherTableEmitter MatcherEmitter(CGP);
|
2010-02-16 14:52:01 +08:00
|
|
|
|
2020-11-17 03:24:25 +08:00
|
|
|
// First we size all the children of the three kinds of matchers that have
|
|
|
|
// them. This is done by sharing the code in EmitMatcher(). but we don't
|
|
|
|
// want to emit anything, so we turn off comments and use a null stream.
|
|
|
|
bool SaveOmitComments = OmitComments;
|
|
|
|
OmitComments = true;
|
|
|
|
raw_null_ostream NullOS;
|
|
|
|
unsigned TotalSize = MatcherEmitter.SizeMatcherList(TheMatcher, NullOS);
|
|
|
|
OmitComments = SaveOmitComments;
|
|
|
|
|
|
|
|
// Now that the matchers are sized, we can emit the code for them to the
|
|
|
|
// final stream.
|
2017-11-11 02:36:04 +08:00
|
|
|
OS << "{\n";
|
2011-03-01 09:37:19 +08:00
|
|
|
OS << " // Some target values are emitted as 2 bytes, TARGET_VAL handles\n";
|
|
|
|
OS << " // this.\n";
|
|
|
|
OS << " #define TARGET_VAL(X) X & 255, unsigned(X) >> 8\n";
|
2010-02-15 16:04:42 +08:00
|
|
|
OS << " static const unsigned char MatcherTable[] = {\n";
|
2020-11-17 03:24:25 +08:00
|
|
|
TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 1, 0, OS);
|
2010-02-15 16:04:42 +08:00
|
|
|
OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-04 09:34:29 +08:00
|
|
|
MatcherEmitter.EmitHistogram(TheMatcher, OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2011-03-01 09:37:19 +08:00
|
|
|
OS << " #undef TARGET_VAL\n";
|
2016-05-11 06:58:26 +08:00
|
|
|
OS << " SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n";
|
2017-11-11 02:36:04 +08:00
|
|
|
OS << "}\n";
|
|
|
|
EndEmitFunction(OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-16 15:21:10 +08:00
|
|
|
// Next up, emit the function for node and pattern predicates:
|
2010-03-29 09:40:38 +08:00
|
|
|
MatcherEmitter.EmitPredicateFunctions(OS);
|
2017-02-15 02:32:41 +08:00
|
|
|
|
|
|
|
if (InstrumentCoverage)
|
|
|
|
MatcherEmitter.EmitPatternMatchTable(OS);
|
2017-11-11 02:36:04 +08:00
|
|
|
|
|
|
|
// Clean up the preprocessor macros.
|
|
|
|
OS << "\n";
|
|
|
|
OS << "#ifdef DAGISEL_INLINE\n";
|
|
|
|
OS << "#undef DAGISEL_INLINE\n";
|
|
|
|
OS << "#endif\n";
|
|
|
|
OS << "#ifdef DAGISEL_CLASS_COLONCOLON\n";
|
|
|
|
OS << "#undef DAGISEL_CLASS_COLONCOLON\n";
|
|
|
|
OS << "#endif\n";
|
|
|
|
OS << "#ifdef GET_DAGISEL_DECL\n";
|
|
|
|
OS << "#undef GET_DAGISEL_DECL\n";
|
|
|
|
OS << "#endif\n";
|
|
|
|
OS << "#ifdef GET_DAGISEL_BODY\n";
|
|
|
|
OS << "#undef GET_DAGISEL_BODY\n";
|
|
|
|
OS << "#endif\n";
|
2010-02-15 16:04:42 +08:00
|
|
|
}
|