[GlobalISel][InstructionSelect] Switching over root LLTs, perf patch 10

This patch continues a series of patches started by r332907 (reapplied
as r332917).

In this commit we introduce new matching opcode for the MatchTable:
GIM_SwitchType, similar to GIM_SwitchOpcode, and use it to switch over
LLTs of def operands of root instructions on the 2nd level of the
MatchTable within GIM_SwitchOpcode's cases.

This is expected to decrease time GlobalISel spends in its
InstructionSelect pass by about 6.5% for an -O0 build as measured on
sqlite3-amalgamation (http://sqlite.org/download.html) targeting
AArch64 (cross-compile on x86).

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: 333146
This commit is contained in:
Roman Tereshin 2018-05-24 00:24:15 +00:00
parent 6cef421b34
commit a4c410d50d
3 changed files with 68 additions and 1 deletions

View File

@ -89,6 +89,15 @@ enum {
/// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets
GIM_SwitchOpcode,
/// Switch over the LLT on the specified instruction operand
/// - InsnID - Instruction ID
/// - OpIdx - Operand index
/// - LowerBound - numerically minimum Type ID supported
/// - UpperBound - numerically maximum + 1 Type ID supported
/// - Default - failure jump target
/// - JumpTable... - (UpperBound - LowerBound) (at least 2) jump targets
GIM_SwitchType,
/// Record the specified instruction
/// - NewInsnID - Instruction ID to define
/// - InsnID - Instruction ID
@ -371,11 +380,16 @@ public:
FeatureBitsets(FeatureBitsets),
ComplexPredicates(ComplexPredicates),
CustomRenderers(CustomRenderers) {
for (size_t I = 0; I < NumTypeObjects; ++I)
TypeIDMap[TypeObjects[I]] = I;
}
const LLT *TypeObjects;
const PredicateBitset *FeatureBitsets;
const ComplexMatcherMemFn *ComplexPredicates;
const CustomRendererFn *CustomRenderers;
SmallDenseMap<LLT, unsigned, 64> TypeIDMap;
};
protected:

View File

@ -180,6 +180,50 @@ bool InstructionSelector::executeMatchTable(
break;
}
case GIM_SwitchType: {
int64_t InsnID = MatchTable[CurrentIdx++];
int64_t OpIdx = MatchTable[CurrentIdx++];
int64_t LowerBound = MatchTable[CurrentIdx++];
int64_t UpperBound = MatchTable[CurrentIdx++];
int64_t Default = MatchTable[CurrentIdx++];
assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), {
dbgs() << CurrentIdx << ": GIM_SwitchType(MIs[" << InsnID
<< "]->getOperand(" << OpIdx << "), [" << LowerBound << ", "
<< UpperBound << "), Default=" << Default
<< ", JumpTable...) // Got=";
if (!MO.isReg())
dbgs() << "Not a VReg\n";
else
dbgs() << MRI.getType(MO.getReg()) << "\n";
});
if (!MO.isReg()) {
CurrentIdx = Default;
break;
}
const LLT Ty = MRI.getType(MO.getReg());
const auto TyI = ISelInfo.TypeIDMap.find(Ty);
if (TyI == ISelInfo.TypeIDMap.end()) {
CurrentIdx = Default;
break;
}
const int64_t TypeID = TyI->second;
if (TypeID < LowerBound || UpperBound <= TypeID) {
CurrentIdx = Default;
break;
}
CurrentIdx = MatchTable[CurrentIdx + (TypeID - LowerBound)];
if (!CurrentIdx) {
CurrentIdx = Default;
break;
}
OnFailResumeAt.push_back(Default);
break;
}
case GIM_CheckNumOperands: {
int64_t InsnID = MatchTable[CurrentIdx++];
int64_t Expected = MatchTable[CurrentIdx++];

View File

@ -4153,6 +4153,8 @@ void GroupMatcher::optimize() {
}
GlobalISelEmitter::optimizeRules<GroupMatcher>(Matchers, MatcherStorage)
.swap(Matchers);
GlobalISelEmitter::optimizeRules<SwitchMatcher>(Matchers, MatcherStorage)
.swap(Matchers);
}
void GlobalISelEmitter::run(raw_ostream &OS) {
@ -4641,7 +4643,7 @@ void GroupMatcher::emit(MatchTable &Table) {
}
bool SwitchMatcher::isSupportedPredicateType(const PredicateMatcher &P) {
return isa<InstructionOpcodeMatcher>(P);
return isa<InstructionOpcodeMatcher>(P) || isa<LLTOperandMatcher>(P);
}
bool SwitchMatcher::candidateConditionMatches(
@ -4717,6 +4719,13 @@ void SwitchMatcher::emitPredicateSpecificOpcodes(const PredicateMatcher &P,
<< MatchTable::IntValue(Condition->getInsnVarID());
return;
}
if (const auto *Condition = dyn_cast<LLTOperandMatcher>(&P)) {
Table << MatchTable::Opcode("GIM_SwitchType") << MatchTable::Comment("MI")
<< MatchTable::IntValue(Condition->getInsnVarID())
<< MatchTable::Comment("Op")
<< MatchTable::IntValue(Condition->getOpIdx());
return;
}
llvm_unreachable("emitPredicateSpecificOpcodes is broken: can not handle a "
"predicate type that is claimed to be supported");