summaryrefslogtreecommitdiffstats
path: root/llvm/utils/TableGen/GlobalISelEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/GlobalISelEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/GlobalISelEmitter.cpp101
1 files changed, 60 insertions, 41 deletions
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index a2d1b1cbc91..7a8acc4ea15 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -332,26 +332,31 @@ public:
/// Generates code to check that an operand is a particular target constant.
class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
protected:
+ const OperandMatcher &Operand;
const Record &TheDef;
- /// The index of the first temporary operand to allocate to this
- /// ComplexPattern.
- unsigned BaseTemporaryID;
unsigned getNumOperands() const {
return TheDef.getValueAsDag("Operands")->getNumArgs();
}
+ unsigned getAllocatedTemporariesBaseID() const;
+
public:
- ComplexPatternOperandMatcher(const Record &TheDef, unsigned BaseTemporaryID)
- : OperandPredicateMatcher(OPM_ComplexPattern), TheDef(TheDef),
- BaseTemporaryID(BaseTemporaryID) {}
+ ComplexPatternOperandMatcher(const OperandMatcher &Operand,
+ const Record &TheDef)
+ : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
+ TheDef(TheDef) {}
+
+ static bool classof(const OperandPredicateMatcher *P) {
+ return P->getKind() == OPM_ComplexPattern;
+ }
void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
StringRef OperandExpr) const override {
OS << TheDef.getValueAsString("MatcherFn") << "(" << OperandExpr;
for (unsigned I = 0; I < getNumOperands(); ++I) {
OS << ", ";
- OperandPlaceholder::CreateTemporary(BaseTemporaryID + I)
+ OperandPlaceholder::CreateTemporary(getAllocatedTemporariesBaseID() + I)
.emitCxxValueExpr(OS);
}
OS << ")";
@@ -425,10 +430,17 @@ protected:
unsigned OpIdx;
std::string SymbolicName;
+ /// The index of the first temporary variable allocated to this operand. The
+ /// number of allocated temporaries can be found with
+ /// countTemporaryOperands().
+ unsigned AllocatedTemporariesBaseID;
+
public:
OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
- const std::string &SymbolicName)
- : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName) {}
+ const std::string &SymbolicName,
+ unsigned AllocatedTemporariesBaseID)
+ : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
+ AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
bool hasSymbolicName() const { return !SymbolicName.empty(); }
const StringRef getSymbolicName() const { return SymbolicName; }
@@ -509,8 +521,16 @@ public:
return A + Predicate->countTemporaryOperands();
});
}
+
+ unsigned getAllocatedTemporariesBaseID() const {
+ return AllocatedTemporariesBaseID;
+ }
};
+unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
+ return Operand.getAllocatedTemporariesBaseID();
+}
+
/// Generates code to check a predicate on an instruction.
///
/// Typical predicates include:
@@ -598,7 +618,7 @@ public:
class InstructionMatcher
: public PredicateListMatcher<InstructionPredicateMatcher> {
protected:
- typedef std::vector<OperandMatcher> OperandVec;
+ typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
/// The operands to match. All rendered operands must be present even if the
/// condition is always true.
@@ -606,18 +626,20 @@ protected:
public:
/// Add an operand to the matcher.
- OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName) {
- Operands.emplace_back(*this, OpIdx, SymbolicName);
- return Operands.back();
+ OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
+ unsigned AllocatedTemporariesBaseID) {
+ Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
+ AllocatedTemporariesBaseID));
+ return *Operands.back();
}
OperandMatcher &getOperand(unsigned OpIdx) {
auto I = std::find_if(Operands.begin(), Operands.end(),
- [&OpIdx](const OperandMatcher &X) {
- return X.getOperandIndex() == OpIdx;
+ [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
+ return X->getOperandIndex() == OpIdx;
});
if (I != Operands.end())
- return *I;
+ return **I;
llvm_unreachable("Failed to lookup operand");
}
@@ -625,7 +647,7 @@ public:
getOptionalOperand(StringRef SymbolicName) const {
assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
for (const auto &Operand : Operands) {
- const auto &OM = Operand.getOptionalOperand(SymbolicName);
+ const auto &OM = Operand->getOptionalOperand(SymbolicName);
if (OM.hasValue())
return OM.getValue();
}
@@ -657,7 +679,7 @@ public:
OS << "if (" << Expr << ".getNumOperands() < " << getNumOperands() << ")\n"
<< " return false;\n";
for (const auto &Operand : Operands) {
- Operand.emitCxxCaptureStmts(OS, Rule, Operand.getOperandExpr(Expr));
+ Operand->emitCxxCaptureStmts(OS, Rule, Operand->getOperandExpr(Expr));
}
}
@@ -668,7 +690,7 @@ public:
emitCxxPredicateListExpr(OS, Rule, InsnVarName);
for (const auto &Operand : Operands) {
OS << " &&\n(";
- Operand.emitCxxPredicateExpr(OS, Rule, InsnVarName);
+ Operand->emitCxxPredicateExpr(OS, Rule, InsnVarName);
OS << ")";
}
}
@@ -691,9 +713,9 @@ public:
}
for (const auto &Operand : zip(Operands, B.Operands)) {
- if (std::get<0>(Operand).isHigherPriorityThan(std::get<1>(Operand)))
+ if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
return true;
- if (std::get<1>(Operand).isHigherPriorityThan(std::get<0>(Operand)))
+ if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
return false;
}
@@ -709,10 +731,11 @@ public:
&Predicate) {
return A + Predicate->countTemporaryOperands();
}) +
- std::accumulate(Operands.begin(), Operands.end(), 0,
- [](unsigned A, const OperandMatcher &Operand) {
- return A + Operand.countTemporaryOperands();
- });
+ std::accumulate(
+ Operands.begin(), Operands.end(), 0,
+ [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
+ return A + Operand->countTemporaryOperands();
+ });
}
};
@@ -1174,8 +1197,7 @@ private:
const InstructionMatcher &InsnMatcher) const;
Error importExplicitUseRenderer(BuildMIAction &DstMIBuilder,
TreePatternNode *DstChild,
- const InstructionMatcher &InsnMatcher,
- unsigned &TempOpIdx) const;
+ const InstructionMatcher &InsnMatcher) const;
Error
importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
const std::vector<Record *> &ImplicitDefs) const;
@@ -1237,6 +1259,7 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
InsnMatcher.addPredicate<InstructionOpcodeMatcher>(&SrcGI);
unsigned OpIdx = 0;
+ unsigned TempOpIdx = 0;
for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
auto OpTyOrNone = MVTToLLT(Ty.getConcrete());
@@ -1246,11 +1269,10 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
// Results don't have a name unless they are the root node. The caller will
// set the name if appropriate.
- OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "");
+ OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
}
- unsigned TempOpIdx = 0;
// Match the used operands (i.e. the children of the operator).
for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
if (auto Error = importChildMatcher(InsnMatcher, Src->getChild(i), OpIdx++,
@@ -1265,7 +1287,8 @@ Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher,
TreePatternNode *SrcChild,
unsigned OpIdx,
unsigned &TempOpIdx) const {
- OperandMatcher &OM = InsnMatcher.addOperand(OpIdx, SrcChild->getName());
+ OperandMatcher &OM =
+ InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
if (SrcChild->hasAnyPredicate())
return failedImport("Src pattern child has predicate");
@@ -1328,7 +1351,7 @@ Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher,
"SelectionDAG ComplexPattern not mapped to GlobalISel");
const auto &Predicate = OM.addPredicate<ComplexPatternOperandMatcher>(
- *ComplexPattern->second, TempOpIdx);
+ OM, *ComplexPattern->second);
TempOpIdx += Predicate.countTemporaryOperands();
return Error::success();
}
@@ -1342,7 +1365,7 @@ Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher,
Error GlobalISelEmitter::importExplicitUseRenderer(
BuildMIAction &DstMIBuilder, TreePatternNode *DstChild,
- const InstructionMatcher &InsnMatcher, unsigned &TempOpIdx) const {
+ const InstructionMatcher &InsnMatcher) const {
// The only non-leaf child we accept is 'bb': it's an operator because
// BasicBlockSDNode isn't inline, but in MI it's just another operand.
if (!DstChild->isLeaf()) {
@@ -1389,13 +1412,10 @@ Error GlobalISelEmitter::importExplicitUseRenderer(
"SelectionDAG ComplexPattern not mapped to GlobalISel");
SmallVector<OperandPlaceholder, 2> RenderedOperands;
- for (unsigned I = 0;
- I <
- InsnMatcher.getOperand(DstChild->getName()).countTemporaryOperands();
- ++I) {
- RenderedOperands.push_back(OperandPlaceholder::CreateTemporary(I));
- TempOpIdx++;
- }
+ const OperandMatcher &OM = InsnMatcher.getOperand(DstChild->getName());
+ for (unsigned I = 0; I < OM.countTemporaryOperands(); ++I)
+ RenderedOperands.push_back(OperandPlaceholder::CreateTemporary(
+ OM.getAllocatedTemporariesBaseID() + I));
DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
*ComplexPattern->second, RenderedOperands);
return Error::success();
@@ -1425,10 +1445,9 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
}
// Render the explicit uses.
- unsigned TempOpIdx = 0;
for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
if (auto Error = importExplicitUseRenderer(DstMIBuilder, Dst->getChild(i),
- InsnMatcher, TempOpIdx))
+ InsnMatcher))
return std::move(Error);
}
OpenPOWER on IntegriCloud