/// Generates code to check that a match rule matches.
class RuleMatcher {
+public:
+ using ActionVec = std::vector<std::unique_ptr<MatchAction>>;
+ using const_action_iterator = ActionVec::const_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
/// A list of actions that need to be taken when all predicates in this rule
/// have succeeded.
- std::vector<std::unique_ptr<MatchAction>> Actions;
+ ActionVec Actions;
using DefinedInsnVariablesMap =
std::map<const InstructionMatcher *, unsigned>;
const std::vector<Record *> &getRequiredFeatures() const;
template <class Kind, class... Args> Kind &addAction(Args &&... args);
+ template <class Kind, class... Args>
+ const_action_iterator insertAction(const_action_iterator InsertPt,
+ Args &&... args);
/// Define an instruction without emitting any code to do so.
/// This is used for the root of the match.
(void)R;
}
+ const_action_iterator actions_begin() const { return Actions.begin(); }
+ const_action_iterator actions_end() const { return Actions.end(); }
+ iterator_range<const_action_iterator> actions() const {
+ return make_range(actions_begin(), actions_end());
+ }
+
void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
};
+using const_action_iterator = RuleMatcher::const_action_iterator;
+
template <class PredicateTy> class PredicateListMatcher {
private:
typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
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 <class Kind, class... Args>
Kind &RuleMatcher::addAction(Args &&... args) {
Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
return *static_cast<Kind *>(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::emplace(), may invalidate all iterators if the new size
+// exceeds the capacity. Otherwise, only invalidates the iterators from the
+// insertion point onwards.
+template <class Kind, class... Args>
+const_action_iterator RuleMatcher::insertAction(const_action_iterator InsertPt,
+ Args &&... args) {
+ return Actions.emplace(InsertPt, llvm::make_unique<Kind>(std::forward<Args>(args)...));
+}
unsigned
RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
Expected<BuildMIAction &>
createAndImportInstructionRenderer(RuleMatcher &M,
const TreePatternNode *Dst);
- Expected<BuildMIAction &>
- createInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst);
+ Expected<const_action_iterator>
+ createInstructionRenderer(const_action_iterator InsertPt, RuleMatcher &M,
+ const TreePatternNode *Dst);
void importExplicitDefRenderers(BuildMIAction &DstMIBuilder);
- Expected<BuildMIAction &>
- importExplicitUseRenderers(RuleMatcher &M, BuildMIAction &DstMIBuilder,
+ Expected<const_action_iterator>
+ importExplicitUseRenderers(const_action_iterator InsertPt, RuleMatcher &M,
+ BuildMIAction &DstMIBuilder,
const llvm::TreePatternNode *Dst);
- Error importExplicitUseRenderer(RuleMatcher &Rule,
- BuildMIAction &DstMIBuilder,
- TreePatternNode *DstChild) const;
+ Expected<const_action_iterator>
+ importExplicitUseRenderer(const_action_iterator InsertPt, RuleMatcher &Rule,
+ BuildMIAction &DstMIBuilder,
+ TreePatternNode *DstChild) const;
Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
DagInit *DefaultOps) const;
Error
return failedImport("Src pattern child is an unsupported kind");
}
-Error GlobalISelEmitter::importExplicitUseRenderer(
- RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
- TreePatternNode *DstChild) const {
+Expected<const_action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
+ const_action_iterator InsertPt, RuleMatcher &Rule,
+ BuildMIAction &DstMIBuilder, TreePatternNode *DstChild) const {
if (DstChild->getTransformFn() != nullptr) {
return failedImport("Dst pattern child has transform fn " +
DstChild->getTransformFn()->getName());
DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
0, *std::get<0>(*SubOperand), DstChild->getName(),
std::get<1>(*SubOperand), std::get<2>(*SubOperand));
- return Error::success();
+ return InsertPt;
}
if (!DstChild->isLeaf()) {
auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
DstMIBuilder.addRenderer<CopyRenderer>(0, DstChild->getName());
- return Error::success();
+ return InsertPt;
}
}
if (DstChild->getOperator()->getName() == "imm") {
DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(0,
DstChild->getName());
- return Error::success();
+ return InsertPt;
} else if (DstChild->getOperator()->getName() == "fpimm") {
DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
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));
if (ChildRec->isSubClassOf("Register")) {
DstMIBuilder.addRenderer<AddRegisterRenderer>(0, ChildRec);
- return Error::success();
+ return InsertPt;
}
if (ChildRec->isSubClassOf("RegisterClass") ||
!ChildRec->isValueUnset("GIZeroRegister")) {
DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
0, DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister"));
- return Error::success();
+ return InsertPt;
}
DstMIBuilder.addRenderer<CopyRenderer>(0, DstChild->getName());
- return Error::success();
+ return InsertPt;
}
if (ChildRec->isSubClassOf("ComplexPattern")) {
DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
0, *ComplexPattern->second, DstChild->getName(),
OM.getAllocatedTemporariesBaseID());
- return Error::success();
+ return InsertPt;
}
if (ChildRec->isSubClassOf("SDNodeXForm"))
Expected<BuildMIAction &> 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();
+ const_action_iterator InsertPt = InsertPtOrError.get();
+ BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(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<BuildMIAction &> GlobalISelEmitter::createInstructionRenderer(
- RuleMatcher &M, const TreePatternNode *Dst) {
+Expected<const_action_iterator>
+GlobalISelEmitter::createInstructionRenderer(const_action_iterator InsertPt,
+ RuleMatcher &M,
+ const TreePatternNode *Dst) {
Record *DstOp = Dst->getOperator();
if (!DstOp->isSubClassOf("Instruction")) {
if (DstOp->isSubClassOf("ValueType"))
else if (DstI->TheDef->getName() == "EXTRACT_SUBREG")
DstI = &Target.getInstruction(RK.getDef("COPY"));
- auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI);
+ InsertPt = M.insertAction<BuildMIAction>(InsertPt, 0, DstI);
- return DstMIBuilder;
+ return InsertPt;
}
void GlobalISelEmitter::importExplicitDefRenderers(
}
}
-Expected<BuildMIAction &> GlobalISelEmitter::importExplicitUseRenderers(
- RuleMatcher &M, BuildMIAction &DstMIBuilder,
+Expected<const_action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
+ const_action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
const llvm::TreePatternNode *Dst) {
const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator());
DstMIBuilder.addRenderer<CopySubRegRenderer>(
0, Dst->getChild(0)->getName(), SubIdx);
- return DstMIBuilder;
+ return InsertPt;
}
return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
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;
}
" explicit ones and " + llvm::to_string(NumDefaultOps) +
" default ones");
- return DstMIBuilder;
+ return InsertPt;
}
Error GlobalISelEmitter::importDefaultOperandRenderers(