diff options
Diffstat (limited to 'utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 141 |
1 files changed, 112 insertions, 29 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index aa60f87..a08cde6 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -580,34 +580,29 @@ typedef std::map<std::string, int> DepVarMap; /// 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 { @@ -621,6 +616,66 @@ void DumpDepVars(MultipleUseVarSet &DepVars) { } #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(); } //===----------------------------------------------------------------------===// @@ -1015,7 +1070,7 @@ void TreePatternNode::print(raw_ostream &OS) const { } 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()) @@ -1150,9 +1205,9 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { 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()) { @@ -2063,9 +2118,9 @@ void CodeGenDAGPatterns::ParsePatternFragments() { // 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. @@ -2288,13 +2343,14 @@ class InstAnalyzer { 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 @@ -2313,6 +2369,29 @@ public: } 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())) { @@ -2333,8 +2412,10 @@ private: 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()); @@ -2363,12 +2444,13 @@ private: 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. @@ -2714,11 +2796,12 @@ void CodeGenDAGPatterns::InferInstructionFlags() { 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; } |