Index: /home/seurer/llvm/llvm-oneoff/utils/TableGen/FastISelEmitter.cpp =================================================================== --- /home/seurer/llvm/llvm-oneoff/utils/TableGen/FastISelEmitter.cpp +++ /home/seurer/llvm/llvm-oneoff/utils/TableGen/FastISelEmitter.cpp @@ -37,6 +37,7 @@ const CodeGenRegisterClass *RC; std::string SubRegNo; std::vector* PhysRegs; + std::string PredicateCheck; }; } // End anonymous namespace @@ -365,7 +366,9 @@ namespace { class FastISelMap { - typedef std::map PredMap; + // A multimap is needed instead of a "plain" map because the key is + // the instruction's complexity (an int) and they are not unique. + typedef std::multimap PredMap; typedef std::map RetPredMap; typedef std::map TypeRetPredMap; typedef std::map OpcodeTypeRetPredMap; @@ -374,6 +377,16 @@ OperandsOpcodeTypeRetPredMap SimplePatterns; + // This is used to check that there are no duplicate predicates + typedef std::multimap PredCheckMap; + typedef std::map RetPredCheckMap; + typedef std::map TypeRetPredCheckMap; + typedef std::map OpcodeTypeRetPredCheckMap; + typedef std::map + OperandsOpcodeTypeRetPredCheckMap; + + OperandsOpcodeTypeRetPredCheckMap SimplePatternsCheck; + std::map > SignaturesWithConstantForms; @@ -385,6 +398,11 @@ void collectPatterns(CodeGenDAGPatterns &CGP); void printImmediatePredicates(raw_ostream &OS); void printFunctionDefinitions(raw_ostream &OS); +private: + void emitInstructionCode(raw_ostream &OS, + const OperandsSignature &Operands, + const PredMap &PM, + const std::string &RetVTName); }; } // End anonymous namespace @@ -561,14 +579,24 @@ Pattern.getDstPattern()->getOperator()->getName(), DstRC, SubRegNo, - PhysRegInputs + PhysRegInputs, + PredicateCheck }; + + int complexity = Pattern.getPatternComplexity(CGP); - if (SimplePatterns[Operands][OpcodeName][VT][RetVT].count(PredicateCheck)) + if (SimplePatternsCheck[Operands][OpcodeName][VT] + [RetVT].count(PredicateCheck)) { PrintFatalError(Pattern.getSrcRecord()->getLoc(), - "Duplicate record in FastISel table!"); + "Duplicate predicate in FastISel table!"); + } + SimplePatternsCheck[Operands][OpcodeName][VT][RetVT].insert( + std::make_pair(PredicateCheck, true)); - SimplePatterns[Operands][OpcodeName][VT][RetVT][PredicateCheck] = Memo; + // Note: Instructions with the same complexity will appear in the order + // that they are encountered. + SimplePatterns[Operands][OpcodeName][VT][RetVT].insert( + std::make_pair(complexity, Memo)); // If any of the operands were immediates with predicates on them, strip // them down to a signature that doesn't have predicates so that we can @@ -594,6 +622,71 @@ OS << "\n\n"; } +void FastISelMap::emitInstructionCode(raw_ostream &OS, + const OperandsSignature &Operands, + const PredMap &PM, + const std::string &RetVTName) { + // Emit code for each possible instruction. There may be + // multiple if there are subtarget concerns. A reverse iterator + // is used to produce the ones with highest complexity first. + + bool OneHadNoPredicate = false; + for (PredMap::const_reverse_iterator PI = PM.rbegin(), PE = PM.rend(); + PI != PE; ++PI) { + const InstructionMemo &Memo = PI->second; + std::string PredicateCheck = Memo.PredicateCheck; + + if (PredicateCheck.empty()) { + assert(!OneHadNoPredicate && + "Multiple instructions match and more than one had " + "no predicate!"); + OneHadNoPredicate = true; + } else { + if (OneHadNoPredicate) { + // FIXME: This should be a PrintError once the x86 target fixes PR21575 + PrintWarning("Multiple instructions match and one with no " + "predicate came before one with a predicate! " + "name:" + Memo.Name + " predicate: " + + PredicateCheck); + } + OS << " if (" + PredicateCheck + ") {\n"; + OS << " "; + } + + for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) { + if ((*Memo.PhysRegs)[i] != "") + OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, " + << "TII.get(TargetOpcode::COPY), " + << (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n"; + } + + OS << " return fastEmitInst_"; + if (Memo.SubRegNo.empty()) { + Operands.PrintManglingSuffix(OS, *Memo.PhysRegs, + ImmediatePredicates, true); + OS << "(" << InstNS << Memo.Name << ", "; + OS << "&" << InstNS << Memo.RC->getName() << "RegClass"; + if (!Operands.empty()) + OS << ", "; + Operands.PrintArguments(OS, *Memo.PhysRegs); + OS << ");\n"; + } else { + OS << "extractsubreg(" << RetVTName + << ", Op0, Op0IsKill, " << Memo.SubRegNo << ");\n"; + } + + if (!PredicateCheck.empty()) { + OS << " }\n"; + } + } + // Return 0 if all of the possibilities had predicates but none + // were satisfied. + if (!OneHadNoPredicate) + OS << " return 0;\n"; + OS << "}\n"; + OS << "\n"; +} + void FastISelMap::printFunctionDefinitions(raw_ostream &OS) { // Now emit code for all the patterns that we collected. @@ -620,7 +713,6 @@ RI != RE; ++RI) { MVT::SimpleValueType RetVT = RI->first; const PredMap &PM = RI->second; - bool HasPred = false; OS << "unsigned fastEmit_" << getLegalCName(Opcode) @@ -631,54 +723,7 @@ Operands.PrintParameters(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; - } - - for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) { - if ((*Memo.PhysRegs)[i] != "") - OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, " - << "TII.get(TargetOpcode::COPY), " - << (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n"; - } - - OS << " return fastEmitInst_"; - if (Memo.SubRegNo.empty()) { - Operands.PrintManglingSuffix(OS, *Memo.PhysRegs, - ImmediatePredicates, true); - OS << "(" << InstNS << Memo.Name << ", "; - OS << "&" << InstNS << Memo.RC->getName() << "RegClass"; - if (!Operands.empty()) - OS << ", "; - Operands.PrintArguments(OS, *Memo.PhysRegs); - OS << ");\n"; - } else { - OS << "extractsubreg(" << getName(RetVT); - OS << ", Op0, Op0IsKill, " << Memo.SubRegNo << ");\n"; - } - - if (HasPred) - OS << " }\n"; - - } - // Return 0 if none of the predicates were satisfied. - if (HasPred) - OS << " return 0;\n"; - OS << "}\n"; - OS << "\n"; + emitInstructionCode(OS, Operands, PM, getName(RetVT)); } // Emit one function for the type that demultiplexes on return type. @@ -720,58 +765,8 @@ << ")\n return 0;\n"; const PredMap &PM = RM.begin()->second; - bool HasPred = false; - - // 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; - } - - for (unsigned i = 0; i < Memo.PhysRegs->size(); ++i) { - if ((*Memo.PhysRegs)[i] != "") - OS << " BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, " - << "TII.get(TargetOpcode::COPY), " - << (*Memo.PhysRegs)[i] << ").addReg(Op" << i << ");\n"; - } - - OS << " return fastEmitInst_"; - - if (Memo.SubRegNo.empty()) { - Operands.PrintManglingSuffix(OS, *Memo.PhysRegs, - ImmediatePredicates, true); - OS << "(" << InstNS << Memo.Name << ", "; - OS << "&" << InstNS << Memo.RC->getName() << "RegClass"; - if (!Operands.empty()) - OS << ", "; - Operands.PrintArguments(OS, *Memo.PhysRegs); - OS << ");\n"; - } else { - OS << "extractsubreg(RetVT, Op0, Op0IsKill, "; - OS << Memo.SubRegNo; - OS << ");\n"; - } - - if (HasPred) - OS << " }\n"; - } - // Return 0 if none of the predicates were satisfied. - if (HasPred) - OS << " return 0;\n"; - OS << "}\n"; - OS << "\n"; + emitInstructionCode(OS, Operands, PM, "RetVT"); } }