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