Skip to content
Merged
Changes from all commits
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
167 changes: 74 additions & 93 deletions llvm/utils/TableGen/CompressInstEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ class CompressInstEmitter {
// Tied operand index within the instruction.
int TiedOpIdx = -1;
};
struct ArgData {
unsigned DAGOpNo;
unsigned MIOpNo;
};
struct CompressPat {
// The source instruction definition.
CodeGenInstruction Source;
Expand Down Expand Up @@ -126,27 +130,23 @@ class CompressInstEmitter {
std::vector<CompressPat> CompressPatterns;
void addDagOperandMapping(const Record *Rec, const DagInit *Dag,
const CodeGenInstruction &Inst,
IndexedMap<OpData> &OperandMap, bool IsSourceInst,
unsigned *SourceLastTiedOpPtr);
IndexedMap<OpData> &OperandMap,
StringMap<ArgData> &Operands, bool IsSourceInst);
void evaluateCompressPat(const Record *Compress);
void emitCompressInstEmitter(raw_ostream &OS, EmitterType EType);
bool validateTypes(const Record *DagOpType, const Record *InstOpType,
bool IsSourceInst);
bool validateRegister(const Record *Reg, const Record *RegClass);
void createDagOperandMapping(const Record *Rec,
StringMap<unsigned> &SourceOperands,
StringMap<unsigned> &DestOperands,
const DagInit *SourceDag, const DagInit *DestDag,
IndexedMap<OpData> &SourceOperandMap,
bool HasSourceTiedOp);
void checkDagOperandMapping(const Record *Rec,
const StringMap<ArgData> &DestOperands,
const DagInit *SourceDag, const DagInit *DestDag);

void createInstOperandMapping(const Record *Rec, const DagInit *SourceDag,
const DagInit *DestDag,
IndexedMap<OpData> &SourceOperandMap,
IndexedMap<OpData> &DestOperandMap,
StringMap<unsigned> &SourceOperands,
const CodeGenInstruction &DestInst,
unsigned SourceLastTiedOp);
StringMap<ArgData> &SourceOperands,
const CodeGenInstruction &DestInst);

public:
CompressInstEmitter(const RecordKeeper &R) : Records(R), Target(R) {}
Expand Down Expand Up @@ -198,6 +198,10 @@ bool CompressInstEmitter::validateTypes(const Record *DagOpType,
return true;
}

static bool validateArgsTypes(const Init *Arg1, const Init *Arg2) {
return cast<DefInit>(Arg1)->getDef() == cast<DefInit>(Arg2)->getDef();
}

/// The patterns in the Dag contain different types of operands:
/// Register operands, e.g.: GPRC:$rs1; Fixed registers, e.g: X1; Immediate
/// operands, e.g.: simm6:$imm; Fixed immediate operands, e.g.: 0. This function
Expand All @@ -209,8 +213,8 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
const DagInit *Dag,
const CodeGenInstruction &Inst,
IndexedMap<OpData> &OperandMap,
bool IsSourceInst,
unsigned *SourceLastTiedOpPtr) {
StringMap<ArgData> &Operands,
bool IsSourceInst) {
unsigned NumMIOperands = 0;
if (!Inst.Operands.empty())
NumMIOperands =
Expand All @@ -224,16 +228,12 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
// are represented.
unsigned TiedCount = 0;
unsigned OpNo = 0;
if (IsSourceInst)
*SourceLastTiedOpPtr = std::numeric_limits<unsigned int>::max();
for (const auto &Opnd : Inst.Operands) {
int TiedOpIdx = Opnd.getTiedRegister();
if (-1 != TiedOpIdx) {
assert((unsigned)TiedOpIdx < OpNo);
// Set the entry in OperandMap for the tied operand we're skipping.
OperandMap[OpNo] = OperandMap[TiedOpIdx];
if (IsSourceInst)
*SourceLastTiedOpPtr = OpNo;
++OpNo;
++TiedCount;
continue;
Expand Down Expand Up @@ -290,6 +290,30 @@ 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};
}
}
}
Expand Down Expand Up @@ -331,60 +355,29 @@ static bool verifyDagOpCount(const CodeGenInstruction &Inst, const DagInit *Dag,
return true;
}

static bool validateArgsTypes(const Init *Arg1, const Init *Arg2) {
return cast<DefInit>(Arg1)->getDef() == cast<DefInit>(Arg2)->getDef();
}

// Creates a mapping between the operand name in the Dag (e.g. $rs1) and
// its index in the list of Dag operands and checks that operands with the same
// name have the same types. For example in 'C_ADD $rs1, $rs2' we generate the
// mapping $rs1 --> 0, $rs2 ---> 1. If the operand appears twice in the (tied)
// same Dag we use the last occurrence for indexing.
void CompressInstEmitter::createDagOperandMapping(
const Record *Rec, StringMap<unsigned> &SourceOperands,
StringMap<unsigned> &DestOperands, const DagInit *SourceDag,
const DagInit *DestDag, IndexedMap<OpData> &SourceOperandMap,
bool HasSourceTiedOp) {
for (unsigned I = 0; I < DestDag->getNumArgs(); ++I) {
// Skip fixed immediates and registers, they were handled in
// addDagOperandMapping.
if ("" == DestDag->getArgNameStr(I))
continue;
DestOperands[DestDag->getArgNameStr(I)] = I;
}
// Check that all names in the source DAG appear in the destionation DAG.
void CompressInstEmitter::checkDagOperandMapping(
const Record *Rec, const StringMap<ArgData> &DestOperands,
const DagInit *SourceDag, const DagInit *DestDag) {

for (unsigned I = 0; I < SourceDag->getNumArgs(); ++I) {
// Skip fixed immediates and registers, they were handled in
// addDagOperandMapping.
if ("" == SourceDag->getArgNameStr(I))
StringRef ArgName = SourceDag->getArgNameStr(I);
if (ArgName.empty())
continue;

StringMap<unsigned>::iterator It =
SourceOperands.find(SourceDag->getArgNameStr(I));
if (It != SourceOperands.end()) {
// Operand sharing the same name in the Dag should be mapped as tied.
if (HasSourceTiedOp)
SourceOperandMap[I + 1].TiedOpIdx = It->getValue() + 1;
else
SourceOperandMap[I].TiedOpIdx = It->getValue();
if (!validateArgsTypes(SourceDag->getArg(It->getValue()),
SourceDag->getArg(I)))
PrintFatalError(Rec->getLoc(),
"Input Operand '" + SourceDag->getArgNameStr(I) +
"' has a mismatched tied operand!\n");
}
It = DestOperands.find(SourceDag->getArgNameStr(I));
auto It = DestOperands.find(ArgName);
if (It == DestOperands.end())
PrintFatalError(Rec->getLoc(), "Operand " + SourceDag->getArgNameStr(I) +
PrintFatalError(Rec->getLoc(), "Operand " + ArgName +
" defined in Input Dag but not used in"
" Output Dag!\n");
" Output Dag!");
// Input Dag operand types must match output Dag operand type.
if (!validateArgsTypes(DestDag->getArg(It->getValue()),
if (!validateArgsTypes(DestDag->getArg(It->getValue().DAGOpNo),
SourceDag->getArg(I)))
PrintFatalError(Rec->getLoc(), "Type mismatch between Input and "
"Output Dag operand '" +
SourceDag->getArgNameStr(I) + "'!");
SourceOperands[SourceDag->getArgNameStr(I)] = I;
ArgName + "'!");
}
}

Expand All @@ -394,8 +387,7 @@ void CompressInstEmitter::createDagOperandMapping(
void CompressInstEmitter::createInstOperandMapping(
const Record *Rec, const DagInit *SourceDag, const DagInit *DestDag,
IndexedMap<OpData> &SourceOperandMap, IndexedMap<OpData> &DestOperandMap,
StringMap<unsigned> &SourceOperands, const CodeGenInstruction &DestInst,
unsigned SourceLastTiedOp) {
StringMap<ArgData> &SourceOperands, const CodeGenInstruction &DestInst) {
// TiedCount keeps track of the number of operands skipped in Inst
// operands list to get to the corresponding Dag operand.
unsigned TiedCount = 0;
Expand Down Expand Up @@ -425,29 +417,21 @@ void CompressInstEmitter::createInstOperandMapping(
continue;

unsigned DagArgIdx = OpNo - TiedCount;
StringMap<unsigned>::iterator SourceOp =
SourceOperands.find(DestDag->getArgNameStr(DagArgIdx));
StringRef ArgName = DestDag->getArgNameStr(DagArgIdx);
auto SourceOp = SourceOperands.find(ArgName);
if (SourceOp == SourceOperands.end())
PrintFatalError(Rec->getLoc(),
"Output Dag operand '" +
DestDag->getArgNameStr(DagArgIdx) +
"Output Dag operand '" + ArgName +
"' has no matching input Dag operand.");

assert(DestDag->getArgNameStr(DagArgIdx) ==
SourceDag->getArgNameStr(SourceOp->getValue()) &&
assert(ArgName ==
SourceDag->getArgNameStr(SourceOp->getValue().DAGOpNo) &&
"Incorrect operand mapping detected!\n");

// Following four lines ensure the correct handling of a single tied
// operand in the Source Inst. SourceDagOp points to the position of
// appropriate Dag argument which is not correct in presence of tied
// operand in the Source Inst and must be incremented by 1 to reflect
// correct position of the operand in Source Inst
unsigned SourceDagOp = SourceOp->getValue();
if (SourceDagOp >= SourceLastTiedOp)
SourceDagOp++;
DestOperandMap[OpNo].Data.Operand = SourceDagOp;
SourceOperandMap[SourceDagOp].Data.Operand = OpNo;
LLVM_DEBUG(dbgs() << " " << SourceDagOp << " ====> " << OpNo << "\n");
unsigned SourceOpNo = SourceOp->getValue().MIOpNo;
DestOperandMap[OpNo].Data.Operand = SourceOpNo;
SourceOperandMap[SourceOpNo].Data.Operand = OpNo;
LLVM_DEBUG(dbgs() << " " << SourceOpNo << " ====> " << OpNo << "\n");
}
}
}
Expand Down Expand Up @@ -506,27 +490,24 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
// Fill the mapping from the source to destination instructions.

IndexedMap<OpData> SourceOperandMap;
unsigned SourceLastTiedOp; // postion of the last tied operand in Source Inst
// Map from arg name to DAG operand number and MI operand number.
StringMap<ArgData> SourceOperands;
// Create a mapping between source Dag operands and source Inst operands.
addDagOperandMapping(Rec, SourceDag, SourceInst, SourceOperandMap,
/*IsSourceInst*/ true, &SourceLastTiedOp);
SourceOperands, /*IsSourceInst*/ true);

IndexedMap<OpData> DestOperandMap;
// Map from arg name to DAG operand number and MI operand number.
StringMap<ArgData> DestOperands;
// Create a mapping between destination Dag operands and destination Inst
// operands.
addDagOperandMapping(Rec, DestDag, DestInst, DestOperandMap,
/*IsSourceInst*/ false, nullptr);

StringMap<unsigned> SourceOperands;
StringMap<unsigned> DestOperands;
bool HasSourceTiedOp =
SourceLastTiedOp != std::numeric_limits<unsigned int>::max();
createDagOperandMapping(Rec, SourceOperands, DestOperands, SourceDag, DestDag,
SourceOperandMap, HasSourceTiedOp);
addDagOperandMapping(Rec, DestDag, DestInst, DestOperandMap, DestOperands,
/*IsSourceInst*/ false);

checkDagOperandMapping(Rec, DestOperands, SourceDag, DestDag);
// Create operand mapping between the source and destination instructions.
createInstOperandMapping(Rec, SourceDag, DestDag, SourceOperandMap,
DestOperandMap, SourceOperands, DestInst,
SourceLastTiedOp);
DestOperandMap, SourceOperands, DestInst);

// Get the target features for the CompressPat.
std::vector<const Record *> PatReqFeatures;
Expand Down Expand Up @@ -624,7 +605,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
if (!AsmWriter->getValueAsInt("PassSubtarget"))
PrintFatalError(AsmWriter->getLoc(),
"'PassSubtarget' is false. SubTargetInfo object is needed "
"for target features.\n");
"for target features.");

StringRef TargetName = Target.getName();

Expand Down Expand Up @@ -780,7 +761,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
<< ").getReg() == MI.getOperand("
<< SourceOperandMap[OpNo].TiedOpIdx << ").getReg()) &&\n";
else
PrintFatalError("Unexpected tied operand types!\n");
PrintFatalError("Unexpected tied operand types!");
}
for (unsigned SubOp = 0; SubOp != SourceOperand.MINumOperands; ++SubOp) {
// Check for fixed immediates\registers in the source instruction.
Expand Down