[go: nahoru, domu]

1d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao/*
2d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao * Copyright 2012, The Android Open Source Project
3d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao *
4d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
5d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao * you may not use this file except in compliance with the License.
6d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao * You may obtain a copy of the License at
7d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao *
8d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
9d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao *
10d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao * Unless required by applicable law or agreed to in writing, software
11d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
12d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao * See the License for the specific language governing permissions and
14d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao * limitations under the License.
15d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao */
16d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
17c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Source.h"
18d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
19d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao#include <new>
20d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
218e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar#include <llvm/ADT/STLExtras.h>
22d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao#include <llvm/Bitcode/ReaderWriter.h>
23b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/LLVMContext.h>
24b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include <llvm/IR/Module.h>
25c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray#include <llvm/IR/Verifier.h>
26c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray#include <llvm/Linker/Linker.h>
27d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao#include <llvm/Support/MemoryBuffer.h>
28c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray#include "llvm/Support/raw_ostream.h"
29d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
30c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/BCCContext.h"
31ef73a242762bcd8113b9b65ceccbe7d909b5acbcZonr Chang#include "bcc/Support/Log.h"
32c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang
338e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar#include "bcinfo/MetadataExtractor.h"
348e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar
35d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao#include "BCCContextImpl.h"
36d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
37d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liaonamespace {
38d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
39d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao// Helper function to load the bitcode. This uses "bitcode lazy load" feature to
40d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao// reduce the startup time. On success, return the LLVM module object created
41d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao// and take the ownership of input memory buffer (i.e., pInput). On error,
42900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes// return nullptr and will NOT take the ownership of pInput.
438e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainarstatic inline std::unique_ptr<llvm::Module> helper_load_bitcode(llvm::LLVMContext &pContext,
44579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines                                                std::unique_ptr<llvm::MemoryBuffer> &&pInput) {
458e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  llvm::ErrorOr<std::unique_ptr<llvm::Module> > moduleOrError
468e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar      = llvm::getLazyBitcodeModule(std::move(pInput), pContext);
47d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines  if (std::error_code ec = moduleOrError.getError()) {
48d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    ALOGE("Unable to parse the given bitcode file `%s'! (%s)",
49c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray          pInput->getBufferIdentifier(), ec.message().c_str());
50d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  }
51d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
528e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  return std::move(moduleOrError.get());
53d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao}
54d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
55d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao} // end anonymous namespace
56d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
57d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liaonamespace bcc {
58d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
5906731a6150ae8014d37258d5f32ef8bc14a3db63Stephen Hinesvoid Source::setModule(llvm::Module *pModule) {
6006731a6150ae8014d37258d5f32ef8bc14a3db63Stephen Hines  if (!mNoDelete && (mModule != pModule)) delete mModule;
6106731a6150ae8014d37258d5f32ef8bc14a3db63Stephen Hines  mModule = pModule;
6206731a6150ae8014d37258d5f32ef8bc14a3db63Stephen Hines}
6306731a6150ae8014d37258d5f32ef8bc14a3db63Stephen Hines
64d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei LiaoSource *Source::CreateFromBuffer(BCCContext &pContext,
65d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao                                 const char *pName,
66d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao                                 const char *pBitcode,
67d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao                                 size_t pBitcodeSize) {
68d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  llvm::StringRef input_data(pBitcode, pBitcodeSize);
69579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines  std::unique_ptr<llvm::MemoryBuffer> input_memory =
70c996b870ae40603b477a8d7a50f461b82389aaf1Shih-wei Liao      llvm::MemoryBuffer::getMemBuffer(input_data, "", false);
71d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
72900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (input_memory == nullptr) {
73d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    ALOGE("Unable to load bitcode `%s' from buffer!", pName);
74900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes    return nullptr;
75d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  }
76d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
778e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  auto managedModule = helper_load_bitcode(pContext.mImpl->mLLVMContext,
788e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar                                           std::move(input_memory));
798e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar
808e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  // Release the managed llvm::Module* since this object gets deleted either in
818e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  // the error check below or in ~Source() (since pNoDelete is false).
828e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  llvm::Module *module = managedModule.release();
83900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (module == nullptr) {
84900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes    return nullptr;
85d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  }
86d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
87a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  Source *result = CreateFromModule(pContext, pName, *module, /* pNoDelete */false);
88900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (result == nullptr) {
89d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    delete module;
90d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  }
91d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
92d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  return result;
93d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao}
94d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
95d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei LiaoSource *Source::CreateFromFile(BCCContext &pContext, const std::string &pPath) {
96d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
97d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> mb_or_error =
98d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines      llvm::MemoryBuffer::getFile(pPath);
99d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines  if (mb_or_error.getError()) {
100d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    ALOGE("Failed to load bitcode from path %s! (%s)", pPath.c_str(),
101d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines          mb_or_error.getError().message().c_str());
102900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes    return nullptr;
103d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  }
104d0993af5b1337f8186dd9aedea2e138a919e02e9Stephen Hines  std::unique_ptr<llvm::MemoryBuffer> input_data = std::move(mb_or_error.get());
105d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
106579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines  std::unique_ptr<llvm::MemoryBuffer> input_memory(input_data.release());
1078e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  auto managedModule = helper_load_bitcode(pContext.mImpl->mLLVMContext,
1088e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar                                           std::move(input_memory));
1098e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar
1108e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  // Release the managed llvm::Module* since this object gets deleted either in
1118e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  // the error check below or in ~Source() (since pNoDelete is false).
1128e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  llvm::Module *module = managedModule.release();
113900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (module == nullptr) {
114900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes    return nullptr;
1156202dda52b7898340aac05e73adebc4fb9199f4dShih-wei Liao  }
1166202dda52b7898340aac05e73adebc4fb9199f4dShih-wei Liao
117a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  Source *result = CreateFromModule(pContext, pPath.c_str(), *module, /* pNoDelete */false);
118900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (result == nullptr) {
1196202dda52b7898340aac05e73adebc4fb9199f4dShih-wei Liao    delete module;
1206202dda52b7898340aac05e73adebc4fb9199f4dShih-wei Liao  }
1216202dda52b7898340aac05e73adebc4fb9199f4dShih-wei Liao
1226202dda52b7898340aac05e73adebc4fb9199f4dShih-wei Liao  return result;
1236202dda52b7898340aac05e73adebc4fb9199f4dShih-wei Liao}
124d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
125a4ded1373d7ad3e503f186e65bccf94126a0f020Yang NiSource *Source::CreateFromModule(BCCContext &pContext, const char* name, llvm::Module &pModule,
126d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao                                 bool pNoDelete) {
127b316f58fd790ad302b72f569af3e89734ae09db7Tobias Grosser  std::string ErrorInfo;
128c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray  llvm::raw_string_ostream ErrorStream(ErrorInfo);
1298e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  pModule.materializeAll();
130c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray  if (llvm::verifyModule(pModule, &ErrorStream)) {
131b316f58fd790ad302b72f569af3e89734ae09db7Tobias Grosser    ALOGE("Bitcode of RenderScript module does not pass verification: `%s'!",
132c2074caf075818abb6d3689ad924ca09f4a5ba1fTim Murray          ErrorStream.str().c_str());
133900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes    return nullptr;
134b316f58fd790ad302b72f569af3e89734ae09db7Tobias Grosser  }
135b316f58fd790ad302b72f569af3e89734ae09db7Tobias Grosser
136a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  Source *result = new (std::nothrow) Source(name, pContext, pModule, pNoDelete);
137900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (result == nullptr) {
138d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    ALOGE("Out of memory during Source object allocation for `%s'!",
139d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao          pModule.getModuleIdentifier().c_str());
140d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  }
141d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  return result;
142d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao}
143d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
144a4ded1373d7ad3e503f186e65bccf94126a0f020Yang NiSource::Source(const char* name, BCCContext &pContext, llvm::Module &pModule,
145a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni               bool pNoDelete)
1468e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar    : mName(name), mContext(pContext), mModule(&pModule), mMetadata(nullptr),
1478e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar      mNoDelete(pNoDelete), mIsModuleDestroyed(false) {
148d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    pContext.addSource(*this);
149d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao}
150d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
151d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei LiaoSource::~Source() {
152d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  mContext.removeSource(*this);
1538e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  if (!mNoDelete && !mIsModuleDestroyed)
154d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    delete mModule;
1558e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  delete mMetadata;
156d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao}
157d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
158579361346abc6696c805e3904a18178ebce4e4a3Stephen Hinesbool Source::merge(Source &pSource) {
159579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines  // TODO(srhines): Add back logging of actual diagnostics from linking.
1608e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  if (llvm::Linker::linkModules(*mModule, std::unique_ptr<llvm::Module>(&pSource.getModule())) != 0) {
161579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines    ALOGE("Failed to link source `%s' with `%s'!",
162579361346abc6696c805e3904a18178ebce4e4a3Stephen Hines          getIdentifier().c_str(), pSource.getIdentifier().c_str());
163d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    return false;
164d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  }
1658e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  // pSource.getModule() is destroyed after linking.
1668e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  pSource.markModuleDestroyed();
167d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
168d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  return true;
169d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao}
170d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
171d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei LiaoSource *Source::CreateEmpty(BCCContext &pContext, const std::string &pName) {
172d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  // Create an empty module
173d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  llvm::Module *module =
174d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao      new (std::nothrow) llvm::Module(pName, pContext.mImpl->mLLVMContext);
175d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
176900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (module == nullptr) {
177d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    ALOGE("Out of memory when creating empty LLVM module `%s'!", pName.c_str());
178900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes    return nullptr;
179d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  }
180d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
181a4ded1373d7ad3e503f186e65bccf94126a0f020Yang Ni  Source *result = CreateFromModule(pContext, pName.c_str(), *module, /* pNoDelete */false);
182900c6c1f08f7c572125d7d39abe0f0f9eafbfa14Chris Wailes  if (result == nullptr) {
183d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao    delete module;
184d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  }
185d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
186d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  return result;
187d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao}
188d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
189d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liaoconst std::string &Source::getIdentifier() const {
190d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao  return mModule->getModuleIdentifier();
191d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao}
192d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao
19351ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainarvoid Source::addBuildChecksumMetadata(const char *buildChecksum) const {
19451ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar    llvm::LLVMContext &context = mContext.mImpl->mLLVMContext;
19551ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar    llvm::MDString *val = llvm::MDString::get(context, buildChecksum);
19651ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar    llvm::NamedMDNode *node =
19751ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar        mModule->getOrInsertNamedMetadata("#rs_build_checksum");
19851ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar    node->addOperand(llvm::MDNode::get(context, val));
19951ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar}
20051ee77bd31e7d8ca6c89e37b5806c8fc2afcf0dcPirama Arumuga Nainar
20109c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leobool Source::getDebugInfoEnabled() const {
20209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo  return mModule->getNamedMetadata("llvm.dbg.cu") != nullptr;
20309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo}
20409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo
2058e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainarbool Source::extractMetadata() {
2068e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  mMetadata = new bcinfo::MetadataExtractor(mModule);
2078e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar  return mMetadata->extract();
2088e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar}
2098e9089377848628813a697b972773e969b942c3bPirama Arumuga Nainar
210d2a5a0eab7a1273797029702652e50b2ed9e6a6dShih-wei Liao} // namespace bcc
211