diff options
author | Roman Tereshin <rtereshin@apple.com> | 2018-05-22 04:31:50 +0000 |
---|---|---|
committer | Roman Tereshin <rtereshin@apple.com> | 2018-05-22 04:31:50 +0000 |
commit | 19da66759944f2a3d2b7142e76a409c68d4c87fd (patch) | |
tree | 5deec36cf54121bd145150fd4206a9a03ba1dcaf /llvm/utils/TableGen/GlobalISelEmitter.cpp | |
parent | 4ca5af07210abb546bd14c8a6a62fe7ec0401382 (diff) | |
download | bcm5719-llvm-19da66759944f2a3d2b7142e76a409c68d4c87fd.tar.gz bcm5719-llvm-19da66759944f2a3d2b7142e76a409c68d4c87fd.zip |
[GlobalISel][InstructionSelect] Removing redundant num operands and nested def operands checks, perf patch 2
This patch continues a series of patches that decrease time spent by
GlobalISel in its InstructionSelect pass by roughly 60% for -O0 builds
for large inputs as measured on sqlite3-amalgamation
(http://sqlite.org/download.html) targeting AArch64.
This commit specifically removes number of operands checks that are
redundant if the instruction's opcode already guarantees that number
of operands (or more), and also avoids any kind of checks on a def
operand of a nested instruction as everything about it was already
checked at its use.
The expected performance implication is about 3% off InstructionSelect
comparing to the baseline (before the series of patches)
This patch also contains a bit of NFC changes required for further
patches in the series.
Every commit planned shares the same Phabricator Review.
Reviewers: qcolombet, dsanders, bogner, aemerson, javed.absar
Reviewed By: qcolombet
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D44700
llvm-svn: 332945
Diffstat (limited to 'llvm/utils/TableGen/GlobalISelEmitter.cpp')
-rw-r--r-- | llvm/utils/TableGen/GlobalISelEmitter.cpp | 66 |
1 files changed, 61 insertions, 5 deletions
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index e7070c40eb5..cdc9df7bf6b 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -854,6 +854,7 @@ public: LLTCodeGen getFirstConditionAsRootType(); bool hasFirstCondition() const override; unsigned getNumOperands() const; + StringRef getOpcode() const; // FIXME: Remove this as soon as possible InstructionMatcher &insnmatchers_front() const { return *Matchers.front(); } @@ -1545,6 +1546,7 @@ public: return I->TheDef->getName() == "G_CONSTANT"; } + StringRef getOpcode() const { return I->TheDef->getName(); } unsigned getNumOperands() const { return I->Operands.size(); } StringRef getOperandType(unsigned OpIdx) const { @@ -1555,6 +1557,32 @@ public: DenseMap<const CodeGenInstruction *, unsigned> InstructionOpcodeMatcher::OpcodeValues; +class InstructionNumOperandsMatcher final : public InstructionPredicateMatcher { + unsigned NumOperands = 0; + +public: + InstructionNumOperandsMatcher(unsigned InsnVarID, unsigned NumOperands) + : InstructionPredicateMatcher(IPM_NumOperands, InsnVarID), + NumOperands(NumOperands) {} + + static bool classof(const PredicateMatcher *P) { + return P->getKind() == IPM_NumOperands; + } + + bool isIdentical(const PredicateMatcher &B) const override { + return InstructionPredicateMatcher::isIdentical(B) && + NumOperands == cast<InstructionNumOperandsMatcher>(&B)->NumOperands; + } + + void emitPredicateOpcodes(MatchTable &Table, + RuleMatcher &Rule) const override { + Table << MatchTable::Opcode("GIM_CheckNumOperands") + << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID) + << MatchTable::Comment("Expected") + << MatchTable::IntValue(NumOperands) << MatchTable::LineBreak; + } +}; + /// Generates code to check that this instruction is a constant whose value /// meets an immediate predicate. /// @@ -1750,6 +1778,7 @@ protected: /// The operands to match. All rendered operands must be present even if the /// condition is always true. OperandVec Operands; + bool NumOperandsCheck = true; std::string SymbolicName; unsigned InsnVarID; @@ -1811,15 +1840,14 @@ public: void pop_front() { Operands.erase(Operands.begin()); } - void optimize() {} + void optimize(); /// 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) { - Table << MatchTable::Opcode("GIM_CheckNumOperands") - << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID) - << MatchTable::Comment("Expected") - << MatchTable::IntValue(getNumOperands()) << MatchTable::LineBreak; + if (NumOperandsCheck) + InstructionNumOperandsMatcher(InsnVarID, getNumOperands()) + .emitPredicateOpcodes(Table, Rule); emitPredicateListOpcodes(Table, Rule); @@ -1882,8 +1910,14 @@ public: bool isConstantInstruction() { return getOpcodeMatcher().isConstantInstruction(); } + + StringRef getOpcode() { return getOpcodeMatcher().getOpcode(); } }; +StringRef RuleMatcher::getOpcode() const { + return Matchers.front()->getOpcode(); +} + unsigned RuleMatcher::getNumOperands() const { return Matchers.front()->getNumOperands(); } @@ -1954,6 +1988,28 @@ public: } }; +void InstructionMatcher::optimize() { + SmallVector<std::unique_ptr<PredicateMatcher>, 8> Stash; + const auto &OpcMatcher = getOpcodeMatcher(); + + Stash.push_back(predicates_pop_front()); + if (Stash.back().get() == &OpcMatcher) { + if (NumOperandsCheck && OpcMatcher.getNumOperands() < getNumOperands()) + Stash.emplace_back( + new InstructionNumOperandsMatcher(InsnVarID, getNumOperands())); + NumOperandsCheck = false; + } + + if (InsnVarID > 0) { + assert(!Operands.empty() && "Nested instruction is expected to def a vreg"); + for (auto &OP : Operands[0]->predicates()) + OP.reset(); + Operands[0]->eraseNullPredicates(); + } + while (!Stash.empty()) + prependPredicate(Stash.pop_back_val()); +} + //===- Actions ------------------------------------------------------------===// class OperandRenderer { public: |