Changes in directory llvm/utils/TableGen:
CodeGenInstruction.h updated: 1.22 -> 1.23 CodeGenTarget.cpp updated: 1.74 -> 1.75 InstrInfoEmitter.cpp updated: 1.48 -> 1.49 InstrInfoEmitter.h updated: 1.14 -> 1.15 --- Log message: simplify the way operand flags and constraints are handled, making it easier to extend. --- Diffs of the changes: (+79 -70) CodeGenInstruction.h | 11 +----- CodeGenTarget.cpp | 51 ++++++++++++++++++------------ InstrInfoEmitter.cpp | 84 ++++++++++++++++++++++++++------------------------- InstrInfoEmitter.h | 3 + 4 files changed, 79 insertions(+), 70 deletions(-) Index: llvm/utils/TableGen/CodeGenInstruction.h diff -u llvm/utils/TableGen/CodeGenInstruction.h:1.22 llvm/utils/TableGen/CodeGenInstruction.h:1.23 --- llvm/utils/TableGen/CodeGenInstruction.h:1.22 Mon Nov 6 15:44:53 2006 +++ llvm/utils/TableGen/CodeGenInstruction.h Mon Nov 6 17:49:51 2006 @@ -60,6 +60,9 @@ /// MIOperandInfo - Default MI operand type. Note an operand may be made /// up of multiple MI operands. DagInit *MIOperandInfo; + + /// Constraint info for this operand. + std::string Constraint; OperandInfo(Record *R, const std::string &N, const std::string &PMN, unsigned MION, unsigned MINO, DagInit *MIOI) @@ -71,14 +74,6 @@ /// type (which is a record). std::vector<OperandInfo> OperandList; - /// ConstraintStr - The operand constraints string. - /// - std::string ConstraintStr; - - /// ConstraintsList - List of constraints, encoded into one unsigned int per - /// operand. - std::vector<unsigned> ConstraintsList; - // Various boolean values we track for the instruction. bool isReturn; bool isBranch; Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.74 llvm/utils/TableGen/CodeGenTarget.cpp:1.75 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.74 Mon Nov 6 15:44:54 2006 +++ llvm/utils/TableGen/CodeGenTarget.cpp Mon Nov 6 17:49:51 2006 @@ -19,7 +19,6 @@ #include "Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Target/TargetInstrInfo.h" #include <set> #include <algorithm> using namespace llvm; @@ -274,8 +273,8 @@ return getInstructionSet()->getValueAsBit("isLittleEndianEncoding"); } -static std::pair<unsigned, unsigned> parseConstraint(const std::string &CStr, - CodeGenInstruction *I) { +static std::string ParseConstraint(const std::string &CStr, + CodeGenInstruction *I, unsigned &DestOp) { const std::string ops("="); // FIXME: Only supports TIED_TO for now. std::string::size_type pos = CStr.find_first_of(ops); assert(pos != std::string::npos && "Unrecognized constraint"); @@ -286,26 +285,24 @@ std::string::size_type wpos = Name.find_first_of(delims); if (wpos != std::string::npos) Name = Name.substr(0, wpos); - unsigned FIdx = I->getOperandNamed(Name); + DestOp = I->getOperandNamed(Name); Name = CStr.substr(pos+1); wpos = Name.find_first_not_of(delims); if (wpos != std::string::npos) Name = Name.substr(wpos+1); + unsigned TIdx = I->getOperandNamed(Name); - if (TIdx >= FIdx) + if (TIdx >= DestOp) throw "Illegal tied-to operand constraint '" + CStr + "'"; - return std::make_pair(FIdx, (TIdx << 16) | - (1 << (unsigned)TargetInstrInfo::TIED_TO)); + + // Build the string. + return "((" + utostr(TIdx) + " << 16) | TargetInstrInfo::TIED_TO)"; } -static std::vector<unsigned> parseConstraints(const std::string &CStr, - CodeGenInstruction *I) { - unsigned NumOps = I->OperandList.size(); - std::vector<unsigned> Res(NumOps, 0); - if (CStr == "") - return Res; - +static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) { + if (CStr.empty()) return; + const std::string delims(","); std::string::size_type bidx, eidx; @@ -314,13 +311,16 @@ eidx = CStr.find_first_of(delims, bidx); if (eidx == std::string::npos) eidx = CStr.length(); - std::pair<unsigned, unsigned> C = - parseConstraint(CStr.substr(bidx, eidx), I); - Res[C.first] = C.second; + + unsigned OpNo; + std::string Constr = ParseConstraint(CStr.substr(bidx, eidx), I, OpNo); + assert(OpNo < I->OperandList.size() && "Invalid operand no?"); + + if (!I->OperandList[OpNo].Constraint.empty()) + throw "Operand #" + utostr(OpNo) + " cannot have multiple constraints!"; + I->OperandList[OpNo].Constraint = Constr; bidx = CStr.find_first_not_of(delims, eidx); } - - return Res; } CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) @@ -403,8 +403,17 @@ MIOperandNo += NumOps; } - ConstraintStr = R->getValueAsString("Constraints"); - ConstraintsList = parseConstraints(ConstraintStr, this); + ParseConstraints(R->getValueAsString("Constraints"), this); + + // For backward compatibility: isTwoAddress means operand 1 is tied to + // operand 0. + if (isTwoAddress && OperandList[1].Constraint.empty()) + OperandList[1].Constraint = "((0 << 16) | TargetInstrInfo::TIED_TO)"; + + // Any operands with unset constraints get 0 as their constraint. + for (unsigned op = 0, e = OperandList.size(); op != e; ++op) + if (OperandList[op].Constraint.empty()) + OperandList[op].Constraint = "0"; } Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.48 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.49 --- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.48 Mon Nov 6 15:44:54 2006 +++ llvm/utils/TableGen/InstrInfoEmitter.cpp Mon Nov 6 17:49:51 2006 @@ -63,35 +63,52 @@ OS << "0 };\n"; } -static std::vector<std::pair<Record*, unsigned> > -GetOperandInfo(const CodeGenInstruction &Inst) { - std::vector<std::pair<Record*, unsigned> > Result; +std::vector<std::string> +InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { + std::vector<std::string> Result; for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) { if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) { - Result.push_back(std::make_pair(Inst.OperandList[i].Rec, - Inst.ConstraintsList[i])); + std::string OpStr = getQualifiedName(Inst.OperandList[i].Rec); + OpStr += "RegClassID, 0, "; + OpStr += Inst.OperandList[i].Constraint; + + Result.push_back(OpStr); } else { - // This might be a multiple operand thing. - // Targets like X86 have registers in their multi-operand operands. + // This might be a multiple operand thing. Targets like X86 have + // registers in their multi-operand operands. It may also be an anonymous + // operand, which has a single operand, but no declared class for the + // operand. DagInit *MIOI = Inst.OperandList[i].MIOperandInfo; - unsigned NumDefs = MIOI->getNumArgs(); + for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) { - if (NumDefs <= j) { - Result.push_back(std::make_pair((Record*)0, Inst.ConstraintsList[i])); - } else { - DefInit *Def = dynamic_cast<DefInit*>(MIOI->getArg(j)); - Result.push_back(std::make_pair(Def ? Def->getDef() : 0, - Inst.ConstraintsList[i])); - } + Record *OpR = 0; + if (MIOI && j < MIOI->getNumArgs()) + if (DefInit *Def = dynamic_cast<DefInit*>(MIOI->getArg(j))) + OpR = Def->getDef(); + + + std::string Res; + + if (OpR && OpR->isSubClassOf("RegisterClass")) + Res += getQualifiedName(OpR) + "RegClassID, "; + else + Res += "0, "; + + // Fill in applicable flags. + Res += "0"; + + // Ptr value whose register class is resolved via callback. + if (OpR && OpR->getName() == "ptr_rc") + Res += "|M_LOOK_UP_PTR_REG_CLASS"; + + // fill in constraint info. + Res += ", " + Inst.OperandList[i].Constraint; + + Result.push_back(Res); } } } - // For backward compatibility: isTwoAddress means operand 1 is tied to - // operand 0. - if (Inst.isTwoAddress) - Result[1].second |= (0 << 16) | (1 << (unsigned)TargetInstrInfo::TIED_TO); - return Result; } @@ -127,34 +144,21 @@ } } - std::map<std::vector<std::pair<Record*, unsigned> >, unsigned> - OperandInfosEmitted; + std::map<std::vector<std::string>, unsigned> OperandInfosEmitted; unsigned OperandListNum = 0; - OperandInfosEmitted[std::vector<std::pair<Record*, unsigned> >()] = - ++OperandListNum; + OperandInfosEmitted[std::vector<std::string>()] = ++OperandListNum; // Emit all of the operand info records. OS << "\n"; for (CodeGenTarget::inst_iterator II = Target.inst_begin(), E = Target.inst_end(); II != E; ++II) { - std::vector<std::pair<Record*, unsigned> > OperandInfo = - GetOperandInfo(II->second); + std::vector<std::string> OperandInfo = GetOperandInfo(II->second); unsigned &N = OperandInfosEmitted[OperandInfo]; if (N == 0) { N = ++OperandListNum; OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { "; - for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) { - Record *RC = OperandInfo[i].first; - // FIXME: We only care about register operands for now. - if (RC && RC->isSubClassOf("RegisterClass")) - OS << "{ " << getQualifiedName(RC) << "RegClassID, 0, "; - else if (RC && RC->getName() == "ptr_rc") - // Ptr value whose register class is resolved via callback. - OS << "{ 0, 1, "; - else - OS << "{ 0, 0, "; - OS << OperandInfo[i].second << " }, "; - } + for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) + OS << "{ " << OperandInfo[i] << " }, "; OS << "};\n"; } } @@ -176,7 +180,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EmittedLists, - std::map<std::vector<std::pair<Record*,unsigned> >, unsigned> &OpInfo, + std::map<std::vector<std::string>, unsigned> &OpInfo, std::ostream &OS) { int MinOperands; if (!Inst.OperandList.empty()) @@ -262,7 +266,7 @@ OS << "ImplicitList" << EmittedLists[DefList] << ", "; // Emit the operand info. - std::vector<std::pair<Record*,unsigned> > OperandInfo = GetOperandInfo(Inst); + std::vector<std::string> OperandInfo = GetOperandInfo(Inst); if (OperandInfo.empty()) OS << "0"; else Index: llvm/utils/TableGen/InstrInfoEmitter.h diff -u llvm/utils/TableGen/InstrInfoEmitter.h:1.14 llvm/utils/TableGen/InstrInfoEmitter.h:1.15 --- llvm/utils/TableGen/InstrInfoEmitter.h:1.14 Sun Nov 5 13:31:28 2006 +++ llvm/utils/TableGen/InstrInfoEmitter.h Mon Nov 6 17:49:51 2006 @@ -45,12 +45,13 @@ void emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EL, - std::map<std::vector<std::pair<Record*,unsigned> >, unsigned> &OpInfo, + std::map<std::vector<std::string>, unsigned> &OpInfo, std::ostream &OS); void GatherItinClasses(); unsigned ItinClassNumber(std::string ItinName); void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift, std::ostream &OS); + std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); }; } // End llvm namespace _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits