X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FFastISelEmitter.cpp;h=ca784d0dda92e3b5e52e76e30d811061648c4afd;hb=95c929f45c01054d91a6878de22892675dd115cf;hp=e3d47aa49a0e6e1cd6dab2930f969556ade3a715;hpb=202a7a1e3fa661bf78b98d77de7e2d575facd9ee;p=oota-llvm.git diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index e3d47aa49a0..ca784d0dda9 100644 --- a/utils/TableGen/FastISelEmitter.cpp +++ b/utils/TableGen/FastISelEmitter.cpp @@ -17,27 +17,31 @@ // //===----------------------------------------------------------------------===// -#include "FastISelEmitter.h" -#include "Record.h" -#include "llvm/Support/Debug.h" +#include "CodeGenDAGPatterns.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/VectorExtras.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; @@ -62,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 }; @@ -246,10 +252,12 @@ struct OperandsSignature { // For now, the only other thing we accept is register operands. const CodeGenRegisterClass *RC = 0; + if (OpLeafRec->isSubClassOf("RegisterOperand")) + OpLeafRec = OpLeafRec->getValueAsDef("RegClass"); if (OpLeafRec->isSubClassOf("RegisterClass")) RC = &Target.getRegisterClass(OpLeafRec); else if (OpLeafRec->isSubClassOf("Register")) - RC = Target.getRegisterClassForRegister(OpLeafRec); + RC = Target.getRegBank().getRegClassForRegister(OpLeafRec); else return false; @@ -276,10 +284,9 @@ struct OperandsSignature { } else if (Operands[i].isImm()) { OS << "uint64_t imm" << i; } else if (Operands[i].isFP()) { - OS << "ConstantFP *f" << i; + OS << "const ConstantFP *f" << i; } else { - assert("Unknown operand kind!"); - abort(); + llvm_unreachable("Unknown operand kind!"); } if (i + 1 != e) OS << ", "; @@ -307,8 +314,7 @@ struct OperandsSignature { OS << "f" << i; PrintedArg = true; } else { - assert("Unknown operand kind!"); - abort(); + llvm_unreachable("Unknown operand kind!"); } } } @@ -322,8 +328,7 @@ struct OperandsSignature { } else if (Operands[i].isFP()) { OS << "f" << i; } else { - assert("Unknown operand kind!"); - abort(); + llvm_unreachable("Unknown operand kind!"); } if (i + 1 != e) OS << ", "; @@ -352,7 +357,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 +382,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(); @@ -393,6 +399,25 @@ FastISelMap::FastISelMap(std::string instns) : InstNS(instns) { } +static std::string PhyRegForNode(TreePatternNode *Op, + const CodeGenTarget &Target) { + std::string PhysReg; + + if (!Op->isLeaf()) + return PhysReg; + + DefInit *OpDI = dynamic_cast(Op->getLeafValue()); + Record *OpLeafRec = OpDI->getDef(); + if (!OpLeafRec->isSubClassOf("Register")) + return PhysReg; + + PhysReg += static_cast(OpLeafRec->getValue( \ + "Namespace")->getValue())->getValue(); + PhysReg += "::"; + PhysReg += Target.getRegBank().getReg(OpLeafRec)->getName(); + return PhysReg; +} + void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { const CodeGenTarget &Target = CGP.getTargetInfo(); @@ -436,6 +461,8 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { std::string SubRegNo; if (Op->getName() != "EXTRACT_SUBREG") { Record *Op0Rec = II.Operands[0].Rec; + if (Op0Rec->isSubClassOf("RegisterOperand")) + Op0Rec = Op0Rec->getValueAsDef("RegClass"); if (!Op0Rec->isSubClassOf("RegisterClass")) continue; DstRC = &Target.getRegisterClass(Op0Rec); @@ -470,11 +497,6 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { assert(InstPatNode->getChild(0)->getNumTypes() == 1); VT = InstPatNode->getChild(0)->getType(0); } - - // For now, filter out instructions which just set a register to - // an Operand or an immediate, like MOV32ri. - if (InstPatOp->isSubClassOf("Operand")) - continue; // For now, filter out any instructions with predicates. if (!InstPatNode->getPredicateFns().empty()) @@ -486,39 +508,35 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { continue; std::vector* PhysRegInputs = new std::vector(); - if (!InstPatNode->isLeaf() && - (InstPatNode->getOperator()->getName() == "imm" || - InstPatNode->getOperator()->getName() == "fpimmm")) + if (InstPatNode->getOperator()->getName() == "imm" || + InstPatNode->getOperator()->getName() == "fpimm") PhysRegInputs->push_back(""); - else if (!InstPatNode->isLeaf()) { + else { + // Compute the PhysRegs used by the given pattern, and check that + // the mapping from the src to dst patterns is simple. + bool FoundNonSimplePattern = false; + unsigned DstIndex = 0; for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) { - TreePatternNode *Op = InstPatNode->getChild(i); - if (!Op->isLeaf()) { - PhysRegInputs->push_back(""); - continue; - } - - DefInit *OpDI = dynamic_cast(Op->getLeafValue()); - Record *OpLeafRec = OpDI->getDef(); - std::string PhysReg; - if (OpLeafRec->isSubClassOf("Register")) { - PhysReg += static_cast(OpLeafRec->getValue( \ - "Namespace")->getValue())->getValue(); - PhysReg += "::"; - - std::vector Regs = Target.getRegisters(); - for (unsigned i = 0; i < Regs.size(); ++i) { - if (Regs[i].TheDef == OpLeafRec) { - PhysReg += Regs[i].getName(); - break; - } + std::string PhysReg = PhyRegForNode(InstPatNode->getChild(i), Target); + if (PhysReg.empty()) { + if (DstIndex >= Dst->getNumChildren() || + Dst->getChild(DstIndex)->getName() != + InstPatNode->getChild(i)->getName()) { + FoundNonSimplePattern = true; + break; } + ++DstIndex; } PhysRegInputs->push_back(PhysReg); } - } else - PhysRegInputs->push_back(""); + + if (Op->getName() != "EXTRACT_SUBREG" && DstIndex < Dst->getNumChildren()) + FoundNonSimplePattern = true; + + if (FoundNonSimplePattern) + continue; + } // Get the predicate that guards this pattern. std::string PredicateCheck = Pattern.getPredicateCheck(); @@ -627,7 +645,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); @@ -719,7 +737,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); @@ -838,23 +856,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