1 //===- MIRParser.cpp - MIR serialization format parser implementation -----===// 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 file implements the class that parses the optional LLVM IR and machine 11 // functions that are stored in MIR files. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/CodeGen/MIRParser/MIRParser.h" 16 #include "MIParser.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/StringMap.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/AsmParser/Parser.h" 22 #include "llvm/AsmParser/SlotMapping.h" 23 #include "llvm/CodeGen/MachineConstantPool.h" 24 #include "llvm/CodeGen/MachineFunction.h" 25 #include "llvm/CodeGen/MachineFrameInfo.h" 26 #include "llvm/CodeGen/MachineRegisterInfo.h" 27 #include "llvm/CodeGen/MIRYamlMapping.h" 28 #include "llvm/IR/BasicBlock.h" 29 #include "llvm/IR/DiagnosticInfo.h" 30 #include "llvm/IR/Instructions.h" 31 #include "llvm/IR/LLVMContext.h" 32 #include "llvm/IR/Module.h" 33 #include "llvm/IR/ValueSymbolTable.h" 34 #include "llvm/Support/LineIterator.h" 35 #include "llvm/Support/SMLoc.h" 36 #include "llvm/Support/SourceMgr.h" 37 #include "llvm/Support/MemoryBuffer.h" 38 #include "llvm/Support/YAMLTraits.h" 39 #include <memory> 40 41 using namespace llvm; 42 43 namespace llvm { 44 45 /// This class implements the parsing of LLVM IR that's embedded inside a MIR 46 /// file. 47 class MIRParserImpl { 48 SourceMgr SM; 49 StringRef Filename; 50 LLVMContext &Context; 51 StringMap<std::unique_ptr<yaml::MachineFunction>> Functions; 52 SlotMapping IRSlots; 53 /// Maps from register class names to register classes. 54 StringMap<const TargetRegisterClass *> Names2RegClasses; 55 56 public: 57 MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename, 58 LLVMContext &Context); 59 60 void reportDiagnostic(const SMDiagnostic &Diag); 61 62 /// Report an error with the given message at unknown location. 63 /// 64 /// Always returns true. 65 bool error(const Twine &Message); 66 67 /// Report an error with the given message at the given location. 68 /// 69 /// Always returns true. 70 bool error(SMLoc Loc, const Twine &Message); 71 72 /// Report a given error with the location translated from the location in an 73 /// embedded string literal to a location in the MIR file. 74 /// 75 /// Always returns true. 76 bool error(const SMDiagnostic &Error, SMRange SourceRange); 77 78 /// Try to parse the optional LLVM module and the machine functions in the MIR 79 /// file. 80 /// 81 /// Return null if an error occurred. 82 std::unique_ptr<Module> parse(); 83 84 /// Parse the machine function in the current YAML document. 85 /// 86 /// \param NoLLVMIR - set to true when the MIR file doesn't have LLVM IR. 87 /// A dummy IR function is created and inserted into the given module when 88 /// this parameter is true. 89 /// 90 /// Return true if an error occurred. 91 bool parseMachineFunction(yaml::Input &In, Module &M, bool NoLLVMIR); 92 93 /// Initialize the machine function to the state that's described in the MIR 94 /// file. 95 /// 96 /// Return true if error occurred. 97 bool initializeMachineFunction(MachineFunction &MF); 98 99 /// Initialize the machine basic block using it's YAML representation. 100 /// 101 /// Return true if an error occurred. 102 bool initializeMachineBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB, 103 const yaml::MachineBasicBlock &YamlMBB, 104 const PerFunctionMIParsingState &PFS); 105 106 bool 107 initializeRegisterInfo(const MachineFunction &MF, 108 MachineRegisterInfo &RegInfo, 109 const yaml::MachineFunction &YamlMF, 110 DenseMap<unsigned, unsigned> &VirtualRegisterSlots); 111 112 bool initializeFrameInfo(const Function &F, MachineFrameInfo &MFI, 113 const yaml::MachineFunction &YamlMF, 114 DenseMap<unsigned, int> &StackObjectSlots, 115 DenseMap<unsigned, int> &FixedStackObjectSlots); 116 117 bool initializeConstantPool(MachineConstantPool &ConstantPool, 118 const yaml::MachineFunction &YamlMF, 119 const MachineFunction &MF, 120 DenseMap<unsigned, unsigned> &ConstantPoolSlots); 121 122 bool initializeJumpTableInfo(MachineFunction &MF, 123 const yaml::MachineJumpTable &YamlJTI, 124 PerFunctionMIParsingState &PFS); 125 126 private: 127 /// Return a MIR diagnostic converted from an MI string diagnostic. 128 SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error, 129 SMRange SourceRange); 130 131 /// Return a MIR diagnostic converted from an LLVM assembly diagnostic. 132 SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, 133 SMRange SourceRange); 134 135 /// Create an empty function with the given name. 136 void createDummyFunction(StringRef Name, Module &M); 137 138 void initNames2RegClasses(const MachineFunction &MF); 139 140 /// Check if the given identifier is a name of a register class. 141 /// 142 /// Return null if the name isn't a register class. 143 const TargetRegisterClass *getRegClass(const MachineFunction &MF, 144 StringRef Name); 145 }; 146 147 } // end namespace llvm 148 149 MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, 150 StringRef Filename, LLVMContext &Context) 151 : SM(), Filename(Filename), Context(Context) { 152 SM.AddNewSourceBuffer(std::move(Contents), SMLoc()); 153 } 154 155 bool MIRParserImpl::error(const Twine &Message) { 156 Context.diagnose(DiagnosticInfoMIRParser( 157 DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str()))); 158 return true; 159 } 160 161 bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) { 162 Context.diagnose(DiagnosticInfoMIRParser( 163 DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message))); 164 return true; 165 } 166 167 bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) { 168 assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error"); 169 reportDiagnostic(diagFromMIStringDiag(Error, SourceRange)); 170 return true; 171 } 172 173 void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) { 174 DiagnosticSeverity Kind; 175 switch (Diag.getKind()) { 176 case SourceMgr::DK_Error: 177 Kind = DS_Error; 178 break; 179 case SourceMgr::DK_Warning: 180 Kind = DS_Warning; 181 break; 182 case SourceMgr::DK_Note: 183 Kind = DS_Note; 184 break; 185 } 186 Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag)); 187 } 188 189 static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) { 190 reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag); 191 } 192 193 std::unique_ptr<Module> MIRParserImpl::parse() { 194 yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(), 195 /*Ctxt=*/nullptr, handleYAMLDiag, this); 196 In.setContext(&In); 197 198 if (!In.setCurrentDocument()) { 199 if (In.error()) 200 return nullptr; 201 // Create an empty module when the MIR file is empty. 202 return llvm::make_unique<Module>(Filename, Context); 203 } 204 205 std::unique_ptr<Module> M; 206 bool NoLLVMIR = false; 207 // Parse the block scalar manually so that we can return unique pointer 208 // without having to go trough YAML traits. 209 if (const auto *BSN = 210 dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) { 211 SMDiagnostic Error; 212 M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error, 213 Context, &IRSlots); 214 if (!M) { 215 reportDiagnostic(diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange())); 216 return M; 217 } 218 In.nextDocument(); 219 if (!In.setCurrentDocument()) 220 return M; 221 } else { 222 // Create an new, empty module. 223 M = llvm::make_unique<Module>(Filename, Context); 224 NoLLVMIR = true; 225 } 226 227 // Parse the machine functions. 228 do { 229 if (parseMachineFunction(In, *M, NoLLVMIR)) 230 return nullptr; 231 In.nextDocument(); 232 } while (In.setCurrentDocument()); 233 234 return M; 235 } 236 237 bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M, 238 bool NoLLVMIR) { 239 auto MF = llvm::make_unique<yaml::MachineFunction>(); 240 yaml::yamlize(In, *MF, false); 241 if (In.error()) 242 return true; 243 auto FunctionName = MF->Name; 244 if (Functions.find(FunctionName) != Functions.end()) 245 return error(Twine("redefinition of machine function '") + FunctionName + 246 "'"); 247 Functions.insert(std::make_pair(FunctionName, std::move(MF))); 248 if (NoLLVMIR) 249 createDummyFunction(FunctionName, M); 250 else if (!M.getFunction(FunctionName)) 251 return error(Twine("function '") + FunctionName + 252 "' isn't defined in the provided LLVM IR"); 253 return false; 254 } 255 256 void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) { 257 auto &Context = M.getContext(); 258 Function *F = cast<Function>(M.getOrInsertFunction( 259 Name, FunctionType::get(Type::getVoidTy(Context), false))); 260 BasicBlock *BB = BasicBlock::Create(Context, "entry", F); 261 new UnreachableInst(Context, BB); 262 } 263 264 bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) { 265 auto It = Functions.find(MF.getName()); 266 if (It == Functions.end()) 267 return error(Twine("no machine function information for function '") + 268 MF.getName() + "' in the MIR file"); 269 // TODO: Recreate the machine function. 270 const yaml::MachineFunction &YamlMF = *It->getValue(); 271 if (YamlMF.Alignment) 272 MF.setAlignment(YamlMF.Alignment); 273 MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice); 274 MF.setHasInlineAsm(YamlMF.HasInlineAsm); 275 PerFunctionMIParsingState PFS; 276 if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF, 277 PFS.VirtualRegisterSlots)) 278 return true; 279 if (initializeFrameInfo(*MF.getFunction(), *MF.getFrameInfo(), YamlMF, 280 PFS.StackObjectSlots, PFS.FixedStackObjectSlots)) 281 return true; 282 if (!YamlMF.Constants.empty()) { 283 auto *ConstantPool = MF.getConstantPool(); 284 assert(ConstantPool && "Constant pool must be created"); 285 if (initializeConstantPool(*ConstantPool, YamlMF, MF, 286 PFS.ConstantPoolSlots)) 287 return true; 288 } 289 290 const auto &F = *MF.getFunction(); 291 for (const auto &YamlMBB : YamlMF.BasicBlocks) { 292 const BasicBlock *BB = nullptr; 293 const yaml::StringValue &Name = YamlMBB.Name; 294 if (!Name.Value.empty()) { 295 BB = dyn_cast_or_null<BasicBlock>( 296 F.getValueSymbolTable().lookup(Name.Value)); 297 if (!BB) 298 return error(Name.SourceRange.Start, 299 Twine("basic block '") + Name.Value + 300 "' is not defined in the function '" + MF.getName() + 301 "'"); 302 } 303 auto *MBB = MF.CreateMachineBasicBlock(BB); 304 MF.insert(MF.end(), MBB); 305 bool WasInserted = 306 PFS.MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second; 307 if (!WasInserted) 308 return error(Twine("redefinition of machine basic block with id #") + 309 Twine(YamlMBB.ID)); 310 } 311 312 if (YamlMF.BasicBlocks.empty()) 313 return error(Twine("machine function '") + Twine(MF.getName()) + 314 "' requires at least one machine basic block in its body"); 315 // Initialize the jump table after creating all the MBBs so that the MBB 316 // references can be resolved. 317 if (!YamlMF.JumpTableInfo.Entries.empty() && 318 initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS)) 319 return true; 320 // Initialize the machine basic blocks after creating them all so that the 321 // machine instructions parser can resolve the MBB references. 322 unsigned I = 0; 323 for (const auto &YamlMBB : YamlMF.BasicBlocks) { 324 if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB, 325 PFS)) 326 return true; 327 } 328 return false; 329 } 330 331 bool MIRParserImpl::initializeMachineBasicBlock( 332 MachineFunction &MF, MachineBasicBlock &MBB, 333 const yaml::MachineBasicBlock &YamlMBB, 334 const PerFunctionMIParsingState &PFS) { 335 MBB.setAlignment(YamlMBB.Alignment); 336 if (YamlMBB.AddressTaken) 337 MBB.setHasAddressTaken(); 338 MBB.setIsLandingPad(YamlMBB.IsLandingPad); 339 SMDiagnostic Error; 340 // Parse the successors. 341 for (const auto &MBBSource : YamlMBB.Successors) { 342 MachineBasicBlock *SuccMBB = nullptr; 343 if (parseMBBReference(SuccMBB, SM, MF, MBBSource.Value, PFS, IRSlots, 344 Error)) 345 return error(Error, MBBSource.SourceRange); 346 // TODO: Report an error when adding the same successor more than once. 347 MBB.addSuccessor(SuccMBB); 348 } 349 // Parse the liveins. 350 for (const auto &LiveInSource : YamlMBB.LiveIns) { 351 unsigned Reg = 0; 352 if (parseNamedRegisterReference(Reg, SM, MF, LiveInSource.Value, PFS, 353 IRSlots, Error)) 354 return error(Error, LiveInSource.SourceRange); 355 MBB.addLiveIn(Reg); 356 } 357 // Parse the instructions. 358 for (const auto &MISource : YamlMBB.Instructions) { 359 MachineInstr *MI = nullptr; 360 if (parseMachineInstr(MI, SM, MF, MISource.Value, PFS, IRSlots, Error)) 361 return error(Error, MISource.SourceRange); 362 MBB.insert(MBB.end(), MI); 363 } 364 return false; 365 } 366 367 bool MIRParserImpl::initializeRegisterInfo( 368 const MachineFunction &MF, MachineRegisterInfo &RegInfo, 369 const yaml::MachineFunction &YamlMF, 370 DenseMap<unsigned, unsigned> &VirtualRegisterSlots) { 371 assert(RegInfo.isSSA()); 372 if (!YamlMF.IsSSA) 373 RegInfo.leaveSSA(); 374 assert(RegInfo.tracksLiveness()); 375 if (!YamlMF.TracksRegLiveness) 376 RegInfo.invalidateLiveness(); 377 RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness); 378 379 // Parse the virtual register information. 380 for (const auto &VReg : YamlMF.VirtualRegisters) { 381 const auto *RC = getRegClass(MF, VReg.Class.Value); 382 if (!RC) 383 return error(VReg.Class.SourceRange.Start, 384 Twine("use of undefined register class '") + 385 VReg.Class.Value + "'"); 386 unsigned Reg = RegInfo.createVirtualRegister(RC); 387 // TODO: Report an error when the same virtual register with the same ID is 388 // redefined. 389 VirtualRegisterSlots.insert(std::make_pair(VReg.ID, Reg)); 390 } 391 return false; 392 } 393 394 bool MIRParserImpl::initializeFrameInfo( 395 const Function &F, MachineFrameInfo &MFI, 396 const yaml::MachineFunction &YamlMF, 397 DenseMap<unsigned, int> &StackObjectSlots, 398 DenseMap<unsigned, int> &FixedStackObjectSlots) { 399 const yaml::MachineFrameInfo &YamlMFI = YamlMF.FrameInfo; 400 MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken); 401 MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken); 402 MFI.setHasStackMap(YamlMFI.HasStackMap); 403 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint); 404 MFI.setStackSize(YamlMFI.StackSize); 405 MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment); 406 if (YamlMFI.MaxAlignment) 407 MFI.ensureMaxAlignment(YamlMFI.MaxAlignment); 408 MFI.setAdjustsStack(YamlMFI.AdjustsStack); 409 MFI.setHasCalls(YamlMFI.HasCalls); 410 MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize); 411 MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment); 412 MFI.setHasVAStart(YamlMFI.HasVAStart); 413 MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc); 414 415 // Initialize the fixed frame objects. 416 for (const auto &Object : YamlMF.FixedStackObjects) { 417 int ObjectIdx; 418 if (Object.Type != yaml::FixedMachineStackObject::SpillSlot) 419 ObjectIdx = MFI.CreateFixedObject(Object.Size, Object.Offset, 420 Object.IsImmutable, Object.IsAliased); 421 else 422 ObjectIdx = MFI.CreateFixedSpillStackObject(Object.Size, Object.Offset); 423 MFI.setObjectAlignment(ObjectIdx, Object.Alignment); 424 // TODO: Report an error when objects are redefined. 425 FixedStackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx)); 426 } 427 428 // Initialize the ordinary frame objects. 429 for (const auto &Object : YamlMF.StackObjects) { 430 int ObjectIdx; 431 const AllocaInst *Alloca = nullptr; 432 const yaml::StringValue &Name = Object.Name; 433 if (!Name.Value.empty()) { 434 Alloca = dyn_cast_or_null<AllocaInst>( 435 F.getValueSymbolTable().lookup(Name.Value)); 436 if (!Alloca) 437 return error(Name.SourceRange.Start, 438 "alloca instruction named '" + Name.Value + 439 "' isn't defined in the function '" + F.getName() + 440 "'"); 441 } 442 if (Object.Type == yaml::MachineStackObject::VariableSized) 443 ObjectIdx = MFI.CreateVariableSizedObject(Object.Alignment, Alloca); 444 else 445 ObjectIdx = MFI.CreateStackObject( 446 Object.Size, Object.Alignment, 447 Object.Type == yaml::MachineStackObject::SpillSlot, Alloca); 448 MFI.setObjectOffset(ObjectIdx, Object.Offset); 449 // TODO: Report an error when objects are redefined. 450 StackObjectSlots.insert(std::make_pair(Object.ID, ObjectIdx)); 451 } 452 return false; 453 } 454 455 bool MIRParserImpl::initializeConstantPool( 456 MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF, 457 const MachineFunction &MF, 458 DenseMap<unsigned, unsigned> &ConstantPoolSlots) { 459 const auto &M = *MF.getFunction()->getParent(); 460 SMDiagnostic Error; 461 for (const auto &YamlConstant : YamlMF.Constants) { 462 const Constant *Value = dyn_cast_or_null<Constant>( 463 parseConstantValue(YamlConstant.Value.Value, Error, M)); 464 if (!Value) 465 return error(Error, YamlConstant.Value.SourceRange); 466 unsigned Alignment = 467 YamlConstant.Alignment 468 ? YamlConstant.Alignment 469 : M.getDataLayout().getPrefTypeAlignment(Value->getType()); 470 // TODO: Report an error when the same constant pool value ID is redefined. 471 ConstantPoolSlots.insert(std::make_pair( 472 YamlConstant.ID, ConstantPool.getConstantPoolIndex(Value, Alignment))); 473 } 474 return false; 475 } 476 477 bool MIRParserImpl::initializeJumpTableInfo( 478 MachineFunction &MF, const yaml::MachineJumpTable &YamlJTI, 479 PerFunctionMIParsingState &PFS) { 480 MachineJumpTableInfo *JTI = MF.getOrCreateJumpTableInfo(YamlJTI.Kind); 481 SMDiagnostic Error; 482 for (const auto &Entry : YamlJTI.Entries) { 483 std::vector<MachineBasicBlock *> Blocks; 484 for (const auto &MBBSource : Entry.Blocks) { 485 MachineBasicBlock *MBB = nullptr; 486 if (parseMBBReference(MBB, SM, MF, MBBSource.Value, PFS, IRSlots, Error)) 487 return error(Error, MBBSource.SourceRange); 488 Blocks.push_back(MBB); 489 } 490 unsigned Index = JTI->createJumpTableIndex(Blocks); 491 // TODO: Report an error when the same jump table slot ID is redefined. 492 PFS.JumpTableSlots.insert(std::make_pair(Entry.ID, Index)); 493 } 494 return false; 495 } 496 497 SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error, 498 SMRange SourceRange) { 499 assert(SourceRange.isValid() && "Invalid source range"); 500 SMLoc Loc = SourceRange.Start; 501 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() && 502 *Loc.getPointer() == '\''; 503 // Translate the location of the error from the location in the MI string to 504 // the corresponding location in the MIR file. 505 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() + 506 (HasQuote ? 1 : 0)); 507 508 // TODO: Translate any source ranges as well. 509 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None, 510 Error.getFixIts()); 511 } 512 513 SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, 514 SMRange SourceRange) { 515 assert(SourceRange.isValid()); 516 517 // Translate the location of the error from the location in the llvm IR string 518 // to the corresponding location in the MIR file. 519 auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start); 520 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1; 521 unsigned Column = Error.getColumnNo(); 522 StringRef LineStr = Error.getLineContents(); 523 SMLoc Loc = Error.getLoc(); 524 525 // Get the full line and adjust the column number by taking the indentation of 526 // LLVM IR into account. 527 for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E; 528 L != E; ++L) { 529 if (L.line_number() == Line) { 530 LineStr = *L; 531 Loc = SMLoc::getFromPointer(LineStr.data()); 532 auto Indent = LineStr.find(Error.getLineContents()); 533 if (Indent != StringRef::npos) 534 Column += Indent; 535 break; 536 } 537 } 538 539 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(), 540 Error.getMessage(), LineStr, Error.getRanges(), 541 Error.getFixIts()); 542 } 543 544 void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) { 545 if (!Names2RegClasses.empty()) 546 return; 547 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 548 for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) { 549 const auto *RC = TRI->getRegClass(I); 550 Names2RegClasses.insert( 551 std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC)); 552 } 553 } 554 555 const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF, 556 StringRef Name) { 557 initNames2RegClasses(MF); 558 auto RegClassInfo = Names2RegClasses.find(Name); 559 if (RegClassInfo == Names2RegClasses.end()) 560 return nullptr; 561 return RegClassInfo->getValue(); 562 } 563 564 MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl) 565 : Impl(std::move(Impl)) {} 566 567 MIRParser::~MIRParser() {} 568 569 std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); } 570 571 bool MIRParser::initializeMachineFunction(MachineFunction &MF) { 572 return Impl->initializeMachineFunction(MF); 573 } 574 575 std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename, 576 SMDiagnostic &Error, 577 LLVMContext &Context) { 578 auto FileOrErr = MemoryBuffer::getFile(Filename); 579 if (std::error_code EC = FileOrErr.getError()) { 580 Error = SMDiagnostic(Filename, SourceMgr::DK_Error, 581 "Could not open input file: " + EC.message()); 582 return nullptr; 583 } 584 return createMIRParser(std::move(FileOrErr.get()), Context); 585 } 586 587 std::unique_ptr<MIRParser> 588 llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents, 589 LLVMContext &Context) { 590 auto Filename = Contents->getBufferIdentifier(); 591 return llvm::make_unique<MIRParser>( 592 llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context)); 593 } 594