-//===- CodegenDAGPatterns.cpp - Read DAG patterns from .td file -----------===//
+//===- CodeGenDAGPatterns.cpp - Read DAG patterns from .td file -----------===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
//
-// This file implements the CodegenDAGPatterns class, which is used to read and
+// This file implements the CodeGenDAGPatterns class, which is used to read and
// represent the patterns present in a .td file for instructions.
//
//===----------------------------------------------------------------------===//
-#include "CodegenDAGPatterns.h"
+#include "CodeGenDAGPatterns.h"
#include "Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
-//#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Streams.h"
-//#include <algorithm>
#include <set>
+#include <algorithm>
using namespace llvm;
//===----------------------------------------------------------------------===//
ConstraintType = SDTCisIntVectorOfSameSize;
x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum =
R->getValueAsInt("OtherOpNum");
+ } else if (R->isSubClassOf("SDTCisEltOfVec")) {
+ ConstraintType = SDTCisEltOfVec;
+ x.SDTCisEltOfVec_Info.OtherOperandNum =
+ R->getValueAsInt("OtherOpNum");
} else {
cerr << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n";
exit(1);
}
return false;
}
+ case SDTCisEltOfVec: {
+ TreePatternNode *OtherOperand =
+ getOperandNum(x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum,
+ N, NumResults);
+ if (OtherOperand->hasTypeSet()) {
+ if (!MVT::isVector(OtherOperand->getTypeNum(0)))
+ TP.error(N->getOperator()->getName() + " VT operand must be a vector!");
+ MVT::ValueType IVT = OtherOperand->getTypeNum(0);
+ IVT = MVT::getVectorElementType(IVT);
+ return NodeToApply->UpdateNodeType(IVT, TP);
+ }
+ return false;
+ }
}
return false;
}
Properties |= 1 << SDNPInFlag;
} else if (PropList[i]->getName() == "SDNPOptInFlag") {
Properties |= 1 << SDNPOptInFlag;
+ } else if (PropList[i]->getName() == "SDNPMayStore") {
+ Properties |= 1 << SDNPMayStore;
+ } else if (PropList[i]->getName() == "SDNPMayLoad") {
+ Properties |= 1 << SDNPMayLoad;
+ } else if (PropList[i]->getName() == "SDNPSideEffect") {
+ Properties |= 1 << SDNPSideEffect;
} else {
cerr << "Unknown SD Node property '" << PropList[i]->getName()
<< "' on node '" << R->getName() << "'!\n";
return Other;
}
+
+/// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
+/// CodeGenIntrinsic information for it, otherwise return a null pointer.
+const CodeGenIntrinsic *TreePatternNode::
+getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const {
+ if (getOperator() != CDP.get_intrinsic_void_sdnode() &&
+ getOperator() != CDP.get_intrinsic_w_chain_sdnode() &&
+ getOperator() != CDP.get_intrinsic_wo_chain_sdnode())
+ return 0;
+
+ unsigned IID =
+ dynamic_cast<IntInit*>(getChild(0)->getLeafValue())->getValue();
+ return &CDP.getIntrinsicInfo(IID);
+}
+
+
/// ApplyTypeConstraints - Apply all of the type constraints relevent to
/// this node and its children in the tree. This returns true if it makes a
/// change, false otherwise. If a type contradiction is found, throw an
/// exception.
bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
- CodegenDAGPatterns &CDP = TP.getDAGPatterns();
+ CodeGenDAGPatterns &CDP = TP.getDAGPatterns();
if (isLeaf()) {
if (DefInit *DI = dynamic_cast<DefInit*>(getLeafValue())) {
// If it's a regclass or something else known, include the type.
MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
MadeChange |= UpdateNodeType(MVT::isVoid, TP);
return MadeChange;
- } else if (getOperator() == CDP.get_intrinsic_void_sdnode() ||
- getOperator() == CDP.get_intrinsic_w_chain_sdnode() ||
- getOperator() == CDP.get_intrinsic_wo_chain_sdnode()) {
- unsigned IID =
- dynamic_cast<IntInit*>(getChild(0)->getLeafValue())->getValue();
- const CodeGenIntrinsic &Int = CDP.getIntrinsicInfo(IID);
+ } else if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
bool MadeChange = false;
// Apply the result type to the node.
- MadeChange = UpdateNodeType(Int.ArgVTs[0], TP);
+ MadeChange = UpdateNodeType(Int->ArgVTs[0], TP);
- if (getNumChildren() != Int.ArgVTs.size())
- TP.error("Intrinsic '" + Int.Name + "' expects " +
- utostr(Int.ArgVTs.size()-1) + " operands, not " +
+ if (getNumChildren() != Int->ArgVTs.size())
+ TP.error("Intrinsic '" + Int->Name + "' expects " +
+ utostr(Int->ArgVTs.size()-1) + " operands, not " +
utostr(getNumChildren()-1) + " operands!");
// Apply type info to the intrinsic ID.
MadeChange |= getChild(0)->UpdateNodeType(MVT::iPTR, TP);
for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
- MVT::ValueType OpVT = Int.ArgVTs[i];
+ MVT::ValueType OpVT = Int->ArgVTs[i];
MadeChange |= getChild(i)->UpdateNodeType(OpVT, TP);
MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
}
/// that can never possibly work), and to prevent the pattern permuter from
/// generating stuff that is useless.
bool TreePatternNode::canPatternMatch(std::string &Reason,
- CodegenDAGPatterns &CDP){
+ CodeGenDAGPatterns &CDP){
if (isLeaf()) return true;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
//
TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput,
- CodegenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
+ CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
isInputPattern = isInput;
for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i)
Trees.push_back(ParseTreePattern((DagInit*)RawPat->getElement(i)));
}
TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput,
- CodegenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
+ CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
isInputPattern = isInput;
Trees.push_back(ParseTreePattern(Pat));
}
TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
- CodegenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
+ CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){
isInputPattern = isInput;
Trees.push_back(Pat);
}
void TreePattern::dump() const { print(*cerr.stream()); }
//===----------------------------------------------------------------------===//
-// CodegenDAGPatterns implementation
+// CodeGenDAGPatterns implementation
//
// FIXME: REMOVE OSTREAM ARGUMENT
-CodegenDAGPatterns::CodegenDAGPatterns(RecordKeeper &R) : Records(R) {
+CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
Intrinsics = LoadIntrinsics(Records);
ParseNodeInfo();
ParseNodeTransforms();
GenerateVariants();
}
-CodegenDAGPatterns::~CodegenDAGPatterns() {
+CodeGenDAGPatterns::~CodeGenDAGPatterns() {
for (std::map<Record*, TreePattern*>::iterator I = PatternFragments.begin(),
E = PatternFragments.end(); I != E; ++I)
delete I->second;
}
-Record *CodegenDAGPatterns::getSDNodeNamed(const std::string &Name) const {
+Record *CodeGenDAGPatterns::getSDNodeNamed(const std::string &Name) const {
Record *N = Records.getDef(Name);
if (!N || !N->isSubClassOf("SDNode")) {
cerr << "Error getting SDNode '" << Name << "'!\n";
}
// Parse all of the SDNode definitions for the target, populating SDNodes.
-void CodegenDAGPatterns::ParseNodeInfo() {
+void CodeGenDAGPatterns::ParseNodeInfo() {
std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("SDNode");
while (!Nodes.empty()) {
SDNodes.insert(std::make_pair(Nodes.back(), Nodes.back()));
/// ParseNodeTransforms - Parse all SDNodeXForm instances into the SDNodeXForms
/// map, and emit them to the file as functions.
-void CodegenDAGPatterns::ParseNodeTransforms() {
+void CodeGenDAGPatterns::ParseNodeTransforms() {
std::vector<Record*> Xforms = Records.getAllDerivedDefinitions("SDNodeXForm");
while (!Xforms.empty()) {
Record *XFormNode = Xforms.back();
}
}
-void CodegenDAGPatterns::ParseComplexPatterns() {
+void CodeGenDAGPatterns::ParseComplexPatterns() {
std::vector<Record*> AMs = Records.getAllDerivedDefinitions("ComplexPattern");
while (!AMs.empty()) {
ComplexPatterns.insert(std::make_pair(AMs.back(), AMs.back()));
/// inline fragments together as necessary, so that there are no references left
/// inside a pattern fragment to a pattern fragment.
///
-void CodegenDAGPatterns::ParsePatternFragments() {
+void CodeGenDAGPatterns::ParsePatternFragments() {
std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrag");
// First step, parse all of the fragments.
}
}
-void CodegenDAGPatterns::ParseDefaultOperands() {
+void CodeGenDAGPatterns::ParseDefaultOperands() {
std::vector<Record*> DefaultOps[2];
DefaultOps[0] = Records.getAllDerivedDefinitions("PredicateOperand");
DefaultOps[1] = Records.getAllDerivedDefinitions("OptionalDefOperand");
/// FindPatternInputsAndOutputs - Scan the specified TreePatternNode (which is
/// part of "I", the instruction), computing the set of inputs and outputs of
/// the pattern. Report errors if we see anything naughty.
-void CodegenDAGPatterns::
+void CodeGenDAGPatterns::
FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
std::map<std::string, TreePatternNode*> &InstInputs,
std::map<std::string, TreePatternNode*>&InstResults,
/// ParseInstructions - Parse all of the instructions, inlining and resolving
/// any fragments involved. This populates the Instructions list with fully
/// resolved instructions.
-void CodegenDAGPatterns::ParseInstructions() {
+void CodeGenDAGPatterns::ParseInstructions() {
std::vector<Record*> Instrs = Records.getAllDerivedDefinitions("Instruction");
for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
for (std::map<Record*, DAGInstruction>::iterator II = Instructions.begin(),
E = Instructions.end(); II != E; ++II) {
DAGInstruction &TheInst = II->second;
- TreePattern *I = TheInst.getPattern();
+ const TreePattern *I = TheInst.getPattern();
if (I == 0) continue; // No pattern.
// FIXME: Assume only the first tree is the pattern. The others are clobber
}
}
-void CodegenDAGPatterns::ParsePatterns() {
+void CodeGenDAGPatterns::ParsePatterns() {
std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern");
for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
static void CombineChildVariants(TreePatternNode *Orig,
const std::vector<std::vector<TreePatternNode*> > &ChildVariants,
std::vector<TreePatternNode*> &OutVariants,
- CodegenDAGPatterns &CDP) {
+ CodeGenDAGPatterns &CDP) {
// Make sure that each operand has at least one variant to choose from.
for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i)
if (ChildVariants[i].empty())
const std::vector<TreePatternNode*> &LHS,
const std::vector<TreePatternNode*> &RHS,
std::vector<TreePatternNode*> &OutVariants,
- CodegenDAGPatterns &CDP) {
+ CodeGenDAGPatterns &CDP) {
std::vector<std::vector<TreePatternNode*> > ChildVariants;
ChildVariants.push_back(LHS);
ChildVariants.push_back(RHS);
///
static void GenerateVariantsOf(TreePatternNode *N,
std::vector<TreePatternNode*> &OutVariants,
- CodegenDAGPatterns &CDP) {
+ CodeGenDAGPatterns &CDP) {
// We cannot permute leaves.
if (N->isLeaf()) {
OutVariants.push_back(N);
// GenerateVariants - Generate variants. For example, commutative patterns can
// match multiple ways. Add them to PatternsToMatch as well.
-void CodegenDAGPatterns::GenerateVariants() {
+void CodeGenDAGPatterns::GenerateVariants() {
DOUT << "Generating instruction variants.\n";
// Loop over all of the patterns we've collected, checking to see if we can