From: Daniel Sanders Date: Tue, 31 Oct 2017 23:03:18 +0000 (+0000) Subject: Re-commit: [globalisel][tablegen] Keep track of the insertion point while adding... X-Git-Tag: android-x86-7.1-r4~9085 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b7e9d79775950e125976271ebbd7a4fcf0fa740d;p=android-x86%2Fexternal-llvm.git Re-commit: [globalisel][tablegen] Keep track of the insertion point while adding BuildMIAction's. NFC Multi-instruction emission needs to ensure the the instructions are generated a depth-first fashion. For example: (ADDWrr (SUBWrr a, b), c) needs to emit the SUBWrr before the ADDWrr. However, our walk over TreePatternNode's is highly context sensitive which makes it difficult to append BuildMIActions in the order we want. To fix this, we now keep track of the insertion point as we add actions. This will allow multi-insn emission to insert BuildMI's in the correct place. The previous commit failed on the Ubuntu bots using GCC 4.8. These bots lack the const_iterator forms of insert() and emplace() that were added in C++11. As a result I've switched the const_iterators to iterators. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317049 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp index 9a38d925278..f8ccded6feb 100644 --- a/utils/TableGen/GlobalISelEmitter.cpp +++ b/utils/TableGen/GlobalISelEmitter.cpp @@ -517,6 +517,11 @@ class MatchAction; /// Generates code to check that a match rule matches. class RuleMatcher { +public: + using ActionVec = std::vector>; + using action_iterator = ActionVec::iterator; + +protected: /// A list of matchers that all need to succeed for the current rule to match. /// FIXME: This currently supports a single match position but could be /// extended to support multiple positions to support div/rem fusion or @@ -525,7 +530,7 @@ class RuleMatcher { /// A list of actions that need to be taken when all predicates in this rule /// have succeeded. - std::vector> Actions; + ActionVec Actions; using DefinedInsnVariablesMap = std::map; @@ -571,6 +576,8 @@ public: const std::vector &getRequiredFeatures() const; template Kind &addAction(Args &&... args); + template + action_iterator insertAction(action_iterator InsertPt, Args &&... args); /// Define an instruction without emitting any code to do so. /// This is used for the root of the match. @@ -606,6 +613,12 @@ public: (void)R; } + action_iterator actions_begin() { return Actions.begin(); } + action_iterator actions_end() { return Actions.end(); } + iterator_range actions() { + return make_range(actions_begin(), actions_end()); + } + void defineOperand(StringRef SymbolicName, OperandMatcher &OM); void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern, @@ -642,6 +655,8 @@ public: InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); } }; +using action_iterator = RuleMatcher::action_iterator; + template class PredicateListMatcher { private: typedef std::vector> PredicateVec; @@ -1942,11 +1957,30 @@ const std::vector &RuleMatcher::getRequiredFeatures() const { return RequiredFeatures; } +// Emplaces an action of the specified Kind at the end of the action list. +// +// Returns a reference to the newly created action. +// +// Like std::vector::emplace_back(), may invalidate all iterators if the new +// size exceeds the capacity. Otherwise, only invalidates the past-the-end +// iterator. template Kind &RuleMatcher::addAction(Args &&... args) { Actions.emplace_back(llvm::make_unique(std::forward(args)...)); return *static_cast(Actions.back().get()); } +// Emplaces an action of the specified Kind before the given insertion point. +// +// Returns an iterator pointing at the newly created instruction. +// +// Like std::vector::insert(), may invalidate all iterators if the new size +// exceeds the capacity. Otherwise, only invalidates the iterators from the +// insertion point onwards. +template +action_iterator RuleMatcher::insertAction(action_iterator InsertPt, + Args &&... args) { + return Actions.insert(InsertPt, llvm::make_unique(std::forward(args)...)); +} unsigned RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) { @@ -2225,15 +2259,18 @@ private: Expected createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst); - Expected - createInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst); + Expected + createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M, + const TreePatternNode *Dst); void importExplicitDefRenderers(BuildMIAction &DstMIBuilder); - Expected - importExplicitUseRenderers(RuleMatcher &M, BuildMIAction &DstMIBuilder, + Expected + importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M, + BuildMIAction &DstMIBuilder, const llvm::TreePatternNode *Dst); - Error importExplicitUseRenderer(RuleMatcher &Rule, - BuildMIAction &DstMIBuilder, - TreePatternNode *DstChild) const; + Expected + importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule, + BuildMIAction &DstMIBuilder, + TreePatternNode *DstChild) const; Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const; Error @@ -2563,8 +2600,8 @@ Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule, return failedImport("Src pattern child is an unsupported kind"); } -Error GlobalISelEmitter::importExplicitUseRenderer( - RuleMatcher &Rule, BuildMIAction &DstMIBuilder, +Expected GlobalISelEmitter::importExplicitUseRenderer( + action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, TreePatternNode *DstChild) const { if (DstChild->getTransformFn() != nullptr) { return failedImport("Dst pattern child has transform fn " + @@ -2576,7 +2613,7 @@ Error GlobalISelEmitter::importExplicitUseRenderer( DstMIBuilder.addRenderer( 0, *std::get<0>(*SubOperand), DstChild->getName(), std::get<1>(*SubOperand), std::get<2>(*SubOperand)); - return Error::success(); + return InsertPt; } if (!DstChild->isLeaf()) { @@ -2586,7 +2623,7 @@ Error GlobalISelEmitter::importExplicitUseRenderer( auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator()); if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") { DstMIBuilder.addRenderer(0, DstChild->getName()); - return Error::success(); + return InsertPt; } } @@ -2597,11 +2634,11 @@ Error GlobalISelEmitter::importExplicitUseRenderer( if (DstChild->getOperator()->getName() == "imm") { DstMIBuilder.addRenderer(0, DstChild->getName()); - return Error::success(); + return InsertPt; } else if (DstChild->getOperator()->getName() == "fpimm") { DstMIBuilder.addRenderer( 0, DstChild->getName()); - return Error::success(); + return InsertPt; } return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild)); @@ -2623,7 +2660,7 @@ Error GlobalISelEmitter::importExplicitUseRenderer( if (ChildRec->isSubClassOf("Register")) { DstMIBuilder.addRenderer(0, ChildRec); - return Error::success(); + return InsertPt; } if (ChildRec->isSubClassOf("RegisterClass") || @@ -2633,11 +2670,11 @@ Error GlobalISelEmitter::importExplicitUseRenderer( !ChildRec->isValueUnset("GIZeroRegister")) { DstMIBuilder.addRenderer( 0, DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister")); - return Error::success(); + return InsertPt; } DstMIBuilder.addRenderer(0, DstChild->getName()); - return Error::success(); + return InsertPt; } if (ChildRec->isSubClassOf("ComplexPattern")) { @@ -2650,7 +2687,7 @@ Error GlobalISelEmitter::importExplicitUseRenderer( DstMIBuilder.addRenderer( 0, *ComplexPattern->second, DstChild->getName(), OM.getAllocatedTemporariesBaseID()); - return Error::success(); + return InsertPt; } if (ChildRec->isSubClassOf("SDNodeXForm")) @@ -2666,22 +2703,24 @@ Error GlobalISelEmitter::importExplicitUseRenderer( Expected GlobalISelEmitter::createAndImportInstructionRenderer( RuleMatcher &M, const TreePatternNode *Dst) { - auto DstMIBuilderOrError = createInstructionRenderer(M, Dst); - if (auto Error = DstMIBuilderOrError.takeError()) + auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst); + if (auto Error = InsertPtOrError.takeError()) return std::move(Error); - BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get(); + action_iterator InsertPt = InsertPtOrError.get(); + BuildMIAction &DstMIBuilder = *static_cast(InsertPt->get()); importExplicitDefRenderers(DstMIBuilder); - if (auto Error = importExplicitUseRenderers(M, DstMIBuilder, Dst).takeError()) + if (auto Error = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst) + .takeError()) return std::move(Error); return DstMIBuilder; } -Expected GlobalISelEmitter::createInstructionRenderer( - RuleMatcher &M, const TreePatternNode *Dst) { +Expected GlobalISelEmitter::createInstructionRenderer( + action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst) { Record *DstOp = Dst->getOperator(); if (!DstOp->isSubClassOf("Instruction")) { if (DstOp->isSubClassOf("ValueType")) @@ -2698,9 +2737,9 @@ Expected GlobalISelEmitter::createInstructionRenderer( else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") DstI = &Target.getInstruction(RK.getDef("COPY")); - auto &DstMIBuilder = M.addAction(0, DstI); + InsertPt = M.insertAction(InsertPt, 0, DstI); - return DstMIBuilder; + return InsertPt; } void GlobalISelEmitter::importExplicitDefRenderers( @@ -2712,8 +2751,8 @@ void GlobalISelEmitter::importExplicitDefRenderers( } } -Expected GlobalISelEmitter::importExplicitUseRenderers( - RuleMatcher &M, BuildMIAction &DstMIBuilder, +Expected GlobalISelEmitter::importExplicitUseRenderers( + action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder, const llvm::TreePatternNode *Dst) { const CodeGenInstruction *DstI = DstMIBuilder.getCGI(); CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator()); @@ -2739,7 +2778,7 @@ Expected GlobalISelEmitter::importExplicitUseRenderers( DstMIBuilder.addRenderer( 0, Dst->getChild(0)->getName(), SubIdx); - return DstMIBuilder; + return InsertPt; } return failedImport("EXTRACT_SUBREG child #1 is not a subreg index"); @@ -2772,9 +2811,11 @@ Expected GlobalISelEmitter::importExplicitUseRenderers( continue; } - if (auto Error = - importExplicitUseRenderer(M, DstMIBuilder, Dst->getChild(Child))) + auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder, + Dst->getChild(Child)); + if (auto Error = InsertPtOrError.takeError()) return std::move(Error); + InsertPt = InsertPtOrError.get(); ++Child; } @@ -2785,7 +2826,7 @@ Expected GlobalISelEmitter::importExplicitUseRenderers( " explicit ones and " + llvm::to_string(NumDefaultOps) + " default ones"); - return DstMIBuilder; + return InsertPt; } Error GlobalISelEmitter::importDefaultOperandRenderers(