mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-15 06:29:05 +00:00
teach tblgen to be more aggressive when factoring CheckType nodes.
Now it will factor things like this: CheckType i32 ... CheckOpcode ISD::AND CheckType i64 ... into: SwitchType: i32: ... i64: CheckOpcode ISD::AND ... This shrinks hte table by a few bytes, nothing spectacular. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97908 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -220,6 +220,17 @@ static void SinkPatternPredicates(OwningPtr<Matcher> &MatcherPtr) {
|
|||||||
N->setNext(CPPM);
|
N->setNext(CPPM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// FindCheckType - Scan a series of matchers looking for a CheckType that can
|
||||||
|
/// be pulled up to the start of the matcher. Return null if we didn't find one
|
||||||
|
/// otherwise return the matcher.
|
||||||
|
static CheckTypeMatcher *FindCheckType(Matcher *M) {
|
||||||
|
for (; M; M = M->getNext())
|
||||||
|
if (CheckTypeMatcher *CTM = dyn_cast<CheckTypeMatcher>(M))
|
||||||
|
return CTM;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// FactorNodes - Turn matches like this:
|
/// FactorNodes - Turn matches like this:
|
||||||
/// Scope
|
/// Scope
|
||||||
/// OPC_CheckType i32
|
/// OPC_CheckType i32
|
||||||
@@ -287,19 +298,42 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
|
|||||||
// we can merge anything else into this matching group.
|
// we can merge anything else into this matching group.
|
||||||
unsigned Scan = OptionIdx;
|
unsigned Scan = OptionIdx;
|
||||||
while (1) {
|
while (1) {
|
||||||
while (Scan != e && Optn->isContradictory(OptionsToMatch[Scan]))
|
// If we ran out of stuff to scan, we're done.
|
||||||
++Scan;
|
if (Scan == e) break;
|
||||||
|
|
||||||
// Ok, we found something that isn't known to be contradictory. If it is
|
// If we found an entry that matches out matcher, merge it into the set to
|
||||||
// equal, we can merge it into the set of nodes to factor, if not, we have
|
// handle.
|
||||||
// to cease factoring.
|
if (Optn->isEqual(OptionsToMatch[Scan])) {
|
||||||
if (Scan == e || !Optn->isEqual(OptionsToMatch[Scan])) break;
|
// If is equal after all, add the option to EqualMatchers and remove it
|
||||||
|
// from OptionsToMatch.
|
||||||
|
EqualMatchers.push_back(OptionsToMatch[Scan]);
|
||||||
|
OptionsToMatch.erase(OptionsToMatch.begin()+Scan);
|
||||||
|
--e;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the option we're checking for contradicts the start of the list,
|
||||||
|
// skip over it.
|
||||||
|
if (Optn->isContradictory(OptionsToMatch[Scan])) {
|
||||||
|
++Scan;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// If is equal after all, add the option to EqualMatchers and remove it
|
// If we're scannig for a type comparison and the type comparison got
|
||||||
// from OptionsToMatch.
|
// moved late, see if we can pull it up.
|
||||||
EqualMatchers.push_back(OptionsToMatch[Scan]);
|
if (isa<CheckTypeMatcher>(Optn)) {
|
||||||
OptionsToMatch.erase(OptionsToMatch.begin()+Scan);
|
CheckTypeMatcher *CTM = FindCheckType(OptionsToMatch[Scan]);
|
||||||
--e;
|
if (CTM != 0 && CTM != OptionsToMatch[Scan] &&
|
||||||
|
CTM->canMoveBefore(OptionsToMatch[Scan])) {
|
||||||
|
Matcher *MatcherWithoutCTM = OptionsToMatch[Scan]->unlinkNode(CTM);
|
||||||
|
CTM->setNext(MatcherWithoutCTM);
|
||||||
|
OptionsToMatch[Scan] = CTM;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we don't know how to handle this entry, we have to bail.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Scan != e &&
|
if (Scan != e &&
|
||||||
@@ -363,9 +397,11 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
|
|||||||
// we can convert this Scope to be a OpcodeSwitch instead.
|
// we can convert this Scope to be a OpcodeSwitch instead.
|
||||||
bool AllOpcodeChecks = true, AllTypeChecks = true;
|
bool AllOpcodeChecks = true, AllTypeChecks = true;
|
||||||
for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
|
for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
|
||||||
if (!isa<CheckOpcodeMatcher>(NewOptionsToMatch[i])) {
|
// Check to see if this breaks a series of CheckOpcodeMatchers.
|
||||||
|
if (AllOpcodeChecks &&
|
||||||
|
!isa<CheckOpcodeMatcher>(NewOptionsToMatch[i])) {
|
||||||
#if 0
|
#if 0
|
||||||
if (i > 3 && AllOpcodeChecks) {
|
if (i > 3) {
|
||||||
errs() << "FAILING OPC #" << i << "\n";
|
errs() << "FAILING OPC #" << i << "\n";
|
||||||
NewOptionsToMatch[i]->dump();
|
NewOptionsToMatch[i]->dump();
|
||||||
}
|
}
|
||||||
@@ -373,20 +409,26 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
|
|||||||
AllOpcodeChecks = false;
|
AllOpcodeChecks = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isa<CheckTypeMatcher>(NewOptionsToMatch[i]) ||
|
// Check to see if this breaks a series of CheckTypeMatcher's.
|
||||||
// iPTR checks could alias any other case without us knowing, don't
|
if (AllTypeChecks) {
|
||||||
// bother with them.
|
CheckTypeMatcher *CTM = FindCheckType(NewOptionsToMatch[i]);
|
||||||
cast<CheckTypeMatcher>(NewOptionsToMatch[i])->getType() == MVT::iPTR) {
|
if (CTM == 0 ||
|
||||||
|
// iPTR checks could alias any other case without us knowing, don't
|
||||||
|
// bother with them.
|
||||||
|
CTM->getType() == MVT::iPTR ||
|
||||||
|
// If the CheckType isn't at the start of the list, see if we can move
|
||||||
|
// it there.
|
||||||
|
!CTM->canMoveBefore(NewOptionsToMatch[i])) {
|
||||||
#if 0
|
#if 0
|
||||||
if (i > 3 && AllTypeChecks) {
|
if (i > 3 && AllTypeChecks) {
|
||||||
errs() << "FAILING TYPE #" << i << "\n";
|
errs() << "FAILING TYPE #" << i << "\n";
|
||||||
NewOptionsToMatch[i]->dump();
|
NewOptionsToMatch[i]->dump();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
AllTypeChecks = false;
|
AllTypeChecks = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Can also do CheckChildNType.
|
|
||||||
|
|
||||||
// If all the options are CheckOpcode's, we can form the SwitchOpcode, woot.
|
// If all the options are CheckOpcode's, we can form the SwitchOpcode, woot.
|
||||||
if (AllOpcodeChecks) {
|
if (AllOpcodeChecks) {
|
||||||
@@ -405,16 +447,40 @@ static void FactorNodes(OwningPtr<Matcher> &MatcherPtr) {
|
|||||||
|
|
||||||
// If all the options are CheckType's, we can form the SwitchType, woot.
|
// If all the options are CheckType's, we can form the SwitchType, woot.
|
||||||
if (AllTypeChecks) {
|
if (AllTypeChecks) {
|
||||||
DenseSet<unsigned> Types;
|
DenseMap<unsigned, unsigned> TypeEntry;
|
||||||
SmallVector<std::pair<MVT::SimpleValueType, Matcher*>, 8> Cases;
|
SmallVector<std::pair<MVT::SimpleValueType, Matcher*>, 8> Cases;
|
||||||
for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
|
for (unsigned i = 0, e = NewOptionsToMatch.size(); i != e; ++i) {
|
||||||
CheckTypeMatcher *CTM = cast<CheckTypeMatcher>(NewOptionsToMatch[i]);
|
CheckTypeMatcher *CTM = FindCheckType(NewOptionsToMatch[i]);
|
||||||
assert(Types.insert(CTM->getType()).second &&
|
Matcher *MatcherWithoutCTM = NewOptionsToMatch[i]->unlinkNode(CTM);
|
||||||
"Duplicate types not factored?");
|
MVT::SimpleValueType CTMTy = CTM->getType();
|
||||||
Cases.push_back(std::make_pair(CTM->getType(), CTM->getNext()));
|
delete CTM;
|
||||||
|
|
||||||
|
unsigned &Entry = TypeEntry[CTMTy];
|
||||||
|
if (Entry != 0) {
|
||||||
|
// If we have unfactored duplicate types, then we should factor them.
|
||||||
|
Matcher *PrevMatcher = Cases[Entry-1].second;
|
||||||
|
if (ScopeMatcher *SM = dyn_cast<ScopeMatcher>(PrevMatcher)) {
|
||||||
|
SM->setNumChildren(SM->getNumChildren()+1);
|
||||||
|
SM->resetChild(SM->getNumChildren()-1, MatcherWithoutCTM);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matcher *Entries[2] = { PrevMatcher, MatcherWithoutCTM };
|
||||||
|
Cases[Entry-1].second = new ScopeMatcher(Entries, 2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry = Cases.size()+1;
|
||||||
|
Cases.push_back(std::make_pair(CTMTy, MatcherWithoutCTM));
|
||||||
}
|
}
|
||||||
|
|
||||||
MatcherPtr.reset(new SwitchTypeMatcher(&Cases[0], Cases.size()));
|
if (Cases.size() != 1) {
|
||||||
|
MatcherPtr.reset(new SwitchTypeMatcher(&Cases[0], Cases.size()));
|
||||||
|
} else {
|
||||||
|
// If we factored and ended up with one case, create it now.
|
||||||
|
MatcherPtr.reset(new CheckTypeMatcher(Cases[0].first));
|
||||||
|
MatcherPtr->setNext(Cases[0].second);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user