#include <set>
using namespace llvm;
+#define DEBUG_TYPE "dag-patterns"
+
//===----------------------------------------------------------------------===//
// EEVT::TypeSet Implementation
//===----------------------------------------------------------------------===//
return false;
for (unsigned i = 0, e = LegalTypes.size(); i != e; ++i)
- if (Pred == 0 || Pred(LegalTypes[i]))
+ if (!Pred || Pred(LegalTypes[i]))
TypeVec.push_back(LegalTypes[i]);
// If we have nothing that matches the predicate, bail out.
// specified. To get best possible pattern match we'll need to dynamically
// calculate the complexity of all patterns a dag can potentially map to.
const ComplexPattern *AM = P->getComplexPatternInfo(CGP);
- if (AM)
+ if (AM) {
Size += AM->getNumOperands() * 3;
+ // We don't want to count any children twice, so return early.
+ return Size;
+ }
+
// If this node has some predicate function that must match, it adds to the
// complexity of this node.
if (!P->getPredicateFns().empty())
// Both RegisterClass and RegisterOperand operands derive their types from a
// register class def.
- Record *RC = 0;
+ Record *RC = nullptr;
if (Operand->isSubClassOf("RegisterClass"))
RC = Operand;
else if (Operand->isSubClassOf("RegisterOperand"))
// Get the result tree.
DagInit *Tree = Operator->getValueAsDag("Fragment");
- Record *Op = 0;
+ Record *Op = nullptr;
if (Tree)
if (DefInit *DI = dyn_cast<DefInit>(Tree->getOperator()))
Op = DI->getDef();
if (Operator->isSubClassOf("ValueType"))
return 1; // A type-cast of one result.
+ if (Operator->isSubClassOf("ComplexPattern"))
+ return 1;
+
Operator->dump();
errs() << "Unhandled node in GetNumNodeResults\n";
exit(1);
/// PatFrag references.
TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
if (TP.hasError())
- return 0;
+ return nullptr;
if (isLeaf())
return this; // nothing to do.
if (Frag->getNumArgs() != Children.size()) {
TP.error("'" + Op->getName() + "' fragment requires " +
utostr(Frag->getNumArgs()) + " operands!");
- return 0;
+ return nullptr;
}
TreePatternNode *FragTree = Frag->getOnlyTree()->clone();
return EEVT::TypeSet(); // Unknown.
}
+ if (R->isSubClassOf("Operand"))
+ return EEVT::TypeSet(getValueType(R->getValueAsDef("Type")));
+
TP.error("Unknown node flavor used in pattern: " + R->getName());
return EEVT::TypeSet(MVT::Other, TP);
}
if (getOperator() != CDP.get_intrinsic_void_sdnode() &&
getOperator() != CDP.get_intrinsic_w_chain_sdnode() &&
getOperator() != CDP.get_intrinsic_wo_chain_sdnode())
- return 0;
+ return nullptr;
unsigned IID = cast<IntInit>(getChild(0)->getLeafValue())->getValue();
return &CDP.getIntrinsicInfo(IID);
/// return the ComplexPattern information, otherwise return null.
const ComplexPattern *
TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const {
- if (!isLeaf()) return 0;
+ Record *Rec;
+ if (isLeaf()) {
+ DefInit *DI = dyn_cast<DefInit>(getLeafValue());
+ if (!DI)
+ return nullptr;
+ Rec = DI->getDef();
+ } else
+ Rec = getOperator();
- DefInit *DI = dyn_cast<DefInit>(getLeafValue());
- if (DI && DI->getDef()->isSubClassOf("ComplexPattern"))
- return &CGP.getComplexPattern(DI->getDef());
- return 0;
+ if (!Rec->isSubClassOf("ComplexPattern"))
+ return nullptr;
+ return &CGP.getComplexPattern(Rec);
+}
+
+unsigned TreePatternNode::getNumMIResults(const CodeGenDAGPatterns &CGP) const {
+ // A ComplexPattern specifically declares how many results it fills in.
+ if (const ComplexPattern *CP = getComplexPatternInfo(CGP))
+ return CP->getNumOperands();
+
+ // If MIOperandInfo is specified, that gives the count.
+ if (isLeaf()) {
+ DefInit *DI = dyn_cast<DefInit>(getLeafValue());
+ if (DI && DI->getDef()->isSubClassOf("Operand")) {
+ DagInit *MIOps = DI->getDef()->getValueAsDag("MIOperandInfo");
+ if (MIOps->getNumArgs())
+ return MIOps->getNumArgs();
+ }
+ }
+
+ // Otherwise there is just one result.
+ return 1;
}
/// NodeHasProperty - Return true if this node has the specified property.
DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo");
if (unsigned NumArgs = MIOpInfo->getNumArgs()) {
// But don't do that if the whole operand is being provided by
- // a single ComplexPattern.
- const ComplexPattern *AM = Child->getComplexPatternInfo(CDP);
- if (!AM || AM->getNumOperands() < NumArgs) {
+ // a single ComplexPattern-related Operand.
+
+ if (Child->getNumMIResults(CDP) < NumArgs) {
// Match first sub-operand against the child we already have.
Record *SubRec = cast<DefInit>(MIOpInfo->getArg(0))->getDef();
MadeChange |=
return MadeChange;
}
+ if (getOperator()->isSubClassOf("ComplexPattern")) {
+ bool MadeChange = false;
+
+ for (unsigned i = 0; i < getNumChildren(); ++i)
+ MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
+
+ return MadeChange;
+ }
+
assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
// Node transforms always take one operand.
return true;
}
+ if (getOperator()->isSubClassOf("ComplexPattern"))
+ return true;
+
// If this node is a commutative operator, check that the LHS isn't an
// immediate.
const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(getOperator());
if (BitsInit *BI = dyn_cast<BitsInit>(TheInit)) {
// Turn this into an IntInit.
Init *II = BI->convertInitializerTo(IntRecTy::get());
- if (II == 0 || !isa<IntInit>(II))
+ if (!II || !isa<IntInit>(II))
error("Bits value must be constants!");
return ParseTreePattern(II, OpName);
}
!Operator->isSubClassOf("Instruction") &&
!Operator->isSubClassOf("SDNodeXForm") &&
!Operator->isSubClassOf("Intrinsic") &&
+ !Operator->isSubClassOf("ComplexPattern") &&
Operator->getName() != "set" &&
Operator->getName() != "implicit")
error("Unrecognized node '" + Operator->getName() + "'!");
Children.insert(Children.begin(), IIDNode);
}
+ if (Operator->isSubClassOf("ComplexPattern")) {
+ for (unsigned i = 0; i < Children.size(); ++i) {
+ TreePatternNode *Child = Children[i];
+
+ if (Child->getName().empty())
+ error("All arguments to a ComplexPattern must be named");
+
+ // Check that the ComplexPattern uses are consistent: "(MY_PAT $a, $b)"
+ // and "(MY_PAT $b, $a)" should not be allowed in the same pattern;
+ // neither should "(MY_PAT_1 $a, $b)" and "(MY_PAT_2 $a, $b)".
+ auto OperandId = std::make_pair(Operator, i);
+ auto PrevOp = ComplexPatternOperands.find(Child->getName());
+ if (PrevOp != ComplexPatternOperands.end()) {
+ if (PrevOp->getValue() != OperandId)
+ error("All ComplexPattern operands must appear consistently: "
+ "in the same order in just one ComplexPattern instance.");
+ } else
+ ComplexPatternOperands[Child->getName()] = OperandId;
+ }
+ }
+
unsigned NumResults = GetNumNodeResults(Operator, CDP);
TreePatternNode *Result = new TreePatternNode(Operator, Children, NumResults);
Result->setName(OpName);
return;
}
- // Get information about the SDNode for the operator.
- const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
-
// Notice properties of the node.
- if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
- if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
- if (OpInfo.hasProperty(SDNPSideEffect)) hasSideEffects = true;
- if (OpInfo.hasProperty(SDNPVariadic)) isVariadic = true;
+ if (N->NodeHasProperty(SDNPMayStore, CDP)) mayStore = true;
+ if (N->NodeHasProperty(SDNPMayLoad, CDP)) mayLoad = true;
+ if (N->NodeHasProperty(SDNPSideEffect, CDP)) hasSideEffects = true;
+ if (N->NodeHasProperty(SDNPVariadic, CDP)) isVariadic = true;
if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
// If this is an intrinsic, analyze it.
// Check that all of the results occur first in the list.
std::vector<Record*> Results;
- TreePatternNode *Res0Node = 0;
+ TreePatternNode *Res0Node = nullptr;
for (unsigned i = 0; i != NumResults; ++i) {
if (i == CGI.Operands.size())
I->error("'" + InstResults.begin()->first +
// Check that it exists in InstResults.
TreePatternNode *RNode = InstResults[OpName];
- if (RNode == 0)
+ if (!RNode)
I->error("Operand $" + OpName + " does not exist in operand list!");
if (i == 0)
Res0Node = RNode;
Record *R = cast<DefInit>(RNode->getLeafValue())->getDef();
- if (R == 0)
+ if (!R)
I->error("Operand $" + OpName + " should be a set destination: all "
"outputs must occur before inputs in operand list!");
// Promote the xform function to be an explicit node if set.
if (Record *Xform = OpNode->getTransformFn()) {
- OpNode->setTransformFn(0);
+ OpNode->setTransformFn(nullptr);
std::vector<TreePatternNode*> Children;
Children.push_back(OpNode);
OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes());
std::vector<Record*> Instrs = Records.getAllDerivedDefinitions("Instruction");
for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
- ListInit *LI = 0;
+ ListInit *LI = nullptr;
if (isa<ListInit>(Instrs[i]->getValueInit("Pattern")))
LI = Instrs[i]->getValueAsListInit("Pattern");
// Create and insert the instruction.
std::vector<Record*> ImpResults;
Instructions.insert(std::make_pair(Instrs[i],
- DAGInstruction(0, Results, Operands, ImpResults)));
+ DAGInstruction(nullptr, Results, Operands, ImpResults)));
continue; // no pattern.
}
E = Instructions.end(); II != E; ++II) {
DAGInstruction &TheInst = II->second;
TreePattern *I = TheInst.getPattern();
- if (I == 0) continue; // No pattern.
+ if (!I) continue; // No pattern.
// FIXME: Assume only the first tree is the pattern. The others are clobber
// nodes.
// they don't exist in the input pattern.
for (std::map<std::string, NameRecord>::iterator
I = DstNames.begin(), E = DstNames.end(); I != E; ++I) {
- if (SrcNames[I->first].first == 0)
+ if (SrcNames[I->first].first == nullptr)
Pattern->error("Pattern has input without matching name in output: $" +
I->first);
}
// name isn't used in the dest, and isn't used to tie two values together.
for (std::map<std::string, NameRecord>::iterator
I = SrcNames.begin(), E = SrcNames.end(); I != E; ++I)
- if (DstNames[I->first].first == 0 && SrcNames[I->first].second == 1)
+ if (DstNames[I->first].first == nullptr && SrcNames[I->first].second == 1)
Pattern->error("Pattern has dead named input: $" + I->first);
PatternsToMatch.push_back(PTM);
for (unsigned ii = 0, ee = DstPattern->getNumChildren(); ii != ee; ++ii) {
TreePatternNode *OpNode = DstPattern->getChild(ii);
if (Record *Xform = OpNode->getTransformFn()) {
- OpNode->setTransformFn(0);
+ OpNode->setTransformFn(nullptr);
std::vector<TreePatternNode*> Children;
Children.push_back(OpNode);
OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes());
std::vector<TreePatternNode*> &OutVariants,
CodeGenDAGPatterns &CDP,
const MultipleUseVarSet &DepVars) {
- // We cannot permute leaves.
- if (N->isLeaf()) {
+ // We cannot permute leaves or ComplexPattern uses.
+ if (N->isLeaf() || N->getOperator()->isSubClassOf("ComplexPattern")) {
OutVariants.push_back(N);
return;
}