Changes in directory llvm/utils/TableGen:
CodeGenInstruction.h updated: 1.19 -> 1.20 CodeGenTarget.cpp updated: 1.69 -> 1.70 DAGISelEmitter.cpp updated: 1.272 -> 1.273 InstrInfoEmitter.cpp updated: 1.45 -> 1.46 InstrInfoEmitter.h updated: 1.12 -> 1.13 --- Log message: Add operand constraints to TargetInstrInfo. --- Diffs of the changes: (+89 -16) CodeGenInstruction.h | 8 ++++++++ CodeGenTarget.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ DAGISelEmitter.cpp | 6 +++++- InstrInfoEmitter.cpp | 41 +++++++++++++++++++++++++++-------------- InstrInfoEmitter.h | 2 +- 5 files changed, 89 insertions(+), 16 deletions(-) Index: llvm/utils/TableGen/CodeGenInstruction.h diff -u llvm/utils/TableGen/CodeGenInstruction.h:1.19 llvm/utils/TableGen/CodeGenInstruction.h:1.20 --- llvm/utils/TableGen/CodeGenInstruction.h:1.19 Mon Jan 9 12:27:06 2006 +++ llvm/utils/TableGen/CodeGenInstruction.h Tue Oct 31 18:27:05 2006 @@ -70,6 +70,14 @@ /// 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.69 llvm/utils/TableGen/CodeGenTarget.cpp:1.70 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.69 Wed Oct 11 16:02:01 2006 +++ llvm/utils/TableGen/CodeGenTarget.cpp Tue Oct 31 18:27:05 2006 @@ -273,6 +273,51 @@ return getInstructionSet()->getValueAsBit("isLittleEndianEncoding"); } +static std::pair<unsigned, unsigned> parseConstraint(const std::string &CStr, + CodeGenInstruction *I) { + 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"); + std::string Name = CStr.substr(1, pos); // Skip '$' + + const std::string delims(" \t"); + 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); + + 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); + return std::make_pair(FIdx, (TIdx << 16) | 1); +} + +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; + + const std::string delims(","); + std::string::size_type bidx, eidx; + + bidx = CStr.find_first_not_of(delims); + while (bidx != std::string::npos) { + 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; + bidx = CStr.find_first_not_of(delims, eidx); + } + + return Res; +} + CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) : TheDef(R), AsmString(AsmStr) { Name = R->getValueAsString("Name"); @@ -338,6 +383,9 @@ MIOperandNo, NumOps, MIOpInfo)); MIOperandNo += NumOps; } + + ConstraintStr = R->getValueAsString("Constraints"); + ConstraintsList = parseConstraints(ConstraintStr, this); } Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.272 llvm/utils/TableGen/DAGISelEmitter.cpp:1.273 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.272 Mon Oct 16 01:33:44 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Tue Oct 31 18:27:05 2006 @@ -3552,11 +3552,14 @@ // Emit boilerplate. OS << "SDNode *Select_INLINEASM(SDOperand N) {\n" << " std::vector<SDOperand> Ops(N.Val->op_begin(), N.Val->op_end());\n" - << " AddToISelQueue(N.getOperand(0)); // Select the chain.\n\n" + << " AddToISelQueue(N.getOperand(0)); // Select the chain.\n" << " // Select the flag operand.\n" << " if (Ops.back().getValueType() == MVT::Flag)\n" << " AddToISelQueue(Ops.back());\n" << " SelectInlineAsmMemoryOperands(Ops, *CurDAG);\n" + << " for (unsigned i = 2, e = Ops.size(); i < e; ++i)\n" + << " if (Ops[i].getOpcode() != ISD::Constant)\n" + << " AddToISelQueue(Ops[i]);\n" << " std::vector<MVT::ValueType> VTs;\n" << " VTs.push_back(MVT::Other);\n" << " VTs.push_back(MVT::Flag);\n" @@ -3582,6 +3585,7 @@ << " case ISD::TargetConstantPool:\n" << " case ISD::TargetFrameIndex:\n" << " case ISD::TargetJumpTable:\n" + << " case ISD::TargetExternalSymbol:\n" << " case ISD::TargetGlobalAddress: {\n" << " return NULL;\n" << " }\n" Index: llvm/utils/TableGen/InstrInfoEmitter.cpp diff -u llvm/utils/TableGen/InstrInfoEmitter.cpp:1.45 llvm/utils/TableGen/InstrInfoEmitter.cpp:1.46 --- llvm/utils/TableGen/InstrInfoEmitter.cpp:1.45 Fri Jul 21 16:15:20 2006 +++ llvm/utils/TableGen/InstrInfoEmitter.cpp Tue Oct 31 18:27:05 2006 @@ -62,11 +62,13 @@ OS << "0 };\n"; } -static std::vector<Record*> GetOperandInfo(const CodeGenInstruction &Inst) { - std::vector<Record*> Result; +static std::vector<std::pair<Record*, unsigned> > +GetOperandInfo(const CodeGenInstruction &Inst) { + std::vector<std::pair<Record*, unsigned> > Result; for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) { if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) { - Result.push_back(Inst.OperandList[i].Rec); + Result.push_back(std::make_pair(Inst.OperandList[i].Rec, + Inst.ConstraintsList[i])); } else { // This might be a multiple operand thing. // Targets like X86 have registers in their multi-operand operands. @@ -74,14 +76,21 @@ unsigned NumDefs = MIOI->getNumArgs(); for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) { if (NumDefs <= j) { - Result.push_back(0); + Result.push_back(std::make_pair((Record*)0, Inst.ConstraintsList[i])); } else { DefInit *Def = dynamic_cast<DefInit*>(MIOI->getArg(j)); - Result.push_back(Def ? Def->getDef() : 0); + Result.push_back(std::make_pair(Def ? Def->getDef() : 0, + Inst.ConstraintsList[i])); } } } } + + // For backward compatibility: isTwoAddress means operand 1 is tied to + // operand 0. + if (Inst.isTwoAddress) + Result[1].second |= 1; + return Result; } @@ -117,29 +126,33 @@ } } - std::map<std::vector<Record*>, unsigned> OperandInfosEmitted; + std::map<std::vector<std::pair<Record*, unsigned> >, unsigned> + OperandInfosEmitted; unsigned OperandListNum = 0; - OperandInfosEmitted[std::vector<Record*>()] = ++OperandListNum; + OperandInfosEmitted[std::vector<std::pair<Record*, unsigned> >()] = + ++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<Record*> OperandInfo = GetOperandInfo(II->second); + std::vector<std::pair<Record*, unsigned> > 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]; + Record *RC = OperandInfo[i].first; // FIXME: We only care about register operands for now. if (RC && RC->isSubClassOf("RegisterClass")) - OS << "{ " << getQualifiedName(RC) << "RegClassID, 0 }, "; + OS << "{ " << getQualifiedName(RC) << "RegClassID, 0, "; else if (RC && RC->getName() == "ptr_rc") // Ptr value whose register class is resolved via callback. - OS << "{ 0, 1 }, "; + OS << "{ 0, 1, "; else - OS << "{ 0, 0 }, "; + OS << "{ 0, 0, "; + OS << OperandInfo[i].second << " }, "; } OS << "};\n"; } @@ -162,7 +175,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EmittedLists, - std::map<std::vector<Record*>, unsigned> &OpInfo, + std::map<std::vector<std::pair<Record*,unsigned> >, unsigned> &OpInfo, std::ostream &OS) { int MinOperands; if (!Inst.OperandList.empty()) @@ -247,7 +260,7 @@ OS << "ImplicitList" << EmittedLists[DefList] << ", "; // Emit the operand info. - std::vector<Record*> OperandInfo = GetOperandInfo(Inst); + std::vector<std::pair<Record*,unsigned> > OperandInfo = GetOperandInfo(Inst); if (OperandInfo.empty()) OS << "0"; else Index: llvm/utils/TableGen/InstrInfoEmitter.h diff -u llvm/utils/TableGen/InstrInfoEmitter.h:1.12 llvm/utils/TableGen/InstrInfoEmitter.h:1.13 --- llvm/utils/TableGen/InstrInfoEmitter.h:1.12 Mon Oct 31 11:16:46 2005 +++ llvm/utils/TableGen/InstrInfoEmitter.h Tue Oct 31 18:27:05 2006 @@ -45,7 +45,7 @@ void emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EL, - std::map<std::vector<Record*>, unsigned> &OpInfo, + std::map<std::vector<std::pair<Record*,unsigned> >, unsigned> &OpInfo, std::ostream &OS); void GatherItinClasses(); unsigned ItinClassNumber(std::string ItinName); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits