1259698Sdim//===- MCModuleYAML.cpp - MCModule YAMLIO implementation ------------------===//
2259698Sdim//
3259698Sdim//                     The LLVM Compiler Infrastructure
4259698Sdim//
5259698Sdim// This file is distributed under the University of Illinois Open Source
6259698Sdim// License. See LICENSE.TXT for details.
7259698Sdim//
8259698Sdim//===----------------------------------------------------------------------===//
9259698Sdim//
10259698Sdim// This file defines classes for handling the YAML representation of MCModule.
11259698Sdim//
12259698Sdim//===----------------------------------------------------------------------===//
13259698Sdim
14259698Sdim#include "llvm/MC/MCModuleYAML.h"
15259698Sdim#include "llvm/ADT/StringMap.h"
16259698Sdim#include "llvm/MC/MCAtom.h"
17259698Sdim#include "llvm/MC/MCFunction.h"
18259698Sdim#include "llvm/MC/MCInstrInfo.h"
19259698Sdim#include "llvm/MC/MCRegisterInfo.h"
20259698Sdim#include "llvm/Object/YAML.h"
21259698Sdim#include "llvm/Support/Allocator.h"
22259698Sdim#include "llvm/Support/MathExtras.h"
23259698Sdim#include "llvm/Support/YAMLTraits.h"
24259698Sdim#include <vector>
25259698Sdim
26259698Sdimnamespace llvm {
27259698Sdim
28259698Sdimnamespace {
29259698Sdim
30259698Sdim// This class is used to map opcode and register names to enum values.
31259698Sdim//
32259698Sdim// There are at least 3 obvious ways to do this:
33259698Sdim// 1- Generate an MII/MRI method using a tablegen StringMatcher
34259698Sdim// 2- Write an MII/MRI method using std::lower_bound and the assumption that
35259698Sdim//    the enums are sorted (starting at a fixed value).
36259698Sdim// 3- Do the matching manually as is done here.
37259698Sdim//
38259698Sdim// Why 3?
39259698Sdim// 1- A StringMatcher function for thousands of entries would incur
40259698Sdim//    a non-negligible binary size overhead.
41259698Sdim// 2- The lower_bound comparators would be somewhat involved and aren't
42259698Sdim//    obviously reusable (see LessRecordRegister in llvm/TableGen/Record.h)
43259698Sdim// 3- This isn't actually something useful outside tests (but the same argument
44259698Sdim//    can be made against having {MII,MRI}::getName).
45259698Sdim//
46259698Sdim// If this becomes useful outside this specific situation, feel free to do
47259698Sdim// the Right Thing (tm) and move the functionality to MII/MRI.
48259698Sdim//
49259698Sdimclass InstrRegInfoHolder {
50259698Sdim  typedef StringMap<unsigned, BumpPtrAllocator> EnumValByNameTy;
51259698Sdim  EnumValByNameTy InstEnumValueByName;
52259698Sdim  EnumValByNameTy RegEnumValueByName;
53259698Sdim
54259698Sdimpublic:
55259698Sdim  const MCInstrInfo &MII;
56259698Sdim  const MCRegisterInfo &MRI;
57259698Sdim  InstrRegInfoHolder(const MCInstrInfo &MII, const MCRegisterInfo &MRI)
58259698Sdim      : InstEnumValueByName(NextPowerOf2(MII.getNumOpcodes())),
59259698Sdim        RegEnumValueByName(NextPowerOf2(MRI.getNumRegs())), MII(MII), MRI(MRI) {
60259698Sdim    for (int i = 0, e = MII.getNumOpcodes(); i != e; ++i)
61259698Sdim      InstEnumValueByName[MII.getName(i)] = i;
62259698Sdim    for (int i = 0, e = MRI.getNumRegs(); i != e; ++i)
63259698Sdim      RegEnumValueByName[MRI.getName(i)] = i;
64259698Sdim  }
65259698Sdim
66259698Sdim  bool matchRegister(StringRef Name, unsigned &Reg) {
67259698Sdim    EnumValByNameTy::const_iterator It = RegEnumValueByName.find(Name);
68259698Sdim    if (It == RegEnumValueByName.end())
69259698Sdim      return false;
70259698Sdim    Reg = It->getValue();
71259698Sdim    return true;
72259698Sdim  }
73259698Sdim  bool matchOpcode(StringRef Name, unsigned &Opc) {
74259698Sdim    EnumValByNameTy::const_iterator It = InstEnumValueByName.find(Name);
75259698Sdim    if (It == InstEnumValueByName.end())
76259698Sdim      return false;
77259698Sdim    Opc = It->getValue();
78259698Sdim    return true;
79259698Sdim  }
80259698Sdim};
81259698Sdim
82259698Sdim} // end unnamed namespace
83259698Sdim
84259698Sdimnamespace MCModuleYAML {
85259698Sdim
86259698SdimLLVM_YAML_STRONG_TYPEDEF(unsigned, OpcodeEnum)
87259698Sdim
88259698Sdimstruct Operand {
89259698Sdim  MCOperand MCOp;
90259698Sdim};
91259698Sdim
92259698Sdimstruct Inst {
93259698Sdim  OpcodeEnum Opcode;
94259698Sdim  std::vector<Operand> Operands;
95259698Sdim  uint64_t Size;
96259698Sdim};
97259698Sdim
98259698Sdimstruct Atom {
99259698Sdim  MCAtom::AtomKind Type;
100259698Sdim  yaml::Hex64 StartAddress;
101259698Sdim  uint64_t Size;
102259698Sdim
103259698Sdim  std::vector<Inst> Insts;
104259698Sdim  object::yaml::BinaryRef Data;
105259698Sdim};
106259698Sdim
107259698Sdimstruct BasicBlock {
108259698Sdim  yaml::Hex64 Address;
109259698Sdim  std::vector<yaml::Hex64> Preds;
110259698Sdim  std::vector<yaml::Hex64> Succs;
111259698Sdim};
112259698Sdim
113259698Sdimstruct Function {
114259698Sdim  StringRef Name;
115259698Sdim  std::vector<BasicBlock> BasicBlocks;
116259698Sdim};
117259698Sdim
118259698Sdimstruct Module {
119259698Sdim  std::vector<Atom> Atoms;
120259698Sdim  std::vector<Function> Functions;
121259698Sdim};
122259698Sdim
123259698Sdim} // end namespace MCModuleYAML
124259698Sdim} // end namespace llvm
125259698Sdim
126259698SdimLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex64)
127259698SdimLLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::MCModuleYAML::Operand)
128259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Inst)
129259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Atom)
130259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::BasicBlock)
131259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Function)
132259698Sdim
133259698Sdimnamespace llvm {
134259698Sdim
135259698Sdimnamespace yaml {
136259698Sdim
137259698Sdimtemplate <> struct ScalarEnumerationTraits<MCAtom::AtomKind> {
138259698Sdim  static void enumeration(IO &IO, MCAtom::AtomKind &Kind);
139259698Sdim};
140259698Sdim
141259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::Atom> {
142259698Sdim  static void mapping(IO &IO, MCModuleYAML::Atom &A);
143259698Sdim};
144259698Sdim
145259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::Inst> {
146259698Sdim  static void mapping(IO &IO, MCModuleYAML::Inst &I);
147259698Sdim};
148259698Sdim
149259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::BasicBlock> {
150259698Sdim  static void mapping(IO &IO, MCModuleYAML::BasicBlock &BB);
151259698Sdim};
152259698Sdim
153259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::Function> {
154259698Sdim  static void mapping(IO &IO, MCModuleYAML::Function &Fn);
155259698Sdim};
156259698Sdim
157259698Sdimtemplate <> struct MappingTraits<MCModuleYAML::Module> {
158259698Sdim  static void mapping(IO &IO, MCModuleYAML::Module &M);
159259698Sdim};
160259698Sdim
161259698Sdimtemplate <> struct ScalarTraits<MCModuleYAML::Operand> {
162259698Sdim  static void output(const MCModuleYAML::Operand &, void *,
163259698Sdim                     llvm::raw_ostream &);
164259698Sdim  static StringRef input(StringRef, void *, MCModuleYAML::Operand &);
165259698Sdim};
166259698Sdim
167259698Sdimtemplate <> struct ScalarTraits<MCModuleYAML::OpcodeEnum> {
168259698Sdim  static void output(const MCModuleYAML::OpcodeEnum &, void *,
169259698Sdim                     llvm::raw_ostream &);
170259698Sdim  static StringRef input(StringRef, void *, MCModuleYAML::OpcodeEnum &);
171259698Sdim};
172259698Sdim
173259698Sdimvoid ScalarEnumerationTraits<MCAtom::AtomKind>::enumeration(
174259698Sdim    IO &IO, MCAtom::AtomKind &Value) {
175259698Sdim  IO.enumCase(Value, "Text", MCAtom::TextAtom);
176259698Sdim  IO.enumCase(Value, "Data", MCAtom::DataAtom);
177259698Sdim}
178259698Sdim
179259698Sdimvoid MappingTraits<MCModuleYAML::Atom>::mapping(IO &IO, MCModuleYAML::Atom &A) {
180259698Sdim  IO.mapRequired("StartAddress", A.StartAddress);
181259698Sdim  IO.mapRequired("Size", A.Size);
182259698Sdim  IO.mapRequired("Type", A.Type);
183259698Sdim  if (A.Type == MCAtom::TextAtom)
184259698Sdim    IO.mapRequired("Content", A.Insts);
185259698Sdim  else if (A.Type == MCAtom::DataAtom)
186259698Sdim    IO.mapRequired("Content", A.Data);
187259698Sdim}
188259698Sdim
189259698Sdimvoid MappingTraits<MCModuleYAML::Inst>::mapping(IO &IO, MCModuleYAML::Inst &I) {
190259698Sdim  IO.mapRequired("Inst", I.Opcode);
191259698Sdim  IO.mapRequired("Size", I.Size);
192259698Sdim  IO.mapRequired("Ops", I.Operands);
193259698Sdim}
194259698Sdim
195259698Sdimvoid
196259698SdimMappingTraits<MCModuleYAML::BasicBlock>::mapping(IO &IO,
197259698Sdim                                                 MCModuleYAML::BasicBlock &BB) {
198259698Sdim  IO.mapRequired("Address", BB.Address);
199259698Sdim  IO.mapRequired("Preds", BB.Preds);
200259698Sdim  IO.mapRequired("Succs", BB.Succs);
201259698Sdim}
202259698Sdim
203259698Sdimvoid MappingTraits<MCModuleYAML::Function>::mapping(IO &IO,
204259698Sdim                                                    MCModuleYAML::Function &F) {
205259698Sdim  IO.mapRequired("Name", F.Name);
206259698Sdim  IO.mapRequired("BasicBlocks", F.BasicBlocks);
207259698Sdim}
208259698Sdim
209259698Sdimvoid MappingTraits<MCModuleYAML::Module>::mapping(IO &IO,
210259698Sdim                                                  MCModuleYAML::Module &M) {
211259698Sdim  IO.mapRequired("Atoms", M.Atoms);
212259698Sdim  IO.mapOptional("Functions", M.Functions);
213259698Sdim}
214259698Sdim
215259698Sdimvoid
216259698SdimScalarTraits<MCModuleYAML::Operand>::output(const MCModuleYAML::Operand &Val,
217259698Sdim                                            void *Ctx, raw_ostream &Out) {
218259698Sdim  InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
219259698Sdim
220259698Sdim  // FIXME: Doesn't support FPImm and expr/inst, but do these make sense?
221259698Sdim  if (Val.MCOp.isImm())
222259698Sdim    Out << "I" << Val.MCOp.getImm();
223259698Sdim  else if (Val.MCOp.isReg())
224259698Sdim    Out << "R" << IRI->MRI.getName(Val.MCOp.getReg());
225259698Sdim  else
226259698Sdim    llvm_unreachable("Trying to output invalid MCOperand!");
227259698Sdim}
228259698Sdim
229259698SdimStringRef
230259698SdimScalarTraits<MCModuleYAML::Operand>::input(StringRef Scalar, void *Ctx,
231259698Sdim                                           MCModuleYAML::Operand &Val) {
232259698Sdim  InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
233259698Sdim  char Type = 0;
234259698Sdim  if (Scalar.size() >= 1)
235259698Sdim    Type = Scalar.front();
236259698Sdim  if (Type != 'R' && Type != 'I')
237259698Sdim    return "Operand must start with 'R' (register) or 'I' (immediate).";
238259698Sdim  if (Type == 'R') {
239259698Sdim    unsigned Reg;
240259698Sdim    if (!IRI->matchRegister(Scalar.substr(1), Reg))
241259698Sdim      return "Invalid register name.";
242259698Sdim    Val.MCOp = MCOperand::CreateReg(Reg);
243259698Sdim  } else if (Type == 'I') {
244259698Sdim    int64_t RIVal;
245259698Sdim    if (Scalar.substr(1).getAsInteger(10, RIVal))
246259698Sdim      return "Invalid immediate value.";
247259698Sdim    Val.MCOp = MCOperand::CreateImm(RIVal);
248259698Sdim  } else {
249259698Sdim    Val.MCOp = MCOperand();
250259698Sdim  }
251259698Sdim  return StringRef();
252259698Sdim}
253259698Sdim
254259698Sdimvoid ScalarTraits<MCModuleYAML::OpcodeEnum>::output(
255259698Sdim    const MCModuleYAML::OpcodeEnum &Val, void *Ctx, raw_ostream &Out) {
256259698Sdim  InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
257259698Sdim  Out << IRI->MII.getName(Val);
258259698Sdim}
259259698Sdim
260259698SdimStringRef
261259698SdimScalarTraits<MCModuleYAML::OpcodeEnum>::input(StringRef Scalar, void *Ctx,
262259698Sdim                                              MCModuleYAML::OpcodeEnum &Val) {
263259698Sdim  InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
264259698Sdim  unsigned Opc;
265259698Sdim  if (!IRI->matchOpcode(Scalar, Opc))
266259698Sdim    return "Invalid instruction opcode.";
267259698Sdim  Val = Opc;
268259698Sdim  return "";
269259698Sdim}
270259698Sdim
271259698Sdim} // end namespace yaml
272259698Sdim
273259698Sdimnamespace {
274259698Sdim
275259698Sdimclass MCModule2YAML {
276259698Sdim  const MCModule &MCM;
277259698Sdim  MCModuleYAML::Module YAMLModule;
278259698Sdim  void dumpAtom(const MCAtom *MCA);
279259698Sdim  void dumpFunction(const MCFunction *MCF);
280259698Sdim  void dumpBasicBlock(const MCBasicBlock *MCBB);
281259698Sdim
282259698Sdimpublic:
283259698Sdim  MCModule2YAML(const MCModule &MCM);
284259698Sdim  MCModuleYAML::Module &getYAMLModule();
285259698Sdim};
286259698Sdim
287259698Sdimclass YAML2MCModule {
288259698Sdim  MCModule &MCM;
289259698Sdim
290259698Sdimpublic:
291259698Sdim  YAML2MCModule(MCModule &MCM);
292259698Sdim  StringRef parse(const MCModuleYAML::Module &YAMLModule);
293259698Sdim};
294259698Sdim
295259698Sdim} // end unnamed namespace
296259698Sdim
297259698SdimMCModule2YAML::MCModule2YAML(const MCModule &MCM) : MCM(MCM), YAMLModule() {
298259698Sdim  for (MCModule::const_atom_iterator AI = MCM.atom_begin(), AE = MCM.atom_end();
299259698Sdim       AI != AE; ++AI)
300259698Sdim    dumpAtom(*AI);
301259698Sdim  for (MCModule::const_func_iterator FI = MCM.func_begin(), FE = MCM.func_end();
302259698Sdim       FI != FE; ++FI)
303259698Sdim    dumpFunction(*FI);
304259698Sdim}
305259698Sdim
306259698Sdimvoid MCModule2YAML::dumpAtom(const MCAtom *MCA) {
307259698Sdim  YAMLModule.Atoms.resize(YAMLModule.Atoms.size() + 1);
308259698Sdim  MCModuleYAML::Atom &A = YAMLModule.Atoms.back();
309259698Sdim  A.Type = MCA->getKind();
310259698Sdim  A.StartAddress = MCA->getBeginAddr();
311259698Sdim  A.Size = MCA->getEndAddr() - MCA->getBeginAddr() + 1;
312259698Sdim  if (const MCTextAtom *TA = dyn_cast<MCTextAtom>(MCA)) {
313259698Sdim    const size_t InstCount = TA->size();
314259698Sdim    A.Insts.resize(InstCount);
315259698Sdim    for (size_t i = 0; i != InstCount; ++i) {
316259698Sdim      const MCDecodedInst &MCDI = TA->at(i);
317259698Sdim      A.Insts[i].Opcode = MCDI.Inst.getOpcode();
318259698Sdim      A.Insts[i].Size = MCDI.Size;
319259698Sdim      const unsigned OpCount = MCDI.Inst.getNumOperands();
320259698Sdim      A.Insts[i].Operands.resize(OpCount);
321259698Sdim      for (unsigned oi = 0; oi != OpCount; ++oi)
322259698Sdim        A.Insts[i].Operands[oi].MCOp = MCDI.Inst.getOperand(oi);
323259698Sdim    }
324259698Sdim  } else if (const MCDataAtom *DA = dyn_cast<MCDataAtom>(MCA)) {
325259698Sdim    A.Data = DA->getData();
326259698Sdim  } else {
327259698Sdim    llvm_unreachable("Unknown atom type.");
328259698Sdim  }
329259698Sdim}
330259698Sdim
331259698Sdimvoid MCModule2YAML::dumpFunction(const MCFunction *MCF) {
332259698Sdim  YAMLModule.Functions.resize(YAMLModule.Functions.size() + 1);
333259698Sdim  MCModuleYAML::Function &F = YAMLModule.Functions.back();
334259698Sdim  F.Name = MCF->getName();
335259698Sdim  for (MCFunction::const_iterator BBI = MCF->begin(), BBE = MCF->end();
336259698Sdim       BBI != BBE; ++BBI) {
337259698Sdim    const MCBasicBlock *MCBB = *BBI;
338259698Sdim    F.BasicBlocks.resize(F.BasicBlocks.size() + 1);
339259698Sdim    MCModuleYAML::BasicBlock &BB = F.BasicBlocks.back();
340259698Sdim    BB.Address = MCBB->getInsts()->getBeginAddr();
341259698Sdim    for (MCBasicBlock::pred_const_iterator PI = MCBB->pred_begin(),
342259698Sdim                                           PE = MCBB->pred_end();
343259698Sdim         PI != PE; ++PI)
344259698Sdim      BB.Preds.push_back((*PI)->getInsts()->getBeginAddr());
345259698Sdim    for (MCBasicBlock::succ_const_iterator SI = MCBB->succ_begin(),
346259698Sdim                                           SE = MCBB->succ_end();
347259698Sdim         SI != SE; ++SI)
348259698Sdim      BB.Succs.push_back((*SI)->getInsts()->getBeginAddr());
349259698Sdim  }
350259698Sdim}
351259698Sdim
352259698SdimMCModuleYAML::Module &MCModule2YAML::getYAMLModule() { return YAMLModule; }
353259698Sdim
354259698SdimYAML2MCModule::YAML2MCModule(MCModule &MCM) : MCM(MCM) {}
355259698Sdim
356259698SdimStringRef YAML2MCModule::parse(const MCModuleYAML::Module &YAMLModule) {
357259698Sdim  typedef std::vector<MCModuleYAML::Atom>::const_iterator AtomIt;
358259698Sdim  typedef std::vector<MCModuleYAML::Inst>::const_iterator InstIt;
359259698Sdim  typedef std::vector<MCModuleYAML::Operand>::const_iterator OpIt;
360259698Sdim
361259698Sdim  typedef DenseMap<uint64_t, MCTextAtom *> AddrToTextAtomTy;
362259698Sdim  AddrToTextAtomTy TAByAddr;
363259698Sdim
364259698Sdim  for (AtomIt AI = YAMLModule.Atoms.begin(), AE = YAMLModule.Atoms.end();
365259698Sdim       AI != AE; ++AI) {
366259698Sdim    uint64_t StartAddress = AI->StartAddress;
367259698Sdim    if (AI->Size == 0)
368259698Sdim      return "Atoms can't be empty!";
369259698Sdim    uint64_t EndAddress = StartAddress + AI->Size - 1;
370259698Sdim    switch (AI->Type) {
371259698Sdim    case MCAtom::TextAtom: {
372259698Sdim      MCTextAtom *TA = MCM.createTextAtom(StartAddress, EndAddress);
373259698Sdim      TAByAddr[StartAddress] = TA;
374259698Sdim      for (InstIt II = AI->Insts.begin(), IE = AI->Insts.end(); II != IE;
375259698Sdim           ++II) {
376259698Sdim        MCInst MI;
377259698Sdim        MI.setOpcode(II->Opcode);
378259698Sdim        for (OpIt OI = II->Operands.begin(), OE = II->Operands.end(); OI != OE;
379259698Sdim             ++OI)
380259698Sdim          MI.addOperand(OI->MCOp);
381259698Sdim        TA->addInst(MI, II->Size);
382259698Sdim      }
383259698Sdim      break;
384259698Sdim    }
385259698Sdim    case MCAtom::DataAtom: {
386259698Sdim      MCDataAtom *DA = MCM.createDataAtom(StartAddress, EndAddress);
387259698Sdim      SmallVector<char, 64> Data;
388259698Sdim      raw_svector_ostream OS(Data);
389259698Sdim      AI->Data.writeAsBinary(OS);
390259698Sdim      OS.flush();
391259698Sdim      for (size_t i = 0, e = Data.size(); i != e; ++i)
392259698Sdim        DA->addData((uint8_t)Data[i]);
393259698Sdim      break;
394259698Sdim    }
395259698Sdim    }
396259698Sdim  }
397259698Sdim
398259698Sdim  typedef std::vector<MCModuleYAML::Function>::const_iterator FuncIt;
399259698Sdim  typedef std::vector<MCModuleYAML::BasicBlock>::const_iterator BBIt;
400259698Sdim  typedef std::vector<yaml::Hex64>::const_iterator AddrIt;
401259698Sdim  for (FuncIt FI = YAMLModule.Functions.begin(),
402259698Sdim              FE = YAMLModule.Functions.end();
403259698Sdim       FI != FE; ++FI) {
404259698Sdim    MCFunction *MCFN = MCM.createFunction(FI->Name);
405259698Sdim    for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end();
406259698Sdim         BBI != BBE; ++BBI) {
407259698Sdim      AddrToTextAtomTy::const_iterator It = TAByAddr.find(BBI->Address);
408259698Sdim      if (It == TAByAddr.end())
409259698Sdim        return "Basic block start address doesn't match any text atom!";
410259698Sdim      MCFN->createBlock(*It->second);
411259698Sdim    }
412259698Sdim    for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end();
413259698Sdim         BBI != BBE; ++BBI) {
414259698Sdim      MCBasicBlock *MCBB = MCFN->find(BBI->Address);
415259698Sdim      if (!MCBB)
416259698Sdim        return "Couldn't find matching basic block in function.";
417259698Sdim      for (AddrIt PI = BBI->Preds.begin(), PE = BBI->Preds.end(); PI != PE;
418259698Sdim           ++PI) {
419259698Sdim        MCBasicBlock *Pred = MCFN->find(*PI);
420259698Sdim        if (!Pred)
421259698Sdim          return "Couldn't find predecessor basic block.";
422259698Sdim        MCBB->addPredecessor(Pred);
423259698Sdim      }
424259698Sdim      for (AddrIt SI = BBI->Succs.begin(), SE = BBI->Succs.end(); SI != SE;
425259698Sdim           ++SI) {
426259698Sdim        MCBasicBlock *Succ = MCFN->find(*SI);
427259698Sdim        if (!Succ)
428259698Sdim          return "Couldn't find predecessor basic block.";
429259698Sdim        MCBB->addSuccessor(Succ);
430259698Sdim      }
431259698Sdim    }
432259698Sdim  }
433259698Sdim  return "";
434259698Sdim}
435259698Sdim
436259698SdimStringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM,
437259698Sdim                        const MCInstrInfo &MII, const MCRegisterInfo &MRI) {
438259698Sdim  MCModule2YAML Dumper(MCM);
439259698Sdim  InstrRegInfoHolder IRI(MII, MRI);
440259698Sdim  yaml::Output YOut(OS, (void *)&IRI);
441259698Sdim  YOut << Dumper.getYAMLModule();
442259698Sdim  return "";
443259698Sdim}
444259698Sdim
445259698SdimStringRef yaml2mcmodule(OwningPtr<MCModule> &MCM, StringRef YamlContent,
446259698Sdim                        const MCInstrInfo &MII, const MCRegisterInfo &MRI) {
447259698Sdim  MCM.reset(new MCModule);
448259698Sdim  YAML2MCModule Parser(*MCM);
449259698Sdim  MCModuleYAML::Module YAMLModule;
450259698Sdim  InstrRegInfoHolder IRI(MII, MRI);
451259698Sdim  yaml::Input YIn(YamlContent, (void *)&IRI);
452259698Sdim  YIn >> YAMLModule;
453259698Sdim  if (error_code ec = YIn.error())
454259698Sdim    return ec.message();
455259698Sdim  StringRef err = Parser.parse(YAMLModule);
456259698Sdim  if (!err.empty())
457259698Sdim    return err;
458259698Sdim  return "";
459259698Sdim}
460259698Sdim
461259698Sdim} // end namespace llvm
462