forked from OSchip/llvm-project
[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:
parent
6cef421b34
commit
a4c410d50d
|
@ -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:
|
||||
|
|
|
@ -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++];
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue