| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 1 | //===- FastISelEmitter.cpp - Generate an instruction selector -------------===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
 | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // This tablegen backend emits a "fast" instruction selector. | 
 | 11 | // | 
 | 12 | // This instruction selection method is designed to emit very poor code | 
 | 13 | // quickly. Also, it is not designed to do much lowering, so most illegal | 
 | 14 | // types (e.g. i64 on 32-bit targets) and operations (e.g. calls) are not | 
 | 15 | // supported and cannot easily be added. Blocks containing operations | 
 | 16 | // that are not supported need to be handled by a more capable selector, | 
 | 17 | // such as the SelectionDAG selector. | 
 | 18 | // | 
 | 19 | // The intended use for "fast" instruction selection is "-O0" mode | 
 | 20 | // compilation, where the quality of the generated code is irrelevant when | 
 | 21 | // weighed against the speed at which the code can be generated. | 
 | 22 | // | 
 | 23 | // If compile time is so important, you might wonder why we don't just | 
 | 24 | // skip codegen all-together, emit LLVM bytecode files, and execute them | 
 | 25 | // with an interpreter. The answer is that it would complicate linking and | 
 | 26 | // debugging, and also because that isn't how a compiler is expected to | 
 | 27 | // work in some circles. | 
 | 28 | // | 
 | 29 | // If you need better generated code or more lowering than what this | 
 | 30 | // instruction selector provides, use the SelectionDAG (DAGISel) instruction | 
 | 31 | // selector instead. If you're looking here because SelectionDAG isn't fast | 
 | 32 | // enough, consider looking into improving the SelectionDAG infastructure | 
 | 33 | // instead. At the time of this writing there remain several major | 
 | 34 | // opportunities for improvement. | 
 | 35 | //  | 
 | 36 | //===----------------------------------------------------------------------===// | 
 | 37 |  | 
 | 38 | #include "FastISelEmitter.h" | 
 | 39 | #include "Record.h" | 
 | 40 | #include "llvm/Support/Debug.h" | 
 | 41 | #include "llvm/Support/Streams.h" | 
 | 42 | #include "llvm/ADT/VectorExtras.h" | 
 | 43 | using namespace llvm; | 
 | 44 |  | 
 | 45 | namespace { | 
 | 46 |  | 
| Dan Gohman | 04b7dfb | 2008-08-19 18:06:12 +0000 | [diff] [blame] | 47 | /// OperandsSignature - This class holds a description of a list of operand | 
 | 48 | /// types. It has utility methods for emitting text based on the operands. | 
 | 49 | /// | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 50 | struct OperandsSignature { | 
 | 51 |   std::vector<std::string> Operands; | 
 | 52 |  | 
 | 53 |   bool operator<(const OperandsSignature &O) const { | 
 | 54 |     return Operands < O.Operands; | 
 | 55 |   } | 
 | 56 |  | 
 | 57 |   bool empty() const { return Operands.empty(); } | 
 | 58 |  | 
 | 59 |   void PrintParameters(std::ostream &OS) const { | 
 | 60 |     for (unsigned i = 0, e = Operands.size(); i != e; ++i) { | 
 | 61 |       if (Operands[i] == "r") { | 
 | 62 |         OS << "unsigned Op" << i; | 
 | 63 |       } else { | 
 | 64 |         assert("Unknown operand kind!"); | 
 | 65 |         abort(); | 
 | 66 |       } | 
 | 67 |       if (i + 1 != e) | 
 | 68 |         OS << ", "; | 
 | 69 |     } | 
 | 70 |   } | 
 | 71 |  | 
 | 72 |   void PrintArguments(std::ostream &OS) const { | 
 | 73 |     for (unsigned i = 0, e = Operands.size(); i != e; ++i) { | 
 | 74 |       if (Operands[i] == "r") { | 
 | 75 |         OS << "Op" << i; | 
 | 76 |       } else { | 
 | 77 |         assert("Unknown operand kind!"); | 
 | 78 |         abort(); | 
 | 79 |       } | 
 | 80 |       if (i + 1 != e) | 
 | 81 |         OS << ", "; | 
 | 82 |     } | 
 | 83 |   } | 
 | 84 |  | 
 | 85 |   void PrintManglingSuffix(std::ostream &OS) const { | 
 | 86 |     for (unsigned i = 0, e = Operands.size(); i != e; ++i) { | 
 | 87 |       OS << Operands[i]; | 
 | 88 |     } | 
 | 89 |   } | 
 | 90 | }; | 
 | 91 |  | 
| Dan Gohman | 04b7dfb | 2008-08-19 18:06:12 +0000 | [diff] [blame] | 92 | /// InstructionMemo - This class holds additional information about an | 
 | 93 | /// instruction needed to emit code for it. | 
 | 94 | /// | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 95 | struct InstructionMemo { | 
 | 96 |   std::string Name; | 
 | 97 |   const CodeGenRegisterClass *RC; | 
 | 98 | }; | 
 | 99 |  | 
 | 100 | } | 
 | 101 |  | 
 | 102 | static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) { | 
 | 103 |   return CGP.getSDNodeInfo(Op).getEnumName(); | 
 | 104 | } | 
 | 105 |  | 
 | 106 | static std::string getLegalCName(std::string OpName) { | 
 | 107 |   std::string::size_type pos = OpName.find("::"); | 
 | 108 |   if (pos != std::string::npos) | 
 | 109 |     OpName.replace(pos, 2, "_"); | 
 | 110 |   return OpName; | 
 | 111 | } | 
 | 112 |  | 
 | 113 | void FastISelEmitter::run(std::ostream &OS) { | 
 | 114 |   EmitSourceFileHeader("\"Fast\" Instruction Selector for the " + | 
 | 115 |                        CGP.getTargetInfo().getName() + " target", OS); | 
 | 116 |    | 
 | 117 |   const CodeGenTarget &Target = CGP.getTargetInfo(); | 
 | 118 |    | 
 | 119 |   // Get the namespace to insert instructions into.  Make sure not to pick up | 
 | 120 |   // "TargetInstrInfo" by accidentally getting the namespace off the PHI | 
 | 121 |   // instruction or something. | 
 | 122 |   std::string InstNS; | 
 | 123 |   for (CodeGenTarget::inst_iterator i = Target.inst_begin(), | 
 | 124 |        e = Target.inst_end(); i != e; ++i) { | 
 | 125 |     InstNS = i->second.Namespace; | 
 | 126 |     if (InstNS != "TargetInstrInfo") | 
 | 127 |       break; | 
 | 128 |   } | 
 | 129 |  | 
 | 130 |   OS << "namespace llvm {\n"; | 
 | 131 |   OS << "namespace " << InstNS << " {\n"; | 
 | 132 |   OS << "class FastISel;\n"; | 
 | 133 |   OS << "}\n"; | 
 | 134 |   OS << "}\n"; | 
 | 135 |   OS << "\n"; | 
 | 136 |    | 
 | 137 |   if (!InstNS.empty()) InstNS += "::"; | 
 | 138 |  | 
 | 139 |   typedef std::map<MVT::SimpleValueType, InstructionMemo> TypeMap; | 
 | 140 |   typedef std::map<std::string, TypeMap> OpcodeTypeMap; | 
 | 141 |   typedef std::map<OperandsSignature, OpcodeTypeMap> OperandsOpcodeTypeMap; | 
 | 142 |   OperandsOpcodeTypeMap SimplePatterns; | 
 | 143 |  | 
 | 144 |   // Create the supported type signatures. | 
 | 145 |   OperandsSignature KnownOperands; | 
 | 146 |   SimplePatterns[KnownOperands] = OpcodeTypeMap(); | 
 | 147 |   KnownOperands.Operands.push_back("r"); | 
 | 148 |   SimplePatterns[KnownOperands] = OpcodeTypeMap(); | 
 | 149 |   KnownOperands.Operands.push_back("r"); | 
 | 150 |   SimplePatterns[KnownOperands] = OpcodeTypeMap(); | 
 | 151 |  | 
 | 152 |   for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), | 
 | 153 |        E = CGP.ptm_end(); I != E; ++I) { | 
 | 154 |     const PatternToMatch &Pattern = *I; | 
 | 155 |  | 
 | 156 |     // For now, just look at Instructions, so that we don't have to worry | 
 | 157 |     // about emitting multiple instructions for a pattern. | 
 | 158 |     TreePatternNode *Dst = Pattern.getDstPattern(); | 
 | 159 |     if (Dst->isLeaf()) continue; | 
 | 160 |     Record *Op = Dst->getOperator(); | 
 | 161 |     if (!Op->isSubClassOf("Instruction")) | 
 | 162 |       continue; | 
 | 163 |     CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op->getName()); | 
 | 164 |     if (II.OperandList.empty()) | 
 | 165 |       continue; | 
 | 166 |     Record *Op0Rec = II.OperandList[0].Rec; | 
 | 167 |     if (!Op0Rec->isSubClassOf("RegisterClass")) | 
 | 168 |       continue; | 
 | 169 |     const CodeGenRegisterClass *DstRC = &Target.getRegisterClass(Op0Rec); | 
 | 170 |     if (!DstRC) | 
 | 171 |       continue; | 
 | 172 |  | 
 | 173 |     // Inspect the pattern. | 
 | 174 |     TreePatternNode *InstPatNode = Pattern.getSrcPattern(); | 
 | 175 |     if (!InstPatNode) continue; | 
 | 176 |     if (InstPatNode->isLeaf()) continue; | 
 | 177 |  | 
 | 178 |     Record *InstPatOp = InstPatNode->getOperator(); | 
 | 179 |     std::string OpcodeName = getOpcodeName(InstPatOp, CGP); | 
 | 180 |     MVT::SimpleValueType VT = InstPatNode->getTypeNum(0); | 
 | 181 |  | 
 | 182 |     // For now, filter out instructions which just set a register to | 
| Dan Gohman | f4137b5 | 2008-08-19 20:30:54 +0000 | [diff] [blame] | 183 |     // an Operand or an immediate, like MOV32ri. | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 184 |     if (InstPatOp->isSubClassOf("Operand")) | 
 | 185 |       continue; | 
| Dan Gohman | f4137b5 | 2008-08-19 20:30:54 +0000 | [diff] [blame] | 186 |     if (InstPatOp->getName() == "imm" || | 
 | 187 |         InstPatOp->getName() == "fpimm") | 
 | 188 |       continue; | 
 | 189 |  | 
 | 190 |     // For now, filter out any instructions with predicates. | 
 | 191 |     if (!InstPatNode->getPredicateFn().empty()) | 
 | 192 |       continue; | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 193 |  | 
 | 194 |     // Check all the operands. For now only accept register operands. | 
 | 195 |     OperandsSignature Operands; | 
 | 196 |     for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) { | 
 | 197 |       TreePatternNode *Op = InstPatNode->getChild(i); | 
 | 198 |       if (!Op->isLeaf()) | 
 | 199 |         goto continue_label; | 
| Dan Gohman | f4137b5 | 2008-08-19 20:30:54 +0000 | [diff] [blame] | 200 |       // For now, filter out any operand with a predicate. | 
 | 201 |       if (!Op->getPredicateFn().empty()) | 
 | 202 |         goto continue_label; | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 203 |       DefInit *OpDI = dynamic_cast<DefInit*>(Op->getLeafValue()); | 
 | 204 |       if (!OpDI) | 
 | 205 |         goto continue_label; | 
 | 206 |       Record *OpLeafRec = OpDI->getDef(); | 
 | 207 |       if (!OpLeafRec->isSubClassOf("RegisterClass")) | 
 | 208 |         goto continue_label; | 
 | 209 |       const CodeGenRegisterClass *RC = &Target.getRegisterClass(OpLeafRec); | 
 | 210 |       if (!RC) | 
 | 211 |         goto continue_label; | 
 | 212 |       if (Op->getTypeNum(0) != VT) | 
 | 213 |         goto continue_label; | 
 | 214 |       Operands.Operands.push_back("r"); | 
 | 215 |     } | 
 | 216 |  | 
 | 217 |     // If it's not a known signature, ignore it. | 
 | 218 |     if (!SimplePatterns.count(Operands)) | 
 | 219 |       continue; | 
 | 220 |  | 
 | 221 |     // Ok, we found a pattern that we can handle. Remember it. | 
 | 222 |     { | 
| Dan Gohman | 5672634 | 2008-08-19 18:07:49 +0000 | [diff] [blame] | 223 |       InstructionMemo Memo = { | 
 | 224 |         Pattern.getDstPattern()->getOperator()->getName(), | 
 | 225 |         DstRC | 
 | 226 |       }; | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 227 |       SimplePatterns[Operands][OpcodeName][VT] = Memo; | 
 | 228 |     } | 
 | 229 |  | 
 | 230 |   continue_label:; | 
 | 231 |   } | 
 | 232 |  | 
 | 233 |   OS << "#include \"llvm/CodeGen/FastISel.h\"\n"; | 
 | 234 |   OS << "\n"; | 
 | 235 |   OS << "namespace llvm {\n"; | 
 | 236 |   OS << "\n"; | 
 | 237 |  | 
 | 238 |   // Declare the target FastISel class. | 
 | 239 |   OS << "class " << InstNS << "FastISel : public llvm::FastISel {\n"; | 
 | 240 |   for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(), | 
 | 241 |        OE = SimplePatterns.end(); OI != OE; ++OI) { | 
 | 242 |     const OperandsSignature &Operands = OI->first; | 
 | 243 |     const OpcodeTypeMap &OTM = OI->second; | 
 | 244 |  | 
 | 245 |     for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end(); | 
 | 246 |          I != E; ++I) { | 
 | 247 |       const std::string &Opcode = I->first; | 
 | 248 |       const TypeMap &TM = I->second; | 
 | 249 |  | 
 | 250 |       for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end(); | 
 | 251 |            TI != TE; ++TI) { | 
 | 252 |         MVT::SimpleValueType VT = TI->first; | 
 | 253 |  | 
 | 254 |         OS << "  unsigned FastEmit_" << getLegalCName(Opcode) | 
 | 255 |            << "_" << getLegalCName(getName(VT)) << "("; | 
 | 256 |         Operands.PrintParameters(OS); | 
 | 257 |         OS << ");\n"; | 
 | 258 |       } | 
 | 259 |  | 
 | 260 |       OS << "  unsigned FastEmit_" << getLegalCName(Opcode) | 
 | 261 |          << "(MVT::SimpleValueType VT"; | 
 | 262 |       if (!Operands.empty()) | 
 | 263 |         OS << ", "; | 
 | 264 |       Operands.PrintParameters(OS); | 
 | 265 |       OS << ");\n"; | 
 | 266 |     } | 
 | 267 |  | 
| Dan Gohman | 56e0f87 | 2008-08-19 20:31:38 +0000 | [diff] [blame^] | 268 |     OS << "  unsigned FastEmit_"; | 
| Dan Gohman | b0cf29c | 2008-08-13 20:19:35 +0000 | [diff] [blame] | 269 |     Operands.PrintManglingSuffix(OS); | 
 | 270 |     OS << "(MVT::SimpleValueType VT, ISD::NodeType Opcode"; | 
 | 271 |     if (!Operands.empty()) | 
 | 272 |       OS << ", "; | 
 | 273 |     Operands.PrintParameters(OS); | 
 | 274 |     OS << ");\n"; | 
 | 275 |   } | 
 | 276 |   OS << "public:\n"; | 
 | 277 |   OS << "  FastISel(MachineBasicBlock *mbb, MachineFunction *mf, "; | 
 | 278 |   OS << "const TargetInstrInfo *tii) : llvm::FastISel(mbb, mf, tii) {}\n"; | 
 | 279 |   OS << "};\n"; | 
 | 280 |   OS << "\n"; | 
 | 281 |  | 
 | 282 |   // Define the target FastISel creation function. | 
 | 283 |   OS << "llvm::FastISel *" << InstNS | 
 | 284 |      << "createFastISel(MachineBasicBlock *mbb, MachineFunction *mf, "; | 
 | 285 |   OS << "const TargetInstrInfo *tii) {\n"; | 
 | 286 |   OS << "  return new " << InstNS << "FastISel(mbb, mf, tii);\n"; | 
 | 287 |   OS << "}\n"; | 
 | 288 |   OS << "\n"; | 
 | 289 |  | 
 | 290 |   // Now emit code for all the patterns that we collected. | 
 | 291 |   for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(), | 
 | 292 |        OE = SimplePatterns.end(); OI != OE; ++OI) { | 
 | 293 |     const OperandsSignature &Operands = OI->first; | 
 | 294 |     const OpcodeTypeMap &OTM = OI->second; | 
 | 295 |  | 
 | 296 |     for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end(); | 
 | 297 |          I != E; ++I) { | 
 | 298 |       const std::string &Opcode = I->first; | 
 | 299 |       const TypeMap &TM = I->second; | 
 | 300 |  | 
 | 301 |       OS << "// FastEmit functions for " << Opcode << ".\n"; | 
 | 302 |       OS << "\n"; | 
 | 303 |  | 
 | 304 |       // Emit one function for each opcode,type pair. | 
 | 305 |       for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end(); | 
 | 306 |            TI != TE; ++TI) { | 
 | 307 |         MVT::SimpleValueType VT = TI->first; | 
 | 308 |         const InstructionMemo &Memo = TI->second; | 
 | 309 |    | 
 | 310 |         OS << "unsigned " << InstNS << "FastISel::FastEmit_" | 
 | 311 |            << getLegalCName(Opcode) | 
 | 312 |            << "_" << getLegalCName(getName(VT)) << "("; | 
 | 313 |         Operands.PrintParameters(OS); | 
 | 314 |         OS << ") {\n"; | 
 | 315 |         OS << "  return FastEmitInst_"; | 
 | 316 |         Operands.PrintManglingSuffix(OS); | 
 | 317 |         OS << "(" << InstNS << Memo.Name << ", "; | 
 | 318 |         OS << InstNS << Memo.RC->getName() << "RegisterClass"; | 
 | 319 |         if (!Operands.empty()) | 
 | 320 |           OS << ", "; | 
 | 321 |         Operands.PrintArguments(OS); | 
 | 322 |         OS << ");\n"; | 
 | 323 |         OS << "}\n"; | 
 | 324 |         OS << "\n"; | 
 | 325 |       } | 
 | 326 |  | 
 | 327 |       // Emit one function for the opcode that demultiplexes based on the type. | 
 | 328 |       OS << "unsigned " << InstNS << "FastISel::FastEmit_" | 
 | 329 |          << getLegalCName(Opcode) << "(MVT::SimpleValueType VT"; | 
 | 330 |       if (!Operands.empty()) | 
 | 331 |         OS << ", "; | 
 | 332 |       Operands.PrintParameters(OS); | 
 | 333 |       OS << ") {\n"; | 
 | 334 |       OS << "  switch (VT) {\n"; | 
 | 335 |       for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end(); | 
 | 336 |            TI != TE; ++TI) { | 
 | 337 |         MVT::SimpleValueType VT = TI->first; | 
 | 338 |         std::string TypeName = getName(VT); | 
 | 339 |         OS << "  case " << TypeName << ": return FastEmit_" | 
 | 340 |            << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "("; | 
 | 341 |         Operands.PrintArguments(OS); | 
 | 342 |         OS << ");\n"; | 
 | 343 |       } | 
 | 344 |       OS << "  default: return 0;\n"; | 
 | 345 |       OS << "  }\n"; | 
 | 346 |       OS << "}\n"; | 
 | 347 |       OS << "\n"; | 
 | 348 |     } | 
 | 349 |  | 
 | 350 |     // Emit one function for the operand signature that demultiplexes based | 
 | 351 |     // on opcode and type. | 
 | 352 |     OS << "unsigned " << InstNS << "FastISel::FastEmit_"; | 
 | 353 |     Operands.PrintManglingSuffix(OS); | 
 | 354 |     OS << "(MVT::SimpleValueType VT, ISD::NodeType Opcode"; | 
 | 355 |     if (!Operands.empty()) | 
 | 356 |       OS << ", "; | 
 | 357 |     Operands.PrintParameters(OS); | 
 | 358 |     OS << ") {\n"; | 
 | 359 |     OS << "  switch (Opcode) {\n"; | 
 | 360 |     for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end(); | 
 | 361 |          I != E; ++I) { | 
 | 362 |       const std::string &Opcode = I->first; | 
 | 363 |  | 
 | 364 |       OS << "  case " << Opcode << ": return FastEmit_" | 
 | 365 |          << getLegalCName(Opcode) << "(VT"; | 
 | 366 |       if (!Operands.empty()) | 
 | 367 |         OS << ", "; | 
 | 368 |       Operands.PrintArguments(OS); | 
 | 369 |       OS << ");\n"; | 
 | 370 |     } | 
 | 371 |     OS << "  default: return 0;\n"; | 
 | 372 |     OS << "  }\n"; | 
 | 373 |     OS << "}\n"; | 
 | 374 |     OS << "\n"; | 
 | 375 |   } | 
 | 376 |  | 
 | 377 |   OS << "}\n"; | 
 | 378 | } | 
 | 379 |  | 
 | 380 | // todo: really filter out Constants |