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 initializeRegisterInfo(const MachineFunction &MF, 106 MachineRegisterInfo &RegInfo, 107 const yaml::MachineFunction &YamlMF); 108 109 bool initializeFrameInfo(MachineFrameInfo &MFI, 110 const yaml::MachineFrameInfo &YamlMFI); 111 112 private: 113 /// Return a MIR diagnostic converted from an MI string diagnostic. 114 SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error, 115 SMRange SourceRange); 116 117 /// Return a MIR diagnostic converted from an LLVM assembly diagnostic. 118 SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, 119 SMRange SourceRange); 120 121 /// Create an empty function with the given name. 122 void createDummyFunction(StringRef Name, Module &M); 123 124 void initNames2RegClasses(const MachineFunction &MF); 125 126 /// Check if the given identifier is a name of a register class. 127 /// 128 /// Return null if the name isn't a register class. 129 const TargetRegisterClass *getRegClass(const MachineFunction &MF, 130 StringRef Name); 131 }; 132 133 } // end namespace llvm 134 135 MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, 136 StringRef Filename, LLVMContext &Context) 137 : SM(), Filename(Filename), Context(Context) { 138 SM.AddNewSourceBuffer(std::move(Contents), SMLoc()); 139 } 140 141 bool MIRParserImpl::error(const Twine &Message) { 142 Context.diagnose(DiagnosticInfoMIRParser( 143 DS_Error, SMDiagnostic(Filename, SourceMgr::DK_Error, Message.str()))); 144 return true; 145 } 146 147 bool MIRParserImpl::error(SMLoc Loc, const Twine &Message) { 148 Context.diagnose(DiagnosticInfoMIRParser( 149 DS_Error, SM.GetMessage(Loc, SourceMgr::DK_Error, Message))); 150 return true; 151 } 152 153 bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) { 154 assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error"); 155 reportDiagnostic(diagFromMIStringDiag(Error, SourceRange)); 156 return true; 157 } 158 159 void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) { 160 DiagnosticSeverity Kind; 161 switch (Diag.getKind()) { 162 case SourceMgr::DK_Error: 163 Kind = DS_Error; 164 break; 165 case SourceMgr::DK_Warning: 166 Kind = DS_Warning; 167 break; 168 case SourceMgr::DK_Note: 169 Kind = DS_Note; 170 break; 171 } 172 Context.diagnose(DiagnosticInfoMIRParser(Kind, Diag)); 173 } 174 175 static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) { 176 reinterpret_cast<MIRParserImpl *>(Context)->reportDiagnostic(Diag); 177 } 178 179 std::unique_ptr<Module> MIRParserImpl::parse() { 180 yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(), 181 /*Ctxt=*/nullptr, handleYAMLDiag, this); 182 In.setContext(&In); 183 184 if (!In.setCurrentDocument()) { 185 if (In.error()) 186 return nullptr; 187 // Create an empty module when the MIR file is empty. 188 return llvm::make_unique<Module>(Filename, Context); 189 } 190 191 std::unique_ptr<Module> M; 192 bool NoLLVMIR = false; 193 // Parse the block scalar manually so that we can return unique pointer 194 // without having to go trough YAML traits. 195 if (const auto *BSN = 196 dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) { 197 SMDiagnostic Error; 198 M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error, 199 Context, &IRSlots); 200 if (!M) { 201 reportDiagnostic(diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange())); 202 return M; 203 } 204 In.nextDocument(); 205 if (!In.setCurrentDocument()) 206 return M; 207 } else { 208 // Create an new, empty module. 209 M = llvm::make_unique<Module>(Filename, Context); 210 NoLLVMIR = true; 211 } 212 213 // Parse the machine functions. 214 do { 215 if (parseMachineFunction(In, *M, NoLLVMIR)) 216 return nullptr; 217 In.nextDocument(); 218 } while (In.setCurrentDocument()); 219 220 return M; 221 } 222 223 bool MIRParserImpl::parseMachineFunction(yaml::Input &In, Module &M, 224 bool NoLLVMIR) { 225 auto MF = llvm::make_unique<yaml::MachineFunction>(); 226 yaml::yamlize(In, *MF, false); 227 if (In.error()) 228 return true; 229 auto FunctionName = MF->Name; 230 if (Functions.find(FunctionName) != Functions.end()) 231 return error(Twine("redefinition of machine function '") + FunctionName + 232 "'"); 233 Functions.insert(std::make_pair(FunctionName, std::move(MF))); 234 if (NoLLVMIR) 235 createDummyFunction(FunctionName, M); 236 else if (!M.getFunction(FunctionName)) 237 return error(Twine("function '") + FunctionName + 238 "' isn't defined in the provided LLVM IR"); 239 return false; 240 } 241 242 void MIRParserImpl::createDummyFunction(StringRef Name, Module &M) { 243 auto &Context = M.getContext(); 244 Function *F = cast<Function>(M.getOrInsertFunction( 245 Name, FunctionType::get(Type::getVoidTy(Context), false))); 246 BasicBlock *BB = BasicBlock::Create(Context, "entry", F); 247 new UnreachableInst(Context, BB); 248 } 249 250 bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) { 251 auto It = Functions.find(MF.getName()); 252 if (It == Functions.end()) 253 return error(Twine("no machine function information for function '") + 254 MF.getName() + "' in the MIR file"); 255 // TODO: Recreate the machine function. 256 const yaml::MachineFunction &YamlMF = *It->getValue(); 257 if (YamlMF.Alignment) 258 MF.setAlignment(YamlMF.Alignment); 259 MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice); 260 MF.setHasInlineAsm(YamlMF.HasInlineAsm); 261 if (initializeRegisterInfo(MF, MF.getRegInfo(), YamlMF)) 262 return true; 263 if (initializeFrameInfo(*MF.getFrameInfo(), YamlMF.FrameInfo)) 264 return true; 265 266 PerFunctionMIParsingState PFS; 267 const auto &F = *MF.getFunction(); 268 for (const auto &YamlMBB : YamlMF.BasicBlocks) { 269 const BasicBlock *BB = nullptr; 270 const yaml::StringValue &Name = YamlMBB.Name; 271 if (!Name.Value.empty()) { 272 BB = dyn_cast_or_null<BasicBlock>( 273 F.getValueSymbolTable().lookup(Name.Value)); 274 if (!BB) 275 return error(Name.SourceRange.Start, 276 Twine("basic block '") + Name.Value + 277 "' is not defined in the function '" + MF.getName() + 278 "'"); 279 } 280 auto *MBB = MF.CreateMachineBasicBlock(BB); 281 MF.insert(MF.end(), MBB); 282 bool WasInserted = 283 PFS.MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second; 284 if (!WasInserted) 285 return error(Twine("redefinition of machine basic block with id #") + 286 Twine(YamlMBB.ID)); 287 } 288 289 if (YamlMF.BasicBlocks.empty()) 290 return error(Twine("machine function '") + Twine(MF.getName()) + 291 "' requires at least one machine basic block in its body"); 292 // Initialize the machine basic blocks after creating them all so that the 293 // machine instructions parser can resolve the MBB references. 294 unsigned I = 0; 295 for (const auto &YamlMBB : YamlMF.BasicBlocks) { 296 if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB, 297 PFS)) 298 return true; 299 } 300 return false; 301 } 302 303 bool MIRParserImpl::initializeMachineBasicBlock( 304 MachineFunction &MF, MachineBasicBlock &MBB, 305 const yaml::MachineBasicBlock &YamlMBB, 306 const PerFunctionMIParsingState &PFS) { 307 MBB.setAlignment(YamlMBB.Alignment); 308 if (YamlMBB.AddressTaken) 309 MBB.setHasAddressTaken(); 310 MBB.setIsLandingPad(YamlMBB.IsLandingPad); 311 SMDiagnostic Error; 312 // Parse the successors. 313 for (const auto &MBBSource : YamlMBB.Successors) { 314 MachineBasicBlock *SuccMBB = nullptr; 315 if (parseMBBReference(SuccMBB, SM, MF, MBBSource.Value, PFS, IRSlots, 316 Error)) 317 return error(Error, MBBSource.SourceRange); 318 // TODO: Report an error when adding the same successor more than once. 319 MBB.addSuccessor(SuccMBB); 320 } 321 // Parse the instructions. 322 for (const auto &MISource : YamlMBB.Instructions) { 323 MachineInstr *MI = nullptr; 324 if (parseMachineInstr(MI, SM, MF, MISource.Value, PFS, IRSlots, Error)) 325 return error(Error, MISource.SourceRange); 326 MBB.insert(MBB.end(), MI); 327 } 328 return false; 329 } 330 331 bool MIRParserImpl::initializeRegisterInfo( 332 const MachineFunction &MF, MachineRegisterInfo &RegInfo, 333 const yaml::MachineFunction &YamlMF) { 334 assert(RegInfo.isSSA()); 335 if (!YamlMF.IsSSA) 336 RegInfo.leaveSSA(); 337 assert(RegInfo.tracksLiveness()); 338 if (!YamlMF.TracksRegLiveness) 339 RegInfo.invalidateLiveness(); 340 RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness); 341 342 // Parse the virtual register information. 343 for (const auto &VReg : YamlMF.VirtualRegisters) { 344 const auto *RC = getRegClass(MF, VReg.Class.Value); 345 if (!RC) 346 return error(VReg.Class.SourceRange.Start, 347 Twine("use of undefined register class '") + 348 VReg.Class.Value + "'"); 349 // TODO: create the mapping from IDs to registers so that the virtual 350 // register references can be parsed correctly. 351 RegInfo.createVirtualRegister(RC); 352 } 353 return false; 354 } 355 356 bool MIRParserImpl::initializeFrameInfo(MachineFrameInfo &MFI, 357 const yaml::MachineFrameInfo &YamlMFI) { 358 MFI.setFrameAddressIsTaken(YamlMFI.IsFrameAddressTaken); 359 MFI.setReturnAddressIsTaken(YamlMFI.IsReturnAddressTaken); 360 MFI.setHasStackMap(YamlMFI.HasStackMap); 361 MFI.setHasPatchPoint(YamlMFI.HasPatchPoint); 362 MFI.setStackSize(YamlMFI.StackSize); 363 MFI.setOffsetAdjustment(YamlMFI.OffsetAdjustment); 364 if (YamlMFI.MaxAlignment) 365 MFI.ensureMaxAlignment(YamlMFI.MaxAlignment); 366 MFI.setAdjustsStack(YamlMFI.AdjustsStack); 367 MFI.setHasCalls(YamlMFI.HasCalls); 368 MFI.setMaxCallFrameSize(YamlMFI.MaxCallFrameSize); 369 MFI.setHasOpaqueSPAdjustment(YamlMFI.HasOpaqueSPAdjustment); 370 MFI.setHasVAStart(YamlMFI.HasVAStart); 371 MFI.setHasMustTailInVarArgFunc(YamlMFI.HasMustTailInVarArgFunc); 372 return false; 373 } 374 375 SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error, 376 SMRange SourceRange) { 377 assert(SourceRange.isValid() && "Invalid source range"); 378 SMLoc Loc = SourceRange.Start; 379 bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() && 380 *Loc.getPointer() == '\''; 381 // Translate the location of the error from the location in the MI string to 382 // the corresponding location in the MIR file. 383 Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() + 384 (HasQuote ? 1 : 0)); 385 386 // TODO: Translate any source ranges as well. 387 return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None, 388 Error.getFixIts()); 389 } 390 391 SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error, 392 SMRange SourceRange) { 393 assert(SourceRange.isValid()); 394 395 // Translate the location of the error from the location in the llvm IR string 396 // to the corresponding location in the MIR file. 397 auto LineAndColumn = SM.getLineAndColumn(SourceRange.Start); 398 unsigned Line = LineAndColumn.first + Error.getLineNo() - 1; 399 unsigned Column = Error.getColumnNo(); 400 StringRef LineStr = Error.getLineContents(); 401 SMLoc Loc = Error.getLoc(); 402 403 // Get the full line and adjust the column number by taking the indentation of 404 // LLVM IR into account. 405 for (line_iterator L(*SM.getMemoryBuffer(SM.getMainFileID()), false), E; 406 L != E; ++L) { 407 if (L.line_number() == Line) { 408 LineStr = *L; 409 Loc = SMLoc::getFromPointer(LineStr.data()); 410 auto Indent = LineStr.find(Error.getLineContents()); 411 if (Indent != StringRef::npos) 412 Column += Indent; 413 break; 414 } 415 } 416 417 return SMDiagnostic(SM, Loc, Filename, Line, Column, Error.getKind(), 418 Error.getMessage(), LineStr, Error.getRanges(), 419 Error.getFixIts()); 420 } 421 422 void MIRParserImpl::initNames2RegClasses(const MachineFunction &MF) { 423 if (!Names2RegClasses.empty()) 424 return; 425 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 426 for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) { 427 const auto *RC = TRI->getRegClass(I); 428 Names2RegClasses.insert( 429 std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC)); 430 } 431 } 432 433 const TargetRegisterClass *MIRParserImpl::getRegClass(const MachineFunction &MF, 434 StringRef Name) { 435 initNames2RegClasses(MF); 436 auto RegClassInfo = Names2RegClasses.find(Name); 437 if (RegClassInfo == Names2RegClasses.end()) 438 return nullptr; 439 return RegClassInfo->getValue(); 440 } 441 442 MIRParser::MIRParser(std::unique_ptr<MIRParserImpl> Impl) 443 : Impl(std::move(Impl)) {} 444 445 MIRParser::~MIRParser() {} 446 447 std::unique_ptr<Module> MIRParser::parseLLVMModule() { return Impl->parse(); } 448 449 bool MIRParser::initializeMachineFunction(MachineFunction &MF) { 450 return Impl->initializeMachineFunction(MF); 451 } 452 453 std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename, 454 SMDiagnostic &Error, 455 LLVMContext &Context) { 456 auto FileOrErr = MemoryBuffer::getFile(Filename); 457 if (std::error_code EC = FileOrErr.getError()) { 458 Error = SMDiagnostic(Filename, SourceMgr::DK_Error, 459 "Could not open input file: " + EC.message()); 460 return nullptr; 461 } 462 return createMIRParser(std::move(FileOrErr.get()), Context); 463 } 464 465 std::unique_ptr<MIRParser> 466 llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents, 467 LLVMContext &Context) { 468 auto Filename = Contents->getBufferIdentifier(); 469 return llvm::make_unique<MIRParser>( 470 llvm::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context)); 471 } 472