InstrInfoEmitter.cpp revision 198892
133965Sjdp//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===// 277298Sobrien// 333965Sjdp// The LLVM Compiler Infrastructure 433965Sjdp// 533965Sjdp// This file is distributed under the University of Illinois Open Source 633965Sjdp// License. See LICENSE.TXT for details. 733965Sjdp// 833965Sjdp//===----------------------------------------------------------------------===// 933965Sjdp// 1033965Sjdp// This tablegen backend is responsible for emitting a description of the target 1133965Sjdp// instruction set for the code generator. 1233965Sjdp// 1333965Sjdp//===----------------------------------------------------------------------===// 1433965Sjdp 1533965Sjdp#include "InstrInfoEmitter.h" 1633965Sjdp#include "CodeGenTarget.h" 1733965Sjdp#include "Record.h" 1833965Sjdp#include "llvm/ADT/StringExtras.h" 1933965Sjdp#include <algorithm> 2077298Sobrienusing namespace llvm; 2133965Sjdp 2233965Sjdpstatic void PrintDefList(const std::vector<Record*> &Uses, 2333965Sjdp unsigned Num, raw_ostream &OS) { 2433965Sjdp OS << "static const unsigned ImplicitList" << Num << "[] = { "; 2533965Sjdp for (unsigned i = 0, e = Uses.size(); i != e; ++i) 2633965Sjdp OS << getQualifiedName(Uses[i]) << ", "; 2733965Sjdp OS << "0 };\n"; 2877298Sobrien} 2933965Sjdp 3033965Sjdpstatic void PrintBarriers(std::vector<Record*> &Barriers, 3133965Sjdp unsigned Num, raw_ostream &OS) { 3277298Sobrien OS << "static const TargetRegisterClass* Barriers" << Num << "[] = { "; 3377298Sobrien for (unsigned i = 0, e = Barriers.size(); i != e; ++i) 3477298Sobrien OS << "&" << getQualifiedName(Barriers[i]) << "RegClass, "; 3577298Sobrien OS << "NULL };\n"; 3677298Sobrien} 3733965Sjdp 3860484Sobrien//===----------------------------------------------------------------------===// 3933965Sjdp// Instruction Itinerary Information. 4033965Sjdp//===----------------------------------------------------------------------===// 4133965Sjdp 4233965Sjdpstruct RecordNameComparator { 4333965Sjdp bool operator()(const Record *Rec1, const Record *Rec2) const { 4433965Sjdp return Rec1->getName() < Rec2->getName(); 4533965Sjdp } 4633965Sjdp}; 4733965Sjdp 4833965Sjdpvoid InstrInfoEmitter::GatherItinClasses() { 4960484Sobrien std::vector<Record*> DefList = 5060484Sobrien Records.getAllDerivedDefinitions("InstrItinClass"); 5160484Sobrien std::sort(DefList.begin(), DefList.end(), RecordNameComparator()); 5260484Sobrien 5360484Sobrien for (unsigned i = 0, N = DefList.size(); i < N; i++) 5460484Sobrien ItinClassMap[DefList[i]->getName()] = i; 5560484Sobrien} 5660484Sobrien 5760484Sobrienunsigned InstrInfoEmitter::getItinClassNumber(const Record *InstRec) { 5833965Sjdp return ItinClassMap[InstRec->getValueAsDef("Itinerary")->getName()]; 5933965Sjdp} 6033965Sjdp 6133965Sjdp//===----------------------------------------------------------------------===// 6233965Sjdp// Operand Info Emission. 6333965Sjdp//===----------------------------------------------------------------------===// 6433965Sjdp 6533965Sjdpstd::vector<std::string> 6633965SjdpInstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { 6733965Sjdp std::vector<std::string> Result; 6833965Sjdp 6933965Sjdp for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) { 7033965Sjdp // Handle aggregate operands and normal operands the same way by expanding 7133965Sjdp // either case into a list of operands for this op. 7233965Sjdp std::vector<CodeGenInstruction::OperandInfo> OperandList; 7333965Sjdp 7433965Sjdp // This might be a multiple operand thing. Targets like X86 have 7533965Sjdp // registers in their multi-operand operands. It may also be an anonymous 7633965Sjdp // operand, which has a single operand, but no declared class for the 7733965Sjdp // operand. 7833965Sjdp DagInit *MIOI = Inst.OperandList[i].MIOperandInfo; 7933965Sjdp 8033965Sjdp if (!MIOI || MIOI->getNumArgs() == 0) { 8133965Sjdp // Single, anonymous, operand. 8233965Sjdp OperandList.push_back(Inst.OperandList[i]); 8333965Sjdp } else { 8433965Sjdp for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) { 8533965Sjdp OperandList.push_back(Inst.OperandList[i]); 8633965Sjdp 8733965Sjdp Record *OpR = dynamic_cast<DefInit*>(MIOI->getArg(j))->getDef(); 8833965Sjdp OperandList.back().Rec = OpR; 8938889Sjdp } 9038889Sjdp } 9138889Sjdp 9238889Sjdp for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { 9333965Sjdp Record *OpR = OperandList[j].Rec; 9433965Sjdp std::string Res; 9533965Sjdp 9633965Sjdp if (OpR->isSubClassOf("RegisterClass")) 9733965Sjdp Res += getQualifiedName(OpR) + "RegClassID, "; 9833965Sjdp else if (OpR->isSubClassOf("PointerLikeRegClass")) 9938889Sjdp Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; 10038889Sjdp else 10133965Sjdp Res += "0, "; 10238889Sjdp 10338889Sjdp // Fill in applicable flags. 10433965Sjdp Res += "0"; 10538889Sjdp 10638889Sjdp // Ptr value whose register class is resolved via callback. 10738889Sjdp if (OpR->isSubClassOf("PointerLikeRegClass")) 10838889Sjdp Res += "|(1<<TOI::LookupPtrRegClass)"; 10938889Sjdp 11038889Sjdp // Predicate operands. Check to see if the original unexpanded operand 11138889Sjdp // was of type PredicateOperand. 11233965Sjdp if (Inst.OperandList[i].Rec->isSubClassOf("PredicateOperand")) 11338889Sjdp Res += "|(1<<TOI::Predicate)"; 11438889Sjdp 11538889Sjdp // Optional def operands. Check to see if the original unexpanded operand 11633965Sjdp // was of type OptionalDefOperand. 11738889Sjdp if (Inst.OperandList[i].Rec->isSubClassOf("OptionalDefOperand")) 11833965Sjdp Res += "|(1<<TOI::OptionalDef)"; 11938889Sjdp 12077298Sobrien // Fill in constraint info. 12133965Sjdp Res += ", " + Inst.OperandList[i].Constraints[j]; 12233965Sjdp Result.push_back(Res); 12333965Sjdp } 12433965Sjdp } 12533965Sjdp 12638889Sjdp return Result; 12738889Sjdp} 12833965Sjdp 12938889Sjdpvoid InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, 13038889Sjdp OperandInfoMapTy &OperandInfoIDs) { 13133965Sjdp // ID #0 is for no operand info. 13233965Sjdp unsigned OperandListNum = 0; 13333965Sjdp OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; 13433965Sjdp 13533965Sjdp OS << "\n"; 13633965Sjdp const CodeGenTarget &Target = CDP.getTargetInfo(); 13733965Sjdp for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 13833965Sjdp E = Target.inst_end(); II != E; ++II) { 13977298Sobrien std::vector<std::string> OperandInfo = GetOperandInfo(II->second); 14077298Sobrien unsigned &N = OperandInfoIDs[OperandInfo]; 14133965Sjdp if (N != 0) continue; 14233965Sjdp 14333965Sjdp N = ++OperandListNum; 14433965Sjdp OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { "; 14533965Sjdp for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) 14633965Sjdp OS << "{ " << OperandInfo[i] << " }, "; 14733965Sjdp OS << "};\n"; 14833965Sjdp } 14933965Sjdp} 15033965Sjdp 15133965Sjdpvoid InstrInfoEmitter::DetectRegisterClassBarriers(std::vector<Record*> &Defs, 15233965Sjdp const std::vector<CodeGenRegisterClass> &RCs, 15333965Sjdp std::vector<Record*> &Barriers) { 15433965Sjdp std::set<Record*> DefSet; 15533965Sjdp unsigned NumDefs = Defs.size(); 15633965Sjdp for (unsigned i = 0; i < NumDefs; ++i) 15733965Sjdp DefSet.insert(Defs[i]); 15833965Sjdp 15960484Sobrien for (unsigned i = 0, e = RCs.size(); i != e; ++i) { 16033965Sjdp const CodeGenRegisterClass &RC = RCs[i]; 16133965Sjdp unsigned NumRegs = RC.Elements.size(); 16233965Sjdp if (NumRegs > NumDefs) 16333965Sjdp continue; // Can't possibly clobber this RC. 16433965Sjdp 16533965Sjdp bool Clobber = true; 16660484Sobrien for (unsigned j = 0; j < NumRegs; ++j) { 16733965Sjdp Record *Reg = RC.Elements[j]; 16833965Sjdp if (!DefSet.count(Reg)) { 16933965Sjdp Clobber = false; 17033965Sjdp break; 17133965Sjdp } 17233965Sjdp } 17333965Sjdp if (Clobber) 17433965Sjdp Barriers.push_back(RC.TheDef); 17533965Sjdp } 17633965Sjdp} 17733965Sjdp 17833965Sjdp//===----------------------------------------------------------------------===// 17977298Sobrien// Main Output. 18033965Sjdp//===----------------------------------------------------------------------===// 18177298Sobrien 18233965Sjdp// run - Emit the main instruction description records for the target... 18333965Sjdpvoid InstrInfoEmitter::run(raw_ostream &OS) { 18433965Sjdp GatherItinClasses(); 18533965Sjdp 18633965Sjdp EmitSourceFileHeader("Target Instruction Descriptors", OS); 18733965Sjdp OS << "namespace llvm {\n\n"; 18833965Sjdp 18933965Sjdp CodeGenTarget &Target = CDP.getTargetInfo(); 19033965Sjdp const std::string &TargetName = Target.getName(); 19133965Sjdp Record *InstrInfo = Target.getInstructionSet(); 19233965Sjdp const std::vector<CodeGenRegisterClass> &RCs = Target.getRegisterClasses(); 19333965Sjdp 19433965Sjdp // Keep track of all of the def lists we have emitted already. 19533965Sjdp std::map<std::vector<Record*>, unsigned> EmittedLists; 19633965Sjdp unsigned ListNumber = 0; 19733965Sjdp std::map<std::vector<Record*>, unsigned> EmittedBarriers; 19833965Sjdp unsigned BarrierNumber = 0; 19933965Sjdp std::map<Record*, unsigned> BarriersMap; 20033965Sjdp 20133965Sjdp // Emit all of the instruction's implicit uses and defs. 20233965Sjdp for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 20333965Sjdp E = Target.inst_end(); II != E; ++II) { 20433965Sjdp Record *Inst = II->second.TheDef; 20533965Sjdp std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 20633965Sjdp if (!Uses.empty()) { 20733965Sjdp unsigned &IL = EmittedLists[Uses]; 20833965Sjdp if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); 20933965Sjdp } 21033965Sjdp std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 21133965Sjdp if (!Defs.empty()) { 21233965Sjdp std::vector<Record*> RCBarriers; 21360484Sobrien DetectRegisterClassBarriers(Defs, RCs, RCBarriers); 21433965Sjdp if (!RCBarriers.empty()) { 21533965Sjdp unsigned &IB = EmittedBarriers[RCBarriers]; 21633965Sjdp if (!IB) PrintBarriers(RCBarriers, IB = ++BarrierNumber, OS); 21733965Sjdp BarriersMap.insert(std::make_pair(Inst, IB)); 21833965Sjdp } 21933965Sjdp 22033965Sjdp unsigned &IL = EmittedLists[Defs]; 22160484Sobrien if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); 22233965Sjdp } 22333965Sjdp } 22433965Sjdp 22533965Sjdp OperandInfoMapTy OperandInfoIDs; 22633965Sjdp 22733965Sjdp // Emit all of the operand info records. 22833965Sjdp EmitOperandInfo(OS, OperandInfoIDs); 22960484Sobrien 23033965Sjdp // Emit all of the TargetInstrDesc records in their ENUM ordering. 23133965Sjdp // 23233965Sjdp OS << "\nstatic const TargetInstrDesc " << TargetName 23333965Sjdp << "Insts[] = {\n"; 23433965Sjdp std::vector<const CodeGenInstruction*> NumberedInstructions; 23533965Sjdp Target.getInstructionsByEnumValue(NumberedInstructions); 23633965Sjdp 23733965Sjdp for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) 23833965Sjdp emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists, 23933965Sjdp BarriersMap, OperandInfoIDs, OS); 24060484Sobrien OS << "};\n"; 24133965Sjdp OS << "} // End llvm namespace \n"; 24233965Sjdp} 24333965Sjdp 24433965Sjdpvoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 24533965Sjdp Record *InstrInfo, 24633965Sjdp std::map<std::vector<Record*>, unsigned> &EmittedLists, 24733965Sjdp std::map<Record*, unsigned> &BarriersMap, 24833965Sjdp const OperandInfoMapTy &OpInfo, 24933965Sjdp raw_ostream &OS) { 25033965Sjdp int MinOperands = 0; 25133965Sjdp if (!Inst.OperandList.empty()) 25233965Sjdp // Each logical operand can be multiple MI operands. 25333965Sjdp MinOperands = Inst.OperandList.back().MIOperandNo + 25433965Sjdp Inst.OperandList.back().MINumOperands; 25533965Sjdp 25633965Sjdp OS << " { "; 25733965Sjdp OS << Num << ",\t" << MinOperands << ",\t" 25833965Sjdp << Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef) 25933965Sjdp << ",\t\"" << Inst.TheDef->getName() << "\", 0"; 26033965Sjdp 26133965Sjdp // Emit all of the target indepedent flags... 26233965Sjdp if (Inst.isReturn) OS << "|(1<<TID::Return)"; 26333965Sjdp if (Inst.isBranch) OS << "|(1<<TID::Branch)"; 26433965Sjdp if (Inst.isIndirectBranch) OS << "|(1<<TID::IndirectBranch)"; 26533965Sjdp if (Inst.isBarrier) OS << "|(1<<TID::Barrier)"; 26633965Sjdp if (Inst.hasDelaySlot) OS << "|(1<<TID::DelaySlot)"; 26733965Sjdp if (Inst.isCall) OS << "|(1<<TID::Call)"; 26833965Sjdp if (Inst.canFoldAsLoad) OS << "|(1<<TID::FoldableAsLoad)"; 26933965Sjdp if (Inst.mayLoad) OS << "|(1<<TID::MayLoad)"; 27033965Sjdp if (Inst.mayStore) OS << "|(1<<TID::MayStore)"; 27133965Sjdp if (Inst.isPredicable) OS << "|(1<<TID::Predicable)"; 27233965Sjdp if (Inst.isConvertibleToThreeAddress) OS << "|(1<<TID::ConvertibleTo3Addr)"; 27333965Sjdp if (Inst.isCommutable) OS << "|(1<<TID::Commutable)"; 27433965Sjdp if (Inst.isTerminator) OS << "|(1<<TID::Terminator)"; 27533965Sjdp if (Inst.isReMaterializable) OS << "|(1<<TID::Rematerializable)"; 27633965Sjdp if (Inst.isNotDuplicable) OS << "|(1<<TID::NotDuplicable)"; 27733965Sjdp if (Inst.hasOptionalDef) OS << "|(1<<TID::HasOptionalDef)"; 27833965Sjdp if (Inst.usesCustomInserter) OS << "|(1<<TID::UsesCustomInserter)"; 27933965Sjdp if (Inst.isVariadic) OS << "|(1<<TID::Variadic)"; 28033965Sjdp if (Inst.hasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)"; 28133965Sjdp if (Inst.isAsCheapAsAMove) OS << "|(1<<TID::CheapAsAMove)"; 28233965Sjdp if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<TID::ExtraSrcRegAllocReq)"; 28333965Sjdp if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<TID::ExtraDefRegAllocReq)"; 28433965Sjdp OS << ", 0"; 28533965Sjdp 28633965Sjdp // Emit all of the target-specific flags... 28733965Sjdp ListInit *LI = InstrInfo->getValueAsListInit("TSFlagsFields"); 28833965Sjdp ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts"); 28933965Sjdp if (LI->getSize() != Shift->getSize()) 29033965Sjdp throw "Lengths of " + InstrInfo->getName() + 29133965Sjdp ":(TargetInfoFields, TargetInfoPositions) must be equal!"; 29233965Sjdp 29333965Sjdp for (unsigned i = 0, e = LI->getSize(); i != e; ++i) 29433965Sjdp emitShiftedValue(Inst.TheDef, dynamic_cast<StringInit*>(LI->getElement(i)), 29533965Sjdp dynamic_cast<IntInit*>(Shift->getElement(i)), OS); 29633965Sjdp 29733965Sjdp OS << ", "; 29833965Sjdp 29933965Sjdp // Emit the implicit uses and defs lists... 30033965Sjdp std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 30133965Sjdp if (UseList.empty()) 30233965Sjdp OS << "NULL, "; 30333965Sjdp else 30433965Sjdp OS << "ImplicitList" << EmittedLists[UseList] << ", "; 30560484Sobrien 30660484Sobrien std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 30760484Sobrien if (DefList.empty()) 30860484Sobrien OS << "NULL, "; 30933965Sjdp else 31033965Sjdp OS << "ImplicitList" << EmittedLists[DefList] << ", "; 31133965Sjdp 31233965Sjdp std::map<Record*, unsigned>::iterator BI = BarriersMap.find(Inst.TheDef); 31333965Sjdp if (BI == BarriersMap.end()) 31433965Sjdp OS << "NULL, "; 31533965Sjdp else 31633965Sjdp OS << "Barriers" << BI->second << ", "; 31733965Sjdp 31833965Sjdp // Emit the operand info. 31933965Sjdp std::vector<std::string> OperandInfo = GetOperandInfo(Inst); 32033965Sjdp if (OperandInfo.empty()) 32133965Sjdp OS << "0"; 32233965Sjdp else 32333965Sjdp OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 32433965Sjdp 32533965Sjdp OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 32633965Sjdp} 32733965Sjdp 32833965Sjdp 32933965Sjdpvoid InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, 33033965Sjdp IntInit *ShiftInt, raw_ostream &OS) { 33133965Sjdp if (Val == 0 || ShiftInt == 0) 33233965Sjdp throw std::string("Illegal value or shift amount in TargetInfo*!"); 33333965Sjdp RecordVal *RV = R->getValue(Val->getValue()); 33433965Sjdp int Shift = ShiftInt->getValue(); 33533965Sjdp 33633965Sjdp if (RV == 0 || RV->getValue() == 0) { 33733965Sjdp // This isn't an error if this is a builtin instruction. 33833965Sjdp if (R->getName() != "PHI" && 33933965Sjdp R->getName() != "INLINEASM" && 34033965Sjdp R->getName() != "DBG_LABEL" && 34133965Sjdp R->getName() != "EH_LABEL" && 34233965Sjdp R->getName() != "GC_LABEL" && 34333965Sjdp R->getName() != "KILL" && 34433965Sjdp R->getName() != "EXTRACT_SUBREG" && 34533965Sjdp R->getName() != "INSERT_SUBREG" && 34633965Sjdp R->getName() != "IMPLICIT_DEF" && 34733965Sjdp R->getName() != "SUBREG_TO_REG" && 34833965Sjdp R->getName() != "COPY_TO_REGCLASS") 34933965Sjdp throw R->getName() + " doesn't have a field named '" + 35033965Sjdp Val->getValue() + "'!"; 35133965Sjdp return; 35233965Sjdp } 35333965Sjdp 35433965Sjdp Init *Value = RV->getValue(); 35533965Sjdp if (BitInit *BI = dynamic_cast<BitInit*>(Value)) { 35633965Sjdp if (BI->getValue()) OS << "|(1<<" << Shift << ")"; 35733965Sjdp return; 35833965Sjdp } else if (BitsInit *BI = dynamic_cast<BitsInit*>(Value)) { 35933965Sjdp // Convert the Bits to an integer to print... 36033965Sjdp Init *I = BI->convertInitializerTo(new IntRecTy()); 36133965Sjdp if (I) 36233965Sjdp if (IntInit *II = dynamic_cast<IntInit*>(I)) { 36333965Sjdp if (II->getValue()) { 36433965Sjdp if (Shift) 36533965Sjdp OS << "|(" << II->getValue() << "<<" << Shift << ")"; 36633965Sjdp else 36733965Sjdp OS << "|" << II->getValue(); 36833965Sjdp } 36933965Sjdp return; 37033965Sjdp } 37133965Sjdp 37233965Sjdp } else if (IntInit *II = dynamic_cast<IntInit*>(Value)) { 37333965Sjdp if (II->getValue()) { 37433965Sjdp if (Shift) 37533965Sjdp OS << "|(" << II->getValue() << "<<" << Shift << ")"; 37633965Sjdp else 37733965Sjdp OS << II->getValue(); 37833965Sjdp } 37933965Sjdp return; 38033965Sjdp } 38133965Sjdp 38233965Sjdp errs() << "Unhandled initializer: " << *Val << "\n"; 38333965Sjdp throw "In record '" + R->getName() + "' for TSFlag emission."; 38433965Sjdp} 38533965Sjdp 38633965Sjdp