diff options
Diffstat (limited to 'utils/TableGen/FastISelEmitter.cpp')
-rw-r--r-- | utils/TableGen/FastISelEmitter.cpp | 94 |
1 files changed, 66 insertions, 28 deletions
diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index cbe77f6d5d..b343013b06 100644 --- a/utils/TableGen/FastISelEmitter.cpp +++ b/utils/TableGen/FastISelEmitter.cpp @@ -175,10 +175,11 @@ void FastISelEmitter::run(std::ostream &OS) { OS << "namespace " << InstNS.substr(0, InstNS.size() - 2) << " {\n"; OS << "\n"; - typedef std::map<MVT::SimpleValueType, InstructionMemo> TypeMap; - typedef std::map<std::string, TypeMap> OpcodeTypeMap; - typedef std::map<OperandsSignature, OpcodeTypeMap> OperandsOpcodeTypeMap; - OperandsOpcodeTypeMap SimplePatterns; + typedef std::map<std::string, InstructionMemo> PredMap; + typedef std::map<MVT::SimpleValueType, PredMap> TypePredMap; + typedef std::map<std::string, TypePredMap> OpcodeTypePredMap; + typedef std::map<OperandsSignature, OpcodeTypePredMap> OperandsOpcodeTypePredMap; + OperandsOpcodeTypePredMap SimplePatterns; for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end(); I != E; ++I) { @@ -230,27 +231,32 @@ void FastISelEmitter::run(std::ostream &OS) { if (!Operands.initialize(InstPatNode, Target, VT, DstRC)) continue; + // Get the predicate that guards this pattern. + std::string PredicateCheck = Pattern.getPredicateCheck(); + // Ok, we found a pattern that we can handle. Remember it. InstructionMemo Memo = { Pattern.getDstPattern()->getOperator()->getName(), DstRC }; - SimplePatterns[Operands][OpcodeName][VT] = Memo; + assert(!SimplePatterns[Operands][OpcodeName][VT].count(PredicateCheck) && + "Duplicate pattern!"); + SimplePatterns[Operands][OpcodeName][VT][PredicateCheck] = Memo; } // Declare the target FastISel class. OS << "class FastISel : public llvm::FastISel {\n"; - for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(), + for (OperandsOpcodeTypePredMap::const_iterator OI = SimplePatterns.begin(), OE = SimplePatterns.end(); OI != OE; ++OI) { const OperandsSignature &Operands = OI->first; - const OpcodeTypeMap &OTM = OI->second; + const OpcodeTypePredMap &OTM = OI->second; - for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end(); + for (OpcodeTypePredMap::const_iterator I = OTM.begin(), E = OTM.end(); I != E; ++I) { const std::string &Opcode = I->first; - const TypeMap &TM = I->second; + const TypePredMap &TM = I->second; - for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end(); + for (TypePredMap::const_iterator TI = TM.begin(), TE = TM.end(); TI != TE; ++TI) { MVT::SimpleValueType VT = TI->first; @@ -279,8 +285,19 @@ void FastISelEmitter::run(std::ostream &OS) { Operands.PrintParameters(OS); OS << ");\n"; } + OS << "\n"; + + // Declare the Subtarget member, which is used for predicate checks. + OS << " const " << InstNS.substr(0, InstNS.size() - 2) + << "Subtarget *Subtarget;\n"; + OS << "\n"; + + // Declare the constructor. OS << "public:\n"; - OS << " explicit FastISel(MachineFunction &mf) : llvm::FastISel(mf) {}\n"; + OS << " explicit FastISel(MachineFunction &mf)\n"; + OS << " : llvm::FastISel(mf),\n"; + OS << " Subtarget(&TM.getSubtarget<" << InstNS.substr(0, InstNS.size() - 2) + << "Subtarget>()) {}\n"; OS << "};\n"; OS << "\n"; @@ -291,25 +308,26 @@ void FastISelEmitter::run(std::ostream &OS) { OS << "\n"; // Now emit code for all the patterns that we collected. - for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(), + for (OperandsOpcodeTypePredMap::const_iterator OI = SimplePatterns.begin(), OE = SimplePatterns.end(); OI != OE; ++OI) { const OperandsSignature &Operands = OI->first; - const OpcodeTypeMap &OTM = OI->second; + const OpcodeTypePredMap &OTM = OI->second; - for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end(); + for (OpcodeTypePredMap::const_iterator I = OTM.begin(), E = OTM.end(); I != E; ++I) { const std::string &Opcode = I->first; - const TypeMap &TM = I->second; + const TypePredMap &TM = I->second; OS << "// FastEmit functions for " << Opcode << ".\n"; OS << "\n"; // Emit one function for each opcode,type pair. - for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end(); + for (TypePredMap::const_iterator TI = TM.begin(), TE = TM.end(); TI != TE; ++TI) { MVT::SimpleValueType VT = TI->first; - const InstructionMemo &Memo = TI->second; - + const PredMap &PM = TI->second; + bool HasPred = false; + OS << "unsigned FastISel::FastEmit_" << getLegalCName(Opcode) << "_" << getLegalCName(getName(VT)) << "_"; @@ -317,14 +335,34 @@ void FastISelEmitter::run(std::ostream &OS) { OS << "("; Operands.PrintParameters(OS); OS << ") {\n"; - OS << " return FastEmitInst_"; - Operands.PrintManglingSuffix(OS); - OS << "(" << InstNS << Memo.Name << ", "; - OS << InstNS << Memo.RC->getName() << "RegisterClass"; - if (!Operands.empty()) - OS << ", "; - Operands.PrintArguments(OS); - OS << ");\n"; + + // Emit code for each possible instruction. There may be + // multiple if there are subtarget concerns. + for (PredMap::const_iterator PI = PM.begin(), PE = PM.end(); + PI != PE; ++PI) { + std::string PredicateCheck = PI->first; + const InstructionMemo &Memo = PI->second; + + if (PredicateCheck.empty()) { + assert(!HasPred && "Multiple instructions match, at least one has " + "a predicate and at least one doesn't!"); + } else { + OS << " if (" + PredicateCheck + ")\n"; + OS << " "; + HasPred = true; + } + OS << " return FastEmitInst_"; + Operands.PrintManglingSuffix(OS); + OS << "(" << InstNS << Memo.Name << ", "; + OS << InstNS << Memo.RC->getName() << "RegisterClass"; + if (!Operands.empty()) + OS << ", "; + Operands.PrintArguments(OS); + OS << ");\n"; + } + // Return 0 if none of the predicates were satisfied. + if (HasPred) + OS << " return 0;\n"; OS << "}\n"; OS << "\n"; } @@ -339,7 +377,7 @@ void FastISelEmitter::run(std::ostream &OS) { Operands.PrintParameters(OS); OS << ") {\n"; OS << " switch (VT) {\n"; - for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end(); + for (TypePredMap::const_iterator TI = TM.begin(), TE = TM.end(); TI != TE; ++TI) { MVT::SimpleValueType VT = TI->first; std::string TypeName = getName(VT); @@ -366,7 +404,7 @@ void FastISelEmitter::run(std::ostream &OS) { Operands.PrintParameters(OS); OS << ") {\n"; OS << " switch (Opcode) {\n"; - for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end(); + for (OpcodeTypePredMap::const_iterator I = OTM.begin(), E = OTM.end(); I != E; ++I) { const std::string &Opcode = I->first; |