[TableGen] Add field kind to the RecordVal class.

Differential Revision: https://reviews.llvm.org/D93969
This commit is contained in:
Paul C. Anagnostopoulos 2020-12-31 14:50:51 -05:00
parent b73736a404
commit aa7968a87b
6 changed files with 41 additions and 22 deletions

View File

@ -1369,14 +1369,22 @@ public:
class RecordVal {
friend class Record;
public:
enum FieldKind {
FK_Normal, // A normal record field.
FK_NonconcreteOK, // A field that can be nonconcrete ('field' keyword).
FK_TemplateArg, // A template argument.
};
private:
Init *Name;
SMLoc Loc; // Source location of definition of name.
PointerIntPair<RecTy *, 1, bool> TyAndPrefix;
PointerIntPair<RecTy *, 2, FieldKind> TyAndKind;
Init *Value;
public:
RecordVal(Init *N, RecTy *T, bool P);
RecordVal(Init *N, SMLoc Loc, RecTy *T, bool P);
RecordVal(Init *N, RecTy *T, FieldKind K);
RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K);
/// Get the name of the field as a StringRef.
StringRef getName() const;
@ -1392,10 +1400,18 @@ public:
/// Get the source location of the point where the field was defined.
const SMLoc &getLoc() const { return Loc; }
bool getPrefix() const { return TyAndPrefix.getInt(); }
/// Is this a field where nonconcrete values are okay?
bool isNonconcreteOK() const {
return TyAndKind.getInt() == FK_NonconcreteOK;
}
/// Is this a template argument?
bool isTemplateArg() const {
return TyAndKind.getInt() == FK_TemplateArg;
}
/// Get the type of the field value as a RecTy.
RecTy *getType() const { return TyAndPrefix.getPointer(); }
RecTy *getType() const { return TyAndKind.getPointer(); }
/// Get the type of the field for printing purposes.
std::string getPrintType() const;

View File

@ -144,7 +144,7 @@ void JSONEmitter::run(raw_ostream &OS) {
for (const RecordVal &RV : Def.getValues()) {
if (!Def.isTemplateArg(RV.getNameInit())) {
auto Name = RV.getNameInitAsString();
if (RV.getPrefix())
if (RV.isNonconcreteOK())
fields.push_back(Name);
obj[Name] = translateInit(*RV.getValue());
}

View File

@ -2141,16 +2141,16 @@ std::string DagInit::getAsString() const {
// Other implementations
//===----------------------------------------------------------------------===//
RecordVal::RecordVal(Init *N, RecTy *T, bool P)
: Name(N), TyAndPrefix(T, P) {
RecordVal::RecordVal(Init *N, RecTy *T, FieldKind K)
: Name(N), TyAndKind(T, K) {
setValue(UnsetInit::get());
assert(Value && "Cannot create unset value for current type!");
}
// This constructor accepts the same arguments as the above, but also
// a source location.
RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, bool P)
: Name(N), Loc(Loc), TyAndPrefix(T, P) {
RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K)
: Name(N), Loc(Loc), TyAndKind(T, K) {
setValue(UnsetInit::get());
assert(Value && "Cannot create unset value for current type!");
}
@ -2170,7 +2170,7 @@ std::string RecordVal::getPrintType() const {
return "string";
}
} else {
return TyAndPrefix.getPointer()->getAsString();
return TyAndKind.getPointer()->getAsString();
}
}
@ -2227,7 +2227,7 @@ LLVM_DUMP_METHOD void RecordVal::dump() const { errs() << *this; }
#endif
void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
if (getPrefix()) OS << "field ";
if (isNonconcreteOK()) OS << "field ";
OS << getPrintType() << " " << getNameInitAsString();
if (getValue())
@ -2368,10 +2368,10 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
OS << "\n";
for (const RecordVal &Val : R.getValues())
if (Val.getPrefix() && !R.isTemplateArg(Val.getNameInit()))
if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
OS << Val;
for (const RecordVal &Val : R.getValues())
if (!Val.getPrefix() && !R.isTemplateArg(Val.getNameInit()))
if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
OS << Val;
return OS << "}\n";

View File

@ -95,7 +95,7 @@ static void checkConcrete(Record &R) {
// done merely because existing targets have legitimate cases of
// non-concrete variables in helper defs. Ideally, we'd introduce a
// 'maybe' or 'optional' modifier instead of this.
if (RV.getPrefix())
if (RV.isNonconcreteOK())
continue;
if (Init *V = RV.getValue()) {
@ -1596,8 +1596,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
ParseRec = ParseRecTmp.get();
}
ParseRec->addValue(RecordVal(A, Start->getType(), false));
ParseRec->addValue(RecordVal(B, ListType->getElementType(), false));
ParseRec->addValue(RecordVal(A, Start->getType(), RecordVal::FK_Normal));
ParseRec->addValue(RecordVal(B, ListType->getElementType(),
RecordVal::FK_Normal));
Init *ExprUntyped = ParseValue(ParseRec);
ParseRec->removeValue(A);
ParseRec->removeValue(B);
@ -1845,7 +1846,7 @@ Init *TGParser::ParseOperationForEachFilter(Record *CurRec, RecTy *ItemType) {
ParseRec = ParseRecTmp.get();
}
ParseRec->addValue(RecordVal(LHS, InEltType, false));
ParseRec->addValue(RecordVal(LHS, InEltType, RecordVal::FK_Normal));
Init *RHS = ParseValue(ParseRec, ExprEltType);
ParseRec->removeValue(LHS);
if (!RHS)
@ -2618,8 +2619,10 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
"::");
}
// Add the value.
if (AddValue(CurRec, IdLoc, RecordVal(DeclName, IdLoc, Type, HasField)))
// Add the field to the record.
if (AddValue(CurRec, IdLoc, RecordVal(DeclName, IdLoc, Type,
HasField ? RecordVal::FK_NonconcreteOK
: RecordVal::FK_Normal)))
return nullptr;
// If a value is present, parse it.

View File

@ -311,7 +311,7 @@ std::string CodeEmitterGen::getInstructionCaseForEncoding(Record *R, Record *Enc
for (const RecordVal &RV : EncodingDef->getValues()) {
// Ignore fixed fields in the record, we're looking for values like:
// bits<5> RST = { ?, ?, ?, ?, ? };
if (RV.getPrefix() || RV.getValue()->isComplete())
if (RV.isNonconcreteOK() || RV.getValue()->isComplete())
continue;
AddCodeToMergeInOperand(R, BI, std::string(RV.getName()), NumberedOp,

View File

@ -1887,7 +1887,7 @@ populateInstruction(CodeGenTarget &Target, const Record &EncodingDef,
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
// Ignore fixed fields in the record, we're looking for values like:
// bits<5> RST = { ?, ?, ?, ?, ? };
if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
if (Vals[i].isNonconcreteOK() || Vals[i].getValue()->isComplete())
continue;
// Determine if Vals[i] actually contributes to the Inst encoding.