Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions llvm/utils/TableGen/AsmMatcherEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1712,11 +1712,11 @@ void AsmMatcherInfo::buildInstructionOperandReference(MatchableInfo *II,
MatchableInfo::AsmOperand *Op = &II->AsmOperands[AsmOpIdx];

// Map this token to an operand.
unsigned Idx;
if (!Operands.hasOperandNamed(OperandName, Idx))
std::optional<unsigned> MayBeIdx = Operands.findOperandNamed(OperandName);
if (!MayBeIdx)
PrintFatalError(II->TheDef->getLoc(),
"error: unable to find operand: '" + OperandName + "'");

unsigned Idx = *MayBeIdx;
// If the instruction operand has multiple suboperands, but the parser
// match class for the asm operand is still the default "ImmAsmOperand",
// then handle each suboperand separately.
Expand Down
9 changes: 4 additions & 5 deletions llvm/utils/TableGen/CodeEmitterGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,11 @@ bool CodeEmitterGen::addCodeToMergeInOperand(const Record *R,
// operand number. Non-matching operands are assumed to be in
// order.
unsigned OpIdx;
std::pair<unsigned, unsigned> SubOp;
if (CGI.Operands.hasSubOperandAlias(VarName, SubOp)) {
OpIdx = CGI.Operands[SubOp.first].MIOperandNo + SubOp.second;
} else if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
if (auto SubOp = CGI.Operands.findSubOperandAlias(VarName)) {
OpIdx = CGI.Operands[SubOp->first].MIOperandNo + SubOp->second;
} else if (auto MayBeOpIdx = CGI.Operands.findOperandNamed(VarName)) {
// Get the machine operand number for the indicated operand.
OpIdx = CGI.Operands[OpIdx].MIOperandNo;
OpIdx = CGI.Operands[*MayBeOpIdx].MIOperandNo;
} else {
PrintError(R, Twine("No operand named ") + VarName + " in record " +
R->getName());
Expand Down
47 changes: 20 additions & 27 deletions llvm/utils/TableGen/Common/CodeGenInstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ CGIOperandList::CGIOperandList(const Record *R) : TheDef(R) {
// If we have no explicit sub-op dag, but have an top-level encoder
// method, the single encoder will multiple sub-ops, itself.
OpInfo.EncoderMethodNames[0] = EncoderMethod;
for (unsigned j = 1; j < NumOps; ++j)
OpInfo.DoNotEncode[j] = true;
OpInfo.DoNotEncode.set();
OpInfo.DoNotEncode[0] = false;
}

MIOperandNo += NumOps;
Expand All @@ -199,36 +199,31 @@ CGIOperandList::CGIOperandList(const Record *R) : TheDef(R) {
/// specified name, abort.
///
unsigned CGIOperandList::getOperandNamed(StringRef Name) const {
unsigned OpIdx;
if (hasOperandNamed(Name, OpIdx))
return OpIdx;
std::optional<unsigned> OpIdx = findOperandNamed(Name);
if (OpIdx)
return *OpIdx;
PrintFatalError(TheDef->getLoc(), "'" + TheDef->getName() +
"' does not have an operand named '$" +
Name + "'!");
}

/// hasOperandNamed - Query whether the instruction has an operand of the
/// given name. If so, return true and set OpIdx to the index of the
/// operand. Otherwise, return false.
bool CGIOperandList::hasOperandNamed(StringRef Name, unsigned &OpIdx) const {
/// findOperandNamed - Query whether the instruction has an operand of the
/// given name. If so, the index of the operand. Otherwise, return std::nullopt.
std::optional<unsigned> CGIOperandList::findOperandNamed(StringRef Name) const {
assert(!Name.empty() && "Cannot search for operand with no name!");
for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
if (OperandList[i].Name == Name) {
OpIdx = i;
return true;
}
return false;
for (const auto &[Index, Opnd] : enumerate(OperandList))
if (Opnd.Name == Name)
return Index;
return std::nullopt;
}

bool CGIOperandList::hasSubOperandAlias(
StringRef Name, std::pair<unsigned, unsigned> &SubOp) const {
std::optional<std::pair<unsigned, unsigned>>
CGIOperandList::findSubOperandAlias(StringRef Name) const {
assert(!Name.empty() && "Cannot search for operand with no name!");
auto SubOpIter = SubOpAliases.find(Name);
if (SubOpIter != SubOpAliases.end()) {
SubOp = SubOpIter->second;
return true;
}
return false;
if (SubOpIter != SubOpAliases.end())
return SubOpIter->second;
return std::nullopt;
}

std::pair<unsigned, unsigned>
Expand All @@ -251,9 +246,7 @@ CGIOperandList::ParseOperandName(StringRef Op, bool AllowWholeOp) {
OpName = OpName.substr(0, DotIdx);
}

unsigned OpIdx;

if (std::pair<unsigned, unsigned> SubOp; hasSubOperandAlias(OpName, SubOp)) {
if (auto SubOp = findSubOperandAlias(OpName)) {
// Found a name for a piece of an operand, just return it directly.
if (!SubOpName.empty()) {
PrintFatalError(
Expand All @@ -262,10 +255,10 @@ CGIOperandList::ParseOperandName(StringRef Op, bool AllowWholeOp) {
": Cannot use dotted suboperand name within suboperand '" +
OpName + "'");
}
return SubOp;
return *SubOp;
}

OpIdx = getOperandNamed(OpName);
unsigned OpIdx = getOperandNamed(OpName);

if (SubOpName.empty()) { // If no suboperand name was specified:
// If one was needed, throw.
Expand Down
15 changes: 7 additions & 8 deletions llvm/utils/TableGen/Common/CodeGenInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,9 @@ class CGIOperandList {
/// getTiedOperand - If this operand is tied to another one, return the
/// other operand number. Otherwise, return -1.
int getTiedRegister() const {
for (const CGIOperandList::ConstraintInfo &CI : Constraints) {
for (const CGIOperandList::ConstraintInfo &CI : Constraints)
if (CI.isTied())
return CI.getTiedOperand();
}
return -1;
}
};
Expand Down Expand Up @@ -176,13 +175,13 @@ class CGIOperandList {
/// specified name, abort.
unsigned getOperandNamed(StringRef Name) const;

/// hasOperandNamed - Query whether the instruction has an operand of the
/// given name. If so, return true and set OpIdx to the index of the
/// operand. Otherwise, return false.
bool hasOperandNamed(StringRef Name, unsigned &OpIdx) const;
/// findOperandNamed - Query whether the instruction has an operand of the
/// given name. If so, the index of the operand. Otherwise, return
/// std::nullopt.
std::optional<unsigned> findOperandNamed(StringRef Name) const;

bool hasSubOperandAlias(StringRef Name,
std::pair<unsigned, unsigned> &SubOp) const;
std::optional<std::pair<unsigned, unsigned>>
findSubOperandAlias(StringRef Name) const;

/// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
/// where $foo is a whole operand and $foo.bar refers to a suboperand.
Expand Down
Loading