[PATCH 1/2] TableGen: Generate a function for getting operand indices based on their defined names
Tom Stellard
tom at stellard.net
Thu Jun 6 18:39:54 PDT 2013
Ping
On Mon, Jun 03, 2013 at 02:23:22PM -0700, Tom Stellard wrote:
> From: Tom Stellard <thomas.stellard at amd.com>
>
> This patch modifies TableGen to generate a function in
> ${TARGET}GenInstrInfo.inc called getNamedOperandIdx(), which can be used
> to look up indices for operands based on their names.
>
> For example, if you have an instruction like:
>
> def ADD : TargetInstr <(outs GPR:$dst), (ins GPR:$src0, GPR:$src1)>;
>
> You can look up the operand indices using the new function, like this:
>
> Target::getNamedOperandIdx(Target::ADD, Target::OpName::DST) => 0
> Target::getNamedOperandIdx(Target::ADD, Target::OpName::SRC0) => 1
> Target::getNamedOperandIdx(Target::ADD, Target::OpName::SRC1) => 2
>
> The operand names are case insensitive, so $dst is equivalent to $DST.
>
> This change is useful for R600 which has instructions with a large number
> of operands, many of which model single bit instruction configuration
> values. These configuration bits are common across most instructions,
> but may have a different operand index depending on the instruction type.
> It is useful to have a convenient way to look up the operand indices,
> so these bits can be generically set on any instruction.
> ---
> utils/TableGen/InstrInfoEmitter.cpp | 76 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 76 insertions(+)
>
> diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
> index d6020a8..884cce7 100644
> --- a/utils/TableGen/InstrInfoEmitter.cpp
> +++ b/utils/TableGen/InstrInfoEmitter.cpp
> @@ -45,6 +45,8 @@ private:
> void emitEnums(raw_ostream &OS);
>
> typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
> + typedef std::map<std::vector<std::pair<std::string, unsigned> >,
> + std::vector<std::string> > OpNameMapTy;
> void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
> Record *InstrInfo,
> std::map<std::vector<Record*>, unsigned> &EL,
> @@ -293,6 +295,80 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
> OS << "} // End llvm namespace \n";
>
> OS << "#endif // GET_INSTRINFO_CTOR\n\n";
> +
> + std::string Namespace = Target.getInstNamespace();
> + std::string OpNameNS = "OpName";
> + std::map<std::string, bool> OperandNames;
> + OpNameMapTy OperandMap;
> + for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
> + const CodeGenInstruction *Inst = NumberedInstructions[i];
> + std::vector<std::pair<std::string, unsigned> > OpList;
> + for (unsigned j = 0, je = Inst->Operands.size(); j != je; ++j) {
> + CGIOperandList::OperandInfo Info = Inst->Operands[j];
> + std::string Name = Info.Name;
> + std::transform(Name.begin(), Name.end(), Name.begin(), ::toupper);
> + OperandNames[Name] = true;
> + Name = OpNameNS + "::" + Name;
> + OpList.push_back(
> + std::pair<std::string, unsigned>(Name, Info.MIOperandNo));
> + }
> + OperandMap[OpList].push_back(Namespace + "::" + Inst->TheDef->getName());
> + }
> +
> + OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
> + OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
> + OS << "namespace llvm {";
> + OS << "namespace " << Namespace << " {\n";
> + OS << "namespace " << OpNameNS << " { \n";
> + OS << "enum {\n";
> + OS << "NO_OPERAND";
> + for (std::map<std::string, bool>::iterator i = OperandNames.begin(),
> + e = OperandNames.end();
> + i != e; ++i) {
> + OS << ",\n" << i->first;
> + }
> + OS << "\n};\n";
> + OS << "} // End namespace OpName\n";
> + OS << "} // End namespace " << Namespace << "\n";
> + OS << "} // End namespace llvm\n";
> + OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n";
> +
> + OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
> + OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
> + OS << "namespace llvm {";
> + OS << "namespace " << Namespace << " {\n";
> + OS << "int getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n";
> + OS << " switch(Opcode) {\n";
> + for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end();
> + i != e; ++i) {
> + std::vector<std::pair<std::string, unsigned> > OpList = i->first;
> + std::vector<std::string> OpcodeList = i->second;
> +
> + for (std::vector<std::string>::iterator ii = OpcodeList.begin(),
> + ie = OpcodeList.end();
> + ii != ie; ++ii) {
> + std::string OpName = *ii;
> + OS << " case " << OpName << ":\n";
> + }
> + OS << " switch(NamedIdx) {\n";
> +
> + for (std::vector<std::pair<std::string, unsigned> >::iterator
> + oi = OpList.begin(),
> + oe = OpList.end();
> + oi != oe; ++oi) {
> + std::pair<std::string, unsigned> OpPair = *oi;
> + OS << " case " << OpPair.first << ": return "
> + << OpPair.second << ";\n";
> + }
> + OS << " default: return -1;\n";
> + OS << " }\n";
> + }
> + OS << " default: return -1;\n";
> + OS << " }\n";
> + OS << "}\n";
> + OS << "} // End namespace " << Namespace << "\n";
> + OS << "} // End namespace llvm\n";
> + OS << "#endif //GET_INSTRINFO_NAMED_OPS\n";
> }
>
> void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
> --
> 1.7.11.4
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list