summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2017-12-15 23:07:42 +0000
committerQuentin Colombet <qcolombet@apple.com>2017-12-15 23:07:42 +0000
commit6b36b462738519662ccef8748db8cf7f17ed4911 (patch)
tree7d598e40099bd2f3f01116493556ff55ada91071 /utils
parentbee91d76343aa0fd5d616ec0e74b74e6de2bb545 (diff)
[TableGen][GlobalISel] Have the predicate directly know which data they are dealing with
Prior to this patch, a predicate wouldn't make sense outside of its rule. Indeed, it was only during emitting a rule that a predicate would be made aware of the IDs of the data it is checking. Because of that, predicates could not be moved around or compared between each other. NFC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320887 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/GlobalISelEmitter.cpp270
1 files changed, 169 insertions, 101 deletions
diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp
index 8b5defd9d32..4bbd463a126 100644
--- a/utils/TableGen/GlobalISelEmitter.cpp
+++ b/utils/TableGen/GlobalISelEmitter.cpp
@@ -641,6 +641,10 @@ public:
/// Define an instruction without emitting any code to do so.
/// This is used for the root of the match.
unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
+ void clearImplicitMap() {
+ NextInsnVarID = 0;
+ InsnVariableIDs.clear();
+ };
/// Define an instruction and emit corresponding state-machine opcodes.
unsigned defineInsnVar(MatchTable &Table, const InstructionMatcher &Matcher,
unsigned InsnVarID, unsigned OpIdx);
@@ -761,8 +765,13 @@ public:
return;
}
- for (const auto &Predicate : predicates())
+ unsigned OpIdx = (*predicates_begin())->getOpIdx();
+ (void)OpIdx;
+ for (const auto &Predicate : predicates()) {
+ assert(Predicate->getOpIdx() == OpIdx &&
+ "Checks touch different operands?");
Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
+ }
}
};
@@ -796,15 +805,18 @@ public:
protected:
PredicateKind Kind;
+ unsigned InsnVarID;
+ unsigned OpIdx;
public:
- PredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
+ PredicateMatcher(PredicateKind Kind, unsigned InsnVarID, unsigned OpIdx = ~0)
+ : Kind(Kind), InsnVarID(InsnVarID), OpIdx(OpIdx) {}
+ unsigned getOpIdx() const { return OpIdx; }
virtual ~PredicateMatcher() = default;
/// Emit MatchTable opcodes that check the predicate for the given operand.
- virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID,
- unsigned OpIdx = ~0) const = 0;
+ virtual void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const = 0;
PredicateKind getKind() const { return Kind; }
};
@@ -817,15 +829,16 @@ public:
/// * Operand is an MBB.
class OperandPredicateMatcher : public PredicateMatcher {
public:
- OperandPredicateMatcher(PredicateKind Kind) : PredicateMatcher(Kind) {}
+ OperandPredicateMatcher(PredicateKind Kind, unsigned InsnVarID,
+ unsigned OpIdx)
+ : PredicateMatcher(Kind, InsnVarID, OpIdx) {}
virtual ~OperandPredicateMatcher() {}
/// Emit MatchTable opcodes to capture instructions into the MIs table.
///
/// Only InstructionOperandMatcher needs to do anything for this method the
/// rest just walk the tree.
- virtual void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const {}
+ virtual void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) const {}
/// Compare the priority of this object and B.
///
@@ -849,15 +862,16 @@ class SameOperandMatcher : public OperandPredicateMatcher {
std::string MatchingName;
public:
- SameOperandMatcher(StringRef MatchingName)
- : OperandPredicateMatcher(OPM_SameOperand), MatchingName(MatchingName) {}
+ SameOperandMatcher(StringRef MatchingName, unsigned InsnVarID, unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_SameOperand, InsnVarID, OpIdx),
+ MatchingName(MatchingName) {}
static bool classof(const OperandPredicateMatcher *P) {
return P->getKind() == OPM_SameOperand;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const override;
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override;
};
/// Generates code to check that an operand is a particular LLT.
@@ -868,8 +882,8 @@ protected:
public:
static std::set<LLTCodeGen> KnownTypes;
- LLTOperandMatcher(const LLTCodeGen &Ty)
- : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {
+ LLTOperandMatcher(const LLTCodeGen &Ty, unsigned InsnVarID, unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_LLT, InsnVarID, OpIdx), Ty(Ty) {
KnownTypes.insert(Ty);
}
@@ -877,8 +891,8 @@ public:
return P->getKind() == OPM_LLT;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIM_CheckType") << MatchTable::Comment("MI")
<< MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
<< MatchTable::IntValue(OpIdx) << MatchTable::Comment("Type")
@@ -904,18 +918,21 @@ protected:
unsigned SizeInBits;
public:
- PointerToAnyOperandMatcher(unsigned SizeInBits)
- : OperandPredicateMatcher(OPM_PointerToAny), SizeInBits(SizeInBits) {}
+ PointerToAnyOperandMatcher(unsigned SizeInBits, unsigned InsnVarID,
+ unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_PointerToAny, InsnVarID, OpIdx),
+ SizeInBits(SizeInBits) {}
static bool classof(const OperandPredicateMatcher *P) {
return P->getKind() == OPM_PointerToAny;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const override {
- Table << MatchTable::Opcode("GIM_CheckPointerToAny") << MatchTable::Comment("MI")
- << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
- << MatchTable::IntValue(OpIdx) << MatchTable::Comment("SizeInBits")
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
+ Table << MatchTable::Opcode("GIM_CheckPointerToAny")
+ << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
+ << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
+ << MatchTable::Comment("SizeInBits")
<< MatchTable::IntValue(SizeInBits) << MatchTable::LineBreak;
}
};
@@ -930,16 +947,17 @@ protected:
public:
ComplexPatternOperandMatcher(const OperandMatcher &Operand,
- const Record &TheDef)
- : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
- TheDef(TheDef) {}
+ const Record &TheDef, unsigned InsnVarID,
+ unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_ComplexPattern, InsnVarID, OpIdx),
+ Operand(Operand), TheDef(TheDef) {}
static bool classof(const PredicateMatcher *P) {
return P->getKind() == OPM_ComplexPattern;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
unsigned ID = getAllocatedTemporariesBaseID();
Table << MatchTable::Opcode("GIM_CheckComplexPattern")
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
@@ -960,15 +978,16 @@ protected:
const CodeGenRegisterClass &RC;
public:
- RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
- : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
+ RegisterBankOperandMatcher(const CodeGenRegisterClass &RC, unsigned InsnVarID,
+ unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_RegBank, InsnVarID, OpIdx), RC(RC) {}
static bool classof(const PredicateMatcher *P) {
return P->getKind() == OPM_RegBank;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIM_CheckRegBankForClass")
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
@@ -981,14 +1000,15 @@ public:
/// Generates code to check that an operand is a basic block.
class MBBOperandMatcher : public OperandPredicateMatcher {
public:
- MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
+ MBBOperandMatcher(unsigned InsnVarID, unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_MBB, InsnVarID, OpIdx) {}
static bool classof(const PredicateMatcher *P) {
return P->getKind() == OPM_MBB;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI")
<< MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
<< MatchTable::IntValue(OpIdx) << MatchTable::LineBreak;
@@ -1002,15 +1022,15 @@ protected:
int64_t Value;
public:
- ConstantIntOperandMatcher(int64_t Value)
- : OperandPredicateMatcher(OPM_Int), Value(Value) {}
+ ConstantIntOperandMatcher(int64_t Value, unsigned InsnVarID, unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_Int, InsnVarID, OpIdx), Value(Value) {}
static bool classof(const PredicateMatcher *P) {
return P->getKind() == OPM_Int;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIM_CheckConstantInt")
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
@@ -1025,15 +1045,16 @@ protected:
int64_t Value;
public:
- LiteralIntOperandMatcher(int64_t Value)
- : OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
+ LiteralIntOperandMatcher(int64_t Value, unsigned InsnVarID, unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_LiteralInt, InsnVarID, OpIdx),
+ Value(Value) {}
static bool classof(const PredicateMatcher *P) {
return P->getKind() == OPM_LiteralInt;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIM_CheckLiteralInt")
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
@@ -1047,15 +1068,16 @@ protected:
const CodeGenIntrinsic *II;
public:
- IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II)
- : OperandPredicateMatcher(OPM_IntrinsicID), II(II) {}
+ IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II, unsigned InsnVarID,
+ unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_IntrinsicID, InsnVarID, OpIdx), II(II) {}
static bool classof(const PredicateMatcher *P) {
return P->getKind() == OPM_IntrinsicID;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID, unsigned OpIdx) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIM_CheckIntrinsicID")
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
<< MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
@@ -1091,6 +1113,7 @@ public:
SymbolicName = Name;
}
unsigned getOperandIndex() const { return OpIdx; }
+ unsigned getInsnVarID() const;
std::string getOperandExpr(unsigned InsnVarID) const {
return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
@@ -1103,26 +1126,24 @@ public:
bool OperandIsAPointer);
/// Emit MatchTable opcodes to capture instructions into the MIs table.
- void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID) const {
+ void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) const {
for (const auto &Predicate : predicates())
- Predicate->emitCaptureOpcodes(Table, Rule, InsnVarID, OpIdx);
+ Predicate->emitCaptureOpcodes(Table, Rule);
}
/// Emit MatchTable opcodes that test whether the instruction named in
/// InsnVarID matches all the predicates and all the operands.
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID) const {
+ void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule) const {
std::string Comment;
raw_string_ostream CommentOS(Comment);
- CommentOS << "MIs[" << InsnVarID << "] ";
+ CommentOS << "MIs[" << getInsnVarID() << "] ";
if (SymbolicName.empty())
CommentOS << "Operand " << OpIdx;
else
CommentOS << SymbolicName;
Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
- emitPredicateListOpcodes(Table, Rule, InsnVarID, OpIdx);
+ emitPredicateListOpcodes(Table, Rule);
}
/// Compare the priority of this object and B.
@@ -1175,14 +1196,17 @@ template <>
template <class Kind, class... Args>
Optional<Kind *>
PredicateListMatcher<OperandPredicateMatcher>::addPredicate(Args &&... args) {
+ auto *OpMatcher = static_cast<OperandMatcher *>(this);
if (static_cast<OperandMatcher *>(this)->isSameAsAnotherOperand())
return None;
- Predicates.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
+ Predicates.emplace_back(llvm::make_unique<Kind>(
+ std::forward<Args>(args)..., OpMatcher->getInsnVarID(),
+ OpMatcher->getOperandIndex()));
return static_cast<Kind *>(Predicates.back().get());
}
Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
- bool OperandIsAPointer) {
+ bool OperandIsAPointer) {
if (!VTy.isMachineValueType())
return failedImport("unsupported typeset");
@@ -1213,7 +1237,8 @@ unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
/// * The nsw/nuw flag is/isn't set.
class InstructionPredicateMatcher : public PredicateMatcher {
public:
- InstructionPredicateMatcher(PredicateKind Kind) : PredicateMatcher(Kind) {}
+ InstructionPredicateMatcher(PredicateKind Kind, unsigned InsnVarID)
+ : PredicateMatcher(Kind, InsnVarID) {}
virtual ~InstructionPredicateMatcher() {}
/// Compare the priority of this object and B.
@@ -1241,16 +1266,15 @@ protected:
const CodeGenInstruction *I;
public:
- InstructionOpcodeMatcher(const CodeGenInstruction *I)
- : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
+ InstructionOpcodeMatcher(unsigned InsnVarID, const CodeGenInstruction *I)
+ : InstructionPredicateMatcher(IPM_Opcode, InsnVarID), I(I) {}
static bool classof(const PredicateMatcher *P) {
return P->getKind() == IPM_Opcode;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID,
- unsigned OpIdx = ~0) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
<< MatchTable::IntValue(InsnVarID)
<< MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
@@ -1313,16 +1337,17 @@ protected:
TreePredicateFn Predicate;
public:
- InstructionImmPredicateMatcher(const TreePredicateFn &Predicate)
- : InstructionPredicateMatcher(IPM_ImmPredicate), Predicate(Predicate) {}
+ InstructionImmPredicateMatcher(unsigned InsnVarID,
+ const TreePredicateFn &Predicate)
+ : InstructionPredicateMatcher(IPM_ImmPredicate, InsnVarID),
+ Predicate(Predicate) {}
static bool classof(const PredicateMatcher *P) {
return P->getKind() == IPM_ImmPredicate;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID,
- unsigned OpIdx = ~0) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
<< MatchTable::Comment("Predicate")
@@ -1346,18 +1371,17 @@ protected:
AOComparator Comparator;
public:
- AtomicOrderingMMOPredicateMatcher(StringRef Order,
+ AtomicOrderingMMOPredicateMatcher(unsigned InsnVarID, StringRef Order,
AOComparator Comparator = AO_Exactly)
- : InstructionPredicateMatcher(IPM_AtomicOrderingMMO), Order(Order),
- Comparator(Comparator) {}
+ : InstructionPredicateMatcher(IPM_AtomicOrderingMMO, InsnVarID),
+ Order(Order), Comparator(Comparator) {}
static bool classof(const InstructionPredicateMatcher *P) {
return P->getKind() == IPM_AtomicOrderingMMO;
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID,
- unsigned OpIdx = ~0) const override {
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
StringRef Opcode = "GIM_CheckAtomicOrdering";
if (Comparator == AO_OrStronger)
@@ -1390,13 +1414,20 @@ protected:
OperandVec Operands;
std::string SymbolicName;
+ unsigned InsnVarID;
public:
InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName)
- : Rule(Rule), SymbolicName(SymbolicName) {}
+ : Rule(Rule), SymbolicName(SymbolicName) {
+ // We create a new instruction matcher.
+ // Get a new ID for that instruction.
+ InsnVarID = Rule.implicitlyDefineInsnVar(*this);
+ }
RuleMatcher &getRuleMatcher() const { return Rule; }
+ unsigned getVarID() const { return InsnVarID; }
+
/// Add an operand to the matcher.
OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
unsigned AllocatedTemporariesBaseID) {
@@ -1433,23 +1464,21 @@ public:
/// Emit MatchTable opcodes to check the shape of the match and capture
/// instructions into the MIs table.
- void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnID) {
+ void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) {
Table << MatchTable::Opcode("GIM_CheckNumOperands")
- << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
+ << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
<< MatchTable::Comment("Expected")
<< MatchTable::IntValue(getNumOperands()) << MatchTable::LineBreak;
for (const auto &Operand : Operands)
- Operand->emitCaptureOpcodes(Table, Rule, InsnID);
+ Operand->emitCaptureOpcodes(Table, Rule);
}
/// Emit MatchTable opcodes that test whether the instruction named in
/// InsnVarName matches all the predicates and all the operands.
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID) const {
- emitPredicateListOpcodes(Table, Rule, InsnVarID);
+ void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule) const {
+ emitPredicateListOpcodes(Table, Rule);
for (const auto &Operand : Operands)
- Operand->emitPredicateOpcodes(Table, Rule, InsnVarID);
+ Operand->emitPredicateOpcodes(Table, Rule);
}
/// Compare the priority of this object and B.
@@ -1504,6 +1533,17 @@ public:
}
};
+template <>
+template <class Kind, class... Args>
+Optional<Kind *>
+PredicateListMatcher<InstructionPredicateMatcher>::addPredicate(
+ Args &&... args) {
+ InstructionMatcher *InstMatcher = static_cast<InstructionMatcher *>(this);
+ Predicates.emplace_back(llvm::make_unique<Kind>(InstMatcher->getVarID(),
+ std::forward<Args>(args)...));
+ return static_cast<Kind *>(Predicates.back().get());
+}
+
/// Generates code to check that the operand is a register defined by an
/// instruction that matches the given instruction matcher.
///
@@ -1518,8 +1558,9 @@ protected:
std::unique_ptr<InstructionMatcher> InsnMatcher;
public:
- InstructionOperandMatcher(RuleMatcher &Rule, StringRef SymbolicName)
- : OperandPredicateMatcher(OPM_Instruction),
+ InstructionOperandMatcher(RuleMatcher &Rule, StringRef SymbolicName,
+ unsigned InsnVarID, unsigned OpIdx)
+ : OperandPredicateMatcher(OPM_Instruction, InsnVarID, OpIdx),
InsnMatcher(new InstructionMatcher(Rule, SymbolicName)) {}
static bool classof(const PredicateMatcher *P) {
@@ -1528,17 +1569,18 @@ public:
InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
- void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnID, unsigned OpIdx) const override {
- unsigned InsnVarID = Rule.defineInsnVar(Table, *InsnMatcher, InsnID, OpIdx);
- InsnMatcher->emitCaptureOpcodes(Table, Rule, InsnVarID);
+ void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
+ unsigned InsnID =
+ Rule.defineInsnVar(Table, *InsnMatcher, InsnVarID, getOpIdx());
+ (void)InsnID;
+ assert(InsnMatcher->getVarID() == InsnID &&
+ "Mismatch between build and emit");
+ InsnMatcher->emitCaptureOpcodes(Table, Rule);
}
- void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
- unsigned InsnVarID_,
- unsigned OpIdx_) const override {
- unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
- InsnMatcher->emitPredicateOpcodes(Table, Rule, InsnVarID);
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
+ InsnMatcher->emitPredicateOpcodes(Table, Rule);
}
};
@@ -2184,7 +2226,9 @@ RuleMatcher::getOperandMatcher(StringRef Name) const {
void RuleMatcher::emitCaptureOpcodes(MatchTable &Table) {
assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
- Matchers.front()->emitCaptureOpcodes(Table, *this, InsnVarID);
+ assert(Matchers.front()->getVarID() == InsnVarID &&
+ "IDs differ between build and emit");
+ Matchers.front()->emitCaptureOpcodes(Table, *this);
}
void RuleMatcher::emit(MatchTable &Table) {
@@ -2215,8 +2259,7 @@ void RuleMatcher::emit(MatchTable &Table) {
emitCaptureOpcodes(Table);
- Matchers.front()->emitPredicateOpcodes(Table, *this,
- getInsnVarID(*Matchers.front()));
+ Matchers.front()->emitPredicateOpcodes(Table, *this);
// We must also check if it's safe to fold the matched instructions.
if (InsnVariableIDs.size() >= 2) {
@@ -2344,11 +2387,10 @@ bool OperandPredicateMatcher::isHigherPriorityThan(
}
void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table,
- RuleMatcher &Rule,
- unsigned InsnVarID,
- unsigned OpIdx) const {
+ RuleMatcher &Rule) const {
const OperandMatcher &OtherOM = Rule.getOperandMatcher(MatchingName);
unsigned OtherInsnVarID = Rule.getInsnVarID(OtherOM.getInstructionMatcher());
+ assert(OtherInsnVarID == OtherOM.getInstructionMatcher().getVarID());
Table << MatchTable::Opcode("GIM_CheckIsSameOperand")
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
@@ -2543,8 +2585,8 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
if (!MemTyOrNone)
return failedImport("MemVT could not be converted to LLT");
- InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(
- MemTyOrNone.getValue());
+ OperandMatcher &OM = InsnMatcher.getOperand(0);
+ OM.addPredicate<LLTOperandMatcher>(MemTyOrNone.getValue());
continue;
}
}
@@ -3140,10 +3182,34 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
return failedImport("Src pattern root isn't a trivial operator (" +
toString(std::move(Err)) + ")");
+ // The different predicates and matchers created during
+ // addInstructionMatcher use the RuleMatcher M to set up their
+ // instruction ID (InsnVarID) that are going to be used when
+ // M is going to be emitted.
+ // However, the code doing the emission still relies on the IDs
+ // returned during that process by the RuleMatcher when issuing
+ // the recordInsn opcodes.
+ // Because of that:
+ // 1. The order in which we created the predicates
+ // and such must be the same as the order in which we emit them,
+ // and
+ // 2. We need to reset the generation of the IDs in M somewhere between
+ // addInstructionMatcher and emit
+ //
+ // FIXME: Long term, we don't want to have to rely on this implicit
+ // naming being the same. One possible solution would be to have
+ // explicit operator for operation capture and reference those.
+ // The plus side is that it would expose opportunities to share
+ // the capture accross rules. The downside is that it would
+ // introduce a dependency between predicates (captures must happen
+ // before their first use.)
InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
unsigned TempOpIdx = 0;
auto InsnMatcherOrError =
createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
+ // Reset the ID generation so that the emitted IDs match the ones
+ // in the InstructionMatcher and such.
+ M.clearImplicitMap();
if (auto Error = InsnMatcherOrError.takeError())
return std::move(Error);
InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
@@ -3708,6 +3774,8 @@ void GlobalISelEmitter::fixupPatternTrees(TreePattern *P) {
}
}
+unsigned OperandMatcher::getInsnVarID() const { return Insn.getVarID(); }
+
} // end anonymous namespace
//===----------------------------------------------------------------------===//