summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/utils/TableGen/GlobalISelEmitter.cpp116
1 files changed, 73 insertions, 43 deletions
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index 85739bbab4a..daa958e211f 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -527,12 +527,19 @@ class RuleMatcher {
/// have succeeded.
std::vector<std::unique_ptr<MatchAction>> Actions;
- typedef std::map<const InstructionMatcher *, unsigned>
- DefinedInsnVariablesMap;
+ using DefinedInsnVariablesMap =
+ std::map<const InstructionMatcher *, unsigned>;
+
/// A map of instruction matchers to the local variables created by
/// emitCaptureOpcodes().
DefinedInsnVariablesMap InsnVariableIDs;
+ using MutatableInsnSet = SmallPtrSet<const InstructionMatcher *, 4>;
+
+ // The set of instruction matchers that have not yet been claimed for mutation
+ // by a BuildMI.
+ MutatableInsnSet MutatableInsns;
+
/// A map of named operands defined by the matchers that may be referenced by
/// the renderers.
StringMap<OperandMatcher *> DefinedOperands;
@@ -553,8 +560,9 @@ class RuleMatcher {
public:
RuleMatcher(ArrayRef<SMLoc> SrcLoc)
- : Matchers(), Actions(), InsnVariableIDs(), DefinedOperands(),
- NextInsnVarID(0), SrcLoc(SrcLoc), ComplexSubOperands() {}
+ : Matchers(), Actions(), InsnVariableIDs(), MutatableInsns(),
+ DefinedOperands(), NextInsnVarID(0), SrcLoc(SrcLoc),
+ ComplexSubOperands() {}
RuleMatcher(RuleMatcher &&Other) = default;
RuleMatcher &operator=(RuleMatcher &&Other) = default;
@@ -582,6 +590,22 @@ public:
return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
}
+ MutatableInsnSet::const_iterator mutatable_insns_begin() const {
+ return MutatableInsns.begin();
+ }
+ MutatableInsnSet::const_iterator mutatable_insns_end() const {
+ return MutatableInsns.end();
+ }
+ iterator_range<typename MutatableInsnSet::const_iterator>
+ mutatable_insns() const {
+ return make_range(mutatable_insns_begin(), mutatable_insns_end());
+ }
+ void reserveInsnMatcherForMutation(const InstructionMatcher *InsnMatcher) {
+ bool R = MutatableInsns.erase(InsnMatcher);
+ assert(R && "Reserving a mutatable insn that isn't available");
+ (void)R;
+ }
+
void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
@@ -1723,12 +1747,8 @@ public:
virtual ~MatchAction() {}
/// Emit the MatchTable opcodes to implement the action.
- ///
- /// \param RecycleInsnID If given, it's an instruction to recycle. The
- /// requirements on the instruction vary from action to
- /// action.
- virtual void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned RecycleInsnID) const = 0;
+ virtual void emitActionOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const = 0;
};
/// Generates a comment describing the matched rule being acted upon.
@@ -1739,8 +1759,7 @@ private:
public:
DebugCommentAction(StringRef S) : S(S) {}
- void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned RecycleInsnID) const override {
+ void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Table << MatchTable::Comment(S) << MatchTable::LineBreak;
}
};
@@ -1755,17 +1774,17 @@ private:
std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
/// True if the instruction can be built solely by mutating the opcode.
- bool canMutate(RuleMatcher &Rule) const {
- if (!Matched)
+ bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const {
+ if (!Insn)
return false;
- if (OperandRenderers.size() != Matched->getNumOperands())
+ if (OperandRenderers.size() != Insn->getNumOperands())
return false;
for (const auto &Renderer : enumerate(OperandRenderers)) {
if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
const OperandMatcher &OM = Rule.getOperandMatcher(Copy->getSymbolicName());
- if (Matched != &OM.getInstructionMatcher() ||
+ if (Insn != &OM.getInstructionMatcher() ||
OM.getOperandIndex() != Renderer.index())
return false;
} else
@@ -1776,9 +1795,19 @@ private:
}
public:
- BuildMIAction(unsigned InsnID, const CodeGenInstruction *I,
- const InstructionMatcher *Matched)
- : InsnID(InsnID), I(I), Matched(Matched) {}
+ BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
+ : InsnID(InsnID), I(I), Matched(nullptr) {}
+
+ void chooseInsnToMutate(RuleMatcher &Rule) {
+ for (const auto *MutateCandidate : Rule.mutatable_insns()) {
+ if (canMutate(Rule, MutateCandidate)) {
+ // Take the first one we're offered that we're able to mutate.
+ Rule.reserveInsnMatcherForMutation(MutateCandidate);
+ Matched = MutateCandidate;
+ return;
+ }
+ }
+ }
template <class Kind, class... Args>
Kind &addRenderer(Args&&... args) {
@@ -1787,9 +1816,12 @@ public:
return *static_cast<Kind *>(OperandRenderers.back().get());
}
- void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned RecycleInsnID) const override {
- if (canMutate(Rule)) {
+ void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
+ if (Matched) {
+ assert(canMutate(Rule, Matched) &&
+ "Arranged to mutate an insn that isn't mutatable");
+
+ unsigned RecycleInsnID = Rule.getInsnVarID(*Matched);
Table << MatchTable::Opcode("GIR_MutateOpcode")
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
<< MatchTable::Comment("RecycleInsnID")
@@ -1853,8 +1885,8 @@ public:
}
Table << MatchTable::Opcode("GIR_EraseFromParent")
- << MatchTable::Comment("InsnID")
- << MatchTable::IntValue(RecycleInsnID) << MatchTable::LineBreak;
+ << MatchTable::Comment("InsnID") << MatchTable::IntValue(0)
+ << MatchTable::LineBreak;
}
};
@@ -1866,8 +1898,7 @@ class ConstrainOperandsToDefinitionAction : public MatchAction {
public:
ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
- void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned RecycleInsnID) const override {
+ void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
<< MatchTable::LineBreak;
@@ -1886,8 +1917,7 @@ public:
const CodeGenRegisterClass &RC)
: InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
- void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned RecycleInsnID) const override {
+ void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
<< MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
@@ -1898,6 +1928,7 @@ public:
InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName));
+ MutatableInsns.insert(Matchers.back().get());
return *Matchers.back();
}
@@ -2069,7 +2100,7 @@ void RuleMatcher::emit(MatchTable &Table) {
}
for (const auto &MA : Actions)
- MA->emitActionOpcodes(Table, *this, 0);
+ MA->emitActionOpcodes(Table, *this);
Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
<< MatchTable::Label(LabelID);
}
@@ -2189,12 +2220,11 @@ private:
bool OperandIsAPointer, unsigned OpIdx,
unsigned &TempOpIdx) const;
Expected<BuildMIAction &>
- createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst,
- const InstructionMatcher &InsnMatcher);
+ createAndImportInstructionRenderer(RuleMatcher &M,
+ const TreePatternNode *Dst);
Error importExplicitUseRenderer(RuleMatcher &Rule,
BuildMIAction &DstMIBuilder,
- TreePatternNode *DstChild,
- const InstructionMatcher &InsnMatcher) const;
+ TreePatternNode *DstChild) const;
Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
DagInit *DefaultOps) const;
Error
@@ -2525,8 +2555,8 @@ Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
}
Error GlobalISelEmitter::importExplicitUseRenderer(
- RuleMatcher &Rule, BuildMIAction &DstMIBuilder, TreePatternNode *DstChild,
- const InstructionMatcher &InsnMatcher) const {
+ RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
+ TreePatternNode *DstChild) const {
if (DstChild->getTransformFn() != nullptr) {
return failedImport("Dst pattern child has transform fn " +
DstChild->getTransformFn()->getName());
@@ -2626,8 +2656,7 @@ Error GlobalISelEmitter::importExplicitUseRenderer(
}
Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
- RuleMatcher &M, const TreePatternNode *Dst,
- const InstructionMatcher &InsnMatcher) {
+ RuleMatcher &M, const TreePatternNode *Dst) {
Record *DstOp = Dst->getOperator();
if (!DstOp->isSubClassOf("Instruction")) {
if (DstOp->isSubClassOf("ValueType"))
@@ -2652,7 +2681,7 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
IsExtractSubReg = true;
}
- auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI, &InsnMatcher);
+ auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI);
// Render the explicit defs.
for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
@@ -2707,8 +2736,8 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
continue;
}
- if (auto Error = importExplicitUseRenderer(
- M, DstMIBuilder, Dst->getChild(Child), InsnMatcher))
+ if (auto Error =
+ importExplicitUseRenderer(M, DstMIBuilder, Dst->getChild(Child)))
return std::move(Error);
++Child;
}
@@ -2805,7 +2834,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
M.defineOperand(OM0.getSymbolicName(), OM0);
OM0.addPredicate<RegisterBankOperandMatcher>(RC);
- auto &DstMIBuilder = M.addAction<BuildMIAction>(0, &DstI, &InsnMatcher);
+ auto &DstMIBuilder = M.addAction<BuildMIAction>(0, &DstI);
DstMIBuilder.addRenderer<CopyRenderer>(0, DstIOperand.Name);
DstMIBuilder.addRenderer<CopyRenderer>(0, Dst->getName());
M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
@@ -2869,8 +2898,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
++OpIdx;
}
- auto DstMIBuilderOrError =
- createAndImportInstructionRenderer(M, Dst, InsnMatcher);
+ auto DstMIBuilderOrError = createAndImportInstructionRenderer(M, Dst);
if (auto Error = DstMIBuilderOrError.takeError())
return std::move(Error);
BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
@@ -2880,6 +2908,8 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
return std::move(Error);
+ DstMIBuilder.chooseInsnToMutate(M);
+
// Constrain the registers to classes. This is normally derived from the
// emitted instruction but a few instructions require special handling.
if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
OpenPOWER on IntegriCloud