using namespace llvm;
//===----------------------------------------------------------------------===//
-// DAGISelEmitter implementation
+// DAGISelEmitter Helper methods
//
-
/// NodeIsComplexPattern - return true if N is a leaf node and a subclass of
/// ComplexPattern.
static bool NodeIsComplexPattern(TreePatternNode *N) {
/// NodeGetComplexPattern - return the pointer to the ComplexPattern if N
/// is a leaf node and a subclass of ComplexPattern, else it returns NULL.
static const ComplexPattern *NodeGetComplexPattern(TreePatternNode *N,
- CodegenDAGPatterns &CGP) {
+ CodeGenDAGPatterns &CGP) {
if (N->isLeaf() &&
dynamic_cast<DefInit*>(N->getLeafValue()) &&
static_cast<DefInit*>(N->getLeafValue())->getDef()->
/// getPatternSize - Return the 'size' of this pattern. We want to match large
/// patterns before small ones. This is used to determine the size of a
/// pattern.
-static unsigned getPatternSize(TreePatternNode *P, CodegenDAGPatterns &CGP) {
+static unsigned getPatternSize(TreePatternNode *P, CodeGenDAGPatterns &CGP) {
assert((MVT::isExtIntegerInVTs(P->getExtTypes()) ||
MVT::isExtFloatingPointInVTs(P->getExtTypes()) ||
P->getExtTypeNum(0) == MVT::isVoid ||
/// This is a temporary hack. We should really include the instruction
/// latencies in this calculation.
static unsigned getResultPatternCost(TreePatternNode *P,
- CodegenDAGPatterns &CGP) {
+ CodeGenDAGPatterns &CGP) {
if (P->isLeaf()) return 0;
unsigned Cost = 0;
/// getResultPatternCodeSize - Compute the code size of instructions for this
/// pattern.
static unsigned getResultPatternSize(TreePatternNode *P,
- CodegenDAGPatterns &CGP) {
+ CodeGenDAGPatterns &CGP) {
if (P->isLeaf()) return 0;
unsigned Cost = 0;
// In particular, we want to match maximal patterns first and lowest cost within
// a particular complexity first.
struct PatternSortingPredicate {
- PatternSortingPredicate(CodegenDAGPatterns &cgp) : CGP(cgp) {}
- CodegenDAGPatterns &CGP;
+ PatternSortingPredicate(CodeGenDAGPatterns &cgp) : CGP(cgp) {}
+ CodeGenDAGPatterns &CGP;
- bool operator()(PatternToMatch *LHS,
- PatternToMatch *RHS) {
+ bool operator()(const PatternToMatch *LHS,
+ const PatternToMatch *RHS) {
unsigned LHSSize = getPatternSize(LHS->getSrcPattern(), CGP);
unsigned RHSSize = getPatternSize(RHS->getSrcPattern(), CGP);
LHSSize += LHS->getAddedComplexity();
/// NodeHasProperty - return true if TreePatternNode has the specified
/// property.
static bool NodeHasProperty(TreePatternNode *N, SDNP Property,
- CodegenDAGPatterns &CGP) {
+ CodeGenDAGPatterns &CGP) {
if (N->isLeaf()) {
const ComplexPattern *CP = NodeGetComplexPattern(N, CGP);
if (CP)
}
static bool PatternHasProperty(TreePatternNode *N, SDNP Property,
- CodegenDAGPatterns &CGP) {
+ CodeGenDAGPatterns &CGP) {
if (NodeHasProperty(N, Property, CGP))
return true;
return false;
}
+//===----------------------------------------------------------------------===//
+// Node Transformation emitter implementation.
+//
+void DAGISelEmitter::EmitNodeTransforms(std::ostream &OS) {
+ // Walk the pattern fragments, adding them to a map, which sorts them by
+ // name.
+ typedef std::map<std::string, CodeGenDAGPatterns::NodeXForm> NXsByNameTy;
+ NXsByNameTy NXsByName;
+
+ for (CodeGenDAGPatterns::nx_iterator I = CGP.nx_begin(), E = CGP.nx_end();
+ I != E; ++I)
+ NXsByName.insert(std::make_pair(I->first->getName(), I->second));
+
+ OS << "\n// Node transformations.\n";
+
+ for (NXsByNameTy::iterator I = NXsByName.begin(), E = NXsByName.end();
+ I != E; ++I) {
+ Record *SDNode = I->second.first;
+ std::string Code = I->second.second;
+
+ if (Code.empty()) continue; // Empty code? Skip it.
+
+ std::string ClassName = CGP.getSDNodeInfo(SDNode).getSDClassName();
+ const char *C2 = ClassName == "SDNode" ? "N" : "inN";
+
+ OS << "inline SDOperand Transform_" << I->first << "(SDNode *" << C2
+ << ") {\n";
+ if (ClassName != "SDNode")
+ OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
+ OS << Code << "\n}\n";
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Predicate emitter implementation.
+//
+
+void DAGISelEmitter::EmitPredicateFunctions(std::ostream &OS) {
+ OS << "\n// Predicate functions.\n";
+
+ // Walk the pattern fragments, adding them to a map, which sorts them by
+ // name.
+ typedef std::map<std::string, std::pair<Record*, TreePattern*> > PFsByNameTy;
+ PFsByNameTy PFsByName;
+
+ for (CodeGenDAGPatterns::pf_iterator I = CGP.pf_begin(), E = CGP.pf_end();
+ I != E; ++I)
+ PFsByName.insert(std::make_pair(I->first->getName(), *I));
+
+
+ for (PFsByNameTy::iterator I = PFsByName.begin(), E = PFsByName.end();
+ I != E; ++I) {
+ Record *PatFragRecord = I->second.first;// Record that derives from PatFrag.
+ TreePattern *P = I->second.second;
+
+ // If there is a code init for this fragment, emit the predicate code.
+ std::string Code = PatFragRecord->getValueAsCode("Predicate");
+ if (Code.empty()) continue;
+
+ if (P->getOnlyTree()->isLeaf())
+ OS << "inline bool Predicate_" << PatFragRecord->getName()
+ << "(SDNode *N) {\n";
+ else {
+ std::string ClassName =
+ CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName();
+ const char *C2 = ClassName == "SDNode" ? "N" : "inN";
+
+ OS << "inline bool Predicate_" << PatFragRecord->getName()
+ << "(SDNode *" << C2 << ") {\n";
+ if (ClassName != "SDNode")
+ OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
+ }
+ OS << Code << "\n}\n";
+ }
+
+ OS << "\n\n";
+}
+
+
+//===----------------------------------------------------------------------===//
+// PatternCodeEmitter implementation.
+//
class PatternCodeEmitter {
private:
- CodegenDAGPatterns &CGP;
+ CodeGenDAGPatterns &CGP;
// Predicates.
ListInit *Predicates;
VTNo++;
}
public:
- PatternCodeEmitter(CodegenDAGPatterns &cgp, ListInit *preds,
+ PatternCodeEmitter(CodeGenDAGPatterns &cgp, ListInit *preds,
TreePatternNode *pattern, TreePatternNode *instr,
std::vector<std::pair<unsigned, std::string> > &gc,
std::set<std::string> &gd,
/// EmitCodeForPattern - Given a pattern to match, emit code to the specified
/// stream to match the pattern, and generate the code for the match if it
/// succeeds. Returns true if the pattern is not guaranteed to match.
-void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern,
+void DAGISelEmitter::GenerateCodeForPattern(const PatternToMatch &Pattern,
std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
std::set<std::string> &GeneratedDecl,
std::vector<std::string> &TargetOpcodes,
std::vector<std::string> &TargetVTs) {
- PatternCodeEmitter Emitter(*CGP, Pattern.getPredicates(),
+ PatternCodeEmitter Emitter(CGP, Pattern.getPredicates(),
Pattern.getSrcPattern(), Pattern.getDstPattern(),
GeneratedCode, GeneratedDecl,
TargetOpcodes, TargetVTs);
Emitter.EmitMatchCode(Pattern.getSrcPattern(), NULL, "N", "", FoundChain);
// TP - Get *SOME* tree pattern, we don't care which.
- TreePattern &TP = *CGP->pf_begin()->second;
+ TreePattern &TP = *CGP.pf_begin()->second;
// At this point, we know that we structurally match the pattern, but the
// types of the nodes may not match. Figure out the fewest number of type
/// EraseCodeLine - Erase one code line from all of the patterns. If removing
/// a line causes any of them to be empty, remove them and return true when
/// done.
-static bool EraseCodeLine(std::vector<std::pair<PatternToMatch*,
+static bool EraseCodeLine(std::vector<std::pair<const PatternToMatch*,
std::vector<std::pair<unsigned, std::string> > > >
&Patterns) {
bool ErasedPatterns = false;
/// EmitPatterns - Emit code for at least one pattern, but try to group common
/// code together between the patterns.
-void DAGISelEmitter::EmitPatterns(std::vector<std::pair<PatternToMatch*,
+void DAGISelEmitter::EmitPatterns(std::vector<std::pair<const PatternToMatch*,
std::vector<std::pair<unsigned, std::string> > > >
&Patterns, unsigned Indent,
std::ostream &OS) {
typedef std::pair<unsigned, std::string> CodeLine;
typedef std::vector<CodeLine> CodeList;
- typedef std::vector<std::pair<PatternToMatch*, CodeList> > PatternList;
+ typedef std::vector<std::pair<const PatternToMatch*, CodeList> > PatternList;
if (Patterns.empty()) return;
// FIXME: Emit braces?
if (Shared.size() == 1) {
- PatternToMatch &Pattern = *Shared.back().first;
+ const PatternToMatch &Pattern = *Shared.back().first;
OS << "\n" << std::string(Indent, ' ') << "// Pattern: ";
Pattern.getSrcPattern()->print(OS);
OS << "\n" << std::string(Indent, ' ') << "// Emits: ";
OS << "\n";
unsigned AddedComplexity = Pattern.getAddedComplexity();
OS << std::string(Indent, ' ') << "// Pattern complexity = "
- << getPatternSize(Pattern.getSrcPattern(), *CGP) + AddedComplexity
+ << getPatternSize(Pattern.getSrcPattern(), CGP) + AddedComplexity
<< " cost = "
- << getResultPatternCost(Pattern.getDstPattern(), *CGP)
+ << getResultPatternCost(Pattern.getDstPattern(), CGP)
<< " size = "
- << getResultPatternSize(Pattern.getDstPattern(), *CGP) << "\n";
+ << getResultPatternSize(Pattern.getDstPattern(), CGP) << "\n";
}
if (FirstCodeLine.first != 1) {
OS << std::string(Indent, ' ') << "{\n";
}
if (Other.size() == 1) {
- PatternToMatch &Pattern = *Other.back().first;
+ const PatternToMatch &Pattern = *Other.back().first;
OS << "\n" << std::string(Indent, ' ') << "// Pattern: ";
Pattern.getSrcPattern()->print(OS);
OS << "\n" << std::string(Indent, ' ') << "// Emits: ";
OS << "\n";
unsigned AddedComplexity = Pattern.getAddedComplexity();
OS << std::string(Indent, ' ') << "// Pattern complexity = "
- << getPatternSize(Pattern.getSrcPattern(), *CGP) + AddedComplexity
+ << getPatternSize(Pattern.getSrcPattern(), CGP) + AddedComplexity
<< " cost = "
- << getResultPatternCost(Pattern.getDstPattern(), *CGP)
+ << getResultPatternCost(Pattern.getDstPattern(), CGP)
<< " size = "
- << getResultPatternSize(Pattern.getDstPattern(), *CGP) << "\n";
+ << getResultPatternSize(Pattern.getDstPattern(), CGP) << "\n";
}
EmitPatterns(Other, Indent, OS);
return;
OS << std::string(Indent-2, ' ') << "}\n";
}
-static std::string getOpcodeName(Record *Op, CodegenDAGPatterns &CGP) {
+static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
return CGP.getSDNodeInfo(Op).getEnumName();
}
}
void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
- const CodeGenTarget &Target = CGP->getTargetInfo();
+ const CodeGenTarget &Target = CGP.getTargetInfo();
// Get the namespace to insert instructions into. Make sure not to pick up
// "TargetInstrInfo" by accidentally getting the namespace off the PHI
if (!InstNS.empty()) InstNS += "::";
// Group the patterns by their top-level opcodes.
- std::map<std::string, std::vector<PatternToMatch*> > PatternsByOpcode;
+ std::map<std::string, std::vector<const PatternToMatch*> > PatternsByOpcode;
// All unique target node emission functions.
std::map<std::string, unsigned> EmitFunctions;
- for (CodegenDAGPatterns::ptm_iterator I = CGP->ptm_begin(),
- E = CGP->ptm_end(); I != E; ++I) {
- PatternToMatch &Pattern = *I;
+ for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
+ E = CGP.ptm_end(); I != E; ++I) {
+ const PatternToMatch &Pattern = *I;
TreePatternNode *Node = Pattern.getSrcPattern();
if (!Node->isLeaf()) {
- PatternsByOpcode[getOpcodeName(Node->getOperator(), *CGP)].
+ PatternsByOpcode[getOpcodeName(Node->getOperator(), CGP)].
push_back(&Pattern);
} else {
const ComplexPattern *CP;
if (dynamic_cast<IntInit*>(Node->getLeafValue())) {
- PatternsByOpcode[getOpcodeName(CGP->getSDNodeNamed("imm"), *CGP)].
+ PatternsByOpcode[getOpcodeName(CGP.getSDNodeNamed("imm"), CGP)].
push_back(&Pattern);
- } else if ((CP = NodeGetComplexPattern(Node, *CGP))) {
+ } else if ((CP = NodeGetComplexPattern(Node, CGP))) {
std::vector<Record*> OpNodes = CP->getRootNodes();
for (unsigned j = 0, e = OpNodes.size(); j != e; j++) {
- PatternsByOpcode[getOpcodeName(OpNodes[j], *CGP)]
- .insert(PatternsByOpcode[getOpcodeName(OpNodes[j], *CGP)].begin(),
+ PatternsByOpcode[getOpcodeName(OpNodes[j], CGP)]
+ .insert(PatternsByOpcode[getOpcodeName(OpNodes[j], CGP)].begin(),
&Pattern);
}
} else {
// Emit one Select_* method for each top-level opcode. We do this instead of
// emitting one giant switch statement to support compilers where this will
// result in the recursive functions taking less stack space.
- for (std::map<std::string, std::vector<PatternToMatch*> >::iterator
+ for (std::map<std::string, std::vector<const PatternToMatch*> >::iterator
PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end();
PBOI != E; ++PBOI) {
const std::string &OpName = PBOI->first;
- std::vector<PatternToMatch*> &PatternsOfOp = PBOI->second;
+ std::vector<const PatternToMatch*> &PatternsOfOp = PBOI->second;
assert(!PatternsOfOp.empty() && "No patterns but map has entry?");
// We want to emit all of the matching code now. However, we want to emit
// the matches in order of minimal cost. Sort the patterns so the least
// cost one is at the start.
std::stable_sort(PatternsOfOp.begin(), PatternsOfOp.end(),
- PatternSortingPredicate(*CGP));
+ PatternSortingPredicate(CGP));
// Split them into groups by type.
- std::map<MVT::ValueType, std::vector<PatternToMatch*> > PatternsByType;
+ std::map<MVT::ValueType, std::vector<const PatternToMatch*> >PatternsByType;
for (unsigned i = 0, e = PatternsOfOp.size(); i != e; ++i) {
- PatternToMatch *Pat = PatternsOfOp[i];
+ const PatternToMatch *Pat = PatternsOfOp[i];
TreePatternNode *SrcPat = Pat->getSrcPattern();
MVT::ValueType VT = SrcPat->getTypeNum(0);
- std::map<MVT::ValueType, std::vector<PatternToMatch*> >::iterator TI =
+ std::map<MVT::ValueType,
+ std::vector<const PatternToMatch*> >::iterator TI =
PatternsByType.find(VT);
if (TI != PatternsByType.end())
TI->second.push_back(Pat);
else {
- std::vector<PatternToMatch*> PVec;
+ std::vector<const PatternToMatch*> PVec;
PVec.push_back(Pat);
PatternsByType.insert(std::make_pair(VT, PVec));
}
}
- for (std::map<MVT::ValueType, std::vector<PatternToMatch*> >::iterator
+ for (std::map<MVT::ValueType, std::vector<const PatternToMatch*> >::iterator
II = PatternsByType.begin(), EE = PatternsByType.end(); II != EE;
++II) {
MVT::ValueType OpVT = II->first;
- std::vector<PatternToMatch*> &Patterns = II->second;
+ std::vector<const PatternToMatch*> &Patterns = II->second;
typedef std::vector<std::pair<unsigned,std::string> > CodeList;
typedef std::vector<std::pair<unsigned,std::string> >::iterator CodeListI;
- std::vector<std::pair<PatternToMatch*, CodeList> > CodeForPatterns;
+ std::vector<std::pair<const PatternToMatch*, CodeList> > CodeForPatterns;
std::vector<std::vector<std::string> > PatternOpcodes;
std::vector<std::vector<std::string> > PatternVTs;
std::vector<std::set<std::string> > PatternDecls;
// Loop over all of the case statements, emiting a call to each method we
// emitted above.
- for (std::map<std::string, std::vector<PatternToMatch*> >::iterator
+ for (std::map<std::string, std::vector<const PatternToMatch*> >::iterator
PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end();
PBOI != E; ++PBOI) {
const std::string &OpName = PBOI->first;
}
void DAGISelEmitter::run(std::ostream &OS) {
- CodeGenTarget Target;
- EmitSourceFileHeader("DAG Instruction Selector for the " + Target.getName() +
- " target", OS);
+ EmitSourceFileHeader("DAG Instruction Selector for the " +
+ CGP.getTargetInfo().getName() + " target", OS);
OS << "// *** NOTE: This file is #included into the middle of the target\n"
<< "// *** instruction selector class. These functions are really "
OS << " return Dummy.getValue();\n";
OS << "}\n";
- CodegenDAGPatterns CGP(Records, OS);
-
- this->CGP = &CGP;
+ EmitNodeTransforms(OS);
+ EmitPredicateFunctions(OS);
DOUT << "\n\nALL PATTERNS TO MATCH:\n\n";
- for (CodegenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end();
+ for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end();
I != E; ++I) {
DOUT << "PATTERN: "; DEBUG(I->getSrcPattern()->dump());
DOUT << "\nRESULT: "; DEBUG(I->getDstPattern()->dump());