aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/CompressInstEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/CompressInstEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/CompressInstEmitter.cpp233
1 files changed, 130 insertions, 103 deletions
diff --git a/llvm/utils/TableGen/CompressInstEmitter.cpp b/llvm/utils/TableGen/CompressInstEmitter.cpp
index 331cea1..89c175b 100644
--- a/llvm/utils/TableGen/CompressInstEmitter.cpp
+++ b/llvm/utils/TableGen/CompressInstEmitter.cpp
@@ -86,16 +86,22 @@ namespace {
class CompressInstEmitter {
struct OpData {
enum MapKind { Operand, Imm, Reg } Kind;
- union {
+ // Info for an operand.
+ struct OpndInfo {
+ // Record from the Dag.
+ const Record *DagRec;
// Operand number mapped to.
- unsigned OpNo;
+ unsigned Idx;
+ // Tied operand index within the instruction.
+ int TiedOpIdx;
+ };
+ union {
+ OpndInfo OpInfo;
// Integer immediate value.
int64_t ImmVal;
// Physical register.
const Record *RegRec;
};
- // Tied operand index within the instruction.
- int TiedOpIdx = -1;
};
struct ArgData {
unsigned DAGOpNo;
@@ -273,6 +279,31 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
"' in the corresponding instruction operand!");
OperandMap[OpNo].Kind = OpData::Operand;
+ OperandMap[OpNo].OpInfo.DagRec = DI->getDef();
+ OperandMap[OpNo].OpInfo.TiedOpIdx = -1;
+
+ // Create a mapping between the operand name in the Dag (e.g. $rs1) and
+ // its index in the list of Dag operands and check that operands with
+ // the same name have the same type. For example in 'C_ADD $rs1, $rs2'
+ // we generate the mapping $rs1 --> 0, $rs2 ---> 1. If the operand
+ // appears twice in the same Dag (tied in the compressed instruction),
+ // we note the previous index in the TiedOpIdx field.
+ StringRef ArgName = Dag->getArgNameStr(DAGOpNo);
+ if (ArgName.empty())
+ continue;
+
+ if (IsSourceInst) {
+ auto It = Operands.find(ArgName);
+ if (It != Operands.end()) {
+ OperandMap[OpNo].OpInfo.TiedOpIdx = It->getValue().MIOpNo;
+ if (OperandMap[It->getValue().MIOpNo].OpInfo.DagRec != DI->getDef())
+ PrintFatalError(Rec->getLoc(),
+ "Input Operand '" + ArgName +
+ "' has a mismatched tied operand!");
+ }
+ }
+
+ Operands[ArgName] = {DAGOpNo, OpNo};
} else if (const auto *II = dyn_cast<IntInit>(Dag->getArg(DAGOpNo))) {
// Validate that corresponding instruction operand expects an immediate.
if (!OpndRec->isSubClassOf("Operand"))
@@ -292,30 +323,6 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
} else {
llvm_unreachable("Unhandled CompressPat argument type!");
}
-
- // Create a mapping between the operand name in the Dag (e.g. $rs1) and
- // its index in the list of Dag operands and check that operands with the
- // same name have the same type. For example in 'C_ADD $rs1, $rs2' we
- // generate the mapping $rs1 --> 0, $rs2 ---> 1. If the operand appears
- // twice in the same Dag (tied in the compressed instruction), we note
- // the previous index in the TiedOpIdx field.
- StringRef ArgName = Dag->getArgNameStr(DAGOpNo);
- if (ArgName.empty())
- continue;
-
- if (IsSourceInst) {
- auto It = Operands.find(ArgName);
- if (It != Operands.end()) {
- OperandMap[OpNo].TiedOpIdx = It->getValue().MIOpNo;
- if (!validateArgsTypes(Dag->getArg(It->getValue().DAGOpNo),
- Dag->getArg(DAGOpNo)))
- PrintFatalError(Rec->getLoc(),
- "Input Operand '" + ArgName +
- "' has a mismatched tied operand!");
- }
- }
-
- Operands[ArgName] = {DAGOpNo, OpNo};
}
}
@@ -372,8 +379,9 @@ void CompressInstEmitter::createInstOperandMapping(
if (DestOperandMap[OpNo].Kind == OpData::Operand)
// No need to fill the SourceOperandMap here since it was mapped to
// destination operand 'TiedInstOpIdx' in a previous iteration.
- LLVM_DEBUG(dbgs() << " " << DestOperandMap[OpNo].OpNo << " ====> "
- << OpNo << " Dest operand tied with operand '"
+ LLVM_DEBUG(dbgs() << " " << DestOperandMap[OpNo].OpInfo.Idx
+ << " ====> " << OpNo
+ << " Dest operand tied with operand '"
<< TiedInstOpIdx << "'\n");
++OpNo;
continue;
@@ -398,8 +406,8 @@ void CompressInstEmitter::createInstOperandMapping(
"Incorrect operand mapping detected!\n");
unsigned SourceOpNo = SourceOp->getValue().MIOpNo;
- DestOperandMap[OpNo].OpNo = SourceOpNo;
- SourceOperandMap[SourceOpNo].OpNo = OpNo;
+ DestOperandMap[OpNo].OpInfo.Idx = SourceOpNo;
+ SourceOperandMap[SourceOpNo].OpInfo.Idx = OpNo;
LLVM_DEBUG(dbgs() << " " << SourceOpNo << " ====> " << OpNo << "\n");
}
}
@@ -558,8 +566,6 @@ static void printPredicates(ArrayRef<const Record *> Predicates, StringRef Name,
static void mergeCondAndCode(raw_ostream &CombinedStream, StringRef CondStr,
StringRef CodeStr) {
- // Remove first indentation and last '&&'.
- CondStr = CondStr.drop_front(8).drop_back(4);
CombinedStream.indent(4) << "if (" << CondStr << ") {\n";
CombinedStream << CodeStr;
CombinedStream.indent(4) << " return true;\n";
@@ -640,7 +646,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
StringRef PrevOp;
StringRef CurOp;
CaseStream << " switch (MI.getOpcode()) {\n";
- CaseStream << " default: return false;\n";
+ CaseStream << " default: return false;\n";
bool CompressOrCheck =
EType == EmitterType::Compress || EType == EmitterType::CheckCompress;
@@ -653,7 +659,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
.str()
: "";
- for (auto &CompressPat : CompressPatterns) {
+ for (const auto &CompressPat : CompressPatterns) {
if (EType == EmitterType::Uncompress && CompressPat.IsCompressOnly)
continue;
@@ -661,23 +667,25 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
std::string CodeString;
raw_string_ostream CondStream(CondString);
raw_string_ostream CodeStream(CodeString);
- CodeGenInstruction &Source =
+ const CodeGenInstruction &Source =
CompressOrCheck ? CompressPat.Source : CompressPat.Dest;
- CodeGenInstruction &Dest =
+ const CodeGenInstruction &Dest =
CompressOrCheck ? CompressPat.Dest : CompressPat.Source;
- IndexedMap<OpData> SourceOperandMap = CompressOrCheck
- ? CompressPat.SourceOperandMap
- : CompressPat.DestOperandMap;
- IndexedMap<OpData> &DestOperandMap = CompressOrCheck
- ? CompressPat.DestOperandMap
- : CompressPat.SourceOperandMap;
+ const IndexedMap<OpData> &SourceOperandMap =
+ CompressOrCheck ? CompressPat.SourceOperandMap
+ : CompressPat.DestOperandMap;
+ const IndexedMap<OpData> &DestOperandMap =
+ CompressOrCheck ? CompressPat.DestOperandMap
+ : CompressPat.SourceOperandMap;
CurOp = Source.TheDef->getName();
// Check current and previous opcode to decide to continue or end a case.
if (CurOp != PrevOp) {
- if (!PrevOp.empty())
- CaseStream.indent(6) << "break;\n } // case " + PrevOp + "\n";
- CaseStream.indent(4) << "case " + TargetName + "::" + CurOp + ": {\n";
+ if (!PrevOp.empty()) {
+ CaseStream.indent(4) << "break;\n";
+ CaseStream.indent(2) << "} // case " + PrevOp + "\n";
+ }
+ CaseStream.indent(2) << "case " + TargetName + "::" + CurOp + ": {\n";
}
std::set<std::pair<bool, StringRef>> FeaturesSet;
@@ -694,17 +702,18 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
});
getReqFeatures(FeaturesSet, AnyOfFeatureSets, ReqFeatures);
+ ListSeparator CondSep(" &&\n ");
+
// Emit checks for all required features.
for (auto &Op : FeaturesSet) {
StringRef Not = Op.first ? "!" : "";
- CondStream.indent(8) << Not << "STI.getFeatureBits()[" << TargetName
- << "::" << Op.second << "]"
- << " &&\n";
+ CondStream << CondSep << Not << "STI.getFeatureBits()[" << TargetName
+ << "::" << Op.second << "]";
}
// Emit checks for all required feature groups.
for (auto &Set : AnyOfFeatureSets) {
- CondStream.indent(8) << "(";
+ CondStream << CondSep << "(";
for (auto &Op : Set) {
bool IsLast = &Op == &*Set.rbegin();
StringRef Not = Op.first ? "!" : "";
@@ -713,41 +722,43 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
if (!IsLast)
CondStream << " || ";
}
- CondStream << ") &&\n";
+ CondStream << ")";
}
// Start Source Inst operands validation.
unsigned OpNo = 0;
for (const auto &SourceOperand : Source.Operands) {
- if (SourceOperandMap[OpNo].TiedOpIdx != -1) {
- if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClass"))
- CondStream.indent(8)
- << "(MI.getOperand(" << OpNo << ").isReg()) && (MI.getOperand("
- << SourceOperandMap[OpNo].TiedOpIdx << ").isReg()) &&\n"
- << indent(8) << "(MI.getOperand(" << OpNo
- << ").getReg() == MI.getOperand("
- << SourceOperandMap[OpNo].TiedOpIdx << ").getReg()) &&\n";
- else
- PrintFatalError("Unexpected tied operand types!");
- }
for (unsigned SubOp = 0; SubOp != SourceOperand.MINumOperands; ++SubOp) {
// Check for fixed immediates\registers in the source instruction.
switch (SourceOperandMap[OpNo].Kind) {
case OpData::Operand:
+ if (SourceOperandMap[OpNo].OpInfo.TiedOpIdx != -1) {
+ if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClass"))
+ CondStream << CondSep << "MI.getOperand(" << OpNo
+ << ").isReg() && MI.getOperand("
+ << SourceOperandMap[OpNo].OpInfo.TiedOpIdx
+ << ").isReg()" << CondSep << "(MI.getOperand(" << OpNo
+ << ").getReg() == MI.getOperand("
+ << SourceOperandMap[OpNo].OpInfo.TiedOpIdx
+ << ").getReg())";
+ else
+ PrintFatalError("Unexpected tied operand types!");
+ }
+
// We don't need to do anything for source instruction operand checks.
break;
case OpData::Imm:
- CondStream.indent(8)
- << "(MI.getOperand(" << OpNo << ").isImm()) &&\n"
- << " (MI.getOperand(" << OpNo
- << ").getImm() == " << SourceOperandMap[OpNo].ImmVal << ") &&\n";
+ CondStream << CondSep << "MI.getOperand(" << OpNo << ").isImm()"
+ << CondSep << "(MI.getOperand(" << OpNo
+ << ").getImm() == " << SourceOperandMap[OpNo].ImmVal
+ << ")";
break;
case OpData::Reg: {
const Record *Reg = SourceOperandMap[OpNo].RegRec;
- CondStream.indent(8) << "(MI.getOperand(" << OpNo << ").isReg()) &&\n"
- << indent(8) << "(MI.getOperand(" << OpNo
- << ").getReg() == " << TargetName
- << "::" << Reg->getName() << ") &&\n";
+ CondStream << CondSep << "MI.getOperand(" << OpNo << ").isReg()"
+ << CondSep << "(MI.getOperand(" << OpNo
+ << ").getReg() == " << TargetName << "::" << Reg->getName()
+ << ")";
break;
}
}
@@ -771,27 +782,27 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
switch (DestOperandMap[OpNo].Kind) {
case OpData::Operand: {
- unsigned OpIdx = DestOperandMap[OpNo].OpNo;
+ unsigned OpIdx = DestOperandMap[OpNo].OpInfo.Idx;
+ const Record *DagRec = DestOperandMap[OpNo].OpInfo.DagRec;
// Check that the operand in the Source instruction fits
// the type for the Dest instruction.
- if (DestRec->isSubClassOf("RegisterClass") ||
- DestRec->isSubClassOf("RegisterOperand")) {
- auto *ClassRec = DestRec->isSubClassOf("RegisterClass")
- ? DestRec
- : DestRec->getValueAsDef("RegClass");
+ if (DagRec->isSubClassOf("RegisterClass") ||
+ DagRec->isSubClassOf("RegisterOperand")) {
+ auto *ClassRec = DagRec->isSubClassOf("RegisterClass")
+ ? DagRec
+ : DagRec->getValueAsDef("RegClass");
// This is a register operand. Check the register class.
// Don't check register class if this is a tied operand, it was done
- // for the operand its tied to.
+ // for the operand it's tied to.
if (DestOperand.getTiedRegister() == -1) {
- CondStream.indent(8) << "MI.getOperand(" << OpIdx << ").isReg()";
+ CondStream << CondSep << "MI.getOperand(" << OpIdx << ").isReg()";
if (EType == EmitterType::CheckCompress)
CondStream << " && MI.getOperand(" << OpIdx
<< ").getReg().isPhysical()";
- CondStream << " &&\n"
- << indent(8) << TargetName << "MCRegisterClasses["
+ CondStream << CondSep << TargetName << "MCRegisterClasses["
<< TargetName << "::" << ClassRec->getName()
<< "RegClassID].contains(MI.getOperand(" << OpIdx
- << ").getReg()) &&\n";
+ << ").getReg())";
}
if (CompressOrUncompress)
@@ -801,19 +812,35 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
// Handling immediate operands.
if (CompressOrUncompress) {
unsigned Entry = getPredicates(MCOpPredicateMap, MCOpPredicates,
- DestRec, "MCOperandPredicate");
- CondStream.indent(8) << ValidatorName << "("
- << "MI.getOperand(" << OpIdx << "), STI, "
- << Entry << ") &&\n";
+ DagRec, "MCOperandPredicate");
+ CondStream << CondSep << ValidatorName << "("
+ << "MI.getOperand(" << OpIdx << "), STI, " << Entry
+ << " /* " << DagRec->getName() << " */)";
+ // Also check DestRec if different than DagRec.
+ if (DagRec != DestRec) {
+ Entry = getPredicates(MCOpPredicateMap, MCOpPredicates, DestRec,
+ "MCOperandPredicate");
+ CondStream << CondSep << ValidatorName << "("
+ << "MI.getOperand(" << OpIdx << "), STI, " << Entry
+ << " /* " << DestRec->getName() << " */)";
+ }
} else {
unsigned Entry =
- getPredicates(ImmLeafPredicateMap, ImmLeafPredicates, DestRec,
+ getPredicates(ImmLeafPredicateMap, ImmLeafPredicates, DagRec,
"ImmediateCode");
- CondStream.indent(8)
- << "MI.getOperand(" << OpIdx << ").isImm() &&\n";
- CondStream.indent(8) << TargetName << "ValidateMachineOperand("
- << "MI.getOperand(" << OpIdx << "), &STI, "
- << Entry << ") &&\n";
+ CondStream << CondSep << "MI.getOperand(" << OpIdx << ").isImm()";
+ CondStream << CondSep << TargetName << "ValidateMachineOperand("
+ << "MI.getOperand(" << OpIdx << "), &STI, " << Entry
+ << " /* " << DagRec->getName() << " */)";
+ if (DagRec != DestRec) {
+ Entry = getPredicates(ImmLeafPredicateMap, ImmLeafPredicates,
+ DestRec, "ImmediateCode");
+ CondStream << CondSep << "MI.getOperand(" << OpIdx
+ << ").isImm()";
+ CondStream << CondSep << TargetName << "ValidateMachineOperand("
+ << "MI.getOperand(" << OpIdx << "), &STI, " << Entry
+ << " /* " << DestRec->getName() << " */)";
+ }
}
if (CompressOrUncompress)
CodeStream.indent(6)
@@ -825,19 +852,18 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
if (CompressOrUncompress) {
unsigned Entry = getPredicates(MCOpPredicateMap, MCOpPredicates,
DestRec, "MCOperandPredicate");
- CondStream.indent(8)
- << ValidatorName << "("
- << "MCOperand::createImm(" << DestOperandMap[OpNo].ImmVal
- << "), STI, " << Entry << ") &&\n";
+ CondStream << CondSep << ValidatorName << "("
+ << "MCOperand::createImm(" << DestOperandMap[OpNo].ImmVal
+ << "), STI, " << Entry << " /* " << DestRec->getName()
+ << " */)";
} else {
unsigned Entry =
getPredicates(ImmLeafPredicateMap, ImmLeafPredicates, DestRec,
"ImmediateCode");
- CondStream.indent(8)
- << TargetName
- << "ValidateMachineOperand(MachineOperand::CreateImm("
- << DestOperandMap[OpNo].ImmVal << "), &STI, " << Entry
- << ") &&\n";
+ CondStream << CondSep << TargetName
+ << "ValidateMachineOperand(MachineOperand::CreateImm("
+ << DestOperandMap[OpNo].ImmVal << "), &STI, " << Entry
+ << " /* " << DestRec->getName() << " */)";
}
if (CompressOrUncompress)
CodeStream.indent(6) << "OutInst.addOperand(MCOperand::createImm("
@@ -861,9 +887,10 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
mergeCondAndCode(CaseStream, CondString, CodeString);
PrevOp = CurOp;
}
- Func << CaseString << "\n";
+ Func << CaseString;
+ Func.indent(4) << "break;\n";
// Close brace for the last case.
- Func.indent(4) << "} // case " << CurOp << "\n";
+ Func.indent(2) << "} // case " << CurOp << "\n";
Func.indent(2) << "} // switch\n";
Func.indent(2) << "return false;\n}\n";