//===----------------------------------------------------------------------===//
#include "CodeGenDAGPatterns.h"
+#include "Error.h"
#include "Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
/// Const iterator shorthand for DepVarMap
typedef DepVarMap::const_iterator DepVarMap_citer;
-namespace {
-void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) {
+static void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) {
if (N->isLeaf()) {
- if (dynamic_cast<DefInit*>(N->getLeafValue()) != NULL) {
+ if (dynamic_cast<DefInit*>(N->getLeafValue()) != NULL)
DepMap[N->getName()]++;
- }
} else {
for (size_t i = 0, e = N->getNumChildren(); i != e; ++i)
FindDepVarsOf(N->getChild(i), DepMap);
}
}
-
-//! Find dependent variables within child patterns
-/*!
- */
-void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) {
+
+/// Find dependent variables within child patterns
+static void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) {
DepVarMap depcounts;
FindDepVarsOf(N, depcounts);
for (DepVarMap_citer i = depcounts.begin(); i != depcounts.end(); ++i) {
- if (i->second > 1) { // std::pair<std::string, int>
+ if (i->second > 1) // std::pair<std::string, int>
DepVars.insert(i->first);
- }
}
}
-//! Dump the dependent variable set:
#ifndef NDEBUG
-void DumpDepVars(MultipleUseVarSet &DepVars) {
+/// Dump the dependent variable set:
+static void DumpDepVars(MultipleUseVarSet &DepVars) {
if (DepVars.empty()) {
DEBUG(errs() << "<empty set>");
} else {
}
#endif
+
+//===----------------------------------------------------------------------===//
+// TreePredicateFn Implementation
+//===----------------------------------------------------------------------===//
+
+/// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag.
+TreePredicateFn::TreePredicateFn(TreePattern *N) : PatFragRec(N) {
+ assert((getPredCode().empty() || getImmCode().empty()) &&
+ ".td file corrupt: can't have a node predicate *and* an imm predicate");
+}
+
+std::string TreePredicateFn::getPredCode() const {
+ return PatFragRec->getRecord()->getValueAsCode("PredicateCode");
+}
+
+std::string TreePredicateFn::getImmCode() const {
+ return PatFragRec->getRecord()->getValueAsCode("ImmediateCode");
+}
+
+
+/// isAlwaysTrue - Return true if this is a noop predicate.
+bool TreePredicateFn::isAlwaysTrue() const {
+ return getPredCode().empty() && getImmCode().empty();
+}
+
+/// Return the name to use in the generated code to reference this, this is
+/// "Predicate_foo" if from a pattern fragment "foo".
+std::string TreePredicateFn::getFnName() const {
+ return "Predicate_" + PatFragRec->getRecord()->getName();
+}
+
+/// getCodeToRunOnSDNode - Return the code for the function body that
+/// evaluates this predicate. The argument is expected to be in "Node",
+/// not N. This handles casting and conversion to a concrete node type as
+/// appropriate.
+std::string TreePredicateFn::getCodeToRunOnSDNode() const {
+ // Handle immediate predicates first.
+ std::string ImmCode = getImmCode();
+ if (!ImmCode.empty()) {
+ std::string Result =
+ " int64_t Imm = cast<ConstantSDNode>(Node)->getSExtValue();\n";
+ return Result + ImmCode;
+ }
+
+ // Handle arbitrary node predicates.
+ assert(!getPredCode().empty() && "Don't have any predicate code!");
+ std::string ClassName;
+ if (PatFragRec->getOnlyTree()->isLeaf())
+ ClassName = "SDNode";
+ else {
+ Record *Op = PatFragRec->getOnlyTree()->getOperator();
+ ClassName = PatFragRec->getDAGPatterns().getSDNodeInfo(Op).getSDClassName();
+ }
+ std::string Result;
+ if (ClassName == "SDNode")
+ Result = " SDNode *N = Node;\n";
+ else
+ Result = " " + ClassName + "*N = cast<" + ClassName + ">(Node);\n";
+
+ return Result + getPredCode();
}
//===----------------------------------------------------------------------===//
}
for (unsigned i = 0, e = PredicateFns.size(); i != e; ++i)
- OS << "<<P:" << PredicateFns[i] << ">>";
+ OS << "<<P:" << PredicateFns[i].getFnName() << ">>";
if (TransformFn)
OS << "<<X:" << TransformFn->getName() << ">>";
if (!getName().empty())
TreePatternNode *FragTree = Frag->getOnlyTree()->clone();
- std::string Code = Op->getValueAsCode("Predicate");
- if (!Code.empty())
- FragTree->addPredicateFn("Predicate_"+Op->getName());
+ TreePredicateFn PredFn(Frag);
+ if (!PredFn.isAlwaysTrue())
+ FragTree->addPredicateFn(PredFn);
// Resolve formal arguments to their actual value.
if (Frag->getNumArgs()) {
///
static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo,
bool NotRegisters, TreePattern &TP) {
+ // Check to see if this is a register operand.
+ if (R->isSubClassOf("RegisterOperand")) {
+ assert(ResNo == 0 && "Regoperand ref only has one result!");
+ if (NotRegisters)
+ return EEVT::TypeSet(); // Unknown.
+ Record *RegClass = R->getValueAsDef("RegClass");
+ const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
+ return EEVT::TypeSet(T.getRegisterClass(RegClass).getValueTypes());
+ }
+
// Check to see if this is a register or a register class.
if (R->isSubClassOf("RegisterClass")) {
assert(ResNo == 0 && "Regclass ref only has one result!");
if (ResultNode->isSubClassOf("PointerLikeRegClass")) {
MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP);
+ } else if (ResultNode->isSubClassOf("RegisterOperand")) {
+ Record *RegClass = ResultNode->getValueAsDef("RegClass");
+ const CodeGenRegisterClass &RC =
+ CDP.getTargetInfo().getRegisterClass(RegClass);
+ MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP);
} else if (ResultNode->getName() == "unknown") {
// Nothing to do.
} else {
const CodeGenRegisterClass &RC =
CDP.getTargetInfo().getRegisterClass(OperandNode);
MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP);
+ } else if (OperandNode->isSubClassOf("RegisterOperand")) {
+ Record *RegClass = OperandNode->getValueAsDef("RegClass");
+ const CodeGenRegisterClass &RC =
+ CDP.getTargetInfo().getRegisterClass(RegClass);
+ MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP);
} else if (OperandNode->isSubClassOf("Operand")) {
VT = getValueType(OperandNode->getValueAsDef("Type"));
MadeChange |= Child->UpdateNodeType(ChildResNo, VT, TP);
Record *R = DI->getDef();
// Direct reference to a leaf DagNode or PatFrag? Turn it into a
- // TreePatternNode if its own. For example:
+ // TreePatternNode of its own. For example:
/// (foo GPR, imm) -> (foo GPR, (imm))
if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag"))
return ParseTreePattern(new DagInit(DI, "",
// def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>;
if (Nodes[i] == Trees[0] && Nodes[i]->isLeaf()) {
DefInit *DI = dynamic_cast<DefInit*>(Nodes[i]->getLeafValue());
- if (DI && DI->getDef()->isSubClassOf("RegisterClass"))
+ if (DI && (DI->getDef()->isSubClassOf("RegisterClass") ||
+ DI->getDef()->isSubClassOf("RegisterOperand")))
continue;
}
// If there is a code init for this fragment, keep track of the fact that
// this fragment uses it.
- std::string Code = Fragments[i]->getValueAsCode("Predicate");
- if (!Code.empty())
- P->getOnlyTree()->addPredicateFn("Predicate_"+Fragments[i]->getName());
+ TreePredicateFn PredFn(P);
+ if (!PredFn.isAlwaysTrue())
+ P->getOnlyTree()->addPredicateFn(PredFn);
// If there is a node transformation corresponding to this, keep track of
// it.
if (Pat->getName().empty()) {
if (Pat->isLeaf()) {
DefInit *DI = dynamic_cast<DefInit*>(Pat->getLeafValue());
- if (DI && DI->getDef()->isSubClassOf("RegisterClass"))
+ if (DI && (DI->getDef()->isSubClassOf("RegisterClass") ||
+ DI->getDef()->isSubClassOf("RegisterOperand")))
I->error("Input " + DI->getDef()->getName() + " must be named!");
}
return false;
I->error("set destination should be a register!");
if (Val->getDef()->isSubClassOf("RegisterClass") ||
+ Val->getDef()->isSubClassOf("RegisterOperand") ||
Val->getDef()->isSubClassOf("PointerLikeRegClass")) {
if (Dest->getName().empty())
I->error("set destination must have a name!");
const CodeGenDAGPatterns &CDP;
bool &mayStore;
bool &mayLoad;
+ bool &IsBitcast;
bool &HasSideEffects;
bool &IsVariadic;
public:
InstAnalyzer(const CodeGenDAGPatterns &cdp,
- bool &maystore, bool &mayload, bool &hse, bool &isv)
- : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse),
- IsVariadic(isv) {
+ bool &maystore, bool &mayload, bool &isbc, bool &hse, bool &isv)
+ : CDP(cdp), mayStore(maystore), mayLoad(mayload), IsBitcast(isbc),
+ HasSideEffects(hse), IsVariadic(isv) {
}
/// Analyze - Analyze the specified instruction, returning true if the
}
private:
+ bool IsNodeBitcast(const TreePatternNode *N) const {
+ if (HasSideEffects || mayLoad || mayStore || IsVariadic)
+ return false;
+
+ if (N->getNumChildren() != 2)
+ return false;
+
+ const TreePatternNode *N0 = N->getChild(0);
+ if (!N0->isLeaf() || !dynamic_cast<DefInit*>(N0->getLeafValue()))
+ return false;
+
+ const TreePatternNode *N1 = N->getChild(1);
+ if (N1->isLeaf())
+ return false;
+ if (N1->getNumChildren() != 1 || !N1->getChild(0)->isLeaf())
+ return false;
+
+ const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N1->getOperator());
+ if (OpInfo.getNumResults() != 1 || OpInfo.getNumOperands() != 1)
+ return false;
+ return OpInfo.getEnumName() == "ISD::BITCAST";
+ }
+
void AnalyzeNode(const TreePatternNode *N) {
if (N->isLeaf()) {
if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
AnalyzeNode(N->getChild(i));
// Ignore set nodes, which are not SDNodes.
- if (N->getOperator()->getName() == "set")
+ if (N->getOperator()->getName() == "set") {
+ IsBitcast = IsNodeBitcast(N);
return;
+ }
// Get information about the SDNode for the operator.
const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
static void InferFromPattern(const CodeGenInstruction &Inst,
bool &MayStore, bool &MayLoad,
+ bool &IsBitcast,
bool &HasSideEffects, bool &IsVariadic,
const CodeGenDAGPatterns &CDP) {
- MayStore = MayLoad = HasSideEffects = IsVariadic = false;
+ MayStore = MayLoad = IsBitcast = HasSideEffects = IsVariadic = false;
bool HadPattern =
- InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects, IsVariadic)
+ InstAnalyzer(CDP, MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic)
.Analyze(Inst.TheDef);
// InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
CodeGenInstruction &InstInfo =
const_cast<CodeGenInstruction &>(*Instructions[i]);
// Determine properties of the instruction from its pattern.
- bool MayStore, MayLoad, HasSideEffects, IsVariadic;
- InferFromPattern(InstInfo, MayStore, MayLoad, HasSideEffects, IsVariadic,
- *this);
+ bool MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic;
+ InferFromPattern(InstInfo, MayStore, MayLoad, IsBitcast,
+ HasSideEffects, IsVariadic, *this);
InstInfo.mayStore = MayStore;
InstInfo.mayLoad = MayLoad;
+ InstInfo.isBitcast = IsBitcast;
InstInfo.hasSideEffects = HasSideEffects;
InstInfo.Operands.isVariadic = IsVariadic;
}