Changeset View
Changeset View
Standalone View
Standalone View
llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
Show First 20 Lines • Show All 1,176 Lines • ▼ Show 20 Lines | unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, | ||||
// Make sure the predicate is in the table. | // Make sure the predicate is in the table. | ||||
Decoders.insert(CachedHashString(Decoder)); | Decoders.insert(CachedHashString(Decoder)); | ||||
// Now figure out the index for when we write out the table. | // Now figure out the index for when we write out the table. | ||||
DecoderSet::const_iterator P = find(Decoders, Decoder.str()); | DecoderSet::const_iterator P = find(Decoders, Decoder.str()); | ||||
return (unsigned)(P - Decoders.begin()); | return (unsigned)(P - Decoders.begin()); | ||||
} | } | ||||
static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, | |||||
const std::string &PredicateNamespace) { | |||||
if (str[0] == '!') | |||||
o << "!Bits[" << PredicateNamespace << "::" | |||||
<< str.slice(1,str.size()) << "]"; | |||||
else | |||||
o << "Bits[" << PredicateNamespace << "::" << str << "]"; | |||||
} | |||||
bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, | bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, | ||||
unsigned Opc) const { | unsigned Opc) const { | ||||
ListInit *Predicates = | ListInit *Predicates = | ||||
AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates"); | AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates"); | ||||
bool IsFirstEmission = true; | bool IsFirstEmission = true; | ||||
for (unsigned i = 0; i < Predicates->size(); ++i) { | for (unsigned i = 0; i < Predicates->size(); ++i) { | ||||
Record *Pred = Predicates->getElementAsRecord(i); | Record *Pred = Predicates->getElementAsRecord(i); | ||||
if (!Pred->getValue("AssemblerMatcherPredicate")) | if (!Pred->getValue("AssemblerMatcherPredicate")) | ||||
continue; | continue; | ||||
StringRef P = Pred->getValueAsString("AssemblerCondString"); | if (!dyn_cast<DagInit>(Pred->getValue("AssemblerCondDag")->getValue())) | ||||
if (P.empty()) | |||||
continue; | continue; | ||||
const DagInit *D = Pred->getValueAsDag("AssemblerCondDag"); | |||||
StringRef CombineType = D->getOperator()->getAsString(); | |||||
if (CombineType != "any_of" && CombineType != "all_of") | |||||
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!"); | |||||
if (D->getNumArgs() == 0) | |||||
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!"); | |||||
bool IsOr = CombineType == "any_of"; | |||||
if (!IsFirstEmission) | if (!IsFirstEmission) | ||||
o << " && "; | o << " && "; | ||||
std::pair<StringRef, StringRef> pairs = P.split(','); | if (IsOr) | ||||
while (!pairs.second.empty()) { | o << "("; | ||||
emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); | |||||
bool First = true; | |||||
for (auto *Arg : D->getArgs()) { | |||||
if (!First) { | |||||
if (IsOr) | |||||
o << " || "; | |||||
else | |||||
o << " && "; | o << " && "; | ||||
pairs = pairs.second.split(','); | |||||
} | } | ||||
emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); | if (auto *NotArg = dyn_cast<DagInit>(Arg)) { | ||||
if (NotArg->getOperator()->getAsString() != "not" || | |||||
NotArg->getNumArgs() != 1) | |||||
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!"); | |||||
Arg = NotArg->getArg(0); | |||||
o << "!"; | |||||
} | |||||
if (!isa<DefInit>(Arg) || | |||||
!cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature")) | |||||
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!"); | |||||
o << "Bits[" << Emitter->PredicateNamespace << "::" << Arg->getAsString() << "]"; | |||||
First = false; | |||||
} | |||||
if (IsOr) | |||||
o << ")"; | |||||
IsFirstEmission = false; | IsFirstEmission = false; | ||||
} | } | ||||
return !Predicates->empty(); | return !Predicates->empty(); | ||||
} | } | ||||
bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const { | bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const { | ||||
ListInit *Predicates = | ListInit *Predicates = | ||||
AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates"); | AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates"); | ||||
for (unsigned i = 0; i < Predicates->size(); ++i) { | for (unsigned i = 0; i < Predicates->size(); ++i) { | ||||
Record *Pred = Predicates->getElementAsRecord(i); | Record *Pred = Predicates->getElementAsRecord(i); | ||||
if (!Pred->getValue("AssemblerMatcherPredicate")) | if (!Pred->getValue("AssemblerMatcherPredicate")) | ||||
continue; | continue; | ||||
StringRef P = Pred->getValueAsString("AssemblerCondString"); | if (dyn_cast<DagInit>(Pred->getValue("AssemblerCondDag")->getValue())) | ||||
if (P.empty()) | |||||
continue; | |||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo, | unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo, | ||||
StringRef Predicate) const { | StringRef Predicate) const { | ||||
// Using the full predicate string as the key value here is a bit | // Using the full predicate string as the key value here is a bit | ||||
// heavyweight, but is effective. If the string comparisons become a | // heavyweight, but is effective. If the string comparisons become a | ||||
▲ Show 20 Lines • Show All 1,288 Lines • Show Last 20 Lines |