2010-02-15 16:04:42 +08:00
|
|
|
//===- DAGISelMatcherEmitter.cpp - Matcher Emitter ------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
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"
|
2010-02-15 16:04:42 +08:00
|
|
|
#include "llvm/Support/FormattedStream.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"
|
2010-02-15 16:04:42 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
enum {
|
2010-02-17 08:39:26 +08:00
|
|
|
CommentIndent = 30
|
2010-02-15 16:04:42 +08:00
|
|
|
};
|
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
// To reduce generated source code size.
|
|
|
|
static cl::opt<bool>
|
|
|
|
OmitComments("omit-comments", cl::desc("Do not generate comments"),
|
|
|
|
cl::init(false));
|
|
|
|
|
2017-02-15 02:32:41 +08:00
|
|
|
static cl::opt<bool> InstrumentCoverage(
|
|
|
|
"instrument-coverage",
|
|
|
|
cl::desc("Generates tables to help identify patterns matched"),
|
|
|
|
cl::init(false));
|
|
|
|
|
2010-02-16 14:52:01 +08:00
|
|
|
namespace {
|
|
|
|
class MatcherTableEmitter {
|
2010-03-29 09:40:38 +08:00
|
|
|
const CodeGenDAGPatterns &CGP;
|
2011-04-18 05:38:24 +08:00
|
|
|
|
|
|
|
DenseMap<TreePattern *, unsigned> NodePredicateMap;
|
|
|
|
std::vector<TreePredicateFn> NodePredicates;
|
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;
|
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:
|
2011-03-11 10:19:02 +08:00
|
|
|
MatcherTableEmitter(const CodeGenDAGPatterns &cgp)
|
|
|
|
: CGP(cgp) {}
|
2010-02-16 14:52:01 +08:00
|
|
|
|
2010-02-25 10:04:40 +08:00
|
|
|
unsigned EmitMatcherList(const Matcher *N, unsigned Indent,
|
2010-02-21 15:16:41 +08:00
|
|
|
unsigned StartIdx, formatted_raw_ostream &OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-29 09:40:38 +08:00
|
|
|
void EmitPredicateFunctions(formatted_raw_ostream &OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-04 09:34:29 +08:00
|
|
|
void EmitHistogram(const Matcher *N, formatted_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:
|
2010-02-26 03:00:39 +08:00
|
|
|
unsigned EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
2010-02-21 14:30:04 +08:00
|
|
|
formatted_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.
|
|
|
|
NodePredicates.push_back(Pred);
|
|
|
|
Entry = NodePredicates.size();
|
|
|
|
} else {
|
|
|
|
// We did see an identical predicate: re-use it.
|
|
|
|
Entry = NodePredicateMap[SameCodePreds.front()];
|
|
|
|
assert(Entry != 0);
|
|
|
|
}
|
|
|
|
// 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;
|
|
|
|
}
|
2011-04-18 05:38:24 +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;
|
|
|
|
}
|
|
|
|
|
2010-02-26 03:00:39 +08:00
|
|
|
static unsigned GetVBRSize(unsigned Val) {
|
|
|
|
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.
|
2010-03-01 06:14:32 +08:00
|
|
|
static uint64_t 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;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
|
|
|
OS << "StringRef getPatternForIndex(unsigned Index) override {\n";
|
|
|
|
OS << "static const char * PATTERN_MATCH_TABLE[] = {\n";
|
|
|
|
|
|
|
|
for (const auto &It : VecPatterns) {
|
|
|
|
OS << "\"" << It.first << "\",\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
OS << "\n};";
|
|
|
|
OS << "\nreturn StringRef(PATTERN_MATCH_TABLE[Index]);";
|
|
|
|
OS << "\n}";
|
|
|
|
|
|
|
|
OS << "\nStringRef getIncludePathForIndex(unsigned Index) override {\n";
|
|
|
|
OS << "static const char * INCLUDE_PATH_TABLE[] = {\n";
|
|
|
|
|
|
|
|
for (const auto &It : VecIncludeStrings) {
|
|
|
|
OS << "\"" << It << "\",\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
OS << "\n};";
|
|
|
|
OS << "\nreturn StringRef(INCLUDE_PATH_TABLE[Index]);";
|
|
|
|
OS << "\n}";
|
|
|
|
}
|
|
|
|
|
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::
|
2010-02-26 03:00:39 +08:00
|
|
|
EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
|
|
|
formatted_raw_ostream &OS) {
|
2010-02-15 16:04:42 +08:00
|
|
|
OS.PadToColumn(Indent*2);
|
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);
|
2014-04-15 15:20:03 +08:00
|
|
|
assert(SM->getNext() == nullptr && "Shouldn't have next after scope");
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-26 03:00:39 +08:00
|
|
|
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) {
|
|
|
|
OS << "/*" << CurrentIdx << "*/";
|
|
|
|
OS.PadToColumn(Indent*2) << "/*Scope*/ ";
|
|
|
|
} else
|
|
|
|
OS.PadToColumn(Indent*2);
|
2010-02-26 03:00:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// We need to encode the child and the offset of the failure code before
|
|
|
|
// emitting either of them. Handle this by buffering the output into a
|
|
|
|
// string while we get the size. Unfortunately, the offset of the
|
|
|
|
// children depends on the VBR size of the child, so for large children we
|
|
|
|
// have to iterate a bit.
|
|
|
|
SmallString<128> TmpBuf;
|
|
|
|
unsigned ChildSize = 0;
|
|
|
|
unsigned VBRSize = 0;
|
|
|
|
do {
|
|
|
|
VBRSize = GetVBRSize(ChildSize);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-26 03:00:39 +08:00
|
|
|
TmpBuf.clear();
|
|
|
|
raw_svector_ostream OS(TmpBuf);
|
|
|
|
formatted_raw_ostream FOS(OS);
|
2010-03-01 14:59:22 +08:00
|
|
|
ChildSize = EmitMatcherList(SM->getChild(i), Indent+1,
|
|
|
|
CurrentIdx+VBRSize, FOS);
|
2010-02-26 03:00:39 +08:00
|
|
|
} while (GetVBRSize(ChildSize) != VBRSize);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-26 03:00:39 +08:00
|
|
|
assert(ChildSize != 0 && "Should not have a zero-sized child!");
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-26 03:00:39 +08:00
|
|
|
CurrentIdx += EmitVBRValue(ChildSize, OS);
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments) {
|
|
|
|
OS << "/*->" << CurrentIdx+ChildSize << "*/";
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
if (i == 0)
|
|
|
|
OS.PadToColumn(CommentIndent) << "// " << SM->getNumChildren()
|
|
|
|
<< " children in Scope";
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2015-03-10 15:33:23 +08:00
|
|
|
OS << '\n' << TmpBuf;
|
2010-02-26 03:00:39 +08:00
|
|
|
CurrentIdx += ChildSize;
|
|
|
|
}
|
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)
|
|
|
|
OS << "/*" << CurrentIdx << "*/";
|
|
|
|
OS.PadToColumn(Indent*2) << "0, ";
|
|
|
|
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)
|
|
|
|
OS.PadToColumn(CommentIndent) << "// #"
|
|
|
|
<< cast<RecordMatcher>(N)->getResultNo() << " = "
|
|
|
|
<< cast<RecordMatcher>(N)->getWhatFor();
|
|
|
|
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)
|
|
|
|
OS.PadToColumn(CommentIndent) << "// #"
|
|
|
|
<< cast<RecordChildMatcher>(N)->getResultNo() << " = "
|
|
|
|
<< cast<RecordChildMatcher>(N)->getWhatFor();
|
|
|
|
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)
|
|
|
|
OS.PadToColumn(CommentIndent) << "// " << Pred;
|
|
|
|
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();
|
2010-02-16 15:21:10 +08:00
|
|
|
OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2011-04-18 05:38:24 +08:00
|
|
|
OS.PadToColumn(CommentIndent) << "// " << Pred.getFnName();
|
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::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-01 14:59:22 +08:00
|
|
|
// We need to encode the opcode and the offset of the case code before
|
|
|
|
// emitting the case code. Handle this by buffering the output into a
|
|
|
|
// string while we get the size. Unfortunately, the offset of the
|
|
|
|
// children depends on the VBR size of the child, so for large children we
|
|
|
|
// have to iterate a bit.
|
|
|
|
SmallString<128> TmpBuf;
|
|
|
|
unsigned ChildSize = 0;
|
|
|
|
unsigned VBRSize = 0;
|
|
|
|
do {
|
|
|
|
VBRSize = GetVBRSize(ChildSize);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-01 14:59:22 +08:00
|
|
|
TmpBuf.clear();
|
|
|
|
raw_svector_ostream OS(TmpBuf);
|
|
|
|
formatted_raw_ostream FOS(OS);
|
2010-03-28 02:49:33 +08:00
|
|
|
ChildSize = EmitMatcherList(Child, Indent+1, CurrentIdx+VBRSize+IdxSize,
|
|
|
|
FOS);
|
2010-03-01 14:59:22 +08:00
|
|
|
} while (GetVBRSize(ChildSize) != VBRSize);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-01 14:59:22 +08:00
|
|
|
assert(ChildSize != 0 && "Should not have a zero-sized child!");
|
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)
|
|
|
|
OS << "/*" << CurrentIdx << "*/";
|
2010-03-02 02:49:10 +08:00
|
|
|
OS.PadToColumn(Indent*2);
|
|
|
|
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
|
|
|
|
2010-03-01 14:59:22 +08:00
|
|
|
// Emit the VBR.
|
|
|
|
CurrentIdx += EmitVBRValue(ChildSize, OS);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
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-28 02:49:33 +08:00
|
|
|
|
|
|
|
CurrentIdx += IdxSize;
|
|
|
|
|
2010-03-02 02:49:10 +08:00
|
|
|
if (!OmitComments)
|
2010-03-25 14:33:05 +08:00
|
|
|
OS << "// ->" << CurrentIdx+ChildSize;
|
2010-03-02 02:49:10 +08:00
|
|
|
OS << '\n';
|
2015-03-10 15:33:23 +08:00
|
|
|
OS << TmpBuf;
|
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)
|
|
|
|
OS << "/*" << CurrentIdx << "*/";
|
2010-03-02 02:49:10 +08:00
|
|
|
OS.PadToColumn(Indent*2) << "0, ";
|
|
|
|
if (!OmitComments)
|
2010-03-03 14:28:15 +08:00
|
|
|
OS << (isa<SwitchOpcodeMatcher>(N) ?
|
|
|
|
"// EndSwitchOpcode" : "// EndSwitchType");
|
|
|
|
|
2010-03-02 03:00:55 +08:00
|
|
|
OS << '\n';
|
2010-03-01 14:59:22 +08:00
|
|
|
++CurrentIdx;
|
|
|
|
return CurrentIdx-StartIdx;
|
|
|
|
}
|
|
|
|
|
2010-03-01 15:17:40 +08:00
|
|
|
case Matcher::CheckType:
|
2010-03-24 08:41:19 +08:00
|
|
|
assert(cast<CheckTypeMatcher>(N)->getResNo() == 0 &&
|
|
|
|
"FIXME: Add support for CheckType of resno != 0");
|
2010-02-15 16:04:42 +08:00
|
|
|
OS << "OPC_CheckType, "
|
2010-02-25 10:04:40 +08:00
|
|
|
<< getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
|
2010-02-15 16:04:42 +08:00
|
|
|
return 2;
|
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, ";
|
2010-03-02 08:13:03 +08:00
|
|
|
unsigned Bytes=1+EmitVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);
|
|
|
|
OS << '\n';
|
|
|
|
return Bytes;
|
|
|
|
}
|
2014-02-05 13:44:28 +08:00
|
|
|
case Matcher::CheckChildInteger: {
|
|
|
|
OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo()
|
|
|
|
<< "Integer, ";
|
|
|
|
unsigned Bytes=1+EmitVBRValue(cast<CheckChildIntegerMatcher>(N)->getValue(),
|
|
|
|
OS);
|
|
|
|
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
|
|
|
|
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) {
|
|
|
|
OS.PadToColumn(CommentIndent) << "// " << 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
|
|
|
|
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();
|
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
|
|
|
// These should always fit into one byte.
|
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();
|
|
|
|
}
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::EmitCopyToReg:
|
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_EmitCopyToReg, "
|
2010-02-25 10:04:40 +08:00
|
|
|
<< cast<EmitCopyToRegMatcher>(N)->getSrcSlot() << ", "
|
|
|
|
<< getQualifiedName(cast<EmitCopyToRegMatcher>(N)->getDestPhysReg())
|
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
|
|
|
<< ",\n";
|
|
|
|
return 3;
|
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)
|
|
|
|
OS.PadToColumn(CommentIndent) << "// "<<XF->getNodeXForm()->getName();
|
|
|
|
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";
|
|
|
|
OS.PadToColumn(Indent * 2);
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
|
2016-05-03 13:54:13 +08:00
|
|
|
OS.PadToColumn(Indent*2+4);
|
|
|
|
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()) {
|
2012-07-19 06:41:03 +08:00
|
|
|
OS.PadToColumn(CommentIndent) << "// 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)) {
|
|
|
|
OS.PadToColumn(Indent*2) << "// 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';
|
2010-03-02 02:49:10 +08:00
|
|
|
OS.PadToColumn(Indent*2) << "// Dst: "
|
|
|
|
<< *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";
|
|
|
|
OS.PadToColumn(Indent * 2);
|
|
|
|
}
|
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) {
|
|
|
|
OS.PadToColumn(Indent*2) << "// 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';
|
2010-03-02 02:49:10 +08:00
|
|
|
OS.PadToColumn(Indent*2) << "// Dst: "
|
|
|
|
<< *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
|
|
|
}
|
|
|
|
|
2010-02-18 10:53:41 +08:00
|
|
|
/// EmitMatcherList - Emit the bytes for the specified matcher subtree.
|
2010-02-16 14:52:01 +08:00
|
|
|
unsigned MatcherTableEmitter::
|
2010-02-25 10:04:40 +08:00
|
|
|
EmitMatcherList(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
|
2010-02-21 14:30:04 +08:00
|
|
|
formatted_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)
|
|
|
|
OS << "/*" << CurrentIdx << "*/";
|
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
|
|
|
}
|
|
|
|
|
2010-03-29 09:40:38 +08:00
|
|
|
void MatcherTableEmitter::EmitPredicateFunctions(formatted_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()) {
|
2014-03-09 15:44:38 +08:00
|
|
|
OS << "bool CheckPatternPredicate(unsigned PredNo) const override {\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";
|
|
|
|
OS << "}\n\n";
|
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-17 08:31:50 +08:00
|
|
|
// Emit Node predicates.
|
2010-03-01 06:57:03 +08:00
|
|
|
if (!NodePredicates.empty()) {
|
2014-03-09 15:44:38 +08:00
|
|
|
OS << "bool CheckNodePredicate(SDNode *Node,\n";
|
|
|
|
OS << " unsigned PredNo) const override {\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 09:54:19 +08:00
|
|
|
for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) {
|
|
|
|
// Emit the predicate code corresponding to this pattern.
|
2011-04-18 05:38:24 +08:00
|
|
|
TreePredicateFn PredFn = NodePredicates[i];
|
|
|
|
|
|
|
|
assert(!PredFn.isAlwaysTrue() && "No code in this predicate");
|
2015-08-28 04:43:34 +08:00
|
|
|
OS << " case " << i << ": { \n";
|
|
|
|
for (auto *SimilarPred :
|
|
|
|
NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()])
|
|
|
|
OS << " // " << TreePredicateFn(SimilarPred).getFnName() <<'\n';
|
2011-04-18 05:38:24 +08:00
|
|
|
|
|
|
|
OS << PredFn.getCodeToRunOnSDNode() << "\n }\n";
|
2010-03-01 09:54:19 +08:00
|
|
|
}
|
2010-03-01 06:57:03 +08:00
|
|
|
OS << " }\n";
|
|
|
|
OS << "}\n\n";
|
|
|
|
}
|
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()) {
|
2014-03-09 15:44:38 +08:00
|
|
|
OS << "bool CheckComplexPattern(SDNode *Root, SDNode *Parent,\n";
|
|
|
|
OS << " SDValue N, unsigned PatternNo,\n";
|
|
|
|
OS << " SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) override {\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";
|
|
|
|
OS << "}\n\n";
|
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()) {
|
2014-03-09 15:44:38 +08:00
|
|
|
OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) override {\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
|
|
|
|
2010-03-01 09:54:19 +08:00
|
|
|
std::string ClassName = CGP.getSDNodeInfo(SDNode).getSDClassName();
|
|
|
|
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";
|
|
|
|
OS << "}\n\n";
|
|
|
|
}
|
2010-02-16 15:21:10 +08:00
|
|
|
}
|
|
|
|
|
2010-03-04 09:34:29 +08:00
|
|
|
static void BuildHistogram(const Matcher *M, std::vector<unsigned> &OpcodeFreq){
|
2014-04-15 15:20:03 +08:00
|
|
|
for (; M != nullptr; M = M->getNext()) {
|
2010-03-04 09:34:29 +08:00
|
|
|
// Count this node.
|
|
|
|
if (unsigned(M->getKind()) >= OpcodeFreq.size())
|
|
|
|
OpcodeFreq.resize(M->getKind()+1);
|
|
|
|
OpcodeFreq[M->getKind()]++;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-04 09:34:29 +08:00
|
|
|
// Handle recursive nodes.
|
|
|
|
if (const ScopeMatcher *SM = dyn_cast<ScopeMatcher>(M)) {
|
|
|
|
for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i)
|
|
|
|
BuildHistogram(SM->getChild(i), OpcodeFreq);
|
2011-03-01 09:39:05 +08:00
|
|
|
} else if (const SwitchOpcodeMatcher *SOM =
|
2010-03-04 09:34:29 +08:00
|
|
|
dyn_cast<SwitchOpcodeMatcher>(M)) {
|
|
|
|
for (unsigned i = 0, e = SOM->getNumCases(); i != e; ++i)
|
|
|
|
BuildHistogram(SOM->getCaseMatcher(i), OpcodeFreq);
|
|
|
|
} else if (const SwitchTypeMatcher *STM = dyn_cast<SwitchTypeMatcher>(M)) {
|
|
|
|
for (unsigned i = 0, e = STM->getNumCases(); i != e; ++i)
|
|
|
|
BuildHistogram(STM->getCaseMatcher(i), OpcodeFreq);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MatcherTableEmitter::EmitHistogram(const Matcher *M,
|
|
|
|
formatted_raw_ostream &OS) {
|
2010-03-02 02:49:10 +08:00
|
|
|
if (OmitComments)
|
|
|
|
return;
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-04 09:34:29 +08:00
|
|
|
std::vector<unsigned> OpcodeFreq;
|
|
|
|
BuildHistogram(M, OpcodeFreq);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-25 03:17:12 +08:00
|
|
|
OS << " // Opcode Histogram:\n";
|
2010-03-04 09:34:29 +08:00
|
|
|
for (unsigned i = 0, e = OpcodeFreq.size(); i != e; ++i) {
|
2010-02-25 03:17:12 +08:00
|
|
|
OS << " // #";
|
2010-02-25 10:04:40 +08:00
|
|
|
switch ((Matcher::KindTy)i) {
|
2011-03-01 09:39:05 +08:00
|
|
|
case Matcher::Scope: OS << "OPC_Scope"; break;
|
|
|
|
case Matcher::RecordNode: OS << "OPC_RecordNode"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::RecordChild: OS << "OPC_RecordChild"; break;
|
|
|
|
case Matcher::RecordMemRef: OS << "OPC_RecordMemRef"; break;
|
2010-12-24 01:24:32 +08:00
|
|
|
case Matcher::CaptureGlueInput: OS << "OPC_CaptureGlueInput"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::MoveChild: OS << "OPC_MoveChild"; break;
|
|
|
|
case Matcher::MoveParent: OS << "OPC_MoveParent"; break;
|
|
|
|
case Matcher::CheckSame: OS << "OPC_CheckSame"; break;
|
2013-10-05 13:38:16 +08:00
|
|
|
case Matcher::CheckChildSame: OS << "OPC_CheckChildSame"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckPatternPredicate:
|
2010-02-25 03:17:12 +08:00
|
|
|
OS << "OPC_CheckPatternPredicate"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckPredicate: OS << "OPC_CheckPredicate"; break;
|
|
|
|
case Matcher::CheckOpcode: OS << "OPC_CheckOpcode"; break;
|
2010-03-01 14:59:22 +08:00
|
|
|
case Matcher::SwitchOpcode: OS << "OPC_SwitchOpcode"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckType: OS << "OPC_CheckType"; break;
|
2010-03-03 14:28:15 +08:00
|
|
|
case Matcher::SwitchType: OS << "OPC_SwitchType"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckChildType: OS << "OPC_CheckChildType"; break;
|
|
|
|
case Matcher::CheckInteger: OS << "OPC_CheckInteger"; break;
|
2014-02-05 13:44:28 +08:00
|
|
|
case Matcher::CheckChildInteger: OS << "OPC_CheckChildInteger"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::CheckCondCode: OS << "OPC_CheckCondCode"; break;
|
|
|
|
case Matcher::CheckValueType: OS << "OPC_CheckValueType"; break;
|
|
|
|
case Matcher::CheckComplexPat: OS << "OPC_CheckComplexPat"; break;
|
|
|
|
case Matcher::CheckAndImm: OS << "OPC_CheckAndImm"; break;
|
|
|
|
case Matcher::CheckOrImm: OS << "OPC_CheckOrImm"; break;
|
|
|
|
case Matcher::CheckFoldableChainNode:
|
2010-02-25 03:17:12 +08:00
|
|
|
OS << "OPC_CheckFoldableChainNode"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::EmitInteger: OS << "OPC_EmitInteger"; break;
|
|
|
|
case Matcher::EmitStringInteger: OS << "OPC_EmitStringInteger"; break;
|
|
|
|
case Matcher::EmitRegister: OS << "OPC_EmitRegister"; break;
|
2010-02-25 10:09:00 +08:00
|
|
|
case Matcher::EmitConvertToTarget: OS << "OPC_EmitConvertToTarget"; break;
|
|
|
|
case Matcher::EmitMergeInputChains: OS << "OPC_EmitMergeInputChains"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::EmitCopyToReg: OS << "OPC_EmitCopyToReg"; break;
|
|
|
|
case Matcher::EmitNode: OS << "OPC_EmitNode"; break;
|
2010-03-01 04:55:18 +08:00
|
|
|
case Matcher::MorphNodeTo: OS << "OPC_MorphNodeTo"; break;
|
2010-02-25 10:04:40 +08:00
|
|
|
case Matcher::EmitNodeXForm: OS << "OPC_EmitNodeXForm"; break;
|
2011-03-01 09:39:05 +08:00
|
|
|
case Matcher::CompleteMatch: OS << "OPC_CompleteMatch"; break;
|
2010-02-25 03:17:12 +08:00
|
|
|
}
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-03-04 09:34:29 +08:00
|
|
|
OS.PadToColumn(40) << " = " << OpcodeFreq[i] << '\n';
|
2010-02-25 03:17:12 +08:00
|
|
|
}
|
|
|
|
OS << '\n';
|
|
|
|
}
|
|
|
|
|
2010-02-16 15:21:10 +08:00
|
|
|
|
2010-03-01 09:54:19 +08:00
|
|
|
void llvm::EmitMatcherTable(const Matcher *TheMatcher,
|
2011-03-01 09:37:19 +08:00
|
|
|
const CodeGenDAGPatterns &CGP,
|
|
|
|
raw_ostream &O) {
|
2010-02-15 16:04:42 +08:00
|
|
|
formatted_raw_ostream OS(O);
|
2011-03-01 09:39:05 +08:00
|
|
|
|
2010-02-15 16:04:42 +08:00
|
|
|
OS << "// The main instruction selector code.\n";
|
2010-02-24 15:35:09 +08:00
|
|
|
OS << "SDNode *SelectCode(SDNode *N) {\n";
|
2010-02-15 16:04:42 +08:00
|
|
|
|
2011-03-11 10:19:02 +08:00
|
|
|
MatcherTableEmitter MatcherEmitter(CGP);
|
2010-02-16 14:52:01 +08:00
|
|
|
|
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";
|
2014-01-30 14:42:52 +08:00
|
|
|
unsigned TotalSize = MatcherEmitter.EmitMatcherList(TheMatcher, 6, 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";
|
|
|
|
OS << " return nullptr;\n";
|
|
|
|
OS << "}\n";
|
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);
|
2010-02-15 16:04:42 +08:00
|
|
|
}
|