Project import
diff --git a/libbcc/Android.mk b/libbcc/Android.mk
new file mode 100644
index 0000000..4ed3ebd
--- /dev/null
+++ b/libbcc/Android.mk
@@ -0,0 +1,121 @@
+#
+# Copyright (C) 2010-2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+LIBBCC_ROOT_PATH := $(LOCAL_PATH)
+
+FORCE_BUILD_LLVM_DISABLE_NDEBUG ?= false
+# Legality check: FORCE_BUILD_LLVM_DISABLE_NDEBUG should consist of one word -- either "true" or "false".
+ifneq "$(words $(FORCE_BUILD_LLVM_DISABLE_NDEBUG))$(words $(filter-out true false,$(FORCE_BUILD_LLVM_DISABLE_NDEBUG)))" "10"
+  $(error FORCE_BUILD_LLVM_DISABLE_NDEBUG may only be true, false, or unset)
+endif
+
+FORCE_BUILD_LLVM_DEBUG ?= false
+# Legality check: FORCE_BUILD_LLVM_DEBUG should consist of one word -- either "true" or "false".
+ifneq "$(words $(FORCE_BUILD_LLVM_DEBUG))$(words $(filter-out true false,$(FORCE_BUILD_LLVM_DEBUG)))" "10"
+  $(error FORCE_BUILD_LLVM_DEBUG may only be true, false, or unset)
+endif
+
+include $(LIBBCC_ROOT_PATH)/libbcc.mk
+
+include frameworks/compile/slang/rs_version.mk
+
+#=====================================================================
+# Whole Static Library to Be Linked In
+#=====================================================================
+
+libbcc_WHOLE_STATIC_LIBRARIES += \
+  libbccRenderscript \
+  libbccCore \
+  libbccSupport
+
+#=====================================================================
+# Device Shared Library libbcc
+#=====================================================================
+ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS))
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libbcc
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
+LOCAL_WHOLE_STATIC_LIBRARIES := $(libbcc_WHOLE_STATIC_LIBRARIES)
+
+LOCAL_SHARED_LIBRARIES := libbcinfo libLLVM libdl libutils libcutils liblog libc++
+
+# Modules that need get installed if and only if the target libbcc.so is
+# installed.
+LOCAL_REQUIRED_MODULES := libclcore.bc libclcore_debug.bc libclcore_g.bc libcompiler_rt
+
+LOCAL_REQUIRED_MODULES_x86 += libclcore_x86.bc
+LOCAL_REQUIRED_MODULES_x86_64 += libclcore_x86.bc
+
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
+  LOCAL_REQUIRED_MODULES_arm += libclcore_neon.bc
+endif
+
+include $(LIBBCC_DEVICE_BUILD_MK)
+include $(LLVM_DEVICE_BUILD_MK)
+include $(BUILD_SHARED_LIBRARY)
+endif
+
+#=====================================================================
+# Host Shared Library libbcc
+#=====================================================================
+
+# Don't build for unbundled branches
+ifeq (,$(TARGET_BUILD_APPS))
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libbcc
+LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_IS_HOST_MODULE := true
+
+LOCAL_WHOLE_STATIC_LIBRARIES += $(libbcc_WHOLE_STATIC_LIBRARIES)
+
+LOCAL_STATIC_LIBRARIES += \
+  libutils \
+  libcutils \
+  liblog
+
+LOCAL_SHARED_LIBRARIES := libbcinfo
+
+LOCAL_LDLIBS_darwin := -ldl -lpthread
+LOCAL_LDLIBS_linux := -ldl -lpthread
+
+include $(LIBBCC_ROOT_PATH)/llvm-loadable-libbcc.mk
+
+ifeq ($(CAN_BUILD_HOST_LLVM_LOADABLE_MODULE),true)
+LOCAL_STATIC_LIBRARIES_linux += libLLVMLinker
+else
+LOCAL_SHARED_LIBRARIES_linux += libLLVM
+endif
+LOCAL_SHARED_LIBRARIES_darwin += libLLVM
+LOCAL_SHARED_LIBRARIES_windows += libLLVM
+
+include $(LIBBCC_HOST_BUILD_MK)
+include $(LLVM_HOST_BUILD_MK)
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+endif # Don't build in unbundled branches
+
+#=====================================================================
+# Include Subdirectories
+#=====================================================================
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libbcc/CleanSpec.mk b/libbcc/CleanSpec.mk
new file mode 100644
index 0000000..86467c6
--- /dev/null
+++ b/libbcc/CleanSpec.mk
@@ -0,0 +1,72 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list.  These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list.  E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libbcc_intermediates)
+$(call add-clean-step, rm -rf $(HOST_OUT)/obj/SHARED_LIBRARIES/libbcc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libruntime.bc)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libbcc_sha1_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libbcc_sha1.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore_neon.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore*.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libbcinfo_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libclcore*.bc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libbc*_intermediates)
+$(call add-clean-step, rm -rf $(HOST_OUT)/obj/STATIC_LIBRARIES/libbc*_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libbc*_intermediates)
+$(call add-clean-step, rm -rf $(HOST_OUT)/obj/SHARED_LIBRARIES/libbc*_intermediates)
+$(call add-clean-step, rm -rf $(HOST_OUT)/obj/STATIC_LIBRARIES/libbc*_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libbc*_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libbcc_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libbcc.sha1_intermediates)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/libbcc/NOTICE b/libbcc/NOTICE
new file mode 100644
index 0000000..1344fe2
--- /dev/null
+++ b/libbcc/NOTICE
@@ -0,0 +1,322 @@
+==========================
+NOTICE file for libbcc.git
+==========================
+
+* NOTICE for lib/ExecutionEngine/, lib/ScriptCRT/, include and helper/.
+
+   Copyright (c) 2005-2011, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+
+
+* NOTICE for runtime/ and lib/CodeGen/.
+  Note: The NOTICE is the same for another git project, external/llvm.git.
+
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2003-2011 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the LLVM Team, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used to
+      endorse or promote products derived from this Software without specific
+      prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The LLVM software contains code written by third parties.  Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+Autoconf            llvm/autoconf
+                    llvm/projects/ModuleMaker/autoconf
+                    llvm/projects/sample/autoconf
+CellSPU backend     llvm/lib/Target/CellSPU/README.txt
+Google Test         llvm/utils/unittest/googletest
+OpenBSD regex       llvm/lib/Support/{reg*, COPYRIGHT.regex}
+
+
+
+* NOTICE for tests/disassem.cpp and tests/disassem.h.
+
+/*      $NetBSD: disassem.c,v 1.14 2003/03/27 16:58:36 mycroft Exp $    */
+
+/*-
+ * Copyright (c) 1996 Mark Brinicombe.
+ * Copyright (c) 1996 Brini.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * RiscBSD kernel project
+ *
+ * db_disasm.c
+ *
+ * Kernel disassembler
+ *
+ * Created      : 10/02/96
+ *
+ * Structured after the sparc/sparc/db_disasm.c by David S. Miller &
+ * Paul Kranenburg
+ *
+ * This code is not complete. Not all instructions are disassembled.
+ */
diff --git a/libbcc/README.html b/libbcc/README.html
new file mode 100644
index 0000000..c4b9653
--- /dev/null
+++ b/libbcc/README.html
@@ -0,0 +1,473 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
+<title>libbcc: A Versatile Bitcode Execution Engine for Mobile Devices</title>
+<style type="text/css">
+
+/*
+:Author: David Goodger (goodger@python.org)
+:Id: $Id: html4css1.css 5951 2009-05-18 18:03:10Z milde $
+:Copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+*/
+
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+  border: 0 }
+
+table.borderless td, table.borderless th {
+  /* Override padding for "table.docutils td" with "! important".
+     The right padding separates the table cells. */
+  padding: 0 0.5em 0 0 ! important }
+
+.first {
+  /* Override more specific margin styles with "! important". */
+  margin-top: 0 ! important }
+
+.last, .with-subtitle {
+  margin-bottom: 0 ! important }
+
+.hidden {
+  display: none }
+
+a.toc-backref {
+  text-decoration: none ;
+  color: black }
+
+blockquote.epigraph {
+  margin: 2em 5em ; }
+
+dl.docutils dd {
+  margin-bottom: 0.5em }
+
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
+  font-weight: bold }
+*/
+
+div.abstract {
+  margin: 2em 5em }
+
+div.abstract p.topic-title {
+  font-weight: bold ;
+  text-align: center }
+
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
+  margin: 2em ;
+  border: medium outset ;
+  padding: 1em }
+
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+  font-weight: bold ;
+  font-family: sans-serif }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+  color: red ;
+  font-weight: bold ;
+  font-family: sans-serif }
+
+/* Uncomment (and remove this text!) to get reduced vertical space in
+   compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+  margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+  margin-top: 0.5em }
+*/
+
+div.dedication {
+  margin: 2em 5em ;
+  text-align: center ;
+  font-style: italic }
+
+div.dedication p.topic-title {
+  font-weight: bold ;
+  font-style: normal }
+
+div.figure {
+  margin-left: 2em ;
+  margin-right: 2em }
+
+div.footer, div.header {
+  clear: both;
+  font-size: smaller }
+
+div.line-block {
+  display: block ;
+  margin-top: 1em ;
+  margin-bottom: 1em }
+
+div.line-block div.line-block {
+  margin-top: 0 ;
+  margin-bottom: 0 ;
+  margin-left: 1.5em }
+
+div.sidebar {
+  margin: 0 0 0.5em 1em ;
+  border: medium outset ;
+  padding: 1em ;
+  background-color: #ffffee ;
+  width: 40% ;
+  float: right ;
+  clear: right }
+
+div.sidebar p.rubric {
+  font-family: sans-serif ;
+  font-size: medium }
+
+div.system-messages {
+  margin: 5em }
+
+div.system-messages h1 {
+  color: red }
+
+div.system-message {
+  border: medium outset ;
+  padding: 1em }
+
+div.system-message p.system-message-title {
+  color: red ;
+  font-weight: bold }
+
+div.topic {
+  margin: 2em }
+
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+  margin-top: 0.4em }
+
+h1.title {
+  text-align: center }
+
+h2.subtitle {
+  text-align: center }
+
+hr.docutils {
+  width: 75% }
+
+img.align-left, .figure.align-left{
+  clear: left ;
+  float: left ;
+  margin-right: 1em }
+
+img.align-right, .figure.align-right {
+  clear: right ;
+  float: right ;
+  margin-left: 1em }
+
+.align-left {
+  text-align: left }
+
+.align-center {
+  clear: both ;
+  text-align: center }
+
+.align-right {
+  text-align: right }
+
+/* reset inner alignment in figures */
+div.align-right {
+  text-align: left }
+
+/* div.align-center * { */
+/*   text-align: left } */
+
+ol.simple, ul.simple {
+  margin-bottom: 1em }
+
+ol.arabic {
+  list-style: decimal }
+
+ol.loweralpha {
+  list-style: lower-alpha }
+
+ol.upperalpha {
+  list-style: upper-alpha }
+
+ol.lowerroman {
+  list-style: lower-roman }
+
+ol.upperroman {
+  list-style: upper-roman }
+
+p.attribution {
+  text-align: right ;
+  margin-left: 50% }
+
+p.caption {
+  font-style: italic }
+
+p.credits {
+  font-style: italic ;
+  font-size: smaller }
+
+p.label {
+  white-space: nowrap }
+
+p.rubric {
+  font-weight: bold ;
+  font-size: larger ;
+  color: maroon ;
+  text-align: center }
+
+p.sidebar-title {
+  font-family: sans-serif ;
+  font-weight: bold ;
+  font-size: larger }
+
+p.sidebar-subtitle {
+  font-family: sans-serif ;
+  font-weight: bold }
+
+p.topic-title {
+  font-weight: bold }
+
+pre.address {
+  margin-bottom: 0 ;
+  margin-top: 0 ;
+  font: inherit }
+
+pre.literal-block, pre.doctest-block {
+  margin-left: 2em ;
+  margin-right: 2em }
+
+span.classifier {
+  font-family: sans-serif ;
+  font-style: oblique }
+
+span.classifier-delimiter {
+  font-family: sans-serif ;
+  font-weight: bold }
+
+span.interpreted {
+  font-family: sans-serif }
+
+span.option {
+  white-space: nowrap }
+
+span.pre {
+  white-space: pre }
+
+span.problematic {
+  color: red }
+
+span.section-subtitle {
+  /* font-size relative to parent (h1..h6 element) */
+  font-size: 80% }
+
+table.citation {
+  border-left: solid 1px gray;
+  margin-left: 1px }
+
+table.docinfo {
+  margin: 2em 4em }
+
+table.docutils {
+  margin-top: 0.5em ;
+  margin-bottom: 0.5em }
+
+table.footnote {
+  border-left: solid 1px black;
+  margin-left: 1px }
+
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
+  padding-left: 0.5em ;
+  padding-right: 0.5em ;
+  vertical-align: top }
+
+table.docutils th.field-name, table.docinfo th.docinfo-name {
+  font-weight: bold ;
+  text-align: left ;
+  white-space: nowrap ;
+  padding-left: 0 }
+
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+  font-size: 100% }
+
+ul.auto-toc {
+  list-style-type: none }
+
+</style>
+</head>
+<body>
+<div class="document" id="libbcc-a-versatile-bitcode-execution-engine-for-mobile-devices">
+<h1 class="title">libbcc: A Versatile Bitcode Execution Engine for Mobile Devices</h1>
+
+<div class="section" id="introduction">
+<h1>Introduction</h1>
+<p>libbcc is an LLVM bitcode execution engine that compiles the bitcode
+to an in-memory executable. libbcc is versatile because:</p>
+<ul class="simple">
+<li>it implements both AOT (Ahead-of-Time) and JIT (Just-in-Time)
+compilation.</li>
+<li>Android devices demand fast start-up time, small size, and high
+performance <em>at the same time</em>. libbcc attempts to address these
+design constraints.</li>
+<li>it supports on-device linking. Each device vendor can supply his or
+her own runtime bitcode library (lib*.bc) that differentiates his or
+her system. Specialization becomes ecosystem-friendly.</li>
+</ul>
+<p>libbcc provides:</p>
+<ul class="simple">
+<li>a <em>just-in-time bitcode compiler</em>, which translates the LLVM bitcode
+into machine code</li>
+<li>a <em>caching mechanism</em>, which can:<ul>
+<li>after each compilation, serialize the in-memory executable into a
+cache file.  Note that the compilation is triggered by a cache
+miss.</li>
+<li>load from the cache file upon cache-hit.</li>
+</ul>
+</li>
+</ul>
+<p>Highlights of libbcc are:</p>
+<ul>
+<li><p class="first">libbcc supports bitcode from various language frontends, such as
+Renderscript, GLSL (pixelflinger2).</p>
+</li>
+<li><p class="first">libbcc strives to balance between library size, launch time and
+steady-state performance:</p>
+<ul>
+<li><p class="first">The size of libbcc is aggressively reduced for mobile devices. We
+customize and improve upon the default Execution Engine from
+upstream. Otherwise, libbcc's execution engine can easily become
+at least 2 times bigger.</p>
+</li>
+<li><p class="first">To reduce launch time, we support caching of
+binaries. Just-in-Time compilation are oftentimes Just-too-Late,
+if the given apps are performance-sensitive. Thus, we implemented
+AOT to get the best of both worlds: Fast launch time and high
+steady-state performance.</p>
+<p>AOT is also important for projects such as NDK on LLVM with
+portability enhancement. Launch time reduction after we
+implemented AOT is signficant:</p>
+<pre class="literal-block">
+Apps          libbcc without AOT       libbcc with AOT
+              launch time in libbcc    launch time in libbcc
+App_1            1218ms                   9ms
+App_2            842ms                    4ms
+Wallpaper:
+  MagicSmoke     182ms                    3ms
+  Halo           127ms                    3ms
+Balls            149ms                    3ms
+SceneGraph       146ms                    90ms
+Model            104ms                    4ms
+Fountain         57ms                     3ms
+</pre>
+<p>AOT also masks the launching time overhead of on-device linking
+and helps it become reality.</p>
+</li>
+<li><p class="first">For steady-state performance, we enable VFP3 and aggressive
+optimizations.</p>
+</li>
+</ul>
+</li>
+<li><p class="first">Currently we disable Lazy JITting.</p>
+</li>
+</ul>
+</div>
+<div class="section" id="api">
+<h1>API</h1>
+<p><strong>Basic:</strong></p>
+<ul class="simple">
+<li><strong>bccCreateScript</strong> - Create new bcc script</li>
+<li><strong>bccRegisterSymbolCallback</strong> - Register the callback function for external
+symbol lookup</li>
+<li><strong>bccReadBC</strong> - Set the source bitcode for compilation</li>
+<li><strong>bccReadModule</strong> - Set the llvm::Module for compilation</li>
+<li><strong>bccLinkBC</strong> - Set the library bitcode for linking</li>
+<li><strong>bccPrepareExecutable</strong> - <em>deprecated</em> - Use bccPrepareExecutableEx instead</li>
+<li><strong>bccPrepareExecutableEx</strong> - Create the in-memory executable by either
+just-in-time compilation or cache loading</li>
+<li><strong>bccGetFuncAddr</strong> - Get the entry address of the function</li>
+<li><strong>bccDisposeScript</strong> - Destroy bcc script and release the resources</li>
+<li><strong>bccGetError</strong> - <em>deprecated</em> - Don't use this</li>
+</ul>
+<p><strong>Reflection:</strong></p>
+<ul class="simple">
+<li><strong>bccGetExportVarCount</strong> - Get the count of exported variables</li>
+<li><strong>bccGetExportVarList</strong> - Get the addresses of exported variables</li>
+<li><strong>bccGetExportFuncCount</strong> - Get the count of exported functions</li>
+<li><strong>bccGetExportFuncList</strong> - Get the addresses of exported functions</li>
+<li><strong>bccGetPragmaCount</strong> - Get the count of pragmas</li>
+<li><strong>bccGetPragmaList</strong> - Get the pragmas</li>
+</ul>
+<p><strong>Debug:</strong></p>
+<ul class="simple">
+<li><strong>bccGetFuncCount</strong> - Get the count of functions (including non-exported)</li>
+<li><strong>bccGetFuncInfoList</strong> - Get the function information (name, base, size)</li>
+</ul>
+</div>
+<div class="section" id="cache-file-format">
+<h1>Cache File Format</h1>
+<p>A cache file (denoted as *.oBCC) for libbcc consists of several sections:
+header, string pool, dependencies table, relocation table, exported
+variable list, exported function list, pragma list, function information
+table, and bcc context.  Every section should be aligned to a word size.
+Here is the brief description of each sections:</p>
+<ul class="simple">
+<li><strong>Header</strong> (MCO_Header) - The header of a cache file. It contains the
+magic word, version, machine integer type information (the endianness,
+the size of off_t, size_t, and ptr_t), and the size
+and offset of other sections.  The header section is guaranteed
+to be at the beginning of the cache file.</li>
+<li><strong>String Pool</strong> (MCO_StringPool) - A collection of serialized variable
+length strings.  The strp_index in the other part of the cache file
+represents the index of such string in this string pool.</li>
+<li><strong>Dependencies Table</strong> (MCO_DependencyTable) - The dependencies table.
+This table stores the resource name (or file path), the resource
+type (rather in APK or on the file system), and the SHA1 checksum.</li>
+<li><strong>Relocation Table</strong> (MCO_RelocationTable) - <em>not enabled</em></li>
+<li><strong>Exported Variable List</strong> (MCO_ExportVarList) -
+The list of the addresses of exported variables.</li>
+<li><strong>Exported Function List</strong> (MCO_ExportFuncList) -
+The list of the addresses of exported functions.</li>
+<li><strong>Pragma List</strong> (MCO_PragmaList) - The list of pragma key-value pair.</li>
+<li><strong>Function Information Table</strong> (MCO_FuncTable) - This is a table of
+function information, such as function name, function entry address,
+and function binary size.  Besides, the table should be ordered by
+function name.</li>
+<li><strong>Context</strong> - The context of the in-memory executable, including
+the code and the data.  The offset of context should aligned to
+a page size, so that we can mmap the context directly into memory.</li>
+</ul>
+<p>For furthur information, you may read <a class="reference external" href="include/bcc/bcc_cache.h">bcc_cache.h</a>,
+<a class="reference external" href="lib/bcc/CacheReader.cpp">CacheReader.cpp</a>, and
+<a class="reference external" href="lib/bcc/CacheWriter.cpp">CacheWriter.cpp</a> for details.</p>
+</div>
+<div class="section" id="jit-ed-code-calling-conventions">
+<h1>JIT'ed Code Calling Conventions</h1>
+<ol class="arabic">
+<li><p class="first">Calls from Execution Environment or from/to within script:</p>
+<p>On ARM, the first 4 arguments will go into r0, r1, r2, and r3, in that order.
+The remaining (if any) will go through stack.</p>
+<p>For ext_vec_types such as float2, a set of registers will be used. In the case
+of float2, a register pair will be used. Specifically, if float2 is the first
+argument in the function prototype, float2.x will go into r0, and float2.y,
+r1.</p>
+<p>Note: stack will be aligned to the coarsest-grained argument. In the case of
+float2 above as an argument, parameter stack will be aligned to an 8-byte
+boundary (if the sizes of other arguments are no greater than 8.)</p>
+</li>
+<li><p class="first">Calls from/to a separate compilation unit: (E.g., calls to Execution
+Environment if those runtime library callees are not compiled using LLVM.)</p>
+<p>On ARM, we use hardfp.  Note that double will be placed in a register pair.</p>
+</li>
+</ol>
+</div>
+</div>
+</body>
+</html>
diff --git a/libbcc/README.rst b/libbcc/README.rst
new file mode 100644
index 0000000..a6db1f1
--- /dev/null
+++ b/libbcc/README.rst
@@ -0,0 +1,200 @@
+===============================================================
+libbcc: A Versatile Bitcode Execution Engine for Mobile Devices
+===============================================================
+
+
+Introduction
+------------
+
+libbcc is an LLVM bitcode execution engine that compiles the bitcode
+to an in-memory executable. libbcc is versatile because:
+
+* it implements both AOT (Ahead-of-Time) and JIT (Just-in-Time)
+  compilation.
+
+* Android devices demand fast start-up time, small size, and high
+  performance *at the same time*. libbcc attempts to address these
+  design constraints.
+
+* it supports on-device linking. Each device vendor can supply his or
+  her own runtime bitcode library (lib*.bc) that differentiates his or
+  her system. Specialization becomes ecosystem-friendly.
+
+libbcc provides:
+
+* a *just-in-time bitcode compiler*, which translates the LLVM bitcode
+  into machine code
+
+* a *caching mechanism*, which can:
+
+  * after each compilation, serialize the in-memory executable into a
+    cache file.  Note that the compilation is triggered by a cache
+    miss.
+  * load from the cache file upon cache-hit.
+
+Highlights of libbcc are:
+
+* libbcc supports bitcode from various language frontends, such as
+  Renderscript, GLSL (pixelflinger2).
+
+* libbcc strives to balance between library size, launch time and
+  steady-state performance:
+
+  * The size of libbcc is aggressively reduced for mobile devices. We
+    customize and improve upon the default Execution Engine from
+    upstream. Otherwise, libbcc's execution engine can easily become
+    at least 2 times bigger.
+
+  * To reduce launch time, we support caching of
+    binaries. Just-in-Time compilation are oftentimes Just-too-Late,
+    if the given apps are performance-sensitive. Thus, we implemented
+    AOT to get the best of both worlds: Fast launch time and high
+    steady-state performance.
+
+    AOT is also important for projects such as NDK on LLVM with
+    portability enhancement. Launch time reduction after we
+    implemented AOT is signficant::
+
+
+     Apps          libbcc without AOT       libbcc with AOT
+                   launch time in libbcc    launch time in libbcc
+     App_1            1218ms                   9ms
+     App_2            842ms                    4ms
+     Wallpaper:
+       MagicSmoke     182ms                    3ms
+       Halo           127ms                    3ms
+     Balls            149ms                    3ms
+     SceneGraph       146ms                    90ms
+     Model            104ms                    4ms
+     Fountain         57ms                     3ms
+
+    AOT also masks the launching time overhead of on-device linking
+    and helps it become reality.
+
+  * For steady-state performance, we enable VFP3 and aggressive
+    optimizations.
+
+* Currently we disable Lazy JITting.
+
+
+
+API
+---
+
+**Basic:**
+
+* **bccCreateScript** - Create new bcc script
+
+* **bccRegisterSymbolCallback** - Register the callback function for external
+  symbol lookup
+
+* **bccReadBC** - Set the source bitcode for compilation
+
+* **bccReadModule** - Set the llvm::Module for compilation
+
+* **bccLinkBC** - Set the library bitcode for linking
+
+* **bccPrepareExecutable** - *deprecated* - Use bccPrepareExecutableEx instead
+
+* **bccPrepareExecutableEx** - Create the in-memory executable by either
+  just-in-time compilation or cache loading
+
+* **bccGetFuncAddr** - Get the entry address of the function
+
+* **bccDisposeScript** - Destroy bcc script and release the resources
+
+* **bccGetError** - *deprecated* - Don't use this
+
+
+**Reflection:**
+
+* **bccGetExportVarCount** - Get the count of exported variables
+
+* **bccGetExportVarList** - Get the addresses of exported variables
+
+* **bccGetExportFuncCount** - Get the count of exported functions
+
+* **bccGetExportFuncList** - Get the addresses of exported functions
+
+* **bccGetPragmaCount** - Get the count of pragmas
+
+* **bccGetPragmaList** - Get the pragmas
+
+
+**Debug:**
+
+* **bccGetFuncCount** - Get the count of functions (including non-exported)
+
+* **bccGetFuncInfoList** - Get the function information (name, base, size)
+
+
+
+Cache File Format
+-----------------
+
+A cache file (denoted as \*.oBCC) for libbcc consists of several sections:
+header, string pool, dependencies table, relocation table, exported
+variable list, exported function list, pragma list, function information
+table, and bcc context.  Every section should be aligned to a word size.
+Here is the brief description of each sections:
+
+* **Header** (MCO_Header) - The header of a cache file. It contains the
+  magic word, version, machine integer type information (the endianness,
+  the size of off_t, size_t, and ptr_t), and the size
+  and offset of other sections.  The header section is guaranteed
+  to be at the beginning of the cache file.
+
+* **String Pool** (MCO_StringPool) - A collection of serialized variable
+  length strings.  The strp_index in the other part of the cache file
+  represents the index of such string in this string pool.
+
+* **Dependencies Table** (MCO_DependencyTable) - The dependencies table.
+  This table stores the resource name (or file path), the resource
+  type (rather in APK or on the file system), and the SHA1 checksum.
+
+* **Relocation Table** (MCO_RelocationTable) - *not enabled*
+
+* **Exported Variable List** (MCO_ExportVarList) -
+  The list of the addresses of exported variables.
+
+* **Exported Function List** (MCO_ExportFuncList) -
+  The list of the addresses of exported functions.
+
+* **Pragma List** (MCO_PragmaList) - The list of pragma key-value pair.
+
+* **Function Information Table** (MCO_FuncTable) - This is a table of
+  function information, such as function name, function entry address,
+  and function binary size.  Besides, the table should be ordered by
+  function name.
+
+* **Context** - The context of the in-memory executable, including
+  the code and the data.  The offset of context should aligned to
+  a page size, so that we can mmap the context directly into memory.
+
+For furthur information, you may read `bcc_cache.h <include/bcc/bcc_cache.h>`_,
+`CacheReader.cpp <lib/bcc/CacheReader.cpp>`_, and
+`CacheWriter.cpp <lib/bcc/CacheWriter.cpp>`_ for details.
+
+
+
+JIT'ed Code Calling Conventions
+-------------------------------
+
+1. Calls from Execution Environment or from/to within script:
+
+   On ARM, the first 4 arguments will go into r0, r1, r2, and r3, in that order.
+   The remaining (if any) will go through stack.
+
+   For ext_vec_types such as float2, a set of registers will be used. In the case
+   of float2, a register pair will be used. Specifically, if float2 is the first
+   argument in the function prototype, float2.x will go into r0, and float2.y,
+   r1.
+
+   Note: stack will be aligned to the coarsest-grained argument. In the case of
+   float2 above as an argument, parameter stack will be aligned to an 8-byte
+   boundary (if the sizes of other arguments are no greater than 8.)
+
+2. Calls from/to a separate compilation unit: (E.g., calls to Execution
+   Environment if those runtime library callees are not compiled using LLVM.)
+
+   On ARM, we use hardfp.  Note that double will be placed in a register pair.
diff --git a/libbcc/bcinfo/Android.mk b/libbcc/bcinfo/Android.mk
new file mode 100644
index 0000000..46b61a7
--- /dev/null
+++ b/libbcc/bcinfo/Android.mk
@@ -0,0 +1,105 @@
+#
+# Copyright (C) 2011-2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+local_cflags_for_libbcinfo := -Wall -Wno-unused-parameter -Werror
+ifneq ($(TARGET_BUILD_VARIANT),eng)
+local_cflags_for_libbcinfo += -D__DISABLE_ASSERTS
+endif
+
+LOCAL_PATH := $(call my-dir)
+
+include frameworks/compile/slang/rs_version.mk
+local_cflags_for_libbcinfo += $(RS_VERSION_DEFINE)
+
+libbcinfo_SRC_FILES := \
+  BitcodeTranslator.cpp \
+  BitcodeWrapper.cpp \
+  MetadataExtractor.cpp
+
+libbcinfo_C_INCLUDES := \
+  $(LOCAL_PATH)/../include \
+  $(RS_ROOT_PATH) \
+  $(LOCAL_PATH)/../../slang
+
+libbcinfo_STATIC_LIBRARIES := \
+  libLLVMWrap \
+  libLLVMBitReader_2_7 \
+  libLLVMBitReader_3_0 \
+  libLLVMBitWriter_3_2
+
+LLVM_ROOT_PATH := external/llvm
+
+ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS))
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libbcinfo
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(libbcinfo_SRC_FILES)
+
+LOCAL_CFLAGS += $(local_cflags_for_libbcinfo)
+
+LOCAL_C_INCLUDES := $(libbcinfo_C_INCLUDES)
+
+LOCAL_STATIC_LIBRARIES := $(libbcinfo_STATIC_LIBRARIES)
+LOCAL_SHARED_LIBRARIES := libLLVM libcutils liblog
+
+include $(LLVM_ROOT_PATH)/llvm-device-build.mk
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(BUILD_SHARED_LIBRARY)
+endif
+
+# Don't build for unbundled branches
+ifeq (,$(TARGET_BUILD_APPS))
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libbcinfo
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MODULE_HOST_OS := darwin linux windows
+LOCAL_IS_HOST_MODULE := true
+
+LOCAL_SRC_FILES := $(libbcinfo_SRC_FILES)
+
+LOCAL_CFLAGS += $(local_cflags_for_libbcinfo)
+
+LOCAL_C_INCLUDES := $(libbcinfo_C_INCLUDES)
+
+LOCAL_STATIC_LIBRARIES += $(libbcinfo_STATIC_LIBRARIES)
+LOCAL_STATIC_LIBRARIES += libcutils liblog
+
+LOCAL_LDLIBS_darwin := -ldl -lpthread
+LOCAL_LDLIBS_linux := -ldl -lpthread
+
+include $(LOCAL_PATH)/../llvm-loadable-libbcc.mk
+
+ifneq ($(CAN_BUILD_HOST_LLVM_LOADABLE_MODULE),true)
+LOCAL_SHARED_LIBRARIES_linux += libLLVM
+endif
+LOCAL_SHARED_LIBRARIES_darwin += libLLVM
+LOCAL_SHARED_LIBRARIES_windows += libLLVM
+
+include $(LLVM_ROOT_PATH)/llvm-host-build.mk
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+endif # don't build for unbundled branches
+
+#=====================================================================
+# Include Subdirectories
+#=====================================================================
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libbcc/bcinfo/BitReader_2_7/Android.mk b/libbcc/bcinfo/BitReader_2_7/Android.mk
new file mode 100644
index 0000000..773c3c9
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_2_7/Android.mk
@@ -0,0 +1,39 @@
+LOCAL_PATH:= $(call my-dir)
+
+LLVM_ROOT_PATH := external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+
+bitcode_reader_2_7_SRC_FILES := \
+  BitcodeReader.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(bitcode_reader_2_7_SRC_FILES)
+
+LOCAL_CFLAGS += -D__HOST__
+
+LOCAL_MODULE:= libLLVMBitReader_2_7
+
+LOCAL_MODULE_HOST_OS := darwin linux windows
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS))
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(bitcode_reader_2_7_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMBitReader_2_7
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
+endif
diff --git a/libbcc/bcinfo/BitReader_2_7/BitReader.cpp b/libbcc/bcinfo/BitReader_2_7/BitReader.cpp
new file mode 100644
index 0000000..15844c0
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_2_7/BitReader.cpp
@@ -0,0 +1,88 @@
+//===-- BitReader.cpp -----------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/BitReader.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <string>
+#include <cstring>
+
+using namespace llvm;
+
+/* Builds a module from the bitcode in the specified memory buffer, returning a
+   reference to the module via the OutModule parameter. Returns 0 on success.
+   Optionally returns a human-readable error message via OutMessage. */
+LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
+                          LLVMModuleRef *OutModule, char **OutMessage) {
+  return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule,
+                                   OutMessage);
+}
+
+LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
+                                   LLVMMemoryBufferRef MemBuf,
+                                   LLVMModuleRef *OutModule,
+                                   char **OutMessage) {
+  std::string Message;
+  
+  *OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), *unwrap(ContextRef),
+                                     &Message));
+  if (!*OutModule) {
+    if (OutMessage)
+      *OutMessage = strdup(Message.c_str());
+    return 1;
+  }
+  
+  return 0;
+}
+
+/* Reads a module from the specified path, returning via the OutModule parameter
+   a module provider which performs lazy deserialization. Returns 0 on success.
+   Optionally returns a human-readable error message via OutMessage. */ 
+LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
+                                       LLVMMemoryBufferRef MemBuf,
+                                       LLVMModuleRef *OutM,
+                                       char **OutMessage) {
+  std::string Message;
+  
+  *OutM = wrap(getLazyBitcodeModule(unwrap(MemBuf), *unwrap(ContextRef),
+                                    &Message));
+  if (!*OutM) {
+    if (OutMessage)
+      *OutMessage = strdup(Message.c_str());
+    return 1;
+  }
+  
+  return 0;
+
+}
+
+LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
+                              char **OutMessage) {
+  return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
+                                       OutMessage);
+}
+
+/* Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
+LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
+                                               LLVMMemoryBufferRef MemBuf,
+                                               LLVMModuleProviderRef *OutMP,
+                                               char **OutMessage) {
+  return LLVMGetBitcodeModuleInContext(ContextRef, MemBuf,
+                                       reinterpret_cast<LLVMModuleRef*>(OutMP),
+                                       OutMessage);
+}
+
+/* Deprecated: Use LLVMGetBitcodeModule instead. */
+LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
+                                      LLVMModuleProviderRef *OutMP,
+                                      char **OutMessage) {
+  return LLVMGetBitcodeModuleProviderInContext(LLVMGetGlobalContext(), MemBuf,
+                                               OutMP, OutMessage);
+}
diff --git a/libbcc/bcinfo/BitReader_2_7/BitReader_2_7.h b/libbcc/bcinfo/BitReader_2_7/BitReader_2_7.h
new file mode 100644
index 0000000..d3b712f
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_2_7/BitReader_2_7.h
@@ -0,0 +1,65 @@
+//===- BitReader_2_7.h - Internal BitcodeReader 2.7 impl --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the BitcodeReader class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BITREADER_2_7_H
+#define BITREADER_2_7_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/GVMaterializer.h"
+#include "llvm/IR/OperandTraits.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/ErrorOr.h"
+#include <string>
+
+namespace llvm {
+  class LLVMContext;
+  class MemoryBuffer;
+  class MemoryBufferRef;
+  class Module;
+} // End llvm namespace
+
+namespace llvm_2_7 {
+
+using llvm::DiagnosticHandlerFunction;
+using llvm::LLVMContext;
+using llvm::MemoryBuffer;
+using llvm::MemoryBufferRef;
+
+
+  /// Read the header of the specified bitcode buffer and prepare for lazy
+  /// deserialization of function bodies.  If successful, this moves Buffer. On
+  /// error, this *does not* move Buffer.
+  llvm::ErrorOr<llvm::Module *>
+  getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
+                       LLVMContext &Context,
+                       const DiagnosticHandlerFunction &DiagnosticHandler = nullptr);
+
+  /// Read the header of the specified bitcode buffer and extract just the
+  /// triple information. If successful, this returns a string. On error, this
+  /// returns "".
+  std::string
+  getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context,
+                         DiagnosticHandlerFunction DiagnosticHandler = nullptr);
+
+  /// Read the specified bitcode file, returning the module.
+  llvm::ErrorOr<llvm::Module *>
+  parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
+                   const DiagnosticHandlerFunction &DiagnosticHandler = nullptr);
+} // End llvm_2_7 namespace
+
+#endif
diff --git a/libbcc/bcinfo/BitReader_2_7/BitcodeReader.cpp b/libbcc/bcinfo/BitReader_2_7/BitcodeReader.cpp
new file mode 100644
index 0000000..c66ea1c
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_2_7/BitcodeReader.cpp
@@ -0,0 +1,3545 @@
+//===- BitcodeReader.cpp - Internal BitcodeReader implementation ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the BitcodeReader class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "BitReader_2_7.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/AutoUpgrade.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/GVMaterializer.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/OperandTraits.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+using namespace llvm_2_7;
+
+#define METADATA_NODE_2_7             2
+#define METADATA_FN_NODE_2_7          3
+#define METADATA_NAMED_NODE_2_7       5
+#define METADATA_ATTACHMENT_2_7       7
+#define FUNC_CODE_INST_UNWIND_2_7     14
+#define FUNC_CODE_INST_MALLOC_2_7     17
+#define FUNC_CODE_INST_FREE_2_7       18
+#define FUNC_CODE_INST_STORE_2_7      21
+#define FUNC_CODE_INST_CALL_2_7       22
+#define FUNC_CODE_INST_GETRESULT_2_7  25
+#define FUNC_CODE_DEBUG_LOC_2_7       32
+
+#define TYPE_BLOCK_ID_OLD_3_0         10
+#define TYPE_SYMTAB_BLOCK_ID_OLD_3_0  13
+#define TYPE_CODE_STRUCT_OLD_3_0      10
+
+namespace {
+
+  void StripDebugInfoOfFunction(Module* M, const char* name) {
+    if (Function* FuncStart = M->getFunction(name)) {
+      while (!FuncStart->use_empty()) {
+        cast<CallInst>(*FuncStart->use_begin())->eraseFromParent();
+      }
+      FuncStart->eraseFromParent();
+    }
+  }
+
+  /// This function strips all debug info intrinsics, except for llvm.dbg.declare.
+  /// If an llvm.dbg.declare intrinsic is invalid, then this function simply
+  /// strips that use.
+  void CheckDebugInfoIntrinsics(Module *M) {
+    StripDebugInfoOfFunction(M, "llvm.dbg.func.start");
+    StripDebugInfoOfFunction(M, "llvm.dbg.stoppoint");
+    StripDebugInfoOfFunction(M, "llvm.dbg.region.start");
+    StripDebugInfoOfFunction(M, "llvm.dbg.region.end");
+
+    if (Function *Declare = M->getFunction("llvm.dbg.declare")) {
+      if (!Declare->use_empty()) {
+        DbgDeclareInst *DDI = cast<DbgDeclareInst>(*Declare->use_begin());
+        if (!isa<MDNode>(ValueAsMetadata::get(DDI->getArgOperand(0))) ||
+            !isa<MDNode>(ValueAsMetadata::get(DDI->getArgOperand(1)))) {
+          while (!Declare->use_empty()) {
+            CallInst *CI = cast<CallInst>(*Declare->use_begin());
+            CI->eraseFromParent();
+          }
+          Declare->eraseFromParent();
+        }
+      }
+    }
+  }
+
+//===----------------------------------------------------------------------===//
+//                          BitcodeReaderValueList Class
+//===----------------------------------------------------------------------===//
+
+class BitcodeReaderValueList {
+  std::vector<WeakVH> ValuePtrs;
+
+  /// ResolveConstants - As we resolve forward-referenced constants, we add
+  /// information about them to this vector.  This allows us to resolve them in
+  /// bulk instead of resolving each reference at a time.  See the code in
+  /// ResolveConstantForwardRefs for more information about this.
+  ///
+  /// The key of this vector is the placeholder constant, the value is the slot
+  /// number that holds the resolved value.
+  typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
+  ResolveConstantsTy ResolveConstants;
+  LLVMContext &Context;
+public:
+  explicit BitcodeReaderValueList(LLVMContext &C) : Context(C) {}
+  ~BitcodeReaderValueList() {
+    assert(ResolveConstants.empty() && "Constants not resolved?");
+  }
+
+  // vector compatibility methods
+  unsigned size() const { return ValuePtrs.size(); }
+  void resize(unsigned N) { ValuePtrs.resize(N); }
+  void push_back(Value *V) {
+    ValuePtrs.push_back(V);
+  }
+
+  void clear() {
+    assert(ResolveConstants.empty() && "Constants not resolved?");
+    ValuePtrs.clear();
+  }
+
+  Value *operator[](unsigned i) const {
+    assert(i < ValuePtrs.size());
+    return ValuePtrs[i];
+  }
+
+  Value *back() const { return ValuePtrs.back(); }
+    void pop_back() { ValuePtrs.pop_back(); }
+  bool empty() const { return ValuePtrs.empty(); }
+  void shrinkTo(unsigned N) {
+    assert(N <= size() && "Invalid shrinkTo request!");
+    ValuePtrs.resize(N);
+  }
+
+  Constant *getConstantFwdRef(unsigned Idx, Type *Ty);
+  Value *getValueFwdRef(unsigned Idx, Type *Ty);
+
+  void AssignValue(Value *V, unsigned Idx);
+
+  /// ResolveConstantForwardRefs - Once all constants are read, this method bulk
+  /// resolves any forward references.
+  void ResolveConstantForwardRefs();
+};
+
+
+//===----------------------------------------------------------------------===//
+//                          BitcodeReaderMDValueList Class
+//===----------------------------------------------------------------------===//
+
+class BitcodeReaderMDValueList {
+  unsigned NumFwdRefs;
+  bool AnyFwdRefs;
+  std::vector<TrackingMDRef> MDValuePtrs;
+
+  LLVMContext &Context;
+public:
+  explicit BitcodeReaderMDValueList(LLVMContext &C)
+      : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {}
+
+  // vector compatibility methods
+  unsigned size() const       { return MDValuePtrs.size(); }
+  void resize(unsigned N)     { MDValuePtrs.resize(N); }
+  void push_back(Metadata *MD) { MDValuePtrs.emplace_back(MD); }
+  void clear()                { MDValuePtrs.clear();  }
+  Metadata *back() const      { return MDValuePtrs.back(); }
+  void pop_back()             { MDValuePtrs.pop_back(); }
+  bool empty() const          { return MDValuePtrs.empty(); }
+
+  Metadata *operator[](unsigned i) const {
+    assert(i < MDValuePtrs.size());
+    return MDValuePtrs[i];
+  }
+
+  void shrinkTo(unsigned N) {
+    assert(N <= size() && "Invalid shrinkTo request!");
+    MDValuePtrs.resize(N);
+  }
+
+  Metadata *getValueFwdRef(unsigned Idx);
+  void AssignValue(Metadata *MD, unsigned Idx);
+  void tryToResolveCycles();
+};
+
+class BitcodeReader : public GVMaterializer {
+  LLVMContext &Context;
+  DiagnosticHandlerFunction DiagnosticHandler;
+  Module *TheModule;
+  std::unique_ptr<MemoryBuffer> Buffer;
+  std::unique_ptr<BitstreamReader> StreamFile;
+  BitstreamCursor Stream;
+  std::unique_ptr<DataStreamer> LazyStreamer;
+  uint64_t NextUnreadBit;
+  bool SeenValueSymbolTable;
+
+  std::vector<Type*> TypeList;
+  BitcodeReaderValueList ValueList;
+  BitcodeReaderMDValueList MDValueList;
+  SmallVector<Instruction *, 64> InstructionList;
+
+  std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
+  std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
+
+  /// MAttributes - The set of attributes by index.  Index zero in the
+  /// file is for null, and is thus not represented here.  As such all indices
+  /// are off by one.
+  std::vector<AttributeSet> MAttributes;
+
+  /// \brief The set of attribute groups.
+  std::map<unsigned, AttributeSet> MAttributeGroups;
+
+  /// FunctionBBs - While parsing a function body, this is a list of the basic
+  /// blocks for the function.
+  std::vector<BasicBlock*> FunctionBBs;
+
+  // When reading the module header, this list is populated with functions that
+  // have bodies later in the file.
+  std::vector<Function*> FunctionsWithBodies;
+
+  // When intrinsic functions are encountered which require upgrading they are
+  // stored here with their replacement function.
+  typedef std::vector<std::pair<Function*, Function*> > UpgradedIntrinsicMap;
+  UpgradedIntrinsicMap UpgradedIntrinsics;
+
+  // Map the bitcode's custom MDKind ID to the Module's MDKind ID.
+  DenseMap<unsigned, unsigned> MDKindMap;
+
+  // Several operations happen after the module header has been read, but
+  // before function bodies are processed. This keeps track of whether
+  // we've done this yet.
+  bool SeenFirstFunctionBody;
+
+  /// DeferredFunctionInfo - When function bodies are initially scanned, this
+  /// map contains info about where to find deferred function body in the
+  /// stream.
+  DenseMap<Function*, uint64_t> DeferredFunctionInfo;
+
+  /// BlockAddrFwdRefs - These are blockaddr references to basic blocks.  These
+  /// are resolved lazily when functions are loaded.
+  typedef std::pair<unsigned, GlobalVariable*> BlockAddrRefTy;
+  DenseMap<Function*, std::vector<BlockAddrRefTy> > BlockAddrFwdRefs;
+
+  /// LLVM2_7MetadataDetected - True if metadata produced by LLVM 2.7 or
+  /// earlier was detected, in which case we behave slightly differently,
+  /// for compatibility.
+  /// FIXME: Remove in LLVM 3.0.
+  bool LLVM2_7MetadataDetected;
+  static const std::error_category &BitcodeErrorCategory();
+
+public:
+  std::error_code Error(BitcodeError E, const Twine &Message);
+  std::error_code Error(BitcodeError E);
+  std::error_code Error(const Twine &Message);
+
+  explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
+                         DiagnosticHandlerFunction DiagnosticHandler);
+  ~BitcodeReader() { FreeState(); }
+
+  void FreeState();
+
+  void releaseBuffer();
+
+  bool isDematerializable(const GlobalValue *GV) const;
+  std::error_code materialize(GlobalValue *GV) override;
+  std::error_code materializeModule() override;
+  std::vector<StructType *> getIdentifiedStructTypes() const override;
+  void dematerialize(GlobalValue *GV);
+
+  /// @brief Main interface to parsing a bitcode buffer.
+  /// @returns true if an error occurred.
+  std::error_code ParseBitcodeInto(Module *M);
+
+  /// @brief Cheap mechanism to just extract module triple
+  /// @returns true if an error occurred.
+  llvm::ErrorOr<std::string> parseTriple();
+
+  static uint64_t decodeSignRotatedValue(uint64_t V);
+
+  /// Materialize any deferred Metadata block.
+  std::error_code materializeMetadata() override;
+
+  void setStripDebugInfo() override;
+
+private:
+  std::vector<StructType *> IdentifiedStructTypes;
+  StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name);
+  StructType *createIdentifiedStructType(LLVMContext &Context);
+
+  Type *getTypeByID(unsigned ID);
+  Type *getTypeByIDOrNull(unsigned ID);
+  Value *getFnValueByID(unsigned ID, Type *Ty) {
+    if (Ty && Ty->isMetadataTy())
+      return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID));
+    return ValueList.getValueFwdRef(ID, Ty);
+  }
+  Metadata *getFnMetadataByID(unsigned ID) {
+    return MDValueList.getValueFwdRef(ID);
+  }
+  BasicBlock *getBasicBlock(unsigned ID) const {
+    if (ID >= FunctionBBs.size()) return nullptr; // Invalid ID
+    return FunctionBBs[ID];
+  }
+  AttributeSet getAttributes(unsigned i) const {
+    if (i-1 < MAttributes.size())
+      return MAttributes[i-1];
+    return AttributeSet();
+  }
+
+  /// getValueTypePair - Read a value/type pair out of the specified record from
+  /// slot 'Slot'.  Increment Slot past the number of slots used in the record.
+  /// Return true on failure.
+  bool getValueTypePair(SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
+                        unsigned InstNum, Value *&ResVal) {
+    if (Slot == Record.size()) return true;
+    unsigned ValNo = (unsigned)Record[Slot++];
+    if (ValNo < InstNum) {
+      // If this is not a forward reference, just return the value we already
+      // have.
+      ResVal = getFnValueByID(ValNo, nullptr);
+      return ResVal == nullptr;
+    } else if (Slot == Record.size()) {
+      return true;
+    }
+
+    unsigned TypeNo = (unsigned)Record[Slot++];
+    ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
+    return ResVal == nullptr;
+  }
+  bool getValue(SmallVector<uint64_t, 64> &Record, unsigned &Slot,
+                Type *Ty, Value *&ResVal) {
+    if (Slot == Record.size()) return true;
+    unsigned ValNo = (unsigned)Record[Slot++];
+    ResVal = getFnValueByID(ValNo, Ty);
+    return ResVal == 0;
+  }
+
+
+  std::error_code ParseModule(bool Resume);
+  std::error_code ParseAttributeBlock();
+  std::error_code ParseTypeTable();
+  std::error_code ParseOldTypeTable();         // FIXME: Remove in LLVM 3.1
+  std::error_code ParseTypeTableBody();
+
+  std::error_code ParseOldTypeSymbolTable();   // FIXME: Remove in LLVM 3.1
+  std::error_code ParseValueSymbolTable();
+  std::error_code ParseConstants();
+  std::error_code RememberAndSkipFunctionBody();
+  std::error_code ParseFunctionBody(Function *F);
+  std::error_code GlobalCleanup();
+  std::error_code ResolveGlobalAndAliasInits();
+  std::error_code ParseMetadata();
+  std::error_code ParseMetadataAttachment();
+  llvm::ErrorOr<std::string> parseModuleTriple();
+  std::error_code InitStream();
+  std::error_code InitStreamFromBuffer();
+  std::error_code InitLazyStream();
+};
+} // end anonymous namespace
+
+static std::error_code Error(const DiagnosticHandlerFunction &DiagnosticHandler,
+                             std::error_code EC, const Twine &Message) {
+  BitcodeDiagnosticInfo DI(EC, DS_Error, Message);
+  DiagnosticHandler(DI);
+  return EC;
+}
+
+static std::error_code Error(const DiagnosticHandlerFunction &DiagnosticHandler,
+                             std::error_code EC) {
+  return Error(DiagnosticHandler, EC, EC.message());
+}
+
+std::error_code BitcodeReader::Error(BitcodeError E, const Twine &Message) {
+  return ::Error(DiagnosticHandler, make_error_code(E), Message);
+}
+
+std::error_code BitcodeReader::Error(const Twine &Message) {
+  return ::Error(DiagnosticHandler,
+                 make_error_code(BitcodeError::CorruptedBitcode), Message);
+}
+
+std::error_code BitcodeReader::Error(BitcodeError E) {
+  return ::Error(DiagnosticHandler, make_error_code(E));
+}
+
+static DiagnosticHandlerFunction getDiagHandler(DiagnosticHandlerFunction F,
+                                                LLVMContext &C) {
+  if (F)
+    return F;
+  return [&C](const DiagnosticInfo &DI) { C.diagnose(DI); };
+}
+
+BitcodeReader::BitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
+                             DiagnosticHandlerFunction DiagnosticHandler)
+    : Context(C), DiagnosticHandler(getDiagHandler(DiagnosticHandler, C)),
+      TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr),
+      NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
+      MDValueList(C), SeenFirstFunctionBody(false),
+      LLVM2_7MetadataDetected(false) {}
+
+
+void BitcodeReader::FreeState() {
+  Buffer = nullptr;
+  std::vector<Type*>().swap(TypeList);
+  ValueList.clear();
+  MDValueList.clear();
+
+  std::vector<AttributeSet>().swap(MAttributes);
+  std::vector<BasicBlock*>().swap(FunctionBBs);
+  std::vector<Function*>().swap(FunctionsWithBodies);
+  DeferredFunctionInfo.clear();
+  MDKindMap.clear();
+}
+
+//===----------------------------------------------------------------------===//
+//  Helper functions to implement forward reference resolution, etc.
+//===----------------------------------------------------------------------===//
+
+/// ConvertToString - Convert a string from a record into an std::string, return
+/// true on failure.
+template<typename StrTy>
+static bool ConvertToString(ArrayRef<uint64_t> Record, unsigned Idx,
+                            StrTy &Result) {
+  if (Idx > Record.size())
+    return true;
+
+  for (unsigned i = Idx, e = Record.size(); i != e; ++i)
+    Result += (char)Record[i];
+  return false;
+}
+
+static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
+  switch (Val) {
+  default: // Map unknown/new linkages to external
+  case 0:
+    return GlobalValue::ExternalLinkage;
+  case 1:
+    return GlobalValue::WeakAnyLinkage;
+  case 2:
+    return GlobalValue::AppendingLinkage;
+  case 3:
+    return GlobalValue::InternalLinkage;
+  case 4:
+    return GlobalValue::LinkOnceAnyLinkage;
+  case 5:
+    return GlobalValue::ExternalLinkage; // Obsolete DLLImportLinkage
+  case 6:
+    return GlobalValue::ExternalLinkage; // Obsolete DLLExportLinkage
+  case 7:
+    return GlobalValue::ExternalWeakLinkage;
+  case 8:
+    return GlobalValue::CommonLinkage;
+  case 9:
+    return GlobalValue::PrivateLinkage;
+  case 10:
+    return GlobalValue::WeakODRLinkage;
+  case 11:
+    return GlobalValue::LinkOnceODRLinkage;
+  case 12:
+    return GlobalValue::AvailableExternallyLinkage;
+  case 13:
+    return GlobalValue::PrivateLinkage; // Obsolete LinkerPrivateLinkage
+  case 14:
+    return GlobalValue::ExternalWeakLinkage; // Obsolete LinkerPrivateWeakLinkage
+  //ANDROID: convert LinkOnceODRAutoHideLinkage -> LinkOnceODRLinkage
+  case 15:
+    return GlobalValue::LinkOnceODRLinkage;
+  }
+}
+
+static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) {
+  switch (Val) {
+  default: // Map unknown visibilities to default.
+  case 0: return GlobalValue::DefaultVisibility;
+  case 1: return GlobalValue::HiddenVisibility;
+  case 2: return GlobalValue::ProtectedVisibility;
+  }
+}
+
+static GlobalVariable::ThreadLocalMode GetDecodedThreadLocalMode(unsigned Val) {
+  switch (Val) {
+    case 0: return GlobalVariable::NotThreadLocal;
+    default: // Map unknown non-zero value to general dynamic.
+    case 1: return GlobalVariable::GeneralDynamicTLSModel;
+    case 2: return GlobalVariable::LocalDynamicTLSModel;
+    case 3: return GlobalVariable::InitialExecTLSModel;
+    case 4: return GlobalVariable::LocalExecTLSModel;
+  }
+}
+
+static int GetDecodedCastOpcode(unsigned Val) {
+  switch (Val) {
+  default: return -1;
+  case bitc::CAST_TRUNC   : return Instruction::Trunc;
+  case bitc::CAST_ZEXT    : return Instruction::ZExt;
+  case bitc::CAST_SEXT    : return Instruction::SExt;
+  case bitc::CAST_FPTOUI  : return Instruction::FPToUI;
+  case bitc::CAST_FPTOSI  : return Instruction::FPToSI;
+  case bitc::CAST_UITOFP  : return Instruction::UIToFP;
+  case bitc::CAST_SITOFP  : return Instruction::SIToFP;
+  case bitc::CAST_FPTRUNC : return Instruction::FPTrunc;
+  case bitc::CAST_FPEXT   : return Instruction::FPExt;
+  case bitc::CAST_PTRTOINT: return Instruction::PtrToInt;
+  case bitc::CAST_INTTOPTR: return Instruction::IntToPtr;
+  case bitc::CAST_BITCAST : return Instruction::BitCast;
+  }
+}
+static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) {
+  switch (Val) {
+  default: return -1;
+  case bitc::BINOP_ADD:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add;
+  case bitc::BINOP_SUB:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub;
+  case bitc::BINOP_MUL:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul;
+  case bitc::BINOP_UDIV: return Instruction::UDiv;
+  case bitc::BINOP_SDIV:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv;
+  case bitc::BINOP_UREM: return Instruction::URem;
+  case bitc::BINOP_SREM:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FRem : Instruction::SRem;
+  case bitc::BINOP_SHL:  return Instruction::Shl;
+  case bitc::BINOP_LSHR: return Instruction::LShr;
+  case bitc::BINOP_ASHR: return Instruction::AShr;
+  case bitc::BINOP_AND:  return Instruction::And;
+  case bitc::BINOP_OR:   return Instruction::Or;
+  case bitc::BINOP_XOR:  return Instruction::Xor;
+  }
+}
+
+namespace llvm {
+namespace {
+  /// @brief A class for maintaining the slot number definition
+  /// as a placeholder for the actual definition for forward constants defs.
+  class ConstantPlaceHolder : public ConstantExpr {
+    void operator=(const ConstantPlaceHolder &) = delete;
+  public:
+    // allocate space for exactly one operand
+    void *operator new(size_t s) {
+      return User::operator new(s, 1);
+    }
+    explicit ConstantPlaceHolder(Type *Ty, LLVMContext& Context)
+      : ConstantExpr(Ty, Instruction::UserOp1, &Op<0>(), 1) {
+      Op<0>() = UndefValue::get(Type::getInt32Ty(Context));
+    }
+
+    /// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
+    static bool classof(const Value *V) {
+      return isa<ConstantExpr>(V) &&
+             cast<ConstantExpr>(V)->getOpcode() == Instruction::UserOp1;
+    }
+
+
+    /// Provide fast operand accessors
+    DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+  };
+}
+
+// FIXME: can we inherit this from ConstantExpr?
+template <>
+struct OperandTraits<ConstantPlaceHolder> :
+  public FixedNumOperandTraits<ConstantPlaceHolder, 1> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
+}
+
+
+void BitcodeReaderValueList::AssignValue(Value *V, unsigned Idx) {
+  if (Idx == size()) {
+    push_back(V);
+    return;
+  }
+
+  if (Idx >= size())
+    resize(Idx+1);
+
+  WeakVH &OldV = ValuePtrs[Idx];
+  if (!OldV) {
+    OldV = V;
+    return;
+  }
+
+  // Handle constants and non-constants (e.g. instrs) differently for
+  // efficiency.
+  if (Constant *PHC = dyn_cast<Constant>(&*OldV)) {
+    ResolveConstants.push_back(std::make_pair(PHC, Idx));
+    OldV = V;
+  } else {
+    // If there was a forward reference to this value, replace it.
+    Value *PrevVal = OldV;
+    OldV->replaceAllUsesWith(V);
+    delete PrevVal;
+  }
+}
+
+
+Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
+                                                    Type *Ty) {
+  if (Idx >= size())
+    resize(Idx + 1);
+
+  if (Value *V = ValuePtrs[Idx]) {
+    assert(Ty == V->getType() && "Type mismatch in constant table!");
+    return cast<Constant>(V);
+  }
+
+  // Create and return a placeholder, which will later be RAUW'd.
+  Constant *C = new ConstantPlaceHolder(Ty, Context);
+  ValuePtrs[Idx] = C;
+  return C;
+}
+
+Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
+  if (Idx >= size())
+    resize(Idx + 1);
+
+  if (Value *V = ValuePtrs[Idx]) {
+    assert((!Ty || Ty == V->getType()) && "Type mismatch in value table!");
+    return V;
+  }
+
+  // No type specified, must be invalid reference.
+  if (!Ty) return nullptr;
+
+  // Create and return a placeholder, which will later be RAUW'd.
+  Value *V = new Argument(Ty);
+  ValuePtrs[Idx] = V;
+  return V;
+}
+
+/// ResolveConstantForwardRefs - Once all constants are read, this method bulk
+/// resolves any forward references.  The idea behind this is that we sometimes
+/// get constants (such as large arrays) which reference *many* forward ref
+/// constants.  Replacing each of these causes a lot of thrashing when
+/// building/reuniquing the constant.  Instead of doing this, we look at all the
+/// uses and rewrite all the place holders at once for any constant that uses
+/// a placeholder.
+void BitcodeReaderValueList::ResolveConstantForwardRefs() {
+  // Sort the values by-pointer so that they are efficient to look up with a
+  // binary search.
+  std::sort(ResolveConstants.begin(), ResolveConstants.end());
+
+  SmallVector<Constant*, 64> NewOps;
+
+  while (!ResolveConstants.empty()) {
+    Value *RealVal = operator[](ResolveConstants.back().second);
+    Constant *Placeholder = ResolveConstants.back().first;
+    ResolveConstants.pop_back();
+
+    // Loop over all users of the placeholder, updating them to reference the
+    // new value.  If they reference more than one placeholder, update them all
+    // at once.
+    while (!Placeholder->use_empty()) {
+      auto UI = Placeholder->user_begin();
+      User *U = *UI;
+
+      // If the using object isn't uniqued, just update the operands.  This
+      // handles instructions and initializers for global variables.
+      if (!isa<Constant>(U) || isa<GlobalValue>(U)) {
+        UI.getUse().set(RealVal);
+        continue;
+      }
+
+      // Otherwise, we have a constant that uses the placeholder.  Replace that
+      // constant with a new constant that has *all* placeholder uses updated.
+      Constant *UserC = cast<Constant>(U);
+      for (User::op_iterator I = UserC->op_begin(), E = UserC->op_end();
+           I != E; ++I) {
+        Value *NewOp;
+        if (!isa<ConstantPlaceHolder>(*I)) {
+          // Not a placeholder reference.
+          NewOp = *I;
+        } else if (*I == Placeholder) {
+          // Common case is that it just references this one placeholder.
+          NewOp = RealVal;
+        } else {
+          // Otherwise, look up the placeholder in ResolveConstants.
+          ResolveConstantsTy::iterator It =
+            std::lower_bound(ResolveConstants.begin(), ResolveConstants.end(),
+                             std::pair<Constant*, unsigned>(cast<Constant>(*I),
+                                                            0));
+          assert(It != ResolveConstants.end() && It->first == *I);
+          NewOp = operator[](It->second);
+        }
+
+        NewOps.push_back(cast<Constant>(NewOp));
+      }
+
+      // Make the new constant.
+      Constant *NewC;
+      if (ConstantArray *UserCA = dyn_cast<ConstantArray>(UserC)) {
+        NewC = ConstantArray::get(UserCA->getType(), NewOps);
+      } else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) {
+        NewC = ConstantStruct::get(UserCS->getType(), NewOps);
+      } else if (isa<ConstantVector>(UserC)) {
+        NewC = ConstantVector::get(NewOps);
+      } else {
+        assert(isa<ConstantExpr>(UserC) && "Must be a ConstantExpr.");
+        NewC = cast<ConstantExpr>(UserC)->getWithOperands(NewOps);
+      }
+
+      UserC->replaceAllUsesWith(NewC);
+      UserC->destroyConstant();
+      NewOps.clear();
+    }
+
+    // Update all ValueHandles, they should be the only users at this point.
+    Placeholder->replaceAllUsesWith(RealVal);
+    delete Placeholder;
+  }
+}
+
+void BitcodeReaderMDValueList::AssignValue(Metadata *MD, unsigned Idx) {
+  if (Idx == size()) {
+    push_back(MD);
+    return;
+  }
+
+  if (Idx >= size())
+    resize(Idx+1);
+
+  TrackingMDRef &OldMD = MDValuePtrs[Idx];
+  if (!OldMD) {
+    OldMD.reset(MD);
+    return;
+  }
+
+  // If there was a forward reference to this value, replace it.
+  TempMDTuple PrevMD(cast<MDTuple>(OldMD.get()));
+  PrevMD->replaceAllUsesWith(MD);
+  --NumFwdRefs;
+}
+
+Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
+  if (Idx >= size())
+    resize(Idx + 1);
+
+  if (Metadata *MD = MDValuePtrs[Idx])
+    return MD;
+
+  // Create and return a placeholder, which will later be RAUW'd.
+  AnyFwdRefs = true;
+  ++NumFwdRefs;
+  Metadata *MD = MDNode::getTemporary(Context, None).release();
+  MDValuePtrs[Idx].reset(MD);
+  return MD;
+}
+
+void BitcodeReaderMDValueList::tryToResolveCycles() {
+  if (!AnyFwdRefs)
+    // Nothing to do.
+    return;
+
+  if (NumFwdRefs)
+    // Still forward references... can't resolve cycles.
+    return;
+
+  // Resolve any cycles.
+  for (auto &MD : MDValuePtrs) {
+    auto *N = dyn_cast_or_null<MDNode>(MD);
+    if (!N)
+      continue;
+
+    assert(!N->isTemporary() && "Unexpected forward reference");
+    N->resolveCycles();
+  }
+}
+
+Type *BitcodeReader::getTypeByID(unsigned ID) {
+  // The type table size is always specified correctly.
+  if (ID >= TypeList.size())
+    return nullptr;
+
+  if (Type *Ty = TypeList[ID])
+    return Ty;
+
+  // If we have a forward reference, the only possible case is when it is to a
+  // named struct.  Just create a placeholder for now.
+  return TypeList[ID] = createIdentifiedStructType(Context);
+}
+
+StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context,
+                                                      StringRef Name) {
+  auto *Ret = StructType::create(Context, Name);
+  IdentifiedStructTypes.push_back(Ret);
+  return Ret;
+}
+
+StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context) {
+  auto *Ret = StructType::create(Context);
+  IdentifiedStructTypes.push_back(Ret);
+  return Ret;
+}
+
+
+/// FIXME: Remove in LLVM 3.1, only used by ParseOldTypeTable.
+Type *BitcodeReader::getTypeByIDOrNull(unsigned ID) {
+  if (ID >= TypeList.size())
+    TypeList.resize(ID+1);
+
+  return TypeList[ID];
+}
+
+//===----------------------------------------------------------------------===//
+//  Functions for parsing blocks from the bitcode file
+//===----------------------------------------------------------------------===//
+
+
+/// \brief This fills an AttrBuilder object with the LLVM attributes that have
+/// been decoded from the given integer. This function must stay in sync with
+/// 'encodeLLVMAttributesForBitcode'.
+static void decodeLLVMAttributesForBitcode(AttrBuilder &B,
+                                           uint64_t EncodedAttrs) {
+  // FIXME: Remove in 4.0.
+
+  // The alignment is stored as a 16-bit raw value from bits 31--16.  We shift
+  // the bits above 31 down by 11 bits.
+  unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16;
+  assert((!Alignment || isPowerOf2_32(Alignment)) &&
+         "Alignment must be a power of two.");
+
+  if (Alignment)
+    B.addAlignmentAttr(Alignment);
+  B.addRawValue(((EncodedAttrs & (0xfffffULL << 32)) >> 11) |
+                (EncodedAttrs & 0xffff));
+}
+
+std::error_code BitcodeReader::ParseAttributeBlock() {
+  if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID))
+    return Error("Invalid record");
+
+  if (!MAttributes.empty())
+    return Error("Invalid multiple blocks");
+
+  SmallVector<uint64_t, 64> Record;
+
+  SmallVector<AttributeSet, 8> Attrs;
+
+  // Read all the records.
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return std::error_code();
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a record.
+    Record.clear();
+    switch (Stream.readRecord(Entry.ID, Record)) {
+    default:  // Default behavior: ignore.
+      break;
+    case bitc::PARAMATTR_CODE_ENTRY_OLD: { // ENTRY: [paramidx0, attr0, ...]
+      if (Record.size() & 1)
+        return Error("Invalid record");
+
+      for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
+        AttrBuilder B;
+        decodeLLVMAttributesForBitcode(B, Record[i+1]);
+        Attrs.push_back(AttributeSet::get(Context, Record[i], B));
+      }
+
+      MAttributes.push_back(AttributeSet::get(Context, Attrs));
+      Attrs.clear();
+      break;
+    }
+    case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [attrgrp0, attrgrp1, ...]
+      for (unsigned i = 0, e = Record.size(); i != e; ++i)
+        Attrs.push_back(MAttributeGroups[Record[i]]);
+
+      MAttributes.push_back(AttributeSet::get(Context, Attrs));
+      Attrs.clear();
+      break;
+    }
+    }
+  }
+}
+
+
+std::error_code BitcodeReader::ParseTypeTable() {
+  if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW))
+    return Error("Invalid record");
+
+  return ParseTypeTableBody();
+}
+
+std::error_code BitcodeReader::ParseTypeTableBody() {
+  if (!TypeList.empty())
+    return Error("Invalid multiple blocks");
+
+  SmallVector<uint64_t, 64> Record;
+  unsigned NumRecords = 0;
+
+  SmallString<64> TypeName;
+
+  // Read all the records for this type table.
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      if (NumRecords != TypeList.size())
+        return Error("Malformed block");
+      return std::error_code();
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a record.
+    Record.clear();
+    Type *ResultTy = nullptr;
+    switch (Stream.readRecord(Entry.ID, Record)) {
+    default:
+      return Error("Invalid value");
+    case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries]
+      // TYPE_CODE_NUMENTRY contains a count of the number of types in the
+      // type list.  This allows us to reserve space.
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      TypeList.resize(Record[0]);
+      continue;
+    case bitc::TYPE_CODE_VOID:      // VOID
+      ResultTy = Type::getVoidTy(Context);
+      break;
+    case bitc::TYPE_CODE_HALF:     // HALF
+      ResultTy = Type::getHalfTy(Context);
+      break;
+    case bitc::TYPE_CODE_FLOAT:     // FLOAT
+      ResultTy = Type::getFloatTy(Context);
+      break;
+    case bitc::TYPE_CODE_DOUBLE:    // DOUBLE
+      ResultTy = Type::getDoubleTy(Context);
+      break;
+    case bitc::TYPE_CODE_X86_FP80:  // X86_FP80
+      ResultTy = Type::getX86_FP80Ty(Context);
+      break;
+    case bitc::TYPE_CODE_FP128:     // FP128
+      ResultTy = Type::getFP128Ty(Context);
+      break;
+    case bitc::TYPE_CODE_PPC_FP128: // PPC_FP128
+      ResultTy = Type::getPPC_FP128Ty(Context);
+      break;
+    case bitc::TYPE_CODE_LABEL:     // LABEL
+      ResultTy = Type::getLabelTy(Context);
+      break;
+    case bitc::TYPE_CODE_METADATA:  // METADATA
+      ResultTy = Type::getMetadataTy(Context);
+      break;
+    case bitc::TYPE_CODE_X86_MMX:   // X86_MMX
+      ResultTy = Type::getX86_MMXTy(Context);
+      break;
+    case bitc::TYPE_CODE_INTEGER:   // INTEGER: [width]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+
+      ResultTy = IntegerType::get(Context, Record[0]);
+      break;
+    case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
+                                    //          [pointee type, address space]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      unsigned AddressSpace = 0;
+      if (Record.size() == 2)
+        AddressSpace = Record[1];
+      ResultTy = getTypeByID(Record[0]);
+      if (!ResultTy)
+        return Error("Invalid type");
+      ResultTy = PointerType::get(ResultTy, AddressSpace);
+      break;
+    }
+    case bitc::TYPE_CODE_FUNCTION_OLD: {
+      // FIXME: attrid is dead, remove it in LLVM 4.0
+      // FUNCTION: [vararg, attrid, retty, paramty x N]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      SmallVector<Type*, 8> ArgTys;
+      for (unsigned i = 3, e = Record.size(); i != e; ++i) {
+        if (Type *T = getTypeByID(Record[i]))
+          ArgTys.push_back(T);
+        else
+          break;
+      }
+
+      ResultTy = getTypeByID(Record[2]);
+      if (!ResultTy || ArgTys.size() < Record.size()-3)
+        return Error("Invalid type");
+
+      ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
+      break;
+    }
+    case bitc::TYPE_CODE_STRUCT_ANON: {  // STRUCT: [ispacked, eltty x N]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      SmallVector<Type*, 8> EltTys;
+      for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+        if (Type *T = getTypeByID(Record[i]))
+          EltTys.push_back(T);
+        else
+          break;
+      }
+      if (EltTys.size() != Record.size()-1)
+        return Error("Invalid type");
+      ResultTy = StructType::get(Context, EltTys, Record[0]);
+      break;
+    }
+    case bitc::TYPE_CODE_STRUCT_NAME:   // STRUCT_NAME: [strchr x N]
+      if (ConvertToString(Record, 0, TypeName))
+        return Error("Invalid record");
+      continue;
+
+    case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+
+      if (NumRecords >= TypeList.size())
+        return Error("Invalid TYPE table");
+
+      // Check to see if this was forward referenced, if so fill in the temp.
+      StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
+      if (Res) {
+        Res->setName(TypeName);
+        TypeList[NumRecords] = nullptr;
+      } else  // Otherwise, create a new struct.
+        Res = createIdentifiedStructType(Context, TypeName);
+      TypeName.clear();
+
+      SmallVector<Type*, 8> EltTys;
+      for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+        if (Type *T = getTypeByID(Record[i]))
+          EltTys.push_back(T);
+        else
+          break;
+      }
+      if (EltTys.size() != Record.size()-1)
+        return Error("Invalid record");
+      Res->setBody(EltTys, Record[0]);
+      ResultTy = Res;
+      break;
+    }
+    case bitc::TYPE_CODE_OPAQUE: {       // OPAQUE: []
+      if (Record.size() != 1)
+        return Error("Invalid record");
+
+      if (NumRecords >= TypeList.size())
+        return Error("Invalid TYPE table");
+
+      // Check to see if this was forward referenced, if so fill in the temp.
+      StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
+      if (Res) {
+        Res->setName(TypeName);
+        TypeList[NumRecords] = nullptr;
+      } else  // Otherwise, create a new struct with no body.
+        Res = createIdentifiedStructType(Context, TypeName);
+      TypeName.clear();
+      ResultTy = Res;
+      break;
+    }
+    case bitc::TYPE_CODE_ARRAY:     // ARRAY: [numelts, eltty]
+      if (Record.size() < 2)
+        return Error("Invalid record");
+      if ((ResultTy = getTypeByID(Record[1])))
+        ResultTy = ArrayType::get(ResultTy, Record[0]);
+      else
+        return Error("Invalid type");
+      break;
+    case bitc::TYPE_CODE_VECTOR:    // VECTOR: [numelts, eltty]
+      if (Record.size() < 2)
+        return Error("Invalid record");
+      if ((ResultTy = getTypeByID(Record[1])))
+        ResultTy = VectorType::get(ResultTy, Record[0]);
+      else
+        return Error("Invalid type");
+      break;
+    }
+
+    if (NumRecords >= TypeList.size())
+      return Error("Invalid TYPE table");
+    assert(ResultTy && "Didn't read a type?");
+    assert(!TypeList[NumRecords] && "Already read type?");
+    TypeList[NumRecords++] = ResultTy;
+  }
+}
+
+// FIXME: Remove in LLVM 3.1
+std::error_code BitcodeReader::ParseOldTypeTable() {
+  if (Stream.EnterSubBlock(TYPE_BLOCK_ID_OLD_3_0))
+    return Error("Malformed block");
+
+  if (!TypeList.empty())
+    return Error("Invalid TYPE table");
+
+
+  // While horrible, we have no good ordering of types in the bc file.  Just
+  // iteratively parse types out of the bc file in multiple passes until we get
+  // them all.  Do this by saving a cursor for the start of the type block.
+  BitstreamCursor StartOfTypeBlockCursor(Stream);
+
+  unsigned NumTypesRead = 0;
+
+  SmallVector<uint64_t, 64> Record;
+RestartScan:
+  unsigned NextTypeID = 0;
+  bool ReadAnyTypes = false;
+
+  // Read all the records for this type table.
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (NextTypeID != TypeList.size())
+        return Error("Invalid TYPE table");
+
+      // If we haven't read all of the types yet, iterate again.
+      if (NumTypesRead != TypeList.size()) {
+        // If we didn't successfully read any types in this pass, then we must
+        // have an unhandled forward reference.
+        if (!ReadAnyTypes)
+          return Error("Invalid TYPE table");
+
+        Stream = StartOfTypeBlockCursor;
+        goto RestartScan;
+      }
+
+      if (Stream.ReadBlockEnd())
+        return Error("Invalid TYPE table");
+      return std::error_code();
+    }
+
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    Record.clear();
+    Type *ResultTy = nullptr;
+    switch (Stream.readRecord(Code, Record)) {
+    default: return Error("Invalid TYPE table");
+    case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries]
+      // TYPE_CODE_NUMENTRY contains a count of the number of types in the
+      // type list.  This allows us to reserve space.
+      if (Record.size() < 1)
+        return Error("Invalid TYPE table");
+      TypeList.resize(Record[0]);
+      continue;
+    case bitc::TYPE_CODE_VOID:      // VOID
+      ResultTy = Type::getVoidTy(Context);
+      break;
+    case bitc::TYPE_CODE_FLOAT:     // FLOAT
+      ResultTy = Type::getFloatTy(Context);
+      break;
+    case bitc::TYPE_CODE_DOUBLE:    // DOUBLE
+      ResultTy = Type::getDoubleTy(Context);
+      break;
+    case bitc::TYPE_CODE_X86_FP80:  // X86_FP80
+      ResultTy = Type::getX86_FP80Ty(Context);
+      break;
+    case bitc::TYPE_CODE_FP128:     // FP128
+      ResultTy = Type::getFP128Ty(Context);
+      break;
+    case bitc::TYPE_CODE_PPC_FP128: // PPC_FP128
+      ResultTy = Type::getPPC_FP128Ty(Context);
+      break;
+    case bitc::TYPE_CODE_LABEL:     // LABEL
+      ResultTy = Type::getLabelTy(Context);
+      break;
+    case bitc::TYPE_CODE_METADATA:  // METADATA
+      ResultTy = Type::getMetadataTy(Context);
+      break;
+    case bitc::TYPE_CODE_X86_MMX:   // X86_MMX
+      ResultTy = Type::getX86_MMXTy(Context);
+      break;
+    case bitc::TYPE_CODE_INTEGER:   // INTEGER: [width]
+      if (Record.size() < 1)
+        return Error("Invalid TYPE table");
+      ResultTy = IntegerType::get(Context, Record[0]);
+      break;
+    case bitc::TYPE_CODE_OPAQUE:    // OPAQUE
+      if (NextTypeID < TypeList.size() && TypeList[NextTypeID] == 0)
+        ResultTy = StructType::create(Context, "");
+      break;
+    case TYPE_CODE_STRUCT_OLD_3_0: {// STRUCT_OLD
+      if (NextTypeID >= TypeList.size()) break;
+      // If we already read it, don't reprocess.
+      if (TypeList[NextTypeID] &&
+          !cast<StructType>(TypeList[NextTypeID])->isOpaque())
+        break;
+
+      // Set a type.
+      if (TypeList[NextTypeID] == 0)
+        TypeList[NextTypeID] = StructType::create(Context, "");
+
+      std::vector<Type*> EltTys;
+      for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+        if (Type *Elt = getTypeByIDOrNull(Record[i]))
+          EltTys.push_back(Elt);
+        else
+          break;
+      }
+
+      if (EltTys.size() != Record.size()-1)
+        break;      // Not all elements are ready.
+
+      cast<StructType>(TypeList[NextTypeID])->setBody(EltTys, Record[0]);
+      ResultTy = TypeList[NextTypeID];
+      TypeList[NextTypeID] = 0;
+      break;
+    }
+    case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
+      //          [pointee type, address space]
+      if (Record.size() < 1)
+        return Error("Invalid TYPE table");
+      unsigned AddressSpace = 0;
+      if (Record.size() == 2)
+        AddressSpace = Record[1];
+      if ((ResultTy = getTypeByIDOrNull(Record[0])))
+        ResultTy = PointerType::get(ResultTy, AddressSpace);
+      break;
+    }
+    case bitc::TYPE_CODE_FUNCTION_OLD: {
+      // FIXME: attrid is dead, remove it in LLVM 3.0
+      // FUNCTION: [vararg, attrid, retty, paramty x N]
+      if (Record.size() < 3)
+        return Error("Invalid TYPE table");
+      std::vector<Type*> ArgTys;
+      for (unsigned i = 3, e = Record.size(); i != e; ++i) {
+        if (Type *Elt = getTypeByIDOrNull(Record[i]))
+          ArgTys.push_back(Elt);
+        else
+          break;
+      }
+      if (ArgTys.size()+3 != Record.size())
+        break;  // Something was null.
+      if ((ResultTy = getTypeByIDOrNull(Record[2])))
+        ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
+      break;
+    }
+    case bitc::TYPE_CODE_ARRAY:     // ARRAY: [numelts, eltty]
+      if (Record.size() < 2)
+        return Error("Invalid TYPE table");
+      if ((ResultTy = getTypeByIDOrNull(Record[1])))
+        ResultTy = ArrayType::get(ResultTy, Record[0]);
+      break;
+    case bitc::TYPE_CODE_VECTOR:    // VECTOR: [numelts, eltty]
+      if (Record.size() < 2)
+        return Error("Invalid TYPE table");
+      if ((ResultTy = getTypeByIDOrNull(Record[1])))
+        ResultTy = VectorType::get(ResultTy, Record[0]);
+      break;
+    }
+
+    if (NextTypeID >= TypeList.size())
+      return Error("Invalid TYPE table");
+
+    if (ResultTy && TypeList[NextTypeID] == 0) {
+      ++NumTypesRead;
+      ReadAnyTypes = true;
+
+      TypeList[NextTypeID] = ResultTy;
+    }
+
+    ++NextTypeID;
+  }
+}
+
+
+std::error_code BitcodeReader::ParseOldTypeSymbolTable() {
+  if (Stream.EnterSubBlock(TYPE_SYMTAB_BLOCK_ID_OLD_3_0))
+    return Error("Malformed block");
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Read all the records for this type table.
+  std::string TypeName;
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Malformed block");
+      return std::error_code();
+    }
+
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    Record.clear();
+    switch (Stream.readRecord(Code, Record)) {
+    default:  // Default behavior: unknown type.
+      break;
+    case bitc::TST_CODE_ENTRY:    // TST_ENTRY: [typeid, namechar x N]
+      if (ConvertToString(Record, 1, TypeName))
+        return Error("Invalid record");
+      unsigned TypeID = Record[0];
+      if (TypeID >= TypeList.size())
+        return Error("Invalid record");
+
+      // Only apply the type name to a struct type with no name.
+      if (StructType *STy = dyn_cast<StructType>(TypeList[TypeID]))
+        if (!STy->isLiteral() && !STy->hasName())
+          STy->setName(TypeName);
+      TypeName.clear();
+      break;
+    }
+  }
+}
+
+std::error_code BitcodeReader::ParseValueSymbolTable() {
+  if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Read all the records for this value table.
+  SmallString<128> ValueName;
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Malformed block");
+      return std::error_code();
+    }
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    Record.clear();
+    switch (Stream.readRecord(Code, Record)) {
+    default:  // Default behavior: unknown type.
+      break;
+    case bitc::VST_CODE_ENTRY: {  // VST_ENTRY: [valueid, namechar x N]
+      if (ConvertToString(Record, 1, ValueName))
+        return Error("Invalid record");
+      unsigned ValueID = Record[0];
+      if (ValueID >= ValueList.size())
+        return Error("Invalid record");
+      Value *V = ValueList[ValueID];
+
+      V->setName(StringRef(ValueName.data(), ValueName.size()));
+      ValueName.clear();
+      break;
+    }
+    case bitc::VST_CODE_BBENTRY: {
+      if (ConvertToString(Record, 1, ValueName))
+        return Error("Invalid record");
+      BasicBlock *BB = getBasicBlock(Record[0]);
+      if (!BB)
+        return Error("Invalid record");
+
+      BB->setName(StringRef(ValueName.data(), ValueName.size()));
+      ValueName.clear();
+      break;
+    }
+    }
+  }
+}
+
+std::error_code BitcodeReader::ParseMetadata() {
+  unsigned NextMDValueNo = MDValueList.size();
+
+  if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Read all the records.
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Malformed block");
+      return std::error_code();
+    }
+
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    bool IsFunctionLocal = false;
+    // Read a record.
+    Record.clear();
+    Code = Stream.readRecord(Code, Record);
+    switch (Code) {
+    default:  // Default behavior: ignore.
+      break;
+    case bitc::METADATA_NAME: {
+      // Read named of the named metadata.
+      unsigned NameLength = Record.size();
+      SmallString<8> Name;
+      Name.resize(NameLength);
+      for (unsigned i = 0; i != NameLength; ++i)
+        Name[i] = Record[i];
+      Record.clear();
+      Code = Stream.ReadCode();
+
+      // METADATA_NAME is always followed by METADATA_NAMED_NODE.
+      unsigned NextBitCode = Stream.readRecord(Code, Record);
+      if (NextBitCode == METADATA_NAMED_NODE_2_7) {
+        LLVM2_7MetadataDetected = true;
+      } else if (NextBitCode != bitc::METADATA_NAMED_NODE) {
+        assert(!"Invalid Named Metadata record.");  (void)NextBitCode;
+      }
+
+      // Read named metadata elements.
+      unsigned Size = Record.size();
+      NamedMDNode *NMD = TheModule->getOrInsertNamedMetadata(Name);
+      for (unsigned i = 0; i != Size; ++i) {
+        MDNode *MD = dyn_cast_or_null<MDNode>(MDValueList.getValueFwdRef(Record[i]));
+        if (!MD)
+          return Error("Invalid record");
+        NMD->addOperand(MD);
+      }
+
+      if (LLVM2_7MetadataDetected) {
+        MDValueList.AssignValue(0, NextMDValueNo++);
+      }
+      break;
+    }
+    case METADATA_FN_NODE_2_7:
+    case bitc::METADATA_OLD_FN_NODE:
+      IsFunctionLocal = true;
+      // fall-through
+    case METADATA_NODE_2_7:
+    case bitc::METADATA_OLD_NODE: {
+      if (Code == METADATA_FN_NODE_2_7 ||
+          Code == METADATA_NODE_2_7) {
+        LLVM2_7MetadataDetected = true;
+      }
+
+      if (Record.size() % 2 == 1)
+        return Error("Invalid record");
+
+      unsigned Size = Record.size();
+      SmallVector<Metadata *, 8> Elts;
+      for (unsigned i = 0; i != Size; i += 2) {
+        Type *Ty = getTypeByID(Record[i]);
+        if (!Ty)
+          return Error("Invalid record");
+        if (Ty->isMetadataTy())
+          Elts.push_back(MDValueList.getValueFwdRef(Record[i+1]));
+        else if (!Ty->isVoidTy()) {
+          auto *MD =
+              ValueAsMetadata::get(ValueList.getValueFwdRef(Record[i + 1], Ty));
+          assert(isa<ConstantAsMetadata>(MD) &&
+                 "Expected non-function-local metadata");
+          Elts.push_back(MD);
+        } else
+          Elts.push_back(nullptr);
+      }
+      MDValueList.AssignValue(MDNode::get(Context, Elts), NextMDValueNo++);
+      break;
+    }
+    case bitc::METADATA_STRING: {
+      std::string String(Record.begin(), Record.end());
+      llvm::UpgradeMDStringConstant(String);
+      Metadata *MD = MDString::get(Context, String);
+      MDValueList.AssignValue(MD, NextMDValueNo++);
+      break;
+    }
+    case bitc::METADATA_KIND: {
+      if (Record.size() < 2)
+        return Error("Invalid record");
+
+      unsigned Kind = Record[0];
+      SmallString<8> Name(Record.begin()+1, Record.end());
+
+      unsigned NewKind = TheModule->getMDKindID(Name.str());
+      if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second)
+        return Error("Conflicting METADATA_KIND records");
+      break;
+    }
+    }
+  }
+}
+
+/// decodeSignRotatedValue - Decode a signed value stored with the sign bit in
+/// the LSB for dense VBR encoding.
+uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
+  if ((V & 1) == 0)
+    return V >> 1;
+  if (V != 1)
+    return -(V >> 1);
+  // There is no such thing as -0 with integers.  "-0" really means MININT.
+  return 1ULL << 63;
+}
+
+// FIXME: Delete this in LLVM 4.0 and just assert that the aliasee is a
+// GlobalObject.
+static GlobalObject &
+getGlobalObjectInExpr(const DenseMap<GlobalAlias *, Constant *> &Map,
+                      Constant &C) {
+  auto *GO = dyn_cast<GlobalObject>(&C);
+  if (GO)
+    return *GO;
+
+  auto *GA = dyn_cast<GlobalAlias>(&C);
+  if (GA)
+    return getGlobalObjectInExpr(Map, *Map.find(GA)->second);
+
+  auto &CE = cast<ConstantExpr>(C);
+  assert(CE.getOpcode() == Instruction::BitCast ||
+         CE.getOpcode() == Instruction::GetElementPtr ||
+         CE.getOpcode() == Instruction::AddrSpaceCast);
+  if (CE.getOpcode() == Instruction::GetElementPtr)
+    assert(cast<GEPOperator>(CE).hasAllZeroIndices());
+  return getGlobalObjectInExpr(Map, *CE.getOperand(0));
+}
+
+/// ResolveGlobalAndAliasInits - Resolve all of the initializers for global
+/// values and aliases that we can.
+std::error_code BitcodeReader::ResolveGlobalAndAliasInits() {
+  std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;
+  std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist;
+
+  GlobalInitWorklist.swap(GlobalInits);
+  AliasInitWorklist.swap(AliasInits);
+
+  while (!GlobalInitWorklist.empty()) {
+    unsigned ValID = GlobalInitWorklist.back().second;
+    if (ValID >= ValueList.size()) {
+      // Not ready to resolve this yet, it requires something later in the file.
+      GlobalInits.push_back(GlobalInitWorklist.back());
+    } else {
+      if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
+        GlobalInitWorklist.back().first->setInitializer(C);
+      else
+        return Error("Expected a constant");
+    }
+    GlobalInitWorklist.pop_back();
+  }
+
+  // FIXME: Delete this in LLVM 4.0
+  // Older versions of llvm could write an alias pointing to another. We cannot
+  // construct those aliases, so we first collect an alias to aliasee expression
+  // and then compute the actual aliasee.
+  DenseMap<GlobalAlias *, Constant *> AliasInit;
+
+  while (!AliasInitWorklist.empty()) {
+    unsigned ValID = AliasInitWorklist.back().second;
+    if (ValID >= ValueList.size()) {
+      AliasInits.push_back(AliasInitWorklist.back());
+    } else {
+      if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
+        AliasInit.insert(std::make_pair(AliasInitWorklist.back().first, C));
+      else
+        return Error("Expected a constant");
+    }
+    AliasInitWorklist.pop_back();
+  }
+
+  for (auto &Pair : AliasInit) {
+    auto &GO = getGlobalObjectInExpr(AliasInit, *Pair.second);
+    Pair.first->setAliasee(&GO);
+  }
+
+  return std::error_code();
+}
+
+static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) {
+  SmallVector<uint64_t, 8> Words(Vals.size());
+  std::transform(Vals.begin(), Vals.end(), Words.begin(),
+                 BitcodeReader::decodeSignRotatedValue);
+
+  return APInt(TypeBits, Words);
+}
+
+std::error_code BitcodeReader::ParseConstants() {
+  if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Read all the records for this value table.
+  Type *CurTy = Type::getInt32Ty(Context);
+  unsigned NextCstNo = ValueList.size();
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      if (NextCstNo != ValueList.size())
+        return Error("Invalid constant reference");
+
+      // Once all the constants have been read, go through and resolve forward
+      // references.
+      ValueList.ResolveConstantForwardRefs();
+      return std::error_code();
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a record.
+    Record.clear();
+    Value *V = nullptr;
+    unsigned BitCode = Stream.readRecord(Entry.ID, Record);
+    switch (BitCode) {
+    default:  // Default behavior: unknown constant
+    case bitc::CST_CODE_UNDEF:     // UNDEF
+      V = UndefValue::get(CurTy);
+      break;
+    case bitc::CST_CODE_SETTYPE:   // SETTYPE: [typeid]
+      if (Record.empty())
+        return Error("Invalid record");
+      if (Record[0] >= TypeList.size())
+        return Error("Invalid record");
+      CurTy = TypeList[Record[0]];
+      continue;  // Skip the ValueList manipulation.
+    case bitc::CST_CODE_NULL:      // NULL
+      V = Constant::getNullValue(CurTy);
+      break;
+    case bitc::CST_CODE_INTEGER:   // INTEGER: [intval]
+      if (!CurTy->isIntegerTy() || Record.empty())
+        return Error("Invalid record");
+      V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0]));
+      break;
+    case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval]
+      if (!CurTy->isIntegerTy() || Record.empty())
+        return Error("Invalid record");
+
+      APInt VInt = ReadWideAPInt(Record,
+                                 cast<IntegerType>(CurTy)->getBitWidth());
+      V = ConstantInt::get(Context, VInt);
+
+      break;
+    }
+    case bitc::CST_CODE_FLOAT: {    // FLOAT: [fpval]
+      if (Record.empty())
+        return Error("Invalid record");
+      if (CurTy->isHalfTy())
+        V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf,
+                                             APInt(16, (uint16_t)Record[0])));
+      else if (CurTy->isFloatTy())
+        V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle,
+                                             APInt(32, (uint32_t)Record[0])));
+      else if (CurTy->isDoubleTy())
+        V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble,
+                                             APInt(64, Record[0])));
+      else if (CurTy->isX86_FP80Ty()) {
+        // Bits are not stored the same way as a normal i80 APInt, compensate.
+        uint64_t Rearrange[2];
+        Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16);
+        Rearrange[1] = Record[0] >> 48;
+        V = ConstantFP::get(Context, APFloat(APFloat::x87DoubleExtended,
+                                             APInt(80, Rearrange)));
+      } else if (CurTy->isFP128Ty())
+        V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad,
+                                             APInt(128, Record)));
+      else if (CurTy->isPPC_FP128Ty())
+        V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble,
+                                             APInt(128, Record)));
+      else
+        V = UndefValue::get(CurTy);
+      break;
+    }
+
+    case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n x value number]
+      if (Record.empty())
+        return Error("Invalid record");
+
+      unsigned Size = Record.size();
+      SmallVector<Constant*, 16> Elts;
+
+      if (StructType *STy = dyn_cast<StructType>(CurTy)) {
+        for (unsigned i = 0; i != Size; ++i)
+          Elts.push_back(ValueList.getConstantFwdRef(Record[i],
+                                                     STy->getElementType(i)));
+        V = ConstantStruct::get(STy, Elts);
+      } else if (ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) {
+        Type *EltTy = ATy->getElementType();
+        for (unsigned i = 0; i != Size; ++i)
+          Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy));
+        V = ConstantArray::get(ATy, Elts);
+      } else if (VectorType *VTy = dyn_cast<VectorType>(CurTy)) {
+        Type *EltTy = VTy->getElementType();
+        for (unsigned i = 0; i != Size; ++i)
+          Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy));
+        V = ConstantVector::get(Elts);
+      } else {
+        V = UndefValue::get(CurTy);
+      }
+      break;
+    }
+    case bitc::CST_CODE_STRING: { // STRING: [values]
+      if (Record.empty())
+        return Error("Invalid record");
+
+      ArrayType *ATy = cast<ArrayType>(CurTy);
+      Type *EltTy = ATy->getElementType();
+
+      unsigned Size = Record.size();
+      std::vector<Constant*> Elts;
+      for (unsigned i = 0; i != Size; ++i)
+        Elts.push_back(ConstantInt::get(EltTy, Record[i]));
+      V = ConstantArray::get(ATy, Elts);
+      break;
+    }
+    case bitc::CST_CODE_CSTRING: { // CSTRING: [values]
+      if (Record.empty())
+        return Error("Invalid record");
+
+      ArrayType *ATy = cast<ArrayType>(CurTy);
+      Type *EltTy = ATy->getElementType();
+
+      unsigned Size = Record.size();
+      std::vector<Constant*> Elts;
+      for (unsigned i = 0; i != Size; ++i)
+        Elts.push_back(ConstantInt::get(EltTy, Record[i]));
+      Elts.push_back(Constant::getNullValue(EltTy));
+      V = ConstantArray::get(ATy, Elts);
+      break;
+    }
+    case bitc::CST_CODE_CE_BINOP: {  // CE_BINOP: [opcode, opval, opval]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      int Opc = GetDecodedBinaryOpcode(Record[0], CurTy);
+      if (Opc < 0) {
+        V = UndefValue::get(CurTy);  // Unknown binop.
+      } else {
+        Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
+        Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
+        unsigned Flags = 0;
+        if (Record.size() >= 4) {
+          if (Opc == Instruction::Add ||
+              Opc == Instruction::Sub ||
+              Opc == Instruction::Mul ||
+              Opc == Instruction::Shl) {
+            if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+              Flags |= OverflowingBinaryOperator::NoSignedWrap;
+            if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+              Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
+          } else if (Opc == Instruction::SDiv ||
+                     Opc == Instruction::UDiv ||
+                     Opc == Instruction::LShr ||
+                     Opc == Instruction::AShr) {
+            if (Record[3] & (1 << bitc::PEO_EXACT))
+              Flags |= SDivOperator::IsExact;
+          }
+        }
+        V = ConstantExpr::get(Opc, LHS, RHS, Flags);
+      }
+      break;
+    }
+    case bitc::CST_CODE_CE_CAST: {  // CE_CAST: [opcode, opty, opval]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      int Opc = GetDecodedCastOpcode(Record[0]);
+      if (Opc < 0) {
+        V = UndefValue::get(CurTy);  // Unknown cast.
+      } else {
+        Type *OpTy = getTypeByID(Record[1]);
+        if (!OpTy)
+          return Error("Invalid record");
+        Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
+        V = ConstantExpr::getCast(Opc, Op, CurTy);
+      }
+      break;
+    }
+    case bitc::CST_CODE_CE_INBOUNDS_GEP:
+    case bitc::CST_CODE_CE_GEP: {  // CE_GEP:        [n x operands]
+      Type *PointeeType = nullptr;
+      if (Record.size() & 1)
+        return Error("Invalid record");
+      SmallVector<Constant*, 16> Elts;
+      for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
+        Type *ElTy = getTypeByID(Record[i]);
+        if (!ElTy)
+          return Error("Invalid record");
+        Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
+      }
+      ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
+      V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices,
+                                         BitCode ==
+                                           bitc::CST_CODE_CE_INBOUNDS_GEP);
+      break;
+    }
+    case bitc::CST_CODE_CE_SELECT:  // CE_SELECT: [opval#, opval#, opval#]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      V = ConstantExpr::getSelect(ValueList.getConstantFwdRef(Record[0],
+                                                              Type::getInt1Ty(Context)),
+                                  ValueList.getConstantFwdRef(Record[1],CurTy),
+                                  ValueList.getConstantFwdRef(Record[2],CurTy));
+      break;
+    case bitc::CST_CODE_CE_EXTRACTELT: { // CE_EXTRACTELT: [opty, opval, opval]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      VectorType *OpTy =
+        dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
+      if (!OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
+      V = ConstantExpr::getExtractElement(Op0, Op1);
+      break;
+    }
+    case bitc::CST_CODE_CE_INSERTELT: { // CE_INSERTELT: [opval, opval, opval]
+      VectorType *OpTy = dyn_cast<VectorType>(CurTy);
+      if (Record.size() < 3 || !OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[1],
+                                                  OpTy->getElementType());
+      Constant *Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
+      V = ConstantExpr::getInsertElement(Op0, Op1, Op2);
+      break;
+    }
+    case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval]
+      VectorType *OpTy = dyn_cast<VectorType>(CurTy);
+      if (Record.size() < 3 || !OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy);
+      Type *ShufTy = VectorType::get(Type::getInt32Ty(Context),
+                                                 OpTy->getNumElements());
+      Constant *Op2 = ValueList.getConstantFwdRef(Record[2], ShufTy);
+      V = ConstantExpr::getShuffleVector(Op0, Op1, Op2);
+      break;
+    }
+    case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval]
+      VectorType *RTy = dyn_cast<VectorType>(CurTy);
+      VectorType *OpTy =
+        dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
+      if (Record.size() < 4 || !RTy || !OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
+      Type *ShufTy = VectorType::get(Type::getInt32Ty(Context),
+                                                 RTy->getNumElements());
+      Constant *Op2 = ValueList.getConstantFwdRef(Record[3], ShufTy);
+      V = ConstantExpr::getShuffleVector(Op0, Op1, Op2);
+      break;
+    }
+    case bitc::CST_CODE_CE_CMP: {     // CE_CMP: [opty, opval, opval, pred]
+      if (Record.size() < 4)
+        return Error("Invalid record");
+      Type *OpTy = getTypeByID(Record[0]);
+      if (!OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
+
+      if (OpTy->isFPOrFPVectorTy())
+        V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
+      else
+        V = ConstantExpr::getICmp(Record[3], Op0, Op1);
+      break;
+    }
+    case bitc::CST_CODE_INLINEASM:
+    case bitc::CST_CODE_INLINEASM_OLD: {
+      if (Record.size() < 2)
+        return Error("Invalid record");
+      std::string AsmStr, ConstrStr;
+      bool HasSideEffects = Record[0] & 1;
+      bool IsAlignStack = Record[0] >> 1;
+      unsigned AsmStrSize = Record[1];
+      if (2+AsmStrSize >= Record.size())
+        return Error("Invalid record");
+      unsigned ConstStrSize = Record[2+AsmStrSize];
+      if (3+AsmStrSize+ConstStrSize > Record.size())
+        return Error("Invalid record");
+
+      for (unsigned i = 0; i != AsmStrSize; ++i)
+        AsmStr += (char)Record[2+i];
+      for (unsigned i = 0; i != ConstStrSize; ++i)
+        ConstrStr += (char)Record[3+AsmStrSize+i];
+      PointerType *PTy = cast<PointerType>(CurTy);
+      V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
+                         AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
+      break;
+    }
+    case bitc::CST_CODE_BLOCKADDRESS:{
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      Type *FnTy = getTypeByID(Record[0]);
+      if (!FnTy)
+        return Error("Invalid record");
+      Function *Fn =
+        dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
+      if (!Fn)
+        return Error("Invalid record");
+
+      GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(),
+                                                  Type::getInt8Ty(Context),
+                                            false, GlobalValue::InternalLinkage,
+                                                  0, "");
+      BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
+      V = FwdRef;
+      break;
+    }
+    }
+
+    ValueList.AssignValue(V, NextCstNo);
+    ++NextCstNo;
+  }
+
+  if (NextCstNo != ValueList.size())
+    return Error("Invalid constant reference");
+
+  if (Stream.ReadBlockEnd())
+    return Error("Expected a constant");
+
+  // Once all the constants have been read, go through and resolve forward
+  // references.
+  ValueList.ResolveConstantForwardRefs();
+  return std::error_code();
+}
+
+std::error_code BitcodeReader::materializeMetadata() {
+  return std::error_code();
+}
+
+void BitcodeReader::setStripDebugInfo() { }
+
+/// RememberAndSkipFunctionBody - When we see the block for a function body,
+/// remember where it is and then skip it.  This lets us lazily deserialize the
+/// functions.
+std::error_code BitcodeReader::RememberAndSkipFunctionBody() {
+  // Get the function we are talking about.
+  if (FunctionsWithBodies.empty())
+    return Error("Insufficient function protos");
+
+  Function *Fn = FunctionsWithBodies.back();
+  FunctionsWithBodies.pop_back();
+
+  // Save the current stream state.
+  uint64_t CurBit = Stream.GetCurrentBitNo();
+  DeferredFunctionInfo[Fn] = CurBit;
+
+  // Skip over the function block for now.
+  if (Stream.SkipBlock())
+    return Error("Invalid record");
+  return std::error_code();
+}
+
+std::error_code BitcodeReader::GlobalCleanup() {
+  // Patch the initializers for globals and aliases up.
+  ResolveGlobalAndAliasInits();
+  if (!GlobalInits.empty() || !AliasInits.empty())
+    return Error("Malformed global initializer set");
+
+  // Look for intrinsic functions which need to be upgraded at some point
+  for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
+       FI != FE; ++FI) {
+    Function *NewFn;
+    if (UpgradeIntrinsicFunction(&*FI, NewFn))
+      UpgradedIntrinsics.push_back(std::make_pair(&*FI, NewFn));
+  }
+
+  // Look for global variables which need to be renamed.
+  for (Module::global_iterator
+         GI = TheModule->global_begin(), GE = TheModule->global_end();
+       GI != GE; GI++) {
+    GlobalVariable *GV = &*GI;
+    UpgradeGlobalVariable(&*GV);
+  }
+
+  // Force deallocation of memory for these vectors to favor the client that
+  // want lazy deserialization.
+  std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
+  std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
+  return std::error_code();
+}
+
+std::error_code BitcodeReader::ParseModule(bool Resume) {
+  if (Resume)
+    Stream.JumpToBit(NextUnreadBit);
+  else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+  std::vector<std::string> SectionTable;
+  std::vector<std::string> GCTable;
+
+  // Read all the records for this module.
+  while (!Stream.AtEndOfStream()) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Malformed block");
+
+      // Patch the initializers for globals and aliases up.
+      ResolveGlobalAndAliasInits();
+      if (!GlobalInits.empty() || !AliasInits.empty())
+        return Error("Malformed global initializer set");
+      if (!FunctionsWithBodies.empty())
+        return Error("Insufficient function protos");
+
+      // Look for intrinsic functions which need to be upgraded at some point
+      for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
+           FI != FE; ++FI) {
+        Function* NewFn;
+        if (UpgradeIntrinsicFunction(&*FI, NewFn))
+          UpgradedIntrinsics.push_back(std::make_pair(&*FI, NewFn));
+      }
+
+      // Look for global variables which need to be renamed.
+      for (Module::global_iterator
+             GI = TheModule->global_begin(), GE = TheModule->global_end();
+           GI != GE; ++GI)
+        UpgradeGlobalVariable(&*GI);
+
+      // Force deallocation of memory for these vectors to favor the client that
+      // want lazy deserialization.
+      std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
+      std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
+      std::vector<Function*>().swap(FunctionsWithBodies);
+      return std::error_code();
+    }
+
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      switch (Stream.ReadSubBlockID()) {
+      default:  // Skip unknown content.
+        if (Stream.SkipBlock())
+          return Error("Invalid record");
+        break;
+      case bitc::BLOCKINFO_BLOCK_ID:
+        if (Stream.ReadBlockInfoBlock())
+          return Error("Malformed block");
+        break;
+      case bitc::PARAMATTR_BLOCK_ID:
+        if (std::error_code EC = ParseAttributeBlock())
+          return EC;
+        break;
+      case bitc::TYPE_BLOCK_ID_NEW:
+        if (std::error_code EC = ParseTypeTable())
+          return EC;
+        break;
+      case TYPE_BLOCK_ID_OLD_3_0:
+        if (std::error_code EC = ParseOldTypeTable())
+          return EC;
+        break;
+      case TYPE_SYMTAB_BLOCK_ID_OLD_3_0:
+        if (std::error_code EC = ParseOldTypeSymbolTable())
+          return EC;
+        break;
+      case bitc::VALUE_SYMTAB_BLOCK_ID:
+        if (std::error_code EC = ParseValueSymbolTable())
+          return EC;
+        SeenValueSymbolTable = true;
+        break;
+      case bitc::CONSTANTS_BLOCK_ID:
+        if (std::error_code EC = ParseConstants())
+          return EC;
+        if (std::error_code EC = ResolveGlobalAndAliasInits())
+          return EC;
+        break;
+      case bitc::METADATA_BLOCK_ID:
+        if (std::error_code EC = ParseMetadata())
+          return EC;
+        break;
+      case bitc::FUNCTION_BLOCK_ID:
+        // If this is the first function body we've seen, reverse the
+        // FunctionsWithBodies list.
+        if (!SeenFirstFunctionBody) {
+          std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
+          if (std::error_code EC = GlobalCleanup())
+            return EC;
+          SeenFirstFunctionBody = true;
+        }
+
+        if (std::error_code EC = RememberAndSkipFunctionBody())
+          return EC;
+        // For streaming bitcode, suspend parsing when we reach the function
+        // bodies. Subsequent materialization calls will resume it when
+        // necessary. For streaming, the function bodies must be at the end of
+        // the bitcode. If the bitcode file is old, the symbol table will be
+        // at the end instead and will not have been seen yet. In this case,
+        // just finish the parse now.
+        if (LazyStreamer && SeenValueSymbolTable) {
+          NextUnreadBit = Stream.GetCurrentBitNo();
+          return std::error_code();
+        }
+        break;
+        break;
+      }
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    switch (Stream.readRecord(Code, Record)) {
+    default: break;  // Default behavior, ignore unknown content.
+    case bitc::MODULE_CODE_VERSION: {  // VERSION: [version#]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      // Only version #0 is supported so far.
+      if (Record[0] != 0)
+        return Error("Invalid value");
+      break;
+    }
+    case bitc::MODULE_CODE_TRIPLE: {  // TRIPLE: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      TheModule->setTargetTriple(S);
+      break;
+    }
+    case bitc::MODULE_CODE_DATALAYOUT: {  // DATALAYOUT: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      TheModule->setDataLayout(S);
+      break;
+    }
+    case bitc::MODULE_CODE_ASM: {  // ASM: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      TheModule->setModuleInlineAsm(S);
+      break;
+    }
+    case bitc::MODULE_CODE_DEPLIB: {  // DEPLIB: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      // ANDROID: Ignore value, since we never used it anyways.
+      // TheModule->addLibrary(S);
+      break;
+    }
+    case bitc::MODULE_CODE_SECTIONNAME: {  // SECTIONNAME: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      SectionTable.push_back(S);
+      break;
+    }
+    case bitc::MODULE_CODE_GCNAME: {  // SECTIONNAME: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      GCTable.push_back(S);
+      break;
+    }
+    // GLOBALVAR: [pointer type, isconst, initid,
+    //             linkage, alignment, section, visibility, threadlocal,
+    //             unnamed_addr]
+    case bitc::MODULE_CODE_GLOBALVAR: {
+      if (Record.size() < 6)
+        return Error("Invalid record");
+      Type *Ty = getTypeByID(Record[0]);
+      if (!Ty)
+        return Error("Invalid record");
+      if (!Ty->isPointerTy())
+        return Error("Invalid type for value");
+      unsigned AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
+      Ty = cast<PointerType>(Ty)->getElementType();
+
+      bool isConstant = Record[1];
+      uint64_t RawLinkage = Record[3];
+      GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage);
+      unsigned Alignment = (1 << Record[4]) >> 1;
+      std::string Section;
+      if (Record[5]) {
+        if (Record[5]-1 >= SectionTable.size())
+          return Error("Invalid ID");
+        Section = SectionTable[Record[5]-1];
+      }
+      GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
+      if (Record.size() > 6)
+        Visibility = GetDecodedVisibility(Record[6]);
+
+      GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal;
+      if (Record.size() > 7)
+        TLM = GetDecodedThreadLocalMode(Record[7]);
+
+      bool UnnamedAddr = false;
+      if (Record.size() > 8)
+        UnnamedAddr = Record[8];
+
+      GlobalVariable *NewGV =
+        new GlobalVariable(*TheModule, Ty, isConstant, Linkage, nullptr, "", nullptr,
+                           TLM, AddressSpace);
+      NewGV->setAlignment(Alignment);
+      if (!Section.empty())
+        NewGV->setSection(Section);
+      NewGV->setVisibility(Visibility);
+      NewGV->setUnnamedAddr(UnnamedAddr);
+
+      ValueList.push_back(NewGV);
+
+      // Remember which value to use for the global initializer.
+      if (unsigned InitID = Record[2])
+        GlobalInits.push_back(std::make_pair(NewGV, InitID-1));
+      break;
+    }
+    // FUNCTION:  [type, callingconv, isproto, linkage, paramattr,
+    //             alignment, section, visibility, gc, unnamed_addr]
+    case bitc::MODULE_CODE_FUNCTION: {
+      if (Record.size() < 8)
+        return Error("Invalid record");
+      Type *Ty = getTypeByID(Record[0]);
+      if (!Ty)
+        return Error("Invalid record");
+      if (!Ty->isPointerTy())
+        return Error("Invalid type for value");
+      FunctionType *FTy =
+        dyn_cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
+      if (!FTy)
+        return Error("Invalid type for value");
+
+      Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage,
+                                        "", TheModule);
+
+      Func->setCallingConv(static_cast<CallingConv::ID>(Record[1]));
+      bool isProto = Record[2];
+      uint64_t RawLinkage = Record[3];
+      Func->setLinkage(getDecodedLinkage(RawLinkage));
+      Func->setAttributes(getAttributes(Record[4]));
+
+      Func->setAlignment((1 << Record[5]) >> 1);
+      if (Record[6]) {
+        if (Record[6]-1 >= SectionTable.size())
+          return Error("Invalid ID");
+        Func->setSection(SectionTable[Record[6]-1]);
+      }
+      Func->setVisibility(GetDecodedVisibility(Record[7]));
+      if (Record.size() > 8 && Record[8]) {
+        if (Record[8]-1 > GCTable.size())
+          return Error("Invalid ID");
+        Func->setGC(GCTable[Record[8]-1].c_str());
+      }
+      bool UnnamedAddr = false;
+      if (Record.size() > 9)
+        UnnamedAddr = Record[9];
+      Func->setUnnamedAddr(UnnamedAddr);
+      ValueList.push_back(Func);
+
+      // If this is a function with a body, remember the prototype we are
+      // creating now, so that we can match up the body with them later.
+      if (!isProto) {
+        Func->setIsMaterializable(true);
+        FunctionsWithBodies.push_back(Func);
+        if (LazyStreamer)
+          DeferredFunctionInfo[Func] = 0;
+      }
+      break;
+    }
+    // ALIAS: [alias type, aliasee val#, linkage]
+    // ALIAS: [alias type, aliasee val#, linkage, visibility]
+    case bitc::MODULE_CODE_ALIAS_OLD: {
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      Type *Ty = getTypeByID(Record[0]);
+      if (!Ty)
+        return Error("Invalid record");
+      auto *PTy = dyn_cast<PointerType>(Ty);
+      if (!PTy)
+        return Error("Invalid type for value");
+
+      auto *NewGA =
+          GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),
+                              getDecodedLinkage(Record[2]), "", TheModule);
+      // Old bitcode files didn't have visibility field.
+      if (Record.size() > 3)
+        NewGA->setVisibility(GetDecodedVisibility(Record[3]));
+      ValueList.push_back(NewGA);
+      AliasInits.push_back(std::make_pair(NewGA, Record[1]));
+      break;
+    }
+    /// MODULE_CODE_PURGEVALS: [numvals]
+    case bitc::MODULE_CODE_PURGEVALS:
+      // Trim down the value list to the specified size.
+      if (Record.size() < 1 || Record[0] > ValueList.size())
+        return Error("Invalid record");
+      ValueList.shrinkTo(Record[0]);
+      break;
+    }
+    Record.clear();
+  }
+
+  return Error("Invalid bitcode signature");
+}
+
+std::error_code BitcodeReader::ParseBitcodeInto(Module *M) {
+  TheModule = nullptr;
+
+  if (std::error_code EC = InitStream())
+    return EC;
+
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'B' ||
+      Stream.Read(8) != 'C' ||
+      Stream.Read(4) != 0x0 ||
+      Stream.Read(4) != 0xC ||
+      Stream.Read(4) != 0xE ||
+      Stream.Read(4) != 0xD)
+    return Error("Invalid bitcode signature");
+
+  // We expect a number of well-defined blocks, though we don't necessarily
+  // need to understand them all.
+  while (1) {
+    if (Stream.AtEndOfStream())
+      return std::error_code();
+
+    BitstreamEntry Entry =
+      Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return std::error_code();
+
+    case BitstreamEntry::SubBlock:
+      switch (Entry.ID) {
+      case bitc::BLOCKINFO_BLOCK_ID:
+        if (Stream.ReadBlockInfoBlock())
+          return Error("Malformed block");
+        break;
+      case bitc::MODULE_BLOCK_ID:
+        // Reject multiple MODULE_BLOCK's in a single bitstream.
+        if (TheModule)
+          return Error("Invalid multiple blocks");
+        TheModule = M;
+        if (std::error_code EC = ParseModule(false))
+          return EC;
+        if (LazyStreamer)
+          return std::error_code();
+        break;
+      default:
+        if (Stream.SkipBlock())
+          return Error("Invalid record");
+        break;
+      }
+      continue;
+    case BitstreamEntry::Record:
+      // There should be no records in the top-level of blocks.
+
+      // The ranlib in Xcode 4 will align archive members by appending newlines
+      // to the end of them. If this file size is a multiple of 4 but not 8, we
+      // have to read and ignore these final 4 bytes :-(
+      if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 &&
+          Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a &&
+          Stream.AtEndOfStream())
+        return std::error_code();
+
+      return Error("Invalid record");
+    }
+  }
+}
+
+llvm::ErrorOr<std::string> BitcodeReader::parseModuleTriple() {
+  if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+
+  std::string Triple;
+  // Read all the records for this module.
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return Triple;
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a record.
+    switch (Stream.readRecord(Entry.ID, Record)) {
+    default: break;  // Default behavior, ignore unknown content.
+    case bitc::MODULE_CODE_VERSION:  // VERSION: [version#]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      // Only version #0 is supported so far.
+      if (Record[0] != 0)
+        return Error("Invalid record");
+      break;
+    case bitc::MODULE_CODE_TRIPLE: {  // TRIPLE: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      Triple = S;
+      break;
+    }
+    }
+    Record.clear();
+  }
+
+  return Error("Invalid bitcode signature");
+}
+
+llvm::ErrorOr<std::string> BitcodeReader::parseTriple() {
+  if (std::error_code EC = InitStream())
+    return EC;
+
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'B' ||
+      Stream.Read(8) != 'C' ||
+      Stream.Read(4) != 0x0 ||
+      Stream.Read(4) != 0xC ||
+      Stream.Read(4) != 0xE ||
+      Stream.Read(4) != 0xD)
+    return Error("Invalid bitcode signature");
+
+  // We expect a number of well-defined blocks, though we don't necessarily
+  // need to understand them all.
+  while (1) {
+    BitstreamEntry Entry = Stream.advance();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return std::error_code();
+
+    case BitstreamEntry::SubBlock:
+      if (Entry.ID == bitc::MODULE_BLOCK_ID)
+        return parseModuleTriple();
+
+      // Ignore other sub-blocks.
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+
+    case BitstreamEntry::Record:
+      Stream.skipRecord(Entry.ID);
+      continue;
+    }
+  }
+}
+
+/// ParseMetadataAttachment - Parse metadata attachments.
+std::error_code BitcodeReader::ParseMetadataAttachment() {
+  if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return std::error_code();
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a metadata attachment record.
+    Record.clear();
+    switch (Stream.readRecord(Entry.ID, Record)) {
+    default:  // Default behavior: ignore.
+      break;
+    case METADATA_ATTACHMENT_2_7:
+      LLVM2_7MetadataDetected = true;
+    case bitc::METADATA_ATTACHMENT: {
+      unsigned RecordLength = Record.size();
+      if (Record.empty() || (RecordLength - 1) % 2 == 1)
+        return Error("Invalid record");
+      Instruction *Inst = InstructionList[Record[0]];
+      for (unsigned i = 1; i != RecordLength; i = i+2) {
+        unsigned Kind = Record[i];
+        DenseMap<unsigned, unsigned>::iterator I =
+          MDKindMap.find(Kind);
+        if (I == MDKindMap.end())
+          return Error("Invalid ID");
+        Metadata *Node = MDValueList.getValueFwdRef(Record[i + 1]);
+        Inst->setMetadata(I->second, cast<MDNode>(Node));
+      }
+      break;
+    }
+    }
+  }
+}
+
+/// ParseFunctionBody - Lazily parse the specified function body block.
+std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
+  if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
+    return Error("Invalid record");
+
+  InstructionList.clear();
+  unsigned ModuleValueListSize = ValueList.size();
+  unsigned ModuleMDValueListSize = MDValueList.size();
+
+  // Add all the function arguments to the value table.
+  for(Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+    ValueList.push_back(&*I);
+
+  unsigned NextValueNo = ValueList.size();
+  BasicBlock *CurBB = nullptr;
+  unsigned CurBBNo = 0;
+
+  DebugLoc LastLoc;
+
+  // Read all the records.
+  SmallVector<uint64_t, 64> Record;
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Malformed block");
+      break;
+    }
+
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      switch (Stream.ReadSubBlockID()) {
+      default:  // Skip unknown content.
+        if (Stream.SkipBlock())
+          return Error("Invalid record");
+        break;
+      case bitc::CONSTANTS_BLOCK_ID:
+        if (std::error_code EC = ParseConstants())
+          return EC;
+        NextValueNo = ValueList.size();
+        break;
+      case bitc::VALUE_SYMTAB_BLOCK_ID:
+        if (std::error_code EC = ParseValueSymbolTable())
+          return EC;
+        break;
+      case bitc::METADATA_ATTACHMENT_ID:
+        if (std::error_code EC = ParseMetadataAttachment())
+          return EC;
+        break;
+      case bitc::METADATA_BLOCK_ID:
+        if (std::error_code EC = ParseMetadata())
+          return EC;
+        break;
+      }
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    Record.clear();
+    Instruction *I = nullptr;
+    unsigned BitCode = Stream.readRecord(Code, Record);
+    switch (BitCode) {
+    default: // Default behavior: reject
+      return Error("Invalid value");
+    case bitc::FUNC_CODE_DECLAREBLOCKS:     // DECLAREBLOCKS: [nblocks]
+      if (Record.size() < 1 || Record[0] == 0)
+        return Error("Invalid record");
+      // Create all the basic blocks for the function.
+      FunctionBBs.resize(Record[0]);
+      for (unsigned i = 0, e = FunctionBBs.size(); i != e; ++i)
+        FunctionBBs[i] = BasicBlock::Create(Context, "", F);
+      CurBB = FunctionBBs[0];
+      continue;
+
+    case bitc::FUNC_CODE_DEBUG_LOC_AGAIN:  // DEBUG_LOC_AGAIN
+      // This record indicates that the last instruction is at the same
+      // location as the previous instruction with a location.
+      I = nullptr;
+
+      // Get the last instruction emitted.
+      if (CurBB && !CurBB->empty())
+        I = &CurBB->back();
+      else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
+               !FunctionBBs[CurBBNo-1]->empty())
+        I = &FunctionBBs[CurBBNo-1]->back();
+
+      if (!I)
+        return Error("Invalid record");
+      I->setDebugLoc(LastLoc);
+      I = nullptr;
+      continue;
+
+    case FUNC_CODE_DEBUG_LOC_2_7:
+      LLVM2_7MetadataDetected = true;
+    case bitc::FUNC_CODE_DEBUG_LOC: {      // DEBUG_LOC: [line, col, scope, ia]
+      I = nullptr;     // Get the last instruction emitted.
+      if (CurBB && !CurBB->empty())
+        I = &CurBB->back();
+      else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
+               !FunctionBBs[CurBBNo-1]->empty())
+        I = &FunctionBBs[CurBBNo-1]->back();
+      if (!I || Record.size() < 4)
+        return Error("Invalid record");
+
+      unsigned Line = Record[0], Col = Record[1];
+      unsigned ScopeID = Record[2], IAID = Record[3];
+
+      MDNode *Scope = nullptr, *IA = nullptr;
+      if (ScopeID) Scope = cast<MDNode>(MDValueList.getValueFwdRef(ScopeID-1));
+      if (IAID)    IA = cast<MDNode>(MDValueList.getValueFwdRef(IAID-1));
+      LastLoc = DebugLoc::get(Line, Col, Scope, IA);
+      I->setDebugLoc(LastLoc);
+      I = nullptr;
+      continue;
+    }
+
+    case bitc::FUNC_CODE_INST_BINOP: {    // BINOP: [opval, ty, opval, opcode]
+      unsigned OpNum = 0;
+      Value *LHS, *RHS;
+      if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
+          getValue(Record, OpNum, LHS->getType(), RHS) ||
+          OpNum+1 > Record.size())
+        return Error("Invalid record");
+
+      int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
+      if (Opc == -1)
+        return Error("Invalid record");
+      I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
+      InstructionList.push_back(I);
+      if (OpNum < Record.size()) {
+        if (Opc == Instruction::Add ||
+            Opc == Instruction::Sub ||
+            Opc == Instruction::Mul ||
+            Opc == Instruction::Shl) {
+          if (Record[OpNum] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+            cast<BinaryOperator>(I)->setHasNoSignedWrap(true);
+          if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+            cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true);
+        } else if (Opc == Instruction::SDiv ||
+                   Opc == Instruction::UDiv ||
+                   Opc == Instruction::LShr ||
+                   Opc == Instruction::AShr) {
+          if (Record[OpNum] & (1 << bitc::PEO_EXACT))
+            cast<BinaryOperator>(I)->setIsExact(true);
+        }
+      }
+      break;
+    }
+    case bitc::FUNC_CODE_INST_CAST: {    // CAST: [opval, opty, destty, castopc]
+      unsigned OpNum = 0;
+      Value *Op;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+          OpNum+2 != Record.size())
+        return Error("Invalid record");
+
+      Type *ResTy = getTypeByID(Record[OpNum]);
+      int Opc = GetDecodedCastOpcode(Record[OpNum+1]);
+      if (Opc == -1 || !ResTy)
+        return Error("Invalid record");
+      I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD:
+    case bitc::FUNC_CODE_INST_GEP_OLD: // GEP: [n x operands]
+    case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands]
+      unsigned OpNum = 0;
+
+      Type *Ty;
+      bool InBounds;
+
+      if (BitCode == bitc::FUNC_CODE_INST_GEP) {
+        InBounds = Record[OpNum++];
+        Ty = getTypeByID(Record[OpNum++]);
+      } else {
+        InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
+        Ty = nullptr;
+      }
+
+      Value *BasePtr;
+      if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr))
+        return Error("Invalid record");
+
+      if (Ty &&
+          Ty !=
+              cast<SequentialType>(BasePtr->getType()->getScalarType())
+                  ->getElementType())
+        return Error(
+            "Explicit gep type does not match pointee type of pointer operand");
+
+      SmallVector<Value*, 16> GEPIdx;
+      while (OpNum != Record.size()) {
+        Value *Op;
+        if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+          return Error("Invalid record");
+        GEPIdx.push_back(Op);
+      }
+
+      I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx);
+
+      InstructionList.push_back(I);
+      if (InBounds)
+        cast<GetElementPtrInst>(I)->setIsInBounds(true);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_EXTRACTVAL: {
+                                       // EXTRACTVAL: [opty, opval, n x indices]
+      unsigned OpNum = 0;
+      Value *Agg;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
+        return Error("Invalid record");
+
+      SmallVector<unsigned, 4> EXTRACTVALIdx;
+      for (unsigned RecSize = Record.size();
+           OpNum != RecSize; ++OpNum) {
+        uint64_t Index = Record[OpNum];
+        if ((unsigned)Index != Index)
+          return Error("Invalid value");
+        EXTRACTVALIdx.push_back((unsigned)Index);
+      }
+
+      I = ExtractValueInst::Create(Agg, EXTRACTVALIdx);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_INSERTVAL: {
+                           // INSERTVAL: [opty, opval, opty, opval, n x indices]
+      unsigned OpNum = 0;
+      Value *Agg;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
+        return Error("Invalid record");
+      Value *Val;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Val))
+        return Error("Invalid record");
+
+      SmallVector<unsigned, 4> INSERTVALIdx;
+      for (unsigned RecSize = Record.size();
+           OpNum != RecSize; ++OpNum) {
+        uint64_t Index = Record[OpNum];
+        if ((unsigned)Index != Index)
+          return Error("Invalid value");
+        INSERTVALIdx.push_back((unsigned)Index);
+      }
+
+      I = InsertValueInst::Create(Agg, Val, INSERTVALIdx);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_SELECT: { // SELECT: [opval, ty, opval, opval]
+      // obsolete form of select
+      // handles select i1 ... in old bitcode
+      unsigned OpNum = 0;
+      Value *TrueVal, *FalseVal, *Cond;
+      if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
+          getValue(Record, OpNum, TrueVal->getType(), FalseVal) ||
+          getValue(Record, OpNum, Type::getInt1Ty(Context), Cond))
+        return Error("Invalid record");
+
+      I = SelectInst::Create(Cond, TrueVal, FalseVal);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_VSELECT: {// VSELECT: [ty,opval,opval,predty,pred]
+      // new form of select
+      // handles select i1 or select [N x i1]
+      unsigned OpNum = 0;
+      Value *TrueVal, *FalseVal, *Cond;
+      if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
+          getValue(Record, OpNum, TrueVal->getType(), FalseVal) ||
+          getValueTypePair(Record, OpNum, NextValueNo, Cond))
+        return Error("Invalid record");
+
+      // select condition can be either i1 or [N x i1]
+      if (VectorType* vector_type =
+          dyn_cast<VectorType>(Cond->getType())) {
+        // expect <n x i1>
+        if (vector_type->getElementType() != Type::getInt1Ty(Context))
+          return Error("Invalid type for value");
+      } else {
+        // expect i1
+        if (Cond->getType() != Type::getInt1Ty(Context))
+          return Error("Invalid type for value");
+      }
+
+      I = SelectInst::Create(Cond, TrueVal, FalseVal);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval]
+      unsigned OpNum = 0;
+      Value *Vec, *Idx;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
+          getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
+        return Error("Invalid record");
+      I = ExtractElementInst::Create(Vec, Idx);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval]
+      unsigned OpNum = 0;
+      Value *Vec, *Elt, *Idx;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
+          getValue(Record, OpNum,
+                   cast<VectorType>(Vec->getType())->getElementType(), Elt) ||
+          getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
+        return Error("Invalid record");
+      I = InsertElementInst::Create(Vec, Elt, Idx);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval]
+      unsigned OpNum = 0;
+      Value *Vec1, *Vec2, *Mask;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) ||
+          getValue(Record, OpNum, Vec1->getType(), Vec2))
+        return Error("Invalid record");
+
+      if (getValueTypePair(Record, OpNum, NextValueNo, Mask))
+        return Error("Invalid record");
+      I = new ShuffleVectorInst(Vec1, Vec2, Mask);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_CMP:   // CMP: [opty, opval, opval, pred]
+      // Old form of ICmp/FCmp returning bool
+      // Existed to differentiate between icmp/fcmp and vicmp/vfcmp which were
+      // both legal on vectors but had different behaviour.
+    case bitc::FUNC_CODE_INST_CMP2: { // CMP2: [opty, opval, opval, pred]
+      // FCmp/ICmp returning bool or vector of bool
+
+      unsigned OpNum = 0;
+      Value *LHS, *RHS;
+      if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
+          getValue(Record, OpNum, LHS->getType(), RHS) ||
+          OpNum+1 != Record.size())
+        return Error("Invalid record");
+
+      if (LHS->getType()->isFPOrFPVectorTy())
+        I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
+      else
+        I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case FUNC_CODE_INST_GETRESULT_2_7: {
+      if (Record.size() != 2) {
+        return Error("Invalid record");
+      }
+      unsigned OpNum = 0;
+      Value *Op;
+      getValueTypePair(Record, OpNum, NextValueNo, Op);
+      unsigned Index = Record[1];
+      I = ExtractValueInst::Create(Op, Index);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_RET: // RET: [opty,opval<optional>]
+      {
+        unsigned Size = Record.size();
+        if (Size == 0) {
+          I = ReturnInst::Create(Context);
+          InstructionList.push_back(I);
+          break;
+        }
+
+        unsigned OpNum = 0;
+        Value *Op = nullptr;
+        if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+          return Error("Invalid record");
+        if (OpNum != Record.size())
+          return Error("Invalid record");
+
+        I = ReturnInst::Create(Context, Op);
+        InstructionList.push_back(I);
+        break;
+      }
+    case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
+      if (Record.size() != 1 && Record.size() != 3)
+        return Error("Invalid record");
+      BasicBlock *TrueDest = getBasicBlock(Record[0]);
+      if (!TrueDest)
+        return Error("Invalid record");
+
+      if (Record.size() == 1) {
+        I = BranchInst::Create(TrueDest);
+        InstructionList.push_back(I);
+      }
+      else {
+        BasicBlock *FalseDest = getBasicBlock(Record[1]);
+        Value *Cond = getFnValueByID(Record[2], Type::getInt1Ty(Context));
+        if (!FalseDest || !Cond)
+          return Error("Invalid record");
+        I = BranchInst::Create(TrueDest, FalseDest, Cond);
+        InstructionList.push_back(I);
+      }
+      break;
+    }
+    case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
+      if (Record.size() < 3 || (Record.size() & 1) == 0)
+        return Error("Invalid record");
+      Type *OpTy = getTypeByID(Record[0]);
+      Value *Cond = getFnValueByID(Record[1], OpTy);
+      BasicBlock *Default = getBasicBlock(Record[2]);
+      if (!OpTy || !Cond || !Default)
+        return Error("Invalid record");
+      unsigned NumCases = (Record.size()-3)/2;
+      SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
+      InstructionList.push_back(SI);
+      for (unsigned i = 0, e = NumCases; i != e; ++i) {
+        ConstantInt *CaseVal =
+          dyn_cast_or_null<ConstantInt>(getFnValueByID(Record[3+i*2], OpTy));
+        BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]);
+        if (!CaseVal || !DestBB) {
+          delete SI;
+          return Error("Invalid record");
+        }
+        SI->addCase(CaseVal, DestBB);
+      }
+      I = SI;
+      break;
+    }
+    case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...]
+      if (Record.size() < 2)
+        return Error("Invalid record");
+      Type *OpTy = getTypeByID(Record[0]);
+      Value *Address = getFnValueByID(Record[1], OpTy);
+      if (!OpTy || !Address)
+        return Error("Invalid record");
+      unsigned NumDests = Record.size()-2;
+      IndirectBrInst *IBI = IndirectBrInst::Create(Address, NumDests);
+      InstructionList.push_back(IBI);
+      for (unsigned i = 0, e = NumDests; i != e; ++i) {
+        if (BasicBlock *DestBB = getBasicBlock(Record[2+i])) {
+          IBI->addDestination(DestBB);
+        } else {
+          delete IBI;
+          return Error("Invalid record");
+        }
+      }
+      I = IBI;
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_INVOKE: {
+      // INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...]
+      if (Record.size() < 4)
+        return Error("Invalid record");
+      AttributeSet PAL = getAttributes(Record[0]);
+      unsigned CCInfo = Record[1];
+      BasicBlock *NormalBB = getBasicBlock(Record[2]);
+      BasicBlock *UnwindBB = getBasicBlock(Record[3]);
+
+      unsigned OpNum = 4;
+      Value *Callee;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
+        return Error("Invalid record");
+
+      PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType());
+      FunctionType *FTy = !CalleeTy ? nullptr :
+        dyn_cast<FunctionType>(CalleeTy->getElementType());
+
+      // Check that the right number of fixed parameters are here.
+      if (!FTy || !NormalBB || !UnwindBB ||
+          Record.size() < OpNum+FTy->getNumParams())
+        return Error("Invalid record");
+
+      SmallVector<Value*, 16> Ops;
+      for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
+        Ops.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i)));
+        if (!Ops.back())
+          return Error("Invalid record");
+      }
+
+      if (!FTy->isVarArg()) {
+        if (Record.size() != OpNum)
+          return Error("Invalid record");
+      } else {
+        // Read type/value pairs for varargs params.
+        while (OpNum != Record.size()) {
+          Value *Op;
+          if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+            return Error("Invalid record");
+          Ops.push_back(Op);
+        }
+      }
+
+      I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops);
+      InstructionList.push_back(I);
+      cast<InvokeInst>(I)->setCallingConv(
+        static_cast<CallingConv::ID>(CCInfo));
+      cast<InvokeInst>(I)->setAttributes(PAL);
+      break;
+    }
+    case FUNC_CODE_INST_UNWIND_2_7: { // UNWIND_OLD
+      // 'unwind' instruction has been removed in LLVM 3.1
+      // Replace 'unwind' with 'landingpad' and 'resume'.
+      Type *ExnTy = StructType::get(Type::getInt8PtrTy(Context),
+                                    Type::getInt32Ty(Context), nullptr);
+
+      LandingPadInst *LP = LandingPadInst::Create(ExnTy, 1);
+      LP->setCleanup(true);
+
+      CurBB->getInstList().push_back(LP);
+      I = ResumeInst::Create(LP);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
+      I = new UnreachableInst(Context);
+      InstructionList.push_back(I);
+      break;
+    case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
+      if (Record.size() < 1 || ((Record.size()-1)&1))
+        return Error("Invalid record");
+      Type *Ty = getTypeByID(Record[0]);
+      if (!Ty)
+        return Error("Invalid record");
+
+      PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2);
+      InstructionList.push_back(PN);
+
+      for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
+        Value *V = getFnValueByID(Record[1+i], Ty);
+        BasicBlock *BB = getBasicBlock(Record[2+i]);
+        if (!V || !BB)
+          return Error("Invalid record");
+        PN->addIncoming(V, BB);
+      }
+      I = PN;
+      break;
+    }
+
+    case FUNC_CODE_INST_MALLOC_2_7: { // MALLOC: [instty, op, align]
+      // Autoupgrade malloc instruction to malloc call.
+      // FIXME: Remove in LLVM 3.0.
+      if (Record.size() < 3) {
+        return Error("Invalid record");
+      }
+      PointerType *Ty =
+          dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
+      Value *Size = getFnValueByID(Record[1], Type::getInt32Ty(Context));
+      if (!Ty || !Size)
+        return Error("Invalid record");
+      if (!CurBB)
+        return Error("Invalid instruction with no BB");
+      Type *Int32Ty = IntegerType::getInt32Ty(CurBB->getContext());
+      Constant *AllocSize = ConstantExpr::getSizeOf(Ty->getElementType());
+      AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, Int32Ty);
+      I = CallInst::CreateMalloc(CurBB, Int32Ty, Ty->getElementType(),
+                                 AllocSize, Size, nullptr);
+      InstructionList.push_back(I);
+      break;
+    }
+    case FUNC_CODE_INST_FREE_2_7: { // FREE: [op, opty]
+      unsigned OpNum = 0;
+      Value *Op;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+          OpNum != Record.size()) {
+        return Error("Invalid record");
+      }
+      if (!CurBB)
+        return Error("Invalid instruction with no BB");
+      I = CallInst::CreateFree(Op, CurBB);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align]
+      // For backward compatibility, tolerate a lack of an opty, and use i32.
+      // Remove this in LLVM 3.0.
+      if (Record.size() < 3 || Record.size() > 4) {
+        return Error("Invalid record");
+      }
+      unsigned OpNum = 0;
+      PointerType *Ty =
+        dyn_cast_or_null<PointerType>(getTypeByID(Record[OpNum++]));
+      Type *OpTy = Record.size() == 4 ? getTypeByID(Record[OpNum++]) :
+                                              Type::getInt32Ty(Context);
+      Value *Size = getFnValueByID(Record[OpNum++], OpTy);
+      unsigned Align = Record[OpNum++];
+      if (!Ty || !Size)
+        return Error("Invalid record");
+      I = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol]
+      unsigned OpNum = 0;
+      Value *Op;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+          OpNum+2 != Record.size())
+        return Error("Invalid record");
+
+      I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol]
+      unsigned OpNum = 0;
+      Value *Val, *Ptr;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
+          getValue(Record, OpNum,
+                    cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
+          OpNum+2 != Record.size())
+        return Error("Invalid record");
+
+      I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+      InstructionList.push_back(I);
+      break;
+    }
+    case FUNC_CODE_INST_STORE_2_7: {
+      unsigned OpNum = 0;
+      Value *Val, *Ptr;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Val) ||
+          getValue(Record, OpNum,
+                   PointerType::getUnqual(Val->getType()), Ptr)||
+          OpNum+2 != Record.size()) {
+        return Error("Invalid record");
+      }
+      I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+      InstructionList.push_back(I);
+      break;
+    }
+    case FUNC_CODE_INST_CALL_2_7:
+      LLVM2_7MetadataDetected = true;
+    case bitc::FUNC_CODE_INST_CALL: {
+      // CALL: [paramattrs, cc, fnty, fnid, arg0, arg1...]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+
+      AttributeSet PAL = getAttributes(Record[0]);
+      unsigned CCInfo = Record[1];
+
+      unsigned OpNum = 2;
+      Value *Callee;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
+        return Error("Invalid record");
+
+      PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
+      FunctionType *FTy = nullptr;
+      if (OpTy) FTy = dyn_cast<FunctionType>(OpTy->getElementType());
+      if (!FTy || Record.size() < FTy->getNumParams()+OpNum)
+        return Error("Invalid record");
+
+      SmallVector<Value*, 16> Args;
+      // Read the fixed params.
+      for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
+        if (FTy->getParamType(i)->isLabelTy())
+          Args.push_back(getBasicBlock(Record[OpNum]));
+        else
+          Args.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i)));
+        if (!Args.back())
+          return Error("Invalid record");
+      }
+
+      // Read type/value pairs for varargs params.
+      if (!FTy->isVarArg()) {
+        if (OpNum != Record.size())
+          return Error("Invalid record");
+      } else {
+        while (OpNum != Record.size()) {
+          Value *Op;
+          if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+            return Error("Invalid record");
+          Args.push_back(Op);
+        }
+      }
+
+      I = CallInst::Create(Callee, Args);
+      InstructionList.push_back(I);
+      cast<CallInst>(I)->setCallingConv(
+        static_cast<CallingConv::ID>(CCInfo>>1));
+      cast<CallInst>(I)->setTailCall(CCInfo & 1);
+      cast<CallInst>(I)->setAttributes(PAL);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_VAARG: { // VAARG: [valistty, valist, instty]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      Type *OpTy = getTypeByID(Record[0]);
+      Value *Op = getFnValueByID(Record[1], OpTy);
+      Type *ResTy = getTypeByID(Record[2]);
+      if (!OpTy || !Op || !ResTy)
+        return Error("Invalid record");
+      I = new VAArgInst(Op, ResTy);
+      InstructionList.push_back(I);
+      break;
+    }
+    }
+
+    // Add instruction to end of current BB.  If there is no current BB, reject
+    // this file.
+    if (!CurBB) {
+      delete I;
+      return Error("Invalid instruction with no BB");
+    }
+    CurBB->getInstList().push_back(I);
+
+    // If this was a terminator instruction, move to the next block.
+    if (isa<TerminatorInst>(I)) {
+      ++CurBBNo;
+      CurBB = CurBBNo < FunctionBBs.size() ? FunctionBBs[CurBBNo] : nullptr;
+    }
+
+    // Non-void values get registered in the value table for future use.
+    if (I && !I->getType()->isVoidTy())
+      ValueList.AssignValue(I, NextValueNo++);
+  }
+
+  // Check the function list for unresolved values.
+  if (Argument *A = dyn_cast<Argument>(ValueList.back())) {
+    if (!A->getParent()) {
+      // We found at least one unresolved value.  Nuke them all to avoid leaks.
+      for (unsigned i = ModuleValueListSize, e = ValueList.size(); i != e; ++i){
+        if ((A = dyn_cast_or_null<Argument>(ValueList[i])) && !A->getParent()) {
+          A->replaceAllUsesWith(UndefValue::get(A->getType()));
+          delete A;
+        }
+      }
+      return Error("Never resolved value found in function");
+    }
+  }
+
+  // FIXME: Check for unresolved forward-declared metadata references
+  // and clean up leaks.
+
+  // See if anything took the address of blocks in this function.  If so,
+  // resolve them now.
+  DenseMap<Function*, std::vector<BlockAddrRefTy> >::iterator BAFRI =
+    BlockAddrFwdRefs.find(F);
+  if (BAFRI != BlockAddrFwdRefs.end()) {
+    std::vector<BlockAddrRefTy> &RefList = BAFRI->second;
+    for (unsigned i = 0, e = RefList.size(); i != e; ++i) {
+      unsigned BlockIdx = RefList[i].first;
+      if (BlockIdx >= FunctionBBs.size())
+        return Error("Invalid ID");
+
+      GlobalVariable *FwdRef = RefList[i].second;
+      FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx]));
+      FwdRef->eraseFromParent();
+    }
+
+    BlockAddrFwdRefs.erase(BAFRI);
+  }
+
+  unsigned NewMDValueListSize = MDValueList.size();
+  // Trim the value list down to the size it was before we parsed this function.
+  ValueList.shrinkTo(ModuleValueListSize);
+  MDValueList.shrinkTo(ModuleMDValueListSize);
+
+  if (LLVM2_7MetadataDetected) {
+    MDValueList.resize(NewMDValueListSize);
+  }
+
+  std::vector<BasicBlock*>().swap(FunctionBBs);
+  return std::error_code();
+}
+
+//===----------------------------------------------------------------------===//
+// GVMaterializer implementation
+//===----------------------------------------------------------------------===//
+
+void BitcodeReader::releaseBuffer() { Buffer.release(); }
+
+std::error_code BitcodeReader::materialize(GlobalValue *GV) {
+  if (std::error_code EC = materializeMetadata())
+    return EC;
+
+  Function *F = dyn_cast<Function>(GV);
+  // If it's not a function or is already material, ignore the request.
+  if (!F || !F->isMaterializable())
+    return std::error_code();
+
+  DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F);
+  assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
+
+  // Move the bit stream to the saved position of the deferred function body.
+  Stream.JumpToBit(DFII->second);
+
+  if (std::error_code EC = ParseFunctionBody(F))
+    return EC;
+  F->setIsMaterializable(false);
+
+  // Upgrade any old intrinsic calls in the function.
+  for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(),
+       E = UpgradedIntrinsics.end(); I != E; ++I) {
+    if (I->first != I->second) {
+      for (auto UI = I->first->user_begin(), UE = I->first->user_end();
+           UI != UE;) {
+        if (CallInst* CI = dyn_cast<CallInst>(*UI++))
+          UpgradeIntrinsicCall(CI, I->second);
+      }
+    }
+  }
+
+  return std::error_code();
+}
+
+bool BitcodeReader::isDematerializable(const GlobalValue *GV) const {
+  const Function *F = dyn_cast<Function>(GV);
+  if (!F || F->isDeclaration())
+    return false;
+  return DeferredFunctionInfo.count(const_cast<Function*>(F));
+}
+
+void BitcodeReader::dematerialize(GlobalValue *GV) {
+  Function *F = dyn_cast<Function>(GV);
+  // If this function isn't dematerializable, this is a noop.
+  if (!F || !isDematerializable(F))
+    return;
+
+  assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
+
+  // Just forget the function body, we can remat it later.
+  F->deleteBody();
+  F->setIsMaterializable(true);
+}
+
+std::error_code BitcodeReader::materializeModule() {
+  // Iterate over the module, deserializing any functions that are still on
+  // disk.
+  for (Module::iterator F = TheModule->begin(), E = TheModule->end();
+       F != E; ++F) {
+    if (std::error_code EC = materialize(&*F))
+      return EC;
+  }
+  // At this point, if there are any function bodies, the current bit is
+  // pointing to the END_BLOCK record after them. Now make sure the rest
+  // of the bits in the module have been read.
+  if (NextUnreadBit)
+    ParseModule(true);
+
+  // Upgrade any intrinsic calls that slipped through (should not happen!) and
+  // delete the old functions to clean up. We can't do this unless the entire
+  // module is materialized because there could always be another function body
+  // with calls to the old function.
+  for (std::vector<std::pair<Function*, Function*> >::iterator I =
+       UpgradedIntrinsics.begin(), E = UpgradedIntrinsics.end(); I != E; ++I) {
+    if (I->first != I->second) {
+      for (auto UI = I->first->user_begin(), UE = I->first->user_end();
+           UI != UE;) {
+        if (CallInst* CI = dyn_cast<CallInst>(*UI++))
+          UpgradeIntrinsicCall(CI, I->second);
+      }
+      if (!I->first->use_empty())
+        I->first->replaceAllUsesWith(I->second);
+      I->first->eraseFromParent();
+    }
+  }
+  std::vector<std::pair<Function*, Function*> >().swap(UpgradedIntrinsics);
+
+  // Check debug info intrinsics.
+  CheckDebugInfoIntrinsics(TheModule);
+
+  return std::error_code();
+}
+
+std::vector<StructType *> BitcodeReader::getIdentifiedStructTypes() const {
+  return IdentifiedStructTypes;
+}
+
+std::error_code BitcodeReader::InitStream() {
+  if (LazyStreamer)
+    return InitLazyStream();
+  return InitStreamFromBuffer();
+}
+
+std::error_code BitcodeReader::InitStreamFromBuffer() {
+  const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart();
+  const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
+
+  if (Buffer->getBufferSize() & 3)
+    return Error("Invalid bitcode signature");
+
+  // If we have a wrapper header, parse it and ignore the non-bc file contents.
+  // The magic number is 0x0B17C0DE stored in little endian.
+  if (isBitcodeWrapper(BufPtr, BufEnd))
+    if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true))
+      return Error("Invalid bitcode wrapper header");
+
+  StreamFile.reset(new BitstreamReader(BufPtr, BufEnd));
+  Stream.init(&*StreamFile);
+
+  return std::error_code();
+}
+
+std::error_code BitcodeReader::InitLazyStream() {
+  // Check and strip off the bitcode wrapper; BitstreamReader expects never to
+  // see it.
+  auto OwnedBytes = llvm::make_unique<StreamingMemoryObject>(
+      std::move(LazyStreamer));
+  StreamingMemoryObject &Bytes = *OwnedBytes;
+  StreamFile = llvm::make_unique<BitstreamReader>(std::move(OwnedBytes));
+  Stream.init(&*StreamFile);
+
+  unsigned char buf[16];
+  if (Bytes.readBytes(buf, 16, 0) != 16)
+    return Error("Invalid bitcode signature");
+
+  if (!isBitcode(buf, buf + 16))
+    return Error("Invalid bitcode signature");
+
+  if (isBitcodeWrapper(buf, buf + 4)) {
+    const unsigned char *bitcodeStart = buf;
+    const unsigned char *bitcodeEnd = buf + 16;
+    SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false);
+    Bytes.dropLeadingBytes(bitcodeStart - buf);
+    Bytes.setKnownObjectSize(bitcodeEnd - bitcodeStart);
+  }
+  return std::error_code();
+}
+
+namespace {
+class BitcodeErrorCategoryType : public std::error_category {
+  const char *name() const LLVM_NOEXCEPT override {
+    return "llvm.bitcode";
+  }
+  std::string message(int IE) const override {
+    BitcodeError E = static_cast<BitcodeError>(IE);
+    switch (E) {
+    case BitcodeError::InvalidBitcodeSignature:
+      return "Invalid bitcode signature";
+    case BitcodeError::CorruptedBitcode:
+      return "Corrupted bitcode";
+    }
+    llvm_unreachable("Unknown error type!");
+  }
+};
+}
+
+static ManagedStatic<BitcodeErrorCategoryType> ErrorCategory;
+
+const std::error_category &BitcodeReader::BitcodeErrorCategory() {
+  return *ErrorCategory;
+}
+
+//===----------------------------------------------------------------------===//
+// External interface
+//===----------------------------------------------------------------------===//
+
+/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
+///
+static llvm::ErrorOr<llvm::Module *>
+getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
+                         LLVMContext &Context, bool WillMaterializeAll,
+                         const DiagnosticHandlerFunction &DiagnosticHandler) {
+  Module *M = new Module(Buffer->getBufferIdentifier(), Context);
+  BitcodeReader *R =
+      new BitcodeReader(Buffer.get(), Context, DiagnosticHandler);
+  M->setMaterializer(R);
+
+  auto cleanupOnError = [&](std::error_code EC) {
+    R->releaseBuffer(); // Never take ownership on error.
+    delete M;  // Also deletes R.
+    return EC;
+  };
+
+  if (std::error_code EC = R->ParseBitcodeInto(M))
+    return cleanupOnError(EC);
+
+  Buffer.release(); // The BitcodeReader owns it now.
+  return M;
+}
+
+llvm::ErrorOr<Module *>
+llvm_2_7::getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
+                           LLVMContext &Context,
+                           const DiagnosticHandlerFunction &DiagnosticHandler) {
+  return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false,
+                                  DiagnosticHandler);
+}
+
+/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+/// If an error occurs, return null and fill in *ErrMsg if non-null.
+llvm::ErrorOr<llvm::Module *>
+llvm_2_7::parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
+                       const DiagnosticHandlerFunction &DiagnosticHandler) {
+  std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
+  ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModuleImpl(
+      std::move(Buf), Context, true, DiagnosticHandler);
+  if (!ModuleOrErr)
+    return ModuleOrErr;
+  Module *M = ModuleOrErr.get();
+  // Read in the entire module, and destroy the BitcodeReader.
+  if (std::error_code EC = M->materializeAll()) {
+    delete M;
+    return EC;
+  }
+
+  return M;
+}
+
+std::string
+llvm_2_7::getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context,
+                             DiagnosticHandlerFunction DiagnosticHandler) {
+  std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
+  auto R = llvm::make_unique<BitcodeReader>(Buf.release(), Context,
+                                            DiagnosticHandler);
+  ErrorOr<std::string> Triple = R->parseTriple();
+  if (Triple.getError())
+    return "";
+  return Triple.get();
+}
diff --git a/libbcc/bcinfo/BitReader_2_7/CMakeLists.txt b/libbcc/bcinfo/BitReader_2_7/CMakeLists.txt
new file mode 100644
index 0000000..693d431
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_2_7/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_llvm_library(LLVMBitReader
+  BitReader.cpp
+  BitcodeReader.cpp
+  )
diff --git a/libbcc/bcinfo/BitReader_2_7/Makefile b/libbcc/bcinfo/BitReader_2_7/Makefile
new file mode 100644
index 0000000..59af8d5
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_2_7/Makefile
@@ -0,0 +1,15 @@
+##===- lib/Bitcode/Reader/Makefile -------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME = LLVMBitReader
+BUILD_ARCHIVE = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/libbcc/bcinfo/BitReader_3_0/Android.mk b/libbcc/bcinfo/BitReader_3_0/Android.mk
new file mode 100644
index 0000000..dd6ce8d
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_3_0/Android.mk
@@ -0,0 +1,37 @@
+LOCAL_PATH:= $(call my-dir)
+
+LLVM_ROOT_PATH := external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+
+bitcode_reader_3_0_SRC_FILES := \
+  BitcodeReader.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libLLVMBitReader_3_0
+LOCAL_MODULE_HOST_OS := darwin linux windows
+
+LOCAL_SRC_FILES := $(bitcode_reader_3_0_SRC_FILES)
+LOCAL_CFLAGS += -D__HOST__
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS))
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libLLVMBitReader_3_0
+
+LOCAL_SRC_FILES := $(bitcode_reader_3_0_SRC_FILES)
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
+endif
diff --git a/libbcc/bcinfo/BitReader_3_0/BitReader.cpp b/libbcc/bcinfo/BitReader_3_0/BitReader.cpp
new file mode 100644
index 0000000..15844c0
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_3_0/BitReader.cpp
@@ -0,0 +1,88 @@
+//===-- BitReader.cpp -----------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/BitReader.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <string>
+#include <cstring>
+
+using namespace llvm;
+
+/* Builds a module from the bitcode in the specified memory buffer, returning a
+   reference to the module via the OutModule parameter. Returns 0 on success.
+   Optionally returns a human-readable error message via OutMessage. */
+LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
+                          LLVMModuleRef *OutModule, char **OutMessage) {
+  return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule,
+                                   OutMessage);
+}
+
+LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
+                                   LLVMMemoryBufferRef MemBuf,
+                                   LLVMModuleRef *OutModule,
+                                   char **OutMessage) {
+  std::string Message;
+  
+  *OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), *unwrap(ContextRef),
+                                     &Message));
+  if (!*OutModule) {
+    if (OutMessage)
+      *OutMessage = strdup(Message.c_str());
+    return 1;
+  }
+  
+  return 0;
+}
+
+/* Reads a module from the specified path, returning via the OutModule parameter
+   a module provider which performs lazy deserialization. Returns 0 on success.
+   Optionally returns a human-readable error message via OutMessage. */ 
+LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
+                                       LLVMMemoryBufferRef MemBuf,
+                                       LLVMModuleRef *OutM,
+                                       char **OutMessage) {
+  std::string Message;
+  
+  *OutM = wrap(getLazyBitcodeModule(unwrap(MemBuf), *unwrap(ContextRef),
+                                    &Message));
+  if (!*OutM) {
+    if (OutMessage)
+      *OutMessage = strdup(Message.c_str());
+    return 1;
+  }
+  
+  return 0;
+
+}
+
+LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
+                              char **OutMessage) {
+  return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM,
+                                       OutMessage);
+}
+
+/* Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
+LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
+                                               LLVMMemoryBufferRef MemBuf,
+                                               LLVMModuleProviderRef *OutMP,
+                                               char **OutMessage) {
+  return LLVMGetBitcodeModuleInContext(ContextRef, MemBuf,
+                                       reinterpret_cast<LLVMModuleRef*>(OutMP),
+                                       OutMessage);
+}
+
+/* Deprecated: Use LLVMGetBitcodeModule instead. */
+LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
+                                      LLVMModuleProviderRef *OutMP,
+                                      char **OutMessage) {
+  return LLVMGetBitcodeModuleProviderInContext(LLVMGetGlobalContext(), MemBuf,
+                                               OutMP, OutMessage);
+}
diff --git a/libbcc/bcinfo/BitReader_3_0/BitReader_3_0.h b/libbcc/bcinfo/BitReader_3_0/BitReader_3_0.h
new file mode 100644
index 0000000..d10f8b3
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_3_0/BitReader_3_0.h
@@ -0,0 +1,65 @@
+//===- BitReader_3_0.h - Internal BitcodeReader 3.0 impl --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the BitcodeReader class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BITREADER_3_0_H
+#define BITREADER_3_0_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/GVMaterializer.h"
+#include "llvm/IR/OperandTraits.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/ErrorOr.h"
+#include <string>
+
+namespace llvm {
+  class LLVMContext;
+  class MemoryBuffer;
+  class MemoryBufferRef;
+  class Module;
+} // End llvm namespace
+
+namespace llvm_3_0 {
+
+using llvm::DiagnosticHandlerFunction;
+using llvm::LLVMContext;
+using llvm::MemoryBuffer;
+using llvm::MemoryBufferRef;
+
+
+  /// Read the header of the specified bitcode buffer and prepare for lazy
+  /// deserialization of function bodies.  If successful, this moves Buffer. On
+  /// error, this *does not* move Buffer.
+  llvm::ErrorOr<llvm::Module *>
+  getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
+                       LLVMContext &Context,
+                       const DiagnosticHandlerFunction &DiagnosticHandler = nullptr);
+
+  /// Read the header of the specified bitcode buffer and extract just the
+  /// triple information. If successful, this returns a string. On error, this
+  /// returns "".
+  std::string
+  getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context,
+                         DiagnosticHandlerFunction DiagnosticHandler = nullptr);
+
+  /// Read the specified bitcode file, returning the module.
+  llvm::ErrorOr<llvm::Module *>
+  parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
+                   const DiagnosticHandlerFunction &DiagnosticHandler = nullptr);
+} // End llvm_3_0 namespace
+
+#endif
diff --git a/libbcc/bcinfo/BitReader_3_0/BitcodeReader.cpp b/libbcc/bcinfo/BitReader_3_0/BitcodeReader.cpp
new file mode 100644
index 0000000..a768cf6
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_3_0/BitcodeReader.cpp
@@ -0,0 +1,3882 @@
+//===- BitcodeReader.cpp - Internal BitcodeReader implementation ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the BitcodeReader class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "BitReader_3_0.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/AutoUpgrade.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/GVMaterializer.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/OperandTraits.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+using namespace llvm_3_0;
+
+#define FUNC_CODE_INST_UNWIND_2_7     14
+#define eh_exception_2_7             145
+#define eh_selector_2_7              149
+
+#define TYPE_BLOCK_ID_OLD_3_0         10
+#define TYPE_SYMTAB_BLOCK_ID_OLD_3_0  13
+#define TYPE_CODE_STRUCT_OLD_3_0      10
+
+namespace {
+  void FindExnAndSelIntrinsics(BasicBlock *BB, CallInst *&Exn,
+                                      CallInst *&Sel,
+                                      SmallPtrSet<BasicBlock*, 8> &Visited) {
+    if (!Visited.insert(BB).second) return;
+
+    for (BasicBlock::iterator
+           I = BB->begin(), E = BB->end(); I != E; ++I) {
+      if (CallInst *CI = dyn_cast<CallInst>(I)) {
+        switch (CI->getCalledFunction()->getIntrinsicID()) {
+        default: break;
+        case eh_exception_2_7:
+          assert(!Exn && "Found more than one eh.exception call!");
+          Exn = CI;
+          break;
+        case eh_selector_2_7:
+          assert(!Sel && "Found more than one eh.selector call!");
+          Sel = CI;
+          break;
+        }
+
+        if (Exn && Sel) return;
+      }
+    }
+
+    if (Exn && Sel) return;
+
+    for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
+      FindExnAndSelIntrinsics(*I, Exn, Sel, Visited);
+      if (Exn && Sel) return;
+    }
+  }
+
+
+
+  /// TransferClausesToLandingPadInst - Transfer the exception handling clauses
+  /// from the eh_selector call to the new landingpad instruction.
+  void TransferClausesToLandingPadInst(LandingPadInst *LPI,
+                                              CallInst *EHSel) {
+    LLVMContext &Context = LPI->getContext();
+    unsigned N = EHSel->getNumArgOperands();
+
+    for (unsigned i = N - 1; i > 1; --i) {
+      if (const ConstantInt *CI = dyn_cast<ConstantInt>(EHSel->getArgOperand(i))){
+        unsigned FilterLength = CI->getZExtValue();
+        unsigned FirstCatch = i + FilterLength + !FilterLength;
+        assert(FirstCatch <= N && "Invalid filter length");
+
+        if (FirstCatch < N)
+          for (unsigned j = FirstCatch; j < N; ++j) {
+            Value *Val = EHSel->getArgOperand(j);
+            if (!Val->hasName() || Val->getName() != "llvm.eh.catch.all.value") {
+              LPI->addClause(cast<Constant>(EHSel->getArgOperand(j)));
+            } else {
+              GlobalVariable *GV = cast<GlobalVariable>(Val);
+              LPI->addClause(GV->getInitializer());
+            }
+          }
+
+        if (!FilterLength) {
+          // Cleanup.
+          LPI->setCleanup(true);
+        } else {
+          // Filter.
+          SmallVector<Constant *, 4> TyInfo;
+          TyInfo.reserve(FilterLength - 1);
+          for (unsigned j = i + 1; j < FirstCatch; ++j)
+            TyInfo.push_back(cast<Constant>(EHSel->getArgOperand(j)));
+          ArrayType *AType =
+            ArrayType::get(!TyInfo.empty() ? TyInfo[0]->getType() :
+                           PointerType::getUnqual(Type::getInt8Ty(Context)),
+                           TyInfo.size());
+          LPI->addClause(ConstantArray::get(AType, TyInfo));
+        }
+
+        N = i;
+      }
+    }
+
+    if (N > 2)
+      for (unsigned j = 2; j < N; ++j) {
+        Value *Val = EHSel->getArgOperand(j);
+        if (!Val->hasName() || Val->getName() != "llvm.eh.catch.all.value") {
+          LPI->addClause(cast<Constant>(EHSel->getArgOperand(j)));
+        } else {
+          GlobalVariable *GV = cast<GlobalVariable>(Val);
+          LPI->addClause(GV->getInitializer());
+        }
+      }
+  }
+
+
+  /// This function upgrades the old pre-3.0 exception handling system to the new
+  /// one. N.B. This will be removed in 3.1.
+  void UpgradeExceptionHandling(Module *M) {
+    Function *EHException = M->getFunction("llvm.eh.exception");
+    Function *EHSelector = M->getFunction("llvm.eh.selector");
+    if (!EHException || !EHSelector)
+      return;
+
+    LLVMContext &Context = M->getContext();
+    Type *ExnTy = PointerType::getUnqual(Type::getInt8Ty(Context));
+    Type *SelTy = Type::getInt32Ty(Context);
+    Type *LPadSlotTy = StructType::get(ExnTy, SelTy, nullptr);
+
+    // This map links the invoke instruction with the eh.exception and eh.selector
+    // calls associated with it.
+    DenseMap<InvokeInst*, std::pair<Value*, Value*> > InvokeToIntrinsicsMap;
+    for (Module::iterator
+           I = M->begin(), E = M->end(); I != E; ++I) {
+      Function &F = *I;
+
+      for (Function::iterator
+             II = F.begin(), IE = F.end(); II != IE; ++II) {
+        BasicBlock *BB = &*II;
+        InvokeInst *Inst = dyn_cast<InvokeInst>(BB->getTerminator());
+        if (!Inst) continue;
+        BasicBlock *UnwindDest = Inst->getUnwindDest();
+        if (UnwindDest->isLandingPad()) continue; // Already converted.
+
+        SmallPtrSet<BasicBlock*, 8> Visited;
+        CallInst *Exn = 0;
+        CallInst *Sel = 0;
+        FindExnAndSelIntrinsics(UnwindDest, Exn, Sel, Visited);
+        assert(Exn && Sel && "Cannot find eh.exception and eh.selector calls!");
+        InvokeToIntrinsicsMap[Inst] = std::make_pair(Exn, Sel);
+      }
+    }
+
+    // This map stores the slots where the exception object and selector value are
+    // stored within a function.
+    DenseMap<Function*, std::pair<Value*, Value*> > FnToLPadSlotMap;
+    SmallPtrSet<Instruction*, 32> DeadInsts;
+    for (DenseMap<InvokeInst*, std::pair<Value*, Value*> >::iterator
+           I = InvokeToIntrinsicsMap.begin(), E = InvokeToIntrinsicsMap.end();
+         I != E; ++I) {
+      InvokeInst *Invoke = I->first;
+      BasicBlock *UnwindDest = Invoke->getUnwindDest();
+      Function *F = UnwindDest->getParent();
+      std::pair<Value*, Value*> EHIntrinsics = I->second;
+      CallInst *Exn = cast<CallInst>(EHIntrinsics.first);
+      CallInst *Sel = cast<CallInst>(EHIntrinsics.second);
+
+      // Store the exception object and selector value in the entry block.
+      Value *ExnSlot = 0;
+      Value *SelSlot = 0;
+      if (!FnToLPadSlotMap[F].first) {
+        BasicBlock *Entry = &F->front();
+        ExnSlot = new AllocaInst(ExnTy, "exn", Entry->getTerminator());
+        SelSlot = new AllocaInst(SelTy, "sel", Entry->getTerminator());
+        FnToLPadSlotMap[F] = std::make_pair(ExnSlot, SelSlot);
+      } else {
+        ExnSlot = FnToLPadSlotMap[F].first;
+        SelSlot = FnToLPadSlotMap[F].second;
+      }
+
+      if (!UnwindDest->getSinglePredecessor()) {
+        // The unwind destination doesn't have a single predecessor. Create an
+        // unwind destination which has only one predecessor.
+        BasicBlock *NewBB = BasicBlock::Create(Context, "new.lpad",
+                                               UnwindDest->getParent());
+        BranchInst::Create(UnwindDest, NewBB);
+        Invoke->setUnwindDest(NewBB);
+
+        // Fix up any PHIs in the original unwind destination block.
+        for (BasicBlock::iterator
+               II = UnwindDest->begin(); isa<PHINode>(II); ++II) {
+          PHINode *PN = cast<PHINode>(II);
+          int Idx = PN->getBasicBlockIndex(Invoke->getParent());
+          if (Idx == -1) continue;
+          PN->setIncomingBlock(Idx, NewBB);
+        }
+
+        UnwindDest = NewBB;
+      }
+
+      IRBuilder<> Builder(Context);
+      Builder.SetInsertPoint(UnwindDest, UnwindDest->getFirstInsertionPt());
+
+      LandingPadInst *LPI = Builder.CreateLandingPad(LPadSlotTy, 0);
+      Value *LPExn = Builder.CreateExtractValue(LPI, 0);
+      Value *LPSel = Builder.CreateExtractValue(LPI, 1);
+      Builder.CreateStore(LPExn, ExnSlot);
+      Builder.CreateStore(LPSel, SelSlot);
+
+      TransferClausesToLandingPadInst(LPI, Sel);
+
+      DeadInsts.insert(Exn);
+      DeadInsts.insert(Sel);
+    }
+
+    // Replace the old intrinsic calls with the values from the landingpad
+    // instruction(s). These values were stored in allocas for us to use here.
+    for (DenseMap<InvokeInst*, std::pair<Value*, Value*> >::iterator
+           I = InvokeToIntrinsicsMap.begin(), E = InvokeToIntrinsicsMap.end();
+         I != E; ++I) {
+      std::pair<Value*, Value*> EHIntrinsics = I->second;
+      CallInst *Exn = cast<CallInst>(EHIntrinsics.first);
+      CallInst *Sel = cast<CallInst>(EHIntrinsics.second);
+      BasicBlock *Parent = Exn->getParent();
+
+      std::pair<Value*,Value*> ExnSelSlots = FnToLPadSlotMap[Parent->getParent()];
+
+      IRBuilder<> Builder(Context);
+      Builder.SetInsertPoint(Parent, Exn->getIterator());
+      LoadInst *LPExn = Builder.CreateLoad(ExnSelSlots.first, "exn.load");
+      LoadInst *LPSel = Builder.CreateLoad(ExnSelSlots.second, "sel.load");
+
+      Exn->replaceAllUsesWith(LPExn);
+      Sel->replaceAllUsesWith(LPSel);
+    }
+
+    // Remove the dead instructions.
+    for (SmallPtrSet<Instruction*, 32>::iterator
+           I = DeadInsts.begin(), E = DeadInsts.end(); I != E; ++I) {
+      Instruction *Inst = *I;
+      Inst->eraseFromParent();
+    }
+
+    // Replace calls to "llvm.eh.resume" with the 'resume' instruction. Load the
+    // exception and selector values from the stored place.
+    Function *EHResume = M->getFunction("llvm.eh.resume");
+    if (!EHResume) return;
+
+    while (!EHResume->use_empty()) {
+      CallInst *Resume = cast<CallInst>(*EHResume->use_begin());
+      BasicBlock *BB = Resume->getParent();
+
+      IRBuilder<> Builder(Context);
+      Builder.SetInsertPoint(BB, Resume->getIterator());
+
+      Value *LPadVal =
+        Builder.CreateInsertValue(UndefValue::get(LPadSlotTy),
+                                  Resume->getArgOperand(0), 0, "lpad.val");
+      LPadVal = Builder.CreateInsertValue(LPadVal, Resume->getArgOperand(1),
+                                          1, "lpad.val");
+      Builder.CreateResume(LPadVal);
+
+      // Remove all instructions after the 'resume.'
+      BasicBlock::iterator I = Resume->getIterator();
+      while (I != BB->end()) {
+        Instruction *Inst = &*I++;
+        Inst->eraseFromParent();
+      }
+    }
+  }
+
+
+  void StripDebugInfoOfFunction(Module* M, const char* name) {
+    if (Function* FuncStart = M->getFunction(name)) {
+      while (!FuncStart->use_empty()) {
+        cast<CallInst>(*FuncStart->use_begin())->eraseFromParent();
+      }
+      FuncStart->eraseFromParent();
+    }
+  }
+
+  /// This function strips all debug info intrinsics, except for llvm.dbg.declare.
+  /// If an llvm.dbg.declare intrinsic is invalid, then this function simply
+  /// strips that use.
+  void CheckDebugInfoIntrinsics(Module *M) {
+    StripDebugInfoOfFunction(M, "llvm.dbg.func.start");
+    StripDebugInfoOfFunction(M, "llvm.dbg.stoppoint");
+    StripDebugInfoOfFunction(M, "llvm.dbg.region.start");
+    StripDebugInfoOfFunction(M, "llvm.dbg.region.end");
+
+    if (Function *Declare = M->getFunction("llvm.dbg.declare")) {
+      if (!Declare->use_empty()) {
+        DbgDeclareInst *DDI = cast<DbgDeclareInst>(*Declare->use_begin());
+        if (!isa<MDNode>(ValueAsMetadata::get(DDI->getArgOperand(0))) ||
+            !isa<MDNode>(ValueAsMetadata::get(DDI->getArgOperand(1)))) {
+          while (!Declare->use_empty()) {
+            CallInst *CI = cast<CallInst>(*Declare->use_begin());
+            CI->eraseFromParent();
+          }
+          Declare->eraseFromParent();
+        }
+      }
+    }
+  }
+
+
+//===----------------------------------------------------------------------===//
+//                          BitcodeReaderValueList Class
+//===----------------------------------------------------------------------===//
+
+class BitcodeReaderValueList {
+  std::vector<WeakVH> ValuePtrs;
+
+  /// ResolveConstants - As we resolve forward-referenced constants, we add
+  /// information about them to this vector.  This allows us to resolve them in
+  /// bulk instead of resolving each reference at a time.  See the code in
+  /// ResolveConstantForwardRefs for more information about this.
+  ///
+  /// The key of this vector is the placeholder constant, the value is the slot
+  /// number that holds the resolved value.
+  typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
+  ResolveConstantsTy ResolveConstants;
+  LLVMContext &Context;
+public:
+  explicit BitcodeReaderValueList(LLVMContext &C) : Context(C) {}
+  ~BitcodeReaderValueList() {
+    assert(ResolveConstants.empty() && "Constants not resolved?");
+  }
+
+  // vector compatibility methods
+  unsigned size() const { return ValuePtrs.size(); }
+  void resize(unsigned N) { ValuePtrs.resize(N); }
+  void push_back(Value *V) {
+    ValuePtrs.push_back(V);
+  }
+
+  void clear() {
+    assert(ResolveConstants.empty() && "Constants not resolved?");
+    ValuePtrs.clear();
+  }
+
+  Value *operator[](unsigned i) const {
+    assert(i < ValuePtrs.size());
+    return ValuePtrs[i];
+  }
+
+  Value *back() const { return ValuePtrs.back(); }
+    void pop_back() { ValuePtrs.pop_back(); }
+  bool empty() const { return ValuePtrs.empty(); }
+  void shrinkTo(unsigned N) {
+    assert(N <= size() && "Invalid shrinkTo request!");
+    ValuePtrs.resize(N);
+  }
+
+  Constant *getConstantFwdRef(unsigned Idx, Type *Ty);
+  Value *getValueFwdRef(unsigned Idx, Type *Ty);
+
+  void AssignValue(Value *V, unsigned Idx);
+
+  /// ResolveConstantForwardRefs - Once all constants are read, this method bulk
+  /// resolves any forward references.
+  void ResolveConstantForwardRefs();
+};
+
+
+//===----------------------------------------------------------------------===//
+//                          BitcodeReaderMDValueList Class
+//===----------------------------------------------------------------------===//
+
+class BitcodeReaderMDValueList {
+  unsigned NumFwdRefs;
+  bool AnyFwdRefs;
+  std::vector<TrackingMDRef> MDValuePtrs;
+
+  LLVMContext &Context;
+public:
+  explicit BitcodeReaderMDValueList(LLVMContext &C)
+      : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {}
+
+  // vector compatibility methods
+  unsigned size() const       { return MDValuePtrs.size(); }
+  void resize(unsigned N)     { MDValuePtrs.resize(N); }
+  void push_back(Metadata *MD) { MDValuePtrs.emplace_back(MD); }
+  void clear()                { MDValuePtrs.clear();  }
+  Metadata *back() const      { return MDValuePtrs.back(); }
+  void pop_back()             { MDValuePtrs.pop_back(); }
+  bool empty() const          { return MDValuePtrs.empty(); }
+
+  Metadata *operator[](unsigned i) const {
+    assert(i < MDValuePtrs.size());
+    return MDValuePtrs[i];
+  }
+
+  void shrinkTo(unsigned N) {
+    assert(N <= size() && "Invalid shrinkTo request!");
+    MDValuePtrs.resize(N);
+  }
+
+  Metadata *getValueFwdRef(unsigned Idx);
+  void AssignValue(Metadata *MD, unsigned Idx);
+  void tryToResolveCycles();
+};
+
+class BitcodeReader : public GVMaterializer {
+  LLVMContext &Context;
+  DiagnosticHandlerFunction DiagnosticHandler;
+  Module *TheModule;
+  std::unique_ptr<MemoryBuffer> Buffer;
+  std::unique_ptr<BitstreamReader> StreamFile;
+  BitstreamCursor Stream;
+  std::unique_ptr<DataStreamer> LazyStreamer;
+  uint64_t NextUnreadBit;
+  bool SeenValueSymbolTable;
+
+  std::vector<Type*> TypeList;
+  BitcodeReaderValueList ValueList;
+  BitcodeReaderMDValueList MDValueList;
+  SmallVector<Instruction *, 64> InstructionList;
+
+  std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
+  std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
+
+  /// MAttributes - The set of attributes by index.  Index zero in the
+  /// file is for null, and is thus not represented here.  As such all indices
+  /// are off by one.
+  std::vector<AttributeSet> MAttributes;
+
+  /// \brief The set of attribute groups.
+  std::map<unsigned, AttributeSet> MAttributeGroups;
+
+  /// FunctionBBs - While parsing a function body, this is a list of the basic
+  /// blocks for the function.
+  std::vector<BasicBlock*> FunctionBBs;
+
+  // When reading the module header, this list is populated with functions that
+  // have bodies later in the file.
+  std::vector<Function*> FunctionsWithBodies;
+
+  // When intrinsic functions are encountered which require upgrading they are
+  // stored here with their replacement function.
+  typedef std::vector<std::pair<Function*, Function*> > UpgradedIntrinsicMap;
+  UpgradedIntrinsicMap UpgradedIntrinsics;
+
+  // Map the bitcode's custom MDKind ID to the Module's MDKind ID.
+  DenseMap<unsigned, unsigned> MDKindMap;
+
+  // Several operations happen after the module header has been read, but
+  // before function bodies are processed. This keeps track of whether
+  // we've done this yet.
+  bool SeenFirstFunctionBody;
+
+  /// DeferredFunctionInfo - When function bodies are initially scanned, this
+  /// map contains info about where to find deferred function body in the
+  /// stream.
+  DenseMap<Function*, uint64_t> DeferredFunctionInfo;
+
+  /// BlockAddrFwdRefs - These are blockaddr references to basic blocks.  These
+  /// are resolved lazily when functions are loaded.
+  typedef std::pair<unsigned, GlobalVariable*> BlockAddrRefTy;
+  DenseMap<Function*, std::vector<BlockAddrRefTy> > BlockAddrFwdRefs;
+
+  static const std::error_category &BitcodeErrorCategory();
+
+public:
+  std::error_code Error(BitcodeError E, const Twine &Message);
+  std::error_code Error(BitcodeError E);
+  std::error_code Error(const Twine &Message);
+
+  explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
+                         DiagnosticHandlerFunction DiagnosticHandler);
+  ~BitcodeReader() { FreeState(); }
+
+  void FreeState();
+
+  void releaseBuffer();
+
+  bool isDematerializable(const GlobalValue *GV) const;
+  std::error_code materialize(GlobalValue *GV) override;
+  std::error_code materializeModule() override;
+  std::vector<StructType *> getIdentifiedStructTypes() const override;
+  void dematerialize(GlobalValue *GV);
+
+  /// @brief Main interface to parsing a bitcode buffer.
+  /// @returns true if an error occurred.
+  std::error_code ParseBitcodeInto(Module *M);
+
+  /// @brief Cheap mechanism to just extract module triple
+  /// @returns true if an error occurred.
+  llvm::ErrorOr<std::string> parseTriple();
+
+  static uint64_t decodeSignRotatedValue(uint64_t V);
+
+  /// Materialize any deferred Metadata block.
+  std::error_code materializeMetadata() override;
+
+  void setStripDebugInfo() override;
+
+private:
+  std::vector<StructType *> IdentifiedStructTypes;
+  StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name);
+  StructType *createIdentifiedStructType(LLVMContext &Context);
+
+  Type *getTypeByID(unsigned ID);
+  Type *getTypeByIDOrNull(unsigned ID);
+  Value *getFnValueByID(unsigned ID, Type *Ty) {
+    if (Ty && Ty->isMetadataTy())
+      return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID));
+    return ValueList.getValueFwdRef(ID, Ty);
+  }
+  Metadata *getFnMetadataByID(unsigned ID) {
+    return MDValueList.getValueFwdRef(ID);
+  }
+  BasicBlock *getBasicBlock(unsigned ID) const {
+    if (ID >= FunctionBBs.size()) return nullptr; // Invalid ID
+    return FunctionBBs[ID];
+  }
+  AttributeSet getAttributes(unsigned i) const {
+    if (i-1 < MAttributes.size())
+      return MAttributes[i-1];
+    return AttributeSet();
+  }
+
+  /// getValueTypePair - Read a value/type pair out of the specified record from
+  /// slot 'Slot'.  Increment Slot past the number of slots used in the record.
+  /// Return true on failure.
+  bool getValueTypePair(SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
+                        unsigned InstNum, Value *&ResVal) {
+    if (Slot == Record.size()) return true;
+    unsigned ValNo = (unsigned)Record[Slot++];
+    if (ValNo < InstNum) {
+      // If this is not a forward reference, just return the value we already
+      // have.
+      ResVal = getFnValueByID(ValNo, nullptr);
+      return ResVal == nullptr;
+    } else if (Slot == Record.size()) {
+      return true;
+    }
+
+    unsigned TypeNo = (unsigned)Record[Slot++];
+    ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
+    return ResVal == nullptr;
+  }
+  bool getValue(SmallVector<uint64_t, 64> &Record, unsigned &Slot,
+                Type *Ty, Value *&ResVal) {
+    if (Slot == Record.size()) return true;
+    unsigned ValNo = (unsigned)Record[Slot++];
+    ResVal = getFnValueByID(ValNo, Ty);
+    return ResVal == 0;
+  }
+
+
+  std::error_code ParseModule(bool Resume);
+  std::error_code ParseAttributeBlock();
+  std::error_code ParseTypeTable();
+  std::error_code ParseOldTypeTable();         // FIXME: Remove in LLVM 3.1
+  std::error_code ParseTypeTableBody();
+
+  std::error_code ParseOldTypeSymbolTable();   // FIXME: Remove in LLVM 3.1
+  std::error_code ParseValueSymbolTable();
+  std::error_code ParseConstants();
+  std::error_code RememberAndSkipFunctionBody();
+  std::error_code ParseFunctionBody(Function *F);
+  std::error_code GlobalCleanup();
+  std::error_code ResolveGlobalAndAliasInits();
+  std::error_code ParseMetadata();
+  std::error_code ParseMetadataAttachment();
+  llvm::ErrorOr<std::string> parseModuleTriple();
+  std::error_code InitStream();
+  std::error_code InitStreamFromBuffer();
+  std::error_code InitLazyStream();
+};
+
+} // end anonymous namespace
+
+static std::error_code Error(const DiagnosticHandlerFunction &DiagnosticHandler,
+                             std::error_code EC, const Twine &Message) {
+  BitcodeDiagnosticInfo DI(EC, DS_Error, Message);
+  DiagnosticHandler(DI);
+  return EC;
+}
+
+static std::error_code Error(const DiagnosticHandlerFunction &DiagnosticHandler,
+                             std::error_code EC) {
+  return Error(DiagnosticHandler, EC, EC.message());
+}
+
+std::error_code BitcodeReader::Error(BitcodeError E, const Twine &Message) {
+  return ::Error(DiagnosticHandler, make_error_code(E), Message);
+}
+
+std::error_code BitcodeReader::Error(const Twine &Message) {
+  return ::Error(DiagnosticHandler,
+                 make_error_code(BitcodeError::CorruptedBitcode), Message);
+}
+
+std::error_code BitcodeReader::Error(BitcodeError E) {
+  return ::Error(DiagnosticHandler, make_error_code(E));
+}
+
+static DiagnosticHandlerFunction getDiagHandler(DiagnosticHandlerFunction F,
+                                                LLVMContext &C) {
+  if (F)
+    return F;
+  return [&C](const DiagnosticInfo &DI) { C.diagnose(DI); };
+}
+
+BitcodeReader::BitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
+                             DiagnosticHandlerFunction DiagnosticHandler)
+    : Context(C), DiagnosticHandler(getDiagHandler(DiagnosticHandler, C)),
+      TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr),
+      NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
+      MDValueList(C), SeenFirstFunctionBody(false) {}
+
+
+void BitcodeReader::FreeState() {
+  Buffer = nullptr;
+  std::vector<Type*>().swap(TypeList);
+  ValueList.clear();
+  MDValueList.clear();
+
+  std::vector<AttributeSet>().swap(MAttributes);
+  std::vector<BasicBlock*>().swap(FunctionBBs);
+  std::vector<Function*>().swap(FunctionsWithBodies);
+  DeferredFunctionInfo.clear();
+  MDKindMap.clear();
+}
+
+//===----------------------------------------------------------------------===//
+//  Helper functions to implement forward reference resolution, etc.
+//===----------------------------------------------------------------------===//
+
+/// ConvertToString - Convert a string from a record into an std::string, return
+/// true on failure.
+template<typename StrTy>
+static bool ConvertToString(ArrayRef<uint64_t> Record, unsigned Idx,
+                            StrTy &Result) {
+  if (Idx > Record.size())
+    return true;
+
+  for (unsigned i = Idx, e = Record.size(); i != e; ++i)
+    Result += (char)Record[i];
+  return false;
+}
+
+static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
+  switch (Val) {
+  default: // Map unknown/new linkages to external
+  case 0:
+    return GlobalValue::ExternalLinkage;
+  case 1:
+    return GlobalValue::WeakAnyLinkage;
+  case 2:
+    return GlobalValue::AppendingLinkage;
+  case 3:
+    return GlobalValue::InternalLinkage;
+  case 4:
+    return GlobalValue::LinkOnceAnyLinkage;
+  case 5:
+    return GlobalValue::ExternalLinkage; // Obsolete DLLImportLinkage
+  case 6:
+    return GlobalValue::ExternalLinkage; // Obsolete DLLExportLinkage
+  case 7:
+    return GlobalValue::ExternalWeakLinkage;
+  case 8:
+    return GlobalValue::CommonLinkage;
+  case 9:
+    return GlobalValue::PrivateLinkage;
+  case 10:
+    return GlobalValue::WeakODRLinkage;
+  case 11:
+    return GlobalValue::LinkOnceODRLinkage;
+  case 12:
+    return GlobalValue::AvailableExternallyLinkage;
+  case 13:
+    return GlobalValue::PrivateLinkage; // Obsolete LinkerPrivateLinkage
+  case 14:
+    return GlobalValue::ExternalWeakLinkage; // Obsolete LinkerPrivateWeakLinkage
+  //ANDROID: convert LinkOnceODRAutoHideLinkage -> LinkOnceODRLinkage
+  case 15:
+    return GlobalValue::LinkOnceODRLinkage;
+  }
+}
+
+static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) {
+  switch (Val) {
+  default: // Map unknown visibilities to default.
+  case 0: return GlobalValue::DefaultVisibility;
+  case 1: return GlobalValue::HiddenVisibility;
+  case 2: return GlobalValue::ProtectedVisibility;
+  }
+}
+
+static GlobalVariable::ThreadLocalMode GetDecodedThreadLocalMode(unsigned Val) {
+  switch (Val) {
+    case 0: return GlobalVariable::NotThreadLocal;
+    default: // Map unknown non-zero value to general dynamic.
+    case 1: return GlobalVariable::GeneralDynamicTLSModel;
+    case 2: return GlobalVariable::LocalDynamicTLSModel;
+    case 3: return GlobalVariable::InitialExecTLSModel;
+    case 4: return GlobalVariable::LocalExecTLSModel;
+  }
+}
+
+static int GetDecodedCastOpcode(unsigned Val) {
+  switch (Val) {
+  default: return -1;
+  case bitc::CAST_TRUNC   : return Instruction::Trunc;
+  case bitc::CAST_ZEXT    : return Instruction::ZExt;
+  case bitc::CAST_SEXT    : return Instruction::SExt;
+  case bitc::CAST_FPTOUI  : return Instruction::FPToUI;
+  case bitc::CAST_FPTOSI  : return Instruction::FPToSI;
+  case bitc::CAST_UITOFP  : return Instruction::UIToFP;
+  case bitc::CAST_SITOFP  : return Instruction::SIToFP;
+  case bitc::CAST_FPTRUNC : return Instruction::FPTrunc;
+  case bitc::CAST_FPEXT   : return Instruction::FPExt;
+  case bitc::CAST_PTRTOINT: return Instruction::PtrToInt;
+  case bitc::CAST_INTTOPTR: return Instruction::IntToPtr;
+  case bitc::CAST_BITCAST : return Instruction::BitCast;
+  }
+}
+static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) {
+  switch (Val) {
+  default: return -1;
+  case bitc::BINOP_ADD:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add;
+  case bitc::BINOP_SUB:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub;
+  case bitc::BINOP_MUL:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul;
+  case bitc::BINOP_UDIV: return Instruction::UDiv;
+  case bitc::BINOP_SDIV:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv;
+  case bitc::BINOP_UREM: return Instruction::URem;
+  case bitc::BINOP_SREM:
+    return Ty->isFPOrFPVectorTy() ? Instruction::FRem : Instruction::SRem;
+  case bitc::BINOP_SHL:  return Instruction::Shl;
+  case bitc::BINOP_LSHR: return Instruction::LShr;
+  case bitc::BINOP_ASHR: return Instruction::AShr;
+  case bitc::BINOP_AND:  return Instruction::And;
+  case bitc::BINOP_OR:   return Instruction::Or;
+  case bitc::BINOP_XOR:  return Instruction::Xor;
+  }
+}
+
+static AtomicRMWInst::BinOp GetDecodedRMWOperation(unsigned Val) {
+  switch (Val) {
+  default: return AtomicRMWInst::BAD_BINOP;
+  case bitc::RMW_XCHG: return AtomicRMWInst::Xchg;
+  case bitc::RMW_ADD: return AtomicRMWInst::Add;
+  case bitc::RMW_SUB: return AtomicRMWInst::Sub;
+  case bitc::RMW_AND: return AtomicRMWInst::And;
+  case bitc::RMW_NAND: return AtomicRMWInst::Nand;
+  case bitc::RMW_OR: return AtomicRMWInst::Or;
+  case bitc::RMW_XOR: return AtomicRMWInst::Xor;
+  case bitc::RMW_MAX: return AtomicRMWInst::Max;
+  case bitc::RMW_MIN: return AtomicRMWInst::Min;
+  case bitc::RMW_UMAX: return AtomicRMWInst::UMax;
+  case bitc::RMW_UMIN: return AtomicRMWInst::UMin;
+  }
+}
+
+static AtomicOrdering GetDecodedOrdering(unsigned Val) {
+  switch (Val) {
+  case bitc::ORDERING_NOTATOMIC: return NotAtomic;
+  case bitc::ORDERING_UNORDERED: return Unordered;
+  case bitc::ORDERING_MONOTONIC: return Monotonic;
+  case bitc::ORDERING_ACQUIRE: return Acquire;
+  case bitc::ORDERING_RELEASE: return Release;
+  case bitc::ORDERING_ACQREL: return AcquireRelease;
+  default: // Map unknown orderings to sequentially-consistent.
+  case bitc::ORDERING_SEQCST: return SequentiallyConsistent;
+  }
+}
+
+static SynchronizationScope GetDecodedSynchScope(unsigned Val) {
+  switch (Val) {
+  case bitc::SYNCHSCOPE_SINGLETHREAD: return SingleThread;
+  default: // Map unknown scopes to cross-thread.
+  case bitc::SYNCHSCOPE_CROSSTHREAD: return CrossThread;
+  }
+}
+
+namespace llvm {
+namespace {
+  /// @brief A class for maintaining the slot number definition
+  /// as a placeholder for the actual definition for forward constants defs.
+  class ConstantPlaceHolder : public ConstantExpr {
+    void operator=(const ConstantPlaceHolder &) = delete;
+  public:
+    // allocate space for exactly one operand
+    void *operator new(size_t s) {
+      return User::operator new(s, 1);
+    }
+    explicit ConstantPlaceHolder(Type *Ty, LLVMContext& Context)
+      : ConstantExpr(Ty, Instruction::UserOp1, &Op<0>(), 1) {
+      Op<0>() = UndefValue::get(Type::getInt32Ty(Context));
+    }
+
+    /// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
+    static bool classof(const Value *V) {
+      return isa<ConstantExpr>(V) &&
+             cast<ConstantExpr>(V)->getOpcode() == Instruction::UserOp1;
+    }
+
+
+    /// Provide fast operand accessors
+    DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+  };
+}
+
+// FIXME: can we inherit this from ConstantExpr?
+template <>
+struct OperandTraits<ConstantPlaceHolder> :
+  public FixedNumOperandTraits<ConstantPlaceHolder, 1> {
+};
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
+}
+
+
+void BitcodeReaderValueList::AssignValue(Value *V, unsigned Idx) {
+  if (Idx == size()) {
+    push_back(V);
+    return;
+  }
+
+  if (Idx >= size())
+    resize(Idx+1);
+
+  WeakVH &OldV = ValuePtrs[Idx];
+  if (!OldV) {
+    OldV = V;
+    return;
+  }
+
+  // Handle constants and non-constants (e.g. instrs) differently for
+  // efficiency.
+  if (Constant *PHC = dyn_cast<Constant>(&*OldV)) {
+    ResolveConstants.push_back(std::make_pair(PHC, Idx));
+    OldV = V;
+  } else {
+    // If there was a forward reference to this value, replace it.
+    Value *PrevVal = OldV;
+    OldV->replaceAllUsesWith(V);
+    delete PrevVal;
+  }
+}
+
+
+Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
+                                                    Type *Ty) {
+  if (Idx >= size())
+    resize(Idx + 1);
+
+  if (Value *V = ValuePtrs[Idx]) {
+    assert(Ty == V->getType() && "Type mismatch in constant table!");
+    return cast<Constant>(V);
+  }
+
+  // Create and return a placeholder, which will later be RAUW'd.
+  Constant *C = new ConstantPlaceHolder(Ty, Context);
+  ValuePtrs[Idx] = C;
+  return C;
+}
+
+Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
+  if (Idx >= size())
+    resize(Idx + 1);
+
+  if (Value *V = ValuePtrs[Idx]) {
+    assert((!Ty || Ty == V->getType()) && "Type mismatch in value table!");
+    return V;
+  }
+
+  // No type specified, must be invalid reference.
+  if (!Ty) return nullptr;
+
+  // Create and return a placeholder, which will later be RAUW'd.
+  Value *V = new Argument(Ty);
+  ValuePtrs[Idx] = V;
+  return V;
+}
+
+/// ResolveConstantForwardRefs - Once all constants are read, this method bulk
+/// resolves any forward references.  The idea behind this is that we sometimes
+/// get constants (such as large arrays) which reference *many* forward ref
+/// constants.  Replacing each of these causes a lot of thrashing when
+/// building/reuniquing the constant.  Instead of doing this, we look at all the
+/// uses and rewrite all the place holders at once for any constant that uses
+/// a placeholder.
+void BitcodeReaderValueList::ResolveConstantForwardRefs() {
+  // Sort the values by-pointer so that they are efficient to look up with a
+  // binary search.
+  std::sort(ResolveConstants.begin(), ResolveConstants.end());
+
+  SmallVector<Constant*, 64> NewOps;
+
+  while (!ResolveConstants.empty()) {
+    Value *RealVal = operator[](ResolveConstants.back().second);
+    Constant *Placeholder = ResolveConstants.back().first;
+    ResolveConstants.pop_back();
+
+    // Loop over all users of the placeholder, updating them to reference the
+    // new value.  If they reference more than one placeholder, update them all
+    // at once.
+    while (!Placeholder->use_empty()) {
+      auto UI = Placeholder->user_begin();
+      User *U = *UI;
+
+      // If the using object isn't uniqued, just update the operands.  This
+      // handles instructions and initializers for global variables.
+      if (!isa<Constant>(U) || isa<GlobalValue>(U)) {
+        UI.getUse().set(RealVal);
+        continue;
+      }
+
+      // Otherwise, we have a constant that uses the placeholder.  Replace that
+      // constant with a new constant that has *all* placeholder uses updated.
+      Constant *UserC = cast<Constant>(U);
+      for (User::op_iterator I = UserC->op_begin(), E = UserC->op_end();
+           I != E; ++I) {
+        Value *NewOp;
+        if (!isa<ConstantPlaceHolder>(*I)) {
+          // Not a placeholder reference.
+          NewOp = *I;
+        } else if (*I == Placeholder) {
+          // Common case is that it just references this one placeholder.
+          NewOp = RealVal;
+        } else {
+          // Otherwise, look up the placeholder in ResolveConstants.
+          ResolveConstantsTy::iterator It =
+            std::lower_bound(ResolveConstants.begin(), ResolveConstants.end(),
+                             std::pair<Constant*, unsigned>(cast<Constant>(*I),
+                                                            0));
+          assert(It != ResolveConstants.end() && It->first == *I);
+          NewOp = operator[](It->second);
+        }
+
+        NewOps.push_back(cast<Constant>(NewOp));
+      }
+
+      // Make the new constant.
+      Constant *NewC;
+      if (ConstantArray *UserCA = dyn_cast<ConstantArray>(UserC)) {
+        NewC = ConstantArray::get(UserCA->getType(), NewOps);
+      } else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) {
+        NewC = ConstantStruct::get(UserCS->getType(), NewOps);
+      } else if (isa<ConstantVector>(UserC)) {
+        NewC = ConstantVector::get(NewOps);
+      } else {
+        assert(isa<ConstantExpr>(UserC) && "Must be a ConstantExpr.");
+        NewC = cast<ConstantExpr>(UserC)->getWithOperands(NewOps);
+      }
+
+      UserC->replaceAllUsesWith(NewC);
+      UserC->destroyConstant();
+      NewOps.clear();
+    }
+
+    // Update all ValueHandles, they should be the only users at this point.
+    Placeholder->replaceAllUsesWith(RealVal);
+    delete Placeholder;
+  }
+}
+
+void BitcodeReaderMDValueList::AssignValue(Metadata *MD, unsigned Idx) {
+  if (Idx == size()) {
+    push_back(MD);
+    return;
+  }
+
+  if (Idx >= size())
+    resize(Idx+1);
+
+  TrackingMDRef &OldMD = MDValuePtrs[Idx];
+  if (!OldMD) {
+    OldMD.reset(MD);
+    return;
+  }
+
+  // If there was a forward reference to this value, replace it.
+  TempMDTuple PrevMD(cast<MDTuple>(OldMD.get()));
+  PrevMD->replaceAllUsesWith(MD);
+  --NumFwdRefs;
+}
+
+Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
+  if (Idx >= size())
+    resize(Idx + 1);
+
+  if (Metadata *MD = MDValuePtrs[Idx])
+    return MD;
+
+  // Create and return a placeholder, which will later be RAUW'd.
+  AnyFwdRefs = true;
+  ++NumFwdRefs;
+  Metadata *MD = MDNode::getTemporary(Context, None).release();
+  MDValuePtrs[Idx].reset(MD);
+  return MD;
+}
+
+void BitcodeReaderMDValueList::tryToResolveCycles() {
+  if (!AnyFwdRefs)
+    // Nothing to do.
+    return;
+
+  if (NumFwdRefs)
+    // Still forward references... can't resolve cycles.
+    return;
+
+  // Resolve any cycles.
+  for (auto &MD : MDValuePtrs) {
+    auto *N = dyn_cast_or_null<MDNode>(MD);
+    if (!N)
+      continue;
+
+    assert(!N->isTemporary() && "Unexpected forward reference");
+    N->resolveCycles();
+  }
+}
+
+Type *BitcodeReader::getTypeByID(unsigned ID) {
+  // The type table size is always specified correctly.
+  if (ID >= TypeList.size())
+    return nullptr;
+
+  if (Type *Ty = TypeList[ID])
+    return Ty;
+
+  // If we have a forward reference, the only possible case is when it is to a
+  // named struct.  Just create a placeholder for now.
+  return TypeList[ID] = createIdentifiedStructType(Context);
+}
+
+StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context,
+                                                      StringRef Name) {
+  auto *Ret = StructType::create(Context, Name);
+  IdentifiedStructTypes.push_back(Ret);
+  return Ret;
+}
+
+StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context) {
+  auto *Ret = StructType::create(Context);
+  IdentifiedStructTypes.push_back(Ret);
+  return Ret;
+}
+
+
+/// FIXME: Remove in LLVM 3.1, only used by ParseOldTypeTable.
+Type *BitcodeReader::getTypeByIDOrNull(unsigned ID) {
+  if (ID >= TypeList.size())
+    TypeList.resize(ID+1);
+
+  return TypeList[ID];
+}
+
+//===----------------------------------------------------------------------===//
+//  Functions for parsing blocks from the bitcode file
+//===----------------------------------------------------------------------===//
+
+
+/// \brief This fills an AttrBuilder object with the LLVM attributes that have
+/// been decoded from the given integer. This function must stay in sync with
+/// 'encodeLLVMAttributesForBitcode'.
+static void decodeLLVMAttributesForBitcode(AttrBuilder &B,
+                                           uint64_t EncodedAttrs) {
+  // FIXME: Remove in 4.0.
+
+  // The alignment is stored as a 16-bit raw value from bits 31--16.  We shift
+  // the bits above 31 down by 11 bits.
+  unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16;
+  assert((!Alignment || isPowerOf2_32(Alignment)) &&
+         "Alignment must be a power of two.");
+
+  if (Alignment)
+    B.addAlignmentAttr(Alignment);
+  B.addRawValue(((EncodedAttrs & (0xfffffULL << 32)) >> 11) |
+                (EncodedAttrs & 0xffff));
+}
+
+std::error_code BitcodeReader::ParseAttributeBlock() {
+  if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID))
+    return Error("Invalid record");
+
+  if (!MAttributes.empty())
+    return Error("Invalid multiple blocks");
+
+  SmallVector<uint64_t, 64> Record;
+
+  SmallVector<AttributeSet, 8> Attrs;
+
+  // Read all the records.
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return std::error_code();
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a record.
+    Record.clear();
+    switch (Stream.readRecord(Entry.ID, Record)) {
+    default:  // Default behavior: ignore.
+      break;
+    case bitc::PARAMATTR_CODE_ENTRY_OLD: { // ENTRY: [paramidx0, attr0, ...]
+      // FIXME: Remove in 4.0.
+      if (Record.size() & 1)
+        return Error("Invalid record");
+
+      for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
+        AttrBuilder B;
+        decodeLLVMAttributesForBitcode(B, Record[i+1]);
+        Attrs.push_back(AttributeSet::get(Context, Record[i], B));
+      }
+
+      MAttributes.push_back(AttributeSet::get(Context, Attrs));
+      Attrs.clear();
+      break;
+    }
+    case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [attrgrp0, attrgrp1, ...]
+      for (unsigned i = 0, e = Record.size(); i != e; ++i)
+        Attrs.push_back(MAttributeGroups[Record[i]]);
+
+      MAttributes.push_back(AttributeSet::get(Context, Attrs));
+      Attrs.clear();
+      break;
+    }
+    }
+  }
+}
+
+
+std::error_code BitcodeReader::ParseTypeTable() {
+  if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW))
+    return Error("Invalid record");
+
+  return ParseTypeTableBody();
+}
+
+std::error_code BitcodeReader::ParseTypeTableBody() {
+  if (!TypeList.empty())
+    return Error("Invalid multiple blocks");
+
+  SmallVector<uint64_t, 64> Record;
+  unsigned NumRecords = 0;
+
+  SmallString<64> TypeName;
+
+  // Read all the records for this type table.
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      if (NumRecords != TypeList.size())
+        return Error("Malformed block");
+      return std::error_code();
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a record.
+    Record.clear();
+    Type *ResultTy = nullptr;
+    switch (Stream.readRecord(Entry.ID, Record)) {
+    default:
+      return Error("Invalid value");
+    case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries]
+      // TYPE_CODE_NUMENTRY contains a count of the number of types in the
+      // type list.  This allows us to reserve space.
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      TypeList.resize(Record[0]);
+      continue;
+    case bitc::TYPE_CODE_VOID:      // VOID
+      ResultTy = Type::getVoidTy(Context);
+      break;
+    case bitc::TYPE_CODE_HALF:     // HALF
+      ResultTy = Type::getHalfTy(Context);
+      break;
+    case bitc::TYPE_CODE_FLOAT:     // FLOAT
+      ResultTy = Type::getFloatTy(Context);
+      break;
+    case bitc::TYPE_CODE_DOUBLE:    // DOUBLE
+      ResultTy = Type::getDoubleTy(Context);
+      break;
+    case bitc::TYPE_CODE_X86_FP80:  // X86_FP80
+      ResultTy = Type::getX86_FP80Ty(Context);
+      break;
+    case bitc::TYPE_CODE_FP128:     // FP128
+      ResultTy = Type::getFP128Ty(Context);
+      break;
+    case bitc::TYPE_CODE_PPC_FP128: // PPC_FP128
+      ResultTy = Type::getPPC_FP128Ty(Context);
+      break;
+    case bitc::TYPE_CODE_LABEL:     // LABEL
+      ResultTy = Type::getLabelTy(Context);
+      break;
+    case bitc::TYPE_CODE_METADATA:  // METADATA
+      ResultTy = Type::getMetadataTy(Context);
+      break;
+    case bitc::TYPE_CODE_X86_MMX:   // X86_MMX
+      ResultTy = Type::getX86_MMXTy(Context);
+      break;
+    case bitc::TYPE_CODE_INTEGER:   // INTEGER: [width]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+
+      ResultTy = IntegerType::get(Context, Record[0]);
+      break;
+    case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
+                                    //          [pointee type, address space]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      unsigned AddressSpace = 0;
+      if (Record.size() == 2)
+        AddressSpace = Record[1];
+      ResultTy = getTypeByID(Record[0]);
+      if (!ResultTy)
+        return Error("Invalid type");
+      ResultTy = PointerType::get(ResultTy, AddressSpace);
+      break;
+    }
+    case bitc::TYPE_CODE_FUNCTION_OLD: {
+      // FIXME: attrid is dead, remove it in LLVM 4.0
+      // FUNCTION: [vararg, attrid, retty, paramty x N]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      SmallVector<Type*, 8> ArgTys;
+      for (unsigned i = 3, e = Record.size(); i != e; ++i) {
+        if (Type *T = getTypeByID(Record[i]))
+          ArgTys.push_back(T);
+        else
+          break;
+      }
+
+      ResultTy = getTypeByID(Record[2]);
+      if (!ResultTy || ArgTys.size() < Record.size()-3)
+        return Error("Invalid type");
+
+      ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
+      break;
+    }
+    case bitc::TYPE_CODE_FUNCTION: {
+      // FUNCTION: [vararg, retty, paramty x N]
+      if (Record.size() < 2)
+        return Error("Invalid record");
+      SmallVector<Type*, 8> ArgTys;
+      for (unsigned i = 2, e = Record.size(); i != e; ++i) {
+        if (Type *T = getTypeByID(Record[i]))
+          ArgTys.push_back(T);
+        else
+          break;
+      }
+
+      ResultTy = getTypeByID(Record[1]);
+      if (!ResultTy || ArgTys.size() < Record.size()-2)
+        return Error("Invalid type");
+
+      ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
+      break;
+    }
+    case bitc::TYPE_CODE_STRUCT_ANON: {  // STRUCT: [ispacked, eltty x N]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      SmallVector<Type*, 8> EltTys;
+      for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+        if (Type *T = getTypeByID(Record[i]))
+          EltTys.push_back(T);
+        else
+          break;
+      }
+      if (EltTys.size() != Record.size()-1)
+        return Error("Invalid type");
+      ResultTy = StructType::get(Context, EltTys, Record[0]);
+      break;
+    }
+    case bitc::TYPE_CODE_STRUCT_NAME:   // STRUCT_NAME: [strchr x N]
+      if (ConvertToString(Record, 0, TypeName))
+        return Error("Invalid record");
+      continue;
+
+    case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+
+      if (NumRecords >= TypeList.size())
+        return Error("Invalid TYPE table");
+
+      // Check to see if this was forward referenced, if so fill in the temp.
+      StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
+      if (Res) {
+        Res->setName(TypeName);
+        TypeList[NumRecords] = nullptr;
+      } else  // Otherwise, create a new struct.
+        Res = createIdentifiedStructType(Context, TypeName);
+      TypeName.clear();
+
+      SmallVector<Type*, 8> EltTys;
+      for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+        if (Type *T = getTypeByID(Record[i]))
+          EltTys.push_back(T);
+        else
+          break;
+      }
+      if (EltTys.size() != Record.size()-1)
+        return Error("Invalid record");
+      Res->setBody(EltTys, Record[0]);
+      ResultTy = Res;
+      break;
+    }
+    case bitc::TYPE_CODE_OPAQUE: {       // OPAQUE: []
+      if (Record.size() != 1)
+        return Error("Invalid record");
+
+      if (NumRecords >= TypeList.size())
+        return Error("Invalid TYPE table");
+
+      // Check to see if this was forward referenced, if so fill in the temp.
+      StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
+      if (Res) {
+        Res->setName(TypeName);
+        TypeList[NumRecords] = nullptr;
+      } else  // Otherwise, create a new struct with no body.
+        Res = createIdentifiedStructType(Context, TypeName);
+      TypeName.clear();
+      ResultTy = Res;
+      break;
+    }
+    case bitc::TYPE_CODE_ARRAY:     // ARRAY: [numelts, eltty]
+      if (Record.size() < 2)
+        return Error("Invalid record");
+      if ((ResultTy = getTypeByID(Record[1])))
+        ResultTy = ArrayType::get(ResultTy, Record[0]);
+      else
+        return Error("Invalid type");
+      break;
+    case bitc::TYPE_CODE_VECTOR:    // VECTOR: [numelts, eltty]
+      if (Record.size() < 2)
+        return Error("Invalid record");
+      if ((ResultTy = getTypeByID(Record[1])))
+        ResultTy = VectorType::get(ResultTy, Record[0]);
+      else
+        return Error("Invalid type");
+      break;
+    }
+
+    if (NumRecords >= TypeList.size())
+      return Error("Invalid TYPE table");
+    assert(ResultTy && "Didn't read a type?");
+    assert(!TypeList[NumRecords] && "Already read type?");
+    TypeList[NumRecords++] = ResultTy;
+  }
+}
+
+// FIXME: Remove in LLVM 3.1
+std::error_code BitcodeReader::ParseOldTypeTable() {
+  if (Stream.EnterSubBlock(TYPE_BLOCK_ID_OLD_3_0))
+    return Error("Malformed block");
+
+  if (!TypeList.empty())
+    return Error("Invalid TYPE table");
+
+
+  // While horrible, we have no good ordering of types in the bc file.  Just
+  // iteratively parse types out of the bc file in multiple passes until we get
+  // them all.  Do this by saving a cursor for the start of the type block.
+  BitstreamCursor StartOfTypeBlockCursor(Stream);
+
+  unsigned NumTypesRead = 0;
+
+  SmallVector<uint64_t, 64> Record;
+RestartScan:
+  unsigned NextTypeID = 0;
+  bool ReadAnyTypes = false;
+
+  // Read all the records for this type table.
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (NextTypeID != TypeList.size())
+        return Error("Invalid TYPE table");
+
+      // If we haven't read all of the types yet, iterate again.
+      if (NumTypesRead != TypeList.size()) {
+        // If we didn't successfully read any types in this pass, then we must
+        // have an unhandled forward reference.
+        if (!ReadAnyTypes)
+          return Error("Invalid TYPE table");
+
+        Stream = StartOfTypeBlockCursor;
+        goto RestartScan;
+      }
+
+      if (Stream.ReadBlockEnd())
+        return Error("Invalid TYPE table");
+      return std::error_code();
+    }
+
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    Record.clear();
+    Type *ResultTy = nullptr;
+    switch (Stream.readRecord(Code, Record)) {
+    default: return Error("Invalid TYPE table");
+    case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries]
+      // TYPE_CODE_NUMENTRY contains a count of the number of types in the
+      // type list.  This allows us to reserve space.
+      if (Record.size() < 1)
+        return Error("Invalid TYPE table");
+      TypeList.resize(Record[0]);
+      continue;
+    case bitc::TYPE_CODE_VOID:      // VOID
+      ResultTy = Type::getVoidTy(Context);
+      break;
+    case bitc::TYPE_CODE_FLOAT:     // FLOAT
+      ResultTy = Type::getFloatTy(Context);
+      break;
+    case bitc::TYPE_CODE_DOUBLE:    // DOUBLE
+      ResultTy = Type::getDoubleTy(Context);
+      break;
+    case bitc::TYPE_CODE_X86_FP80:  // X86_FP80
+      ResultTy = Type::getX86_FP80Ty(Context);
+      break;
+    case bitc::TYPE_CODE_FP128:     // FP128
+      ResultTy = Type::getFP128Ty(Context);
+      break;
+    case bitc::TYPE_CODE_PPC_FP128: // PPC_FP128
+      ResultTy = Type::getPPC_FP128Ty(Context);
+      break;
+    case bitc::TYPE_CODE_LABEL:     // LABEL
+      ResultTy = Type::getLabelTy(Context);
+      break;
+    case bitc::TYPE_CODE_METADATA:  // METADATA
+      ResultTy = Type::getMetadataTy(Context);
+      break;
+    case bitc::TYPE_CODE_X86_MMX:   // X86_MMX
+      ResultTy = Type::getX86_MMXTy(Context);
+      break;
+    case bitc::TYPE_CODE_INTEGER:   // INTEGER: [width]
+      if (Record.size() < 1)
+        return Error("Invalid TYPE table");
+      ResultTy = IntegerType::get(Context, Record[0]);
+      break;
+    case bitc::TYPE_CODE_OPAQUE:    // OPAQUE
+      if (NextTypeID < TypeList.size() && TypeList[NextTypeID] == 0)
+        ResultTy = StructType::create(Context, "");
+      break;
+    case TYPE_CODE_STRUCT_OLD_3_0: {// STRUCT_OLD
+      if (NextTypeID >= TypeList.size()) break;
+      // If we already read it, don't reprocess.
+      if (TypeList[NextTypeID] &&
+          !cast<StructType>(TypeList[NextTypeID])->isOpaque())
+        break;
+
+      // Set a type.
+      if (TypeList[NextTypeID] == 0)
+        TypeList[NextTypeID] = StructType::create(Context, "");
+
+      std::vector<Type*> EltTys;
+      for (unsigned i = 1, e = Record.size(); i != e; ++i) {
+        if (Type *Elt = getTypeByIDOrNull(Record[i]))
+          EltTys.push_back(Elt);
+        else
+          break;
+      }
+
+      if (EltTys.size() != Record.size()-1)
+        break;      // Not all elements are ready.
+
+      cast<StructType>(TypeList[NextTypeID])->setBody(EltTys, Record[0]);
+      ResultTy = TypeList[NextTypeID];
+      TypeList[NextTypeID] = 0;
+      break;
+    }
+    case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or
+      //          [pointee type, address space]
+      if (Record.size() < 1)
+        return Error("Invalid TYPE table");
+      unsigned AddressSpace = 0;
+      if (Record.size() == 2)
+        AddressSpace = Record[1];
+      if ((ResultTy = getTypeByIDOrNull(Record[0])))
+        ResultTy = PointerType::get(ResultTy, AddressSpace);
+      break;
+    }
+    case bitc::TYPE_CODE_FUNCTION_OLD: {
+      // FIXME: attrid is dead, remove it in LLVM 3.0
+      // FUNCTION: [vararg, attrid, retty, paramty x N]
+      if (Record.size() < 3)
+        return Error("Invalid TYPE table");
+      std::vector<Type*> ArgTys;
+      for (unsigned i = 3, e = Record.size(); i != e; ++i) {
+        if (Type *Elt = getTypeByIDOrNull(Record[i]))
+          ArgTys.push_back(Elt);
+        else
+          break;
+      }
+      if (ArgTys.size()+3 != Record.size())
+        break;  // Something was null.
+      if ((ResultTy = getTypeByIDOrNull(Record[2])))
+        ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
+      break;
+    }
+    case bitc::TYPE_CODE_FUNCTION: {
+      // FUNCTION: [vararg, retty, paramty x N]
+      if (Record.size() < 2)
+        return Error("Invalid TYPE table");
+      std::vector<Type*> ArgTys;
+      for (unsigned i = 2, e = Record.size(); i != e; ++i) {
+        if (Type *Elt = getTypeByIDOrNull(Record[i]))
+          ArgTys.push_back(Elt);
+        else
+          break;
+      }
+      if (ArgTys.size()+2 != Record.size())
+        break;  // Something was null.
+      if ((ResultTy = getTypeByIDOrNull(Record[1])))
+        ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]);
+      break;
+    }
+    case bitc::TYPE_CODE_ARRAY:     // ARRAY: [numelts, eltty]
+      if (Record.size() < 2)
+        return Error("Invalid TYPE table");
+      if ((ResultTy = getTypeByIDOrNull(Record[1])))
+        ResultTy = ArrayType::get(ResultTy, Record[0]);
+      break;
+    case bitc::TYPE_CODE_VECTOR:    // VECTOR: [numelts, eltty]
+      if (Record.size() < 2)
+        return Error("Invalid TYPE table");
+      if ((ResultTy = getTypeByIDOrNull(Record[1])))
+        ResultTy = VectorType::get(ResultTy, Record[0]);
+      break;
+    }
+
+    if (NextTypeID >= TypeList.size())
+      return Error("Invalid TYPE table");
+
+    if (ResultTy && TypeList[NextTypeID] == 0) {
+      ++NumTypesRead;
+      ReadAnyTypes = true;
+
+      TypeList[NextTypeID] = ResultTy;
+    }
+
+    ++NextTypeID;
+  }
+}
+
+
+std::error_code BitcodeReader::ParseOldTypeSymbolTable() {
+  if (Stream.EnterSubBlock(TYPE_SYMTAB_BLOCK_ID_OLD_3_0))
+    return Error("Malformed block");
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Read all the records for this type table.
+  std::string TypeName;
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Malformed block");
+      return std::error_code();
+    }
+
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    Record.clear();
+    switch (Stream.readRecord(Code, Record)) {
+    default:  // Default behavior: unknown type.
+      break;
+    case bitc::TST_CODE_ENTRY:    // TST_ENTRY: [typeid, namechar x N]
+      if (ConvertToString(Record, 1, TypeName))
+        return Error("Invalid record");
+      unsigned TypeID = Record[0];
+      if (TypeID >= TypeList.size())
+        return Error("Invalid record");
+
+      // Only apply the type name to a struct type with no name.
+      if (StructType *STy = dyn_cast<StructType>(TypeList[TypeID]))
+        if (!STy->isLiteral() && !STy->hasName())
+          STy->setName(TypeName);
+      TypeName.clear();
+      break;
+    }
+  }
+}
+
+std::error_code BitcodeReader::ParseValueSymbolTable() {
+  if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Read all the records for this value table.
+  SmallString<128> ValueName;
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Malformed block");
+      return std::error_code();
+    }
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    Record.clear();
+    switch (Stream.readRecord(Code, Record)) {
+    default:  // Default behavior: unknown type.
+      break;
+    case bitc::VST_CODE_ENTRY: {  // VST_ENTRY: [valueid, namechar x N]
+      if (ConvertToString(Record, 1, ValueName))
+        return Error("Invalid record");
+      unsigned ValueID = Record[0];
+      if (ValueID >= ValueList.size())
+        return Error("Invalid record");
+      Value *V = ValueList[ValueID];
+
+      V->setName(StringRef(ValueName.data(), ValueName.size()));
+      ValueName.clear();
+      break;
+    }
+    case bitc::VST_CODE_BBENTRY: {
+      if (ConvertToString(Record, 1, ValueName))
+        return Error("Invalid record");
+      BasicBlock *BB = getBasicBlock(Record[0]);
+      if (!BB)
+        return Error("Invalid record");
+
+      BB->setName(StringRef(ValueName.data(), ValueName.size()));
+      ValueName.clear();
+      break;
+    }
+    }
+  }
+}
+
+std::error_code BitcodeReader::ParseMetadata() {
+  unsigned NextMDValueNo = MDValueList.size();
+
+  if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Read all the records.
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Malformed block");
+      return std::error_code();
+    }
+
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      // No known subblocks, always skip them.
+      Stream.ReadSubBlockID();
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    bool IsFunctionLocal = false;
+    // Read a record.
+    Record.clear();
+    Code = Stream.readRecord(Code, Record);
+    switch (Code) {
+    default:  // Default behavior: ignore.
+      break;
+    case bitc::METADATA_NAME: {
+      // Read name of the named metadata.
+      SmallString<8> Name(Record.begin(), Record.end());
+      Record.clear();
+      Code = Stream.ReadCode();
+
+      // METADATA_NAME is always followed by METADATA_NAMED_NODE.
+      unsigned NextBitCode = Stream.readRecord(Code, Record);
+      assert(NextBitCode == bitc::METADATA_NAMED_NODE); (void)NextBitCode;
+
+      // Read named metadata elements.
+      unsigned Size = Record.size();
+      NamedMDNode *NMD = TheModule->getOrInsertNamedMetadata(Name);
+      for (unsigned i = 0; i != Size; ++i) {
+        MDNode *MD = dyn_cast_or_null<MDNode>(MDValueList.getValueFwdRef(Record[i]));
+        if (!MD)
+          return Error("Invalid record");
+        NMD->addOperand(MD);
+      }
+      break;
+    }
+    case bitc::METADATA_OLD_FN_NODE:
+      IsFunctionLocal = true;
+      // fall-through
+    case bitc::METADATA_OLD_NODE: {
+      if (Record.size() % 2 == 1)
+        return Error("Invalid record");
+
+      unsigned Size = Record.size();
+      SmallVector<Metadata *, 8> Elts;
+      for (unsigned i = 0; i != Size; i += 2) {
+        Type *Ty = getTypeByID(Record[i]);
+        if (!Ty)
+          return Error("Invalid record");
+        if (Ty->isMetadataTy())
+          Elts.push_back(MDValueList.getValueFwdRef(Record[i+1]));
+        else if (!Ty->isVoidTy()) {
+          auto *MD =
+              ValueAsMetadata::get(ValueList.getValueFwdRef(Record[i + 1], Ty));
+          assert(isa<ConstantAsMetadata>(MD) &&
+                 "Expected non-function-local metadata");
+          Elts.push_back(MD);
+        } else
+          Elts.push_back(nullptr);
+      }
+      MDValueList.AssignValue(MDNode::get(Context, Elts), NextMDValueNo++);
+      break;
+    }
+    case bitc::METADATA_STRING: {
+      std::string String(Record.begin(), Record.end());
+      llvm::UpgradeMDStringConstant(String);
+      Metadata *MD = MDString::get(Context, String);
+      MDValueList.AssignValue(MD, NextMDValueNo++);
+      break;
+    }
+    case bitc::METADATA_KIND: {
+      if (Record.size() < 2)
+        return Error("Invalid record");
+
+      unsigned Kind = Record[0];
+      SmallString<8> Name(Record.begin()+1, Record.end());
+
+      unsigned NewKind = TheModule->getMDKindID(Name.str());
+      if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second)
+        return Error("Conflicting METADATA_KIND records");
+      break;
+    }
+    }
+  }
+}
+
+/// decodeSignRotatedValue - Decode a signed value stored with the sign bit in
+/// the LSB for dense VBR encoding.
+uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
+  if ((V & 1) == 0)
+    return V >> 1;
+  if (V != 1)
+    return -(V >> 1);
+  // There is no such thing as -0 with integers.  "-0" really means MININT.
+  return 1ULL << 63;
+}
+
+// FIXME: Delete this in LLVM 4.0 and just assert that the aliasee is a
+// GlobalObject.
+static GlobalObject &
+getGlobalObjectInExpr(const DenseMap<GlobalAlias *, Constant *> &Map,
+                      Constant &C) {
+  auto *GO = dyn_cast<GlobalObject>(&C);
+  if (GO)
+    return *GO;
+
+  auto *GA = dyn_cast<GlobalAlias>(&C);
+  if (GA)
+    return getGlobalObjectInExpr(Map, *Map.find(GA)->second);
+
+  auto &CE = cast<ConstantExpr>(C);
+  assert(CE.getOpcode() == Instruction::BitCast ||
+         CE.getOpcode() == Instruction::GetElementPtr ||
+         CE.getOpcode() == Instruction::AddrSpaceCast);
+  if (CE.getOpcode() == Instruction::GetElementPtr)
+    assert(cast<GEPOperator>(CE).hasAllZeroIndices());
+  return getGlobalObjectInExpr(Map, *CE.getOperand(0));
+}
+
+/// ResolveGlobalAndAliasInits - Resolve all of the initializers for global
+/// values and aliases that we can.
+std::error_code BitcodeReader::ResolveGlobalAndAliasInits() {
+  std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;
+  std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist;
+
+  GlobalInitWorklist.swap(GlobalInits);
+  AliasInitWorklist.swap(AliasInits);
+
+  while (!GlobalInitWorklist.empty()) {
+    unsigned ValID = GlobalInitWorklist.back().second;
+    if (ValID >= ValueList.size()) {
+      // Not ready to resolve this yet, it requires something later in the file.
+      GlobalInits.push_back(GlobalInitWorklist.back());
+    } else {
+      if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
+        GlobalInitWorklist.back().first->setInitializer(C);
+      else
+        return Error("Expected a constant");
+    }
+    GlobalInitWorklist.pop_back();
+  }
+
+  // FIXME: Delete this in LLVM 4.0
+  // Older versions of llvm could write an alias pointing to another. We cannot
+  // construct those aliases, so we first collect an alias to aliasee expression
+  // and then compute the actual aliasee.
+  DenseMap<GlobalAlias *, Constant *> AliasInit;
+
+  while (!AliasInitWorklist.empty()) {
+    unsigned ValID = AliasInitWorklist.back().second;
+    if (ValID >= ValueList.size()) {
+      AliasInits.push_back(AliasInitWorklist.back());
+    } else {
+      if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
+        AliasInit.insert(std::make_pair(AliasInitWorklist.back().first, C));
+      else
+        return Error("Expected a constant");
+    }
+    AliasInitWorklist.pop_back();
+  }
+
+  for (auto &Pair : AliasInit) {
+    auto &GO = getGlobalObjectInExpr(AliasInit, *Pair.second);
+    Pair.first->setAliasee(&GO);
+  }
+
+  return std::error_code();
+}
+
+static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) {
+  SmallVector<uint64_t, 8> Words(Vals.size());
+  std::transform(Vals.begin(), Vals.end(), Words.begin(),
+                 BitcodeReader::decodeSignRotatedValue);
+
+  return APInt(TypeBits, Words);
+}
+
+std::error_code BitcodeReader::ParseConstants() {
+  if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Read all the records for this value table.
+  Type *CurTy = Type::getInt32Ty(Context);
+  unsigned NextCstNo = ValueList.size();
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      if (NextCstNo != ValueList.size())
+        return Error("Invalid constant reference");
+
+      // Once all the constants have been read, go through and resolve forward
+      // references.
+      ValueList.ResolveConstantForwardRefs();
+      return std::error_code();
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a record.
+    Record.clear();
+    Value *V = nullptr;
+    unsigned BitCode = Stream.readRecord(Entry.ID, Record);
+    switch (BitCode) {
+    default:  // Default behavior: unknown constant
+    case bitc::CST_CODE_UNDEF:     // UNDEF
+      V = UndefValue::get(CurTy);
+      break;
+    case bitc::CST_CODE_SETTYPE:   // SETTYPE: [typeid]
+      if (Record.empty())
+        return Error("Invalid record");
+      if (Record[0] >= TypeList.size())
+        return Error("Invalid record");
+      CurTy = TypeList[Record[0]];
+      continue;  // Skip the ValueList manipulation.
+    case bitc::CST_CODE_NULL:      // NULL
+      V = Constant::getNullValue(CurTy);
+      break;
+    case bitc::CST_CODE_INTEGER:   // INTEGER: [intval]
+      if (!CurTy->isIntegerTy() || Record.empty())
+        return Error("Invalid record");
+      V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0]));
+      break;
+    case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval]
+      if (!CurTy->isIntegerTy() || Record.empty())
+        return Error("Invalid record");
+
+      APInt VInt = ReadWideAPInt(Record,
+                                 cast<IntegerType>(CurTy)->getBitWidth());
+      V = ConstantInt::get(Context, VInt);
+
+      break;
+    }
+    case bitc::CST_CODE_FLOAT: {    // FLOAT: [fpval]
+      if (Record.empty())
+        return Error("Invalid record");
+      if (CurTy->isHalfTy())
+        V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf,
+                                             APInt(16, (uint16_t)Record[0])));
+      else if (CurTy->isFloatTy())
+        V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle,
+                                             APInt(32, (uint32_t)Record[0])));
+      else if (CurTy->isDoubleTy())
+        V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble,
+                                             APInt(64, Record[0])));
+      else if (CurTy->isX86_FP80Ty()) {
+        // Bits are not stored the same way as a normal i80 APInt, compensate.
+        uint64_t Rearrange[2];
+        Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16);
+        Rearrange[1] = Record[0] >> 48;
+        V = ConstantFP::get(Context, APFloat(APFloat::x87DoubleExtended,
+                                             APInt(80, Rearrange)));
+      } else if (CurTy->isFP128Ty())
+        V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad,
+                                             APInt(128, Record)));
+      else if (CurTy->isPPC_FP128Ty())
+        V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble,
+                                             APInt(128, Record)));
+      else
+        V = UndefValue::get(CurTy);
+      break;
+    }
+
+    case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n x value number]
+      if (Record.empty())
+        return Error("Invalid record");
+
+      unsigned Size = Record.size();
+      SmallVector<Constant*, 16> Elts;
+
+      if (StructType *STy = dyn_cast<StructType>(CurTy)) {
+        for (unsigned i = 0; i != Size; ++i)
+          Elts.push_back(ValueList.getConstantFwdRef(Record[i],
+                                                     STy->getElementType(i)));
+        V = ConstantStruct::get(STy, Elts);
+      } else if (ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) {
+        Type *EltTy = ATy->getElementType();
+        for (unsigned i = 0; i != Size; ++i)
+          Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy));
+        V = ConstantArray::get(ATy, Elts);
+      } else if (VectorType *VTy = dyn_cast<VectorType>(CurTy)) {
+        Type *EltTy = VTy->getElementType();
+        for (unsigned i = 0; i != Size; ++i)
+          Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy));
+        V = ConstantVector::get(Elts);
+      } else {
+        V = UndefValue::get(CurTy);
+      }
+      break;
+    }
+    case bitc::CST_CODE_STRING: { // STRING: [values]
+      if (Record.empty())
+        return Error("Invalid record");
+
+      ArrayType *ATy = cast<ArrayType>(CurTy);
+      Type *EltTy = ATy->getElementType();
+
+      unsigned Size = Record.size();
+      std::vector<Constant*> Elts;
+      for (unsigned i = 0; i != Size; ++i)
+        Elts.push_back(ConstantInt::get(EltTy, Record[i]));
+      V = ConstantArray::get(ATy, Elts);
+      break;
+    }
+    case bitc::CST_CODE_CSTRING: { // CSTRING: [values]
+      if (Record.empty())
+        return Error("Invalid record");
+
+      ArrayType *ATy = cast<ArrayType>(CurTy);
+      Type *EltTy = ATy->getElementType();
+
+      unsigned Size = Record.size();
+      std::vector<Constant*> Elts;
+      for (unsigned i = 0; i != Size; ++i)
+        Elts.push_back(ConstantInt::get(EltTy, Record[i]));
+      Elts.push_back(Constant::getNullValue(EltTy));
+      V = ConstantArray::get(ATy, Elts);
+      break;
+    }
+    case bitc::CST_CODE_CE_BINOP: {  // CE_BINOP: [opcode, opval, opval]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      int Opc = GetDecodedBinaryOpcode(Record[0], CurTy);
+      if (Opc < 0) {
+        V = UndefValue::get(CurTy);  // Unknown binop.
+      } else {
+        Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
+        Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
+        unsigned Flags = 0;
+        if (Record.size() >= 4) {
+          if (Opc == Instruction::Add ||
+              Opc == Instruction::Sub ||
+              Opc == Instruction::Mul ||
+              Opc == Instruction::Shl) {
+            if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+              Flags |= OverflowingBinaryOperator::NoSignedWrap;
+            if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+              Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
+          } else if (Opc == Instruction::SDiv ||
+                     Opc == Instruction::UDiv ||
+                     Opc == Instruction::LShr ||
+                     Opc == Instruction::AShr) {
+            if (Record[3] & (1 << bitc::PEO_EXACT))
+              Flags |= SDivOperator::IsExact;
+          }
+        }
+        V = ConstantExpr::get(Opc, LHS, RHS, Flags);
+      }
+      break;
+    }
+    case bitc::CST_CODE_CE_CAST: {  // CE_CAST: [opcode, opty, opval]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      int Opc = GetDecodedCastOpcode(Record[0]);
+      if (Opc < 0) {
+        V = UndefValue::get(CurTy);  // Unknown cast.
+      } else {
+        Type *OpTy = getTypeByID(Record[1]);
+        if (!OpTy)
+          return Error("Invalid record");
+        Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
+        V = ConstantExpr::getCast(Opc, Op, CurTy);
+      }
+      break;
+    }
+    case bitc::CST_CODE_CE_INBOUNDS_GEP:
+    case bitc::CST_CODE_CE_GEP: {  // CE_GEP:        [n x operands]
+      Type *PointeeType = nullptr;
+      if (Record.size() & 1)
+        return Error("Invalid record");
+      SmallVector<Constant*, 16> Elts;
+      for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
+        Type *ElTy = getTypeByID(Record[i]);
+        if (!ElTy)
+          return Error("Invalid record");
+        Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
+      }
+      ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
+      V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices,
+                                         BitCode ==
+                                           bitc::CST_CODE_CE_INBOUNDS_GEP);
+      break;
+    }
+    case bitc::CST_CODE_CE_SELECT:  // CE_SELECT: [opval#, opval#, opval#]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      V = ConstantExpr::getSelect(ValueList.getConstantFwdRef(Record[0],
+                                                              Type::getInt1Ty(Context)),
+                                  ValueList.getConstantFwdRef(Record[1],CurTy),
+                                  ValueList.getConstantFwdRef(Record[2],CurTy));
+      break;
+    case bitc::CST_CODE_CE_EXTRACTELT: { // CE_EXTRACTELT: [opty, opval, opval]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      VectorType *OpTy =
+        dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
+      if (!OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
+      V = ConstantExpr::getExtractElement(Op0, Op1);
+      break;
+    }
+    case bitc::CST_CODE_CE_INSERTELT: { // CE_INSERTELT: [opval, opval, opval]
+      VectorType *OpTy = dyn_cast<VectorType>(CurTy);
+      if (Record.size() < 3 || !OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[1],
+                                                  OpTy->getElementType());
+      Constant *Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
+      V = ConstantExpr::getInsertElement(Op0, Op1, Op2);
+      break;
+    }
+    case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval]
+      VectorType *OpTy = dyn_cast<VectorType>(CurTy);
+      if (Record.size() < 3 || !OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy);
+      Type *ShufTy = VectorType::get(Type::getInt32Ty(Context),
+                                                 OpTy->getNumElements());
+      Constant *Op2 = ValueList.getConstantFwdRef(Record[2], ShufTy);
+      V = ConstantExpr::getShuffleVector(Op0, Op1, Op2);
+      break;
+    }
+    case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval]
+      VectorType *RTy = dyn_cast<VectorType>(CurTy);
+      VectorType *OpTy =
+        dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
+      if (Record.size() < 4 || !RTy || !OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
+      Type *ShufTy = VectorType::get(Type::getInt32Ty(Context),
+                                                 RTy->getNumElements());
+      Constant *Op2 = ValueList.getConstantFwdRef(Record[3], ShufTy);
+      V = ConstantExpr::getShuffleVector(Op0, Op1, Op2);
+      break;
+    }
+    case bitc::CST_CODE_CE_CMP: {     // CE_CMP: [opty, opval, opval, pred]
+      if (Record.size() < 4)
+        return Error("Invalid record");
+      Type *OpTy = getTypeByID(Record[0]);
+      if (!OpTy)
+        return Error("Invalid record");
+      Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
+      Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
+
+      if (OpTy->isFPOrFPVectorTy())
+        V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
+      else
+        V = ConstantExpr::getICmp(Record[3], Op0, Op1);
+      break;
+    }
+    case bitc::CST_CODE_INLINEASM:
+    case bitc::CST_CODE_INLINEASM_OLD: {
+      if (Record.size() < 2)
+        return Error("Invalid record");
+      std::string AsmStr, ConstrStr;
+      bool HasSideEffects = Record[0] & 1;
+      bool IsAlignStack = Record[0] >> 1;
+      unsigned AsmStrSize = Record[1];
+      if (2+AsmStrSize >= Record.size())
+        return Error("Invalid record");
+      unsigned ConstStrSize = Record[2+AsmStrSize];
+      if (3+AsmStrSize+ConstStrSize > Record.size())
+        return Error("Invalid record");
+
+      for (unsigned i = 0; i != AsmStrSize; ++i)
+        AsmStr += (char)Record[2+i];
+      for (unsigned i = 0; i != ConstStrSize; ++i)
+        ConstrStr += (char)Record[3+AsmStrSize+i];
+      PointerType *PTy = cast<PointerType>(CurTy);
+      V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
+                         AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
+      break;
+    }
+    case bitc::CST_CODE_BLOCKADDRESS:{
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      Type *FnTy = getTypeByID(Record[0]);
+      if (!FnTy)
+        return Error("Invalid record");
+      Function *Fn =
+        dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
+      if (!Fn)
+        return Error("Invalid record");
+
+      GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(),
+                                                  Type::getInt8Ty(Context),
+                                            false, GlobalValue::InternalLinkage,
+                                                  0, "");
+      BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
+      V = FwdRef;
+      break;
+    }
+    }
+
+    ValueList.AssignValue(V, NextCstNo);
+    ++NextCstNo;
+  }
+
+  if (NextCstNo != ValueList.size())
+    return Error("Invalid constant reference");
+
+  if (Stream.ReadBlockEnd())
+    return Error("Expected a constant");
+
+  // Once all the constants have been read, go through and resolve forward
+  // references.
+  ValueList.ResolveConstantForwardRefs();
+  return std::error_code();
+}
+
+std::error_code BitcodeReader::materializeMetadata() {
+  return std::error_code();
+}
+
+void BitcodeReader::setStripDebugInfo() { }
+
+/// RememberAndSkipFunctionBody - When we see the block for a function body,
+/// remember where it is and then skip it.  This lets us lazily deserialize the
+/// functions.
+std::error_code BitcodeReader::RememberAndSkipFunctionBody() {
+  // Get the function we are talking about.
+  if (FunctionsWithBodies.empty())
+    return Error("Insufficient function protos");
+
+  Function *Fn = FunctionsWithBodies.back();
+  FunctionsWithBodies.pop_back();
+
+  // Save the current stream state.
+  uint64_t CurBit = Stream.GetCurrentBitNo();
+  DeferredFunctionInfo[Fn] = CurBit;
+
+  // Skip over the function block for now.
+  if (Stream.SkipBlock())
+    return Error("Invalid record");
+  return std::error_code();
+}
+
+std::error_code BitcodeReader::GlobalCleanup() {
+  // Patch the initializers for globals and aliases up.
+  ResolveGlobalAndAliasInits();
+  if (!GlobalInits.empty() || !AliasInits.empty())
+    return Error("Malformed global initializer set");
+
+  // Look for intrinsic functions which need to be upgraded at some point
+  for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
+       FI != FE; ++FI) {
+    Function *NewFn;
+    if (UpgradeIntrinsicFunction(&*FI, NewFn))
+      UpgradedIntrinsics.push_back(std::make_pair(&*FI, NewFn));
+  }
+
+  // Look for global variables which need to be renamed.
+  for (Module::global_iterator
+         GI = TheModule->global_begin(), GE = TheModule->global_end();
+       GI != GE; GI++) {
+    GlobalVariable *GV = &*GI;
+    UpgradeGlobalVariable(GV);
+  }
+
+  // Force deallocation of memory for these vectors to favor the client that
+  // want lazy deserialization.
+  std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
+  std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
+  return std::error_code();
+}
+
+std::error_code BitcodeReader::ParseModule(bool Resume) {
+  if (Resume)
+    Stream.JumpToBit(NextUnreadBit);
+  else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+  std::vector<std::string> SectionTable;
+  std::vector<std::string> GCTable;
+
+  // Read all the records for this module.
+  while (1) {
+    BitstreamEntry Entry = Stream.advance();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return GlobalCleanup();
+
+    case BitstreamEntry::SubBlock:
+      switch (Entry.ID) {
+      default:  // Skip unknown content.
+        if (Stream.SkipBlock())
+          return Error("Invalid record");
+        break;
+      case bitc::BLOCKINFO_BLOCK_ID:
+        if (Stream.ReadBlockInfoBlock())
+          return Error("Malformed block");
+        break;
+      case bitc::PARAMATTR_BLOCK_ID:
+        if (std::error_code EC = ParseAttributeBlock())
+          return EC;
+        break;
+      case bitc::TYPE_BLOCK_ID_NEW:
+        if (std::error_code EC = ParseTypeTable())
+          return EC;
+        break;
+      case TYPE_BLOCK_ID_OLD_3_0:
+        if (std::error_code EC = ParseOldTypeTable())
+          return EC;
+        break;
+      case TYPE_SYMTAB_BLOCK_ID_OLD_3_0:
+        if (std::error_code EC = ParseOldTypeSymbolTable())
+          return EC;
+        break;
+      case bitc::VALUE_SYMTAB_BLOCK_ID:
+        if (std::error_code EC = ParseValueSymbolTable())
+          return EC;
+        SeenValueSymbolTable = true;
+        break;
+      case bitc::CONSTANTS_BLOCK_ID:
+        if (std::error_code EC = ParseConstants())
+          return EC;
+        if (std::error_code EC = ResolveGlobalAndAliasInits())
+          return EC;
+        break;
+      case bitc::METADATA_BLOCK_ID:
+        if (std::error_code EC = ParseMetadata())
+          return EC;
+        break;
+      case bitc::FUNCTION_BLOCK_ID:
+        // If this is the first function body we've seen, reverse the
+        // FunctionsWithBodies list.
+        if (!SeenFirstFunctionBody) {
+          std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
+          if (std::error_code EC = GlobalCleanup())
+            return EC;
+          SeenFirstFunctionBody = true;
+        }
+
+        if (std::error_code EC = RememberAndSkipFunctionBody())
+          return EC;
+        // For streaming bitcode, suspend parsing when we reach the function
+        // bodies. Subsequent materialization calls will resume it when
+        // necessary. For streaming, the function bodies must be at the end of
+        // the bitcode. If the bitcode file is old, the symbol table will be
+        // at the end instead and will not have been seen yet. In this case,
+        // just finish the parse now.
+        if (LazyStreamer && SeenValueSymbolTable) {
+          NextUnreadBit = Stream.GetCurrentBitNo();
+          return std::error_code();
+        }
+        break;
+        break;
+      }
+      continue;
+
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+
+    // Read a record.
+    switch (Stream.readRecord(Entry.ID, Record)) {
+    default: break;  // Default behavior, ignore unknown content.
+    case bitc::MODULE_CODE_VERSION: {  // VERSION: [version#]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      // Only version #0 is supported so far.
+      if (Record[0] != 0)
+        return Error("Invalid value");
+      break;
+    }
+    case bitc::MODULE_CODE_TRIPLE: {  // TRIPLE: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      TheModule->setTargetTriple(S);
+      break;
+    }
+    case bitc::MODULE_CODE_DATALAYOUT: {  // DATALAYOUT: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      TheModule->setDataLayout(S);
+      break;
+    }
+    case bitc::MODULE_CODE_ASM: {  // ASM: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      TheModule->setModuleInlineAsm(S);
+      break;
+    }
+    case bitc::MODULE_CODE_DEPLIB: {  // DEPLIB: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      // ANDROID: Ignore value, since we never used it anyways.
+      // TheModule->addLibrary(S);
+      break;
+    }
+    case bitc::MODULE_CODE_SECTIONNAME: {  // SECTIONNAME: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      SectionTable.push_back(S);
+      break;
+    }
+    case bitc::MODULE_CODE_GCNAME: {  // SECTIONNAME: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      GCTable.push_back(S);
+      break;
+    }
+    // GLOBALVAR: [pointer type, isconst, initid,
+    //             linkage, alignment, section, visibility, threadlocal,
+    //             unnamed_addr]
+    case bitc::MODULE_CODE_GLOBALVAR: {
+      if (Record.size() < 6)
+        return Error("Invalid record");
+      Type *Ty = getTypeByID(Record[0]);
+      if (!Ty)
+        return Error("Invalid record");
+      if (!Ty->isPointerTy())
+        return Error("Invalid type for value");
+      unsigned AddressSpace = cast<PointerType>(Ty)->getAddressSpace();
+      Ty = cast<PointerType>(Ty)->getElementType();
+
+      bool isConstant = Record[1];
+      uint64_t RawLinkage = Record[3];
+      GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage);
+      unsigned Alignment = (1 << Record[4]) >> 1;
+      std::string Section;
+      if (Record[5]) {
+        if (Record[5]-1 >= SectionTable.size())
+          return Error("Invalid ID");
+        Section = SectionTable[Record[5]-1];
+      }
+      GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
+      if (Record.size() > 6)
+        Visibility = GetDecodedVisibility(Record[6]);
+
+      GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal;
+      if (Record.size() > 7)
+        TLM = GetDecodedThreadLocalMode(Record[7]);
+
+      bool UnnamedAddr = false;
+      if (Record.size() > 8)
+        UnnamedAddr = Record[8];
+
+      GlobalVariable *NewGV =
+        new GlobalVariable(*TheModule, Ty, isConstant, Linkage, nullptr, "", nullptr,
+                           TLM, AddressSpace);
+      NewGV->setAlignment(Alignment);
+      if (!Section.empty())
+        NewGV->setSection(Section);
+      NewGV->setVisibility(Visibility);
+      NewGV->setUnnamedAddr(UnnamedAddr);
+
+      ValueList.push_back(NewGV);
+
+      // Remember which value to use for the global initializer.
+      if (unsigned InitID = Record[2])
+        GlobalInits.push_back(std::make_pair(NewGV, InitID-1));
+      break;
+    }
+    // FUNCTION:  [type, callingconv, isproto, linkage, paramattr,
+    //             alignment, section, visibility, gc, unnamed_addr]
+    case bitc::MODULE_CODE_FUNCTION: {
+      if (Record.size() < 8)
+        return Error("Invalid record");
+      Type *Ty = getTypeByID(Record[0]);
+      if (!Ty)
+        return Error("Invalid record");
+      if (!Ty->isPointerTy())
+        return Error("Invalid type for value");
+      FunctionType *FTy =
+        dyn_cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
+      if (!FTy)
+        return Error("Invalid type for value");
+
+      Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage,
+                                        "", TheModule);
+
+      Func->setCallingConv(static_cast<CallingConv::ID>(Record[1]));
+      bool isProto = Record[2];
+      uint64_t RawLinkage = Record[3];
+      Func->setLinkage(getDecodedLinkage(RawLinkage));
+      Func->setAttributes(getAttributes(Record[4]));
+
+      Func->setAlignment((1 << Record[5]) >> 1);
+      if (Record[6]) {
+        if (Record[6]-1 >= SectionTable.size())
+          return Error("Invalid ID");
+        Func->setSection(SectionTable[Record[6]-1]);
+      }
+      Func->setVisibility(GetDecodedVisibility(Record[7]));
+      if (Record.size() > 8 && Record[8]) {
+        if (Record[8]-1 > GCTable.size())
+          return Error("Invalid ID");
+        Func->setGC(GCTable[Record[8]-1].c_str());
+      }
+      bool UnnamedAddr = false;
+      if (Record.size() > 9)
+        UnnamedAddr = Record[9];
+      Func->setUnnamedAddr(UnnamedAddr);
+      ValueList.push_back(Func);
+
+      // If this is a function with a body, remember the prototype we are
+      // creating now, so that we can match up the body with them later.
+      if (!isProto) {
+        Func->setIsMaterializable(true);
+        FunctionsWithBodies.push_back(Func);
+        if (LazyStreamer)
+          DeferredFunctionInfo[Func] = 0;
+      }
+      break;
+    }
+    // ALIAS: [alias type, aliasee val#, linkage]
+    // ALIAS: [alias type, aliasee val#, linkage, visibility]
+    case bitc::MODULE_CODE_ALIAS_OLD: {
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      Type *Ty = getTypeByID(Record[0]);
+      if (!Ty)
+        return Error("Invalid record");
+      auto *PTy = dyn_cast<PointerType>(Ty);
+      if (!PTy)
+        return Error("Invalid type for value");
+
+      auto *NewGA =
+          GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),
+                              getDecodedLinkage(Record[2]), "", TheModule);
+      // Old bitcode files didn't have visibility field.
+      if (Record.size() > 3)
+        NewGA->setVisibility(GetDecodedVisibility(Record[3]));
+      ValueList.push_back(NewGA);
+      AliasInits.push_back(std::make_pair(NewGA, Record[1]));
+      break;
+    }
+    /// MODULE_CODE_PURGEVALS: [numvals]
+    case bitc::MODULE_CODE_PURGEVALS:
+      // Trim down the value list to the specified size.
+      if (Record.size() < 1 || Record[0] > ValueList.size())
+        return Error("Invalid record");
+      ValueList.shrinkTo(Record[0]);
+      break;
+    }
+    Record.clear();
+  }
+}
+
+std::error_code BitcodeReader::ParseBitcodeInto(Module *M) {
+  TheModule = nullptr;
+
+  if (std::error_code EC = InitStream())
+    return EC;
+
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'B' ||
+      Stream.Read(8) != 'C' ||
+      Stream.Read(4) != 0x0 ||
+      Stream.Read(4) != 0xC ||
+      Stream.Read(4) != 0xE ||
+      Stream.Read(4) != 0xD)
+    return Error("Invalid bitcode signature");
+
+  // We expect a number of well-defined blocks, though we don't necessarily
+  // need to understand them all.
+  while (1) {
+    if (Stream.AtEndOfStream())
+      return std::error_code();
+
+    BitstreamEntry Entry =
+      Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return std::error_code();
+
+    case BitstreamEntry::SubBlock:
+      switch (Entry.ID) {
+      case bitc::BLOCKINFO_BLOCK_ID:
+        if (Stream.ReadBlockInfoBlock())
+          return Error("Malformed block");
+        break;
+      case bitc::MODULE_BLOCK_ID:
+        // Reject multiple MODULE_BLOCK's in a single bitstream.
+        if (TheModule)
+          return Error("Invalid multiple blocks");
+        TheModule = M;
+        if (std::error_code EC = ParseModule(false))
+          return EC;
+        if (LazyStreamer)
+          return std::error_code();
+        break;
+      default:
+        if (Stream.SkipBlock())
+          return Error("Invalid record");
+        break;
+      }
+      continue;
+    case BitstreamEntry::Record:
+      // There should be no records in the top-level of blocks.
+
+      // The ranlib in Xcode 4 will align archive members by appending newlines
+      // to the end of them. If this file size is a multiple of 4 but not 8, we
+      // have to read and ignore these final 4 bytes :-(
+      if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 &&
+          Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a &&
+          Stream.AtEndOfStream())
+        return std::error_code();
+
+      return Error("Invalid record");
+    }
+  }
+}
+
+llvm::ErrorOr<std::string> BitcodeReader::parseModuleTriple() {
+  if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+
+  std::string Triple;
+  // Read all the records for this module.
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return Triple;
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a record.
+    switch (Stream.readRecord(Entry.ID, Record)) {
+    default: break;  // Default behavior, ignore unknown content.
+    case bitc::MODULE_CODE_VERSION:  // VERSION: [version#]
+      if (Record.size() < 1)
+        return Error("Invalid record");
+      // Only version #0 is supported so far.
+      if (Record[0] != 0)
+        return Error("Invalid record");
+      break;
+    case bitc::MODULE_CODE_TRIPLE: {  // TRIPLE: [strchr x N]
+      std::string S;
+      if (ConvertToString(Record, 0, S))
+        return Error("Invalid record");
+      Triple = S;
+      break;
+    }
+    }
+    Record.clear();
+  }
+
+  return Error("Invalid bitcode signature");
+}
+
+llvm::ErrorOr<std::string> BitcodeReader::parseTriple() {
+  if (std::error_code EC = InitStream())
+    return EC;
+
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'B' ||
+      Stream.Read(8) != 'C' ||
+      Stream.Read(4) != 0x0 ||
+      Stream.Read(4) != 0xC ||
+      Stream.Read(4) != 0xE ||
+      Stream.Read(4) != 0xD)
+    return Error("Invalid bitcode signature");
+
+  // We expect a number of well-defined blocks, though we don't necessarily
+  // need to understand them all.
+  while (1) {
+    BitstreamEntry Entry = Stream.advance();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return std::error_code();
+
+    case BitstreamEntry::SubBlock:
+      if (Entry.ID == bitc::MODULE_BLOCK_ID)
+        return parseModuleTriple();
+
+      // Ignore other sub-blocks.
+      if (Stream.SkipBlock())
+        return Error("Malformed block");
+      continue;
+
+    case BitstreamEntry::Record:
+      Stream.skipRecord(Entry.ID);
+      continue;
+    }
+  }
+}
+
+/// ParseMetadataAttachment - Parse metadata attachments.
+std::error_code BitcodeReader::ParseMetadataAttachment() {
+  if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
+    return Error("Invalid record");
+
+  SmallVector<uint64_t, 64> Record;
+  while (1) {
+    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+
+    switch (Entry.Kind) {
+    case BitstreamEntry::SubBlock: // Handled for us already.
+    case BitstreamEntry::Error:
+      return Error("Malformed block");
+    case BitstreamEntry::EndBlock:
+      return std::error_code();
+    case BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read a metadata attachment record.
+    Record.clear();
+    switch (Stream.readRecord(Entry.ID, Record)) {
+    default:  // Default behavior: ignore.
+      break;
+    case bitc::METADATA_ATTACHMENT: {
+      unsigned RecordLength = Record.size();
+      if (Record.empty() || (RecordLength - 1) % 2 == 1)
+        return Error("Invalid record");
+      Instruction *Inst = InstructionList[Record[0]];
+      for (unsigned i = 1; i != RecordLength; i = i+2) {
+        unsigned Kind = Record[i];
+        DenseMap<unsigned, unsigned>::iterator I =
+          MDKindMap.find(Kind);
+        if (I == MDKindMap.end())
+          return Error("Invalid ID");
+        Metadata *Node = MDValueList.getValueFwdRef(Record[i + 1]);
+        Inst->setMetadata(I->second, cast<MDNode>(Node));
+      }
+      break;
+    }
+    }
+  }
+}
+
+/// ParseFunctionBody - Lazily parse the specified function body block.
+std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
+  if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
+    return Error("Invalid record");
+
+  InstructionList.clear();
+  unsigned ModuleValueListSize = ValueList.size();
+  unsigned ModuleMDValueListSize = MDValueList.size();
+
+  // Add all the function arguments to the value table.
+  for(Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+    ValueList.push_back(&*I);
+
+  unsigned NextValueNo = ValueList.size();
+  BasicBlock *CurBB = nullptr;
+  unsigned CurBBNo = 0;
+
+  DebugLoc LastLoc;
+
+  // Read all the records.
+  SmallVector<uint64_t, 64> Record;
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Malformed block");
+      break;
+    }
+
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      switch (Stream.ReadSubBlockID()) {
+      default:  // Skip unknown content.
+        if (Stream.SkipBlock())
+          return Error("Invalid record");
+        break;
+      case bitc::CONSTANTS_BLOCK_ID:
+        if (std::error_code EC = ParseConstants())
+          return EC;
+        NextValueNo = ValueList.size();
+        break;
+      case bitc::VALUE_SYMTAB_BLOCK_ID:
+        if (std::error_code EC = ParseValueSymbolTable())
+          return EC;
+        break;
+      case bitc::METADATA_ATTACHMENT_ID:
+        if (std::error_code EC = ParseMetadataAttachment())
+          return EC;
+        break;
+      case bitc::METADATA_BLOCK_ID:
+        if (std::error_code EC = ParseMetadata())
+          return EC;
+        break;
+      }
+      continue;
+    }
+
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+
+    // Read a record.
+    Record.clear();
+    Instruction *I = nullptr;
+    unsigned BitCode = Stream.readRecord(Code, Record);
+    switch (BitCode) {
+    default: // Default behavior: reject
+      return Error("Invalid value");
+    case bitc::FUNC_CODE_DECLAREBLOCKS:     // DECLAREBLOCKS: [nblocks]
+      if (Record.size() < 1 || Record[0] == 0)
+        return Error("Invalid record");
+      // Create all the basic blocks for the function.
+      FunctionBBs.resize(Record[0]);
+      for (unsigned i = 0, e = FunctionBBs.size(); i != e; ++i)
+        FunctionBBs[i] = BasicBlock::Create(Context, "", F);
+      CurBB = FunctionBBs[0];
+      continue;
+
+    case bitc::FUNC_CODE_DEBUG_LOC_AGAIN:  // DEBUG_LOC_AGAIN
+      // This record indicates that the last instruction is at the same
+      // location as the previous instruction with a location.
+      I = nullptr;
+
+      // Get the last instruction emitted.
+      if (CurBB && !CurBB->empty())
+        I = &CurBB->back();
+      else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
+               !FunctionBBs[CurBBNo-1]->empty())
+        I = &FunctionBBs[CurBBNo-1]->back();
+
+      if (!I)
+        return Error("Invalid record");
+      I->setDebugLoc(LastLoc);
+      I = nullptr;
+      continue;
+
+    case bitc::FUNC_CODE_DEBUG_LOC: {      // DEBUG_LOC: [line, col, scope, ia]
+      I = nullptr;     // Get the last instruction emitted.
+      if (CurBB && !CurBB->empty())
+        I = &CurBB->back();
+      else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
+               !FunctionBBs[CurBBNo-1]->empty())
+        I = &FunctionBBs[CurBBNo-1]->back();
+      if (!I || Record.size() < 4)
+        return Error("Invalid record");
+
+      unsigned Line = Record[0], Col = Record[1];
+      unsigned ScopeID = Record[2], IAID = Record[3];
+
+      MDNode *Scope = nullptr, *IA = nullptr;
+      if (ScopeID) Scope = cast<MDNode>(MDValueList.getValueFwdRef(ScopeID-1));
+      if (IAID)    IA = cast<MDNode>(MDValueList.getValueFwdRef(IAID-1));
+      LastLoc = DebugLoc::get(Line, Col, Scope, IA);
+      I->setDebugLoc(LastLoc);
+      I = nullptr;
+      continue;
+    }
+
+    case bitc::FUNC_CODE_INST_BINOP: {    // BINOP: [opval, ty, opval, opcode]
+      unsigned OpNum = 0;
+      Value *LHS, *RHS;
+      if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
+          getValue(Record, OpNum, LHS->getType(), RHS) ||
+          OpNum+1 > Record.size())
+        return Error("Invalid record");
+
+      int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
+      if (Opc == -1)
+        return Error("Invalid record");
+      I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
+      InstructionList.push_back(I);
+      if (OpNum < Record.size()) {
+        if (Opc == Instruction::Add ||
+            Opc == Instruction::Sub ||
+            Opc == Instruction::Mul ||
+            Opc == Instruction::Shl) {
+          if (Record[OpNum] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+            cast<BinaryOperator>(I)->setHasNoSignedWrap(true);
+          if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+            cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true);
+        } else if (Opc == Instruction::SDiv ||
+                   Opc == Instruction::UDiv ||
+                   Opc == Instruction::LShr ||
+                   Opc == Instruction::AShr) {
+          if (Record[OpNum] & (1 << bitc::PEO_EXACT))
+            cast<BinaryOperator>(I)->setIsExact(true);
+        }
+      }
+      break;
+    }
+    case bitc::FUNC_CODE_INST_CAST: {    // CAST: [opval, opty, destty, castopc]
+      unsigned OpNum = 0;
+      Value *Op;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+          OpNum+2 != Record.size())
+        return Error("Invalid record");
+
+      Type *ResTy = getTypeByID(Record[OpNum]);
+      int Opc = GetDecodedCastOpcode(Record[OpNum+1]);
+      if (Opc == -1 || !ResTy)
+        return Error("Invalid record");
+      I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD:
+    case bitc::FUNC_CODE_INST_GEP_OLD: // GEP: [n x operands]
+    case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands]
+      unsigned OpNum = 0;
+
+      Type *Ty;
+      bool InBounds;
+
+      if (BitCode == bitc::FUNC_CODE_INST_GEP) {
+        InBounds = Record[OpNum++];
+        Ty = getTypeByID(Record[OpNum++]);
+      } else {
+        InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
+        Ty = nullptr;
+      }
+
+      Value *BasePtr;
+      if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr))
+        return Error("Invalid record");
+
+      if (Ty &&
+          Ty !=
+              cast<SequentialType>(BasePtr->getType()->getScalarType())
+                  ->getElementType())
+        return Error(
+            "Explicit gep type does not match pointee type of pointer operand");
+
+      SmallVector<Value*, 16> GEPIdx;
+      while (OpNum != Record.size()) {
+        Value *Op;
+        if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+          return Error("Invalid record");
+        GEPIdx.push_back(Op);
+      }
+
+      I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx);
+
+      InstructionList.push_back(I);
+      if (InBounds)
+        cast<GetElementPtrInst>(I)->setIsInBounds(true);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_EXTRACTVAL: {
+                                       // EXTRACTVAL: [opty, opval, n x indices]
+      unsigned OpNum = 0;
+      Value *Agg;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
+        return Error("Invalid record");
+
+      SmallVector<unsigned, 4> EXTRACTVALIdx;
+      for (unsigned RecSize = Record.size();
+           OpNum != RecSize; ++OpNum) {
+        uint64_t Index = Record[OpNum];
+        if ((unsigned)Index != Index)
+          return Error("Invalid value");
+        EXTRACTVALIdx.push_back((unsigned)Index);
+      }
+
+      I = ExtractValueInst::Create(Agg, EXTRACTVALIdx);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_INSERTVAL: {
+                           // INSERTVAL: [opty, opval, opty, opval, n x indices]
+      unsigned OpNum = 0;
+      Value *Agg;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
+        return Error("Invalid record");
+      Value *Val;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Val))
+        return Error("Invalid record");
+
+      SmallVector<unsigned, 4> INSERTVALIdx;
+      for (unsigned RecSize = Record.size();
+           OpNum != RecSize; ++OpNum) {
+        uint64_t Index = Record[OpNum];
+        if ((unsigned)Index != Index)
+          return Error("Invalid value");
+        INSERTVALIdx.push_back((unsigned)Index);
+      }
+
+      I = InsertValueInst::Create(Agg, Val, INSERTVALIdx);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_SELECT: { // SELECT: [opval, ty, opval, opval]
+      // obsolete form of select
+      // handles select i1 ... in old bitcode
+      unsigned OpNum = 0;
+      Value *TrueVal, *FalseVal, *Cond;
+      if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
+          getValue(Record, OpNum, TrueVal->getType(), FalseVal) ||
+          getValue(Record, OpNum, Type::getInt1Ty(Context), Cond))
+        return Error("Invalid record");
+
+      I = SelectInst::Create(Cond, TrueVal, FalseVal);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_VSELECT: {// VSELECT: [ty,opval,opval,predty,pred]
+      // new form of select
+      // handles select i1 or select [N x i1]
+      unsigned OpNum = 0;
+      Value *TrueVal, *FalseVal, *Cond;
+      if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
+          getValue(Record, OpNum, TrueVal->getType(), FalseVal) ||
+          getValueTypePair(Record, OpNum, NextValueNo, Cond))
+        return Error("Invalid record");
+
+      // select condition can be either i1 or [N x i1]
+      if (VectorType* vector_type =
+          dyn_cast<VectorType>(Cond->getType())) {
+        // expect <n x i1>
+        if (vector_type->getElementType() != Type::getInt1Ty(Context))
+          return Error("Invalid type for value");
+      } else {
+        // expect i1
+        if (Cond->getType() != Type::getInt1Ty(Context))
+          return Error("Invalid type for value");
+      }
+
+      I = SelectInst::Create(Cond, TrueVal, FalseVal);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval]
+      unsigned OpNum = 0;
+      Value *Vec, *Idx;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
+          getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
+        return Error("Invalid record");
+      I = ExtractElementInst::Create(Vec, Idx);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval]
+      unsigned OpNum = 0;
+      Value *Vec, *Elt, *Idx;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
+          getValue(Record, OpNum,
+                   cast<VectorType>(Vec->getType())->getElementType(), Elt) ||
+          getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
+        return Error("Invalid record");
+      I = InsertElementInst::Create(Vec, Elt, Idx);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval]
+      unsigned OpNum = 0;
+      Value *Vec1, *Vec2, *Mask;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) ||
+          getValue(Record, OpNum, Vec1->getType(), Vec2))
+        return Error("Invalid record");
+
+      if (getValueTypePair(Record, OpNum, NextValueNo, Mask))
+        return Error("Invalid record");
+      I = new ShuffleVectorInst(Vec1, Vec2, Mask);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_CMP:   // CMP: [opty, opval, opval, pred]
+      // Old form of ICmp/FCmp returning bool
+      // Existed to differentiate between icmp/fcmp and vicmp/vfcmp which were
+      // both legal on vectors but had different behaviour.
+    case bitc::FUNC_CODE_INST_CMP2: { // CMP2: [opty, opval, opval, pred]
+      // FCmp/ICmp returning bool or vector of bool
+
+      unsigned OpNum = 0;
+      Value *LHS, *RHS;
+      if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
+          getValue(Record, OpNum, LHS->getType(), RHS) ||
+          OpNum+1 != Record.size())
+        return Error("Invalid record");
+
+      if (LHS->getType()->isFPOrFPVectorTy())
+        I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
+      else
+        I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_RET: // RET: [opty,opval<optional>]
+      {
+        unsigned Size = Record.size();
+        if (Size == 0) {
+          I = ReturnInst::Create(Context);
+          InstructionList.push_back(I);
+          break;
+        }
+
+        unsigned OpNum = 0;
+        Value *Op = nullptr;
+        if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+          return Error("Invalid record");
+        if (OpNum != Record.size())
+          return Error("Invalid record");
+
+        I = ReturnInst::Create(Context, Op);
+        InstructionList.push_back(I);
+        break;
+      }
+    case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
+      if (Record.size() != 1 && Record.size() != 3)
+        return Error("Invalid record");
+      BasicBlock *TrueDest = getBasicBlock(Record[0]);
+      if (!TrueDest)
+        return Error("Invalid record");
+
+      if (Record.size() == 1) {
+        I = BranchInst::Create(TrueDest);
+        InstructionList.push_back(I);
+      }
+      else {
+        BasicBlock *FalseDest = getBasicBlock(Record[1]);
+        Value *Cond = getFnValueByID(Record[2], Type::getInt1Ty(Context));
+        if (!FalseDest || !Cond)
+          return Error("Invalid record");
+        I = BranchInst::Create(TrueDest, FalseDest, Cond);
+        InstructionList.push_back(I);
+      }
+      break;
+    }
+    case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
+      if (Record.size() < 3 || (Record.size() & 1) == 0)
+        return Error("Invalid record");
+      Type *OpTy = getTypeByID(Record[0]);
+      Value *Cond = getFnValueByID(Record[1], OpTy);
+      BasicBlock *Default = getBasicBlock(Record[2]);
+      if (!OpTy || !Cond || !Default)
+        return Error("Invalid record");
+      unsigned NumCases = (Record.size()-3)/2;
+      SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
+      InstructionList.push_back(SI);
+      for (unsigned i = 0, e = NumCases; i != e; ++i) {
+        ConstantInt *CaseVal =
+          dyn_cast_or_null<ConstantInt>(getFnValueByID(Record[3+i*2], OpTy));
+        BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]);
+        if (!CaseVal || !DestBB) {
+          delete SI;
+          return Error("Invalid record");
+        }
+        SI->addCase(CaseVal, DestBB);
+      }
+      I = SI;
+      break;
+    }
+    case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...]
+      if (Record.size() < 2)
+        return Error("Invalid record");
+      Type *OpTy = getTypeByID(Record[0]);
+      Value *Address = getFnValueByID(Record[1], OpTy);
+      if (!OpTy || !Address)
+        return Error("Invalid record");
+      unsigned NumDests = Record.size()-2;
+      IndirectBrInst *IBI = IndirectBrInst::Create(Address, NumDests);
+      InstructionList.push_back(IBI);
+      for (unsigned i = 0, e = NumDests; i != e; ++i) {
+        if (BasicBlock *DestBB = getBasicBlock(Record[2+i])) {
+          IBI->addDestination(DestBB);
+        } else {
+          delete IBI;
+          return Error("Invalid record");
+        }
+      }
+      I = IBI;
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_INVOKE: {
+      // INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...]
+      if (Record.size() < 4)
+        return Error("Invalid record");
+      AttributeSet PAL = getAttributes(Record[0]);
+      unsigned CCInfo = Record[1];
+      BasicBlock *NormalBB = getBasicBlock(Record[2]);
+      BasicBlock *UnwindBB = getBasicBlock(Record[3]);
+
+      unsigned OpNum = 4;
+      Value *Callee;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
+        return Error("Invalid record");
+
+      PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType());
+      FunctionType *FTy = !CalleeTy ? nullptr :
+        dyn_cast<FunctionType>(CalleeTy->getElementType());
+
+      // Check that the right number of fixed parameters are here.
+      if (!FTy || !NormalBB || !UnwindBB ||
+          Record.size() < OpNum+FTy->getNumParams())
+        return Error("Invalid record");
+
+      SmallVector<Value*, 16> Ops;
+      for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
+        Ops.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i)));
+        if (!Ops.back())
+          return Error("Invalid record");
+      }
+
+      if (!FTy->isVarArg()) {
+        if (Record.size() != OpNum)
+          return Error("Invalid record");
+      } else {
+        // Read type/value pairs for varargs params.
+        while (OpNum != Record.size()) {
+          Value *Op;
+          if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+            return Error("Invalid record");
+          Ops.push_back(Op);
+        }
+      }
+
+      I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops);
+      InstructionList.push_back(I);
+      cast<InvokeInst>(I)->setCallingConv(
+        static_cast<CallingConv::ID>(CCInfo));
+      cast<InvokeInst>(I)->setAttributes(PAL);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval]
+      unsigned Idx = 0;
+      Value *Val = nullptr;
+      if (getValueTypePair(Record, Idx, NextValueNo, Val))
+        return Error("Invalid record");
+      I = ResumeInst::Create(Val);
+      InstructionList.push_back(I);
+      break;
+    }
+    case FUNC_CODE_INST_UNWIND_2_7: { // UNWIND_OLD
+      // 'unwind' instruction has been removed in LLVM 3.1
+      // Replace 'unwind' with 'landingpad' and 'resume'.
+      Type *ExnTy = StructType::get(Type::getInt8PtrTy(Context),
+                                    Type::getInt32Ty(Context), nullptr);
+
+      LandingPadInst *LP = LandingPadInst::Create(ExnTy, 1);
+      LP->setCleanup(true);
+
+      CurBB->getInstList().push_back(LP);
+      I = ResumeInst::Create(LP);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
+      I = new UnreachableInst(Context);
+      InstructionList.push_back(I);
+      break;
+    case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
+      if (Record.size() < 1 || ((Record.size()-1)&1))
+        return Error("Invalid record");
+      Type *Ty = getTypeByID(Record[0]);
+      if (!Ty)
+        return Error("Invalid record");
+
+      PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2);
+      InstructionList.push_back(PN);
+
+      for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
+        Value *V = getFnValueByID(Record[1+i], Ty);
+        BasicBlock *BB = getBasicBlock(Record[2+i]);
+        if (!V || !BB)
+          return Error("Invalid record");
+        PN->addIncoming(V, BB);
+      }
+      I = PN;
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_LANDINGPAD_OLD: {
+      // LANDINGPAD: [ty, val, val, num, (id0,val0 ...)?]
+      unsigned Idx = 0;
+      if (Record.size() < 4)
+        return Error("Invalid record");
+      Type *Ty = getTypeByID(Record[Idx++]);
+      if (!Ty)
+        return Error("Invalid record");
+      Value *PersFn = nullptr;
+      if (getValueTypePair(Record, Idx, NextValueNo, PersFn))
+        return Error("Invalid record");
+
+      bool IsCleanup = !!Record[Idx++];
+      unsigned NumClauses = Record[Idx++];
+      LandingPadInst *LP = LandingPadInst::Create(Ty, NumClauses);
+      LP->setCleanup(IsCleanup);
+      for (unsigned J = 0; J != NumClauses; ++J) {
+        LandingPadInst::ClauseType CT =
+          LandingPadInst::ClauseType(Record[Idx++]); (void)CT;
+        Value *Val;
+
+        if (getValueTypePair(Record, Idx, NextValueNo, Val)) {
+          delete LP;
+          return Error("Invalid record");
+        }
+
+        assert((CT != LandingPadInst::Catch ||
+                !isa<ArrayType>(Val->getType())) &&
+               "Catch clause has a invalid type!");
+        assert((CT != LandingPadInst::Filter ||
+                isa<ArrayType>(Val->getType())) &&
+               "Filter clause has invalid type!");
+        LP->addClause(cast<Constant>(Val));
+      }
+
+      I = LP;
+      InstructionList.push_back(I);
+      break;
+    }
+
+    case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align]
+      if (Record.size() != 4)
+        return Error("Invalid record");
+      PointerType *Ty =
+        dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
+      Type *OpTy = getTypeByID(Record[1]);
+      Value *Size = getFnValueByID(Record[2], OpTy);
+      unsigned Align = Record[3];
+      if (!Ty || !Size)
+        return Error("Invalid record");
+      I = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol]
+      unsigned OpNum = 0;
+      Value *Op;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+          OpNum+2 != Record.size())
+        return Error("Invalid record");
+
+      I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_LOADATOMIC: {
+       // LOADATOMIC: [opty, op, align, vol, ordering, synchscope]
+      unsigned OpNum = 0;
+      Value *Op;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+          OpNum+4 != Record.size())
+        return Error("Invalid record");
+
+      AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
+      if (Ordering == NotAtomic || Ordering == Release ||
+          Ordering == AcquireRelease)
+        return Error("Invalid record");
+      if (Ordering != NotAtomic && Record[OpNum] == 0)
+        return Error("Invalid record");
+      SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]);
+
+      I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1,
+                       Ordering, SynchScope);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol]
+      unsigned OpNum = 0;
+      Value *Val, *Ptr;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
+          getValue(Record, OpNum,
+                    cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
+          OpNum+2 != Record.size())
+        return Error("Invalid record");
+
+      I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_STOREATOMIC: {
+      // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, synchscope]
+      unsigned OpNum = 0;
+      Value *Val, *Ptr;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
+          getValue(Record, OpNum,
+                    cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
+          OpNum+4 != Record.size())
+        return Error("Invalid record");
+
+      AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
+      if (Ordering == NotAtomic || Ordering == Acquire ||
+          Ordering == AcquireRelease)
+        return Error("Invalid record");
+      SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]);
+      if (Ordering != NotAtomic && Record[OpNum] == 0)
+        return Error("Invalid record");
+
+      I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1,
+                        Ordering, SynchScope);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_CMPXCHG: {
+      // CMPXCHG:[ptrty, ptr, cmp, new, vol, ordering, synchscope]
+      unsigned OpNum = 0;
+      Value *Ptr, *Cmp, *New;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
+          getValue(Record, OpNum,
+                    cast<PointerType>(Ptr->getType())->getElementType(), Cmp) ||
+          getValue(Record, OpNum,
+                    cast<PointerType>(Ptr->getType())->getElementType(), New) ||
+          OpNum+3 != Record.size())
+        return Error("Invalid record");
+      AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+1]);
+      if (Ordering == NotAtomic || Ordering == Unordered)
+        return Error("Invalid record");
+      SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+2]);
+      I = new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, Ordering, SynchScope);
+      cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_ATOMICRMW: {
+      // ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, synchscope]
+      unsigned OpNum = 0;
+      Value *Ptr, *Val;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
+          getValue(Record, OpNum,
+                    cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
+          OpNum+4 != Record.size())
+        return Error("Invalid record");
+      AtomicRMWInst::BinOp Operation = GetDecodedRMWOperation(Record[OpNum]);
+      if (Operation < AtomicRMWInst::FIRST_BINOP ||
+          Operation > AtomicRMWInst::LAST_BINOP)
+        return Error("Invalid record");
+      AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
+      if (Ordering == NotAtomic || Ordering == Unordered)
+        return Error("Invalid record");
+      SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]);
+      I = new AtomicRMWInst(Operation, Ptr, Val, Ordering, SynchScope);
+      cast<AtomicRMWInst>(I)->setVolatile(Record[OpNum+1]);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_FENCE: { // FENCE:[ordering, synchscope]
+      if (2 != Record.size())
+        return Error("Invalid record");
+      AtomicOrdering Ordering = GetDecodedOrdering(Record[0]);
+      if (Ordering == NotAtomic || Ordering == Unordered ||
+          Ordering == Monotonic)
+        return Error("Invalid record");
+      SynchronizationScope SynchScope = GetDecodedSynchScope(Record[1]);
+      I = new FenceInst(Context, Ordering, SynchScope);
+      InstructionList.push_back(I);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_CALL: {
+      // CALL: [paramattrs, cc, fnty, fnid, arg0, arg1...]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+
+      AttributeSet PAL = getAttributes(Record[0]);
+      unsigned CCInfo = Record[1];
+
+      unsigned OpNum = 2;
+      Value *Callee;
+      if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
+        return Error("Invalid record");
+
+      PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
+      FunctionType *FTy = nullptr;
+      if (OpTy) FTy = dyn_cast<FunctionType>(OpTy->getElementType());
+      if (!FTy || Record.size() < FTy->getNumParams()+OpNum)
+        return Error("Invalid record");
+
+      SmallVector<Value*, 16> Args;
+      // Read the fixed params.
+      for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
+        if (FTy->getParamType(i)->isLabelTy())
+          Args.push_back(getBasicBlock(Record[OpNum]));
+        else
+          Args.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i)));
+        if (!Args.back())
+          return Error("Invalid record");
+      }
+
+      // Read type/value pairs for varargs params.
+      if (!FTy->isVarArg()) {
+        if (OpNum != Record.size())
+          return Error("Invalid record");
+      } else {
+        while (OpNum != Record.size()) {
+          Value *Op;
+          if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+            return Error("Invalid record");
+          Args.push_back(Op);
+        }
+      }
+
+      I = CallInst::Create(Callee, Args);
+      InstructionList.push_back(I);
+      cast<CallInst>(I)->setCallingConv(
+        static_cast<CallingConv::ID>(CCInfo>>1));
+      cast<CallInst>(I)->setTailCall(CCInfo & 1);
+      cast<CallInst>(I)->setAttributes(PAL);
+      break;
+    }
+    case bitc::FUNC_CODE_INST_VAARG: { // VAARG: [valistty, valist, instty]
+      if (Record.size() < 3)
+        return Error("Invalid record");
+      Type *OpTy = getTypeByID(Record[0]);
+      Value *Op = getFnValueByID(Record[1], OpTy);
+      Type *ResTy = getTypeByID(Record[2]);
+      if (!OpTy || !Op || !ResTy)
+        return Error("Invalid record");
+      I = new VAArgInst(Op, ResTy);
+      InstructionList.push_back(I);
+      break;
+    }
+    }
+
+    // Add instruction to end of current BB.  If there is no current BB, reject
+    // this file.
+    if (!CurBB) {
+      delete I;
+      return Error("Invalid instruction with no BB");
+    }
+    CurBB->getInstList().push_back(I);
+
+    // If this was a terminator instruction, move to the next block.
+    if (isa<TerminatorInst>(I)) {
+      ++CurBBNo;
+      CurBB = CurBBNo < FunctionBBs.size() ? FunctionBBs[CurBBNo] : nullptr;
+    }
+
+    // Non-void values get registered in the value table for future use.
+    if (I && !I->getType()->isVoidTy())
+      ValueList.AssignValue(I, NextValueNo++);
+  }
+
+  // Check the function list for unresolved values.
+  if (Argument *A = dyn_cast<Argument>(ValueList.back())) {
+    if (!A->getParent()) {
+      // We found at least one unresolved value.  Nuke them all to avoid leaks.
+      for (unsigned i = ModuleValueListSize, e = ValueList.size(); i != e; ++i){
+        if ((A = dyn_cast_or_null<Argument>(ValueList[i])) && !A->getParent()) {
+          A->replaceAllUsesWith(UndefValue::get(A->getType()));
+          delete A;
+        }
+      }
+      return Error("Never resolved value found in function");
+    }
+  }
+
+  // FIXME: Check for unresolved forward-declared metadata references
+  // and clean up leaks.
+
+  // See if anything took the address of blocks in this function.  If so,
+  // resolve them now.
+  DenseMap<Function*, std::vector<BlockAddrRefTy> >::iterator BAFRI =
+    BlockAddrFwdRefs.find(F);
+  if (BAFRI != BlockAddrFwdRefs.end()) {
+    std::vector<BlockAddrRefTy> &RefList = BAFRI->second;
+    for (unsigned i = 0, e = RefList.size(); i != e; ++i) {
+      unsigned BlockIdx = RefList[i].first;
+      if (BlockIdx >= FunctionBBs.size())
+        return Error("Invalid ID");
+
+      GlobalVariable *FwdRef = RefList[i].second;
+      FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx]));
+      FwdRef->eraseFromParent();
+    }
+
+    BlockAddrFwdRefs.erase(BAFRI);
+  }
+
+  // Trim the value list down to the size it was before we parsed this function.
+  ValueList.shrinkTo(ModuleValueListSize);
+  MDValueList.shrinkTo(ModuleMDValueListSize);
+  std::vector<BasicBlock*>().swap(FunctionBBs);
+  return std::error_code();
+}
+
+//===----------------------------------------------------------------------===//
+// GVMaterializer implementation
+//===----------------------------------------------------------------------===//
+
+void BitcodeReader::releaseBuffer() { Buffer.release(); }
+
+std::error_code BitcodeReader::materialize(GlobalValue *GV) {
+  if (std::error_code EC = materializeMetadata())
+    return EC;
+
+  Function *F = dyn_cast<Function>(GV);
+  // If it's not a function or is already material, ignore the request.
+  if (!F || !F->isMaterializable())
+    return std::error_code();
+
+  DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F);
+  assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
+
+  // Move the bit stream to the saved position of the deferred function body.
+  Stream.JumpToBit(DFII->second);
+
+  if (std::error_code EC = ParseFunctionBody(F))
+    return EC;
+  F->setIsMaterializable(false);
+
+  // Upgrade any old intrinsic calls in the function.
+  for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(),
+       E = UpgradedIntrinsics.end(); I != E; ++I) {
+    if (I->first != I->second) {
+      for (auto UI = I->first->user_begin(), UE = I->first->user_end();
+           UI != UE;) {
+        if (CallInst* CI = dyn_cast<CallInst>(*UI++))
+          UpgradeIntrinsicCall(CI, I->second);
+      }
+    }
+  }
+
+  return std::error_code();
+}
+
+bool BitcodeReader::isDematerializable(const GlobalValue *GV) const {
+  const Function *F = dyn_cast<Function>(GV);
+  if (!F || F->isDeclaration())
+    return false;
+  return DeferredFunctionInfo.count(const_cast<Function*>(F));
+}
+
+void BitcodeReader::dematerialize(GlobalValue *GV) {
+  Function *F = dyn_cast<Function>(GV);
+  // If this function isn't dematerializable, this is a noop.
+  if (!F || !isDematerializable(F))
+    return;
+
+  assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
+
+  // Just forget the function body, we can remat it later.
+  F->deleteBody();
+  F->setIsMaterializable(true);
+}
+
+std::error_code BitcodeReader::materializeModule() {
+  // Iterate over the module, deserializing any functions that are still on
+  // disk.
+  for (Module::iterator F = TheModule->begin(), E = TheModule->end();
+       F != E; ++F) {
+    if (std::error_code EC = materialize(&*F))
+      return EC;
+  }
+  // At this point, if there are any function bodies, the current bit is
+  // pointing to the END_BLOCK record after them. Now make sure the rest
+  // of the bits in the module have been read.
+  if (NextUnreadBit)
+    ParseModule(true);
+
+  // Upgrade any intrinsic calls that slipped through (should not happen!) and
+  // delete the old functions to clean up. We can't do this unless the entire
+  // module is materialized because there could always be another function body
+  // with calls to the old function.
+  for (std::vector<std::pair<Function*, Function*> >::iterator I =
+       UpgradedIntrinsics.begin(), E = UpgradedIntrinsics.end(); I != E; ++I) {
+    if (I->first != I->second) {
+      for (auto UI = I->first->user_begin(), UE = I->first->user_end();
+           UI != UE;) {
+        if (CallInst* CI = dyn_cast<CallInst>(*UI++))
+          UpgradeIntrinsicCall(CI, I->second);
+      }
+      if (!I->first->use_empty())
+        I->first->replaceAllUsesWith(I->second);
+      I->first->eraseFromParent();
+    }
+  }
+  std::vector<std::pair<Function*, Function*> >().swap(UpgradedIntrinsics);
+
+  // Upgrade to new EH scheme. N.B. This will go away in 3.1.
+  UpgradeExceptionHandling(TheModule);
+
+  // Check debug info intrinsics.
+  CheckDebugInfoIntrinsics(TheModule);
+
+  return std::error_code();
+}
+
+std::vector<StructType *> BitcodeReader::getIdentifiedStructTypes() const {
+  return IdentifiedStructTypes;
+}
+
+std::error_code BitcodeReader::InitStream() {
+  if (LazyStreamer)
+    return InitLazyStream();
+  return InitStreamFromBuffer();
+}
+
+std::error_code BitcodeReader::InitStreamFromBuffer() {
+  const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart();
+  const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
+
+  if (Buffer->getBufferSize() & 3)
+    return Error("Invalid bitcode signature");
+
+  // If we have a wrapper header, parse it and ignore the non-bc file contents.
+  // The magic number is 0x0B17C0DE stored in little endian.
+  if (isBitcodeWrapper(BufPtr, BufEnd))
+    if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true))
+      return Error("Invalid bitcode wrapper header");
+
+  StreamFile.reset(new BitstreamReader(BufPtr, BufEnd));
+  Stream.init(&*StreamFile);
+
+  return std::error_code();
+}
+
+std::error_code BitcodeReader::InitLazyStream() {
+  // Check and strip off the bitcode wrapper; BitstreamReader expects never to
+  // see it.
+  auto OwnedBytes = llvm::make_unique<StreamingMemoryObject>(
+      std::move(LazyStreamer));
+  StreamingMemoryObject &Bytes = *OwnedBytes;
+  StreamFile = llvm::make_unique<BitstreamReader>(std::move(OwnedBytes));
+  Stream.init(&*StreamFile);
+
+  unsigned char buf[16];
+  if (Bytes.readBytes(buf, 16, 0) != 16)
+    return Error("Invalid bitcode signature");
+
+  if (!isBitcode(buf, buf + 16))
+    return Error("Invalid bitcode signature");
+
+  if (isBitcodeWrapper(buf, buf + 4)) {
+    const unsigned char *bitcodeStart = buf;
+    const unsigned char *bitcodeEnd = buf + 16;
+    SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false);
+    Bytes.dropLeadingBytes(bitcodeStart - buf);
+    Bytes.setKnownObjectSize(bitcodeEnd - bitcodeStart);
+  }
+  return std::error_code();
+}
+
+namespace {
+class BitcodeErrorCategoryType : public std::error_category {
+  const char *name() const LLVM_NOEXCEPT override {
+    return "llvm.bitcode";
+  }
+  std::string message(int IE) const override {
+    BitcodeError E = static_cast<BitcodeError>(IE);
+    switch (E) {
+    case BitcodeError::InvalidBitcodeSignature:
+      return "Invalid bitcode signature";
+    case BitcodeError::CorruptedBitcode:
+      return "Corrupted bitcode";
+    }
+    llvm_unreachable("Unknown error type!");
+  }
+};
+}
+
+static ManagedStatic<BitcodeErrorCategoryType> ErrorCategory;
+
+const std::error_category &BitcodeReader::BitcodeErrorCategory() {
+  return *ErrorCategory;
+}
+
+//===----------------------------------------------------------------------===//
+// External interface
+//===----------------------------------------------------------------------===//
+
+/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
+///
+static llvm::ErrorOr<llvm::Module *>
+getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
+                         LLVMContext &Context, bool WillMaterializeAll,
+                         const DiagnosticHandlerFunction &DiagnosticHandler) {
+  Module *M = new Module(Buffer->getBufferIdentifier(), Context);
+  BitcodeReader *R =
+      new BitcodeReader(Buffer.get(), Context, DiagnosticHandler);
+  M->setMaterializer(R);
+
+  auto cleanupOnError = [&](std::error_code EC) {
+    R->releaseBuffer(); // Never take ownership on error.
+    delete M;  // Also deletes R.
+    return EC;
+  };
+
+  if (std::error_code EC = R->ParseBitcodeInto(M))
+    return cleanupOnError(EC);
+
+  Buffer.release(); // The BitcodeReader owns it now.
+  return M;
+}
+
+llvm::ErrorOr<Module *>
+llvm_3_0::getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
+                           LLVMContext &Context,
+                           const DiagnosticHandlerFunction &DiagnosticHandler) {
+  return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false,
+                                  DiagnosticHandler);
+}
+
+/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+/// If an error occurs, return null and fill in *ErrMsg if non-null.
+llvm::ErrorOr<llvm::Module *>
+llvm_3_0::parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
+                       const DiagnosticHandlerFunction &DiagnosticHandler) {
+  std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
+  ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModuleImpl(
+      std::move(Buf), Context, true, DiagnosticHandler);
+  if (!ModuleOrErr)
+    return ModuleOrErr;
+  Module *M = ModuleOrErr.get();
+  // Read in the entire module, and destroy the BitcodeReader.
+  if (std::error_code EC = M->materializeAll()) {
+    delete M;
+    return EC;
+  }
+
+  return M;
+}
+
+std::string
+llvm_3_0::getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context,
+                             DiagnosticHandlerFunction DiagnosticHandler) {
+  std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
+  auto R = llvm::make_unique<BitcodeReader>(Buf.release(), Context,
+                                            DiagnosticHandler);
+  ErrorOr<std::string> Triple = R->parseTriple();
+  if (Triple.getError())
+    return "";
+  return Triple.get();
+}
diff --git a/libbcc/bcinfo/BitReader_3_0/CMakeLists.txt b/libbcc/bcinfo/BitReader_3_0/CMakeLists.txt
new file mode 100644
index 0000000..37bebc4
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_3_0/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_llvm_library(LLVMBitReader
+  BitReader.cpp
+  BitcodeReader.cpp
+  )
+
+add_llvm_library_dependencies(LLVMBitReader
+  LLVMCore
+  LLVMSupport
+  )
diff --git a/libbcc/bcinfo/BitReader_3_0/LLVMBuild.txt b/libbcc/bcinfo/BitReader_3_0/LLVMBuild.txt
new file mode 100644
index 0000000..948b335
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_3_0/LLVMBuild.txt
@@ -0,0 +1,23 @@
+;===- ./lib/Bitcode/Reader/LLVMBuild.txt -----------------------*- Conf -*--===;
+;
+;                     The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+;   http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = BitReader
+parent = Bitcode
+required_libraries = Core Support
+
diff --git a/libbcc/bcinfo/BitReader_3_0/Makefile b/libbcc/bcinfo/BitReader_3_0/Makefile
new file mode 100644
index 0000000..59af8d5
--- /dev/null
+++ b/libbcc/bcinfo/BitReader_3_0/Makefile
@@ -0,0 +1,15 @@
+##===- lib/Bitcode/Reader/Makefile -------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME = LLVMBitReader
+BUILD_ARCHIVE = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/libbcc/bcinfo/BitcodeTranslator.cpp b/libbcc/bcinfo/BitcodeTranslator.cpp
new file mode 100644
index 0000000..3621c82
--- /dev/null
+++ b/libbcc/bcinfo/BitcodeTranslator.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2011-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bcinfo/BitcodeTranslator.h"
+
+#include "bcinfo/BitcodeWrapper.h"
+
+#include "BitReader_2_7/BitReader_2_7.h"
+#include "BitReader_3_0/BitReader_3_0.h"
+
+#include "BitWriter_3_2/ReaderWriter_3_2.h"
+
+#define LOG_TAG "bcinfo"
+#include <cutils/log.h>
+
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <cstdlib>
+#include <climits>
+
+namespace bcinfo {
+
+/**
+ * Define minimum and maximum target API versions. These correspond to the
+ * same API levels used by the standard Android SDK.
+ *
+ * LLVM 2.7
+ *  11 - Honeycomb
+ *  12 - Honeycomb MR1
+ *  13 - Honeycomb MR2
+ *
+ * LLVM 3.0
+ *  14 - Ice Cream Sandwich
+ *  15 - Ice Cream Sandwich MR1
+ *
+ * LLVM 3.1
+ *  16 - Ice Cream Sandwich MR2
+ */
+static const unsigned int kMinimumAPIVersion     = 11;
+static const unsigned int kMaximumAPIVersion     = RS_VERSION;
+static const unsigned int kCurrentAPIVersion     = 10000;
+static const unsigned int kDevelopmentAPIVersion = UINT_MAX;
+
+/**
+ * The minimum version which does not require translation (i.e. is already
+ * compatible with LLVM's default bitcode reader).
+ */
+static const unsigned int kMinimumUntranslatedVersion = 16;
+static const unsigned int kMinimumCompatibleVersion_LLVM_3_0 = 14;
+static const unsigned int kMinimumCompatibleVersion_LLVM_2_7 = 11;
+
+
+BitcodeTranslator::BitcodeTranslator(const char *bitcode, size_t bitcodeSize,
+                                     unsigned int version)
+    : mBitcode(bitcode), mBitcodeSize(bitcodeSize), mTranslatedBitcode(nullptr),
+      mTranslatedBitcodeSize(0), mVersion(version) {
+  return;
+}
+
+
+BitcodeTranslator::~BitcodeTranslator() {
+  if (mVersion < kMinimumUntranslatedVersion) {
+    // We didn't actually do a translation in the alternate case, so deleting
+    // the bitcode would be improper.
+    delete [] mTranslatedBitcode;
+  }
+  mTranslatedBitcode = nullptr;
+  return;
+}
+
+
+bool BitcodeTranslator::translate() {
+  if (!mBitcode || !mBitcodeSize) {
+    ALOGE("Invalid/empty bitcode");
+    return false;
+  }
+
+  BitcodeWrapper BCWrapper(mBitcode, mBitcodeSize);
+  if (BCWrapper.getTargetAPI() != mVersion) {
+    ALOGE("Bitcode wrapper (%u) and translator (%u) disagree about target API",
+          BCWrapper.getTargetAPI(), mVersion);
+  }
+
+  if ((mVersion != kDevelopmentAPIVersion) &&
+      (mVersion != kCurrentAPIVersion)     &&
+       ((mVersion < kMinimumAPIVersion) ||
+        (mVersion > kMaximumAPIVersion))) {
+    ALOGE("Invalid API version: %u is out of range ('%u' - '%u')", mVersion,
+         kMinimumAPIVersion, kMaximumAPIVersion);
+    return false;
+  }
+
+  // We currently don't need to transcode any API version higher than 14 or
+  // the current API version (i.e. 10000)
+  if (mVersion >= kMinimumUntranslatedVersion) {
+    mTranslatedBitcode = mBitcode;
+    mTranslatedBitcodeSize = mBitcodeSize;
+    return true;
+  }
+
+  // Do the actual transcoding by invoking a 2.7-era bitcode reader that can
+  // then write the bitcode back out in a more modern (acceptable) version.
+  std::unique_ptr<llvm::LLVMContext> mContext(new llvm::LLVMContext());
+  std::unique_ptr<llvm::MemoryBuffer> MEM(
+    llvm::MemoryBuffer::getMemBuffer(
+      llvm::StringRef(mBitcode, mBitcodeSize), "", false));
+  std::string error;
+  llvm::ErrorOr<llvm::MemoryBufferRef> MBOrErr = MEM->getMemBufferRef();
+
+  llvm::ErrorOr<llvm::Module *> MOrErr(nullptr);
+
+  if (mVersion >= kMinimumCompatibleVersion_LLVM_3_0) {
+    MOrErr = llvm_3_0::parseBitcodeFile(*MBOrErr, *mContext);
+  } else if (mVersion >= kMinimumCompatibleVersion_LLVM_2_7) {
+    MOrErr = llvm_2_7::parseBitcodeFile(*MBOrErr, *mContext);
+  } else {
+    ALOGE("No compatible bitcode reader for API version %d", mVersion);
+    return false;
+  }
+
+  if (std::error_code EC = MOrErr.getError()) {
+    ALOGE("Could not parse bitcode file");
+    ALOGE("%s", EC.message().c_str());
+    return false;
+  }
+
+  // Module ownership is handled by the context, so we don't need to free it.
+  llvm::Module *module = MOrErr.get();
+
+  std::string Buffer;
+
+  llvm::raw_string_ostream OS(Buffer);
+  // Use the LLVM 3.2 bitcode writer, instead of the top-of-tree version.
+  llvm_3_2::WriteBitcodeToFile(module, OS);
+  OS.flush();
+
+  AndroidBitcodeWrapper wrapper;
+  size_t actualWrapperLen = writeAndroidBitcodeWrapper(
+      &wrapper, Buffer.size(), kMinimumUntranslatedVersion,
+      BCWrapper.getCompilerVersion(), BCWrapper.getOptimizationLevel());
+  if (!actualWrapperLen) {
+    ALOGE("Couldn't produce bitcode wrapper!");
+    return false;
+  }
+
+  mTranslatedBitcodeSize = actualWrapperLen + Buffer.size();
+  char *c = new char[mTranslatedBitcodeSize];
+  memcpy(c, &wrapper, actualWrapperLen);
+  memcpy(c + actualWrapperLen, Buffer.c_str(), Buffer.size());
+
+  mTranslatedBitcode = c;
+
+  return true;
+}
+
+}  // namespace bcinfo
diff --git a/libbcc/bcinfo/BitcodeWrapper.cpp b/libbcc/bcinfo/BitcodeWrapper.cpp
new file mode 100644
index 0000000..1258067
--- /dev/null
+++ b/libbcc/bcinfo/BitcodeWrapper.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2011-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bcinfo/BitcodeWrapper.h"
+#include "bcinfo/Wrap/bitcode_wrapperer.h"
+#include "bcinfo/Wrap/in_memory_wrapper_input.h"
+
+#define LOG_TAG "bcinfo"
+#include <cutils/log.h>
+
+#include "llvm/Bitcode/ReaderWriter.h"
+
+#include <cstdlib>
+#include <cstring>
+
+namespace bcinfo {
+
+BitcodeWrapper::BitcodeWrapper(const char *bitcode, size_t bitcodeSize)
+    : mFileType(BC_NOT_BC), mBitcode(bitcode),
+      mBitcodeSize(bitcodeSize),
+      mHeaderVersion(0), mTargetAPI(0), mCompilerVersion(0),
+      mOptimizationLevel(3) {
+  InMemoryWrapperInput inMem(mBitcode, mBitcodeSize);
+  BitcodeWrapperer wrapperer(&inMem, nullptr);
+  if (wrapperer.IsInputBitcodeWrapper()) {
+    mFileType = BC_WRAPPER;
+    mHeaderVersion = wrapperer.getAndroidHeaderVersion();
+    mTargetAPI = wrapperer.getAndroidTargetAPI();
+    mCompilerVersion = wrapperer.getAndroidCompilerVersion();
+    mOptimizationLevel = wrapperer.getAndroidOptimizationLevel();
+  } else if (wrapperer.IsInputBitcodeFile()) {
+    mFileType = BC_RAW;
+  }
+}
+
+
+BitcodeWrapper::~BitcodeWrapper() {
+  return;
+}
+
+
+bool BitcodeWrapper::unwrap() {
+  return mFileType != BC_NOT_BC;
+}
+
+}  // namespace bcinfo
+
diff --git a/libbcc/bcinfo/MetadataExtractor.cpp b/libbcc/bcinfo/MetadataExtractor.cpp
new file mode 100644
index 0000000..48a2ecb
--- /dev/null
+++ b/libbcc/bcinfo/MetadataExtractor.cpp
@@ -0,0 +1,685 @@
+/*
+ * Copyright 2011-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bcinfo/MetadataExtractor.h"
+
+#include "bcinfo/BitcodeWrapper.h"
+#include "rsDefines.h"
+
+#define LOG_TAG "bcinfo"
+#include <cutils/log.h>
+#ifdef __ANDROID__
+#include <cutils/properties.h>
+#endif
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Function.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+#include <cstdlib>
+
+namespace bcinfo {
+
+namespace {
+
+llvm::StringRef getStringOperand(const llvm::Metadata *node) {
+  if (auto *mds = llvm::dyn_cast_or_null<const llvm::MDString>(node)) {
+    return mds->getString();
+  }
+  return llvm::StringRef();
+}
+
+bool extractUIntFromMetadataString(uint32_t *value,
+    const llvm::Metadata *m) {
+  llvm::StringRef SigString = getStringOperand(m);
+  if (SigString != "") {
+    if (!SigString.getAsInteger(10, *value)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+const char *createStringFromValue(llvm::Metadata *m) {
+  auto ref = getStringOperand(m);
+  char *c = new char[ref.size() + 1];
+  memcpy(c, ref.data(), ref.size());
+  c[ref.size()] = '\0';
+  return c;
+}
+
+const char *createStringFromOptionalValue(llvm::MDNode *n, unsigned opndNum) {
+  llvm::Metadata *opnd;
+  if (opndNum >= n->getNumOperands() || !(opnd = n->getOperand(opndNum)))
+    return nullptr;
+  return createStringFromValue(opnd);
+}
+
+// Collect metadata from NamedMDNodes that contain a list of names
+// (strings).
+//
+// Inputs:
+//
+// NamedMetadata - An LLVM metadata node, each of whose operands have
+// a string as their first entry
+//
+// NameList - A reference that will hold an allocated array of strings
+//
+// Count - A reference that will hold the length of the allocated
+// array of strings
+//
+// Return value:
+//
+// Return true on success, false on error.
+//
+// Upon success, the function sets NameList to an array of strings
+// corresponding the names found in the metadata. The function sets
+// Count to the number of entries in NameList.
+//
+// An error occurs if one of the metadata operands doesn't have a
+// first entry.
+bool populateNameMetadata(const llvm::NamedMDNode *NameMetadata,
+                          const char **&NameList, size_t &Count) {
+  if (!NameMetadata) {
+    NameList = nullptr;
+    Count = 0;
+    return true;
+  }
+
+  Count = NameMetadata->getNumOperands();
+  if (!Count) {
+    NameList = nullptr;
+    return true;
+  }
+
+  NameList = new const char *[Count];
+
+  for (size_t i = 0; i < Count; i++) {
+    llvm::MDNode *Name = NameMetadata->getOperand(i);
+    if (Name && Name->getNumOperands() > 0) {
+      NameList[i] = createStringFromValue(Name->getOperand(0));
+    } else {
+      ALOGE("Metadata operand does not contain a name string");
+      for (size_t AllocatedIndex = 0; AllocatedIndex < i; AllocatedIndex++) {
+        delete [] NameList[AllocatedIndex];
+      }
+      delete [] NameList;
+      NameList = nullptr;
+      Count = 0;
+
+      return false;
+    }
+  }
+
+  return true;
+}
+
+} // end anonymous namespace
+
+// Name of metadata node where pragma info resides (should be synced with
+// slang.cpp)
+static const llvm::StringRef PragmaMetadataName = "#pragma";
+
+// Name of metadata node where exported variable names reside (should be
+// synced with slang_rs_metadata.h)
+static const llvm::StringRef ExportVarMetadataName = "#rs_export_var";
+
+// Name of metadata node where exported function names reside (should be
+// synced with slang_rs_metadata.h)
+static const llvm::StringRef ExportFuncMetadataName = "#rs_export_func";
+
+// Name of metadata node where exported ForEach name information resides
+// (should be synced with slang_rs_metadata.h)
+static const llvm::StringRef ExportForEachNameMetadataName =
+    "#rs_export_foreach_name";
+
+// Name of metadata node where exported ForEach signature information resides
+// (should be synced with slang_rs_metadata.h)
+static const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";
+
+// Name of metadata node where exported general reduce information resides
+// (should be synced with slang_rs_metadata.h)
+static const llvm::StringRef ExportReduceMetadataName = "#rs_export_reduce";
+
+// Name of metadata node where RS object slot info resides (should be
+// synced with slang_rs_metadata.h)
+static const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
+
+static const llvm::StringRef ThreadableMetadataName = "#rs_is_threadable";
+
+// Name of metadata node where the checksum for this build is stored.  (should
+// be synced with libbcc/lib/Core/Source.cpp)
+static const llvm::StringRef ChecksumMetadataName = "#rs_build_checksum";
+
+// Name of metadata node which contains a list of compile units that have debug
+// metadata. If this is null then there is no debug metadata in the compile
+// unit.
+static const llvm::StringRef DebugInfoMetadataName = "llvm.dbg.cu";
+
+MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
+    : mModule(nullptr), mBitcode(bitcode), mBitcodeSize(bitcodeSize),
+      mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
+      mExportReduceCount(0), mExportVarNameList(nullptr),
+      mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
+      mExportForEachSignatureList(nullptr),
+      mExportForEachInputCountList(nullptr),
+      mExportReduceList(nullptr),
+      mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
+      mObjectSlotCount(0), mObjectSlotList(nullptr),
+      mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
+      mBuildChecksum(nullptr), mHasDebugInfo(false) {
+  BitcodeWrapper wrapper(bitcode, bitcodeSize);
+  mTargetAPI = wrapper.getTargetAPI();
+  mCompilerVersion = wrapper.getCompilerVersion();
+  mOptimizationLevel = wrapper.getOptimizationLevel();
+}
+
+MetadataExtractor::MetadataExtractor(const llvm::Module *module)
+    : mModule(module), mBitcode(nullptr), mBitcodeSize(0),
+      mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
+      mExportReduceCount(0), mExportVarNameList(nullptr),
+      mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
+      mExportForEachSignatureList(nullptr),
+      mExportForEachInputCountList(nullptr),
+      mExportReduceList(nullptr),
+      mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
+      mObjectSlotCount(0), mObjectSlotList(nullptr),
+      mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
+      mBuildChecksum(nullptr) {
+  mCompilerVersion = RS_VERSION;  // Default to the actual current version.
+  mOptimizationLevel = 3;
+}
+
+
+MetadataExtractor::~MetadataExtractor() {
+  if (mExportVarNameList) {
+    for (size_t i = 0; i < mExportVarCount; i++) {
+        delete [] mExportVarNameList[i];
+        mExportVarNameList[i] = nullptr;
+    }
+  }
+  delete [] mExportVarNameList;
+  mExportVarNameList = nullptr;
+
+  if (mExportFuncNameList) {
+    for (size_t i = 0; i < mExportFuncCount; i++) {
+        delete [] mExportFuncNameList[i];
+        mExportFuncNameList[i] = nullptr;
+    }
+  }
+  delete [] mExportFuncNameList;
+  mExportFuncNameList = nullptr;
+
+  if (mExportForEachNameList) {
+    for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
+        delete [] mExportForEachNameList[i];
+        mExportForEachNameList[i] = nullptr;
+    }
+  }
+  delete [] mExportForEachNameList;
+  mExportForEachNameList = nullptr;
+
+  delete [] mExportForEachSignatureList;
+  mExportForEachSignatureList = nullptr;
+
+  delete [] mExportForEachInputCountList;
+  mExportForEachInputCountList = nullptr;
+
+  delete [] mExportReduceList;
+  mExportReduceList = nullptr;
+
+  for (size_t i = 0; i < mPragmaCount; i++) {
+    if (mPragmaKeyList) {
+      delete [] mPragmaKeyList[i];
+      mPragmaKeyList[i] = nullptr;
+    }
+    if (mPragmaValueList) {
+      delete [] mPragmaValueList[i];
+      mPragmaValueList[i] = nullptr;
+    }
+  }
+  delete [] mPragmaKeyList;
+  mPragmaKeyList = nullptr;
+  delete [] mPragmaValueList;
+  mPragmaValueList = nullptr;
+
+  delete [] mObjectSlotList;
+  mObjectSlotList = nullptr;
+
+  delete [] mBuildChecksum;
+
+  return;
+}
+
+
+bool MetadataExtractor::populateObjectSlotMetadata(
+    const llvm::NamedMDNode *ObjectSlotMetadata) {
+  if (!ObjectSlotMetadata) {
+    return true;
+  }
+
+  mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
+
+  if (!mObjectSlotCount) {
+    return true;
+  }
+
+  uint32_t *TmpSlotList = new uint32_t[mObjectSlotCount];
+  memset(TmpSlotList, 0, mObjectSlotCount * sizeof(*TmpSlotList));
+
+  for (size_t i = 0; i < mObjectSlotCount; i++) {
+    llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
+    if (ObjectSlot != nullptr && ObjectSlot->getNumOperands() == 1) {
+      if (!extractUIntFromMetadataString(&TmpSlotList[i], ObjectSlot->getOperand(0))) {
+        ALOGE("Non-integer object slot value");
+        return false;
+      }
+    } else {
+      ALOGE("Corrupt object slot information");
+      return false;
+    }
+  }
+
+  mObjectSlotList = TmpSlotList;
+
+  return true;
+}
+
+
+void MetadataExtractor::populatePragmaMetadata(
+    const llvm::NamedMDNode *PragmaMetadata) {
+  if (!PragmaMetadata) {
+    return;
+  }
+
+  mPragmaCount = PragmaMetadata->getNumOperands();
+  if (!mPragmaCount) {
+    return;
+  }
+
+  const char **TmpKeyList = new const char*[mPragmaCount];
+  const char **TmpValueList = new const char*[mPragmaCount];
+
+  for (size_t i = 0; i < mPragmaCount; i++) {
+    llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
+    if (Pragma != nullptr && Pragma->getNumOperands() == 2) {
+      llvm::Metadata *PragmaKeyMDS = Pragma->getOperand(0);
+      TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
+      llvm::Metadata *PragmaValueMDS = Pragma->getOperand(1);
+      TmpValueList[i] = createStringFromValue(PragmaValueMDS);
+    }
+  }
+
+  mPragmaKeyList = TmpKeyList;
+  mPragmaValueList = TmpValueList;
+
+  // Check to see if we have any FP precision-related pragmas.
+  std::string Relaxed("rs_fp_relaxed");
+  std::string Imprecise("rs_fp_imprecise");
+  std::string Full("rs_fp_full");
+  bool RelaxedPragmaSeen = false;
+  bool FullPragmaSeen = false;
+  for (size_t i = 0; i < mPragmaCount; i++) {
+    if (!Relaxed.compare(mPragmaKeyList[i])) {
+      RelaxedPragmaSeen = true;
+    } else if (!Imprecise.compare(mPragmaKeyList[i])) {
+      ALOGW("rs_fp_imprecise is deprecated.  Assuming rs_fp_relaxed instead.");
+      RelaxedPragmaSeen = true;
+    } else if (!Full.compare(mPragmaKeyList[i])) {
+      FullPragmaSeen = true;
+    }
+  }
+
+  if (RelaxedPragmaSeen && FullPragmaSeen) {
+    ALOGE("Full and relaxed precision specified at the same time!");
+  }
+  mRSFloatPrecision = RelaxedPragmaSeen ? RS_FP_Relaxed : RS_FP_Full;
+
+#ifdef __ANDROID__
+  // Provide an override for precsiion via adb shell setprop
+  // adb shell setprop debug.rs.precision rs_fp_full
+  // adb shell setprop debug.rs.precision rs_fp_relaxed
+  // adb shell setprop debug.rs.precision rs_fp_imprecise
+  char PrecisionPropBuf[PROPERTY_VALUE_MAX];
+  const std::string PrecisionPropName("debug.rs.precision");
+  property_get("debug.rs.precision", PrecisionPropBuf, "");
+  if (PrecisionPropBuf[0]) {
+    if (!Relaxed.compare(PrecisionPropBuf)) {
+      ALOGI("Switching to RS FP relaxed mode via setprop");
+      mRSFloatPrecision = RS_FP_Relaxed;
+    } else if (!Imprecise.compare(PrecisionPropBuf)) {
+      ALOGW("Switching to RS FP relaxed mode via setprop. rs_fp_imprecise was "
+            "specified but is deprecated ");
+      mRSFloatPrecision = RS_FP_Relaxed;
+    } else if (!Full.compare(PrecisionPropBuf)) {
+      ALOGI("Switching to RS FP full mode via setprop");
+      mRSFloatPrecision = RS_FP_Full;
+    } else {
+      ALOGE("Unrecognized debug.rs.precision %s", PrecisionPropBuf);
+    }
+  }
+#endif
+}
+
+uint32_t MetadataExtractor::calculateNumInputs(const llvm::Function *Function,
+                                               uint32_t Signature) {
+
+  if (hasForEachSignatureIn(Signature)) {
+    uint32_t OtherCount = 0;
+
+    OtherCount += hasForEachSignatureUsrData(Signature);
+    OtherCount += hasForEachSignatureX(Signature);
+    OtherCount += hasForEachSignatureY(Signature);
+    OtherCount += hasForEachSignatureZ(Signature);
+    OtherCount += hasForEachSignatureCtxt(Signature);
+    OtherCount += hasForEachSignatureOut(Signature) &&
+                  Function->getReturnType()->isVoidTy();
+
+    return Function->arg_size() - OtherCount;
+
+  } else {
+    return 0;
+  }
+}
+
+
+bool MetadataExtractor::populateForEachMetadata(
+    const llvm::NamedMDNode *Names,
+    const llvm::NamedMDNode *Signatures) {
+  if (!Names && !Signatures && mCompilerVersion == 0) {
+    // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
+    // section for ForEach. We generate a full signature for a "root" function
+    // which means that we need to set the bottom 5 bits in the mask.
+    mExportForEachSignatureCount = 1;
+    char **TmpNameList = new char*[mExportForEachSignatureCount];
+    size_t RootLen = strlen(kRoot) + 1;
+    TmpNameList[0] = new char[RootLen];
+    strncpy(TmpNameList[0], kRoot, RootLen);
+
+    uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
+    TmpSigList[0] = 0x1f;
+
+    mExportForEachNameList = (const char**)TmpNameList;
+    mExportForEachSignatureList = TmpSigList;
+    return true;
+  }
+
+  if (Signatures) {
+    mExportForEachSignatureCount = Signatures->getNumOperands();
+    if (!mExportForEachSignatureCount) {
+      return true;
+    }
+  } else {
+    mExportForEachSignatureCount = 0;
+    mExportForEachSignatureList = nullptr;
+    return true;
+  }
+
+  uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
+  const char **TmpNameList = new const char*[mExportForEachSignatureCount];
+  uint32_t *TmpInputCountList = new uint32_t[mExportForEachSignatureCount];
+
+  for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
+    llvm::MDNode *SigNode = Signatures->getOperand(i);
+    if (SigNode != nullptr && SigNode->getNumOperands() == 1) {
+      if (!extractUIntFromMetadataString(&TmpSigList[i], SigNode->getOperand(0))) {
+        ALOGE("Non-integer signature value");
+        return false;
+      }
+    } else {
+      ALOGE("Corrupt signature information");
+      return false;
+    }
+  }
+
+  if (Names) {
+    for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
+      llvm::MDNode *Name = Names->getOperand(i);
+      if (Name != nullptr && Name->getNumOperands() == 1) {
+        TmpNameList[i] = createStringFromValue(Name->getOperand(0));
+
+        // Note that looking up the function by name can fail: One of
+        // the uses of MetadataExtractor is as part of the
+        // RSEmbedInfoPass, which bcc_compat runs sufficiently late in
+        // the phase order that RSKernelExpandPass has already run and
+        // the original (UNexpanded) kernel function (TmpNameList[i])
+        // may have been deleted as having no references (if it has
+        // been inlined into the expanded kernel function and is
+        // otherwise unreferenced).
+        llvm::Function *Func =
+            mModule->getFunction(llvm::StringRef(TmpNameList[i]));
+
+        TmpInputCountList[i] = (Func != nullptr) ?
+          calculateNumInputs(Func, TmpSigList[i]) : 0;
+      }
+    }
+  } else {
+    if (mExportForEachSignatureCount != 1) {
+      ALOGE("mExportForEachSignatureCount = %zu, but should be 1",
+            mExportForEachSignatureCount);
+    }
+    char *RootName = new char[5];
+    strncpy(RootName, "root", 5);
+    TmpNameList[0] = RootName;
+  }
+
+  mExportForEachNameList = TmpNameList;
+  mExportForEachSignatureList = TmpSigList;
+  mExportForEachInputCountList = TmpInputCountList;
+
+  return true;
+}
+
+
+bool MetadataExtractor::populateReduceMetadata(const llvm::NamedMDNode *ReduceMetadata) {
+  mExportReduceCount = 0;
+  mExportReduceList = nullptr;
+
+  if (!ReduceMetadata || !(mExportReduceCount = ReduceMetadata->getNumOperands()))
+    return true;
+
+  Reduce *TmpReduceList = new Reduce[mExportReduceCount];
+
+  for (size_t i = 0; i < mExportReduceCount; i++) {
+    llvm::MDNode *Node = ReduceMetadata->getOperand(i);
+    if (!Node || Node->getNumOperands() < 3) {
+      ALOGE("Missing reduce metadata");
+      return false;
+    }
+
+    TmpReduceList[i].mReduceName = createStringFromValue(Node->getOperand(0));
+
+    if (!extractUIntFromMetadataString(&TmpReduceList[i].mAccumulatorDataSize,
+                                       Node->getOperand(1))) {
+      ALOGE("Non-integer accumulator data size value in reduce metadata");
+      return false;
+    }
+
+    llvm::MDNode *AccumulatorNode = llvm::dyn_cast<llvm::MDNode>(Node->getOperand(2));
+    if (!AccumulatorNode || AccumulatorNode->getNumOperands() != 2) {
+      ALOGE("Malformed accumulator node in reduce metadata");
+      return false;
+    }
+    TmpReduceList[i].mAccumulatorName = createStringFromValue(AccumulatorNode->getOperand(0));
+    if (!extractUIntFromMetadataString(&TmpReduceList[i].mSignature,
+                                       AccumulatorNode->getOperand(1))) {
+      ALOGE("Non-integer signature value in reduce metadata");
+      return false;
+    }
+    // Note that looking up the function by name can fail: One of the
+    // uses of MetadataExtractor is as part of the RSEmbedInfoPass,
+    // which bcc_compat runs sufficiently late in the phase order that
+    // RSKernelExpandPass has already run and the original
+    // (UNexpanded) accumulator function (mAccumulatorName) may have
+    // been deleted as having no references (if it has been inlined
+    // into the expanded accumulator function and is otherwise
+    // unreferenced).
+    llvm::Function *Func =
+        mModule->getFunction(llvm::StringRef(TmpReduceList[i].mAccumulatorName));
+    // Why calculateNumInputs() - 1?  The "-1" is because we don't
+    // want to treat the accumulator argument as an input.
+    TmpReduceList[i].mInputCount = (Func ? calculateNumInputs(Func, TmpReduceList[i].mSignature) - 1 : 0);
+
+    TmpReduceList[i].mInitializerName = createStringFromOptionalValue(Node, 3);
+    TmpReduceList[i].mCombinerName = createStringFromOptionalValue(Node, 4);
+    TmpReduceList[i].mOutConverterName = createStringFromOptionalValue(Node, 5);
+    TmpReduceList[i].mHalterName = createStringFromOptionalValue(Node, 6);
+  }
+
+  mExportReduceList = TmpReduceList;
+  return true;
+}
+
+void MetadataExtractor::readThreadableFlag(
+    const llvm::NamedMDNode *ThreadableMetadata) {
+
+  // Scripts are threadable by default.  If we read a valid metadata value for
+  // 'ThreadableMetadataName' and it is set to 'no', we mark script as non
+  // threadable.  All other exception paths retain the default value.
+
+  mIsThreadable = true;
+  if (ThreadableMetadata == nullptr)
+    return;
+
+  llvm::MDNode *mdNode = ThreadableMetadata->getOperand(0);
+  if (mdNode == nullptr)
+    return;
+
+  llvm::Metadata *mdValue = mdNode->getOperand(0);
+  if (mdValue == nullptr)
+    return;
+
+  if (getStringOperand(mdValue) == "no")
+    mIsThreadable = false;
+}
+
+void MetadataExtractor::readBuildChecksumMetadata(
+    const llvm::NamedMDNode *ChecksumMetadata) {
+
+  if (ChecksumMetadata == nullptr)
+    return;
+
+  llvm::MDNode *mdNode = ChecksumMetadata->getOperand(0);
+  if (mdNode == nullptr)
+    return;
+
+  llvm::Metadata *mdValue = mdNode->getOperand(0);
+  if (mdValue == nullptr)
+    return;
+
+  mBuildChecksum = createStringFromValue(mdValue);
+}
+
+bool MetadataExtractor::extract() {
+  if (!(mBitcode && mBitcodeSize) && !mModule) {
+    ALOGE("Invalid/empty bitcode/module");
+    return false;
+  }
+
+  std::unique_ptr<llvm::LLVMContext> mContext;
+  bool shouldNullModule = false;
+
+  if (!mModule) {
+    mContext.reset(new llvm::LLVMContext());
+    std::unique_ptr<llvm::MemoryBuffer> MEM(
+      llvm::MemoryBuffer::getMemBuffer(
+        llvm::StringRef(mBitcode, mBitcodeSize), "", false));
+    std::string error;
+
+    llvm::ErrorOr<std::unique_ptr<llvm::Module> > errval =
+        llvm::parseBitcodeFile(MEM.get()->getMemBufferRef(), *mContext);
+    if (std::error_code ec = errval.getError()) {
+        ALOGE("Could not parse bitcode file");
+        ALOGE("%s", ec.message().c_str());
+        return false;
+    }
+
+    mModule = errval.get().release();
+    shouldNullModule = true;
+  }
+
+  const llvm::NamedMDNode *ExportVarMetadata =
+      mModule->getNamedMetadata(ExportVarMetadataName);
+  const llvm::NamedMDNode *ExportFuncMetadata =
+      mModule->getNamedMetadata(ExportFuncMetadataName);
+  const llvm::NamedMDNode *ExportForEachNameMetadata =
+      mModule->getNamedMetadata(ExportForEachNameMetadataName);
+  const llvm::NamedMDNode *ExportForEachMetadata =
+      mModule->getNamedMetadata(ExportForEachMetadataName);
+  const llvm::NamedMDNode *ExportReduceMetadata =
+      mModule->getNamedMetadata(ExportReduceMetadataName);
+  const llvm::NamedMDNode *PragmaMetadata =
+      mModule->getNamedMetadata(PragmaMetadataName);
+  const llvm::NamedMDNode *ObjectSlotMetadata =
+      mModule->getNamedMetadata(ObjectSlotMetadataName);
+  const llvm::NamedMDNode *ThreadableMetadata =
+      mModule->getNamedMetadata(ThreadableMetadataName);
+  const llvm::NamedMDNode *ChecksumMetadata =
+      mModule->getNamedMetadata(ChecksumMetadataName);
+  const llvm::NamedMDNode *DebugInfoMetadata =
+      mModule->getNamedMetadata(DebugInfoMetadataName);
+
+  if (!populateNameMetadata(ExportVarMetadata, mExportVarNameList,
+                            mExportVarCount)) {
+    ALOGE("Could not populate export variable metadata");
+    goto err;
+  }
+
+  if (!populateNameMetadata(ExportFuncMetadata, mExportFuncNameList,
+                            mExportFuncCount)) {
+    ALOGE("Could not populate export function metadata");
+    goto err;
+  }
+
+  if (!populateForEachMetadata(ExportForEachNameMetadata,
+                               ExportForEachMetadata)) {
+    ALOGE("Could not populate ForEach signature metadata");
+    goto err;
+  }
+
+  if (!populateReduceMetadata(ExportReduceMetadata)) {
+    ALOGE("Could not populate export general reduction metadata");
+    goto err;
+  }
+
+  populatePragmaMetadata(PragmaMetadata);
+
+  if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
+    ALOGE("Could not populate object slot metadata");
+    goto err;
+  }
+
+  readThreadableFlag(ThreadableMetadata);
+  readBuildChecksumMetadata(ChecksumMetadata);
+
+  mHasDebugInfo = DebugInfoMetadata != nullptr;
+
+  if (shouldNullModule) {
+    mModule = nullptr;
+  }
+  return true;
+
+err:
+  if (shouldNullModule) {
+    mModule = nullptr;
+  }
+  return false;
+}
+
+}  // namespace bcinfo
diff --git a/libbcc/bcinfo/Wrap/Android.mk b/libbcc/bcinfo/Wrap/Android.mk
new file mode 100644
index 0000000..92508d8
--- /dev/null
+++ b/libbcc/bcinfo/Wrap/Android.mk
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+LLVM_ROOT_PATH := external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+
+llvm_wrap_SRC_FILES := \
+  bitcode_wrapperer.cpp \
+  file_wrapper_input.cpp \
+  file_wrapper_output.cpp \
+  in_memory_wrapper_input.cpp \
+  wrapper_output.cpp
+
+llvm_wrap_C_INCLUDES := $(LOCAL_PATH)/../../include
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libLLVMWrap
+LOCAL_MODULE_HOST_OS := darwin linux windows
+
+LOCAL_SRC_FILES := $(llvm_wrap_SRC_FILES)
+LOCAL_CFLAGS += -D__HOST__
+LOCAL_C_INCLUDES := $(llvm_wrap_C_INCLUDES)
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS))
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libLLVMWrap
+
+LOCAL_SRC_FILES := $(llvm_wrap_SRC_FILES)
+LOCAL_C_INCLUDES := $(llvm_wrap_C_INCLUDES)
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
+endif
diff --git a/libbcc/bcinfo/Wrap/LLVMBuild.txt b/libbcc/bcinfo/Wrap/LLVMBuild.txt
new file mode 100644
index 0000000..8750711
--- /dev/null
+++ b/libbcc/bcinfo/Wrap/LLVMBuild.txt
@@ -0,0 +1,21 @@
+;===- ./lib/Wrap/LLVMBuild.txt ------------------------------*- Conf -*--===;
+;
+;                     The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+;   http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = Wrap
+parent = Libraries
diff --git a/libbcc/bcinfo/Wrap/Makefile b/libbcc/bcinfo/Wrap/Makefile
new file mode 100644
index 0000000..79aa2b3
--- /dev/null
+++ b/libbcc/bcinfo/Wrap/Makefile
@@ -0,0 +1,14 @@
+##===- lib/Linker/Makefile ---------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+LIBRARYNAME = LLVMWrap
+BUILD_ARCHIVE := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/libbcc/bcinfo/Wrap/bitcode_wrapperer.cpp b/libbcc/bcinfo/Wrap/bitcode_wrapperer.cpp
new file mode 100644
index 0000000..0a49497
--- /dev/null
+++ b/libbcc/bcinfo/Wrap/bitcode_wrapperer.cpp
@@ -0,0 +1,385 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bcinfo/Wrap/bitcode_wrapperer.h"
+
+#define LOG_TAG "bcinfo"
+#include <cutils/log.h>
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+using std::vector;
+
+// The number of bytes in a 32 bit integer.
+static const uint32_t kWordSize = 4;
+
+// Number of LLVM-defined fixed fields in the header.
+static const uint32_t kLLVMFields = 4;
+
+// Total number of fixed fields in the header.
+static const uint32_t kFixedFields = 7;
+
+// The magic number that must exist for bitcode wrappers.
+static const uint32_t kWrapperMagicNumber = 0x0B17C0DE;
+
+// The version number associated with a wrapper file.
+// Note: llvm currently only allows the value 0. When this changes,
+// we should consider making this a command line option.
+static const uint32_t kLLVMVersionNumber = 0;
+
+// Fields defined by Android bitcode header.
+static const uint32_t kAndroidHeaderVersion = 0;
+static const uint32_t kAndroidTargetAPI = 0;
+static const uint32_t kAndroidDefaultCompilerVersion = 0;
+static const uint32_t kAndroidDefaultOptimizationLevel = 3;
+
+// PNaCl bitcode version number.
+static const uint32_t kPnaclBitcodeVersion = 0;
+
+// Max size for variable fields. Currently only used for writing them
+// out to files (the parsing works for arbitrary sizes).
+static const size_t kMaxVariableFieldSize = 256;
+
+BitcodeWrapperer::BitcodeWrapperer(WrapperInput* infile, WrapperOutput* outfile)
+    : infile_(infile),
+      outfile_(outfile),
+      buffer_size_(0),
+      cursor_(0),
+      infile_at_eof_(false),
+      infile_bc_offset_(0),
+      wrapper_bc_offset_(0),
+      wrapper_bc_size_(0),
+      android_header_version_(kAndroidHeaderVersion),
+      android_target_api_(kAndroidTargetAPI),
+      android_compiler_version_(kAndroidDefaultCompilerVersion),
+      android_optimization_level_(kAndroidDefaultOptimizationLevel),
+      pnacl_bc_version_(0),
+      error_(false) {
+  buffer_.resize(kBitcodeWrappererBufferSize);
+  if (IsInputBitcodeWrapper()) {
+    ParseWrapperHeader();
+  } else if (IsInputBitcodeFile()) {
+    wrapper_bc_offset_ = kWordSize * kFixedFields;
+    wrapper_bc_size_ = GetInFileSize();
+  } else {
+    ALOGE("Error: input file is not a bitcode file.\n");
+    error_ = true;
+  }
+}
+
+BitcodeWrapperer::~BitcodeWrapperer() {
+  for(size_t i = 0; i < variable_field_data_.size(); i++) {
+    delete [] variable_field_data_[i];
+  }
+}
+
+
+void BitcodeWrapperer::ClearBuffer() {
+  buffer_size_ = 0;
+  cursor_ = 0;
+  infile_at_eof_ = false;
+}
+
+bool BitcodeWrapperer::Seek(uint32_t pos) {
+  if (infile_ != nullptr && infile_->Seek(pos)) {
+    ClearBuffer();
+    return true;
+  }
+  return false;
+}
+
+bool BitcodeWrapperer::CanReadWord() {
+  if (GetBufferUnreadBytes() < kWordSize) {
+    FillBuffer();
+    return GetBufferUnreadBytes() >= kWordSize;
+  } else {
+    return true;
+  }
+}
+
+void BitcodeWrapperer::FillBuffer() {
+  if (cursor_ > 0) {
+    // Before filling, move any remaining bytes to the
+    // front of the buffer. This allows us to assume
+    // that after the call to FillBuffer, readable
+    // text is contiguous.
+    if (cursor_ < buffer_size_) {
+      size_t i = 0;
+      while (cursor_ < buffer_size_) {
+        buffer_[i++] = buffer_[cursor_++];
+      }
+      cursor_ = 0;
+      buffer_size_ = i;
+    }
+  } else {
+    // Assume the buffer contents have been used,
+    // and we want to completely refill it.
+    buffer_size_ = 0;
+  }
+
+  // If we don't have an input, we can't refill the buffer at all.
+  if (infile_ == nullptr) {
+    return;
+  }
+
+  // Now fill in remaining space.
+  size_t needed = buffer_.size() - buffer_size_;
+
+  while (buffer_.size() > buffer_size_) {
+    int actually_read = infile_->Read(&buffer_[buffer_size_], needed);
+    if (infile_->AtEof()) {
+      infile_at_eof_ = true;
+    }
+    if (actually_read) {
+      buffer_size_ += actually_read;
+      needed -= actually_read;
+    } else if (infile_at_eof_) {
+      break;
+    }
+  }
+}
+
+bool BitcodeWrapperer::ReadWord(uint32_t& word) {
+  if (!CanReadWord()) return false;
+  word = (((uint32_t) BufferLookahead(0)) << 0)
+      | (((uint32_t) BufferLookahead(1)) << 8)
+      | (((uint32_t) BufferLookahead(2)) << 16)
+      | (((uint32_t) BufferLookahead(3)) << 24);
+  cursor_ += kWordSize;
+  return true;
+}
+
+bool BitcodeWrapperer::WriteWord(uint32_t value) {
+  uint8_t buffer[kWordSize];
+  buffer[3] = (value >> 24) & 0xFF;
+  buffer[2] = (value >> 16) & 0xFF;
+  buffer[1] = (value >> 8)  & 0xFF;
+  buffer[0] = (value >> 0)  & 0xFF;
+  return outfile_->Write(buffer, kWordSize);
+}
+
+bool BitcodeWrapperer::WriteVariableFields() {
+  // This buffer may have to be bigger if we start using the fields
+  // for larger things.
+  uint8_t buffer[kMaxVariableFieldSize];
+  for (vector<BCHeaderField>::iterator it = header_fields_.begin();
+       it != header_fields_.end(); ++it) {
+    if (!it->Write(buffer, kMaxVariableFieldSize) ||
+        !outfile_->Write(buffer, it->GetTotalSize())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool BitcodeWrapperer::ParseWrapperHeader() {
+  // Make sure LLVM-defined fields have been parsed
+  if (!IsInputBitcodeWrapper()) return false;
+  // Check the android/pnacl fields
+  if (!ReadWord(android_header_version_) ||
+      !ReadWord(android_target_api_) || !ReadWord(pnacl_bc_version_)) {
+    ALOGW("Error: file not long enough to contain header\n");
+    return false;
+  }
+  if (pnacl_bc_version_ != kPnaclBitcodeVersion) {
+    ALOGW("Error: bad PNaCl Bitcode version\n");
+    return false;
+  }
+  int field_data_total = wrapper_bc_offset_ - kWordSize * kFixedFields;
+  if (field_data_total > 0) {
+    // Read in the variable fields. We need to allocate space for the data.
+    int field_data_read = 0;
+
+    while (field_data_read < field_data_total) {
+      FillBuffer();
+      size_t buffer_needed = BCHeaderField::GetDataSizeFromSerialized(
+          &buffer_[cursor_]);
+      if (buffer_needed > buffer_.size()) {
+        buffer_.resize(buffer_needed +
+                       sizeof(BCHeaderField::FixedSubfield) * 2);
+        FillBuffer();
+      }
+      variable_field_data_.push_back(new uint8_t[buffer_needed]);
+
+      BCHeaderField field(BCHeaderField::kInvalid, 0,
+                          variable_field_data_.back());
+      field.Read(&buffer_[cursor_], buffer_size_);
+      header_fields_.push_back(field);
+      size_t field_size = field.GetTotalSize();
+      cursor_ += field_size;
+      field_data_read += field_size;
+      if (field_data_read > field_data_total) {
+        // We read too much data, the header is corrupted
+        ALOGE("Error: raw bitcode offset inconsistent with "
+              "variable field data\n");
+        return false;
+      }
+
+      struct IntFieldHelper {
+        BCHeaderField::FixedSubfield tag;
+        uint16_t len;
+        uint32_t val;
+      };
+      IntFieldHelper tempIntField;
+
+      switch (field.getID()) {
+        case BCHeaderField::kAndroidCompilerVersion:
+          if (field.Write((uint8_t*)&tempIntField,
+                          sizeof(tempIntField))) {
+            android_compiler_version_ = tempIntField.val;
+          }
+          break;
+        case BCHeaderField::kAndroidOptimizationLevel:
+          if (field.Write((uint8_t*)&tempIntField,
+                          sizeof(tempIntField))) {
+            android_optimization_level_ = tempIntField.val;
+          }
+          break;
+        default:
+          // Ignore other field types for now
+          break;
+      }
+    }
+    Seek(0);
+  }
+  return true;
+}
+
+bool BitcodeWrapperer::IsInputBitcodeWrapper() {
+  ResetCursor();
+  // First make sure that there are enough words (LLVM header)
+  // to peek at.
+  if (GetBufferUnreadBytes() < kLLVMFields * kWordSize) {
+    FillBuffer();
+    if (GetBufferUnreadBytes() < kLLVMFields * kWordSize) return false;
+  }
+
+  // Now make sure the magic number is right.
+  uint32_t first_word;
+  if ((!ReadWord(first_word)) ||
+      (kWrapperMagicNumber != first_word)) return false;
+
+  // Make sure the version is right.
+  uint32_t second_word;
+  if ((!ReadWord(second_word)) ||
+      (kLLVMVersionNumber != second_word)) return false;
+
+  // Make sure that the offset and size (for llvm) is defined.
+  uint32_t bc_offset;
+  uint32_t bc_size;
+  if (ReadWord(bc_offset) &&
+      ReadWord(bc_size)) {
+    // Before returning, save the extracted values.
+    wrapper_bc_offset_ = bc_offset;
+    infile_bc_offset_ = bc_offset;
+    wrapper_bc_size_ = bc_size;
+    return true;
+  }
+  // If reached, unable to read wrapped header.
+  return false;
+}
+
+bool BitcodeWrapperer::IsInputBitcodeFile() {
+  ResetCursor();
+  // First make sure that there are four bytes to peek at.
+  if (GetBufferUnreadBytes() < kWordSize) {
+    FillBuffer();
+    if (GetBufferUnreadBytes() < kWordSize) return false;
+  }
+  // If reached, Check if first 4 bytes match bitcode
+  // file magic number.
+  return (BufferLookahead(0) == 'B') &&
+      (BufferLookahead(1) == 'C') &&
+      (BufferLookahead(2) == 0xc0) &&
+      (BufferLookahead(3) == 0xde);
+}
+
+bool BitcodeWrapperer::BufferCopyInToOut(uint32_t size) {
+  while (size > 0) {
+    // Be sure buffer is non-empty before writing.
+    if (0 == buffer_size_) {
+      FillBuffer();
+      if (0 == buffer_size_) {
+        return false;
+      }
+    }
+    // copy the buffer to the output file.
+    size_t block = (buffer_size_ < size) ? buffer_size_ : size;
+    if (!outfile_->Write(&buffer_[cursor_], block)) return false;
+    size -= block;
+    buffer_size_ = 0;
+  }
+  // Be sure that there isn't more bytes on the input stream.
+  FillBuffer();
+  return buffer_size_ == 0;
+}
+
+void BitcodeWrapperer::AddHeaderField(BCHeaderField* field) {
+  header_fields_.push_back(*field);
+  wrapper_bc_offset_ += field->GetTotalSize();
+}
+
+bool BitcodeWrapperer::WriteBitcodeWrapperHeader() {
+  return
+      // Note: This writes out the 4 word header required by llvm wrapped
+      // bitcode.
+      WriteWord(kWrapperMagicNumber) &&
+      WriteWord(kLLVMVersionNumber) &&
+      WriteWord(wrapper_bc_offset_) &&
+      WriteWord(wrapper_bc_size_) &&
+      // 2 fixed fields defined by Android
+      WriteWord(android_header_version_) &&
+      WriteWord(android_target_api_) &&
+      // PNaClBitcode version
+      WriteWord(kPnaclBitcodeVersion) &&
+      // Common variable-length fields
+      WriteVariableFields();
+}
+
+void BitcodeWrapperer::PrintWrapperHeader() {
+  if (error_) {
+    fprintf(stderr, "Error condition exists: the following"
+            "data may not be reliable\n");
+  }
+  fprintf(stderr, "Wrapper magic:\t\t%x\n", kWrapperMagicNumber);
+  fprintf(stderr, "LLVM Bitcode version:\t%d\n", kLLVMVersionNumber);
+  fprintf(stderr, "Raw bitcode offset:\t%d\n", wrapper_bc_offset_);
+  fprintf(stderr, "Raw bitcode size:\t%d\n", wrapper_bc_size_);
+  fprintf(stderr, "Android header version:\t%d\n", android_header_version_);
+  fprintf(stderr, "Android target API:\t%d\n", android_target_api_);
+  fprintf(stderr, "PNaCl bitcode version:\t%d\n", kPnaclBitcodeVersion);
+  for (size_t i = 0; i < header_fields_.size(); i++) header_fields_[i].Print();
+}
+
+bool BitcodeWrapperer::GenerateWrappedBitcodeFile() {
+  if (!error_ &&
+      WriteBitcodeWrapperHeader() &&
+      Seek(infile_bc_offset_) &&
+      BufferCopyInToOut(wrapper_bc_size_)) {
+    off_t dangling = wrapper_bc_size_ & 3;
+    if (dangling) {
+      return outfile_->Write((const uint8_t*) "\0\0\0\0", 4 - dangling);
+    }
+    return true;
+  }
+  return false;
+}
+
+bool BitcodeWrapperer::GenerateRawBitcodeFile() {
+  return !error_ && Seek(infile_bc_offset_) &&
+      BufferCopyInToOut(wrapper_bc_size_);
+}
diff --git a/libbcc/bcinfo/Wrap/file_wrapper_input.cpp b/libbcc/bcinfo/Wrap/file_wrapper_input.cpp
new file mode 100644
index 0000000..7e34ba5
--- /dev/null
+++ b/libbcc/bcinfo/Wrap/file_wrapper_input.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include "bcinfo/Wrap/file_wrapper_input.h"
+
+FileWrapperInput::FileWrapperInput(const char* name) :
+    _name(name), _at_eof(false), _size_found(false), _size(0) {
+  _file = fopen(name, "rb");
+  if (_file == nullptr) {
+    fprintf(stderr, "Unable to open: %s\n", name);
+    exit(1);
+  }
+}
+
+FileWrapperInput::~FileWrapperInput() {
+  fclose(_file);
+}
+
+size_t FileWrapperInput::Read(uint8_t* buffer, size_t wanted) {
+  size_t found = fread((char*) buffer, 1, wanted, _file);
+  if (feof(_file) || ferror(_file)) {
+    _at_eof = true;
+  }
+  return found;
+}
+
+bool FileWrapperInput::AtEof() {
+  return _at_eof;
+}
+
+off_t FileWrapperInput::Size() {
+  if (_size_found) return _size;
+  struct stat st;
+  if (stat(_name, &st) == 0) {
+    _size_found = true;
+    _size = st.st_size;
+    return _size;
+  } else {
+    fprintf(stderr, "Unable to compute file size: %s\n", _name);
+    exit(1);
+  }
+  // NOT REACHABLE.
+  return 0;
+}
+
+bool FileWrapperInput::Seek(uint32_t pos) {
+  return fseek(_file, (long) pos, SEEK_SET) == 0;
+}
diff --git a/libbcc/bcinfo/Wrap/file_wrapper_output.cpp b/libbcc/bcinfo/Wrap/file_wrapper_output.cpp
new file mode 100644
index 0000000..c785223
--- /dev/null
+++ b/libbcc/bcinfo/Wrap/file_wrapper_output.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+
+#include "bcinfo/Wrap/file_wrapper_output.h"
+
+FileWrapperOutput::FileWrapperOutput(const char* name)
+    : _name(name) {
+  _file = fopen(name, "wb");
+  if (nullptr == _file) {
+    fprintf(stderr, "Unable to open: %s\n", name);
+    exit(1);
+  }
+}
+
+FileWrapperOutput::~FileWrapperOutput() {
+  fclose(_file);
+}
+
+bool FileWrapperOutput::Write(uint8_t byte) {
+  return EOF != fputc(byte, _file);
+}
+
+bool FileWrapperOutput::Write(const uint8_t* buffer, size_t buffer_size) {
+  if (!buffer) {
+    return false;
+  }
+
+  if (buffer_size > 0) {
+    return buffer_size == fwrite(buffer, 1, buffer_size, _file);
+  } else {
+    return true;
+  }
+}
diff --git a/libbcc/bcinfo/Wrap/in_memory_wrapper_input.cpp b/libbcc/bcinfo/Wrap/in_memory_wrapper_input.cpp
new file mode 100644
index 0000000..2d45d9c
--- /dev/null
+++ b/libbcc/bcinfo/Wrap/in_memory_wrapper_input.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include "bcinfo/Wrap/in_memory_wrapper_input.h"
+
+InMemoryWrapperInput::InMemoryWrapperInput(const char* buffer, size_t size) :
+    _buffer(buffer), _pos(0), _size(size) {
+}
+
+InMemoryWrapperInput::~InMemoryWrapperInput() {
+}
+
+size_t InMemoryWrapperInput::Read(uint8_t* buffer, size_t wanted) {
+  size_t found = 0;
+
+  if (!buffer) {
+    return 0;
+  }
+
+  while (found < wanted) {
+    if (_pos >= _size) {
+      return found;
+    }
+    buffer[found++] = _buffer[_pos++];
+  }
+  return found;
+}
+
+bool InMemoryWrapperInput::AtEof() {
+  return (_pos >= _size);
+}
+
+off_t InMemoryWrapperInput::Size() {
+  return _size;
+}
+
+bool InMemoryWrapperInput::Seek(uint32_t pos) {
+  if (pos < _size) {
+    _pos = pos;
+    return true;
+  } else {
+    return false;
+  }
+}
diff --git a/libbcc/bcinfo/Wrap/wrapper_output.cpp b/libbcc/bcinfo/Wrap/wrapper_output.cpp
new file mode 100644
index 0000000..3c72422
--- /dev/null
+++ b/libbcc/bcinfo/Wrap/wrapper_output.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bcinfo/Wrap/wrapper_output.h"
+
+bool WrapperOutput::Write(const uint8_t* buffer, size_t buffer_size) {
+  // Default implementation that uses the byte write routine.
+  for (size_t i = 0; i < buffer_size; ++i) {
+    if (!Write(buffer[i])) return false;
+  }
+  return true;
+}
diff --git a/libbcc/bcinfo/tools/Android.mk b/libbcc/bcinfo/tools/Android.mk
new file mode 100644
index 0000000..876a53c
--- /dev/null
+++ b/libbcc/bcinfo/tools/Android.mk
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+LLVM_ROOT_PATH := external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+
+# Executable for host
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bcinfo
+LOCAL_MODULE_CLASS := EXECUTABLES
+
+LOCAL_SRC_FILES := \
+  main.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+  libbcinfo
+
+LOCAL_STATIC_LIBRARIES := \
+  libLLVMBitReader \
+  libLLVMBitWriter \
+  libLLVMCore \
+  libLLVMSupport
+
+LOCAL_CFLAGS += -D__HOST__
+
+LOCAL_C_INCLUDES := \
+  $(LOCAL_PATH)/../../include
+
+LOCAL_LDLIBS = -ldl -lpthread
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(BUILD_HOST_EXECUTABLE)
+
diff --git a/libbcc/bcinfo/tools/main.cpp b/libbcc/bcinfo/tools/main.cpp
new file mode 100644
index 0000000..c85fdc4
--- /dev/null
+++ b/libbcc/bcinfo/tools/main.cpp
@@ -0,0 +1,393 @@
+/*
+ * Copyright 2011-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bcinfo/BitcodeTranslator.h>
+#include <bcinfo/BitcodeWrapper.h>
+#include <bcinfo/MetadataExtractor.h>
+
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Bitcode/ReaderWriter.h>
+#include <llvm/IR/AssemblyAnnotationWriter.h>
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/Module.h>
+#include <llvm/Support/FileSystem.h>
+#include <llvm/Support/ManagedStatic.h>
+#include <llvm/Support/MemoryBuffer.h>
+#include <llvm/Support/ToolOutputFile.h>
+
+#include <ctype.h>
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+// This file corresponds to the standalone bcinfo tool. It prints a variety of
+// information about a supplied bitcode input file.
+
+std::string inFile;
+std::string outFile;
+std::string infoFile;
+
+extern int opterr;
+extern int optind;
+
+bool translateFlag = false;
+bool infoFlag = false;
+bool verbose = true;
+
+static int parseOption(int argc, char** argv) {
+  int c;
+  while ((c = getopt(argc, argv, "itv")) != -1) {
+    opterr = 0;
+
+    switch(c) {
+      case '?':
+        // ignore any error
+        break;
+
+      case 't':
+        translateFlag = true;
+        break;
+
+      case 'i':
+        // Turn off verbose so that we only generate the .info file.
+        infoFlag = true;
+        verbose = false;
+        break;
+
+      case 'v':
+        verbose = true;
+        break;
+
+      default:
+        // Critical error occurs
+        return 0;
+        break;
+    }
+  }
+
+  if(optind >= argc) {
+    fprintf(stderr, "input file required\n");
+    return 0;
+  }
+
+  inFile = argv[optind];
+
+  int l = inFile.length();
+  if (l > 3 && inFile[l-3] == '.' && inFile[l-2] == 'b' && inFile[l-1] == 'c') {
+    outFile = std::string(inFile.begin(), inFile.end() - 3) + ".ll";
+    infoFile = std::string(inFile.begin(), inFile.end() - 3) + ".bcinfo";
+  } else {
+    outFile = inFile + ".ll";
+    infoFile = inFile + ".bcinfo";
+  }
+  return 1;
+}
+
+
+static void dumpReduceInfo(FILE *info, const char *Kind, const char *Name) {
+  if (Name)
+    fprintf(info, "  %s(%s)\n", Kind, Name);
+}
+
+static int dumpInfo(bcinfo::MetadataExtractor *ME) {
+  if (!ME) {
+    return 1;
+  }
+
+  FILE *info = fopen(infoFile.c_str(), "w");
+  if (!info) {
+    fprintf(stderr, "Could not open info file %s\n", infoFile.c_str());
+    return 2;
+  }
+
+  fprintf(info, "exportVarCount: %zu\n", ME->getExportVarCount());
+  const char **varNameList = ME->getExportVarNameList();
+  for (size_t i = 0; i < ME->getExportVarCount(); i++) {
+    fprintf(info, "%s\n", varNameList[i]);
+  }
+
+  fprintf(info, "exportFuncCount: %zu\n", ME->getExportFuncCount());
+  const char **funcNameList = ME->getExportFuncNameList();
+  for (size_t i = 0; i < ME->getExportFuncCount(); i++) {
+    fprintf(info, "%s\n", funcNameList[i]);
+  }
+
+  fprintf(info, "exportForEachCount: %zu\n",
+          ME->getExportForEachSignatureCount());
+  const char **nameList = ME->getExportForEachNameList();
+  const uint32_t *sigList = ME->getExportForEachSignatureList();
+  const uint32_t *inputCountList = ME->getExportForEachInputCountList();
+  for (size_t i = 0; i < ME->getExportForEachSignatureCount(); i++) {
+    fprintf(info, "%u - %s - %u\n", sigList[i], nameList[i],
+            inputCountList[i]);
+  }
+
+  fprintf(info, "exportReduceCount: %zu\n", ME->getExportReduceCount());
+  const bcinfo::MetadataExtractor::Reduce *reduceList =
+      ME->getExportReduceList();
+  for (size_t i = 0; i < ME->getExportReduceCount(); i++) {
+    const bcinfo::MetadataExtractor::Reduce &reduce = reduceList[i];
+    fprintf(info, "%u - %s - %u - %u\n", reduce.mSignature, reduce.mReduceName,
+            reduce.mInputCount, reduce.mAccumulatorDataSize);
+    dumpReduceInfo(info, "initializer",  reduce.mInitializerName);
+    dumpReduceInfo(info, "accumulator",  reduce.mAccumulatorName);
+    dumpReduceInfo(info, "combiner",     reduce.mCombinerName);
+    dumpReduceInfo(info, "outconverter", reduce.mOutConverterName);
+    dumpReduceInfo(info, "halter",       reduce.mHalterName);
+  }
+
+  fprintf(info, "objectSlotCount: %zu\n", ME->getObjectSlotCount());
+  const uint32_t *slotList = ME->getObjectSlotList();
+  for (size_t i = 0; i < ME->getObjectSlotCount(); i++) {
+    fprintf(info, "%u\n", slotList[i]);
+  }
+
+  fclose(info);
+  return 0;
+}
+
+
+static void dumpMetadata(bcinfo::MetadataExtractor *ME) {
+  if (!ME) {
+    return;
+  }
+
+  printf("RSFloatPrecision: ");
+  switch (ME->getRSFloatPrecision()) {
+  case bcinfo::RS_FP_Full:
+    printf("Full\n\n");
+    break;
+  case bcinfo::RS_FP_Relaxed:
+    printf("Relaxed\n\n");
+    break;
+  default:
+    printf("UNKNOWN\n\n");
+    break;
+  }
+
+  printf("exportVarCount: %zu\n", ME->getExportVarCount());
+  const char **varNameList = ME->getExportVarNameList();
+  for (size_t i = 0; i < ME->getExportVarCount(); i++) {
+    printf("var[%zu]: %s\n", i, varNameList[i]);
+  }
+  printf("\n");
+
+  printf("exportFuncCount: %zu\n", ME->getExportFuncCount());
+  const char **funcNameList = ME->getExportFuncNameList();
+  for (size_t i = 0; i < ME->getExportFuncCount(); i++) {
+    printf("func[%zu]: %s\n", i, funcNameList[i]);
+  }
+  printf("\n");
+
+  printf("exportForEachSignatureCount: %zu\n",
+         ME->getExportForEachSignatureCount());
+  const char **nameList = ME->getExportForEachNameList();
+  const uint32_t *sigList = ME->getExportForEachSignatureList();
+  const uint32_t *inputCountList = ME->getExportForEachInputCountList();
+  for (size_t i = 0; i < ME->getExportForEachSignatureCount(); i++) {
+    printf("exportForEachSignatureList[%zu]: %s - 0x%08x - %u\n", i, nameList[i],
+           sigList[i], inputCountList[i]);
+  }
+  printf("\n");
+
+  printf("exportReduceCount: %zu\n", ME->getExportReduceCount());
+  const bcinfo::MetadataExtractor::Reduce *reduceList = ME->getExportReduceList();
+  for (size_t i = 0; i < ME->getExportReduceCount(); i++) {
+    const bcinfo::MetadataExtractor::Reduce &reduce = reduceList[i];
+    printf("exportReduceList[%zu]: %s - 0x%08x - %u - %u\n", i, reduce.mReduceName,
+           reduce.mSignature, reduce.mInputCount, reduce.mAccumulatorDataSize);
+    dumpReduceInfo(stdout, "initializer",  reduce.mInitializerName);
+    dumpReduceInfo(stdout, "accumulator",  reduce.mAccumulatorName);
+    dumpReduceInfo(stdout, "combiner",     reduce.mCombinerName);
+    dumpReduceInfo(stdout, "outconverter", reduce.mOutConverterName);
+    dumpReduceInfo(stdout, "halter",       reduce.mHalterName);
+  }
+  printf("\n");
+
+  printf("pragmaCount: %zu\n", ME->getPragmaCount());
+  const char **keyList = ME->getPragmaKeyList();
+  const char **valueList = ME->getPragmaValueList();
+  for (size_t i = 0; i < ME->getPragmaCount(); i++) {
+    printf("pragma[%zu]: %s - %s\n", i, keyList[i], valueList[i]);
+  }
+  printf("\n");
+
+  printf("objectSlotCount: %zu\n", ME->getObjectSlotCount());
+  const uint32_t *slotList = ME->getObjectSlotList();
+  for (size_t i = 0; i < ME->getObjectSlotCount(); i++) {
+    printf("objectSlotList[%zu]: %u\n", i, slotList[i]);
+  }
+  printf("\n");
+
+  return;
+}
+
+
+static size_t readBitcode(const char **bitcode) {
+  if (!inFile.length()) {
+    fprintf(stderr, "input file required\n");
+    return 0;
+  }
+
+  struct stat statInFile;
+  if (stat(inFile.c_str(), &statInFile) < 0) {
+    fprintf(stderr, "Unable to stat input file: %s\n", strerror(errno));
+    return 0;
+  }
+
+  if (!S_ISREG(statInFile.st_mode)) {
+    fprintf(stderr, "Input file should be a regular file.\n");
+    return 0;
+  }
+
+  FILE *in = fopen(inFile.c_str(), "r");
+  if (!in) {
+    fprintf(stderr, "Could not open input file %s\n", inFile.c_str());
+    return 0;
+  }
+
+  size_t bitcodeSize = statInFile.st_size;
+
+  *bitcode = (const char*) calloc(1, bitcodeSize + 1);
+  size_t nread = fread((void*) *bitcode, 1, bitcodeSize, in);
+
+  if (nread != bitcodeSize)
+      fprintf(stderr, "Could not read all of file %s\n", inFile.c_str());
+
+  fclose(in);
+  return nread;
+}
+
+
+static void releaseBitcode(const char **bitcode) {
+  if (bitcode && *bitcode) {
+    free((void*) *bitcode);
+    *bitcode = nullptr;
+  }
+  return;
+}
+
+
+int main(int argc, char** argv) {
+  if(!parseOption(argc, argv)) {
+    fprintf(stderr, "failed to parse option\n");
+    return 1;
+  }
+
+  const char *bitcode = nullptr;
+  size_t bitcodeSize = readBitcode(&bitcode);
+
+  unsigned int version = 0;
+
+  bcinfo::BitcodeWrapper bcWrapper((const char *)bitcode, bitcodeSize);
+  if (bcWrapper.getBCFileType() == bcinfo::BC_WRAPPER) {
+    version = bcWrapper.getTargetAPI();
+    if (verbose) {
+      printf("Found bitcodeWrapper\n");
+    }
+  } else if (translateFlag) {
+    version = 12;
+  }
+
+  if (verbose) {
+    printf("targetAPI: %u\n", version);
+    printf("compilerVersion: %u\n", bcWrapper.getCompilerVersion());
+    printf("optimizationLevel: %u\n\n", bcWrapper.getOptimizationLevel());
+  }
+
+  std::unique_ptr<bcinfo::BitcodeTranslator> BT;
+  BT.reset(new bcinfo::BitcodeTranslator(bitcode, bitcodeSize, version));
+  if (!BT->translate()) {
+    fprintf(stderr, "failed to translate bitcode\n");
+    return 3;
+  }
+
+  std::unique_ptr<bcinfo::MetadataExtractor> ME;
+  ME.reset(new bcinfo::MetadataExtractor(BT->getTranslatedBitcode(),
+                                         BT->getTranslatedBitcodeSize()));
+  if (!ME->extract()) {
+    fprintf(stderr, "failed to get metadata\n");
+    return 4;
+  }
+
+  if (verbose) {
+    dumpMetadata(ME.get());
+
+    const char *translatedBitcode = BT->getTranslatedBitcode();
+    size_t translatedBitcodeSize = BT->getTranslatedBitcodeSize();
+
+    llvm::LLVMContext &ctx = llvm::getGlobalContext();
+    llvm::llvm_shutdown_obj called_on_exit;
+
+    std::unique_ptr<llvm::MemoryBuffer> mem;
+
+    mem = llvm::MemoryBuffer::getMemBuffer(
+        llvm::StringRef(translatedBitcode, translatedBitcodeSize),
+        inFile.c_str(), false);
+
+    std::unique_ptr<llvm::Module> module;
+    llvm::ErrorOr<std::unique_ptr<llvm::Module> > moduleOrError =
+        llvm::parseBitcodeFile(mem.get()->getMemBufferRef(), ctx);
+    std::error_code ec = moduleOrError.getError();
+    if (!ec) {
+        module = std::move(moduleOrError.get());
+        ec = module->materializeAll();
+    }
+    std::string errmsg;
+    if (ec) {
+      errmsg = ec.message();
+      module.reset();
+      if (errmsg.size()) {
+        fprintf(stderr, "error: %s\n", errmsg.c_str());
+      } else {
+        fprintf(stderr, "error: failed to parse bitcode file\n");
+      }
+      return 5;
+    }
+
+    std::unique_ptr<llvm::tool_output_file> tof(
+        new llvm::tool_output_file(outFile.c_str(), ec,
+                                   llvm::sys::fs::F_None));
+    std::unique_ptr<llvm::AssemblyAnnotationWriter> ann;
+    module->print(tof->os(), ann.get());
+
+    tof->keep();
+  }
+
+  if (infoFlag) {
+    if (dumpInfo(ME.get()) != 0) {
+      fprintf(stderr, "Error dumping info file\n");
+      return 6;
+    }
+  }
+
+  releaseBitcode(&bitcode);
+
+  return 0;
+}
diff --git a/libbcc/gdb_plugin/android-commands.py b/libbcc/gdb_plugin/android-commands.py
new file mode 100644
index 0000000..92b771c
--- /dev/null
+++ b/libbcc/gdb_plugin/android-commands.py
@@ -0,0 +1,771 @@
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# GDB plugin to allow debugging of apps on remote Android systems using gdbserver.
+#
+# To use this plugin, source this file from a Python-enabled GDB client, then use:
+#   load-android-app <app-source-dir>  to tell GDB about the app you are debugging
+#   run-android-app to start the app in a running state
+#   start-android-app to start the app in a paused state
+#   attach-android-ap to attach to an existing (running) instance of app
+#   set-android-device to select a target (only if multiple devices are attached)
+
+import fnmatch
+import gdb
+import os
+import shutil
+import subprocess
+import tempfile
+import time
+
+be_verbose = False
+enable_renderscript_dumps = True
+local_symbols_library_directory = os.path.join(os.getenv('ANDROID_PRODUCT_OUT', 'out'),
+      'symbols', 'system', 'lib')
+local_library_directory = os.path.join(os.getenv('ANDROID_PRODUCT_OUT', 'out'),
+      'system', 'lib')
+
+# ADB              - Basic ADB wrapper, far from complete
+# DebugAppInfo     - App configuration struct, as far as GDB cares
+# StartAndroidApp  - Implementation of GDB start (for android apps)
+# RunAndroidApp    - Implementation of GDB run (for android apps)
+# AttachAndroidApp - GDB command to attach to an existing android app process
+# AndroidStatus    - app status query command (not needed, mostly harmless)
+# LoadAndroidApp   - Sets the package and intent names for an app
+
+def _interesting_libs():
+  return ['libc', 'libbcc', 'libRS', 'libandroid_runtime', 'libart']
+
+# In python 2.6, subprocess.check_output does not exist, so it is implemented here
+def check_output(*popenargs, **kwargs):
+  p = subprocess.Popen(stdout=subprocess.PIPE, stderr=subprocess.STDOUT, *popenargs, **kwargs)
+  out, err = p.communicate()
+  retcode = p.poll()
+  if retcode != 0:
+    c = kwargs.get("args")
+    if c is None:
+      c = popenargs[0]
+    e = subprocess.CalledProcessError(retcode, c)
+    e.output = str(out) + str(err)
+    raise e
+  return out
+
+class DebugAppInfo:
+  """Stores information from an app manifest"""
+
+  def __init__(self):
+    self.name = None
+    self.intent = None
+
+  def get_name(self):
+    return self.name
+
+  def get_intent(self):
+    return self.intent
+
+  def get_data_directory(self):
+    return self.data_directory
+
+  def get_gdbserver_path(self):
+    return os.path.join(self.data_directory, "lib", "gdbserver")
+
+  def set_info(self, name, intent, data_directory):
+    self.name = name
+    self.intent = intent
+    self.data_directory = data_directory
+
+  def unset_info():
+    self.name = None
+    self.intent = None
+    self.data_directory = None
+
+class ADB:
+  """
+  Python class implementing a basic ADB wrapper for useful commands.
+  Uses subprocess to invoke adb.
+  """
+
+  def __init__(self, device=None, verbose=False):
+    self.verbose = verbose
+    self.current_device = device
+    self.temp_libdir = None
+    self.background_processes = []
+    self.android_build_top = os.getenv('ANDROID_BUILD_TOP', None)
+    if not self.android_build_top:
+      raise gdb.GdbError("Unable to read ANDROID_BUILD_TOP. " \
+        + "Is your environment setup correct?")
+
+    self.adb_path = os.path.join(self.android_build_top,
+                      'out', 'host', 'linux-x86', 'bin', 'adb')
+
+    if not self.current_device:
+      devices = self.devices()
+      if len(devices) == 1:
+        self.set_current_device(devices[0])
+        return
+      else:
+        msg = ""
+        if len(devices) == 0:
+          msg = "No devices detected. Please connect a device and "
+        else:
+          msg = "Too many devices (" + ", ".join(devices) + ") detected. " \
+              + "Please "
+
+        print "Warning: " + msg + " use the set-android-device command."
+
+
+  def _prepare_adb_args(self, args):
+    largs = list(args)
+
+    # Prepare serial number option from current_device
+    if self.current_device and len(self.current_device) > 0:
+      largs.insert(0, self.current_device)
+      largs.insert(0, "-s")
+
+    largs.insert(0, self.adb_path)
+    return largs
+
+
+  def _background_adb(self, *args):
+    largs = self._prepare_adb_args(args)
+    p = None
+    try:
+      if self.verbose:
+        print "### " + str(largs)
+      p = subprocess.Popen(largs)
+      self.background_processes.append(p)
+    except CalledProcessError, e:
+      raise gdb.GdbError("Error starting background adb " + str(largs))
+    except:
+      raise gdb.GdbError("Unknown error starting background adb " + str(largs))
+
+    return p
+
+  def _call_adb(self, *args):
+    output = ""
+    largs = self._prepare_adb_args(args)
+    try:
+      if self.verbose:
+        print "### " + str(largs)
+      output = check_output(largs)
+    except subprocess.CalledProcessError, e:
+      raise gdb.GdbError("Error starting adb " + str(largs))
+    except Exception as e:
+      raise gdb.GdbError("Unknown error starting adb " + str(largs))
+
+    return output
+
+  def _shell(self, *args):
+    args = ["shell"] + list(args)
+    return self._call_adb(*args)
+
+  def _background_shell(self, *args):
+    args = ["shell"] + list(args)
+    return self._background_adb(*args)
+
+  def _cleanup_background_processes(self):
+    for handle in self.background_processes:
+      try:
+        handle.terminate()
+      except OSError, e:
+        # Background process died already
+        pass
+
+  def _cleanup_temp(self):
+    if self.temp_libdir:
+      shutil.rmtree(self.temp_libdir)
+      self.temp_libdir = None
+
+  def __del__(self):
+    self._cleanup_temp()
+    self._cleanup_background_processes()
+
+  def _get_local_libs(self):
+    ret = []
+    for lib in _interesting_libs():
+      lib_path = os.path.join(local_library_directory, lib + ".so")
+      if not os.path.exists(lib_path) and self.verbose:
+        print "Warning: unable to find expected library " \
+          + lib_path + "."
+      ret.append(lib_path)
+
+    return ret
+
+  def _check_remote_libs_match_local_libs(self):
+    ret = []
+    all_remote_libs = self._shell("ls", "/system/lib/*.so").split()
+    local_libs = self._get_local_libs()
+
+    self.temp_libdir = tempfile.mkdtemp()
+
+    for lib in _interesting_libs():
+      lib += ".so"
+      for remote_lib in all_remote_libs:
+        if lib in remote_lib:
+          # Pull lib from device and compute hash
+          tmp_path = os.path.join(self.temp_libdir, lib)
+          self.pull(remote_lib, tmp_path)
+          remote_hash = self._md5sum(tmp_path)
+
+          # Find local lib and compute hash
+          built_library = filter(lambda l: lib in l, local_libs)[0]
+          built_hash = self._md5sum(built_library)
+
+          # Alert user if library mismatch is detected
+          if built_hash != remote_hash:
+            self._cleanup_temp()
+            raise gdb.GdbError("Library mismatch between:\n" \
+              + "\t(" + remote_hash + ") " + tmp_path + " (from target) and\n " \
+              + "\t(" + built_hash + ") " + built_library + " (on host)\n" \
+              + "The target is running a different build than the host." \
+              + " This situation is not debuggable.")
+
+    self._cleanup_temp()
+
+  def _md5sum(self, file):
+    try:
+      return check_output(["md5sum", file]).strip().split()[0]
+    except subprocess.CalledProcessError, e:
+      raise gdb.GdbError("Error invoking md5sum commandline utility")
+
+  # Returns the list of serial numbers of connected devices
+  def devices(self):
+    ret = []
+    raw_output = self._call_adb("devices").split()
+    if len(raw_output) < 5:
+      return None
+    else:
+      for serial_num_index in range(4, len(raw_output), 2):
+        ret.append(raw_output[serial_num_index])
+    return ret
+
+  def set_current_device(self, serial):
+    if self.current_device == str(serial):
+      print "Current device already is: " + str(serial)
+      return
+
+    # TODO: this function should probably check the serial is valid.
+    self.current_device = str(serial)
+
+    api_version = self.getprop("ro.build.version.sdk")
+    if api_version < 15:
+      print "Warning: untested API version. Upgrade to 15 or higher"
+
+    # Verify the local libraries loaded by GDB are identical to those
+    # sitting on the device actually executing. Alert the user if
+    # this is happening
+    self._check_remote_libs_match_local_libs()
+
+  # adb getprop [property]
+  # if property is not None, returns the given property, otherwise
+  # returns all properties.
+  def getprop(self, property=None):
+    if property == None:
+      # get all the props
+      return self._call_adb(*["shell", "getprop"]).split('\n')
+    else:
+      return str(self._call_adb(*["shell", "getprop",
+        str(property)]).split('\n')[0])
+
+  # adb push
+  def push(self, source, destination):
+    self._call_adb(*["push", source, destination])
+
+  # adb forward <source> <destination>
+  def forward(self, source, destination):
+    self._call_adb(*["forward", source, destination])
+
+  # Returns true if filename exists on Android fs, false otherwise
+  def exists(self, filename):
+    raw_listing = self._shell(*["ls", filename])
+    return "No such file or directory" not in raw_listing
+
+  # adb pull <remote_path> <local_path>
+  def pull(self, remote_path, local_path):
+    self._call_adb(*["pull", remote_path, local_path])
+
+  #wrapper for adb shell ps. leave process_name=None for list of all processes
+  #Otherwise, returns triple with process name, pid and owner,
+  def get_process_info(self, process_name=None):
+    ret = []
+    raw_output = self._shell("ps")
+    for raw_line in raw_output.splitlines()[1:]:
+      line = raw_line.split()
+      name = line[-1]
+
+      if process_name == None or name == process_name:
+        user = line[0]
+        pid = line[1]
+
+        if process_name != None:
+          return (pid, user)
+        else:
+          ret.append((pid, user))
+
+    # No match in target process
+    if process_name != None:
+      return (None, None)
+
+    return ret
+
+  def kill_by_pid(self, pid):
+    self._shell(*["kill", "-9", pid])
+
+  def kill_by_name(self, process_name):
+    (pid, user) = self.get_process_info(process_name)
+    while pid != None:
+      self.kill_by_pid(pid)
+      (pid, user) = self.get_process_info(process_name)
+
+class AndroidStatus(gdb.Command):
+  """Implements the android-status gdb command."""
+
+  def __init__(self, adb, name="android-status", cat=gdb.COMMAND_OBSCURE, verbose=False):
+    super (AndroidStatus, self).__init__(name, cat)
+    self.verbose = verbose
+    self.adb = adb
+
+  def _update_status(self, process_name, gdbserver_process_name):
+    self._check_app_is_loaded()
+
+    # Update app status
+    (self.pid, self.owner_user) = \
+      self.adb.get_process_info(process_name)
+    self.running = self.pid != None
+
+    # Update gdbserver status
+    (self.gdbserver_pid, self.gdbserver_user) = \
+      self.adb.get_process_info(gdbserver_process_name)
+    self.gdbserver_running = self.gdbserver_pid != None
+
+    # Print results
+    if self.verbose:
+      print "--==Android GDB Plugin Status Update==--"
+      print "\tinferior name: " + process_name
+      print "\trunning: " + str(self.running)
+      print "\tpid: " + str(self.pid)
+      print "\tgdbserver running: " + str(self.gdbserver_running)
+      print "\tgdbserver pid: " + str(self.gdbserver_pid)
+      print "\tgdbserver user: " + str(self.gdbserver_user)
+
+  def _check_app_is_loaded(self):
+    if not currentAppInfo.get_name():
+      raise gdb.GdbError("Error: no app loaded. Try load-android-app.")
+
+  def invoke(self, arg, from_tty):
+    self._check_app_is_loaded()
+    self._update_status(currentAppInfo.get_name(),
+      currentAppInfo.get_gdbserver_path())
+    # TODO: maybe print something if verbose is off
+
+class StartAndroidApp (AndroidStatus):
+  """Implements the 'start-android-app' gdb command."""
+
+  def _update_status(self):
+    AndroidStatus._update_status(self, self.process_name, \
+      self.gdbserver_path)
+
+  # Calls adb shell ps every retry_delay seconds and returns
+  # the pid when process_name show up in output, or return 0
+  # after num_retries attempts. num_retries=0 means retry
+  # indefinitely.
+  def _wait_for_process(self, process_name, retry_delay=1, num_retries=10):
+    """ This function is a hack and should not be required"""
+    (pid, user) = self.adb.get_process_info(process_name)
+    retries_left = num_retries
+    while pid == None and retries_left != 0:
+      (pid, user) = self.adb.get_process_info(process_name)
+      time.sleep(retry_delay)
+      retries_left -= 1
+
+    return pid
+
+  def _gdbcmd(self, cmd, from_tty=False):
+    if self.verbose:
+      print '### GDB Command: ' + str(cmd)
+
+    gdb.execute(cmd, from_tty)
+
+  # Remove scratch directory if any
+  def _cleanup_temp(self):
+    if self.temp_dir:
+      shutil.rmtree(self.temp_dir)
+      self.temp_dir = None
+
+  def _cleanup_jdb(self):
+    if self.jdb_handle:
+      try:
+        self.jdb_handle.terminate()
+      except OSError, e:
+        # JDB process has likely died
+        pass
+
+      self.jdb_handle = None
+
+  def _load_local_libs(self):
+    for lib in _interesting_libs():
+      self._gdbcmd("shar " + lib)
+
+  def __del__(self):
+    self._cleanup_temp()
+    self._cleanup_jdb()
+
+  def __init__ (self, adb, name="start-android-app", cat=gdb.COMMAND_RUNNING, verbose=False):
+    super (StartAndroidApp, self).__init__(adb, name, cat, verbose)
+    self.adb = adb
+
+    self.jdb_handle = None
+    # TODO: handle possibility that port 8700 is in use (may help with
+    # Eclipse problems)
+    self.jdwp_port = 8700
+
+    # Port for gdbserver
+    self.gdbserver_port = 5039
+
+    self.temp_dir = None
+
+  def start_process(self, start_running=False):
+    #TODO: implement libbcc cache removal if needed
+
+    args = ["am", "start"]
+
+    # If we are to start running, we can take advantage of am's -W flag to wait
+    # for the process to start before returning. That way, we don't have to
+    # emulate the behaviour (poorly) through the sleep-loop below.
+    if not start_running:
+      args.append("-D")
+    else:
+      args.append("-W")
+
+    args.append(self.process_name + "/" + self.intent)
+    am_output = self.adb._shell(*args)
+    if "Error:" in am_output:
+      raise gdb.GdbError("Cannot start app. Activity Manager returned:\n"\
+        + am_output)
+
+    # Gotta wait until the process starts if we can't use -W
+    if not start_running:
+      self.pid = self._wait_for_process(self.process_name)
+
+    if not self.pid:
+      raise gdb.GdbError("Unable to detect running app remotely." \
+        + "Is " + self.process_name + " installed correctly?")
+
+    if self.verbose:
+      print "--==Android App Started: " + self.process_name \
+        + " (pid=" + self.pid + ")==--"
+
+    # Forward port for java debugger to Dalvik
+    self.adb.forward("tcp:" + str(self.jdwp_port), \
+                     "jdwp:" + str(self.pid))
+
+  def start_gdbserver(self):
+    # TODO: adjust for architecture...
+    gdbserver_local_path = os.path.join(os.getenv('ANDROID_BUILD_TOP'),
+      'prebuilt', 'android-arm', 'gdbserver', 'gdbserver')
+
+    if not self.adb.exists(self.gdbserver_path):
+      # Install gdbserver
+      try:
+        self.adb.push(gdbserver_local_path, self.gdbserver_path)
+      except gdb.GdbError, e:
+        print "Unable to push gdbserver to device. Try re-installing app."
+        raise e
+
+    self.adb._background_shell(*[self.gdbserver_path, "--attach",
+      ":" + str(self.gdbserver_port), self.pid])
+
+    self._wait_for_process(self.gdbserver_path)
+    self._update_status()
+
+    if self.verbose:
+      print "--==Remote gdbserver Started " \
+        + " (pid=" + str(self.gdbserver_pid) \
+        + " port=" + str(self.gdbserver_port) + ") ==--"
+
+    # Forward port for gdbserver
+    self.adb.forward("tcp:" + str(self.gdbserver_port), \
+                     "tcp:" + str(5039))
+
+  def attach_gdb(self, from_tty):
+    self._gdbcmd("target remote :" + str(self.gdbserver_port), False)
+    if self.verbose:
+      print "--==GDB Plugin requested attach (port=" \
+        + str(self.gdbserver_port) + ")==-"
+
+    # If GDB has no file set, things start breaking...so grab the same
+    # binary the NDK grabs from the filesystem and continue
+    self._cleanup_temp()
+    self.temp_dir = tempfile.mkdtemp()
+    self.gdb_inferior = os.path.join(self.temp_dir, 'app_process')
+    self.adb.pull("/system/bin/app_process", self.gdb_inferior)
+    self._gdbcmd('file ' + self.gdb_inferior)
+
+  def start_jdb(self, port):
+    # Kill if running
+    self._cleanup_jdb()
+
+    # Start the java debugger
+    args = ["jdb", "-connect",
+      "com.sun.jdi.SocketAttach:hostname=localhost,port=" + str(port)]
+    if self.verbose:
+      self.jdb_handle = subprocess.Popen(args, \
+        stdin=subprocess.PIPE)
+    else:
+      # Unix-only bit here..
+      self.jdb_handle = subprocess.Popen(args, \
+        stdin=subprocess.PIPE,
+        stderr=subprocess.STDOUT,
+        stdout=open('/dev/null', 'w'))
+
+  def invoke (self, arg, from_tty):
+    # TODO: self._check_app_is_installed()
+    self._check_app_is_loaded()
+
+    self.intent = currentAppInfo.get_intent()
+    self.process_name = currentAppInfo.get_name()
+    self.data_directory = currentAppInfo.get_data_directory()
+    self.gdbserver_path = currentAppInfo.get_gdbserver_path()
+
+    self._update_status()
+
+    if self.gdbserver_running:
+      self.adb.kill_by_name(self.gdbserver_path)
+      if self.verbose:
+        print "--==Killed gdbserver process (pid=" \
+          + str(self.gdbserver_pid) + ")==--"
+      self._update_status()
+
+    if self.running:
+      self.adb.kill_by_name(self.process_name)
+      if self.verbose:
+        print "--==Killed app process (pid=" + str(self.pid) + ")==--"
+      self._update_status()
+
+    self.start_process()
+
+    # Start remote gdbserver
+    self.start_gdbserver()
+
+    # Attach the gdb
+    self.attach_gdb(from_tty)
+
+    # Load symbolic libraries
+    self._load_local_libs()
+
+    # Set the debug output directory (for JIT debugging)
+    if enable_renderscript_dumps:
+      self._gdbcmd('set gDebugDumpDirectory="' + self.data_directory + '"')
+
+    # Start app
+    # unblock the gdb by connecting with jdb
+    self.start_jdb(self.jdwp_port)
+
+class RunAndroidApp(StartAndroidApp):
+  """Implements the run-android-app gdb command."""
+
+  def __init__(self, adb, name="run-android-app", cat=gdb.COMMAND_RUNNING, verbose=False):
+    super (RunAndroidApp, self).__init__(adb, name, cat, verbose)
+
+  def invoke(self, arg, from_tty):
+    StartAndroidApp.invoke(self, arg, from_tty)
+    self._gdbcmd("continue")
+
+class AttachAndroidApp(StartAndroidApp):
+  """Implements the attach-android-app gdb command."""
+
+  def __init__(self, adb, name="attach-android-app", cat=gdb.COMMAND_RUNNING, verbose=False):
+    super (AttachAndroidApp, self).__init__(adb, name, cat, verbose)
+
+  def invoke(self, arg, from_tty):
+    # TODO: self._check_app_is_installed()
+    self._check_app_is_loaded()
+
+    self.intent = currentAppInfo.get_intent()
+    self.process_name = currentAppInfo.get_name()
+    self.data_directory = currentAppInfo.get_data_directory()
+    self.gdbserver_path = currentAppInfo.get_gdbserver_path()
+
+    self._update_status()
+
+    if self.gdbserver_running:
+      self.adb.kill_by_name(self.gdbserver_path)
+      if self.verbose:
+        print "--==Killed gdbserver process (pid=" \
+          + str(self.gdbserver_pid) + ")==--"
+      self._update_status()
+
+    # Start remote gdbserver
+    self.start_gdbserver()
+
+    # Attach the gdb
+    self.attach_gdb(from_tty)
+
+    # Load symbolic libraries
+    self._load_local_libs()
+
+    # Set the debug output directory (for JIT debugging)
+    if enable_renderscript_dumps:
+      self._gdbcmd('set gDebugDumpDirectory="' + self.data_directory + '"')
+
+class LoadApp(AndroidStatus):
+  """ Implements the load-android-app gbd command.
+  """
+  def _awk_script_path(self, script_name):
+    if os.path.exists(script_name):
+      return script_name
+
+    script_root = os.path.join(os.getenv('ANDROID_BUILD_TOP'), \
+      'ndk', 'build', 'awk')
+
+    path_in_root = os.path.join(script_root, script_name)
+    if os.path.exists(path_in_root):
+      return path_in_root
+
+    raise gdb.GdbError("Unable to find awk script " \
+      +  str(script_name) + " in " + path_in_root)
+
+  def _awk(self, script, command):
+    args = ["awk", "-f", self._awk_script_path(script), str(command)]
+
+    if self.verbose:
+      print "### awk command: " + str(args)
+
+    awk_output = ""
+    try:
+      awk_output = check_output(args)
+    except subprocess.CalledProcessError, e:
+      raise gdb.GdbError("### Error in subprocess awk " + str(args))
+    except:
+      print "### Random error calling awk " + str(args)
+
+    return awk_output.rstrip()
+
+  def __init__(self, adb, name="load-android-app", cat=gdb.COMMAND_RUNNING, verbose=False):
+    super (LoadApp, self).__init__(adb, name, cat, verbose)
+    self.manifest_name = "AndroidManifest.xml"
+    self.verbose = verbose
+    self.adb = adb
+    self.temp_libdir = None
+
+  def _find_manifests(self, path):
+    manifests = []
+    for root, dirnames, filenames in os.walk(path):
+      for filename in fnmatch.filter(filenames, self.manifest_name):
+        manifests.append(os.path.join(root, filename))
+    return manifests
+
+  def _usage(self):
+    return "Usage: load-android-app [<path-to-AndroidManifest.xml>" \
+            + " | <package-name> <intent-name>]"
+
+  def invoke(self, arg, from_tty):
+ 
+    package_name = ''
+    launchable = ''
+    args = arg.strip('"').split()
+    if len(args) == 2:
+      package_name = args[0]
+      launchable = args[1]
+    elif len(args) == 1:
+      if os.path.isfile(args[0]) and os.path.basename(args[0]) == self.manifest_name:
+        self.manifest_path = args[0]
+      elif os.path.isdir(args[0]):
+        manifests = self._find_manifests(args[0])
+        if len(manifests) == 0:
+          raise gdb.GdbError(self.manifest_name + " not found in: " \
+            + args[0] + "\n" + self._usage())
+        elif len(manifests) > 1:
+          raise gdb.GdbError("Ambiguous argument! Found too many " \
+            + self.manifest_name + " files found:\n" + "\n".join(manifests))
+        else:
+          self.manifest_path = manifests[0]
+      else:
+        raise gdb.GdbError("Invalid path: " + args[0] + "\n" + self._usage())
+
+      package_name = self._awk("extract-package-name.awk",
+        self.manifest_path)
+      launchable = self._awk("extract-launchable.awk",
+        self.manifest_path)
+    else:
+      raise gdb.GdbError(self._usage())
+
+
+    data_directory = self.adb._shell("run-as", package_name,
+      "/system/bin/sh", "-c", "pwd").rstrip()
+
+    if not data_directory \
+      or len(data_directory) == 0 \
+      or not self.adb.exists(data_directory):
+      data_directory = os.path.join('/data', 'data', package_name)
+      print "Warning: unable to read data directory for package " \
+        + package_name + ". Meh, defaulting to " + data_directory
+
+    currentAppInfo.set_info(package_name, launchable, data_directory)
+
+    if self.verbose:
+      print "--==Android App Loaded==--"
+      print "\tname=" + currentAppInfo.get_name()
+      print "\tintent=" + currentAppInfo.get_intent()
+
+    # TODO: Check status of app on device
+
+class SetAndroidDevice (gdb.Command):
+  def __init__(self, adb, name="set-android-device", cat=gdb.COMMAND_RUNNING, verbose=False):
+    super (SetAndroidDevice, self).__init__(name, cat)
+    self.verbose = verbose
+    self.adb = adb
+
+  def _usage(self):
+    return "Usage: set-android-device <serial>"
+
+  def invoke(self, arg, from_tty):
+    if not arg or len(arg) == 0:
+      raise gdb.GdbError(self._usage)
+
+    serial = str(arg)
+    devices = adb.devices()
+    if serial in devices:
+      adb.set_current_device(serial)
+    else:
+      raise gdb.GdbError("Invalid serial. Serial numbers of connected " \
+        + "device(s): \n" + "\n".join(devices))
+
+# Global initialization
+def initOnce(adb):
+  # Try to speed up startup by skipping most android shared objects
+  gdb.execute("set auto-solib-add 0", False);
+
+  # Set shared object search path
+  gdb.execute("set solib-search-path " + local_symbols_library_directory, False)
+
+# Global instance of the object containing the info for current app
+currentAppInfo = DebugAppInfo ()
+
+# Global instance of ADB helper
+adb = ADB(verbose=be_verbose)
+
+# Perform global initialization
+initOnce(adb)
+
+# Command registration
+StartAndroidApp (adb, "start-android-app", gdb.COMMAND_RUNNING, be_verbose)
+RunAndroidApp (adb, "run-android-app", gdb.COMMAND_RUNNING, be_verbose)
+AndroidStatus (adb, "android-status", gdb.COMMAND_OBSCURE, be_verbose)
+LoadApp (adb, "load-android-app", gdb.COMMAND_RUNNING, be_verbose)
+SetAndroidDevice (adb, "set-android-device", gdb.COMMAND_RUNNING, be_verbose)
+AttachAndroidApp (adb, "attach-android-app", gdb.COMMAND_RUNNING, be_verbose)
diff --git a/libbcc/include/bcc/Assert.h b/libbcc/include/bcc/Assert.h
new file mode 100644
index 0000000..e87ba42
--- /dev/null
+++ b/libbcc/include/bcc/Assert.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _FRAMEWORKS_COMPILE_LIBBCC_INCLUDE_BCC_ASSERT_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_LIBBCC_INCLUDE_BCC_ASSERT_H_
+
+#ifdef __cplusplus
+#include <cstdlib>
+#include <cstdio>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#endif  // __cplusplus
+
+#ifdef __DISABLE_ASSERTS
+
+#define bccAssert(v) do {} while (0)
+
+#else
+
+#define LOG_TAG "bcc"
+#include <cutils/log.h>
+
+#define __ABORT_ON_FAILURES 1
+
+#define bccAssert(v)                                \
+  do {                                              \
+    if (!(v)) {                                     \
+      ALOGE("bccAssert failed at %s:%d - '%s'\n",   \
+          __FILE__, __LINE__, #v);                  \
+      if (__ABORT_ON_FAILURES) {                    \
+        abort();                                    \
+      }                                             \
+    }                                               \
+  } while (0)
+
+#endif  // __DISABLE_ASSERTS
+
+#endif  // _FRAMEWORKS_COMPILE_LIBBCC_INCLUDE_BCC_ASSERT_H_  NOLINT
diff --git a/libbcc/include/bcc/BCCContext.h b/libbcc/include/bcc/BCCContext.h
new file mode 100644
index 0000000..be24d31
--- /dev/null
+++ b/libbcc/include/bcc/BCCContext.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_CONTEXT_H
+#define BCC_CONTEXT_H
+
+namespace llvm {
+  class LLVMContext;
+}
+
+namespace bcc {
+
+class BCCContextImpl;
+class Source;
+
+/*
+ * class BCCContext manages the global data across the libbcc infrastructure.
+ */
+class BCCContext {
+public:
+  BCCContextImpl *const mImpl;
+
+  BCCContext();
+  ~BCCContext();
+
+  llvm::LLVMContext &getLLVMContext();
+  const llvm::LLVMContext &getLLVMContext() const;
+
+  void addSource(Source &pSource);
+  void removeSource(Source &pSource);
+
+  // Global BCCContext
+  static BCCContext *GetOrCreateGlobalContext();
+  static void DestroyGlobalContext();
+};
+
+} // namespace bcc
+
+#endif  // BCC_CONTEXT_H
diff --git a/libbcc/include/bcc/Compiler.h b/libbcc/include/bcc/Compiler.h
new file mode 100644
index 0000000..92150fa
--- /dev/null
+++ b/libbcc/include/bcc/Compiler.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2010-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_COMPILER_H
+#define BCC_COMPILER_H
+
+namespace llvm {
+
+class raw_ostream;
+class raw_pwrite_stream;
+class DataLayout;
+class TargetMachine;
+
+namespace legacy {
+class PassManager;
+} // end namespace legacy
+
+using legacy::PassManager;
+
+} // end namespace llvm
+
+namespace bcc {
+
+class CompilerConfig;
+class OutputFile;
+class Script;
+
+//===----------------------------------------------------------------------===//
+// Design of Compiler
+//===----------------------------------------------------------------------===//
+// 1. A compiler instance can be constructed provided an "initial config."
+// 2. A compiler can later be re-configured using config().
+// 3. Once config() is invoked, it'll re-create TargetMachine instance (i.e.,
+//    mTarget) according to the configuration supplied. TargetMachine instance
+//    is *shared* across the different calls to compile() before the next call
+//    to config().
+// 4. Once a compiler instance is created, you can use the compile() service
+//    to compile the file over and over again. Each call uses TargetMachine
+//    instance to construct the compilation passes.
+class Compiler {
+public:
+  enum ErrorCode {
+    kSuccess,
+
+    kInvalidConfigNoTarget,
+    kErrCreateTargetMachine,
+    kErrSwitchTargetMachine,
+    kErrNoTargetMachine,
+    kErrMaterialization,
+    kErrInvalidOutputFileState,
+    kErrPrepareOutput,
+    kPrepareCodeGenPass,
+
+    kErrCustomPasses,
+
+    kErrInvalidSource,
+
+    kIllegalGlobalFunction,
+
+    kErrInvalidTargetMachine
+  };
+
+  static const char *GetErrorString(enum ErrorCode pErrCode);
+
+private:
+  llvm::TargetMachine *mTarget;
+  // Optimization is enabled by default.
+  bool mEnableOpt;
+
+  enum ErrorCode runPasses(Script &pScript, llvm::raw_pwrite_stream &pResult);
+
+  bool addInternalizeSymbolsPass(Script &pScript, llvm::legacy::PassManager &pPM);
+  void addExpandKernelPass(llvm::legacy::PassManager &pPM);
+  void addDebugInfoPass(Script &pScript, llvm::legacy::PassManager &pPM);
+  void addGlobalInfoPass(Script &pScript, llvm::legacy::PassManager &pPM);
+  void addInvariantPass(llvm::legacy::PassManager &pPM);
+  void addInvokeHelperPass(llvm::legacy::PassManager &pPM);
+
+public:
+  Compiler();
+  explicit Compiler(const CompilerConfig &pConfig);
+
+  enum ErrorCode config(const CompilerConfig &pConfig);
+
+  // Compile a script and output the result to a LLVM stream.
+  //
+  // @param IRStream If not NULL, the LLVM-IR that is fed to code generation
+  //                 will be written to IRStream.
+  enum ErrorCode compile(Script &pScript, llvm::raw_pwrite_stream &pResult,
+                         llvm::raw_ostream *IRStream);
+
+  // Compile a script and output the result to a file.
+  enum ErrorCode compile(Script &pScript, OutputFile &pResult,
+                         llvm::raw_ostream *IRStream = 0);
+
+  const llvm::TargetMachine& getTargetMachine() const
+  { return *mTarget; }
+
+  void enableOpt(bool pEnable = true)
+  { mEnableOpt = pEnable; }
+
+  ~Compiler();
+
+  // Compare undefined external functions in pScript against a 'whitelist' of
+  // all RenderScript functions.  Returns error if any external function that is
+  // not in this whitelist is callable from the script.
+  enum ErrorCode screenGlobalFunctions(Script &pScript);
+
+  void translateGEPs(Script &pScript);
+};
+
+} // end namespace bcc
+
+#endif // BCC_COMPILER_H
diff --git a/libbcc/include/bcc/Config/Config.h b/libbcc/include/bcc/Config/Config.h
new file mode 100644
index 0000000..8293827
--- /dev/null
+++ b/libbcc/include/bcc/Config/Config.h
@@ -0,0 +1,111 @@
+#ifndef BCC_CONFIG_CONFIG_H
+#define BCC_CONFIG_CONFIG_H
+
+//---------------------------------------------------------------------------
+// Configuration for Disassembler
+//---------------------------------------------------------------------------
+
+#if DEBUG_MC_DISASSEMBLER
+#define USE_DISASSEMBLER 1
+#else
+#define USE_DISASSEMBLER 0
+#endif
+
+#if defined(__HOST__)
+#define DEBUG_DISASSEMBLER_FILE "/tmp/mc-dis.s"
+#else
+#define DEBUG_DISASSEMBLER_FILE "/data/local/tmp/mc-dis.s"
+#endif // defined(__HOST__)
+
+//---------------------------------------------------------------------------
+// Configuration for CodeGen and CompilerRT
+//---------------------------------------------------------------------------
+
+#if defined(FORCE_ARM_CODEGEN)
+  #define PROVIDE_ARM_CODEGEN
+  #define DEFAULT_ARM_CODEGEN
+
+#elif defined(FORCE_ARM64_CODEGEN)
+  #define PROVIDE_ARM_CODEGEN
+  #define PROVIDE_ARM64_CODEGEN
+  #define DEFAULT_ARM64_CODEGEN
+
+#elif defined(FORCE_MIPS_CODEGEN)
+  #define PROVIDE_MIPS_CODEGEN
+  #define DEFAULT_MIPS_CODEGEN
+
+#elif defined(FORCE_MIPS64_CODEGEN)
+  #define PROVIDE_MIPS_CODEGEN
+  #define PROVIDE_MIPS64_CODEGEN
+  #define DEFAULT_MIPS64_CODEGEN
+
+#elif defined(FORCE_X86_CODEGEN)
+  #define PROVIDE_X86_CODEGEN
+  #define DEFAULT_X86_CODEGEN
+
+#elif defined(FORCE_X86_64_CODEGEN)
+  // There is no separate X86_64 code generation target. It is all part of X86.
+  #define PROVIDE_X86_CODEGEN
+  #define DEFAULT_X86_64_CODEGEN
+
+#else
+  #define PROVIDE_ARM_CODEGEN
+  #define PROVIDE_ARM64_CODEGEN
+  #define PROVIDE_MIPS_CODEGEN
+  #define PROVIDE_MIPS64_CODEGEN
+  #define PROVIDE_X86_CODEGEN
+  #define PROVIDE_X86_64_CODEGEN
+
+  #if defined(__arm__)
+    #define DEFAULT_ARM_CODEGEN
+  #elif defined(__aarch64__)
+    #define DEFAULT_ARM64_CODEGEN
+  #elif defined(__mips__)
+    #if defined(__LP64__)
+      #define DEFAULT_MIPS64_CODEGEN
+    #else
+      #define DEFAULT_MIPS_CODEGEN
+    #endif
+  #elif defined(__i386__)
+    #define DEFAULT_X86_CODEGEN
+  #elif defined(__x86_64__)
+    #define DEFAULT_X86_64_CODEGEN
+  #endif
+#endif
+
+#define DEFAULT_ARM_TRIPLE_STRING      "armv7-none-linux-gnueabi"
+#define DEFAULT_THUMB_TRIPLE_STRING    "thumbv7-none-linux-gnueabi"
+#define DEFAULT_ARM64_TRIPLE_STRING    "aarch64-none-linux-gnueabi"
+#define DEFAULT_MIPS_TRIPLE_STRING     "mipsel-none-linux-gnueabi"
+#define DEFAULT_MIPS64_TRIPLE_STRING   "mips64el-none-linux-gnueabi"
+#define DEFAULT_X86_TRIPLE_STRING      "i686-unknown-linux"
+#define DEFAULT_X86_64_TRIPLE_STRING   "x86_64-unknown-linux"
+
+// Custom DataLayout string for X86 with i64 and f64 set to match the ARM32
+// alignment requirement of 64-bits.
+#define X86_CUSTOM_DL_STRING "e-m:e-p:32:32-i64:64-f64:64:64-f80:32-n8:16:32-S128"
+// Default DataLayout string for X86.  Present to detect future LLVM datalayout
+// changes so X86_CUSTOM_DL_STRING above can be modified appropriately.
+#define X86_DEFAULT_DL_STRING "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
+
+#if defined(DEFAULT_ARM_CODEGEN)
+  #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_ARM_TRIPLE_STRING
+#elif defined(DEFAULT_ARM64_CODEGEN)
+  #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_ARM64_TRIPLE_STRING
+#elif defined(DEFAULT_MIPS_CODEGEN)
+  #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_MIPS_TRIPLE_STRING
+#elif defined(DEFAULT_MIPS64_CODEGEN)
+  #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_MIPS64_TRIPLE_STRING
+#elif defined(DEFAULT_X86_CODEGEN)
+  #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_X86_TRIPLE_STRING
+#elif defined(DEFAULT_X86_64_CODEGEN)
+  #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_X86_64_TRIPLE_STRING
+#endif
+
+#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
+  #define ARM_USE_VFP
+#endif
+
+//---------------------------------------------------------------------------
+
+#endif // BCC_CONFIG_CONFIG_H
diff --git a/libbcc/include/bcc/Renderscript/RSCompilerDriver.h b/libbcc/include/bcc/Renderscript/RSCompilerDriver.h
new file mode 100644
index 0000000..76c9f98
--- /dev/null
+++ b/libbcc/include/bcc/Renderscript/RSCompilerDriver.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_RS_COMPILER_DRIVER_H
+#define BCC_RS_COMPILER_DRIVER_H
+
+#include "bcc/Compiler.h"
+#include "bcc/Renderscript/RSScript.h"
+
+#include "bcinfo/MetadataExtractor.h"
+
+#include <list>
+#include <string>
+#include <vector>
+
+namespace bcc {
+
+class BCCContext;
+class CompilerConfig;
+class RSCompilerDriver;
+class Source;
+
+// Type signature for dynamically loaded initialization of an RSCompilerDriver.
+typedef void (*RSCompilerDriverInit_t) (bcc::RSCompilerDriver *);
+// Name of the function that we attempt to dynamically load/execute.
+#define RS_COMPILER_DRIVER_INIT_FN rsCompilerDriverInit
+
+class RSCompilerDriver {
+private:
+  CompilerConfig *mConfig;
+  Compiler mCompiler;
+
+  // Are we compiling under an RS debug context with additional checks?
+  bool mDebugContext;
+
+  // Callback before linking with the runtime library.
+  RSLinkRuntimeCallback mLinkRuntimeCallback;
+
+  // Do we merge global variables on ARM using LLVM's optimization pass?
+  // Disabling LLVM's global merge pass allows static globals to be correctly
+  // emitted to ELF. This can result in decreased performance due to increased
+  // register pressure, but it does make the resulting code easier to debug
+  // and work with.
+  bool mEnableGlobalMerge;
+
+  // Specifies whether we should embed global variable information in the
+  // code via special RS variables that can be examined later by the driver.
+  bool mEmbedGlobalInfo;
+
+  // Specifies whether we should skip constant (immutable) global variables
+  // when potentially embedding information about globals.
+  bool mEmbedGlobalInfoSkipConstant;
+
+  // Setup the compiler config for the given script. Return true if mConfig has
+  // been changed and false if it remains unchanged.
+  bool setupConfig(const RSScript &pScript);
+
+  // Compiles the provided bitcode, placing the binary at pOutputPath.
+  // - If pDumpIR is true, a ".ll" file will also be created.
+  Compiler::ErrorCode compileScript(RSScript& pScript, const char* pScriptName,
+                                    const char* pOutputPath,
+                                    const char* pRuntimePath,
+                                    const char* pBuildChecksum,
+                                    bool pDumpIR);
+
+public:
+  RSCompilerDriver();
+  ~RSCompilerDriver();
+
+  Compiler *getCompiler() {
+    return &mCompiler;
+  }
+
+  void setConfig(CompilerConfig *config) {
+    mConfig = config;
+  }
+
+  void setDebugContext(bool v) {
+    mDebugContext = v;
+  }
+
+  void setLinkRuntimeCallback(RSLinkRuntimeCallback c) {
+    mLinkRuntimeCallback = c;
+  }
+
+  RSLinkRuntimeCallback getLinkRuntimeCallback() const {
+    return mLinkRuntimeCallback;
+  }
+
+  // This function enables/disables merging of global static variables.
+  // Note that it only takes effect on ARM architectures (other architectures
+  // do not offer this option).
+  void setEnableGlobalMerge(bool v) {
+    mEnableGlobalMerge = v;
+  }
+
+  bool getEnableGlobalMerge() const {
+    return mEnableGlobalMerge;
+  }
+
+  const CompilerConfig * getConfig() const {
+    return mConfig;
+  }
+
+  // Set to true if we should embed global variable information in the code.
+  void setEmbedGlobalInfo(bool v) {
+    mEmbedGlobalInfo = v;
+  }
+
+  // Returns true if we should embed global variable information in the code.
+  bool getEmbedGlobalInfo() const {
+    return mEmbedGlobalInfo;
+  }
+
+  // Set to true if we should skip constant (immutable) global variables when
+  // potentially embedding information about globals.
+  void setEmbedGlobalInfoSkipConstant(bool v) {
+    mEmbedGlobalInfoSkipConstant = v;
+  }
+
+  // Returns true if we should skip constant (immutable) global variables when
+  // potentially embedding information about globals.
+  bool getEmbedGlobalInfoSkipConstant() const {
+    return mEmbedGlobalInfoSkipConstant;
+  }
+
+  // FIXME: This method accompany with loadScript and compileScript should
+  //        all be const-methods. They're not now because the getAddress() in
+  //        SymbolResolverInterface is not a const-method.
+  // Returns true if script is successfully compiled.
+  bool build(BCCContext& pContext, const char* pCacheDir, const char* pResName,
+             const char* pBitcode, size_t pBitcodeSize,
+             const char *pBuildChecksum, const char* pRuntimePath,
+             RSLinkRuntimeCallback pLinkRuntimeCallback = nullptr,
+             bool pDumpIR = false);
+
+  bool buildScriptGroup(
+      BCCContext& Context, const char* pOutputFilepath, const char* pRuntimePath,
+      const char* pRuntimeRelaxedPath, bool dumpIR, const char* buildChecksum,
+      const std::vector<Source*>& sources,
+      const std::list<std::list<std::pair<int, int>>>& toFuse,
+      const std::list<std::string>& fused,
+      const std::list<std::list<std::pair<int, int>>>& invokes,
+      const std::list<std::string>& invokeBatchNames);
+
+  // Returns true if script is successfully compiled.
+  bool buildForCompatLib(RSScript &pScript, const char *pOut,
+                         const char *pBuildChecksum, const char *pRuntimePath,
+                         bool pDumpIR);
+};
+
+} // end namespace bcc
+
+#endif // BCC_RS_COMPILER_DRIVER_H
diff --git a/libbcc/include/bcc/Renderscript/RSScript.h b/libbcc/include/bcc/Renderscript/RSScript.h
new file mode 100644
index 0000000..b88298a
--- /dev/null
+++ b/libbcc/include/bcc/Renderscript/RSScript.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_RS_SCRIPT_H
+#define BCC_RS_SCRIPT_H
+
+#include "bcc/Script.h"
+#include "bcc/Support/Sha1Util.h"
+
+namespace llvm {
+  class Module;
+}
+
+namespace bcc {
+
+class RSScript;
+class Source;
+class CompilerConfig;
+
+typedef llvm::Module* (*RSLinkRuntimeCallback) (bcc::RSScript *, llvm::Module *, llvm::Module *);
+
+
+class RSScript : public Script {
+public:
+  // This is one-one mapping with the llvm::CodeGenOpt::Level in
+  // llvm/Support/CodeGen.h. Therefore, value of this type can safely cast
+  // to llvm::CodeGenOpt::Level. This makes RSScript LLVM-free.
+  enum OptimizationLevel {
+    kOptLvl0, // -O0
+    kOptLvl1, // -O1
+    kOptLvl2, // -O2, -Os
+    kOptLvl3  // -O3
+  };
+
+private:
+  unsigned mCompilerVersion;
+
+  OptimizationLevel mOptimizationLevel;
+
+  RSLinkRuntimeCallback mLinkRuntimeCallback;
+
+  bool mEmbedInfo;
+
+  // Specifies whether we should embed global variable information in the
+  // code via special RS variables that can be examined later by the driver.
+  bool mEmbedGlobalInfo;
+
+  // Specifies whether we should skip constant (immutable) global variables
+  // when potentially embedding information about globals.
+  bool mEmbedGlobalInfoSkipConstant;
+
+private:
+  // This will be invoked when the containing source has been reset.
+  virtual bool doReset();
+
+public:
+  static bool LinkRuntime(RSScript &pScript, const char *rt_path = nullptr);
+
+  explicit RSScript(Source &pSource);
+
+  // Passing in the CompilerConfig allows the optimization level to
+  // be derived rather than defaulted to aggressive (-O3)
+  RSScript(Source &pSource, const CompilerConfig * pCompilerConfig);
+
+  virtual ~RSScript() { }
+
+  void setCompilerVersion(unsigned pCompilerVersion) {
+    mCompilerVersion = pCompilerVersion;
+  }
+
+  unsigned getCompilerVersion() const {
+    return mCompilerVersion;
+  }
+
+  void setOptimizationLevel(OptimizationLevel pOptimizationLevel) {
+    mOptimizationLevel = pOptimizationLevel;
+  }
+
+  OptimizationLevel getOptimizationLevel() const {
+    return mOptimizationLevel;
+  }
+
+  void setLinkRuntimeCallback(RSLinkRuntimeCallback fn){
+    mLinkRuntimeCallback = fn;
+  }
+
+  void setEmbedInfo(bool pEnable) {
+    mEmbedInfo = pEnable;
+  }
+
+  bool getEmbedInfo() const {
+    return mEmbedInfo;
+  }
+
+  // Set to true if we should embed global variable information in the code.
+  void setEmbedGlobalInfo(bool pEnable) {
+    mEmbedGlobalInfo = pEnable;
+  }
+
+  // Returns true if we should embed global variable information in the code.
+  bool getEmbedGlobalInfo() const {
+    return mEmbedGlobalInfo;
+  }
+
+  // Set to true if we should skip constant (immutable) global variables when
+  // potentially embedding information about globals.
+  void setEmbedGlobalInfoSkipConstant(bool pEnable) {
+    mEmbedGlobalInfoSkipConstant = pEnable;
+  }
+
+  // Returns true if we should skip constant (immutable) global variables when
+  // potentially embedding information about globals.
+  bool getEmbedGlobalInfoSkipConstant() const {
+    return mEmbedGlobalInfoSkipConstant;
+  }
+};
+
+} // end namespace bcc
+
+#endif // BCC_RS_SCRIPT_H
diff --git a/libbcc/include/bcc/Renderscript/RSScriptGroupFusion.h b/libbcc/include/bcc/Renderscript/RSScriptGroupFusion.h
new file mode 100644
index 0000000..c173ac4
--- /dev/null
+++ b/libbcc/include/bcc/Renderscript/RSScriptGroupFusion.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_RS_SCRIPT_GROUP_FUSION_H
+#define BCC_RS_SCRIPT_GROUP_FUSION_H
+
+#include <vector>
+#include <string>
+
+namespace llvm {
+class Module;
+}
+
+namespace bcc {
+
+class Source;
+class BCCContext;
+
+/// @brief Fuse kernels
+///
+/// @param Context bcc context.
+/// @param sources The Sources containing the kernels.
+/// @param slots The slots where the kernels are located.
+/// @param fusedName
+/// @return True, if kernels are successfully fused. False, otherwise. It's up to
+/// the caller on how to deal with unsuccessful fusion. A script group can
+/// execute with either fused kernels or individual kernels.
+bool fuseKernels(BCCContext& Context,
+                 const std::vector<Source *>& sources,
+                 const std::vector<int>& slots,
+                 const std::string& fusedName,
+                 llvm::Module* mergedModule);
+
+bool renameInvoke(BCCContext& Context, const Source* source, const int slot,
+                  const std::string& newName, llvm::Module* mergedModule);
+}
+
+#endif /* BCC_RS_SCRIPT_GROUP_FUSION_H */
diff --git a/libbcc/include/bcc/Renderscript/RSTransforms.h b/libbcc/include/bcc/Renderscript/RSTransforms.h
new file mode 100644
index 0000000..04e8460
--- /dev/null
+++ b/libbcc/include/bcc/Renderscript/RSTransforms.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_RS_TRANSFORMS_H
+#define BCC_RS_TRANSFORMS_H
+
+namespace llvm {
+  class ModulePass;
+  class FunctionPass;
+}
+
+namespace bcc {
+
+extern const char BCC_INDEX_VAR_NAME[];
+
+llvm::ModulePass *
+createRSKernelExpandPass(bool pEnableStepOpt);
+
+llvm::FunctionPass *
+createRSInvariantPass();
+
+llvm::FunctionPass *
+createRSInvokeHelperPass();
+
+llvm::ModulePass * createRSEmbedInfoPass();
+
+llvm::ModulePass * createRSGlobalInfoPass(bool pSkipConstants);
+
+llvm::ModulePass * createRSScreenFunctionsPass();
+
+llvm::ModulePass * createRSIsThreadablePass();
+
+llvm::ModulePass * createRSX86_64CallConvPass();
+
+llvm::ModulePass * createRSAddDebugInfoPass();
+
+llvm::FunctionPass *createRSX86TranslateGEPPass();
+
+} // end namespace bcc
+
+#endif // BCC_RS_TRANSFORMS_H
diff --git a/libbcc/include/bcc/Renderscript/RSUtils.h b/libbcc/include/bcc/Renderscript/RSUtils.h
new file mode 100644
index 0000000..4e80c4e
--- /dev/null
+++ b/libbcc/include/bcc/Renderscript/RSUtils.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_RS_UTILS_H
+#define BCC_RS_UTILS_H
+
+#include "rsDefines.h"
+
+#include <llvm/IR/Type.h>
+#include <llvm/IR/DerivedTypes.h>
+#include <llvm/ADT/StringRef.h>
+
+#include <string>
+
+namespace {
+
+static inline llvm::StringRef getUnsuffixedStructName(const llvm::StructType *T) {
+#ifdef FORCE_BUILD_LLVM_DISABLE_NDEBUG
+  // Bug: 22926131
+  // When building with assertions enabled, LLVM cannot read the name of a
+  // literal (anonymous) structure, because they shouldn't actually ever have
+  // a name. Unfortunately, due to past definitions of RenderScript object
+  // types as anonymous structures typedef-ed to their proper typename,
+  // we had been relying on accessing this information. LLVM bitcode retains
+  // the typedef-ed name for such anonymous structures. There is a
+  // corresponding (safe) fix to the RenderScript headers to actually name
+  // these types the same as their typedef name to simplify things. That
+  // fixes this issue going forward, but it won't allow us to compile legacy
+  // code properly. In that case, we just have non-assert builds ignore the
+  // fact that anonymous structures shouldn't have their name read, and do it
+  // anyway. Note that RSCompilerDriver.cpp checks the compiler version
+  // number (from llvm-rs-cc) to ensure that we are only ever building modern
+  // code when we have assertions enabled. Legacy code can only be compiled
+  // correctly with a non-asserting compiler.
+  //
+  // Note that the whole reason for looking at the "unsuffixed" name of the
+  // type is because LLVM suffixes duplicate typedefs of the same anonymous
+  // structure. In the new case, where all of the RS object types have a
+  // proper name, they won't have a dotted suffix at all. We still need
+  // to look at the old unsuffixed version to handle legacy code properly.
+  if (T->isLiteral()) {
+    return "";
+  }
+#endif
+
+  // Get just the object type name with no suffix.
+  size_t LastDot = T->getName().rfind('.');
+  if (LastDot == strlen("struct")) {
+    // If we get back to just the "struct" part, we know that we had a
+    // raw typename (i.e. struct.rs_element with no ".[0-9]+" suffix on it.
+    // In that case, we will want to create our slice such that it contains
+    // the entire name.
+    LastDot = T->getName().size();
+  }
+  return T->getStructName().slice(0, LastDot);
+}
+
+const char kAllocationTypeName[] = "struct.rs_allocation";
+const char kElementTypeName[]    = "struct.rs_element";
+const char kSamplerTypeName[]    = "struct.rs_sampler";
+const char kScriptTypeName[]     = "struct.rs_script";
+const char kTypeTypeName[]       = "struct.rs_type";
+
+// Returns the RsDataType for a given input LLVM type.
+// This is only used to distinguish the associated RS object types (i.e.
+// rs_allocation, rs_element, rs_sampler, rs_script, and rs_type).
+// All other types are reported back as RS_TYPE_NONE, since no special
+// handling would be necessary.
+static inline enum RsDataType getRsDataTypeForType(const llvm::Type *T) {
+  if (T->isStructTy()) {
+    const llvm::StringRef StructName = getUnsuffixedStructName(llvm::dyn_cast<const llvm::StructType>(T));
+    if (StructName.equals(kAllocationTypeName)) {
+      return RS_TYPE_ALLOCATION;
+    } else if (StructName.equals(kElementTypeName)) {
+      return RS_TYPE_ELEMENT;
+    } else if (StructName.equals(kSamplerTypeName)) {
+      return RS_TYPE_SAMPLER;
+    } else if (StructName.equals(kScriptTypeName)) {
+      return RS_TYPE_SCRIPT;
+    } else if (StructName.equals(kTypeTypeName)) {
+      return RS_TYPE_TYPE;
+    }
+  }
+  return RS_TYPE_NONE;
+}
+
+// Returns true if the input type is one of our RenderScript object types
+// (allocation, element, sampler, script, type) and false if it is not.
+static inline bool isRsObjectType(const llvm::Type *T) {
+  return getRsDataTypeForType(T) != RS_TYPE_NONE;
+}
+
+}  // end namespace
+
+// When we have a general reduction kernel with no combiner function,
+// we will synthesize a combiner function from the accumulator
+// function.  Given the accumulator function name, what should be the
+// name of the combiner function?
+static inline std::string nameReduceCombinerFromAccumulator(llvm::StringRef accumName) {
+  return std::string(accumName) + ".combiner";
+}
+
+#endif // BCC_RS_UTILS_H
diff --git a/libbcc/include/bcc/Script.h b/libbcc/include/bcc/Script.h
new file mode 100644
index 0000000..660cbee
--- /dev/null
+++ b/libbcc/include/bcc/Script.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SCRIPT_H
+#define BCC_SCRIPT_H
+
+namespace bcc {
+
+class Source;
+
+class Script {
+private:
+  // This is the source associated with this object and is going to be
+  // compiled.
+  Source *mSource;
+
+protected:
+  // This hook will be invoked after the script object is successfully reset.
+  virtual bool doReset()
+  { return true; }
+
+public:
+  explicit Script(Source &pSource) : mSource(&pSource) { }
+
+  virtual ~Script() { }
+
+  // Reset this object with the new source supplied. Return false if this
+  // object remains unchanged after the call (e.g., the supplied source is
+  // the same with the one contain in this object.) If pPreserveCurrent is
+  // false, the current containing source will be destroyed after successfully
+  // reset.
+  bool reset(Source &pSource, bool pPreserveCurrent = false);
+
+  // Merge (or link) another source into the current source associated with
+  // this Script object. Return false on error.
+  //
+  // This is equivalent to the call to Script::merge(...) on mSource.
+  bool mergeSource(Source &pSource);
+
+  inline Source &getSource()
+  { return *mSource; }
+  inline const Source &getSource() const
+  { return *mSource; }
+};
+
+} // end namespace bcc
+
+#endif  // BCC_SCRIPT_H
diff --git a/libbcc/include/bcc/Source.h b/libbcc/include/bcc/Source.h
new file mode 100644
index 0000000..ad337c9
--- /dev/null
+++ b/libbcc/include/bcc/Source.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2010-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SOURCE_H
+#define BCC_SOURCE_H
+
+#include <string>
+
+namespace llvm {
+  class Module;
+}
+
+namespace bcinfo {
+  class MetadataExtractor;
+}
+
+namespace bcc {
+
+class BCCContext;
+
+class Source {
+private:
+  const std::string mName; // A unique name
+  BCCContext &mContext;
+  llvm::Module *mModule;
+
+  bcinfo::MetadataExtractor *mMetadata;
+
+  // If true, destructor won't destroy the mModule.
+  bool mNoDelete;
+
+  // Keep track of whether mModule is destroyed (possibly as a consequence of
+  // getting linked with a different llvm::Module).
+  bool mIsModuleDestroyed;
+
+private:
+  Source(const char* name, BCCContext &pContext, llvm::Module &pModule,
+         bool pNoDelete = false);
+
+public:
+  static Source *CreateFromBuffer(BCCContext &pContext,
+                                  const char *pName,
+                                  const char *pBitcode,
+                                  size_t pBitcodeSize);
+
+  static Source *CreateFromFile(BCCContext &pContext,
+                                const std::string &pPath);
+
+  // Create a Source object from an existing module. If pNoDelete
+  // is true, destructor won't call delete on the given module.
+  static Source *CreateFromModule(BCCContext &pContext,
+                                  const char* name,
+                                  llvm::Module &pModule,
+                                  bool pNoDelete = false);
+
+  static Source *CreateEmpty(BCCContext &pContext, const std::string &pName);
+
+  const std::string& getName() const { return mName; }
+
+  // Merge the current source with pSource. pSource
+  // will be destroyed after successfully merged. Return false on error.
+  bool merge(Source &pSource);
+
+  inline BCCContext &getContext()
+  { return mContext; }
+  inline const BCCContext &getContext() const
+  { return mContext; }
+
+  void setModule(llvm::Module *pModule);
+
+  inline llvm::Module &getModule()
+  { return *mModule;  }
+  inline const llvm::Module &getModule() const
+  { return *mModule;  }
+
+  // Get the "identifier" of the bitcode. This will return the value of pName
+  // when it's created using CreateFromBuffer and pPath if CreateFromFile().
+  const std::string &getIdentifier() const;
+
+  void addBuildChecksumMetadata(const char *) const;
+
+  // Get whether debugging has been enabled for this module by checking
+  // for presence of debug info in the module.
+  bool getDebugInfoEnabled() const;
+
+  // Extract metadata from mModule using MetadataExtractor.
+  bool extractMetadata();
+  bcinfo::MetadataExtractor* getMetadata() const { return mMetadata; }
+
+  // Mark mModule was destroyed in the process of linking with a different
+  // llvm::Module
+  void markModuleDestroyed() { mIsModuleDestroyed = true; }
+
+  ~Source();
+};
+
+} // namespace bcc
+
+#endif // BCC_SOURCE_H
diff --git a/libbcc/include/bcc/Support/CompilerConfig.h b/libbcc/include/bcc/Support/CompilerConfig.h
new file mode 100644
index 0000000..c558a16
--- /dev/null
+++ b/libbcc/include/bcc/Support/CompilerConfig.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_COMPILER_CONFIG_H
+#define BCC_SUPPORT_COMPILER_CONFIG_H
+
+#include <string>
+#include <vector>
+
+#include <llvm/ADT/Triple.h>
+#include <llvm/Support/CodeGen.h>
+#include <llvm/Target/TargetOptions.h>
+
+namespace llvm {
+
+class Target;
+
+} // end namespace llvm
+
+namespace bcc {
+
+class CompilerConfig {
+private:
+  //===--------------------------------------------------------------------===//
+  // Available Configurations
+  //===--------------------------------------------------------------------===//
+  std::string mTriple;
+
+  // Optional. If given, the name of the target CPU to generate code for.
+  std::string mCPU;
+
+  llvm::TargetOptions mTargetOpts;
+
+  llvm::CodeModel::Model mCodeModel;
+
+  llvm::CodeGenOpt::Level mOptLevel;
+
+  llvm::Reloc::Model mRelocModel;
+
+  // Are we set up to compile for full precision or something reduced?
+  bool mFullPrecision;
+
+  // The list of target specific features to enable or disable -- this should
+  // be a list of strings starting with '+' (enable) or '-' (disable).
+  std::string mFeatureString;
+
+  //===--------------------------------------------------------------------===//
+  // These are generated by CompilerConfig during initialize().
+  //===--------------------------------------------------------------------===//
+  const llvm::Target *mTarget;
+  bool initializeTarget();
+
+  llvm::Triple::ArchType mArchType;
+  bool initializeArch();
+
+public:
+  //===--------------------------------------------------------------------===//
+  // Getters
+  //===--------------------------------------------------------------------===//
+  inline const std::string &getTriple() const
+  { return mTriple; }
+
+  inline const std::string &getCPU() const
+  { return mCPU; }
+  inline void setCPU(const std::string &pCPU)
+  { mCPU = pCPU; }
+
+  inline const llvm::TargetOptions &getTargetOptions() const
+  { return mTargetOpts; }
+  inline llvm::TargetOptions &getTargetOptions()
+  { return mTargetOpts; }
+
+  inline llvm::CodeModel::Model getCodeModel() const
+  { return mCodeModel; }
+  inline void setCodeModel(llvm::CodeModel::Model pCodeMode)
+  { mCodeModel = pCodeMode; }
+
+  inline llvm::CodeGenOpt::Level getOptimizationLevel() const
+  { return mOptLevel; }
+  inline void setOptimizationLevel(llvm::CodeGenOpt::Level pOptLvl)
+  { mOptLevel = pOptLvl; }
+
+  inline llvm::Reloc::Model getRelocationModel() const
+  { return mRelocModel; }
+  inline void setRelocationModel(llvm::Reloc::Model pRelocModel)
+  { mRelocModel = pRelocModel; }
+
+  inline const llvm::Target *getTarget() const
+  { return mTarget; }
+
+  inline llvm::Triple::ArchType getArchType() const
+  { return mArchType; }
+
+  inline bool getFullPrecision() const
+  { return mFullPrecision; }
+  inline void setFullPrecision(bool pFullPrecision) {
+    mFullPrecision = pFullPrecision;
+    // Note that we have to reinitialize here to ensure that mFeatureString
+    // is up to date.
+    initializeArch();
+  }
+
+  inline const std::string &getFeatureString() const
+  { return mFeatureString; }
+  void setFeatureString(const std::vector<std::string> &pAttrs);
+
+  explicit CompilerConfig(const std::string &pTriple);
+
+  virtual ~CompilerConfig() { }
+};
+
+} // end namespace bcc
+
+#endif  // BCC_SUPPORT_COMPILER_CONFIG_H
diff --git a/libbcc/include/bcc/Support/Disassembler.h b/libbcc/include/bcc/Support/Disassembler.h
new file mode 100644
index 0000000..0ec0eed
--- /dev/null
+++ b/libbcc/include/bcc/Support/Disassembler.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_DISASSEMBLER_H
+#define BCC_SUPPORT_DISASSEMBLER_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+namespace llvm {
+  class raw_ostream;
+} // end namespace llvm
+
+namespace bcc {
+
+class OutputFile;
+
+enum DisassembleResult {
+  kDisassembleSuccess,
+  kDisassemblerNotAvailable,
+  kDisassembleInvalidOutput,
+  kDisassembleFailedPrepareOutput,
+  kDisassembleUnknownTarget,
+  kDisassembleFailedSetup,
+  kDisassembleOutOfMemory,
+  kDisassembleInvalidInstruction,
+};
+
+DisassembleResult Disassemble(llvm::raw_ostream &pOutput, const char *pTriple,
+                              const char *pFuncName, const uint8_t *pFunc,
+                              size_t pFuncSize);
+
+DisassembleResult Disassemble(OutputFile &pOutput, const char *pTriple,
+                              const char *pFuncName, const uint8_t *pFunc,
+                              size_t pFuncSize);
+
+} // end namespace bcc
+
+#endif // BCC_SUPPORT_DISASSEMBLER_H
diff --git a/libbcc/include/bcc/Support/File.h b/libbcc/include/bcc/Support/File.h
new file mode 100644
index 0000000..6367359
--- /dev/null
+++ b/libbcc/include/bcc/Support/File.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_FILE_H
+#define BCC_SUPPORT_FILE_H
+
+#include "bcc/Support/FileBase.h"
+
+namespace bcc {
+
+template<enum FileBase::OpenModeEnum OpenMode>
+struct FileAttribute {
+  // The flags to the 2nd argument in ::open().
+  enum { kOpenFlags };
+
+  // Default value of LockMode.
+  enum { kDefaultLockMode };
+};
+
+// FileAttribute for accessing read-only file
+template<>
+struct FileAttribute<FileBase::kReadMode> {
+  enum { kOpenFlags       = O_RDONLY };
+  enum { kDefaultLockMode = FileBase::kReadLock };
+};
+
+// FileAttribute for accessing writable file
+template<>
+struct FileAttribute<FileBase::kWriteMode> {
+  enum { kOpenFlags       = O_RDWR | O_CREAT };
+  enum { kDefaultLockMode = FileBase::kWriteLock };
+};
+
+template<enum FileBase::OpenModeEnum OpenMode>
+class File : public FileBase {
+public:
+  File(const std::string &pFilename, unsigned pFlags)
+    : FileBase(pFilename, FileAttribute<OpenMode>::kOpenFlags, pFlags) { }
+
+  inline bool lock(enum LockModeEnum pMode = static_cast<enum LockModeEnum>(
+                      FileAttribute<OpenMode>::kDefaultLockMode),
+                   bool pNonblocking = true,
+                   unsigned pMaxRetry = FileBase::kDefaultMaxRetryLock,
+                   useconds_t pRetryInterval =
+                      FileBase::kDefaultRetryLockInterval) {
+    return FileBase::lock(pMode, pNonblocking, pMaxRetry, pRetryInterval);
+  }
+
+  inline android::FileMap *createMap(off_t pOffset, size_t pLength,
+                                     bool pIsReadOnly =
+                                        (OpenMode == FileBase::kReadMode)) {
+    return FileBase::createMap(pOffset, pLength, pIsReadOnly);
+  }
+};
+
+
+} // end namespace bcc
+
+#endif  // BCC_SUPPORT_FILE_H
diff --git a/libbcc/include/bcc/Support/FileBase.h b/libbcc/include/bcc/Support/FileBase.h
new file mode 100644
index 0000000..cf9c998
--- /dev/null
+++ b/libbcc/include/bcc/Support/FileBase.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_FILE_BASE_H
+#define BCC_SUPPORT_FILE_BASE_H
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <string>
+#include <system_error>
+
+namespace android {
+  class FileMap;
+}
+
+namespace bcc {
+
+class FileBase {
+public:
+  enum OpenModeEnum {
+    kReadMode       = 1 << 0,
+    kWriteMode      = 1 << 1,
+    kReadWriteMode  = (kReadMode | kWriteMode),
+  };
+
+  enum FlagEnum {
+    kBinary = 1 << 0,
+    kTruncate = 1 << 1,
+    kAppend = 1 << 2,
+    kDeleteOnClose = 1 << 3
+  };
+
+  enum LockModeEnum {
+    // The shared resource behind the Stream locked in ReadLock mode can be
+    // locked by other processes at the same time.
+    kReadLock,
+
+    // The shared resource behind the Stream locked in WriteLock mode can only
+    // be locked by one process. It's exclusive. That is, the shared resource
+    // cannot have both ReadLock and WriteLock simultaneously.
+    kWriteLock
+  };
+
+  // Default configuration to the lock().
+  enum {
+    kDefaultMaxRetryLock = 4,
+    kDefaultRetryLockInterval = 200000UL,
+  };
+
+protected:
+  // Grant direct access of the internal file descriptor to the sub-class and
+  // error message such that they can implement their own I/O functionality.
+  int mFD;
+
+  std::error_code mError;
+
+private:
+  std::string mName;
+
+  // The 2nd argument to the POSIX open().
+  unsigned mOpenFlags;
+
+  // True true if we should call unlock() in destructor.
+  bool mShouldUnlock;
+
+  // True if file should be deleted in destructor.
+  bool mShouldDelete;
+
+  // Open mName with flag mOpenFlags (using POSIX open().)
+  bool open();
+
+  // Return true if mFD is the corresponded file descriptor to the file named
+  // mName on the filesystem. This check may returns failed, for example,
+  // someone re-create the file with the same name after we openning the file.
+  bool checkFileIntegrity();
+
+  inline bool reopen() {
+    // It's a private method, and all its callers are the few that can invoke it.
+    // That is, the pre-condition will be checked by the caller. Therefore, we don't
+    // need to check it again in reopen().
+    close();
+    return open();
+  }
+
+private:
+  FileBase(FileBase &); // Do not implement.
+  void operator=(const FileBase &); // Do not implement.
+
+protected:
+  // pOpenFlags is the 2nd argument to the POSIX open(). pFlags are the flags to
+  // FileBase. It's a bit set composed by the value defined in
+  // FileBase::FlagEnum.
+  FileBase(const std::string &pFilename, unsigned pOpenFlags, unsigned pFlags);
+
+  void detectError();
+
+public:
+  // Lock the file descriptor in given pMode. If pNonblocking is true, the lock
+  // request issued will return immediately when the shared resource is locked.
+  // In this case, it retries pMaxRetry times, each wait pRetryInterval (in
+  // usecs) before the previous retry getting done.
+  //
+  // Only file is allowed to use this API.
+  bool lock(enum LockModeEnum pMode, bool pNonblocking = true,
+            unsigned pMaxRetry = kDefaultMaxRetryLock,
+            useconds_t pRetryInterval = kDefaultRetryLockInterval);
+
+  void unlock();
+
+  // Map the file content to the memory.
+  //
+  // One who gets non-null android::FileMap returned from this API is responsible
+  // for destroying it after the use.
+  android::FileMap *createMap(off_t pOffset, size_t pLength, bool pIsReadOnly);
+
+  size_t getSize();
+
+  off_t seek(off_t pOffset);
+  off_t tell();
+
+  inline bool hasError() const
+  { return (bool) mError; }
+
+  inline const std::error_code &getError() const
+  { return mError; }
+
+  // The return value of std::error_code::message() is obtained upon the call
+  // and is passed by value (that is, it's not a member of std::error_code.)
+  inline std::string getErrorMessage() const
+  { return mError.message(); }
+
+  inline const std::string &getName() const
+  { return mName; }
+
+  void close();
+
+  virtual ~FileBase();
+};
+
+} // end namespace bcc
+
+#endif  // BCC_SUPPORT_FILE_BASE_H
diff --git a/libbcc/include/bcc/Support/FileMutex.h b/libbcc/include/bcc/Support/FileMutex.h
new file mode 100644
index 0000000..ec9ac21
--- /dev/null
+++ b/libbcc/include/bcc/Support/FileMutex.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_FILE_MUTEX_H
+#define BCC_SUPPORT_FILE_MUTEX_H
+
+#include <string>
+
+#include "bcc/Support/FileBase.h"
+
+namespace bcc {
+
+template<enum FileBase::LockModeEnum LockMode>
+class FileMutex : public FileBase {
+public:
+  explicit FileMutex(const std::string &pFileToLock)
+    : FileBase(pFileToLock + ".lock", O_RDONLY | O_CREAT, kDeleteOnClose) { }
+
+  // Provide a lock() interface filled with default configuration.
+  inline bool lock(bool pNonblocking = true,
+                   unsigned pMaxRetry = FileBase::kDefaultMaxRetryLock,
+                   useconds_t pRetryInterval =
+                       FileBase::kDefaultRetryLockInterval) {
+    return FileBase::lock(LockMode, pNonblocking, pMaxRetry, pRetryInterval);
+  }
+};
+
+} // namespace bcc
+
+#endif  // BCC_SUPPORT_FILE_MUTEX_H
diff --git a/libbcc/include/bcc/Support/Initialization.h b/libbcc/include/bcc/Support/Initialization.h
new file mode 100644
index 0000000..521f082
--- /dev/null
+++ b/libbcc/include/bcc/Support/Initialization.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_INITIALIZATION_H
+#define BCC_SUPPORT_INITIALIZATION_H
+
+namespace bcc {
+
+namespace init {
+
+void Initialize();
+
+} // end namespace init
+
+} // end namespace bcc
+
+#endif // BCC_SUPPORT_INITIALIZATION_H
diff --git a/libbcc/include/bcc/Support/InputFile.h b/libbcc/include/bcc/Support/InputFile.h
new file mode 100644
index 0000000..01f2b02
--- /dev/null
+++ b/libbcc/include/bcc/Support/InputFile.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_INPUT_FILE_H
+#define BCC_SUPPORT_INPUT_FILE_H
+
+#include "bcc/Support/File.h"
+#include "bcc/Support/FileBase.h"
+
+namespace bcc {
+
+class InputFile : public File<FileBase::kReadMode> {
+  typedef File<FileBase::kReadMode> super;
+public:
+  explicit InputFile(const std::string &pFilename, unsigned pFlags = 0);
+
+  ssize_t read(void *pBuf, size_t count);
+};
+
+} // end namespace bcc
+
+#endif  // BCC_SUPPORT_INPUT_FILE_H
diff --git a/libbcc/include/bcc/Support/Log.h b/libbcc/include/bcc/Support/Log.h
new file mode 100644
index 0000000..f4079ef
--- /dev/null
+++ b/libbcc/include/bcc/Support/Log.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_LOG_H
+#define BCC_SUPPORT_LOG_H
+
+#ifndef LOG_TAG
+#   define LOG_TAG "bcc"
+#   include <cutils/log.h>
+#endif
+
+#endif // BCC_SUPPORT_LOG_H
diff --git a/libbcc/include/bcc/Support/OutputFile.h b/libbcc/include/bcc/Support/OutputFile.h
new file mode 100644
index 0000000..daabbf8
--- /dev/null
+++ b/libbcc/include/bcc/Support/OutputFile.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_OUTPUT_FILE_H
+#define BCC_SUPPORT_OUTPUT_FILE_H
+
+#include "bcc/Support/File.h"
+#include "bcc/Support/FileBase.h"
+
+namespace llvm {
+  class raw_fd_ostream;
+}
+
+namespace bcc {
+
+class OutputFile : public File<FileBase::kWriteMode> {
+  typedef File<FileBase::kWriteMode> super;
+public:
+  explicit OutputFile(const std::string &pFilename, unsigned pFlags = 0);
+
+  ssize_t write(const void *pBuf, size_t count);
+
+  void truncate();
+
+  // This is similar to the system call dup(). It creates a copy of the file
+  // descriptor it contains and wrap it in llvm::raw_fd_ostream object. It
+  // returns a non-NULL object if everything goes well and user should later
+  // use delete operator to destroy it by itself.
+  llvm::raw_fd_ostream *dup();
+};
+
+} // end namespace bcc
+
+#endif  // BCC_SUPPORT_OUTPUT_FILE_H
diff --git a/libbcc/include/bcc/Support/Properties.h b/libbcc/include/bcc/Support/Properties.h
new file mode 100644
index 0000000..4c3c404
--- /dev/null
+++ b/libbcc/include/bcc/Support/Properties.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_PROPERTIES_H
+#define BCC_SUPPORT_PROPERTIES_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#if !defined(RS_SERVER) && defined(__ANDROID__)
+#include <cutils/properties.h>
+#endif
+
+static inline uint32_t getProperty(const char *str) {
+#if !defined(RS_SERVER) && defined(__ANDROID__)
+    char buf[PROPERTY_VALUE_MAX];
+    property_get(str, buf, "0");
+    return atoi(buf);
+#else
+    return 0;
+#endif
+}
+
+#endif // BCC_SUPPORT_PROPERTIES_H
diff --git a/libbcc/include/bcc/Support/Sha1Util.h b/libbcc/include/bcc/Support/Sha1Util.h
new file mode 100644
index 0000000..b7712ed
--- /dev/null
+++ b/libbcc/include/bcc/Support/Sha1Util.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SUPPORT_SHA1_UTIL_H
+#define BCC_SUPPORT_SHA1_UTIL_H
+
+#include <stdint.h>
+
+#include <cstddef>
+
+// This guard prevents system sha1.h (such as the one in bionic) has been
+// included before this header.
+#ifndef SHA1_DIGEST_LENGTH
+#define SHA1_DIGEST_LENGTH 20
+#endif
+
+namespace bcc {
+
+class Sha1Util {
+private:
+  Sha1Util(); // DISABLED.
+  Sha1Util(Sha1Util &); // DISABLED.
+
+public:
+  // Return true on success.
+  static bool GetSHA1DigestFromFile(uint8_t pResult[SHA1_DIGEST_LENGTH],
+                                    const char *pFilename);
+
+  // Return true on success.
+  static bool GetSHA1DigestFromBuffer(uint8_t pResult[SHA1_DIGEST_LENGTH],
+                                      const uint8_t *pData, size_t pSize);
+
+  // Useful function when passing buffer of type  "const char *."
+  static bool GetSHA1DigestFromBuffer(uint8_t pResult[SHA1_DIGEST_LENGTH],
+                                      const char *pData, size_t pSize) {
+    return GetSHA1DigestFromBuffer(pResult,
+                                   reinterpret_cast<const uint8_t*>(pData),
+                                   pSize);
+  }
+};
+
+} // end namespace bcc
+
+#endif // BCC_SUPPORT_SHA1_UTIL_H
diff --git a/libbcc/include/bcinfo/BitcodeTranslator.h b/libbcc/include/bcinfo/BitcodeTranslator.h
new file mode 100644
index 0000000..92fe777
--- /dev/null
+++ b/libbcc/include/bcinfo/BitcodeTranslator.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ANDROID_BCINFO_BITCODETRANSLATOR_H__
+#define __ANDROID_BCINFO_BITCODETRANSLATOR_H__
+
+#include <cstddef>
+
+namespace bcinfo {
+
+class BitcodeTranslator {
+ private:
+  const char *mBitcode;
+  size_t mBitcodeSize;
+  const char *mTranslatedBitcode;
+  size_t mTranslatedBitcodeSize;
+  unsigned int mVersion;
+
+ public:
+  /**
+   * Translates \p bitcode of a particular \p version to the latest version.
+   *
+   * \param bitcode - input bitcode string.
+   * \param bitcodeSize - length of \p bitcode string (in bytes).
+   * \param version - corresponding target SDK version of \p bitcode.
+   */
+  BitcodeTranslator(const char *bitcode, size_t bitcodeSize,
+                    unsigned int version);
+
+  ~BitcodeTranslator();
+
+  /**
+   * Translate the supplied bitcode to the latest supported version.
+   *
+   * \return true if the bitcode was translated successfully and false if an
+   *         error occurred.
+   */
+  bool translate();
+
+  /**
+   * \return translated bitcode.
+   */
+  const char *getTranslatedBitcode() const {
+    return mTranslatedBitcode;
+  }
+
+  /**
+   * \return size of the translated bitcode (in bytes).
+   */
+  size_t getTranslatedBitcodeSize() const {
+    return mTranslatedBitcodeSize;
+  }
+};
+
+}  // namespace bcinfo
+
+#endif  // __ANDROID_BCINFO_BITCODETRANSLATOR_H__
diff --git a/libbcc/include/bcinfo/BitcodeWrapper.h b/libbcc/include/bcinfo/BitcodeWrapper.h
new file mode 100644
index 0000000..e3e65d2
--- /dev/null
+++ b/libbcc/include/bcinfo/BitcodeWrapper.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2011-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ANDROID_BCINFO_BITCODEWRAPPER_H__
+#define __ANDROID_BCINFO_BITCODEWRAPPER_H__
+
+#include "bcinfo/Wrap/BCHeaderField.h"
+
+#include <cstddef>
+#include <stdint.h>
+
+namespace bcinfo {
+
+struct AndroidBitcodeWrapper {
+  uint32_t Magic;
+  uint32_t Version;
+  uint32_t BitcodeOffset;
+  uint32_t BitcodeSize;
+  uint32_t HeaderVersion;
+  uint32_t TargetAPI;
+  uint32_t PNaClVersion;
+  uint16_t CompilerVersionTag;
+  uint16_t CompilerVersionLen;
+  uint32_t CompilerVersion;
+  uint16_t OptimizationLevelTag;
+  uint16_t OptimizationLevelLen;
+  uint32_t OptimizationLevel;
+};
+
+enum BCFileType {
+  BC_NOT_BC = 0,
+  BC_WRAPPER = 1,
+  BC_RAW = 2
+};
+
+class BitcodeWrapper {
+ private:
+  enum BCFileType mFileType;
+  const char *mBitcode;
+  size_t mBitcodeSize;
+
+  uint32_t mHeaderVersion;
+  uint32_t mTargetAPI;
+  uint32_t mCompilerVersion;
+  uint32_t mOptimizationLevel;
+
+ public:
+  /**
+   * Reads wrapper information from \p bitcode.
+   *
+   * \param bitcode - input bitcode string.
+   * \param bitcodeSize - length of \p bitcode string (in bytes).
+   */
+  BitcodeWrapper(const char *bitcode, size_t bitcodeSize);
+
+  ~BitcodeWrapper();
+
+  /**
+   * Attempt to unwrap the target bitcode. This function is \deprecated.
+   *
+   * \return true on success and false if an error occurred.
+   */
+  bool unwrap();
+
+  /**
+   * \return type of bitcode file.
+   */
+  enum BCFileType getBCFileType() const {
+    return mFileType;
+  }
+
+  /**
+   * \return header version of bitcode wrapper.
+   */
+  uint32_t getHeaderVersion() const {
+    return mHeaderVersion;
+  }
+
+  /**
+   * \return target API version for this bitcode.
+   */
+  uint32_t getTargetAPI() const {
+    return mTargetAPI;
+  }
+
+  /**
+   * \return compiler version that generated this bitcode.
+   */
+  uint32_t getCompilerVersion() const {
+    return mCompilerVersion;
+  }
+
+  /**
+   * \return compiler optimization level for this bitcode.
+   */
+  uint32_t getOptimizationLevel() const {
+    return mOptimizationLevel;
+  }
+
+};
+
+/**
+ * Helper function to emit just the bitcode wrapper returning the number of
+ * bytes that were written.
+ *
+ * \param wrapper - where to write header information into.
+ * \param bitcodeSize - size of bitcode in bytes.
+ * \param targetAPI - target API version for this bitcode.
+ * \param compilerVersion - compiler version that generated this bitcode.
+ * \param optimizationLevel - compiler optimization level for this bitcode.
+ *
+ * \return number of wrapper bytes written into the \p buffer.
+ */
+static inline size_t writeAndroidBitcodeWrapper(AndroidBitcodeWrapper *wrapper,
+    size_t bitcodeSize, uint32_t targetAPI, uint32_t compilerVersion,
+    uint32_t optimizationLevel) {
+  if (!wrapper) {
+    return 0;
+  }
+
+  wrapper->Magic = 0x0B17C0DE;
+  wrapper->Version = 0;
+  wrapper->BitcodeOffset = sizeof(*wrapper);
+  wrapper->BitcodeSize = bitcodeSize;
+  wrapper->HeaderVersion = 0;
+  wrapper->TargetAPI = targetAPI;
+  wrapper->PNaClVersion = 0;
+  wrapper->CompilerVersionTag = BCHeaderField::kAndroidCompilerVersion;
+  wrapper->CompilerVersionLen = 4;
+  wrapper->CompilerVersion = compilerVersion;
+  wrapper->OptimizationLevelTag = BCHeaderField::kAndroidOptimizationLevel;
+  wrapper->OptimizationLevelLen = 4;
+  wrapper->OptimizationLevel = optimizationLevel;
+
+  return sizeof(*wrapper);
+}
+
+}  // namespace bcinfo
+
+#endif  // __ANDROID_BCINFO_BITCODEWRAPPER_H__
diff --git a/libbcc/include/bcinfo/MetadataExtractor.h b/libbcc/include/bcinfo/MetadataExtractor.h
new file mode 100644
index 0000000..d1de4fe
--- /dev/null
+++ b/libbcc/include/bcinfo/MetadataExtractor.h
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2011-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ANDROID_BCINFO_METADATAEXTRACTOR_H__
+#define __ANDROID_BCINFO_METADATAEXTRACTOR_H__
+
+#include <cstddef>
+#include <memory>
+
+#include <stdint.h>
+
+namespace llvm {
+  class Function;
+  class Module;
+  class NamedMDNode;
+}
+
+namespace bcinfo {
+
+enum RSFloatPrecision {
+  RS_FP_Full = 0,
+  RS_FP_Relaxed = 1,
+};
+
+enum MetadataSignatureBitval {
+  MD_SIG_None        = 0,
+  MD_SIG_In          = 0x000001,
+  MD_SIG_Out         = 0x000002,
+  MD_SIG_Usr         = 0x000004,
+  MD_SIG_X           = 0x000008,
+  MD_SIG_Y           = 0x000010,
+  MD_SIG_Kernel      = 0x000020,
+  MD_SIG_Z           = 0x000040,
+  MD_SIG_Ctxt        = 0x000080,
+};
+
+class MetadataExtractor {
+ public:
+  struct Reduce {
+    // These strings are owned by the Reduce instance, and deleted upon its destruction.
+    // They are assumed to have been allocated by "new []" and hence are deleted by "delete []".
+    const char *mReduceName;
+    const char *mInitializerName;
+    const char *mAccumulatorName;
+    const char *mCombinerName;
+    const char *mOutConverterName;
+    const char *mHalterName;
+
+    uint32_t mSignature;   // of accumulator function
+    uint32_t mInputCount;  // of accumulator function (and of kernel itself)
+    uint32_t mAccumulatorDataSize;  // in bytes
+
+    Reduce() :
+        mReduceName(nullptr),
+        mInitializerName(nullptr), mAccumulatorName(nullptr), mCombinerName(nullptr),
+        mOutConverterName(nullptr), mHalterName(nullptr),
+        mSignature(0), mInputCount(0), mAccumulatorDataSize(0) {
+    }
+    ~Reduce() {
+      delete [] mReduceName;
+      delete [] mInitializerName;
+      delete [] mAccumulatorName;
+      delete [] mCombinerName;
+      delete [] mOutConverterName;
+      delete [] mHalterName;
+    }
+
+    Reduce(const Reduce &) = delete;
+    void operator=(const Reduce &) = delete;
+  };
+
+ private:
+  const llvm::Module *mModule;
+  const char *mBitcode;
+  size_t mBitcodeSize;
+
+  size_t mExportVarCount;
+  size_t mExportFuncCount;
+  size_t mExportForEachSignatureCount;
+  size_t mExportReduceCount;
+  const char **mExportVarNameList;
+  const char **mExportFuncNameList;
+  const char **mExportForEachNameList;
+  const uint32_t *mExportForEachSignatureList;
+  const uint32_t *mExportForEachInputCountList;
+  const Reduce *mExportReduceList;
+
+  size_t mPragmaCount;
+  const char **mPragmaKeyList;
+  const char **mPragmaValueList;
+
+  size_t mObjectSlotCount;
+  const uint32_t *mObjectSlotList;
+
+  uint32_t mTargetAPI;
+  uint32_t mCompilerVersion;
+  uint32_t mOptimizationLevel;
+
+  enum RSFloatPrecision mRSFloatPrecision;
+
+  // Flag to mark that script is threadable.  True by default.
+  bool mIsThreadable;
+
+  const char *mBuildChecksum;
+
+  bool mHasDebugInfo;
+
+  // Helper functions for extraction
+  bool populateForEachMetadata(const llvm::NamedMDNode *Names,
+                               const llvm::NamedMDNode *Signatures);
+  bool populateReduceMetadata(const llvm::NamedMDNode *ReduceMetadata);
+  bool populateObjectSlotMetadata(const llvm::NamedMDNode *ObjectSlotMetadata);
+  void populatePragmaMetadata(const llvm::NamedMDNode *PragmaMetadata);
+  void readThreadableFlag(const llvm::NamedMDNode *ThreadableMetadata);
+  void readBuildChecksumMetadata(const llvm::NamedMDNode *ChecksumMetadata);
+
+  uint32_t calculateNumInputs(const llvm::Function *Function,
+                              uint32_t Signature);
+
+ public:
+  /**
+   * Reads metadata from \p bitcode.
+   *
+   * \param bitcode - input bitcode string.
+   * \param bitcodeSize - length of \p bitcode string (in bytes).
+   */
+  MetadataExtractor(const char *bitcode, size_t bitcodeSize);
+
+  /**
+   * Reads metadata from \p module.
+   *
+   * \param module - input module.
+   */
+  explicit MetadataExtractor(const llvm::Module *module);
+
+  ~MetadataExtractor();
+
+  /**
+   * Extract the actual metadata from the supplied bitcode.
+   *
+   * \return true on success and false if an error occurred.
+   */
+  bool extract();
+
+  /**
+   * \return target API level of this bitcode.
+   *
+   * The target API is used during the SDK compilation to provide proper
+   * visibility of the RenderScript runtime API functions.
+   */
+  uint32_t getTargetAPI() const {
+    return mTargetAPI;
+  }
+
+  /**
+   * \return number of exported global variables (slots) in this script/module.
+   */
+  size_t getExportVarCount() const {
+    return mExportVarCount;
+  }
+
+  /**
+   * \return array of exported variable names.
+   */
+  const char **getExportVarNameList() const {
+    return mExportVarNameList;
+  }
+
+  /**
+   * \return number of exported global functions (slots) in this script/module.
+   */
+  size_t getExportFuncCount() const {
+    return mExportFuncCount;
+  }
+
+  /**
+   * \return array of exported function names.
+   */
+  const char **getExportFuncNameList() const {
+    return mExportFuncNameList;
+  }
+
+  /**
+   * \return number of exported ForEach functions in this script/module.
+   */
+  size_t getExportForEachSignatureCount() const {
+    return mExportForEachSignatureCount;
+  }
+
+  /**
+   * \return array of exported ForEach function signatures.
+   */
+  const uint32_t *getExportForEachSignatureList() const {
+    return mExportForEachSignatureList;
+  }
+
+  /**
+   * \return array of exported ForEach function names.
+   */
+  const char **getExportForEachNameList() const {
+    return mExportForEachNameList;
+  }
+
+  /**
+   * \return array of input parameter counts.
+   */
+  const uint32_t *getExportForEachInputCountList() const {
+    return mExportForEachInputCountList;
+  }
+
+  /**
+   * \return number of exported general reduce kernels (slots) in this script/module.
+   */
+  size_t getExportReduceCount() const {
+    return mExportReduceCount;
+  }
+
+  /**
+   * \return array of exported general reduce kernel descriptions.
+   */
+  const Reduce *getExportReduceList() const {
+    return mExportReduceList;
+  }
+
+  /**
+   * \return number of pragmas contained in pragmaKeyList and pragmaValueList.
+   */
+  size_t getPragmaCount() const {
+    return mPragmaCount;
+  }
+
+  /**
+   * \return pragma keys (the name for the pragma).
+   */
+  const char **getPragmaKeyList() const {
+    return mPragmaKeyList;
+  }
+
+  /**
+   * \return pragma values (contents corresponding to a particular pragma key).
+   */
+  const char **getPragmaValueList() const {
+    return mPragmaValueList;
+  }
+
+  /**
+   * \return number of object slots contained in objectSlotList.
+   */
+  size_t getObjectSlotCount() const {
+    return mObjectSlotCount;
+  }
+
+  /**
+   * \return array of object slot numbers that must be cleaned up by driver
+   *         on script teardown.
+   */
+  const uint32_t *getObjectSlotList() const {
+    return mObjectSlotList;
+  }
+
+  /**
+   * \return compiler version that generated this bitcode.
+   */
+  uint32_t getCompilerVersion() const {
+    return mCompilerVersion;
+  }
+
+  /**
+   * \return compiler optimization level for this bitcode.
+   */
+  uint32_t getOptimizationLevel() const {
+    return mOptimizationLevel;
+  }
+
+  /**
+   * \return minimal floating point precision that the script requires.
+   */
+  enum RSFloatPrecision getRSFloatPrecision() const {
+    return mRSFloatPrecision;
+  }
+
+  /**
+   * \return whether or not this ForEach function signature has an "In"
+   * parameter.
+   *
+   * \param sig - ForEach function signature to check.
+   */
+  static bool hasForEachSignatureIn(uint32_t sig) {
+    return sig & MD_SIG_In;
+  }
+
+  /**
+   * \return whether or not this ForEach function signature has an "Out"
+   * parameter.
+   *
+   * \param sig - ForEach function signature to check.
+   */
+  static bool hasForEachSignatureOut(uint32_t sig) {
+    return sig & MD_SIG_Out;
+  }
+
+  /**
+   * \return whether or not this ForEach function signature has a "UsrData"
+   * parameter.
+   *
+   * \param sig - ForEach function signature to check.
+   */
+  static bool hasForEachSignatureUsrData(uint32_t sig) {
+    return sig & MD_SIG_Usr;
+  }
+
+  /**
+   * \return whether or not this ForEach function signature has an "X"
+   * parameter.
+   *
+   * \param sig - ForEach function signature to check.
+   */
+  static bool hasForEachSignatureX(uint32_t sig) {
+    return sig & MD_SIG_X;
+  }
+
+  /**
+   * \return whether or not this ForEach function signature has a "Y"
+   * parameter.
+   *
+   * \param sig - ForEach function signature to check.
+   */
+  static bool hasForEachSignatureY(uint32_t sig) {
+    return sig & MD_SIG_Y;
+  }
+
+  /**
+   * \return whether or not this ForEach function signature is a
+   * pass-by-value "Kernel".
+   *
+   * \param sig - ForEach function signature to check.
+   */
+  static bool hasForEachSignatureKernel(uint32_t sig) {
+    return sig & MD_SIG_Kernel;
+  }
+
+  /**
+   * \return whether or not this ForEach function signature has a "Z"
+   * parameter.
+   *
+   * \param sig - ForEach function signature to check.
+   */
+  static bool hasForEachSignatureZ(uint32_t sig) {
+    return sig & MD_SIG_Z;
+  }
+
+  /**
+   * \return whether or not this ForEach function signature has a "Ctxt"
+   * parameter.
+   *
+   * \param sig - ForEach function signature to check.
+   */
+  static bool hasForEachSignatureCtxt(uint32_t sig) {
+    return sig & MD_SIG_Ctxt;
+  }
+
+  /**
+   * \return whether "Kernels" in this script can be processed
+   * by multiple threads
+   */
+
+  bool isThreadable() const {
+    return mIsThreadable;
+  }
+
+  /**
+   * \return the build checksum extracted from the LLVM metadata
+   */
+  const char *getBuildChecksum() const {
+    return mBuildChecksum;
+  }
+
+  /**
+   * \return whether the module contains debug metadata
+   */
+  bool hasDebugInfo() const {
+    return mHasDebugInfo;
+  }
+};
+
+}  // namespace bcinfo
+
+#endif  // __ANDROID_BCINFO_METADATAEXTRACTOR_H__
diff --git a/libbcc/include/bcinfo/Wrap/BCHeaderField.h b/libbcc/include/bcinfo/Wrap/BCHeaderField.h
new file mode 100644
index 0000000..fd8d585
--- /dev/null
+++ b/libbcc/include/bcinfo/Wrap/BCHeaderField.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LLVM_WRAP_BCHEADER_FIELD_H__
+#define LLVM_WRAP_BCHEADER_FIELD_H__
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+// Class representing a variable-size metadata field in the bitcode header.
+// Also contains the list of known Tag IDs.
+// Contains a pointer to the data but does not own the data, so it can be
+// copied with the trivial copy constructor/assignment operator.
+
+// The serialized format has 2 fixed subfields (ID and length) and the
+// variable-length data subfield
+class BCHeaderField {
+ public:
+  typedef enum {
+    kInvalid = 0,
+    kBitcodeHash = 1,
+    kAndroidCompilerVersion = 0x4001,
+    kAndroidOptimizationLevel = 0x4002
+  } Tag;
+  typedef uint16_t FixedSubfield;
+
+  BCHeaderField(Tag ID, size_t len, uint8_t* data) :
+      ID_(ID), len_(len), data_(data) {}
+  size_t GetTotalSize() {
+    // Round up to 4 byte alignment
+    return (kTagLenSize + len_ + 3) & ~3;
+  }
+
+  bool Write(uint8_t* buf, size_t buf_len) {
+    size_t fields_len = kTagLenSize + len_;
+    size_t pad_len = (4 - (fields_len & 3)) & 3;
+    // Ensure buffer is large enough and that length can be represented
+    // in 16 bits
+    const size_t max_uint16_t = 65535;
+    if (buf_len < fields_len + pad_len ||
+        len_ > max_uint16_t) return false;
+
+    WriteFixedSubfield(static_cast<FixedSubfield>(ID_), buf);
+    WriteFixedSubfield(static_cast<FixedSubfield>(len_),
+                       buf + sizeof(FixedSubfield));
+    memcpy(buf + kTagLenSize, data_, len_);
+    // Pad out to 4 byte alignment
+    if (pad_len) {
+      memset(buf + fields_len, 0, pad_len);
+    }
+    return true;
+  }
+
+  bool Read(const uint8_t* buf, size_t buf_len) {
+    if (buf_len < kTagLenSize) return false;
+    FixedSubfield field;
+    ReadFixedSubfield(&field, buf);
+    ID_ = static_cast<Tag>(field);
+    ReadFixedSubfield(&field, buf + sizeof(FixedSubfield));
+    len_ = static_cast<size_t>(field);
+    if (buf_len < kTagLenSize + len_) return false;
+    memcpy(data_, buf + kTagLenSize, len_);
+    return true;
+  }
+
+  void Print() {
+    fprintf(stderr, "Field ID: %d, data length %d, total length %d\n",
+            ID_, static_cast<int>(len_), static_cast<int>(GetTotalSize()));
+    fprintf(stderr, "Data:");
+    for (size_t i = 0; i < len_; i++) fprintf(stderr, "0x%x ", data_[i]);
+    fprintf(stderr, "\n");
+  }
+
+  // Get the data size from a serialized field to allow allocation
+  static size_t GetDataSizeFromSerialized(const uint8_t* buf) {
+    FixedSubfield len;
+    ReadFixedSubfield(&len, buf + sizeof(FixedSubfield));
+    return len;
+  }
+
+  Tag getID() const {
+    return ID_;
+  }
+
+  size_t getLen() const {
+    return len_;
+  }
+
+ private:
+ // Combined size of the fixed subfields
+ const static size_t kTagLenSize = 2 * sizeof(FixedSubfield);
+  static void WriteFixedSubfield(FixedSubfield value, uint8_t* buf) {
+    buf[0] = value & 0xFF;
+    buf[1] = (value >> 8) & 0xFF;
+  }
+  static void ReadFixedSubfield(FixedSubfield* value, const uint8_t* buf) {
+    *value = buf[0] | buf[1] << 8;
+  }
+  Tag ID_;
+  size_t len_;
+  uint8_t *data_;
+};
+
+#endif  // LLVM_WRAP_BCHEADER_FIELD_H__
diff --git a/libbcc/include/bcinfo/Wrap/bitcode_wrapperer.h b/libbcc/include/bcinfo/Wrap/bitcode_wrapperer.h
new file mode 100644
index 0000000..42ad5a9
--- /dev/null
+++ b/libbcc/include/bcinfo/Wrap/bitcode_wrapperer.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Define utility class to wrap/unwrap bitcode files. Does wrapping/unwrapping
+// in such a way that the wrappered bitcode file is still a bitcode file.
+
+#ifndef LLVM_WRAP_BITCODE_WRAPPERER_H__
+#define LLVM_WRAP_BITCODE_WRAPPERER_H__
+
+#include <stdint.h>
+#include <stddef.h>
+#include <vector>
+
+#include "bcinfo/Wrap/support_macros.h"
+#include "bcinfo/Wrap/BCHeaderField.h"
+#include "bcinfo/Wrap/wrapper_input.h"
+#include "bcinfo/Wrap/wrapper_output.h"
+
+// The bitcode wrapper header is the following 7 fixed 4-byte fields:
+//      1) 0B17C0DE - The magic number expected by llvm for wrapped bitcodes
+//      2) Version # 0 - The current version of wrapped bitcode files
+//      3) (raw) bitcode offset
+//      4) (raw) bitcode size
+//      5) Android header version
+//      6) Android target API
+//      7) PNaCl Bitcode version
+//      plus 0 or more variable-length fields (consisting of ID, length, data)
+
+// Initial buffer size. It is expanded if needed to hold large variable-size
+// fields.
+static const size_t kBitcodeWrappererBufferSize = 1024;
+
+// Support class for outputting a wrapped bitcode file from a raw bitcode
+// file (and optionally additional header fields), or for outputting a raw
+// bitcode file from a wrapped one.
+class BitcodeWrapperer {
+ public:
+  // Create a bitcode wrapperer using the following
+  // input and output files.
+  BitcodeWrapperer(WrapperInput* infile, WrapperOutput* outfile);
+
+  // Returns true if the input file begins with a bitcode
+  // wrapper magic number. As a side effect, _wrapper_ fields are set.
+  bool IsInputBitcodeWrapper();
+
+  // Returns true if the input file begins with a bitcode
+  // file magic number.
+  bool IsInputBitcodeFile();
+
+  // Add a variable-length field to the header. The caller is responsible
+  // for freeing the data pointed to by the BCHeaderField.
+  void AddHeaderField(BCHeaderField* field);
+
+  // Generate a wrapped bitcode file from the input bitcode file
+  // and the current header data. Return true on success.
+  bool GenerateWrappedBitcodeFile();
+
+  // Unwrap the wrapped bitcode file, to the corresponding
+  // outfile. Return true on success.
+  bool GenerateRawBitcodeFile();
+
+  // Print current wrapper header fields to stderr for debugging.
+  void PrintWrapperHeader();
+
+  uint32_t getAndroidHeaderVersion() {
+    return android_header_version_;
+  }
+
+  uint32_t getAndroidTargetAPI() {
+    return android_target_api_;
+  }
+
+  uint32_t getAndroidCompilerVersion() {
+    return android_compiler_version_;
+  }
+
+  uint32_t getAndroidOptimizationLevel() {
+    return android_optimization_level_;
+  }
+
+  ~BitcodeWrapperer();
+
+ private:
+  DISALLOW_CLASS_COPY_AND_ASSIGN(BitcodeWrapperer);
+
+  // Refills the buffer with more bytes. Does this in a way
+  // such that it is maximally filled.
+  void FillBuffer();
+
+  // Returns the number of bytes in infile.
+  off_t GetInFileSize() {
+    if (infile_ != nullptr) {
+      return infile_->Size();
+    } else {
+      return 0;
+    }
+  }
+
+  // Returns the offset of bitcode (i.e. the size of the wrapper header)
+  // if the output file were to be written now.
+  size_t BitcodeOffset();
+
+  // Returns true if we can read a word. If necessary, fills the buffer
+  // with enough characters so that there are at least a 32-bit value
+  // in the buffer. Returns false if there isn't a 32-bit value
+  // to read from the input file.
+  bool CanReadWord();
+
+  // Read a (32-bit) word from the input. Return true
+  // if able to read the word.
+  bool ReadWord(uint32_t& word);
+
+  // Write a (32-bit) word to the output. Return true if successful
+  bool WriteWord(uint32_t word);
+
+  // Write all variable-sized header fields to the output. Return true
+  // if successful.
+  bool WriteVariableFields();
+
+  // Parse the bitcode wrapper header in the infile, if any. Return true
+  // if successful.
+  bool ParseWrapperHeader();
+
+  // Returns the i-th character in front of the cursor in the buffer.
+  uint8_t BufferLookahead(int i) { return buffer_[cursor_ + i]; }
+
+  // Returns how many unread bytes are in the buffer.
+  size_t GetBufferUnreadBytes() { return buffer_size_ - cursor_; }
+
+
+  // Backs up the read cursor to the beginning of the input buffer.
+  void ResetCursor() {
+    cursor_ = 0;
+  }
+
+  // Generates the header sequence for the wrapped bitcode being
+  // generated.
+  bool WriteBitcodeWrapperHeader();
+
+  // Copies size bytes of infile to outfile, using the buffer.
+  bool BufferCopyInToOut(uint32_t size);
+
+  // Discards the old infile and replaces it with the given file.
+  void ReplaceInFile(WrapperInput* new_infile);
+
+  // Discards the old outfile and replaces it with the given file.
+  void ReplaceOutFile(WrapperOutput* new_outfile);
+
+  // Moves to the given position in the input file. Returns false
+  // if unsuccessful.
+  bool Seek(uint32_t pos);
+
+  // Clear the buffer of all contents.
+  void ClearBuffer();
+
+  // The input file being processed. Can be either
+  // a bitcode file, a wrappered bitcode file, or a secondary
+  // file to be wrapped.
+  WrapperInput* infile_;
+
+  // The output file being generated. Can be either
+  // a bitcode file, a wrappered bitcode file, or a secondary
+  // unwrapped file.
+  WrapperOutput* outfile_;
+
+  // A buffer of bytes read from the input file.
+  std::vector<uint8_t> buffer_;
+
+  // The number of bytes that were read from the input file
+  // into the buffer.
+  size_t buffer_size_;
+
+  // The index to the current read point within the buffer.
+  size_t cursor_;
+
+  // True when eof of input is reached.
+  bool infile_at_eof_;
+
+  // The 32-bit value defining the offset of the raw bitcode in the input file.
+  uint32_t infile_bc_offset_;
+
+  // The 32-bit value defining the generated offset of the wrapped bitcode.
+  // This value changes as new fields are added with AddHeaderField
+  uint32_t wrapper_bc_offset_;
+
+  // The 32-bit value defining the size of the raw wrapped bitcode.
+  uint32_t wrapper_bc_size_;
+
+  // Android header version and target API
+  uint32_t android_header_version_;
+  uint32_t android_target_api_;
+  uint32_t android_compiler_version_;
+  uint32_t android_optimization_level_;
+
+  // PNaCl bitcode version
+  uint32_t pnacl_bc_version_;
+
+  // Vector of variable header fields
+  std::vector<BCHeaderField> header_fields_;
+  // If any bufferdata from header fields is owned, it is stored here and
+  // freed on destruction.
+  std::vector<uint8_t*> variable_field_data_;
+
+  // True if there was an error condition (e.g. the file is not bitcode)
+  bool error_;
+};
+
+#endif  // LLVM_WRAP_BITCODE_WRAPPERER_H__
diff --git a/libbcc/include/bcinfo/Wrap/file_wrapper_input.h b/libbcc/include/bcinfo/Wrap/file_wrapper_input.h
new file mode 100644
index 0000000..117d335
--- /dev/null
+++ b/libbcc/include/bcinfo/Wrap/file_wrapper_input.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Defines utility allowing files for bitcode input wrapping.
+
+#ifndef FILE_WRAPPER_INPUT_H__
+#define FILE_WRAPPER_INPUT_H__
+
+#include <stdio.h>
+
+#include "bcinfo/Wrap/support_macros.h"
+#include "bcinfo/Wrap/wrapper_input.h"
+
+// Define a class to wrap named files.
+class FileWrapperInput : public WrapperInput {
+ public:
+  explicit FileWrapperInput(const char* _name);
+  ~FileWrapperInput();
+  // Tries to read the requested number of bytes into the buffer. Returns the
+  // actual number of bytes read.
+  virtual size_t Read(uint8_t* buffer, size_t wanted);
+  // Returns true if at end of file. Note: May return false
+  // until Read is called, and returns 0.
+  virtual bool AtEof();
+  // Returns the size of the file (in bytes).
+  virtual off_t Size();
+  // Moves to the given offset within the file. Returns
+  // false if unable to move to that position.
+  virtual bool Seek(uint32_t pos);
+ private:
+  // The name of the file.
+  const char* _name;
+  // True once eof has been encountered.
+  bool _at_eof;
+  // True if size has been computed.
+  bool _size_found;
+  // The size of the file.
+  off_t _size;
+  // The corresponding (opened) file.
+  FILE* _file;
+ private:
+  DISALLOW_CLASS_COPY_AND_ASSIGN(FileWrapperInput);
+};
+
+#endif // FILE_WRAPPER_INPUT_H__
diff --git a/libbcc/include/bcinfo/Wrap/