X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FFastISelEmitter.cpp;h=ce7f8c81632a7a919b6dd50e604699312dd7c620;hb=7a88b655ccad0f128ea1a5e8ca433a8827a24ff3;hp=e8dad77302c3b163709c6ebf6defe1dd66318469;hpb=f321e1075eabae96f62b1f2570d9dee5d10b8200;p=oota-llvm.git diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index e8dad77302c..ce7f8c81632 100644 --- a/utils/TableGen/FastISelEmitter.cpp +++ b/utils/TableGen/FastISelEmitter.cpp @@ -17,28 +17,31 @@ // //===----------------------------------------------------------------------===// -#include "FastISelEmitter.h" -#include "llvm/TableGen/Error.h" -#include "llvm/TableGen/Record.h" +#include "CodeGenDAGPatterns.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" using namespace llvm; -namespace { /// InstructionMemo - This class holds additional information about an /// instruction needed to emit code for it. /// +namespace { struct InstructionMemo { std::string Name; const CodeGenRegisterClass *RC; std::string SubRegNo; std::vector* PhysRegs; }; - +} // End anonymous namespace + /// ImmPredicateSet - This uniques predicates (represented as a string) and /// gives them unique (small) integer ID's that start at 0. +namespace { class ImmPredicateSet { DenseMap ImmIDs; std::vector PredsByName; @@ -63,10 +66,12 @@ public: iterator end() const { return PredsByName.end(); } }; +} // End anonymous namespace /// OperandsSignature - This class holds a description of a list of operand /// types. It has utility methods for emitting text based on the operands. /// +namespace { struct OperandsSignature { class OpKind { enum { OK_Reg, OK_FP, OK_Imm, OK_Invalid = -1 }; @@ -168,7 +173,8 @@ struct OperandsSignature { /// bool initialize(TreePatternNode *InstPatNode, const CodeGenTarget &Target, MVT::SimpleValueType VT, - ImmPredicateSet &ImmediatePredicates) { + ImmPredicateSet &ImmediatePredicates, + const CodeGenRegisterClass *OrigDstRC) { if (InstPatNode->isLeaf()) return false; @@ -240,7 +246,7 @@ struct OperandsSignature { if (Op->getType(0) != VT) return false; - DefInit *OpDI = dynamic_cast(Op->getLeafValue()); + DefInit *OpDI = dyn_cast(Op->getLeafValue()); if (!OpDI) return false; Record *OpLeafRec = OpDI->getDef(); @@ -253,7 +259,9 @@ struct OperandsSignature { RC = &Target.getRegisterClass(OpLeafRec); else if (OpLeafRec->isSubClassOf("Register")) RC = Target.getRegBank().getRegClassForRegister(OpLeafRec); - else + else if (OpLeafRec->isSubClassOf("ValueType")) { + RC = OrigDstRC; + } else return false; // For now, this needs to be a register class of some sort. @@ -352,7 +360,9 @@ struct OperandsSignature { Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes); } }; +} // End anonymous namespace +namespace { class FastISelMap { typedef std::map PredMap; typedef std::map RetPredMap; @@ -375,8 +385,7 @@ public: void printImmediatePredicates(raw_ostream &OS); void printFunctionDefinitions(raw_ostream &OS); }; - -} +} // End anonymous namespace static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) { return CGP.getSDNodeInfo(Op).getEnumName(); @@ -400,13 +409,12 @@ static std::string PhyRegForNode(TreePatternNode *Op, if (!Op->isLeaf()) return PhysReg; - DefInit *OpDI = dynamic_cast(Op->getLeafValue()); - Record *OpLeafRec = OpDI->getDef(); + Record *OpLeafRec = cast(Op->getLeafValue())->getDef(); if (!OpLeafRec->isSubClassOf("Register")) return PhysReg; - PhysReg += static_cast(OpLeafRec->getValue( \ - "Namespace")->getValue())->getValue(); + PhysReg += cast(OpLeafRec->getValue("Namespace")->getValue()) + ->getValue(); PhysReg += "::"; PhysReg += Target.getRegBank().getReg(OpLeafRec)->getName(); return PhysReg; @@ -467,7 +475,7 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { // a bit too complicated for now. if (!Dst->getChild(1)->isLeaf()) continue; - DefInit *SR = dynamic_cast(Dst->getChild(1)->getLeafValue()); + DefInit *SR = dyn_cast(Dst->getChild(1)->getLeafValue()); if (SR) SubRegNo = getQualifiedName(SR->getDef()); else @@ -498,7 +506,8 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { // Check all the operands. OperandsSignature Operands; - if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates)) + if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates, + DstRC)) continue; std::vector* PhysRegInputs = new std::vector(); @@ -544,7 +553,7 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { }; if (SimplePatterns[Operands][OpcodeName][VT][RetVT].count(PredicateCheck)) - throw TGError(Pattern.getSrcRecord()->getLoc(), + PrintFatalError(Pattern.getSrcRecord()->getLoc(), "Duplicate record in FastISel table!"); SimplePatterns[Operands][OpcodeName][VT][RetVT][PredicateCheck] = Memo; @@ -639,7 +648,7 @@ void FastISelMap::printFunctionDefinitions(raw_ostream &OS) { Operands.PrintManglingSuffix(OS, *Memo.PhysRegs, ImmediatePredicates, true); OS << "(" << InstNS << Memo.Name << ", "; - OS << InstNS << Memo.RC->getName() << "RegisterClass"; + OS << "&" << InstNS << Memo.RC->getName() << "RegClass"; if (!Operands.empty()) OS << ", "; Operands.PrintArguments(OS, *Memo.PhysRegs); @@ -731,7 +740,7 @@ void FastISelMap::printFunctionDefinitions(raw_ostream &OS) { Operands.PrintManglingSuffix(OS, *Memo.PhysRegs, ImmediatePredicates, true); OS << "(" << InstNS << Memo.Name << ", "; - OS << InstNS << Memo.RC->getName() << "RegisterClass"; + OS << "&" << InstNS << Memo.RC->getName() << "RegClass"; if (!Operands.empty()) OS << ", "; Operands.PrintArguments(OS, *Memo.PhysRegs); @@ -850,23 +859,22 @@ void FastISelMap::printFunctionDefinitions(raw_ostream &OS) { // TODO: SignaturesWithConstantForms should be empty here. } -void FastISelEmitter::run(raw_ostream &OS) { +namespace llvm { + +void EmitFastISel(RecordKeeper &RK, raw_ostream &OS) { + CodeGenDAGPatterns CGP(RK); const CodeGenTarget &Target = CGP.getTargetInfo(); + emitSourceFileHeader("\"Fast\" Instruction Selector for the " + + Target.getName() + " target", OS); // Determine the target's namespace name. std::string InstNS = Target.getInstNamespace() + "::"; assert(InstNS.size() > 2 && "Can't determine target-specific namespace!"); - EmitSourceFileHeader("\"Fast\" Instruction Selector for the " + - Target.getName() + " target", OS); - FastISelMap F(InstNS); F.collectPatterns(CGP); F.printImmediatePredicates(OS); F.printFunctionDefinitions(OS); } -FastISelEmitter::FastISelEmitter(RecordKeeper &R) - : Records(R), CGP(R) { -} - +} // End llvm namespace