Changeset View
Changeset View
Standalone View
Standalone View
llvm/utils/TableGen/RISCVCompressInstEmitter.cpp
Show First 20 Lines • Show All 468 Lines • ▼ Show 20 Lines | void RISCVCompressInstEmitter::evaluateCompressPat(Record *Rec) { | ||||
copy_if(RF, std::back_inserter(PatReqFeatures), [](Record *R) { | copy_if(RF, std::back_inserter(PatReqFeatures), [](Record *R) { | ||||
return R->getValueAsBit("AssemblerMatcherPredicate"); | return R->getValueAsBit("AssemblerMatcherPredicate"); | ||||
}); | }); | ||||
CompressPatterns.push_back(CompressPat(SourceInst, DestInst, PatReqFeatures, | CompressPatterns.push_back(CompressPat(SourceInst, DestInst, PatReqFeatures, | ||||
SourceOperandMap, DestOperandMap)); | SourceOperandMap, DestOperandMap)); | ||||
} | } | ||||
static void getReqFeatures(std::set<StringRef> &FeaturesSet, | static void getReqFeatures(std::set<std::pair<bool, StringRef>> &FeaturesSet, | ||||
std::set<std::set<std::pair<bool, StringRef>>> &AnyOfFeatureSets, | |||||
const std::vector<Record *> &ReqFeatures) { | const std::vector<Record *> &ReqFeatures) { | ||||
for (auto &R : ReqFeatures) { | for (auto &R : ReqFeatures) { | ||||
StringRef AsmCondString = R->getValueAsString("AssemblerCondString"); | const DagInit *D = R->getValueAsDag("AssemblerCondDag"); | ||||
StringRef CombineType = D->getOperator()->getAsString(); | |||||
// AsmCondString has syntax [!]F(,[!]F)* | if (CombineType != "any_of" && CombineType != "all_of") | ||||
SmallVector<StringRef, 4> Ops; | PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!"); | ||||
SplitString(AsmCondString, Ops, ","); | if (D->getNumArgs() == 0) | ||||
assert(!Ops.empty() && "AssemblerCondString cannot be empty"); | PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!"); | ||||
for (auto &Op : Ops) { | bool IsOr = CombineType == "any_of"; | ||||
assert(!Op.empty() && "Empty operator"); | std::set<std::pair<bool, StringRef>> AnyOfSet; | ||||
FeaturesSet.insert(Op); | |||||
for (auto *Arg : D->getArgs()) { | |||||
bool IsNot = false; | |||||
if (auto *NotArg = dyn_cast<DagInit>(Arg)) { | |||||
if (NotArg->getOperator()->getAsString() != "not" || | |||||
NotArg->getNumArgs() != 1) | |||||
PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!"); | |||||
Arg = NotArg->getArg(0); | |||||
IsNot = true; | |||||
} | |||||
if (!isa<DefInit>(Arg) || | |||||
!cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature")) | |||||
PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!"); | |||||
if (IsOr) | |||||
AnyOfSet.insert({IsNot, cast<DefInit>(Arg)->getDef()->getName()}); | |||||
else | |||||
FeaturesSet.insert({IsNot, cast<DefInit>(Arg)->getDef()->getName()}); | |||||
} | } | ||||
if (IsOr) | |||||
AnyOfFeatureSets.insert(AnyOfSet); | |||||
} | } | ||||
} | } | ||||
static unsigned getPredicates(DenseMap<const Record *, unsigned> &PredicateMap, | static unsigned getPredicates(DenseMap<const Record *, unsigned> &PredicateMap, | ||||
std::vector<const Record *> &Predicates, | std::vector<const Record *> &Predicates, | ||||
Record *Rec, StringRef Name) { | Record *Rec, StringRef Name) { | ||||
unsigned Entry = PredicateMap[Rec]; | unsigned Entry = PredicateMap[Rec]; | ||||
if (Entry) | if (Entry) | ||||
▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | for (auto &CompressPat : CompressPatterns) { | ||||
CurOp = Source.TheDef->getName().str(); | CurOp = Source.TheDef->getName().str(); | ||||
// Check current and previous opcode to decide to continue or end a case. | // Check current and previous opcode to decide to continue or end a case. | ||||
if (CurOp != PrevOp) { | if (CurOp != PrevOp) { | ||||
if (PrevOp != "") | if (PrevOp != "") | ||||
CaseStream.indent(6) << "break;\n } // case " + PrevOp + "\n"; | CaseStream.indent(6) << "break;\n } // case " + PrevOp + "\n"; | ||||
CaseStream.indent(4) << "case " + Namespace + "::" + CurOp + ": {\n"; | CaseStream.indent(4) << "case " + Namespace + "::" + CurOp + ": {\n"; | ||||
} | } | ||||
std::set<StringRef> FeaturesSet; | std::set<std::pair<bool, StringRef>> FeaturesSet; | ||||
std::set<std::set<std::pair<bool, StringRef>>> AnyOfFeatureSets; | |||||
// Add CompressPat required features. | // Add CompressPat required features. | ||||
getReqFeatures(FeaturesSet, CompressPat.PatReqFeatures); | getReqFeatures(FeaturesSet, AnyOfFeatureSets, CompressPat.PatReqFeatures); | ||||
// Add Dest instruction required features. | // Add Dest instruction required features. | ||||
std::vector<Record *> ReqFeatures; | std::vector<Record *> ReqFeatures; | ||||
std::vector<Record *> RF = Dest.TheDef->getValueAsListOfDefs("Predicates"); | std::vector<Record *> RF = Dest.TheDef->getValueAsListOfDefs("Predicates"); | ||||
copy_if(RF, std::back_inserter(ReqFeatures), [](Record *R) { | copy_if(RF, std::back_inserter(ReqFeatures), [](Record *R) { | ||||
return R->getValueAsBit("AssemblerMatcherPredicate"); | return R->getValueAsBit("AssemblerMatcherPredicate"); | ||||
}); | }); | ||||
getReqFeatures(FeaturesSet, ReqFeatures); | getReqFeatures(FeaturesSet, AnyOfFeatureSets, ReqFeatures); | ||||
// Emit checks for all required features. | // Emit checks for all required features. | ||||
for (auto &Op : FeaturesSet) { | for (auto &Op : FeaturesSet) { | ||||
if (Op[0] == '!') | StringRef Not = Op.first ? "!" : ""; | ||||
CondStream.indent(6) << ("!STI.getFeatureBits()[" + Namespace + | |||||
"::" + Op.substr(1) + "]") | |||||
.str() + | |||||
" &&\n"; | |||||
else | |||||
CondStream.indent(6) | CondStream.indent(6) | ||||
<< ("STI.getFeatureBits()[" + Namespace + "::" + Op + "]").str() + | << Not << ("STI.getFeatureBits()[" + Namespace + "::" + Op.second + "]").str() + | ||||
" &&\n"; | " &&\n"; | ||||
} | } | ||||
// Emit checks for all required feature groups. | |||||
for (auto &Set : AnyOfFeatureSets) { | |||||
CondStream.indent(6) << "("; | |||||
for (auto &Op : Set) { | |||||
bool isLast = &Op == &*Set.rbegin(); | |||||
StringRef Not = Op.first ? "!" : ""; | |||||
CondStream << Not << ("STI.getFeatureBits()[" + Namespace + "::" + Op.second + | |||||
"]").str(); | |||||
if (!isLast) | |||||
CondStream << " || "; | |||||
} | |||||
CondStream << ") &&\n"; | |||||
} | |||||
// Start Source Inst operands validation. | // Start Source Inst operands validation. | ||||
unsigned OpNo = 0; | unsigned OpNo = 0; | ||||
for (OpNo = 0; OpNo < Source.Operands.size(); ++OpNo) { | for (OpNo = 0; OpNo < Source.Operands.size(); ++OpNo) { | ||||
if (SourceOperandMap[OpNo].TiedOpIdx != -1) { | if (SourceOperandMap[OpNo].TiedOpIdx != -1) { | ||||
if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClass")) | if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClass")) | ||||
CondStream.indent(6) | CondStream.indent(6) | ||||
<< "(MI.getOperand(" | << "(MI.getOperand(" | ||||
<< std::to_string(OpNo) + ").getReg() == MI.getOperand(" | << std::to_string(OpNo) + ").getReg() == MI.getOperand(" | ||||
▲ Show 20 Lines • Show All 198 Lines • Show Last 20 Lines |