[llvm] r363747 - Revert [tblgen][disasm] Allow multiple encodings to disassemble to the same instruction
Jordan Rupprecht via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 18 15:21:31 PDT 2019
Author: rupprecht
Date: Tue Jun 18 15:21:31 2019
New Revision: 363747
URL: http://llvm.org/viewvc/llvm-project?rev=363747&view=rev
Log:
Revert [tblgen][disasm] Allow multiple encodings to disassemble to the same instruction
This reverts r363744 (git commit 9b2252123d1e79d2b3594097a9d9cc60072b83d9)
This breaks many buildbots, e.g. http://lab.llvm.org:8011/builders/clang-atom-d525-fedora-rel/builds/203/steps/build%20stage%201/logs/stdio
Modified:
llvm/trunk/include/llvm/Target/Target.td
llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
Modified: llvm/trunk/include/llvm/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=363747&r1=363746&r2=363747&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/Target.td (original)
+++ llvm/trunk/include/llvm/Target/Target.td Tue Jun 18 15:21:31 2019
@@ -398,49 +398,11 @@ include "llvm/Target/TargetSchedule.td"
class Predicate; // Forward def
-class InstructionEncoding {
- // Size of encoded instruction.
- int Size;
-
- // The "namespace" in which this instruction exists, on targets like ARM
- // which multiple ISA namespaces exist.
- string DecoderNamespace = "";
-
- // List of predicates which will be turned into isel matching code.
- list<Predicate> Predicates = [];
-
- string DecoderMethod = "";
-
- // Is the instruction decoder method able to completely determine if the
- // given instruction is valid or not. If the TableGen definition of the
- // instruction specifies bitpattern A??B where A and B are static bits, the
- // hasCompleteDecoder flag says whether the decoder method fully handles the
- // ?? space, i.e. if it is a final arbiter for the instruction validity.
- // If not then the decoder attempts to continue decoding when the decoder
- // method fails.
- //
- // This allows to handle situations where the encoding is not fully
- // orthogonal. Example:
- // * InstA with bitpattern 0b0000????,
- // * InstB with bitpattern 0b000000?? but the associated decoder method
- // DecodeInstB() returns Fail when ?? is 0b00 or 0b11.
- //
- // The decoder tries to decode a bitpattern that matches both InstA and
- // InstB bitpatterns first as InstB (because it is the most specific
- // encoding). In the default case (hasCompleteDecoder = 1), when
- // DecodeInstB() returns Fail the bitpattern gets rejected. By setting
- // hasCompleteDecoder = 0 in InstB, the decoder is informed that
- // DecodeInstB() is not able to determine if all possible values of ?? are
- // valid or not. If DecodeInstB() returns Fail the decoder will attempt to
- // decode the bitpattern as InstA too.
- bit hasCompleteDecoder = 1;
-}
-
//===----------------------------------------------------------------------===//
// Instruction set description - These classes correspond to the C++ classes in
// the Target/TargetInstrInfo.h file.
//
-class Instruction : InstructionEncoding {
+class Instruction {
string Namespace = "";
dag OutOperandList; // An dag containing the MI def operand list.
@@ -465,6 +427,10 @@ class Instruction : InstructionEncoding
// from the opcode.
int Size = 0;
+ // DecoderNamespace - The "namespace" in which this instruction exists, on
+ // targets like ARM which multiple ISA namespaces exist.
+ string DecoderNamespace = "";
+
// Code size, for instruction selection.
// FIXME: What does this actually mean?
int CodeSize = 0;
@@ -566,6 +532,31 @@ class Instruction : InstructionEncoding
string DisableEncoding = "";
string PostEncoderMethod = "";
+ string DecoderMethod = "";
+
+ // Is the instruction decoder method able to completely determine if the
+ // given instruction is valid or not. If the TableGen definition of the
+ // instruction specifies bitpattern A??B where A and B are static bits, the
+ // hasCompleteDecoder flag says whether the decoder method fully handles the
+ // ?? space, i.e. if it is a final arbiter for the instruction validity.
+ // If not then the decoder attempts to continue decoding when the decoder
+ // method fails.
+ //
+ // This allows to handle situations where the encoding is not fully
+ // orthogonal. Example:
+ // * InstA with bitpattern 0b0000????,
+ // * InstB with bitpattern 0b000000?? but the associated decoder method
+ // DecodeInstB() returns Fail when ?? is 0b00 or 0b11.
+ //
+ // The decoder tries to decode a bitpattern that matches both InstA and
+ // InstB bitpatterns first as InstB (because it is the most specific
+ // encoding). In the default case (hasCompleteDecoder = 1), when
+ // DecodeInstB() returns Fail the bitpattern gets rejected. By setting
+ // hasCompleteDecoder = 0 in InstB, the decoder is informed that
+ // DecodeInstB() is not able to determine if all possible values of ?? are
+ // valid or not. If DecodeInstB() returns Fail the decoder will attempt to
+ // decode the bitpattern as InstA too.
+ bit hasCompleteDecoder = 1;
/// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc.
bits<64> TSFlags = 0;
@@ -602,13 +593,6 @@ class Instruction : InstructionEncoding
bit FastISelShouldIgnore = 0;
}
-/// Defines an additional encoding that disassembles to the given instruction
-/// Like Instruction, the Inst and SoftFail fields are omitted to allow targets
-// to specify their size.
-class AdditionalEncoding<Instruction I> : InstructionEncoding {
- Instruction AliasOf = I;
-}
-
/// PseudoInstExpansion - Expansion information for a pseudo-instruction.
/// Which instruction it expands to and how the operands map from the
/// pseudo.
Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=363747&r1=363746&r2=363747&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Tue Jun 18 15:21:31 2019
@@ -16,10 +16,9 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/CachedHashString.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
@@ -48,12 +47,6 @@ using namespace llvm;
namespace {
-STATISTIC(NumEncodings, "Number of encodings considered");
-STATISTIC(NumEncodingsLackingDisasm, "Number of encodings without disassembler info");
-STATISTIC(NumInstructions, "Number of instructions considered");
-STATISTIC(NumEncodingsSupported, "Number of encodings supported");
-STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");
-
struct EncodingField {
unsigned Base, Width, Offset;
EncodingField(unsigned B, unsigned W, unsigned O)
@@ -101,15 +94,6 @@ struct EncodingAndInst {
: EncodingDef(EncodingDef), Inst(Inst) {}
};
-struct EncodingIDAndOpcode {
- unsigned EncodingID;
- unsigned Opcode;
-
- EncodingIDAndOpcode() : EncodingID(0), Opcode(0) {}
- EncodingIDAndOpcode(unsigned EncodingID, unsigned Opcode)
- : EncodingID(EncodingID), Opcode(Opcode) {}
-};
-
raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
if (Value.EncodingDef != Value.Inst->TheDef)
OS << Value.EncodingDef->getName() << ":";
@@ -118,7 +102,6 @@ raw_ostream &operator<<(raw_ostream &OS,
}
class FixedLenDecoderEmitter {
- RecordKeeper &RK;
std::vector<EncodingAndInst> NumberedEncodings;
public:
@@ -130,7 +113,7 @@ public:
std::string ROK = "MCDisassembler::Success",
std::string RFail = "MCDisassembler::Fail",
std::string L = "")
- : RK(R), Target(R), PredicateNamespace(std::move(PredicateNamespace)),
+ : Target(R), PredicateNamespace(std::move(PredicateNamespace)),
GuardPrefix(std::move(GPrefix)), GuardPostfix(std::move(GPostfix)),
ReturnOK(std::move(ROK)), ReturnFail(std::move(RFail)),
Locals(std::move(L)) {}
@@ -268,11 +251,10 @@ protected:
bool Mixed; // a mixed region contains both set and unset bits
// Map of well-known segment value to the set of uid's with that value.
- std::map<uint64_t, std::vector<EncodingIDAndOpcode>>
- FilteredInstructions;
+ std::map<uint64_t, std::vector<unsigned>> FilteredInstructions;
// Set of uid's with non-constant segment values.
- std::vector<EncodingIDAndOpcode> VariableInstructions;
+ std::vector<unsigned> VariableInstructions;
// Map of well-known segment value to its delegate.
std::map<unsigned, std::unique_ptr<const FilterChooser>> FilterChooserMap;
@@ -281,7 +263,7 @@ protected:
unsigned NumFiltered;
// Keeps track of the last opcode in the filtered bucket.
- EncodingIDAndOpcode LastOpcFiltered;
+ unsigned LastOpcFiltered;
public:
Filter(Filter &&f);
@@ -291,7 +273,7 @@ public:
unsigned getNumFiltered() const { return NumFiltered; }
- EncodingIDAndOpcode getSingletonOpc() const {
+ unsigned getSingletonOpc() const {
assert(NumFiltered == 1);
return LastOpcFiltered;
}
@@ -355,12 +337,10 @@ protected:
friend class Filter;
// Vector of codegen instructions to choose our filter.
- ArrayRef<const EncodingAndInst> AllInstructions;
+ ArrayRef<EncodingAndInst> AllInstructions;
// Vector of uid's for this filter chooser to work on.
- // The first member of the pair is the opcode id being decoded, the second is
- // the opcode id that should be emitted.
- const std::vector<EncodingIDAndOpcode> &Opcodes;
+ const std::vector<unsigned> &Opcodes;
// Lookup table for the operand decoding of instructions.
const std::map<unsigned, std::vector<OperandInfo>> &Operands;
@@ -385,8 +365,8 @@ protected:
const FixedLenDecoderEmitter *Emitter;
public:
- FilterChooser(ArrayRef<const EncodingAndInst> Insts,
- const std::vector<EncodingIDAndOpcode> &IDs,
+ FilterChooser(ArrayRef<EncodingAndInst> Insts,
+ const std::vector<unsigned> &IDs,
const std::map<unsigned, std::vector<OperandInfo>> &Ops,
unsigned BW, const FixedLenDecoderEmitter *E)
: AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
@@ -395,8 +375,8 @@ public:
doFilter();
}
- FilterChooser(ArrayRef<const EncodingAndInst> Insts,
- const std::vector<EncodingIDAndOpcode> &IDs,
+ FilterChooser(ArrayRef<EncodingAndInst> Insts,
+ const std::vector<unsigned> &IDs,
const std::map<unsigned, std::vector<OperandInfo>> &Ops,
const std::vector<bit_value_t> &ParentFilterBitValues,
const FilterChooser &parent)
@@ -432,15 +412,6 @@ protected:
}
}
- // Emit the name of the encoding/instruction pair.
- void emitNameWithID(raw_ostream &OS, unsigned Opcode) const {
- const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
- const Record *InstDef = AllInstructions[Opcode].Inst->TheDef;
- if (EncodingDef != InstDef)
- OS << EncodingDef->getName() << ":";
- OS << InstDef->getName();
- }
-
// Populates the field of the insn given the start position and the number of
// consecutive bits to scan for.
//
@@ -491,7 +462,7 @@ protected:
// Emits table entries to decode the singleton.
void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
- EncodingIDAndOpcode Opc) const;
+ unsigned Opc) const;
// Emits code to decode the singleton, and then to decode the rest.
void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
@@ -552,13 +523,13 @@ Filter::Filter(FilterChooser &owner, uns
assert(StartBit + NumBits - 1 < Owner->BitWidth);
NumFiltered = 0;
- LastOpcFiltered = {0, 0};
+ LastOpcFiltered = 0;
for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) {
insn_t Insn;
// Populates the insn given the uid.
- Owner->insnWithID(Insn, Owner->Opcodes[i].EncodingID);
+ Owner->insnWithID(Insn, Owner->Opcodes[i]);
uint64_t Field;
// Scans the segment for possibly well-specified encoding bits.
@@ -1054,7 +1025,7 @@ unsigned FilterChooser::getIslands(std::
// 1: Water (the bit value does not affect decoding)
// 2: Island (well-known bit value needed for decoding)
int State = 0;
- int64_t Val = -1;
+ int Val = -1;
for (unsigned i = 0; i < BitWidth; ++i) {
Val = Value(Insn[i]);
@@ -1342,12 +1313,12 @@ void FilterChooser::emitSoftFailTableEnt
// Emits table entries to decode the singleton.
void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
- EncodingIDAndOpcode Opc) const {
+ unsigned Opc) const {
std::vector<unsigned> StartBits;
std::vector<unsigned> EndBits;
std::vector<uint64_t> FieldVals;
insn_t Insn;
- insnWithID(Insn, Opc.EncodingID);
+ insnWithID(Insn, Opc);
// Look for islands of undecoded bits of the singleton.
getIslands(StartBits, EndBits, FieldVals, Insn);
@@ -1355,7 +1326,7 @@ void FilterChooser::emitSingletonTableEn
unsigned Size = StartBits.size();
// Emit the predicate table entry if one is needed.
- emitPredicateTableEntry(TableInfo, Opc.EncodingID);
+ emitPredicateTableEntry(TableInfo, Opc);
// Check any additional encoding fields needed.
for (unsigned I = Size; I != 0; --I) {
@@ -1379,11 +1350,10 @@ void FilterChooser::emitSingletonTableEn
}
// Check for soft failure of the match.
- emitSoftFailTableEntry(TableInfo, Opc.EncodingID);
+ emitSoftFailTableEntry(TableInfo, Opc);
bool HasCompleteDecoder;
- unsigned DIdx =
- getDecoderIndex(TableInfo.Decoders, Opc.EncodingID, HasCompleteDecoder);
+ unsigned DIdx = getDecoderIndex(TableInfo.Decoders, Opc, HasCompleteDecoder);
// Produce OPC_Decode or OPC_TryDecode opcode based on the information
// whether the instruction decoder is complete or not. If it is complete
@@ -1396,9 +1366,8 @@ void FilterChooser::emitSingletonTableEn
// can decode it.
TableInfo.Table.push_back(HasCompleteDecoder ? MCD::OPC_Decode :
MCD::OPC_TryDecode);
- NumEncodingsSupported++;
uint8_t Buffer[16], *p;
- encodeULEB128(Opc.Opcode, Buffer);
+ encodeULEB128(Opc, Buffer);
for (p = Buffer; *p >= 128 ; ++p)
TableInfo.Table.push_back(*p);
TableInfo.Table.push_back(*p);
@@ -1424,7 +1393,7 @@ void FilterChooser::emitSingletonTableEn
// Emits table entries to decode the singleton, and then to decode the rest.
void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
const Filter &Best) const {
- EncodingIDAndOpcode Opc = Best.getSingletonOpc();
+ unsigned Opc = Best.getSingletonOpc();
// complex singletons need predicate checks from the first singleton
// to refer forward to the variable filterchooser that follows.
@@ -1484,7 +1453,7 @@ bool FilterChooser::filterProcessor(bool
std::vector<uint64_t> FieldVals;
insn_t Insn;
- insnWithID(Insn, Opcodes[i].EncodingID);
+ insnWithID(Insn, Opcodes[i]);
// Look for islands of undecoded bits of any instruction.
if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
@@ -1528,7 +1497,7 @@ bool FilterChooser::filterProcessor(bool
for (unsigned InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) {
insn_t insn;
- insnWithID(insn, Opcodes[InsnIndex].EncodingID);
+ insnWithID(insn, Opcodes[InsnIndex]);
for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
switch (bitAttrs[BitIndex]) {
@@ -1747,12 +1716,9 @@ void FilterChooser::emitTableEntries(Dec
dumpStack(errs(), "\t\t");
for (unsigned i = 0; i < Opcodes.size(); ++i) {
- errs() << '\t';
- emitNameWithID(errs(), Opcodes[i].EncodingID);
- errs() << " ";
- dumpBits(
- errs(),
- getBitsField(*AllInstructions[Opcodes[i].EncodingID].EncodingDef, "Inst"));
+ errs() << '\t' << AllInstructions[Opcodes[i]] << " ";
+ dumpBits(errs(),
+ getBitsField(*AllInstructions[Opcodes[i]].EncodingDef, "Inst"));
errs() << '\n';
}
}
@@ -1784,25 +1750,24 @@ static std::string findOperandDecoderMet
return Decoder;
}
-static bool
-populateInstruction(CodeGenTarget &Target, const Record &EncodingDef,
- const CodeGenInstruction &CGI, unsigned Opc,
- std::map<unsigned, std::vector<OperandInfo>> &Operands) {
+static bool populateInstruction(CodeGenTarget &Target,
+ const CodeGenInstruction &CGI, unsigned Opc,
+ std::map<unsigned, std::vector<OperandInfo>> &Operands){
const Record &Def = *CGI.TheDef;
// If all the bit positions are not specified; do not decode this instruction.
// We are bound to fail! For proper disassembly, the well-known encoding bits
// of the instruction must be fully specified.
- BitsInit &Bits = getBitsField(EncodingDef, "Inst");
+ BitsInit &Bits = getBitsField(Def, "Inst");
if (Bits.allInComplete()) return false;
std::vector<OperandInfo> InsnOperands;
// If the instruction has specified a custom decoding hook, use that instead
// of trying to auto-generate the decoder.
- StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod");
+ StringRef InstDecoder = Def.getValueAsString("DecoderMethod");
if (InstDecoder != "") {
- bool HasCompleteInstDecoder = EncodingDef.getValueAsBit("hasCompleteDecoder");
+ bool HasCompleteInstDecoder = Def.getValueAsBit("hasCompleteDecoder");
InsnOperands.push_back(OperandInfo(InstDecoder, HasCompleteInstDecoder));
Operands[Opc] = InsnOperands;
return true;
@@ -2178,7 +2143,7 @@ static void emitDecodeInstruction(format
<< " const FeatureBitset& Bits = STI.getFeatureBits();\n"
<< "\n"
<< " const uint8_t *Ptr = DecodeTable;\n"
- << " InsnType CurFieldValue = 0;\n"
+ << " uint32_t CurFieldValue = 0;\n"
<< " DecodeStatus S = MCDisassembler::Success;\n"
<< " while (true) {\n"
<< " ptrdiff_t Loc = Ptr - DecodeTable;\n"
@@ -2223,7 +2188,7 @@ static void emitDecodeInstruction(format
<< " unsigned Len = *++Ptr;\n"
<< " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\n"
<< " // Decode the field value.\n"
- << " InsnType ExpectedValue = decodeULEB128(++Ptr, &Len);\n"
+ << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\n"
<< " Ptr += Len;\n"
<< " // NumToSkip is a plain 24-bit integer.\n"
<< " unsigned NumToSkip = *Ptr++;\n"
@@ -2370,52 +2335,37 @@ void FixedLenDecoderEmitter::run(raw_ost
// Parameterize the decoders based on namespace and instruction width.
const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
NumberedEncodings.reserve(NumberedInstructions.size());
- DenseMap<Record *, unsigned> IndexOfInstruction;
- for (const auto &NumberedInstruction : NumberedInstructions) {
- IndexOfInstruction[NumberedInstruction->TheDef] = NumberedEncodings.size();
+ for (const auto &NumberedInstruction : NumberedInstructions)
NumberedEncodings.emplace_back(NumberedInstruction->TheDef, NumberedInstruction);
- }
- for (const auto &NumberedAlias : RK.getAllDerivedDefinitions("AdditionalEncoding"))
- NumberedEncodings.emplace_back(
- NumberedAlias,
- &Target.getInstruction(NumberedAlias->getValueAsDef("AliasOf")));
- std::map<std::pair<std::string, unsigned>, std::vector<EncodingIDAndOpcode>>
- OpcMap;
+ std::map<std::pair<std::string, unsigned>,
+ std::vector<unsigned>> OpcMap;
std::map<unsigned, std::vector<OperandInfo>> Operands;
for (unsigned i = 0; i < NumberedEncodings.size(); ++i) {
- const Record *EncodingDef = NumberedEncodings[i].EncodingDef;
const CodeGenInstruction *Inst = NumberedEncodings[i].Inst;
const Record *Def = Inst->TheDef;
- unsigned Size = EncodingDef->getValueAsInt("Size");
+ unsigned Size = Def->getValueAsInt("Size");
if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
Def->getValueAsBit("isPseudo") ||
Def->getValueAsBit("isAsmParserOnly") ||
- Def->getValueAsBit("isCodeGenOnly")) {
- NumEncodingsLackingDisasm++;
+ Def->getValueAsBit("isCodeGenOnly"))
continue;
- }
-
- if (i < NumberedInstructions.size())
- NumInstructions++;
- NumEncodings++;
- StringRef DecoderNamespace = EncodingDef->getValueAsString("DecoderNamespace");
+ StringRef DecoderNamespace = Def->getValueAsString("DecoderNamespace");
if (Size) {
- if (populateInstruction(Target, *EncodingDef, *Inst, i, Operands)) {
- OpcMap[std::make_pair(DecoderNamespace, Size)].emplace_back(i, IndexOfInstruction.find(Def)->second);
- } else
- NumEncodingsOmitted++;
+ if (populateInstruction(Target, *Inst, i, Operands)) {
+ OpcMap[std::make_pair(DecoderNamespace, Size)].push_back(i);
+ }
}
}
DecoderTableInfo TableInfo;
for (const auto &Opc : OpcMap) {
// Emit the decoder for this namespace+width combination.
- ArrayRef<const EncodingAndInst> NumberedEncodingsRef(
- NumberedEncodings.data(), NumberedEncodings.size());
+ ArrayRef<EncodingAndInst> NumberedEncodingsRef(NumberedEncodings.data(),
+ NumberedEncodings.size());
FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands,
8 * Opc.first.second, this);
More information about the llvm-commits
mailing list