MIRParser.cpp 19 KB

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