257 changes: 129 additions & 128 deletions llvm/utils/TableGen/CompressInstEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// This tablegen backend processes CompressPat declarations in a
// td file and generates all the required checks to validate the pattern
// declarations; validate the input and output operands to generate the correct
// compressed instructions. The checks include validating different types of
// compressed instructions. The checks include validating different types of
// operands; register operands, immediate operands, fixed register and fixed
// immediate inputs.
//
Expand All @@ -26,7 +26,7 @@
// /// CompressInstEmitter backend.
// class CompressPat<dag input, dag output, list<Predicate> predicates = []> {
// /// Uncompressed instruction description.
// dag Input = input;
// dag Input = input;
// /// Compressed instruction description.
// dag Output = output;
// /// Predicates that must be true for this to match.
Expand Down Expand Up @@ -105,8 +105,8 @@ class CompressInstEmitter {
// Required target features to enable pattern.
std::vector<Record *> PatReqFeatures;
// Maps operands in the Source Instruction to
IndexedMap<OpData> SourceOperandMap;
// the corresponding Dest instruction operand.
IndexedMap<OpData> SourceOperandMap;
// Maps operands in the Dest Instruction
// to the corresponding Source instruction operand.
IndexedMap<OpData> DestOperandMap;
Expand All @@ -126,7 +126,7 @@ class CompressInstEmitter {
void addDagOperandMapping(Record *Rec, DagInit *Dag, CodeGenInstruction &Inst,
IndexedMap<OpData> &OperandMap, bool IsSourceInst);
void evaluateCompressPat(Record *Compress);
void emitCompressInstEmitter(raw_ostream &o, EmitterType EType);
void emitCompressInstEmitter(raw_ostream &OS, EmitterType EType);
bool validateTypes(Record *SubType, Record *Type, bool IsSourceInst);
bool validateRegister(Record *Reg, Record *RegClass);
void createDagOperandMapping(Record *Rec, StringMap<unsigned> &SourceOperands,
Expand All @@ -144,7 +144,7 @@ class CompressInstEmitter {
public:
CompressInstEmitter(RecordKeeper &R) : Records(R), Target(R) {}

void run(raw_ostream &o);
void run(raw_ostream &OS);
};
} // End anonymous namespace.

Expand Down Expand Up @@ -206,53 +206,53 @@ void CompressInstEmitter::addDagOperandMapping(Record *Rec, DagInit *Dag,
// than number of operands in the Dag due to how tied operands
// are represented.
unsigned TiedCount = 0;
for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) {
int TiedOpIdx = Inst.Operands[i].getTiedRegister();
for (unsigned I = 0, E = Inst.Operands.size(); I != E; ++I) {
int TiedOpIdx = Inst.Operands[I].getTiedRegister();
if (-1 != TiedOpIdx) {
// Set the entry in OperandMap for the tied operand we're skipping.
OperandMap[i].Kind = OperandMap[TiedOpIdx].Kind;
OperandMap[i].Data = OperandMap[TiedOpIdx].Data;
OperandMap[I].Kind = OperandMap[TiedOpIdx].Kind;
OperandMap[I].Data = OperandMap[TiedOpIdx].Data;
TiedCount++;
continue;
}
if (DefInit *DI = dyn_cast<DefInit>(Dag->getArg(i - TiedCount))) {
if (DefInit *DI = dyn_cast<DefInit>(Dag->getArg(I - TiedCount))) {
if (DI->getDef()->isSubClassOf("Register")) {
// Check if the fixed register belongs to the Register class.
if (!validateRegister(DI->getDef(), Inst.Operands[i].Rec))
if (!validateRegister(DI->getDef(), Inst.Operands[I].Rec))
PrintFatalError(Rec->getLoc(),
"Error in Dag '" + Dag->getAsString() +
"'Register: '" + DI->getDef()->getName() +
"' is not in register class '" +
Inst.Operands[i].Rec->getName() + "'");
OperandMap[i].Kind = OpData::Reg;
OperandMap[i].Data.Reg = DI->getDef();
Inst.Operands[I].Rec->getName() + "'");
OperandMap[I].Kind = OpData::Reg;
OperandMap[I].Data.Reg = DI->getDef();
continue;
}
// Validate that Dag operand type matches the type defined in the
// corresponding instruction. Operands in the input Dag pattern are
// allowed to be a subclass of the type specified in corresponding
// instruction operand instead of being an exact match.
if (!validateTypes(DI->getDef(), Inst.Operands[i].Rec, IsSourceInst))
if (!validateTypes(DI->getDef(), Inst.Operands[I].Rec, IsSourceInst))
PrintFatalError(Rec->getLoc(),
"Error in Dag '" + Dag->getAsString() + "'. Operand '" +
Dag->getArgNameStr(i - TiedCount) + "' has type '" +
Dag->getArgNameStr(I - TiedCount) + "' has type '" +
DI->getDef()->getName() +
"' which does not match the type '" +
Inst.Operands[i].Rec->getName() +
Inst.Operands[I].Rec->getName() +
"' in the corresponding instruction operand!");

OperandMap[i].Kind = OpData::Operand;
} else if (IntInit *II = dyn_cast<IntInit>(Dag->getArg(i - TiedCount))) {
OperandMap[I].Kind = OpData::Operand;
} else if (IntInit *II = dyn_cast<IntInit>(Dag->getArg(I - TiedCount))) {
// Validate that corresponding instruction operand expects an immediate.
if (Inst.Operands[i].Rec->isSubClassOf("RegisterClass"))
if (Inst.Operands[I].Rec->isSubClassOf("RegisterClass"))
PrintFatalError(
Rec->getLoc(),
"Error in Dag '" + Dag->getAsString() + "' Found immediate: '" +
II->getAsString() +
"' but corresponding instruction operand expected a register!");
// No pattern validation check possible for values of fixed immediate.
OperandMap[i].Kind = OpData::Imm;
OperandMap[i].Data.Imm = II->getValue();
OperandMap[I].Kind = OpData::Imm;
OperandMap[I].Data.Imm = II->getValue();
LLVM_DEBUG(
dbgs() << " Found immediate '" << II->getValue() << "' at "
<< (IsSourceInst ? "input " : "output ")
Expand Down Expand Up @@ -281,7 +281,7 @@ static bool verifyDagOpCount(CodeGenInstruction &Inst, DagInit *Dag,
"' and Dag operand count mismatch");

// The Instruction might have tied operands so the Dag might have
// a fewer operand count.
// a fewer operand count.
unsigned RealCount = Inst.Operands.size();
for (const auto &Operand : Inst.Operands)
if (Operand.getTiedRegister() != -1)
Expand All @@ -307,43 +307,43 @@ void CompressInstEmitter::createDagOperandMapping(
Record *Rec, StringMap<unsigned> &SourceOperands,
StringMap<unsigned> &DestOperands, DagInit *SourceDag, DagInit *DestDag,
IndexedMap<OpData> &SourceOperandMap) {
for (unsigned i = 0; i < DestDag->getNumArgs(); ++i) {
for (unsigned I = 0; I < DestDag->getNumArgs(); ++I) {
// Skip fixed immediates and registers, they were handled in
// addDagOperandMapping.
if ("" == DestDag->getArgNameStr(i))
if ("" == DestDag->getArgNameStr(I))
continue;
DestOperands[DestDag->getArgNameStr(i)] = i;
DestOperands[DestDag->getArgNameStr(I)] = I;
}

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

StringMap<unsigned>::iterator it =
SourceOperands.find(SourceDag->getArgNameStr(i));
if (it != SourceOperands.end()) {
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.
SourceOperandMap[i].TiedOpIdx = it->getValue();
if (!validateArgsTypes(SourceDag->getArg(it->getValue()),
SourceDag->getArg(i)))
SourceOperandMap[I].TiedOpIdx = It->getValue();
if (!validateArgsTypes(SourceDag->getArg(It->getValue()),
SourceDag->getArg(I)))
PrintFatalError(Rec->getLoc(),
"Input Operand '" + SourceDag->getArgNameStr(i) +
"Input Operand '" + SourceDag->getArgNameStr(I) +
"' has a mismatched tied operand!\n");
}
it = DestOperands.find(SourceDag->getArgNameStr(i));
if (it == DestOperands.end())
PrintFatalError(Rec->getLoc(), "Operand " + SourceDag->getArgNameStr(i) +
It = DestOperands.find(SourceDag->getArgNameStr(I));
if (It == DestOperands.end())
PrintFatalError(Rec->getLoc(), "Operand " + SourceDag->getArgNameStr(I) +
" defined in Input Dag but not used in"
" Output Dag!\n");
// Input Dag operand types must match output Dag operand type.
if (!validateArgsTypes(DestDag->getArg(it->getValue()),
SourceDag->getArg(i)))
if (!validateArgsTypes(DestDag->getArg(It->getValue()),
SourceDag->getArg(I)))
PrintFatalError(Rec->getLoc(), "Type mismatch between Input and "
"Output Dag operand '" +
SourceDag->getArgNameStr(i) + "'!");
SourceOperands[SourceDag->getArgNameStr(i)] = i;
SourceDag->getArgNameStr(I) + "'!");
SourceOperands[SourceDag->getArgNameStr(I)] = I;
}
}

Expand All @@ -358,27 +358,27 @@ void CompressInstEmitter::createInstOperandMapping(
// operands list to get to the corresponding Dag operand.
unsigned TiedCount = 0;
LLVM_DEBUG(dbgs() << " Operand mapping:\n Source Dest\n");
for (unsigned i = 0, e = DestInst.Operands.size(); i != e; ++i) {
int TiedInstOpIdx = DestInst.Operands[i].getTiedRegister();
for (unsigned I = 0, E = DestInst.Operands.size(); I != E; ++I) {
int TiedInstOpIdx = DestInst.Operands[I].getTiedRegister();
if (TiedInstOpIdx != -1) {
++TiedCount;
DestOperandMap[i].Data = DestOperandMap[TiedInstOpIdx].Data;
DestOperandMap[i].Kind = DestOperandMap[TiedInstOpIdx].Kind;
if (DestOperandMap[i].Kind == OpData::Operand)
DestOperandMap[I].Data = DestOperandMap[TiedInstOpIdx].Data;
DestOperandMap[I].Kind = DestOperandMap[TiedInstOpIdx].Kind;
if (DestOperandMap[I].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[i].Data.Operand
<< " ====> " << i
LLVM_DEBUG(dbgs() << " " << DestOperandMap[I].Data.Operand
<< " ====> " << I
<< " Dest operand tied with operand '"
<< TiedInstOpIdx << "'\n");
continue;
}
// Skip fixed immediates and registers, they were handled in
// addDagOperandMapping.
if (DestOperandMap[i].Kind != OpData::Operand)
if (DestOperandMap[I].Kind != OpData::Operand)
continue;

unsigned DagArgIdx = i - TiedCount;
unsigned DagArgIdx = I - TiedCount;
StringMap<unsigned>::iterator SourceOp =
SourceOperands.find(DestDag->getArgNameStr(DagArgIdx));
if (SourceOp == SourceOperands.end())
Expand All @@ -390,9 +390,9 @@ void CompressInstEmitter::createInstOperandMapping(
assert(DestDag->getArgNameStr(DagArgIdx) ==
SourceDag->getArgNameStr(SourceOp->getValue()) &&
"Incorrect operand mapping detected!\n");
DestOperandMap[i].Data.Operand = SourceOp->getValue();
SourceOperandMap[SourceOp->getValue()].Data.Operand = i;
LLVM_DEBUG(dbgs() << " " << SourceOp->getValue() << " ====> " << i
DestOperandMap[I].Data.Operand = SourceOp->getValue();
SourceOperandMap[SourceOp->getValue()].Data.Operand = I;
LLVM_DEBUG(dbgs() << " " << SourceOp->getValue() << " ====> " << I
<< "\n");
}
}
Expand All @@ -403,31 +403,32 @@ void CompressInstEmitter::createInstOperandMapping(
/// - Dag Input opcode is an expanded instruction and Dag Output opcode is a
/// compressed instruction.
/// - Operands in Dag Input must be all used in Dag Output.
/// Register Operand type in Dag Input Type must be contained in the
/// Register Operand type in Dag Input Type must be contained in the
/// corresponding Source Instruction type.
/// - Register Operand type in Dag Input must be the same as in Dag Ouput.
/// - Register Operand type in Dag Output must be the same as the
/// - Register Operand type in Dag Input must be the same as in Dag Ouput.
/// - Register Operand type in Dag Output must be the same as the
/// corresponding Destination Inst type.
/// - Immediate Operand type in Dag Input must be the same as in Dag Ouput.
/// - Immediate Operand type in Dag Ouput must be the same as the corresponding
/// Destination Instruction type.
/// - Fixed register must be contained in the corresponding Source Instruction
/// type.
/// - Fixed register must be contained in the corresponding Destination
/// Instruction type. Warning message printed under these conditions:
/// Instruction type.
/// Warning message printed under these conditions:
/// - Fixed immediate in Dag Input or Dag Ouput cannot be checked at this time
/// and generate warning.
/// - Immediate operand type in Dag Input differs from the corresponding Source
/// Instruction type and generate a warning.
/// Instruction type and generate a warning.
void CompressInstEmitter::evaluateCompressPat(Record *Rec) {
// Validate input Dag operands.
DagInit *SourceDag = Rec->getValueAsDag("Input");
assert(SourceDag && "Missing 'Input' in compress pattern!");
LLVM_DEBUG(dbgs() << "Input: " << *SourceDag << "\n");

// Checking we are transforming from compressed to uncompressed instructions.
Record *Operator = SourceDag->getOperatorAsDef(Rec->getLoc());
CodeGenInstruction SourceInst(Operator);
Record *SourceOperator = SourceDag->getOperatorAsDef(Rec->getLoc());
CodeGenInstruction SourceInst(SourceOperator);
verifyDagOpCount(SourceInst, SourceDag, true);

// Validate output Dag operands.
Expand All @@ -439,12 +440,13 @@ void CompressInstEmitter::evaluateCompressPat(Record *Rec) {
CodeGenInstruction DestInst(DestOperator);
verifyDagOpCount(DestInst, DestDag, false);

if (Operator->getValueAsInt("Size") <= DestOperator->getValueAsInt("Size"))
if (SourceOperator->getValueAsInt("Size") <=
DestOperator->getValueAsInt("Size"))
PrintFatalError(
Rec->getLoc(),
"Compressed instruction '" + DestOperator->getName() +
"'is not strictly smaller than the uncompressed instruction '" +
Operator->getName() + "' !");
SourceOperator->getName() + "' !");

// Fill the mapping from the source to destination instructions.

Expand Down Expand Up @@ -538,13 +540,13 @@ static unsigned getPredicates(DenseMap<const Record *, unsigned> &PredicateMap,
}

static void printPredicates(const std::vector<const Record *> &Predicates,
StringRef Name, raw_ostream &o) {
for (unsigned i = 0; i < Predicates.size(); ++i) {
StringRef Pred = Predicates[i]->getValueAsString(Name);
o << " case " << i + 1 << ": {\n"
<< " // " << Predicates[i]->getName() << "\n"
<< " " << Pred << "\n"
<< " }\n";
StringRef Name, raw_ostream &OS) {
for (unsigned I = 0; I < Predicates.size(); ++I) {
StringRef Pred = Predicates[I]->getValueAsString(Name);
OS << " case " << I + 1 << ": {\n"
<< " // " << Predicates[I]->getName() << "\n"
<< " " << Pred << "\n"
<< " }\n";
}
}

Expand All @@ -558,7 +560,7 @@ static void mergeCondAndCode(raw_ostream &CombinedStream, StringRef CondStr,
CombinedStream.indent(4) << "} // if\n";
}

void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
EmitterType EType) {
Record *AsmWriter = Target.getAsmWriter();
if (!AsmWriter->getValueAsInt("PassSubtarget"))
Expand All @@ -577,8 +579,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
const CompressPat &RHS) {
if (EType == EmitterType::Compress || EType == EmitterType::CheckCompress)
return (LHS.Source.TheDef->getName() < RHS.Source.TheDef->getName());
else
return (LHS.Dest.TheDef->getName() < RHS.Dest.TheDef->getName());
return (LHS.Dest.TheDef->getName() < RHS.Dest.TheDef->getName());
});

// A list of MCOperandPredicates for all operands in use, and the reverse map.
Expand All @@ -594,14 +595,14 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
raw_string_ostream FuncH(FH);

if (EType == EmitterType::Compress)
o << "\n#ifdef GEN_COMPRESS_INSTR\n"
<< "#undef GEN_COMPRESS_INSTR\n\n";
OS << "\n#ifdef GEN_COMPRESS_INSTR\n"
<< "#undef GEN_COMPRESS_INSTR\n\n";
else if (EType == EmitterType::Uncompress)
o << "\n#ifdef GEN_UNCOMPRESS_INSTR\n"
<< "#undef GEN_UNCOMPRESS_INSTR\n\n";
OS << "\n#ifdef GEN_UNCOMPRESS_INSTR\n"
<< "#undef GEN_UNCOMPRESS_INSTR\n\n";
else if (EType == EmitterType::CheckCompress)
o << "\n#ifdef GEN_CHECK_COMPRESS_INSTR\n"
<< "#undef GEN_CHECK_COMPRESS_INSTR\n\n";
OS << "\n#ifdef GEN_CHECK_COMPRESS_INSTR\n"
<< "#undef GEN_CHECK_COMPRESS_INSTR\n\n";

if (EType == EmitterType::Compress) {
FuncH << "static bool compressInst(MCInst &OutInst,\n";
Expand All @@ -617,14 +618,14 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
}

if (CompressPatterns.empty()) {
o << FuncH.str();
o.indent(2) << "return false;\n}\n";
OS << FuncH.str();
OS.indent(2) << "return false;\n}\n";
if (EType == EmitterType::Compress)
o << "\n#endif //GEN_COMPRESS_INSTR\n";
OS << "\n#endif //GEN_COMPRESS_INSTR\n";
else if (EType == EmitterType::Uncompress)
o << "\n#endif //GEN_UNCOMPRESS_INSTR\n\n";
OS << "\n#endif //GEN_UNCOMPRESS_INSTR\n\n";
else if (EType == EmitterType::CheckCompress)
o << "\n#endif //GEN_CHECK_COMPRESS_INSTR\n\n";
OS << "\n#endif //GEN_CHECK_COMPRESS_INSTR\n\n";
return;
}

Expand Down Expand Up @@ -698,11 +699,11 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
for (auto &Set : AnyOfFeatureSets) {
CondStream.indent(6) << "(";
for (auto &Op : Set) {
bool isLast = &Op == &*Set.rbegin();
bool IsLast = &Op == &*Set.rbegin();
StringRef Not = Op.first ? "!" : "";
CondStream << Not << "STI.getFeatureBits()[" << TargetName
<< "::" << Op.second << "]";
if (!isLast)
if (!IsLast)
CondStream << " || ";
}
CondStream << ") &&\n";
Expand Down Expand Up @@ -766,8 +767,8 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
if (DestOperand.getTiedRegister() == -1)
CondStream.indent(6)
<< "(MI.getOperand(" << OpIdx << ").isReg()) &&\n"
<< " (" << TargetName << "MCRegisterClasses["
<< TargetName << "::" << ClassRec->getName()
<< " (" << TargetName << "MCRegisterClasses[" << TargetName
<< "::" << ClassRec->getName()
<< "RegClassID].contains(MI.getOperand(" << OpIdx
<< ").getReg())) &&\n";

Expand All @@ -790,8 +791,8 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
CondStream.indent(6)
<< "MI.getOperand(" << OpIdx << ").isImm() &&\n";
CondStream.indent(6) << TargetName << "ValidateMachineOperand("
<< "MI.getOperand(" << OpIdx
<< "), &STI, " << Entry << ") &&\n";
<< "MI.getOperand(" << OpIdx << "), &STI, "
<< Entry << ") &&\n";
}
if (CompressOrUncompress)
CodeStream.indent(6)
Expand Down Expand Up @@ -844,63 +845,63 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &o,
Func.indent(2) << "return false;\n}\n";

if (!MCOpPredicates.empty()) {
o << "static bool " << ValidatorName << "(const MCOperand &MCOp,\n"
<< " const MCSubtargetInfo &STI,\n"
<< " unsigned PredicateIndex) {\n"
<< " switch (PredicateIndex) {\n"
<< " default:\n"
<< " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n"
<< " break;\n";

printPredicates(MCOpPredicates, "MCOperandPredicate", o);

o << " }\n"
<< "}\n\n";
OS << "static bool " << ValidatorName << "(const MCOperand &MCOp,\n"
<< " const MCSubtargetInfo &STI,\n"
<< " unsigned PredicateIndex) {\n"
<< " switch (PredicateIndex) {\n"
<< " default:\n"
<< " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n"
<< " break;\n";

printPredicates(MCOpPredicates, "MCOperandPredicate", OS);

OS << " }\n"
<< "}\n\n";
}

if (!ImmLeafPredicates.empty()) {
o << "static bool " << TargetName
<< "ValidateMachineOperand(const MachineOperand &MO,\n"
<< " const " << TargetName << "Subtarget *Subtarget,\n"
<< " unsigned PredicateIndex) {\n"
<< " int64_t Imm = MO.getImm();\n"
<< " switch (PredicateIndex) {\n"
<< " default:\n"
<< " llvm_unreachable(\"Unknown ImmLeaf Predicate kind\");\n"
<< " break;\n";

printPredicates(ImmLeafPredicates, "ImmediateCode", o);

o << " }\n"
<< "}\n\n";
OS << "static bool " << TargetName
<< "ValidateMachineOperand(const MachineOperand &MO,\n"
<< " const " << TargetName << "Subtarget *Subtarget,\n"
<< " unsigned PredicateIndex) {\n"
<< " int64_t Imm = MO.getImm();\n"
<< " switch (PredicateIndex) {\n"
<< " default:\n"
<< " llvm_unreachable(\"Unknown ImmLeaf Predicate kind\");\n"
<< " break;\n";

printPredicates(ImmLeafPredicates, "ImmediateCode", OS);

OS << " }\n"
<< "}\n\n";
}

o << FuncH.str();
o << Func.str();
OS << FuncH.str();
OS << Func.str();

if (EType == EmitterType::Compress)
o << "\n#endif //GEN_COMPRESS_INSTR\n";
OS << "\n#endif //GEN_COMPRESS_INSTR\n";
else if (EType == EmitterType::Uncompress)
o << "\n#endif //GEN_UNCOMPRESS_INSTR\n\n";
OS << "\n#endif //GEN_UNCOMPRESS_INSTR\n\n";
else if (EType == EmitterType::CheckCompress)
o << "\n#endif //GEN_CHECK_COMPRESS_INSTR\n\n";
OS << "\n#endif //GEN_CHECK_COMPRESS_INSTR\n\n";
}

void CompressInstEmitter::run(raw_ostream &o) {
void CompressInstEmitter::run(raw_ostream &OS) {
std::vector<Record *> Insts = Records.getAllDerivedDefinitions("CompressPat");

// Process the CompressPat definitions, validating them as we do so.
for (unsigned i = 0, e = Insts.size(); i != e; ++i)
evaluateCompressPat(Insts[i]);
for (unsigned I = 0, E = Insts.size(); I != E; ++I)
evaluateCompressPat(Insts[I]);

// Emit file header.
emitSourceFileHeader("Compress instruction Source Fragment", o);
emitSourceFileHeader("Compress instruction Source Fragment", OS, Records);
// Generate compressInst() function.
emitCompressInstEmitter(o, EmitterType::Compress);
emitCompressInstEmitter(OS, EmitterType::Compress);
// Generate uncompressInst() function.
emitCompressInstEmitter(o, EmitterType::Uncompress);
emitCompressInstEmitter(OS, EmitterType::Uncompress);
// Generate isCompressibleInst() function.
emitCompressInstEmitter(o, EmitterType::CheckCompress);
emitCompressInstEmitter(OS, EmitterType::CheckCompress);
}

static TableGen::Emitter::OptClass<CompressInstEmitter>
Expand Down
23 changes: 12 additions & 11 deletions mlir/docs/Bufferization.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ the buffer allocated for this "destination" input.
As an example, consider the following op: `%0 = tensor.insert %cst into
%t[%idx] : tensor<?xf32>`

`%t` is the destination in this example. When choosing a buffer for the result
`%0`, One-Shot Bufferize considers only two options:
`%t` is the "destination" in this example. When choosing a buffer for the result
`%0`, denoted as `buffer(%0)`, One-Shot Bufferize considers only two options:

1. buffer(`%0`) = buffer(`%t`): alias the destination tensor with the
1. `buffer(%0) = buffer(%t)` : alias the "destination" tensor with the
result and perform the operation in-place.
3. buffer(`%0`) is a newly allocated buffer.
2. `buffer(%0)` is a newly allocated buffer.

There may be other buffers in the same function that could potentially be used
for buffer(`%0`), but those are not considered by One-Shot Bufferize to keep the
for `buffer(%0)`, but those are not considered by One-Shot Bufferize to keep the
bufferization simple. One-Shot Bufferize could be extended to consider such
buffers in the future to achieve a better quality of bufferization.

Expand All @@ -150,10 +150,10 @@ memory allocation. E.g.:
} : tensor<?xf32>
```

The result of `tensor.generate` does not have a "destination", so bufferization
allocates a new buffer. This could be avoided by choosing an op such as
`linalg.generic`, which can express the same computation with a destination
("out") tensor:
The result of `tensor.generate` does not have a "destination" operand, so
bufferization allocates a new buffer. This could be avoided by choosing an
op such as `linalg.generic`, which can express the same computation with a
"destination" operand, as specified behind outputs (`outs`):

```mlir
#map = affine_map<(i) -> (i)>
Expand Down Expand Up @@ -184,7 +184,8 @@ to a no-op (in the absence of RaW conflicts such as a subsequent read of `%s`).

RaW conflicts are detected with an analysis of SSA use-def chains (details
later). One-Shot Bufferize works best if there is a single SSA use-def chain,
where the result of a tensor op is the "destination" operand of the next tensor
where the result of a tensor op is the
operand of the next tensor
ops, e.g.:

```mlir
Expand Down Expand Up @@ -282,7 +283,7 @@ must be inserted due to a RaW conflict. E.g.:
}
```

In the above example, a buffer copy of buffer(`%another_tensor`) (with `%cst`
In the above example, a buffer copy of `buffer(%another_tensor)` (with `%cst`
inserted) is yielded from the "then" branch.

Note: Buffer allocations that are returned from a function are not deallocated.
Expand Down
2 changes: 1 addition & 1 deletion openmp/libompd/gdb-plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ target_link_libraries (ompdModule ${CMAKE_DL_LIBS})
set_target_properties (ompdModule PROPERTIES PREFIX "")
set_target_properties (ompdModule PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/python-module/ompd/")

install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python-module/ompd DESTINATION ${CMAKE_INSTALL_PREFIX}/share/gdb/python/ PATTERN ompdModule.so PERMISSIONS OWNER_READ WORLD_READ GROUP_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python-module/ompd DESTINATION share/gdb/python/ PATTERN ompdModule.so PERMISSIONS OWNER_READ WORLD_READ GROUP_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)