Project import
diff --git a/slang/.clang-format b/slang/.clang-format
new file mode 100644
index 0000000..00c22f5
--- /dev/null
+++ b/slang/.clang-format
@@ -0,0 +1,2 @@
+# See http://clang.llvm.org/docs/ClangFormatStyleOptions.html
+BasedOnStyle: llvm
diff --git a/slang/Android.mk b/slang/Android.mk
new file mode 100644
index 0000000..61fba19
--- /dev/null
+++ b/slang/Android.mk
@@ -0,0 +1,207 @@
+#
+# Copyright (C) 2010 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)
+
+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
+
+# The prebuilt tools should be used when we are doing app-only build.
+ifeq ($(TARGET_BUILD_APPS),)
+
+
+local_cflags_for_slang := -Wall -Werror -std=c++11
+ifeq ($(TARGET_BUILD_VARIANT),eng)
+local_cflags_for_slang += -O0 -D__ENABLE_INTERNAL_OPTIONS
+else
+ifeq ($(TARGET_BUILD_VARIANT),userdebug)
+else
+local_cflags_for_slang += -D__DISABLE_ASSERTS
+endif
+endif
+local_cflags_for_slang += -DTARGET_BUILD_VARIANT=$(TARGET_BUILD_VARIANT)
+
+include $(LOCAL_PATH)/rs_version.mk
+local_cflags_for_slang += $(RS_VERSION_DEFINE)
+
+static_libraries_needed_by_slang := \
+	libLLVMBitWriter_2_9 \
+	libLLVMBitWriter_2_9_func \
+	libLLVMBitWriter_3_2
+
+# Static library libslang for host
+# ========================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+LLVM_ROOT_PATH := external/llvm
+CLANG_ROOT_PATH := external/clang
+
+include $(CLANG_ROOT_PATH)/clang.mk
+
+LOCAL_MODULE := libslang
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS += $(local_cflags_for_slang)
+
+# Skip missing-field-initializer warnings for mingw.
+LOCAL_CFLAGS_windows += -Wno-error=missing-field-initializers
+
+TBLGEN_TABLES :=    \
+	AttrList.inc	\
+	Attrs.inc	\
+	CommentCommandList.inc \
+	CommentNodes.inc \
+	DeclNodes.inc	\
+	DiagnosticCommonKinds.inc	\
+	DiagnosticFrontendKinds.inc	\
+	DiagnosticSemaKinds.inc	\
+	StmtNodes.inc
+
+LOCAL_SRC_FILES :=	\
+	slang.cpp	\
+	slang_bitcode_gen.cpp	\
+	slang_backend.cpp	\
+	slang_diagnostic_buffer.cpp
+
+LOCAL_C_INCLUDES += frameworks/compile/libbcc/include
+
+LOCAL_LDLIBS := -ldl -lpthread
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# ========================================================
+include $(CLEAR_VARS)
+
+LLVM_ROOT_PATH := external/llvm
+
+LOCAL_MODULE := llvm-rs-as
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_CLASS := EXECUTABLES
+
+LOCAL_SRC_FILES :=	\
+	llvm-rs-as.cpp
+
+LOCAL_CFLAGS += $(local_cflags_for_slang)
+LOCAL_STATIC_LIBRARIES :=	\
+	libslang \
+	$(static_libraries_needed_by_slang)
+LOCAL_SHARED_LIBRARIES := \
+	libLLVM
+
+include $(CLANG_HOST_BUILD_MK)
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(BUILD_HOST_EXECUTABLE)
+
+# Executable llvm-rs-cc for host
+# ========================================================
+include $(CLEAR_VARS)
+include $(CLEAR_TBLGEN_VARS)
+
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE := llvm-rs-cc
+
+LOCAL_CFLAGS += $(local_cflags_for_slang)
+
+# Skip missing-field-initializer warnings for mingw.
+LOCAL_CFLAGS += -Wno-error=missing-field-initializers
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_CLASS := EXECUTABLES
+
+TBLGEN_TABLES :=    \
+	AttrList.inc    \
+	Attrs.inc    \
+	CommentCommandList.inc \
+	CommentNodes.inc \
+	DeclNodes.inc    \
+	DiagnosticCommonKinds.inc   \
+	DiagnosticDriverKinds.inc	\
+	DiagnosticFrontendKinds.inc	\
+	DiagnosticSemaKinds.inc	\
+	Options.inc \
+	RSCCOptions.inc \
+	StmtNodes.inc
+
+LOCAL_SRC_FILES :=	\
+	llvm-rs-cc.cpp	\
+	rs_cc_options.cpp \
+	slang_rs_foreach_lowering.cpp \
+	slang_rs_ast_replace.cpp	\
+	slang_rs_check_ast.cpp	\
+	slang_rs_context.cpp	\
+	slang_rs_pragma_handler.cpp	\
+	slang_rs_exportable.cpp	\
+	slang_rs_export_type.cpp	\
+	slang_rs_export_element.cpp	\
+	slang_rs_export_var.cpp	\
+	slang_rs_export_func.cpp	\
+	slang_rs_export_foreach.cpp	\
+	slang_rs_export_reduce.cpp	\
+	slang_rs_object_ref_count.cpp	\
+	slang_rs_reflection.cpp \
+	slang_rs_reflection_cpp.cpp \
+	slang_rs_reflect_utils.cpp \
+	slang_rs_special_func.cpp	\
+	slang_rs_special_kernel_param.cpp \
+	strip_unknown_attributes.cpp
+
+LOCAL_C_INCLUDES += frameworks/compile/libbcc/include
+
+LOCAL_STATIC_LIBRARIES :=	\
+	libslang \
+	$(static_libraries_needed_by_slang)
+
+LOCAL_SHARED_LIBRARIES := \
+	libclang \
+	libLLVM
+
+LOCAL_LDLIBS_windows := -limagehlp -lpsapi
+LOCAL_LDLIBS_linux := -ldl -lpthread
+LOCAL_LDLIBS_darwin := -ldl -lpthread
+
+# For build RSCCOptions.inc from RSCCOptions.td
+intermediates := $(call local-generated-sources-dir)
+LOCAL_GENERATED_SOURCES += $(intermediates)/RSCCOptions.inc
+$(intermediates)/RSCCOptions.inc: $(LOCAL_PATH)/RSCCOptions.td $(LLVM_ROOT_PATH)/include/llvm/Option/OptParser.td $(LLVM_TBLGEN)
+	@echo "Building Renderscript compiler (llvm-rs-cc) Option tables with tblgen"
+	$(call transform-host-td-to-out,opt-parser-defs)
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(BUILD_HOST_EXECUTABLE)
+
+endif  # TARGET_BUILD_APPS
+
+#=====================================================================
+# Include Subdirectories
+#=====================================================================
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/slang/BitWriter_2_9/Android.mk b/slang/BitWriter_2_9/Android.mk
new file mode 100644
index 0000000..ff9c5bc
--- /dev/null
+++ b/slang/BitWriter_2_9/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH:= $(call my-dir)
+
+LLVM_ROOT_PATH := $(LOCAL_PATH)/../../../../external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+
+bitcode_writer_2_9_SRC_FILES :=	\
+	BitcodeWriter.cpp	\
+	BitcodeWriterPass.cpp	\
+	ValueEnumerator.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS += $(local_cflags_for_slang)
+LOCAL_C_INCLUDES += frameworks/compile/slang
+
+LOCAL_SRC_FILES := $(bitcode_writer_2_9_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMBitWriter_2_9
+
+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)
+
diff --git a/slang/BitWriter_2_9/BitcodeWriter.cpp b/slang/BitWriter_2_9/BitcodeWriter.cpp
new file mode 100644
index 0000000..5a905f8
--- /dev/null
+++ b/slang/BitWriter_2_9/BitcodeWriter.cpp
@@ -0,0 +1,1739 @@
+//===--- Bitcode/Writer/BitcodeWriter.cpp - Bitcode Writer ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Bitcode writer implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReaderWriter_2_9.h"
+#include "legacy_bitcode.h"
+#include "ValueEnumerator.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cctype>
+#include <map>
+using namespace llvm;
+
+// Redefine older bitcode opcodes for use here. Note that these come from
+// LLVM 2.7 (which is what HC shipped with).
+#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_CALL_2_7       22
+#define FUNC_CODE_DEBUG_LOC_2_7       32
+
+// Redefine older bitcode opcodes for use here. Note that these come from
+// LLVM 2.7 - 3.0.
+#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
+
+/// These are manifest constants used by the bitcode writer. They do not need to
+/// be kept in sync with the reader, but need to be consistent within this file.
+enum {
+  CurVersion = 0,
+
+  // VALUE_SYMTAB_BLOCK abbrev id's.
+  VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+  VST_ENTRY_7_ABBREV,
+  VST_ENTRY_6_ABBREV,
+  VST_BBENTRY_6_ABBREV,
+
+  // CONSTANTS_BLOCK abbrev id's.
+  CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+  CONSTANTS_INTEGER_ABBREV,
+  CONSTANTS_CE_CAST_Abbrev,
+  CONSTANTS_NULL_Abbrev,
+
+  // FUNCTION_BLOCK abbrev id's.
+  FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+  FUNCTION_INST_BINOP_ABBREV,
+  FUNCTION_INST_BINOP_FLAGS_ABBREV,
+  FUNCTION_INST_CAST_ABBREV,
+  FUNCTION_INST_RET_VOID_ABBREV,
+  FUNCTION_INST_RET_VAL_ABBREV,
+  FUNCTION_INST_UNREACHABLE_ABBREV
+};
+
+static unsigned GetEncodedCastOpcode(unsigned Opcode) {
+  switch (Opcode) {
+  default: llvm_unreachable("Unknown cast instruction!");
+  case Instruction::Trunc   : return bitc::CAST_TRUNC;
+  case Instruction::ZExt    : return bitc::CAST_ZEXT;
+  case Instruction::SExt    : return bitc::CAST_SEXT;
+  case Instruction::FPToUI  : return bitc::CAST_FPTOUI;
+  case Instruction::FPToSI  : return bitc::CAST_FPTOSI;
+  case Instruction::UIToFP  : return bitc::CAST_UITOFP;
+  case Instruction::SIToFP  : return bitc::CAST_SITOFP;
+  case Instruction::FPTrunc : return bitc::CAST_FPTRUNC;
+  case Instruction::FPExt   : return bitc::CAST_FPEXT;
+  case Instruction::PtrToInt: return bitc::CAST_PTRTOINT;
+  case Instruction::IntToPtr: return bitc::CAST_INTTOPTR;
+  case Instruction::BitCast : return bitc::CAST_BITCAST;
+  }
+}
+
+static unsigned GetEncodedBinaryOpcode(unsigned Opcode) {
+  switch (Opcode) {
+  default: llvm_unreachable("Unknown binary instruction!");
+  case Instruction::Add:
+  case Instruction::FAdd: return bitc::BINOP_ADD;
+  case Instruction::Sub:
+  case Instruction::FSub: return bitc::BINOP_SUB;
+  case Instruction::Mul:
+  case Instruction::FMul: return bitc::BINOP_MUL;
+  case Instruction::UDiv: return bitc::BINOP_UDIV;
+  case Instruction::FDiv:
+  case Instruction::SDiv: return bitc::BINOP_SDIV;
+  case Instruction::URem: return bitc::BINOP_UREM;
+  case Instruction::FRem:
+  case Instruction::SRem: return bitc::BINOP_SREM;
+  case Instruction::Shl:  return bitc::BINOP_SHL;
+  case Instruction::LShr: return bitc::BINOP_LSHR;
+  case Instruction::AShr: return bitc::BINOP_ASHR;
+  case Instruction::And:  return bitc::BINOP_AND;
+  case Instruction::Or:   return bitc::BINOP_OR;
+  case Instruction::Xor:  return bitc::BINOP_XOR;
+  }
+}
+
+static void WriteStringRecord(unsigned Code, StringRef Str,
+                              unsigned AbbrevToUse, BitstreamWriter &Stream) {
+  SmallVector<unsigned, 64> Vals;
+
+  // Code: [strchar x N]
+  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+    if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i]))
+      AbbrevToUse = 0;
+    Vals.push_back(Str[i]);
+  }
+
+  // Emit the finished record.
+  Stream.EmitRecord(Code, Vals, AbbrevToUse);
+}
+
+// Emit information about parameter attributes.
+static void WriteAttributeTable(const llvm_2_9::ValueEnumerator &VE,
+                                BitstreamWriter &Stream) {
+  const std::vector<AttributeSet> &Attrs = VE.getAttributes();
+  if (Attrs.empty()) return;
+
+  Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
+
+  SmallVector<uint64_t, 64> Record;
+  for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
+    const AttributeSet &A = Attrs[i];
+    for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) {
+      Record.push_back(A.getSlotIndex(i));
+      Record.push_back(encodeLLVMAttributesForBitcode(A, A.getSlotIndex(i)));
+    }
+
+    // This needs to use the 3.2 entry type
+    Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY_OLD, Record);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void WriteTypeSymbolTable(const llvm_2_9::ValueEnumerator &VE,
+                                 BitstreamWriter &Stream) {
+  const llvm_2_9::ValueEnumerator::TypeList &TypeList = VE.getTypes();
+  Stream.EnterSubblock(TYPE_SYMTAB_BLOCK_ID_OLD_3_0, 3);
+
+  // 7-bit fixed width VST_CODE_ENTRY strings.
+  BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                            Log2_32_Ceil(VE.getTypes().size()+1)));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
+  unsigned V7Abbrev = Stream.EmitAbbrev(Abbv);
+
+  SmallVector<unsigned, 64> NameVals;
+
+  for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
+    Type *T = TypeList[i];
+
+    switch (T->getTypeID()) {
+    case Type::StructTyID: {
+      StructType *ST = cast<StructType>(T);
+      if (ST->isLiteral()) {
+        // Skip anonymous struct definitions in type symbol table
+        // FIXME(srhines)
+        break;
+      }
+
+      // TST_ENTRY: [typeid, namechar x N]
+      NameVals.push_back(i);
+
+      const std::string &Str = ST->getName();
+      bool is7Bit = true;
+      for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+        NameVals.push_back((unsigned char)Str[i]);
+        if (Str[i] & 128)
+          is7Bit = false;
+      }
+
+      // Emit the finished record.
+      Stream.EmitRecord(bitc::VST_CODE_ENTRY, NameVals, is7Bit ? V7Abbrev : 0);
+      NameVals.clear();
+
+      break;
+    }
+    default: break;
+    }
+  }
+
+  Stream.ExitBlock();
+}
+
+/// WriteTypeTable - Write out the type table for a module.
+static void WriteTypeTable(const llvm_2_9::ValueEnumerator &VE,
+                           BitstreamWriter &Stream) {
+  const llvm_2_9::ValueEnumerator::TypeList &TypeList = VE.getTypes();
+
+  Stream.EnterSubblock(TYPE_BLOCK_ID_OLD_3_0, 4 /*count from # abbrevs */);
+  SmallVector<uint64_t, 64> TypeVals;
+
+  uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1);
+
+  // Abbrev for TYPE_CODE_POINTER.
+  BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+  Abbv->Add(BitCodeAbbrevOp(0));  // Addrspace = 0
+  unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_FUNCTION.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION_OLD));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // isvararg
+  Abbv->Add(BitCodeAbbrevOp(0));  // FIXME: DEAD value, remove in LLVM 3.0
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+  unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv);
+
+
+  // Abbrev for TYPE_CODE_STRUCT.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(TYPE_CODE_STRUCT_OLD_3_0));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // ispacked
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+  unsigned StructAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_ARRAY.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // size
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+  unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Emit an entry count so the reader can reserve space.
+  TypeVals.push_back(TypeList.size());
+  Stream.EmitRecord(bitc::TYPE_CODE_NUMENTRY, TypeVals);
+  TypeVals.clear();
+
+  // Loop over all of the types, emitting each in turn.
+  for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
+    Type *T = TypeList[i];
+    int AbbrevToUse = 0;
+    unsigned Code = 0;
+
+    switch (T->getTypeID()) {
+    default: llvm_unreachable("Unknown type!");
+    case Type::VoidTyID:      Code = bitc::TYPE_CODE_VOID;   break;
+    case Type::FloatTyID:     Code = bitc::TYPE_CODE_FLOAT;  break;
+    case Type::DoubleTyID:    Code = bitc::TYPE_CODE_DOUBLE; break;
+    case Type::X86_FP80TyID:  Code = bitc::TYPE_CODE_X86_FP80; break;
+    case Type::FP128TyID:     Code = bitc::TYPE_CODE_FP128; break;
+    case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break;
+    case Type::LabelTyID:     Code = bitc::TYPE_CODE_LABEL;  break;
+    case Type::MetadataTyID:  Code = bitc::TYPE_CODE_METADATA; break;
+    case Type::X86_MMXTyID:   Code = bitc::TYPE_CODE_X86_MMX; break;
+    case Type::IntegerTyID:
+      // INTEGER: [width]
+      Code = bitc::TYPE_CODE_INTEGER;
+      TypeVals.push_back(cast<IntegerType>(T)->getBitWidth());
+      break;
+    case Type::PointerTyID: {
+      PointerType *PTy = cast<PointerType>(T);
+      // POINTER: [pointee type, address space]
+      Code = bitc::TYPE_CODE_POINTER;
+      TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
+      unsigned AddressSpace = PTy->getAddressSpace();
+      TypeVals.push_back(AddressSpace);
+      if (AddressSpace == 0) AbbrevToUse = PtrAbbrev;
+      break;
+    }
+    case Type::FunctionTyID: {
+      FunctionType *FT = cast<FunctionType>(T);
+      // FUNCTION: [isvararg, attrid, retty, paramty x N]
+      Code = bitc::TYPE_CODE_FUNCTION_OLD;
+      TypeVals.push_back(FT->isVarArg());
+      TypeVals.push_back(0);  // FIXME: DEAD: remove in llvm 3.0
+      TypeVals.push_back(VE.getTypeID(FT->getReturnType()));
+      for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i)
+        TypeVals.push_back(VE.getTypeID(FT->getParamType(i)));
+      AbbrevToUse = FunctionAbbrev;
+      break;
+    }
+    case Type::StructTyID: {
+      StructType *ST = cast<StructType>(T);
+      // STRUCT: [ispacked, eltty x N]
+      TypeVals.push_back(ST->isPacked());
+      // Output all of the element types.
+      for (StructType::element_iterator I = ST->element_begin(),
+           E = ST->element_end(); I != E; ++I)
+        TypeVals.push_back(VE.getTypeID(*I));
+      Code = TYPE_CODE_STRUCT_OLD_3_0;
+      AbbrevToUse = StructAbbrev;
+      break;
+    }
+    case Type::ArrayTyID: {
+      ArrayType *AT = cast<ArrayType>(T);
+      // ARRAY: [numelts, eltty]
+      Code = bitc::TYPE_CODE_ARRAY;
+      TypeVals.push_back(AT->getNumElements());
+      TypeVals.push_back(VE.getTypeID(AT->getElementType()));
+      AbbrevToUse = ArrayAbbrev;
+      break;
+    }
+    case Type::VectorTyID: {
+      VectorType *VT = cast<VectorType>(T);
+      // VECTOR [numelts, eltty]
+      Code = bitc::TYPE_CODE_VECTOR;
+      TypeVals.push_back(VT->getNumElements());
+      TypeVals.push_back(VE.getTypeID(VT->getElementType()));
+      break;
+    }
+    }
+
+    // Emit the finished record.
+    Stream.EmitRecord(Code, TypeVals, AbbrevToUse);
+    TypeVals.clear();
+  }
+
+  Stream.ExitBlock();
+
+  WriteTypeSymbolTable(VE, Stream);
+}
+
+static unsigned getEncodedLinkage(const GlobalValue &GV) {
+  switch (GV.getLinkage()) {
+  case GlobalValue::ExternalLinkage:
+    return 0;
+  case GlobalValue::WeakAnyLinkage:
+    return 1;
+  case GlobalValue::AppendingLinkage:
+    return 2;
+  case GlobalValue::InternalLinkage:
+    return 3;
+  case GlobalValue::LinkOnceAnyLinkage:
+    return 4;
+  case GlobalValue::ExternalWeakLinkage:
+    return 7;
+  case GlobalValue::CommonLinkage:
+    return 8;
+  case GlobalValue::PrivateLinkage:
+    return 9;
+  case GlobalValue::WeakODRLinkage:
+    return 10;
+  case GlobalValue::LinkOnceODRLinkage:
+    return 11;
+  case GlobalValue::AvailableExternallyLinkage:
+    return 12;
+  }
+  llvm_unreachable("Invalid linkage");
+}
+
+static unsigned getEncodedVisibility(const GlobalValue &GV) {
+  switch (GV.getVisibility()) {
+  case GlobalValue::DefaultVisibility:   return 0;
+  case GlobalValue::HiddenVisibility:    return 1;
+  case GlobalValue::ProtectedVisibility: return 2;
+  }
+  llvm_unreachable("Invalid visibility");
+}
+
+// Emit top-level description of module, including target triple, inline asm,
+// descriptors for global variables, and function prototype info.
+static void WriteModuleInfo(const Module *M,
+                            const llvm_2_9::ValueEnumerator &VE,
+                            BitstreamWriter &Stream) {
+  // Emit various pieces of data attached to a module.
+  if (!M->getTargetTriple().empty())
+    WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(),
+                      0/*TODO*/, Stream);
+  const std::string &DL = M->getDataLayoutStr();
+  if (!DL.empty())
+    WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/, Stream);
+  if (!M->getModuleInlineAsm().empty())
+    WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
+                      0/*TODO*/, Stream);
+
+  // Emit information about sections and GC, computing how many there are. Also
+  // compute the maximum alignment value.
+  std::map<std::string, unsigned> SectionMap;
+  std::map<std::string, unsigned> GCMap;
+  unsigned MaxAlignment = 0;
+  unsigned MaxGlobalType = 0;
+  for (const GlobalValue &GV : M->globals()) {
+    MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
+    MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getType()));
+    if (GV.hasSection()) {
+      // Give section names unique ID's.
+      unsigned &Entry = SectionMap[GV.getSection()];
+      if (!Entry) {
+        WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV.getSection(),
+                          0/*TODO*/, Stream);
+        Entry = SectionMap.size();
+      }
+    }
+  }
+  for (const Function &F : *M) {
+    MaxAlignment = std::max(MaxAlignment, F.getAlignment());
+    if (F.hasSection()) {
+      // Give section names unique ID's.
+      unsigned &Entry = SectionMap[F.getSection()];
+      if (!Entry) {
+        WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F.getSection(),
+                          0/*TODO*/, Stream);
+        Entry = SectionMap.size();
+      }
+    }
+    if (F.hasGC()) {
+      // Same for GC names.
+      unsigned &Entry = GCMap[F.getGC()];
+      if (!Entry) {
+        WriteStringRecord(bitc::MODULE_CODE_GCNAME, F.getGC(),
+                          0/*TODO*/, Stream);
+        Entry = GCMap.size();
+      }
+    }
+  }
+
+  // Emit abbrev for globals, now that we know # sections and max alignment.
+  unsigned SimpleGVarAbbrev = 0;
+  if (!M->global_empty()) {
+    // Add an abbrev for common globals with no visibility or thread localness.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_GLOBALVAR));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                              Log2_32_Ceil(MaxGlobalType+1)));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));      // Constant.
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));        // Initializer.
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));      // Linkage.
+    if (MaxAlignment == 0)                                      // Alignment.
+      Abbv->Add(BitCodeAbbrevOp(0));
+    else {
+      unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1;
+      Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                               Log2_32_Ceil(MaxEncAlignment+1)));
+    }
+    if (SectionMap.empty())                                    // Section.
+      Abbv->Add(BitCodeAbbrevOp(0));
+    else
+      Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                               Log2_32_Ceil(SectionMap.size()+1)));
+    // Don't bother emitting vis + thread local.
+    SimpleGVarAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  // Emit the global variable information.
+  SmallVector<unsigned, 64> Vals;
+  for (const GlobalVariable &GV : M->globals()) {
+    unsigned AbbrevToUse = 0;
+
+    // GLOBALVAR: [type, isconst, initid,
+    //             linkage, alignment, section, visibility, threadlocal,
+    //             unnamed_addr]
+    Vals.push_back(VE.getTypeID(GV.getType()));
+    Vals.push_back(GV.isConstant());
+    Vals.push_back(GV.isDeclaration() ? 0 :
+                   (VE.getValueID(GV.getInitializer()) + 1));
+    Vals.push_back(getEncodedLinkage(GV));
+    Vals.push_back(Log2_32(GV.getAlignment())+1);
+    Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
+    if (GV.isThreadLocal() ||
+        GV.getVisibility() != GlobalValue::DefaultVisibility ||
+        GV.hasUnnamedAddr()) {
+      Vals.push_back(getEncodedVisibility(GV));
+      Vals.push_back(GV.isThreadLocal());
+      Vals.push_back(GV.hasUnnamedAddr());
+    } else {
+      AbbrevToUse = SimpleGVarAbbrev;
+    }
+
+    Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse);
+    Vals.clear();
+  }
+
+  // Emit the function proto information.
+  for (const Function &F : *M) {
+    // FUNCTION:  [type, callingconv, isproto, paramattr,
+    //             linkage, alignment, section, visibility, gc, unnamed_addr]
+    Vals.push_back(VE.getTypeID(F.getType()));
+    Vals.push_back(F.getCallingConv());
+    Vals.push_back(F.isDeclaration());
+    Vals.push_back(getEncodedLinkage(F));
+    Vals.push_back(VE.getAttributeID(F.getAttributes()));
+    Vals.push_back(Log2_32(F.getAlignment())+1);
+    Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
+    Vals.push_back(getEncodedVisibility(F));
+    Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
+    Vals.push_back(F.hasUnnamedAddr());
+
+    unsigned AbbrevToUse = 0;
+    Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
+    Vals.clear();
+  }
+
+  // Emit the alias information.
+  for (const GlobalAlias &A : M->aliases()) {
+    Vals.push_back(VE.getTypeID(A.getType()));
+    Vals.push_back(VE.getValueID(A.getAliasee()));
+    Vals.push_back(getEncodedLinkage(A));
+    Vals.push_back(getEncodedVisibility(A));
+    unsigned AbbrevToUse = 0;
+    Stream.EmitRecord(bitc::MODULE_CODE_ALIAS_OLD, Vals, AbbrevToUse);
+    Vals.clear();
+  }
+}
+
+static uint64_t GetOptimizationFlags(const Value *V) {
+  uint64_t Flags = 0;
+
+  if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(V)) {
+    if (OBO->hasNoSignedWrap())
+      Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
+    if (OBO->hasNoUnsignedWrap())
+      Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
+  } else if (const auto *PEO = dyn_cast<PossiblyExactOperator>(V)) {
+    if (PEO->isExact())
+      Flags |= 1 << bitc::PEO_EXACT;
+  }
+
+  return Flags;
+}
+
+static void WriteValueAsMetadata(const ValueAsMetadata *MD,
+                                 const llvm_2_9::ValueEnumerator &VE,
+                                 BitstreamWriter &Stream,
+                                 SmallVectorImpl<uint64_t> &Record) {
+  // Mimic an MDNode with a value as one operand.
+  Value *V = MD->getValue();
+  Record.push_back(VE.getTypeID(V->getType()));
+  Record.push_back(VE.getValueID(V));
+  Stream.EmitRecord(METADATA_NODE_2_7, Record, 0);
+  Record.clear();
+}
+
+static void WriteMDTuple(const MDTuple *N, const llvm_2_9::ValueEnumerator &VE,
+                         BitstreamWriter &Stream,
+                         SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
+  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+    Metadata *MD = N->getOperand(i);
+    assert(!(MD && isa<LocalAsMetadata>(MD)) &&
+           "Unexpected function-local metadata");
+    if (!MD) {
+      // TODO(srhines): I don't believe this case can exist for RS.
+      Record.push_back(VE.getTypeID(llvm::Type::getVoidTy(N->getContext())));
+      Record.push_back(0);
+    } else if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+      Record.push_back(VE.getTypeID(MDC->getType()));
+      Record.push_back(VE.getValueID(MDC->getValue()));
+    } else {
+      Record.push_back(VE.getTypeID(
+          llvm::Type::getMetadataTy(N->getContext())));
+      Record.push_back(VE.getMetadataID(MD));
+    }
+  }
+  Stream.EmitRecord(METADATA_NODE_2_7, Record, Abbrev);
+  Record.clear();
+}
+
+/*static void WriteMDLocation(const MDLocation *N, const llvm_2_9::ValueEnumerator &VE,
+                            BitstreamWriter &Stream,
+                            SmallVectorImpl<uint64_t> &Record,
+                            unsigned Abbrev) {
+  Record.push_back(N->isDistinct());
+  Record.push_back(N->getLine());
+  Record.push_back(N->getColumn());
+  Record.push_back(VE.getMetadataID(N->getScope()));
+  Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt()));
+
+  Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
+  Record.clear();
+}
+
+static void WriteGenericDebugNode(const GenericDebugNode *,
+                                  const llvm_2_9::ValueEnumerator &, BitstreamWriter &,
+                                  SmallVectorImpl<uint64_t> &, unsigned) {
+  llvm_unreachable("unimplemented");
+}*/
+
+static void WriteModuleMetadata(const Module *M,
+                                const llvm_2_9::ValueEnumerator &VE,
+                                BitstreamWriter &Stream) {
+  const auto &MDs = VE.getMDs();
+  if (MDs.empty() && M->named_metadata_empty())
+    return;
+
+  // RenderScript files *ALWAYS* have metadata!
+  Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
+  unsigned MDSAbbrev = 0;
+  if (VE.hasMDString()) {
+    // Abbrev for METADATA_STRING.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    MDSAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  unsigned MDLocationAbbrev = 0;
+  if (VE.hasDILocation()) {
+    // TODO(srhines): Should be unreachable for RenderScript.
+    // Abbrev for METADATA_LOCATION.
+    //
+    // Assume the column is usually under 128, and always output the inlined-at
+    // location (it's never more expensive than building an array size 1).
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    MDLocationAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  unsigned NameAbbrev = 0;
+  if (!M->named_metadata_empty()) {
+    // Abbrev for METADATA_NAME.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_NAME));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    NameAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  unsigned MDTupleAbbrev = 0;
+  //unsigned GenericDebugNodeAbbrev = 0;
+  SmallVector<uint64_t, 64> Record;
+  for (const Metadata *MD : MDs) {
+    if (const MDNode *N = dyn_cast<MDNode>(MD)) {
+      switch (N->getMetadataID()) {
+      default:
+        llvm_unreachable("Invalid MDNode subclass");
+#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)
+#define HANDLE_MDNODE_LEAF(CLASS)                                              \
+  case Metadata::CLASS##Kind:                                                  \
+    Write##CLASS(cast<CLASS>(N), VE, Stream, Record, CLASS##Abbrev);           \
+    continue;
+#include "llvm/IR/Metadata.def"
+      }
+    }
+    if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+      WriteValueAsMetadata(MDC, VE, Stream, Record);
+      continue;
+    }
+    const MDString *MDS = cast<MDString>(MD);
+    // Code: [strchar x N]
+    Record.append(MDS->bytes_begin(), MDS->bytes_end());
+
+    // Emit the finished record.
+    Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
+    Record.clear();
+  }
+
+  // Write named metadata.
+  for (const NamedMDNode &NMD : M->named_metadata()) {
+    // Write name.
+    StringRef Str = NMD.getName();
+    Record.append(Str.bytes_begin(), Str.bytes_end());
+    Stream.EmitRecord(bitc::METADATA_NAME, Record, NameAbbrev);
+    Record.clear();
+
+    // Write named metadata operands.
+    for (const MDNode *N : NMD.operands())
+      Record.push_back(VE.getMetadataID(N));
+    Stream.EmitRecord(METADATA_NAMED_NODE_2_7, Record, 0);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void WriteFunctionLocalMetadata(const Function &F,
+                                       const llvm_2_9::ValueEnumerator &VE,
+                                       BitstreamWriter &Stream) {
+  bool StartedMetadataBlock = false;
+  SmallVector<uint64_t, 64> Record;
+  const SmallVectorImpl<const LocalAsMetadata *> &MDs =
+      VE.getFunctionLocalMDs();
+  for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+    assert(MDs[i] && "Expected valid function-local metadata");
+    if (!StartedMetadataBlock) {
+      Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+      StartedMetadataBlock = true;
+    }
+    WriteValueAsMetadata(MDs[i], VE, Stream, Record);
+  }
+
+  if (StartedMetadataBlock)
+    Stream.ExitBlock();
+}
+
+static void WriteMetadataAttachment(const Function &F,
+                                    const llvm_2_9::ValueEnumerator &VE,
+                                    BitstreamWriter &Stream) {
+  Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Write metadata attachments
+  // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
+  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+         I != E; ++I) {
+      MDs.clear();
+      I->getAllMetadataOtherThanDebugLoc(MDs);
+
+      // If no metadata, ignore instruction.
+      if (MDs.empty()) continue;
+
+      Record.push_back(VE.getInstructionID(&*I));
+
+      for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+        Record.push_back(MDs[i].first);
+        Record.push_back(VE.getMetadataID(MDs[i].second));
+      }
+      Stream.EmitRecord(METADATA_ATTACHMENT_2_7, Record, 0);
+      Record.clear();
+    }
+
+  Stream.ExitBlock();
+}
+
+static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
+  SmallVector<uint64_t, 64> Record;
+
+  // Write metadata kinds
+  // METADATA_KIND - [n x [id, name]]
+  SmallVector<StringRef, 4> Names;
+  M->getMDKindNames(Names);
+
+  if (Names.empty()) return;
+
+  Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
+  for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {
+    Record.push_back(MDKindID);
+    StringRef KName = Names[MDKindID];
+    Record.append(KName.begin(), KName.end());
+
+    Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void WriteConstants(unsigned FirstVal, unsigned LastVal,
+                           const llvm_2_9::ValueEnumerator &VE,
+                           BitstreamWriter &Stream, bool isGlobal) {
+  if (FirstVal == LastVal) return;
+
+  Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4);
+
+  unsigned AggregateAbbrev = 0;
+  unsigned String8Abbrev = 0;
+  unsigned CString7Abbrev = 0;
+  unsigned CString6Abbrev = 0;
+  // If this is a constant pool for the module, emit module-specific abbrevs.
+  if (isGlobal) {
+    // Abbrev for CST_CODE_AGGREGATE.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_AGGREGATE));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(LastVal+1)));
+    AggregateAbbrev = Stream.EmitAbbrev(Abbv);
+
+    // Abbrev for CST_CODE_STRING.
+    Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_STRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    String8Abbrev = Stream.EmitAbbrev(Abbv);
+    // Abbrev for CST_CODE_CSTRING.
+    Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
+    CString7Abbrev = Stream.EmitAbbrev(Abbv);
+    // Abbrev for CST_CODE_CSTRING.
+    Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    CString6Abbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  SmallVector<uint64_t, 64> Record;
+
+  const llvm_2_9::ValueEnumerator::ValueList &Vals = VE.getValues();
+  Type *LastTy = nullptr;
+  for (unsigned i = FirstVal; i != LastVal; ++i) {
+    const Value *V = Vals[i].first;
+    // If we need to switch types, do so now.
+    if (V->getType() != LastTy) {
+      LastTy = V->getType();
+      Record.push_back(VE.getTypeID(LastTy));
+      Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record,
+                        CONSTANTS_SETTYPE_ABBREV);
+      Record.clear();
+    }
+
+    if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
+      Record.push_back(unsigned(IA->hasSideEffects()) |
+                       unsigned(IA->isAlignStack()) << 1);
+
+      // Add the asm string.
+      const std::string &AsmStr = IA->getAsmString();
+      Record.push_back(AsmStr.size());
+      for (unsigned i = 0, e = AsmStr.size(); i != e; ++i)
+        Record.push_back(AsmStr[i]);
+
+      // Add the constraint string.
+      const std::string &ConstraintStr = IA->getConstraintString();
+      Record.push_back(ConstraintStr.size());
+      for (unsigned i = 0, e = ConstraintStr.size(); i != e; ++i)
+        Record.push_back(ConstraintStr[i]);
+      Stream.EmitRecord(bitc::CST_CODE_INLINEASM, Record);
+      Record.clear();
+      continue;
+    }
+    const Constant *C = cast<Constant>(V);
+    unsigned Code = -1U;
+    unsigned AbbrevToUse = 0;
+    if (C->isNullValue()) {
+      Code = bitc::CST_CODE_NULL;
+    } else if (isa<UndefValue>(C)) {
+      Code = bitc::CST_CODE_UNDEF;
+    } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
+      if (IV->getBitWidth() <= 64) {
+        uint64_t V = IV->getSExtValue();
+        if ((int64_t)V >= 0)
+          Record.push_back(V << 1);
+        else
+          Record.push_back((-V << 1) | 1);
+        Code = bitc::CST_CODE_INTEGER;
+        AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
+      } else {                             // Wide integers, > 64 bits in size.
+        // We have an arbitrary precision integer value to write whose
+        // bit width is > 64. However, in canonical unsigned integer
+        // format it is likely that the high bits are going to be zero.
+        // So, we only write the number of active words.
+        unsigned NWords = IV->getValue().getActiveWords();
+        const uint64_t *RawWords = IV->getValue().getRawData();
+        for (unsigned i = 0; i != NWords; ++i) {
+          int64_t V = RawWords[i];
+          if (V >= 0)
+            Record.push_back(V << 1);
+          else
+            Record.push_back((-V << 1) | 1);
+        }
+        Code = bitc::CST_CODE_WIDE_INTEGER;
+      }
+    } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
+      Code = bitc::CST_CODE_FLOAT;
+      Type *Ty = CFP->getType();
+      if (Ty->isFloatTy() || Ty->isDoubleTy()) {
+        Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
+      } else if (Ty->isX86_FP80Ty()) {
+        // api needed to prevent premature destruction
+        // bits are not in the same order as a normal i80 APInt, compensate.
+        APInt api = CFP->getValueAPF().bitcastToAPInt();
+        const uint64_t *p = api.getRawData();
+        Record.push_back((p[1] << 48) | (p[0] >> 16));
+        Record.push_back(p[0] & 0xffffLL);
+      } else if (Ty->isFP128Ty() || Ty->isPPC_FP128Ty()) {
+        APInt api = CFP->getValueAPF().bitcastToAPInt();
+        const uint64_t *p = api.getRawData();
+        Record.push_back(p[0]);
+        Record.push_back(p[1]);
+      } else {
+        assert (0 && "Unknown FP type!");
+      }
+    } else if (isa<ConstantDataSequential>(C) &&
+               cast<ConstantDataSequential>(C)->isString()) {
+      const ConstantDataSequential *Str = cast<ConstantDataSequential>(C);
+      // Emit constant strings specially.
+      unsigned NumElts = Str->getNumElements();
+      // If this is a null-terminated string, use the denser CSTRING encoding.
+      if (Str->isCString()) {
+        Code = bitc::CST_CODE_CSTRING;
+        --NumElts;  // Don't encode the null, which isn't allowed by char6.
+      } else {
+        Code = bitc::CST_CODE_STRING;
+        AbbrevToUse = String8Abbrev;
+      }
+      bool isCStr7 = Code == bitc::CST_CODE_CSTRING;
+      bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING;
+      for (unsigned i = 0; i != NumElts; ++i) {
+        unsigned char V = Str->getElementAsInteger(i);
+        Record.push_back(V);
+        isCStr7 &= (V & 128) == 0;
+        if (isCStrChar6)
+          isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
+      }
+
+      if (isCStrChar6)
+        AbbrevToUse = CString6Abbrev;
+      else if (isCStr7)
+        AbbrevToUse = CString7Abbrev;
+    } else if (const ConstantDataSequential *CDS =
+                  dyn_cast<ConstantDataSequential>(C)) {
+      // We must replace ConstantDataSequential's representation with the
+      // legacy ConstantArray/ConstantVector/ConstantStruct version.
+      // ValueEnumerator is similarly modified to mark the appropriate
+      // Constants as used (so they are emitted).
+      Code = bitc::CST_CODE_AGGREGATE;
+      for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+        Record.push_back(VE.getValueID(CDS->getElementAsConstant(i)));
+      AbbrevToUse = AggregateAbbrev;
+    } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) ||
+               isa<ConstantVector>(C)) {
+      Code = bitc::CST_CODE_AGGREGATE;
+      for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
+        Record.push_back(VE.getValueID(C->getOperand(i)));
+      AbbrevToUse = AggregateAbbrev;
+    } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+      switch (CE->getOpcode()) {
+      default:
+        if (Instruction::isCast(CE->getOpcode())) {
+          Code = bitc::CST_CODE_CE_CAST;
+          Record.push_back(GetEncodedCastOpcode(CE->getOpcode()));
+          Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+          Record.push_back(VE.getValueID(C->getOperand(0)));
+          AbbrevToUse = CONSTANTS_CE_CAST_Abbrev;
+        } else {
+          assert(CE->getNumOperands() == 2 && "Unknown constant expr!");
+          Code = bitc::CST_CODE_CE_BINOP;
+          Record.push_back(GetEncodedBinaryOpcode(CE->getOpcode()));
+          Record.push_back(VE.getValueID(C->getOperand(0)));
+          Record.push_back(VE.getValueID(C->getOperand(1)));
+          uint64_t Flags = GetOptimizationFlags(CE);
+          if (Flags != 0)
+            Record.push_back(Flags);
+        }
+        break;
+      case Instruction::GetElementPtr:
+        Code = bitc::CST_CODE_CE_GEP;
+        if (cast<GEPOperator>(C)->isInBounds())
+          Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
+        for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
+          Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
+          Record.push_back(VE.getValueID(C->getOperand(i)));
+        }
+        break;
+      case Instruction::Select:
+        Code = bitc::CST_CODE_CE_SELECT;
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(VE.getValueID(C->getOperand(2)));
+        break;
+      case Instruction::ExtractElement:
+        Code = bitc::CST_CODE_CE_EXTRACTELT;
+        Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        break;
+      case Instruction::InsertElement:
+        Code = bitc::CST_CODE_CE_INSERTELT;
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(VE.getValueID(C->getOperand(2)));
+        break;
+      case Instruction::ShuffleVector:
+        // If the return type and argument types are the same, this is a
+        // standard shufflevector instruction.  If the types are different,
+        // then the shuffle is widening or truncating the input vectors, and
+        // the argument type must also be encoded.
+        if (C->getType() == C->getOperand(0)->getType()) {
+          Code = bitc::CST_CODE_CE_SHUFFLEVEC;
+        } else {
+          Code = bitc::CST_CODE_CE_SHUFVEC_EX;
+          Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        }
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(VE.getValueID(C->getOperand(2)));
+        break;
+      case Instruction::ICmp:
+      case Instruction::FCmp:
+        Code = bitc::CST_CODE_CE_CMP;
+        Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(CE->getPredicate());
+        break;
+      }
+    } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
+      Code = bitc::CST_CODE_BLOCKADDRESS;
+      Record.push_back(VE.getTypeID(BA->getFunction()->getType()));
+      Record.push_back(VE.getValueID(BA->getFunction()));
+      Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock()));
+    } else {
+#ifndef NDEBUG
+      C->dump();
+#endif
+      llvm_unreachable("Unknown constant!");
+    }
+    Stream.EmitRecord(Code, Record, AbbrevToUse);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void WriteModuleConstants(const llvm_2_9::ValueEnumerator &VE,
+                                 BitstreamWriter &Stream) {
+  const llvm_2_9::ValueEnumerator::ValueList &Vals = VE.getValues();
+
+  // Find the first constant to emit, which is the first non-globalvalue value.
+  // We know globalvalues have been emitted by WriteModuleInfo.
+  for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+    if (!isa<GlobalValue>(Vals[i].first)) {
+      WriteConstants(i, Vals.size(), VE, Stream, true);
+      return;
+    }
+  }
+}
+
+/// PushValueAndType - The file has to encode both the value and type id for
+/// many values, because we need to know what type to create for forward
+/// references.  However, most operands are not forward references, so this type
+/// field is not needed.
+///
+/// This function adds V's value ID to Vals.  If the value ID is higher than the
+/// instruction ID, then it is a forward reference, and it also includes the
+/// type ID.
+static bool PushValueAndType(const Value *V, unsigned InstID,
+                             SmallVector<unsigned, 64> &Vals,
+                             llvm_2_9::ValueEnumerator &VE) {
+  unsigned ValID = VE.getValueID(V);
+  Vals.push_back(ValID);
+  if (ValID >= InstID) {
+    Vals.push_back(VE.getTypeID(V->getType()));
+    return true;
+  }
+  return false;
+}
+
+/// WriteInstruction - Emit an instruction to the specified stream.
+static void WriteInstruction(const Instruction &I, unsigned InstID,
+                             llvm_2_9::ValueEnumerator &VE,
+                             BitstreamWriter &Stream,
+                             SmallVector<unsigned, 64> &Vals) {
+  unsigned Code = 0;
+  unsigned AbbrevToUse = 0;
+  VE.setInstructionID(&I);
+  switch (I.getOpcode()) {
+  default:
+    if (Instruction::isCast(I.getOpcode())) {
+      Code = bitc::FUNC_CODE_INST_CAST;
+      if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+        AbbrevToUse = FUNCTION_INST_CAST_ABBREV;
+      Vals.push_back(VE.getTypeID(I.getType()));
+      Vals.push_back(GetEncodedCastOpcode(I.getOpcode()));
+    } else {
+      assert(isa<BinaryOperator>(I) && "Unknown instruction!");
+      Code = bitc::FUNC_CODE_INST_BINOP;
+      if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+        AbbrevToUse = FUNCTION_INST_BINOP_ABBREV;
+      Vals.push_back(VE.getValueID(I.getOperand(1)));
+      Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode()));
+      uint64_t Flags = GetOptimizationFlags(&I);
+      if (Flags != 0) {
+        if (AbbrevToUse == FUNCTION_INST_BINOP_ABBREV)
+          AbbrevToUse = FUNCTION_INST_BINOP_FLAGS_ABBREV;
+        Vals.push_back(Flags);
+      }
+    }
+    break;
+
+  case Instruction::GetElementPtr:
+    Code = bitc::FUNC_CODE_INST_GEP_OLD;
+    if (cast<GEPOperator>(&I)->isInBounds())
+      Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
+    for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
+      PushValueAndType(I.getOperand(i), InstID, Vals, VE);
+    break;
+  case Instruction::ExtractValue: {
+    Code = bitc::FUNC_CODE_INST_EXTRACTVAL;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    const ExtractValueInst *EVI = cast<ExtractValueInst>(&I);
+    for (const unsigned *i = EVI->idx_begin(), *e = EVI->idx_end(); i != e; ++i)
+      Vals.push_back(*i);
+    break;
+  }
+  case Instruction::InsertValue: {
+    Code = bitc::FUNC_CODE_INST_INSERTVAL;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    PushValueAndType(I.getOperand(1), InstID, Vals, VE);
+    const InsertValueInst *IVI = cast<InsertValueInst>(&I);
+    for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i)
+      Vals.push_back(*i);
+    break;
+  }
+  case Instruction::Select:
+    Code = bitc::FUNC_CODE_INST_VSELECT;
+    PushValueAndType(I.getOperand(1), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(2)));
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    break;
+  case Instruction::ExtractElement:
+    Code = bitc::FUNC_CODE_INST_EXTRACTELT;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    break;
+  case Instruction::InsertElement:
+    Code = bitc::FUNC_CODE_INST_INSERTELT;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    Vals.push_back(VE.getValueID(I.getOperand(2)));
+    break;
+  case Instruction::ShuffleVector:
+    Code = bitc::FUNC_CODE_INST_SHUFFLEVEC;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    Vals.push_back(VE.getValueID(I.getOperand(2)));
+    break;
+  case Instruction::ICmp:
+  case Instruction::FCmp:
+    // compare returning Int1Ty or vector of Int1Ty
+    Code = bitc::FUNC_CODE_INST_CMP2;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    Vals.push_back(cast<CmpInst>(I).getPredicate());
+    break;
+
+  case Instruction::Ret:
+    {
+      Code = bitc::FUNC_CODE_INST_RET;
+      unsigned NumOperands = I.getNumOperands();
+      if (NumOperands == 0)
+        AbbrevToUse = FUNCTION_INST_RET_VOID_ABBREV;
+      else if (NumOperands == 1) {
+        if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+          AbbrevToUse = FUNCTION_INST_RET_VAL_ABBREV;
+      } else {
+        for (unsigned i = 0, e = NumOperands; i != e; ++i)
+          PushValueAndType(I.getOperand(i), InstID, Vals, VE);
+      }
+    }
+    break;
+  case Instruction::Br:
+    {
+      Code = bitc::FUNC_CODE_INST_BR;
+      const BranchInst &II = cast<BranchInst>(I);
+      Vals.push_back(VE.getValueID(II.getSuccessor(0)));
+      if (II.isConditional()) {
+        Vals.push_back(VE.getValueID(II.getSuccessor(1)));
+        Vals.push_back(VE.getValueID(II.getCondition()));
+      }
+    }
+    break;
+  case Instruction::Switch:
+    {
+      Code = bitc::FUNC_CODE_INST_SWITCH;
+      const SwitchInst &SI = cast<SwitchInst>(I);
+      Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
+      Vals.push_back(VE.getValueID(SI.getCondition()));
+      Vals.push_back(VE.getValueID(SI.getDefaultDest()));
+      for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
+           i != e; ++i) {
+        Vals.push_back(VE.getValueID(i.getCaseValue()));
+        Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
+      }
+    }
+    break;
+  case Instruction::IndirectBr:
+    Code = bitc::FUNC_CODE_INST_INDIRECTBR;
+    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+    for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
+      Vals.push_back(VE.getValueID(I.getOperand(i)));
+    break;
+
+  case Instruction::Invoke: {
+    const InvokeInst *II = cast<InvokeInst>(&I);
+    const Value *Callee(II->getCalledValue());
+    PointerType *PTy = cast<PointerType>(Callee->getType());
+    FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+    Code = bitc::FUNC_CODE_INST_INVOKE;
+
+    Vals.push_back(VE.getAttributeID(II->getAttributes()));
+    Vals.push_back(II->getCallingConv());
+    Vals.push_back(VE.getValueID(II->getNormalDest()));
+    Vals.push_back(VE.getValueID(II->getUnwindDest()));
+    PushValueAndType(Callee, InstID, Vals, VE);
+
+    // Emit value #'s for the fixed parameters.
+    for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+      Vals.push_back(VE.getValueID(I.getOperand(i)));  // fixed param.
+
+    // Emit type/value pairs for varargs params.
+    if (FTy->isVarArg()) {
+      for (unsigned i = FTy->getNumParams(), e = I.getNumOperands()-3;
+           i != e; ++i)
+        PushValueAndType(I.getOperand(i), InstID, Vals, VE); // vararg
+    }
+    break;
+  }
+  case Instruction::Unreachable:
+    Code = bitc::FUNC_CODE_INST_UNREACHABLE;
+    AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV;
+    break;
+
+  case Instruction::PHI: {
+    const PHINode &PN = cast<PHINode>(I);
+    Code = bitc::FUNC_CODE_INST_PHI;
+    Vals.push_back(VE.getTypeID(PN.getType()));
+    for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+      Vals.push_back(VE.getValueID(PN.getIncomingValue(i)));
+      Vals.push_back(VE.getValueID(PN.getIncomingBlock(i)));
+    }
+    break;
+  }
+
+  case Instruction::Alloca:
+    Code = bitc::FUNC_CODE_INST_ALLOCA;
+    Vals.push_back(VE.getTypeID(I.getType()));
+    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+    Vals.push_back(VE.getValueID(I.getOperand(0))); // size.
+    Vals.push_back(Log2_32(cast<AllocaInst>(I).getAlignment())+1);
+    break;
+
+  case Instruction::Load:
+    Code = bitc::FUNC_CODE_INST_LOAD;
+    if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))  // ptr
+      AbbrevToUse = FUNCTION_INST_LOAD_ABBREV;
+
+    Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment())+1);
+    Vals.push_back(cast<LoadInst>(I).isVolatile());
+    break;
+  case Instruction::Store:
+    Code = bitc::FUNC_CODE_INST_STORE_OLD;
+    PushValueAndType(I.getOperand(1), InstID, Vals, VE);  // ptrty + ptr
+    Vals.push_back(VE.getValueID(I.getOperand(0)));       // val.
+    Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1);
+    Vals.push_back(cast<StoreInst>(I).isVolatile());
+    break;
+  case Instruction::Call: {
+    const CallInst &CI = cast<CallInst>(I);
+    PointerType *PTy = cast<PointerType>(CI.getCalledValue()->getType());
+    FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+
+    Code = FUNC_CODE_INST_CALL_2_7;
+
+    Vals.push_back(VE.getAttributeID(CI.getAttributes()));
+    Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()));
+    PushValueAndType(CI.getCalledValue(), InstID, Vals, VE);  // Callee
+
+    // Emit value #'s for the fixed parameters.
+    for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+      Vals.push_back(VE.getValueID(CI.getArgOperand(i)));  // fixed param.
+
+    // Emit type/value pairs for varargs params.
+    if (FTy->isVarArg()) {
+      for (unsigned i = FTy->getNumParams(), e = CI.getNumArgOperands();
+           i != e; ++i)
+        PushValueAndType(CI.getArgOperand(i), InstID, Vals, VE);  // varargs
+    }
+    break;
+  }
+  case Instruction::VAArg:
+    Code = bitc::FUNC_CODE_INST_VAARG;
+    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));   // valistty
+    Vals.push_back(VE.getValueID(I.getOperand(0))); // valist.
+    Vals.push_back(VE.getTypeID(I.getType())); // restype.
+    break;
+  }
+
+  Stream.EmitRecord(Code, Vals, AbbrevToUse);
+  Vals.clear();
+}
+
+// Emit names for globals/functions etc.
+static void WriteValueSymbolTable(const ValueSymbolTable &VST,
+                                  const llvm_2_9::ValueEnumerator &VE,
+                                  BitstreamWriter &Stream) {
+  if (VST.empty()) return;
+  Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4);
+
+  // FIXME: Set up the abbrev, we know how many values there are!
+  // FIXME: We know if the type names can use 7-bit ascii.
+  SmallVector<unsigned, 64> NameVals;
+
+  for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
+       SI != SE; ++SI) {
+
+    const ValueName &Name = *SI;
+
+    // Figure out the encoding to use for the name.
+    bool is7Bit = true;
+    bool isChar6 = true;
+    for (const char *C = Name.getKeyData(), *E = C+Name.getKeyLength();
+         C != E; ++C) {
+      if (isChar6)
+        isChar6 = BitCodeAbbrevOp::isChar6(*C);
+      if ((unsigned char)*C & 128) {
+        is7Bit = false;
+        break;  // don't bother scanning the rest.
+      }
+    }
+
+    unsigned AbbrevToUse = VST_ENTRY_8_ABBREV;
+
+    // VST_ENTRY:   [valueid, namechar x N]
+    // VST_BBENTRY: [bbid, namechar x N]
+    unsigned Code;
+    if (isa<BasicBlock>(SI->getValue())) {
+      Code = bitc::VST_CODE_BBENTRY;
+      if (isChar6)
+        AbbrevToUse = VST_BBENTRY_6_ABBREV;
+    } else {
+      Code = bitc::VST_CODE_ENTRY;
+      if (isChar6)
+        AbbrevToUse = VST_ENTRY_6_ABBREV;
+      else if (is7Bit)
+        AbbrevToUse = VST_ENTRY_7_ABBREV;
+    }
+
+    NameVals.push_back(VE.getValueID(SI->getValue()));
+    for (const char *P = Name.getKeyData(),
+         *E = Name.getKeyData()+Name.getKeyLength(); P != E; ++P)
+      NameVals.push_back((unsigned char)*P);
+
+    // Emit the finished record.
+    Stream.EmitRecord(Code, NameVals, AbbrevToUse);
+    NameVals.clear();
+  }
+  Stream.ExitBlock();
+}
+
+/// WriteFunction - Emit a function body to the module stream.
+static void WriteFunction(const Function &F, llvm_2_9::ValueEnumerator &VE,
+                          BitstreamWriter &Stream) {
+  Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4);
+  VE.incorporateFunction(F);
+
+  SmallVector<unsigned, 64> Vals;
+
+  // Emit the number of basic blocks, so the reader can create them ahead of
+  // time.
+  Vals.push_back(VE.getBasicBlocks().size());
+  Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals);
+  Vals.clear();
+
+  // If there are function-local constants, emit them now.
+  unsigned CstStart, CstEnd;
+  VE.getFunctionConstantRange(CstStart, CstEnd);
+  WriteConstants(CstStart, CstEnd, VE, Stream, false);
+
+  // If there is function-local metadata, emit it now.
+  WriteFunctionLocalMetadata(F, VE, Stream);
+
+  // Keep a running idea of what the instruction ID is.
+  unsigned InstID = CstEnd;
+
+  bool NeedsMetadataAttachment = false;
+
+  DILocation *LastDL = nullptr;;
+
+  // Finally, emit all the instructions, in order.
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+         I != E; ++I) {
+      WriteInstruction(*I, InstID, VE, Stream, Vals);
+
+      if (!I->getType()->isVoidTy())
+        ++InstID;
+
+      // If the instruction has metadata, write a metadata attachment later.
+      NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
+
+      // If the instruction has a debug location, emit it.
+      DILocation *DL = I->getDebugLoc();
+      if (!DL)
+        continue;
+
+      if (DL == LastDL) {
+        // Just repeat the same debug loc as last time.
+        Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
+        continue;
+      }
+
+      Vals.push_back(DL->getLine());
+      Vals.push_back(DL->getColumn());
+      Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
+      Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
+      Stream.EmitRecord(FUNC_CODE_DEBUG_LOC_2_7, Vals);
+      Vals.clear();
+
+      LastDL = DL;
+    }
+
+  // Emit names for all the instructions etc.
+  WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
+
+  if (NeedsMetadataAttachment)
+    WriteMetadataAttachment(F, VE, Stream);
+  VE.purgeFunction();
+  Stream.ExitBlock();
+}
+
+// Emit blockinfo, which defines the standard abbreviations etc.
+static void WriteBlockInfo(const llvm_2_9::ValueEnumerator &VE,
+                           BitstreamWriter &Stream) {
+  // We only want to emit block info records for blocks that have multiple
+  // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK.  Other
+  // blocks can defined their abbrevs inline.
+  Stream.EnterBlockInfoBlock(2);
+
+  { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_ENTRY_8_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // 7-bit fixed width VST_ENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_ENTRY_7_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // 6-bit char6 VST_ENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_ENTRY_6_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // 6-bit char6 VST_BBENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_BBENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_BBENTRY_6_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+
+
+  { // SETTYPE abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                              Log2_32_Ceil(VE.getTypes().size()+1)));
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_SETTYPE_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // INTEGER abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_INTEGER));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_INTEGER_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // CE_CAST abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CE_CAST));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));  // cast opc
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,       // typeid
+                              Log2_32_Ceil(VE.getTypes().size()+1)));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));    // value id
+
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_CE_CAST_Abbrev)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // NULL abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_NULL));
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_NULL_Abbrev)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  // FIXME: This should only use space for first class types!
+
+  { // INST_LOAD abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_LOAD_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_BINOP abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_BINOP_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_BINOP_FLAGS abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // flags
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_BINOP_FLAGS_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_CAST abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));    // OpVal
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,       // dest ty
+                              Log2_32_Ceil(VE.getTypes().size()+1)));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));  // opc
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_CAST_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // INST_RET abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_RET_VOID_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_RET abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ValID
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_RET_VAL_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_UNREACHABLE abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE));
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  Stream.ExitBlock();
+}
+
+/// WriteModule - Emit the specified module to the bitstream.
+static void WriteModule(const Module *M, BitstreamWriter &Stream) {
+  Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
+
+  // Emit the version number if it is non-zero.
+  if (CurVersion) {
+    SmallVector<unsigned, 1> Vals;
+    Vals.push_back(CurVersion);
+    Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals);
+  }
+
+  // Analyze the module, enumerating globals, functions, etc.
+  llvm_2_9::ValueEnumerator VE(*M);
+
+  // Emit blockinfo, which defines the standard abbreviations etc.
+  WriteBlockInfo(VE, Stream);
+
+  // Emit information about parameter attributes.
+  WriteAttributeTable(VE, Stream);
+
+  // Emit information describing all of the types in the module.
+  WriteTypeTable(VE, Stream);
+
+  // Emit top-level description of module, including target triple, inline asm,
+  // descriptors for global variables, and function prototype info.
+  WriteModuleInfo(M, VE, Stream);
+
+  // Emit constants.
+  WriteModuleConstants(VE, Stream);
+
+  // Emit metadata.
+  WriteModuleMetadata(M, VE, Stream);
+
+  // Emit function bodies.
+  for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)
+    if (!F->isDeclaration())
+      WriteFunction(*F, VE, Stream);
+
+  // Emit metadata.
+  WriteModuleMetadataStore(M, Stream);
+
+  // Emit names for globals/functions etc.
+  WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream);
+
+  Stream.ExitBlock();
+}
+
+/// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a
+/// header and trailer to make it compatible with the system archiver.  To do
+/// this we emit the following header, and then emit a trailer that pads the
+/// file out to be a multiple of 16 bytes.
+///
+/// struct bc_header {
+///   uint32_t Magic;         // 0x0B17C0DE
+///   uint32_t Version;       // Version, currently always 0.
+///   uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+///   uint32_t BitcodeSize;   // Size of traditional bitcode file.
+///   uint32_t CPUType;       // CPU specifier.
+///   ... potentially more later ...
+/// };
+enum {
+  DarwinBCSizeFieldOffset = 3*4, // Offset to bitcode_size.
+  DarwinBCHeaderSize = 5*4
+};
+
+static void WriteInt32ToBuffer(uint32_t Value, SmallVectorImpl<char> &Buffer,
+                               uint32_t &Position) {
+  Buffer[Position + 0] = (unsigned char) (Value >>  0);
+  Buffer[Position + 1] = (unsigned char) (Value >>  8);
+  Buffer[Position + 2] = (unsigned char) (Value >> 16);
+  Buffer[Position + 3] = (unsigned char) (Value >> 24);
+  Position += 4;
+}
+
+static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
+                                         const Triple &TT) {
+  unsigned CPUType = ~0U;
+
+  // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*,
+  // armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. The CPUType is a magic
+  // number from /usr/include/mach/machine.h.  It is ok to reproduce the
+  // specific constants here because they are implicitly part of the Darwin ABI.
+  enum {
+    DARWIN_CPU_ARCH_ABI64      = 0x01000000,
+    DARWIN_CPU_TYPE_X86        = 7,
+    DARWIN_CPU_TYPE_ARM        = 12,
+    DARWIN_CPU_TYPE_POWERPC    = 18
+  };
+
+  Triple::ArchType Arch = TT.getArch();
+  if (Arch == Triple::x86_64)
+    CPUType = DARWIN_CPU_TYPE_X86 | DARWIN_CPU_ARCH_ABI64;
+  else if (Arch == Triple::x86)
+    CPUType = DARWIN_CPU_TYPE_X86;
+  else if (Arch == Triple::ppc)
+    CPUType = DARWIN_CPU_TYPE_POWERPC;
+  else if (Arch == Triple::ppc64)
+    CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64;
+  else if (Arch == Triple::arm || Arch == Triple::thumb)
+    CPUType = DARWIN_CPU_TYPE_ARM;
+
+  // Traditional Bitcode starts after header.
+  assert(Buffer.size() >= DarwinBCHeaderSize &&
+         "Expected header size to be reserved");
+  unsigned BCOffset = DarwinBCHeaderSize;
+  unsigned BCSize = Buffer.size()-DarwinBCHeaderSize;
+
+  // Write the magic and version.
+  unsigned Position = 0;
+  WriteInt32ToBuffer(0x0B17C0DE , Buffer, Position);
+  WriteInt32ToBuffer(0          , Buffer, Position); // Version.
+  WriteInt32ToBuffer(BCOffset   , Buffer, Position);
+  WriteInt32ToBuffer(BCSize     , Buffer, Position);
+  WriteInt32ToBuffer(CPUType    , Buffer, Position);
+
+  // If the file is not a multiple of 16 bytes, insert dummy padding.
+  while (Buffer.size() & 15)
+    Buffer.push_back(0);
+}
+
+/// WriteBitcodeToFile - Write the specified module to the specified output
+/// stream.
+void llvm_2_9::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
+  SmallVector<char, 1024> Buffer;
+  Buffer.reserve(256*1024);
+
+  // If this is darwin or another generic macho target, reserve space for the
+  // header.
+  Triple TT(M->getTargetTriple());
+  if (TT.isOSDarwin())
+    Buffer.insert(Buffer.begin(), DarwinBCHeaderSize, 0);
+
+  // Emit the module into the buffer.
+  {
+    BitstreamWriter Stream(Buffer);
+
+    // Emit the file header.
+    Stream.Emit((unsigned)'B', 8);
+    Stream.Emit((unsigned)'C', 8);
+    Stream.Emit(0x0, 4);
+    Stream.Emit(0xC, 4);
+    Stream.Emit(0xE, 4);
+    Stream.Emit(0xD, 4);
+
+    // Emit the module.
+    WriteModule(M, Stream);
+  }
+
+  if (TT.isOSDarwin())
+    EmitDarwinBCHeaderAndTrailer(Buffer, TT);
+
+  // Write the generated bitstream to "Out".
+  Out.write((char*)&Buffer.front(), Buffer.size());
+}
diff --git a/slang/BitWriter_2_9/BitcodeWriterPass.cpp b/slang/BitWriter_2_9/BitcodeWriterPass.cpp
new file mode 100644
index 0000000..d43d690
--- /dev/null
+++ b/slang/BitWriter_2_9/BitcodeWriterPass.cpp
@@ -0,0 +1,46 @@
+//===--- Bitcode/Writer/BitcodeWriterPass.cpp - Bitcode Writer ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// BitcodeWriterPass implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReaderWriter_2_9.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+using namespace llvm;
+
+namespace {
+  class WriteBitcodePass : public ModulePass {
+    raw_ostream &OS; // raw_ostream to print on
+
+  public:
+    static char ID; // Pass identification, replacement for typeid
+    explicit WriteBitcodePass(raw_ostream &o)
+      : ModulePass(ID), OS(o) {}
+
+    const char *getPassName() const { return "Bitcode Writer"; }
+
+    bool runOnModule(Module &M) {
+      bool Changed = false;
+      llvm_2_9::WriteBitcodeToFile(&M, OS);
+      return Changed;
+    }
+  };
+}
+
+char WriteBitcodePass::ID = 0;
+
+/// createBitcodeWriterPass - Create and return a pass that writes the module
+/// to the specified ostream.
+llvm::ModulePass *llvm_2_9::createBitcodeWriterPass(llvm::raw_ostream &Str) {
+  return new WriteBitcodePass(Str);
+}
diff --git a/slang/BitWriter_2_9/CMakeLists.txt b/slang/BitWriter_2_9/CMakeLists.txt
new file mode 100644
index 0000000..f097b09
--- /dev/null
+++ b/slang/BitWriter_2_9/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_llvm_library(LLVMBitWriter
+  BitWriter.cpp
+  BitcodeWriter.cpp
+  BitcodeWriterPass.cpp
+  ValueEnumerator.cpp
+  )
diff --git a/slang/BitWriter_2_9/Makefile b/slang/BitWriter_2_9/Makefile
new file mode 100644
index 0000000..7b0bd72
--- /dev/null
+++ b/slang/BitWriter_2_9/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 = LLVMBitWriter
+BUILD_ARCHIVE = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/slang/BitWriter_2_9/ReaderWriter_2_9.h b/slang/BitWriter_2_9/ReaderWriter_2_9.h
new file mode 100644
index 0000000..997e9c7
--- /dev/null
+++ b/slang/BitWriter_2_9/ReaderWriter_2_9.h
@@ -0,0 +1,143 @@
+//===-- llvm/Bitcode/ReaderWriter.h - Bitcode reader/writers ----*- 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 interfaces to read and write LLVM bitcode files/streams.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_2_9_H
+#define LLVM_BITCODE_2_9_H
+
+#include <string>
+
+namespace llvm {
+  class Module;
+  class MemoryBuffer;
+  class ModulePass;
+  class BitstreamWriter;
+  class LLVMContext;
+  class raw_ostream;
+} // End llvm namespace
+
+namespace llvm_2_9 {
+  /// getLazyBitcodeModule - Read the header of the specified bitcode buffer
+  /// and prepare for lazy deserialization of function bodies.  If successful,
+  /// this takes ownership of 'buffer' and returns a non-null pointer.  On
+  /// error, this returns null, *does not* take ownership of Buffer, and fills
+  /// in *ErrMsg with an error description if ErrMsg is non-null.
+  llvm::Module *getLazyBitcodeModule(llvm::MemoryBuffer *Buffer,
+                               llvm::LLVMContext& Context,
+                               std::string *ErrMsg = 0);
+
+  /// getBitcodeTargetTriple - Read the header of the specified bitcode
+  /// buffer and extract just the triple information. If successful,
+  /// this returns a string and *does not* take ownership
+  /// of 'buffer'. On error, this returns "", and fills in *ErrMsg
+  /// if ErrMsg is non-null.
+  std::string getBitcodeTargetTriple(llvm::MemoryBuffer *Buffer,
+                                     llvm::LLVMContext& Context,
+                                     std::string *ErrMsg = 0);
+
+  /// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+  /// If an error occurs, this returns null and fills in *ErrMsg if it is
+  /// non-null.  This method *never* takes ownership of Buffer.
+  llvm::Module *ParseBitcodeFile(llvm::MemoryBuffer *Buffer, llvm::LLVMContext& Context,
+                           std::string *ErrMsg = 0);
+
+  /// WriteBitcodeToFile - Write the specified module to the specified
+  /// raw output stream.  For streams where it matters, the given stream
+  /// should be in "binary" mode.
+  void WriteBitcodeToFile(const llvm::Module *M, llvm::raw_ostream &Out);
+
+  /// createBitcodeWriterPass - Create and return a pass that writes the module
+  /// to the specified ostream.
+  llvm::ModulePass *createBitcodeWriterPass(llvm::raw_ostream &Str);
+
+
+  /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
+  /// for an LLVM IR bitcode wrapper.
+  ///
+  static inline bool isBitcodeWrapper(const unsigned char *BufPtr,
+                                      const unsigned char *BufEnd) {
+    // See if you can find the hidden message in the magic bytes :-).
+    // (Hint: it's a little-endian encoding.)
+    return BufPtr != BufEnd &&
+           BufPtr[0] == 0xDE &&
+           BufPtr[1] == 0xC0 &&
+           BufPtr[2] == 0x17 &&
+           BufPtr[3] == 0x0B;
+  }
+
+  /// isRawBitcode - Return true if the given bytes are the magic bytes for
+  /// raw LLVM IR bitcode (without a wrapper).
+  ///
+  static inline bool isRawBitcode(const unsigned char *BufPtr,
+                                  const unsigned char *BufEnd) {
+    // These bytes sort of have a hidden message, but it's not in
+    // little-endian this time, and it's a little redundant.
+    return BufPtr != BufEnd &&
+           BufPtr[0] == 'B' &&
+           BufPtr[1] == 'C' &&
+           BufPtr[2] == 0xc0 &&
+           BufPtr[3] == 0xde;
+  }
+
+  /// isBitcode - Return true if the given bytes are the magic bytes for
+  /// LLVM IR bitcode, either with or without a wrapper.
+  ///
+  static bool inline isBitcode(const unsigned char *BufPtr,
+                               const unsigned char *BufEnd) {
+    return isBitcodeWrapper(BufPtr, BufEnd) ||
+           isRawBitcode(BufPtr, BufEnd);
+  }
+
+  /// SkipBitcodeWrapperHeader - Some systems wrap bc files with a special
+  /// header for padding or other reasons.  The format of this header is:
+  ///
+  /// struct bc_header {
+  ///   uint32_t Magic;         // 0x0B17C0DE
+  ///   uint32_t Version;       // Version, currently always 0.
+  ///   uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+  ///   uint32_t BitcodeSize;   // Size of traditional bitcode file.
+  ///   ... potentially other gunk ...
+  /// };
+  ///
+  /// This function is called when we find a file with a matching magic number.
+  /// In this case, skip down to the subsection of the file that is actually a
+  /// BC file.
+  static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr,
+                                              unsigned char *&BufEnd) {
+    enum {
+      KnownHeaderSize = 4*4,  // Size of header we read.
+      OffsetField = 2*4,      // Offset in bytes to Offset field.
+      SizeField = 3*4         // Offset in bytes to Size field.
+    };
+
+    // Must contain the header!
+    if (BufEnd-BufPtr < KnownHeaderSize) return true;
+
+    unsigned Offset = ( BufPtr[OffsetField  ]        |
+                       (BufPtr[OffsetField+1] << 8)  |
+                       (BufPtr[OffsetField+2] << 16) |
+                       (BufPtr[OffsetField+3] << 24));
+    unsigned Size   = ( BufPtr[SizeField    ]        |
+                       (BufPtr[SizeField  +1] << 8)  |
+                       (BufPtr[SizeField  +2] << 16) |
+                       (BufPtr[SizeField  +3] << 24));
+
+    // Verify that Offset+Size fits in the file.
+    if (Offset+Size > unsigned(BufEnd-BufPtr))
+      return true;
+    BufPtr += Offset;
+    BufEnd = BufPtr+Size;
+    return false;
+  }
+} // End llvm_2_9 namespace
+
+#endif
diff --git a/slang/BitWriter_2_9/ValueEnumerator.cpp b/slang/BitWriter_2_9/ValueEnumerator.cpp
new file mode 100644
index 0000000..dedbedd
--- /dev/null
+++ b/slang/BitWriter_2_9/ValueEnumerator.cpp
@@ -0,0 +1,546 @@
+//===-- ValueEnumerator.cpp - Number values and types for bitcode writer --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ValueEnumerator class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ValueEnumerator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+using namespace llvm;
+
+namespace llvm_2_9 {
+
+static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
+  return V.first->getType()->isIntOrIntVectorTy();
+}
+
+/// ValueEnumerator - Enumerate module-level information.
+ValueEnumerator::ValueEnumerator(const llvm::Module &M)
+    : HasMDString(false), HasDILocation(false) {
+  // Enumerate the global variables.
+  for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I)
+    EnumerateValue(&*I);
+
+  // Enumerate the functions.
+  for (llvm::Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
+    EnumerateValue(&*I);
+    EnumerateAttributes(cast<Function>(I)->getAttributes());
+  }
+
+  // Enumerate the aliases.
+  for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
+       I != E; ++I)
+    EnumerateValue(&*I);
+
+  // Remember what is the cutoff between globalvalue's and other constants.
+  unsigned FirstConstant = Values.size();
+
+  // Enumerate the global variable initializers.
+  for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I)
+    if (I->hasInitializer())
+      EnumerateValue(I->getInitializer());
+
+  // Enumerate the aliasees.
+  for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
+       I != E; ++I)
+    EnumerateValue(I->getAliasee());
+
+  // Enumerate the metadata type.
+  //
+  // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode
+  // only encodes the metadata type when it's used as a value.
+  EnumerateType(Type::getMetadataTy(M.getContext()));
+
+  // Insert constants and metadata that are named at module level into the slot
+  // pool so that the module symbol table can refer to them...
+  EnumerateValueSymbolTable(M.getValueSymbolTable());
+  EnumerateNamedMetadata(M);
+
+  SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
+
+  // Enumerate types used by function bodies and argument lists.
+  for (const Function &F : M) {
+    for (const Argument &A : F.args())
+      EnumerateType(A.getType());
+
+    for (const BasicBlock &BB : F)
+      for (const Instruction &I : BB) {
+        for (const Use &Op : I.operands()) {
+          auto *MD = dyn_cast<MetadataAsValue>(&Op);
+          if (!MD) {
+            EnumerateOperandType(Op);
+            continue;
+          }
+
+          // Local metadata is enumerated during function-incorporation.
+          if (isa<LocalAsMetadata>(MD->getMetadata()))
+            continue;
+
+          EnumerateMetadata(MD->getMetadata());
+        }
+        EnumerateType(I.getType());
+        if (const CallInst *CI = dyn_cast<CallInst>(&I))
+          EnumerateAttributes(CI->getAttributes());
+        else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I))
+          EnumerateAttributes(II->getAttributes());
+
+        // Enumerate metadata attached with this instruction.
+        MDs.clear();
+        I.getAllMetadataOtherThanDebugLoc(MDs);
+        for (unsigned i = 0, e = MDs.size(); i != e; ++i)
+          EnumerateMetadata(MDs[i].second);
+
+        // Don't enumerate the location directly -- it has a special record
+        // type -- but enumerate its operands.
+        if (DILocation *L = I.getDebugLoc())
+          EnumerateMDNodeOperands(L);
+      }
+  }
+
+  // Optimize constant ordering.
+  OptimizeConstants(FirstConstant, Values.size());
+}
+
+unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
+  InstructionMapType::const_iterator I = InstructionMap.find(Inst);
+  assert(I != InstructionMap.end() && "Instruction is not mapped!");
+  return I->second;
+}
+
+void ValueEnumerator::setInstructionID(const Instruction *I) {
+  InstructionMap[I] = InstructionCount++;
+}
+
+unsigned ValueEnumerator::getValueID(const Value *V) const {
+  if (auto *MD = dyn_cast<MetadataAsValue>(V))
+    return getMetadataID(MD->getMetadata());
+
+  ValueMapType::const_iterator I = ValueMap.find(V);
+  assert(I != ValueMap.end() && "Value not in slotcalculator!");
+  return I->second-1;
+}
+
+void ValueEnumerator::dump() const {
+  print(dbgs(), ValueMap, "Default");
+  dbgs() << '\n';
+  print(dbgs(), MDValueMap, "MetaData");
+  dbgs() << '\n';
+}
+
+void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
+                            const char *Name) const {
+
+  OS << "Map Name: " << Name << "\n";
+  OS << "Size: " << Map.size() << "\n";
+  for (ValueMapType::const_iterator I = Map.begin(),
+         E = Map.end(); I != E; ++I) {
+
+    const Value *V = I->first;
+    if (V->hasName())
+      OS << "Value: " << V->getName();
+    else
+      OS << "Value: [null]\n";
+    V->dump();
+
+    OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
+    for (const Use &U : V->uses()) {
+      if (&U != &*V->use_begin())
+        OS << ",";
+      if(U->hasName())
+        OS << " " << U->getName();
+      else
+        OS << " [null]";
+
+    }
+    OS <<  "\n\n";
+  }
+}
+
+void ValueEnumerator::print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+                            const char *Name) const {
+
+  OS << "Map Name: " << Name << "\n";
+  OS << "Size: " << Map.size() << "\n";
+  for (auto I = Map.begin(), E = Map.end(); I != E; ++I) {
+    const llvm::Metadata *MD = I->first;
+    OS << "Metadata: slot = " << I->second << "\n";
+    MD->print(OS);
+  }
+}
+
+
+// Optimize constant ordering.
+namespace {
+  struct CstSortPredicate {
+    ValueEnumerator &VE;
+    explicit CstSortPredicate(ValueEnumerator &ve) : VE(ve) {}
+    bool operator()(const std::pair<const Value*, unsigned> &LHS,
+                    const std::pair<const Value*, unsigned> &RHS) {
+      // Sort by plane.
+      if (LHS.first->getType() != RHS.first->getType())
+        return VE.getTypeID(LHS.first->getType()) <
+               VE.getTypeID(RHS.first->getType());
+      // Then by frequency.
+      return LHS.second > RHS.second;
+    }
+  };
+}
+
+/// OptimizeConstants - Reorder constant pool for denser encoding.
+void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {
+  if (CstStart == CstEnd || CstStart+1 == CstEnd) return;
+
+  CstSortPredicate P(*this);
+  std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P);
+
+  // Ensure that integer and vector of integer constants are at the start of the
+  // constant pool.  This is important so that GEP structure indices come before
+  // gep constant exprs.
+  std::partition(Values.begin()+CstStart, Values.begin()+CstEnd,
+                 isIntOrIntVectorValue);
+
+  // Rebuild the modified portion of ValueMap.
+  for (; CstStart != CstEnd; ++CstStart)
+    ValueMap[Values[CstStart].first] = CstStart+1;
+}
+
+
+/// EnumerateValueSymbolTable - Insert all of the values in the specified symbol
+/// table into the values table.
+void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
+  for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end();
+       VI != VE; ++VI)
+    EnumerateValue(VI->getValue());
+}
+
+/// EnumerateNamedMetadata - Insert all of the values referenced by
+/// named metadata in the specified module.
+void ValueEnumerator::EnumerateNamedMetadata(const llvm::Module &M) {
+  for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
+                                             E = M.named_metadata_end();
+       I != E; ++I)
+    EnumerateNamedMDNode(&*I);
+}
+
+void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
+  for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i)
+    EnumerateMetadata(MD->getOperand(i));
+}
+
+/// EnumerateMDNodeOperands - Enumerate all non-function-local values
+/// and types referenced by the given MDNode.
+void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) {
+  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+    Metadata *MD = N->getOperand(i);
+    if (!MD)
+      continue;
+    assert(!isa<LocalAsMetadata>(MD) && "MDNodes cannot be function-local");
+    EnumerateMetadata(MD);
+  }
+}
+
+void ValueEnumerator::EnumerateMetadata(const llvm::Metadata *MD) {
+  assert(
+      (isa<MDNode>(MD) || isa<MDString>(MD) || isa<ConstantAsMetadata>(MD)) &&
+      "Invalid metadata kind");
+
+  // Insert a dummy ID to block the co-recursive call to
+  // EnumerateMDNodeOperands() from re-visiting MD in a cyclic graph.
+  //
+  // Return early if there's already an ID.
+  if (!MDValueMap.insert(std::make_pair(MD, 0)).second)
+    return;
+
+  // Visit operands first to minimize RAUW.
+  if (auto *N = dyn_cast<MDNode>(MD))
+    EnumerateMDNodeOperands(N);
+  else if (auto *C = dyn_cast<ConstantAsMetadata>(MD))
+    EnumerateValue(C->getValue());
+
+  HasMDString |= isa<MDString>(MD);
+  HasDILocation |= isa<DILocation>(MD);
+
+  // Replace the dummy ID inserted above with the correct one.  MDValueMap may
+  // have changed by inserting operands, so we need a fresh lookup here.
+  MDs.push_back(MD);
+  MDValueMap[MD] = MDs.size();
+}
+
+/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata
+/// information reachable from the metadata.
+void ValueEnumerator::EnumerateFunctionLocalMetadata(
+    const llvm::LocalAsMetadata *Local) {
+  // Check to see if it's already in!
+  unsigned &MDValueID = MDValueMap[Local];
+  if (MDValueID)
+    return;
+
+  MDs.push_back(Local);
+  MDValueID = MDs.size();
+
+  EnumerateValue(Local->getValue());
+
+  // Also, collect all function-local metadata for easy access.
+  FunctionLocalMDs.push_back(Local);
+}
+
+void ValueEnumerator::EnumerateValue(const Value *V) {
+  assert(!V->getType()->isVoidTy() && "Can't insert void values!");
+  assert(!isa<MetadataAsValue>(V) && "EnumerateValue doesn't handle Metadata!");
+
+  // Check to see if it's already in!
+  unsigned &ValueID = ValueMap[V];
+  if (ValueID) {
+    // Increment use count.
+    Values[ValueID-1].second++;
+    return;
+  }
+
+  // Enumerate the type of this value.
+  EnumerateType(V->getType());
+
+  if (const Constant *C = dyn_cast<Constant>(V)) {
+    if (isa<GlobalValue>(C)) {
+      // Initializers for globals are handled explicitly elsewhere.
+    } else if (C->getNumOperands()) {
+      // If a constant has operands, enumerate them.  This makes sure that if a
+      // constant has uses (for example an array of const ints), that they are
+      // inserted also.
+
+      // We prefer to enumerate them with values before we enumerate the user
+      // itself.  This makes it more likely that we can avoid forward references
+      // in the reader.  We know that there can be no cycles in the constants
+      // graph that don't go through a global variable.
+      for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
+           I != E; ++I)
+        if (!isa<BasicBlock>(*I)) // Don't enumerate BB operand to BlockAddress.
+          EnumerateValue(*I);
+
+      // Finally, add the value.  Doing this could make the ValueID reference be
+      // dangling, don't reuse it.
+      Values.push_back(std::make_pair(V, 1U));
+      ValueMap[V] = Values.size();
+      return;
+    } else if (const ConstantDataSequential *CDS =
+               dyn_cast<ConstantDataSequential>(C)) {
+      // For our legacy handling of the new ConstantDataSequential type, we
+      // need to enumerate the individual elements, as well as mark the
+      // outer constant as used.
+      for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+        EnumerateValue(CDS->getElementAsConstant(i));
+      Values.push_back(std::make_pair(V, 1U));
+      ValueMap[V] = Values.size();
+      return;
+    }
+  }
+
+  // Add the value.
+  Values.push_back(std::make_pair(V, 1U));
+  ValueID = Values.size();
+}
+
+
+void ValueEnumerator::EnumerateType(Type *Ty) {
+  unsigned *TypeID = &TypeMap[Ty];
+
+  // We've already seen this type.
+  if (*TypeID)
+    return;
+
+  // If it is a non-anonymous struct, mark the type as being visited so that we
+  // don't recursively visit it.  This is safe because we allow forward
+  // references of these in the bitcode reader.
+  if (StructType *STy = dyn_cast<StructType>(Ty))
+    if (!STy->isLiteral())
+      *TypeID = ~0U;
+
+  // Enumerate all of the subtypes before we enumerate this type.  This ensures
+  // that the type will be enumerated in an order that can be directly built.
+  for (Type *SubTy : Ty->subtypes())
+    EnumerateType(SubTy);
+
+  // Refresh the TypeID pointer in case the table rehashed.
+  TypeID = &TypeMap[Ty];
+
+  // Check to see if we got the pointer another way.  This can happen when
+  // enumerating recursive types that hit the base case deeper than they start.
+  //
+  // If this is actually a struct that we are treating as forward ref'able,
+  // then emit the definition now that all of its contents are available.
+  if (*TypeID && *TypeID != ~0U)
+    return;
+
+  // Add this type now that its contents are all happily enumerated.
+  Types.push_back(Ty);
+
+  *TypeID = Types.size();
+}
+
+// Enumerate the types for the specified value.  If the value is a constant,
+// walk through it, enumerating the types of the constant.
+void ValueEnumerator::EnumerateOperandType(const Value *V) {
+  EnumerateType(V->getType());
+
+  if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
+    assert(!isa<LocalAsMetadata>(MD->getMetadata()) &&
+           "Function-local metadata should be left for later");
+
+    EnumerateMetadata(MD->getMetadata());
+    return;
+  }
+
+  const Constant *C = dyn_cast<Constant>(V);
+  if (!C)
+    return;
+
+  // If this constant is already enumerated, ignore it, we know its type must
+  // be enumerated.
+  if (ValueMap.count(C))
+    return;
+
+  // This constant may have operands, make sure to enumerate the types in
+  // them.
+  for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
+    const Value *Op = C->getOperand(i);
+
+    // Don't enumerate basic blocks here, this happens as operands to
+    // blockaddress.
+    if (isa<BasicBlock>(Op))
+      continue;
+
+    EnumerateOperandType(Op);
+  }
+}
+
+void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
+  if (PAL.isEmpty()) return;  // null is always 0.
+
+  // Do a lookup.
+  unsigned &Entry = AttributeMap[PAL];
+  if (Entry == 0) {
+    // Never saw this before, add it.
+    Attribute.push_back(PAL);
+    Entry = Attribute.size();
+  }
+
+  // Do lookups for all attribute groups.
+  for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) {
+    AttributeSet AS = PAL.getSlotAttributes(i);
+    unsigned &Entry = AttributeGroupMap[AS];
+    if (Entry == 0) {
+      AttributeGroups.push_back(AS);
+      Entry = AttributeGroups.size();
+    }
+  }
+}
+
+void ValueEnumerator::incorporateFunction(const Function &F) {
+  InstructionCount = 0;
+  NumModuleValues = Values.size();
+  NumModuleMDs = MDs.size();
+
+  // Adding function arguments to the value table.
+  for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
+       I != E; ++I)
+    EnumerateValue(&*I);
+
+  FirstFuncConstantID = Values.size();
+
+  // Add all function-level constants to the value table.
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I)
+      for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
+           OI != E; ++OI) {
+        if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||
+            isa<InlineAsm>(*OI))
+          EnumerateValue(*OI);
+      }
+    BasicBlocks.push_back(&*BB);
+    ValueMap[&*BB] = BasicBlocks.size();
+  }
+
+  // Optimize the constant layout.
+  OptimizeConstants(FirstFuncConstantID, Values.size());
+
+  // Add the function's parameter attributes so they are available for use in
+  // the function's instruction.
+  EnumerateAttributes(F.getAttributes());
+
+  FirstInstID = Values.size();
+
+  SmallVector<llvm::LocalAsMetadata *, 8> FnLocalMDVector;
+  // Add all of the instructions.
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
+      for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
+           OI != E; ++OI) {
+        if (auto *MD = dyn_cast<llvm::MetadataAsValue>(&*OI))
+          if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata()))
+            // Enumerate metadata after the instructions they might refer to.
+            FnLocalMDVector.push_back(Local);
+      }
+
+      if (!I->getType()->isVoidTy())
+        EnumerateValue(&*I);
+    }
+  }
+
+  // Add all of the function-local metadata.
+  for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i)
+    EnumerateFunctionLocalMetadata(FnLocalMDVector[i]);
+}
+
+void ValueEnumerator::purgeFunction() {
+  /// Remove purged values from the ValueMap.
+  for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i)
+    ValueMap.erase(Values[i].first);
+  for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i)
+    MDValueMap.erase(MDs[i]);
+  for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
+    ValueMap.erase(BasicBlocks[i]);
+
+  Values.resize(NumModuleValues);
+  MDs.resize(NumModuleMDs);
+  BasicBlocks.clear();
+  FunctionLocalMDs.clear();
+}
+
+static void IncorporateFunctionInfoGlobalBBIDs(const Function *F,
+                                 DenseMap<const BasicBlock*, unsigned> &IDMap) {
+  unsigned Counter = 0;
+  for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+    IDMap[&*BB] = ++Counter;
+}
+
+/// getGlobalBasicBlockID - This returns the function-specific ID for the
+/// specified basic block.  This is relatively expensive information, so it
+/// should only be used by rare constructs such as address-of-label.
+unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const {
+  unsigned &Idx = GlobalBasicBlockIDs[BB];
+  if (Idx != 0)
+    return Idx-1;
+
+  IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs);
+  return getGlobalBasicBlockID(BB);
+}
+
+} // end llvm_2_9 namespace
diff --git a/slang/BitWriter_2_9/ValueEnumerator.h b/slang/BitWriter_2_9/ValueEnumerator.h
new file mode 100644
index 0000000..1812cd8
--- /dev/null
+++ b/slang/BitWriter_2_9/ValueEnumerator.h
@@ -0,0 +1,195 @@
+//===-- Bitcode/Writer/ValueEnumerator.h - Number values --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class gives values and types Unique ID's.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef VALUE_ENUMERATOR_H
+#define VALUE_ENUMERATOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Attributes.h"
+#include <vector>
+
+namespace llvm {
+
+class Type;
+class Value;
+class Instruction;
+class BasicBlock;
+class Function;
+class Module;
+class Metadata;
+class LocalAsMetadata;
+class MDNode;
+class NamedMDNode;
+class AttributeSet;
+class ValueSymbolTable;
+class MDSymbolTable;
+class raw_ostream;
+
+}  // end llvm namespace
+
+namespace llvm_2_9 {
+
+class ValueEnumerator {
+public:
+  typedef std::vector<llvm::Type*> TypeList;
+
+  // For each value, we remember its Value* and occurrence frequency.
+  typedef std::vector<std::pair<const llvm::Value*, unsigned> > ValueList;
+private:
+  typedef llvm::DenseMap<llvm::Type*, unsigned> TypeMapType;
+  TypeMapType TypeMap;
+  TypeList Types;
+
+  typedef llvm::DenseMap<const llvm::Value*, unsigned> ValueMapType;
+  ValueMapType ValueMap;
+  ValueList Values;
+
+
+  std::vector<const llvm::Metadata *> MDs;
+  llvm::SmallVector<const llvm::LocalAsMetadata *, 8> FunctionLocalMDs;
+  typedef llvm::DenseMap<const llvm::Metadata *, unsigned> MetadataMapType;
+  MetadataMapType MDValueMap;
+  bool HasMDString;
+  bool HasDILocation;
+
+  typedef llvm::DenseMap<llvm::AttributeSet, unsigned> AttributeGroupMapType;
+  AttributeGroupMapType AttributeGroupMap;
+  std::vector<llvm::AttributeSet> AttributeGroups;
+
+  typedef llvm::DenseMap<llvm::AttributeSet, unsigned> AttributeMapType;
+  AttributeMapType AttributeMap;
+  std::vector<llvm::AttributeSet> Attribute;
+
+  /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
+  /// the "getGlobalBasicBlockID" method.
+  mutable llvm::DenseMap<const llvm::BasicBlock*, unsigned> GlobalBasicBlockIDs;
+
+  typedef llvm::DenseMap<const llvm::Instruction*, unsigned> InstructionMapType;
+  InstructionMapType InstructionMap;
+  unsigned InstructionCount;
+
+  /// BasicBlocks - This contains all the basic blocks for the currently
+  /// incorporated function.  Their reverse mapping is stored in ValueMap.
+  std::vector<const llvm::BasicBlock*> BasicBlocks;
+
+  /// When a function is incorporated, this is the size of the Values list
+  /// before incorporation.
+  unsigned NumModuleValues;
+
+  /// When a function is incorporated, this is the size of the MDValues list
+  /// before incorporation.
+  unsigned NumModuleMDs;
+
+  unsigned FirstFuncConstantID;
+  unsigned FirstInstID;
+
+  ValueEnumerator(const ValueEnumerator &) = delete;
+  void operator=(const ValueEnumerator &) = delete;
+public:
+  explicit ValueEnumerator(const llvm::Module &M);
+
+  void dump() const;
+  void print(llvm::raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
+  void print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+             const char *Name) const;
+
+  unsigned getValueID(const llvm::Value *V) const;
+  unsigned getMetadataID(const llvm::Metadata *MD) const {
+    auto ID = getMetadataOrNullID(MD);
+    assert(ID != 0 && "Metadata not in slotcalculator!");
+    return ID - 1;
+  }
+  unsigned getMetadataOrNullID(const llvm::Metadata *MD) const {
+    return MDValueMap.lookup(MD);
+  }
+
+  bool hasMDString() const { return HasMDString; }
+  bool hasDILocation() const { return HasDILocation; }
+
+  unsigned getTypeID(llvm::Type *T) const {
+    TypeMapType::const_iterator I = TypeMap.find(T);
+    assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
+    return I->second-1;
+  }
+
+  unsigned getInstructionID(const llvm::Instruction *I) const;
+  void setInstructionID(const llvm::Instruction *I);
+
+  unsigned getAttributeID(llvm::AttributeSet PAL) const {
+    if (PAL.isEmpty()) return 0;  // Null maps to zero.
+    AttributeMapType::const_iterator I = AttributeMap.find(PAL);
+    assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!");
+    return I->second;
+  }
+
+  unsigned getAttributeGroupID(llvm::AttributeSet PAL) const {
+    if (PAL.isEmpty()) return 0;  // Null maps to zero.
+    AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL);
+    assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
+    return I->second;
+  }
+
+  /// getFunctionConstantRange - Return the range of values that corresponds to
+  /// function-local constants.
+  void getFunctionConstantRange(unsigned &Start, unsigned &End) const {
+    Start = FirstFuncConstantID;
+    End = FirstInstID;
+  }
+
+  const ValueList &getValues() const { return Values; }
+  const std::vector<const llvm::Metadata *> &getMDs() const { return MDs; }
+  const llvm::SmallVectorImpl<const llvm::LocalAsMetadata *> &getFunctionLocalMDs() const {
+    return FunctionLocalMDs;
+  }
+  const TypeList &getTypes() const { return Types; }
+  const std::vector<const llvm::BasicBlock*> &getBasicBlocks() const {
+    return BasicBlocks;
+  }
+  const std::vector<llvm::AttributeSet> &getAttributes() const {
+    return Attribute;
+  }
+  const std::vector<llvm::AttributeSet> &getAttributeGroups() const {
+    return AttributeGroups;
+  }
+
+  /// getGlobalBasicBlockID - This returns the function-specific ID for the
+  /// specified basic block.  This is relatively expensive information, so it
+  /// should only be used by rare constructs such as address-of-label.
+  unsigned getGlobalBasicBlockID(const llvm::BasicBlock *BB) const;
+
+  /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
+  /// use these two methods to get its data into the ValueEnumerator!
+  ///
+  void incorporateFunction(const llvm::Function &F);
+  void purgeFunction();
+
+private:
+  void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
+
+  void EnumerateMDNodeOperands(const llvm::MDNode *N);
+  void EnumerateMetadata(const llvm::Metadata *MD);
+  void EnumerateFunctionLocalMetadata(const llvm::LocalAsMetadata *Local);
+  void EnumerateNamedMDNode(const llvm::NamedMDNode *NMD);
+  void EnumerateValue(const llvm::Value *V);
+  void EnumerateType(llvm::Type *T);
+  void EnumerateOperandType(const llvm::Value *V);
+  void EnumerateAttributes(llvm::AttributeSet PAL);
+
+  void EnumerateValueSymbolTable(const llvm::ValueSymbolTable &ST);
+  void EnumerateNamedMetadata(const llvm::Module &M);
+};
+
+}  // end llvm_2_9 namespace
+
+#endif
diff --git a/slang/BitWriter_2_9_func/Android.mk b/slang/BitWriter_2_9_func/Android.mk
new file mode 100644
index 0000000..a33313a
--- /dev/null
+++ b/slang/BitWriter_2_9_func/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH:= $(call my-dir)
+
+LLVM_ROOT_PATH := $(LOCAL_PATH)/../../../../external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+
+bitcode_writer_2_9_func_SRC_FILES :=	\
+	BitcodeWriter.cpp	\
+	BitcodeWriterPass.cpp	\
+	ValueEnumerator.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS += $(local_cflags_for_slang)
+LOCAL_C_INCLUDES += frameworks/compile/slang
+
+LOCAL_SRC_FILES := $(bitcode_writer_2_9_func_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMBitWriter_2_9_func
+
+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)
+
diff --git a/slang/BitWriter_2_9_func/BitcodeWriter.cpp b/slang/BitWriter_2_9_func/BitcodeWriter.cpp
new file mode 100644
index 0000000..4ef7ac2
--- /dev/null
+++ b/slang/BitWriter_2_9_func/BitcodeWriter.cpp
@@ -0,0 +1,1803 @@
+//===--- Bitcode/Writer/BitcodeWriter.cpp - Bitcode Writer ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Bitcode writer implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReaderWriter_2_9_func.h"
+#include "legacy_bitcode.h"
+#include "ValueEnumerator.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cctype>
+#include <map>
+using namespace llvm;
+
+/// These are manifest constants used by the bitcode writer. They do not need to
+/// be kept in sync with the reader, but need to be consistent within this file.
+enum {
+  CurVersion = 0,
+
+  // VALUE_SYMTAB_BLOCK abbrev id's.
+  VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+  VST_ENTRY_7_ABBREV,
+  VST_ENTRY_6_ABBREV,
+  VST_BBENTRY_6_ABBREV,
+
+  // CONSTANTS_BLOCK abbrev id's.
+  CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+  CONSTANTS_INTEGER_ABBREV,
+  CONSTANTS_CE_CAST_Abbrev,
+  CONSTANTS_NULL_Abbrev,
+
+  // FUNCTION_BLOCK abbrev id's.
+  FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+  FUNCTION_INST_BINOP_ABBREV,
+  FUNCTION_INST_BINOP_FLAGS_ABBREV,
+  FUNCTION_INST_CAST_ABBREV,
+  FUNCTION_INST_RET_VOID_ABBREV,
+  FUNCTION_INST_RET_VAL_ABBREV,
+  FUNCTION_INST_UNREACHABLE_ABBREV
+};
+
+static unsigned GetEncodedCastOpcode(unsigned Opcode) {
+  switch (Opcode) {
+  default: llvm_unreachable("Unknown cast instruction!");
+  case Instruction::Trunc   : return bitc::CAST_TRUNC;
+  case Instruction::ZExt    : return bitc::CAST_ZEXT;
+  case Instruction::SExt    : return bitc::CAST_SEXT;
+  case Instruction::FPToUI  : return bitc::CAST_FPTOUI;
+  case Instruction::FPToSI  : return bitc::CAST_FPTOSI;
+  case Instruction::UIToFP  : return bitc::CAST_UITOFP;
+  case Instruction::SIToFP  : return bitc::CAST_SITOFP;
+  case Instruction::FPTrunc : return bitc::CAST_FPTRUNC;
+  case Instruction::FPExt   : return bitc::CAST_FPEXT;
+  case Instruction::PtrToInt: return bitc::CAST_PTRTOINT;
+  case Instruction::IntToPtr: return bitc::CAST_INTTOPTR;
+  case Instruction::BitCast : return bitc::CAST_BITCAST;
+  }
+}
+
+static unsigned GetEncodedBinaryOpcode(unsigned Opcode) {
+  switch (Opcode) {
+  default: llvm_unreachable("Unknown binary instruction!");
+  case Instruction::Add:
+  case Instruction::FAdd: return bitc::BINOP_ADD;
+  case Instruction::Sub:
+  case Instruction::FSub: return bitc::BINOP_SUB;
+  case Instruction::Mul:
+  case Instruction::FMul: return bitc::BINOP_MUL;
+  case Instruction::UDiv: return bitc::BINOP_UDIV;
+  case Instruction::FDiv:
+  case Instruction::SDiv: return bitc::BINOP_SDIV;
+  case Instruction::URem: return bitc::BINOP_UREM;
+  case Instruction::FRem:
+  case Instruction::SRem: return bitc::BINOP_SREM;
+  case Instruction::Shl:  return bitc::BINOP_SHL;
+  case Instruction::LShr: return bitc::BINOP_LSHR;
+  case Instruction::AShr: return bitc::BINOP_ASHR;
+  case Instruction::And:  return bitc::BINOP_AND;
+  case Instruction::Or:   return bitc::BINOP_OR;
+  case Instruction::Xor:  return bitc::BINOP_XOR;
+  }
+}
+
+static unsigned GetEncodedRMWOperation(AtomicRMWInst::BinOp Op) {
+  switch (Op) {
+  default: llvm_unreachable("Unknown RMW operation!");
+  case AtomicRMWInst::Xchg: return bitc::RMW_XCHG;
+  case AtomicRMWInst::Add: return bitc::RMW_ADD;
+  case AtomicRMWInst::Sub: return bitc::RMW_SUB;
+  case AtomicRMWInst::And: return bitc::RMW_AND;
+  case AtomicRMWInst::Nand: return bitc::RMW_NAND;
+  case AtomicRMWInst::Or: return bitc::RMW_OR;
+  case AtomicRMWInst::Xor: return bitc::RMW_XOR;
+  case AtomicRMWInst::Max: return bitc::RMW_MAX;
+  case AtomicRMWInst::Min: return bitc::RMW_MIN;
+  case AtomicRMWInst::UMax: return bitc::RMW_UMAX;
+  case AtomicRMWInst::UMin: return bitc::RMW_UMIN;
+  }
+}
+
+static unsigned GetEncodedOrdering(AtomicOrdering Ordering) {
+  switch (Ordering) {
+  default: llvm_unreachable("Unknown atomic ordering");
+  case NotAtomic: return bitc::ORDERING_NOTATOMIC;
+  case Unordered: return bitc::ORDERING_UNORDERED;
+  case Monotonic: return bitc::ORDERING_MONOTONIC;
+  case Acquire: return bitc::ORDERING_ACQUIRE;
+  case Release: return bitc::ORDERING_RELEASE;
+  case AcquireRelease: return bitc::ORDERING_ACQREL;
+  case SequentiallyConsistent: return bitc::ORDERING_SEQCST;
+  }
+}
+
+static unsigned GetEncodedSynchScope(SynchronizationScope SynchScope) {
+  switch (SynchScope) {
+  default: llvm_unreachable("Unknown synchronization scope");
+  case SingleThread: return bitc::SYNCHSCOPE_SINGLETHREAD;
+  case CrossThread: return bitc::SYNCHSCOPE_CROSSTHREAD;
+  }
+}
+
+static void WriteStringRecord(unsigned Code, StringRef Str,
+                              unsigned AbbrevToUse, BitstreamWriter &Stream) {
+  SmallVector<unsigned, 64> Vals;
+
+  // Code: [strchar x N]
+  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+    if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i]))
+      AbbrevToUse = 0;
+    Vals.push_back(Str[i]);
+  }
+
+  // Emit the finished record.
+  Stream.EmitRecord(Code, Vals, AbbrevToUse);
+}
+
+// Emit information about parameter attributes.
+static void WriteAttributeTable(const llvm_2_9_func::ValueEnumerator &VE,
+                                BitstreamWriter &Stream) {
+  const std::vector<AttributeSet> &Attrs = VE.getAttributes();
+  if (Attrs.empty()) return;
+
+  Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
+
+  SmallVector<uint64_t, 64> Record;
+  for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
+    const AttributeSet &A = Attrs[i];
+    for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) {
+      Record.push_back(A.getSlotIndex(i));
+      Record.push_back(encodeLLVMAttributesForBitcode(A, A.getSlotIndex(i)));
+    }
+
+    // This needs to use the 3.2 entry type
+    Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY_OLD, Record);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+/// WriteTypeTable - Write out the type table for a module.
+static void WriteTypeTable(const llvm_2_9_func::ValueEnumerator &VE,
+                           BitstreamWriter &Stream) {
+  const llvm_2_9_func::ValueEnumerator::TypeList &TypeList = VE.getTypes();
+
+  Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */);
+  SmallVector<uint64_t, 64> TypeVals;
+
+  uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1);
+
+  // Abbrev for TYPE_CODE_POINTER.
+  BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+  Abbv->Add(BitCodeAbbrevOp(0));  // Addrspace = 0
+  unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_FUNCTION.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION_OLD));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // isvararg
+  Abbv->Add(BitCodeAbbrevOp(0));  // FIXME: DEAD value, remove in LLVM 3.0
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+  unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_STRUCT_ANON.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // ispacked
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+  unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_STRUCT_NAME.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+  unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_STRUCT_NAMED.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // ispacked
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+  unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_ARRAY.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // size
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+  unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Emit an entry count so the reader can reserve space.
+  TypeVals.push_back(TypeList.size());
+  Stream.EmitRecord(bitc::TYPE_CODE_NUMENTRY, TypeVals);
+  TypeVals.clear();
+
+  // Loop over all of the types, emitting each in turn.
+  for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
+    Type *T = TypeList[i];
+    int AbbrevToUse = 0;
+    unsigned Code = 0;
+
+    switch (T->getTypeID()) {
+    default: llvm_unreachable("Unknown type!");
+    case Type::VoidTyID:      Code = bitc::TYPE_CODE_VOID;   break;
+    case Type::FloatTyID:     Code = bitc::TYPE_CODE_FLOAT;  break;
+    case Type::DoubleTyID:    Code = bitc::TYPE_CODE_DOUBLE; break;
+    case Type::X86_FP80TyID:  Code = bitc::TYPE_CODE_X86_FP80; break;
+    case Type::FP128TyID:     Code = bitc::TYPE_CODE_FP128; break;
+    case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break;
+    case Type::LabelTyID:     Code = bitc::TYPE_CODE_LABEL;  break;
+    case Type::MetadataTyID:  Code = bitc::TYPE_CODE_METADATA; break;
+    case Type::X86_MMXTyID:   Code = bitc::TYPE_CODE_X86_MMX; break;
+    case Type::IntegerTyID:
+      // INTEGER: [width]
+      Code = bitc::TYPE_CODE_INTEGER;
+      TypeVals.push_back(cast<IntegerType>(T)->getBitWidth());
+      break;
+    case Type::PointerTyID: {
+      PointerType *PTy = cast<PointerType>(T);
+      // POINTER: [pointee type, address space]
+      Code = bitc::TYPE_CODE_POINTER;
+      TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
+      unsigned AddressSpace = PTy->getAddressSpace();
+      TypeVals.push_back(AddressSpace);
+      if (AddressSpace == 0) AbbrevToUse = PtrAbbrev;
+      break;
+    }
+    case Type::FunctionTyID: {
+      FunctionType *FT = cast<FunctionType>(T);
+      // FUNCTION: [isvararg, attrid, retty, paramty x N]
+      Code = bitc::TYPE_CODE_FUNCTION_OLD;
+      TypeVals.push_back(FT->isVarArg());
+      TypeVals.push_back(0);  // FIXME: DEAD: remove in llvm 3.0
+      TypeVals.push_back(VE.getTypeID(FT->getReturnType()));
+      for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i)
+        TypeVals.push_back(VE.getTypeID(FT->getParamType(i)));
+      AbbrevToUse = FunctionAbbrev;
+      break;
+    }
+    case Type::StructTyID: {
+      StructType *ST = cast<StructType>(T);
+      // STRUCT: [ispacked, eltty x N]
+      TypeVals.push_back(ST->isPacked());
+      // Output all of the element types.
+      for (StructType::element_iterator I = ST->element_begin(),
+           E = ST->element_end(); I != E; ++I)
+        TypeVals.push_back(VE.getTypeID(*I));
+
+      if (ST->isLiteral()) {
+        Code = bitc::TYPE_CODE_STRUCT_ANON;
+        AbbrevToUse = StructAnonAbbrev;
+      } else {
+        if (ST->isOpaque()) {
+          Code = bitc::TYPE_CODE_OPAQUE;
+        } else {
+          Code = bitc::TYPE_CODE_STRUCT_NAMED;
+          AbbrevToUse = StructNamedAbbrev;
+        }
+
+        // Emit the name if it is present.
+        if (!ST->getName().empty())
+          WriteStringRecord(bitc::TYPE_CODE_STRUCT_NAME, ST->getName(),
+                            StructNameAbbrev, Stream);
+      }
+      break;
+    }
+    case Type::ArrayTyID: {
+      ArrayType *AT = cast<ArrayType>(T);
+      // ARRAY: [numelts, eltty]
+      Code = bitc::TYPE_CODE_ARRAY;
+      TypeVals.push_back(AT->getNumElements());
+      TypeVals.push_back(VE.getTypeID(AT->getElementType()));
+      AbbrevToUse = ArrayAbbrev;
+      break;
+    }
+    case Type::VectorTyID: {
+      VectorType *VT = cast<VectorType>(T);
+      // VECTOR [numelts, eltty]
+      Code = bitc::TYPE_CODE_VECTOR;
+      TypeVals.push_back(VT->getNumElements());
+      TypeVals.push_back(VE.getTypeID(VT->getElementType()));
+      break;
+    }
+    }
+
+    // Emit the finished record.
+    Stream.EmitRecord(Code, TypeVals, AbbrevToUse);
+    TypeVals.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static unsigned getEncodedLinkage(const GlobalValue &GV) {
+  switch (GV.getLinkage()) {
+  case GlobalValue::ExternalLinkage:
+    return 0;
+  case GlobalValue::WeakAnyLinkage:
+    return 1;
+  case GlobalValue::AppendingLinkage:
+    return 2;
+  case GlobalValue::InternalLinkage:
+    return 3;
+  case GlobalValue::LinkOnceAnyLinkage:
+    return 4;
+  case GlobalValue::ExternalWeakLinkage:
+    return 7;
+  case GlobalValue::CommonLinkage:
+    return 8;
+  case GlobalValue::PrivateLinkage:
+    return 9;
+  case GlobalValue::WeakODRLinkage:
+    return 10;
+  case GlobalValue::LinkOnceODRLinkage:
+    return 11;
+  case GlobalValue::AvailableExternallyLinkage:
+    return 12;
+  }
+  llvm_unreachable("Invalid linkage");
+}
+
+static unsigned getEncodedVisibility(const GlobalValue &GV) {
+  switch (GV.getVisibility()) {
+  case GlobalValue::DefaultVisibility:   return 0;
+  case GlobalValue::HiddenVisibility:    return 1;
+  case GlobalValue::ProtectedVisibility: return 2;
+  }
+  llvm_unreachable("Invalid visibility");
+}
+
+// Emit top-level description of module, including target triple, inline asm,
+// descriptors for global variables, and function prototype info.
+static void WriteModuleInfo(const Module *M,
+                            const llvm_2_9_func::ValueEnumerator &VE,
+                            BitstreamWriter &Stream) {
+  // Emit various pieces of data attached to a module.
+  if (!M->getTargetTriple().empty())
+    WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(),
+                      0/*TODO*/, Stream);
+  const std::string &DL = M->getDataLayoutStr();
+  if (!DL.empty())
+    WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/, Stream);
+  if (!M->getModuleInlineAsm().empty())
+    WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
+                      0/*TODO*/, Stream);
+
+  // Emit information about sections and GC, computing how many there are. Also
+  // compute the maximum alignment value.
+  std::map<std::string, unsigned> SectionMap;
+  std::map<std::string, unsigned> GCMap;
+  unsigned MaxAlignment = 0;
+  unsigned MaxGlobalType = 0;
+  for (const GlobalValue &GV : M->globals()) {
+    MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
+    MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getType()));
+    if (GV.hasSection()) {
+      // Give section names unique ID's.
+      unsigned &Entry = SectionMap[GV.getSection()];
+      if (!Entry) {
+        WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV.getSection(),
+                          0/*TODO*/, Stream);
+        Entry = SectionMap.size();
+      }
+    }
+  }
+  for (const Function &F : *M) {
+    MaxAlignment = std::max(MaxAlignment, F.getAlignment());
+    if (F.hasSection()) {
+      // Give section names unique ID's.
+      unsigned &Entry = SectionMap[F.getSection()];
+      if (!Entry) {
+        WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F.getSection(),
+                          0/*TODO*/, Stream);
+        Entry = SectionMap.size();
+      }
+    }
+    if (F.hasGC()) {
+      // Same for GC names.
+      unsigned &Entry = GCMap[F.getGC()];
+      if (!Entry) {
+        WriteStringRecord(bitc::MODULE_CODE_GCNAME, F.getGC(),
+                          0/*TODO*/, Stream);
+        Entry = GCMap.size();
+      }
+    }
+  }
+
+  // Emit abbrev for globals, now that we know # sections and max alignment.
+  unsigned SimpleGVarAbbrev = 0;
+  if (!M->global_empty()) {
+    // Add an abbrev for common globals with no visibility or thread localness.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_GLOBALVAR));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                              Log2_32_Ceil(MaxGlobalType+1)));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));      // Constant.
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));        // Initializer.
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));      // Linkage.
+    if (MaxAlignment == 0)                                      // Alignment.
+      Abbv->Add(BitCodeAbbrevOp(0));
+    else {
+      unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1;
+      Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                               Log2_32_Ceil(MaxEncAlignment+1)));
+    }
+    if (SectionMap.empty())                                    // Section.
+      Abbv->Add(BitCodeAbbrevOp(0));
+    else
+      Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                               Log2_32_Ceil(SectionMap.size()+1)));
+    // Don't bother emitting vis + thread local.
+    SimpleGVarAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  // Emit the global variable information.
+  SmallVector<unsigned, 64> Vals;
+  for (const GlobalVariable &GV : M->globals()) {
+    unsigned AbbrevToUse = 0;
+
+    // GLOBALVAR: [type, isconst, initid,
+    //             linkage, alignment, section, visibility, threadlocal,
+    //             unnamed_addr]
+    Vals.push_back(VE.getTypeID(GV.getType()));
+    Vals.push_back(GV.isConstant());
+    Vals.push_back(GV.isDeclaration() ? 0 :
+                   (VE.getValueID(GV.getInitializer()) + 1));
+    Vals.push_back(getEncodedLinkage(GV));
+    Vals.push_back(Log2_32(GV.getAlignment())+1);
+    Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
+    if (GV.isThreadLocal() ||
+        GV.getVisibility() != GlobalValue::DefaultVisibility ||
+        GV.hasUnnamedAddr()) {
+      Vals.push_back(getEncodedVisibility(GV));
+      Vals.push_back(GV.isThreadLocal());
+      Vals.push_back(GV.hasUnnamedAddr());
+    } else {
+      AbbrevToUse = SimpleGVarAbbrev;
+    }
+
+    Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse);
+    Vals.clear();
+  }
+
+  // Emit the function proto information.
+  for (const Function &F : *M) {
+    // FUNCTION:  [type, callingconv, isproto, paramattr,
+    //             linkage, alignment, section, visibility, gc, unnamed_addr]
+    Vals.push_back(VE.getTypeID(F.getType()));
+    Vals.push_back(F.getCallingConv());
+    Vals.push_back(F.isDeclaration());
+    Vals.push_back(getEncodedLinkage(F));
+    Vals.push_back(VE.getAttributeID(F.getAttributes()));
+    Vals.push_back(Log2_32(F.getAlignment())+1);
+    Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
+    Vals.push_back(getEncodedVisibility(F));
+    Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
+    Vals.push_back(F.hasUnnamedAddr());
+
+    unsigned AbbrevToUse = 0;
+    Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
+    Vals.clear();
+  }
+
+  // Emit the alias information.
+  for (const GlobalAlias &A : M->aliases()) {
+    Vals.push_back(VE.getTypeID(A.getType()));
+    Vals.push_back(VE.getValueID(A.getAliasee()));
+    Vals.push_back(getEncodedLinkage(A));
+    Vals.push_back(getEncodedVisibility(A));
+    unsigned AbbrevToUse = 0;
+    Stream.EmitRecord(bitc::MODULE_CODE_ALIAS_OLD, Vals, AbbrevToUse);
+    Vals.clear();
+  }
+}
+
+static uint64_t GetOptimizationFlags(const Value *V) {
+  uint64_t Flags = 0;
+
+  if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(V)) {
+    if (OBO->hasNoSignedWrap())
+      Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
+    if (OBO->hasNoUnsignedWrap())
+      Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
+  } else if (const auto *PEO = dyn_cast<PossiblyExactOperator>(V)) {
+    if (PEO->isExact())
+      Flags |= 1 << bitc::PEO_EXACT;
+  }
+
+  return Flags;
+}
+
+static void WriteValueAsMetadata(const ValueAsMetadata *MD,
+                                 const llvm_2_9_func::ValueEnumerator &VE,
+                                 BitstreamWriter &Stream,
+                                 SmallVectorImpl<uint64_t> &Record) {
+  // Mimic an MDNode with a value as one operand.
+  Value *V = MD->getValue();
+  Record.push_back(VE.getTypeID(V->getType()));
+  Record.push_back(VE.getValueID(V));
+  Stream.EmitRecord(bitc::METADATA_OLD_NODE, Record, 0);
+  Record.clear();
+}
+
+static void WriteMDTuple(const MDTuple *N, const llvm_2_9_func::ValueEnumerator &VE,
+                         BitstreamWriter &Stream,
+                         SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
+  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+    Metadata *MD = N->getOperand(i);
+    assert(!(MD && isa<LocalAsMetadata>(MD)) &&
+           "Unexpected function-local metadata");
+    if (!MD) {
+      // TODO(srhines): I don't believe this case can exist for RS.
+      Record.push_back(VE.getTypeID(llvm::Type::getVoidTy(N->getContext())));
+      Record.push_back(0);
+    } else if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+      Record.push_back(VE.getTypeID(MDC->getType()));
+      Record.push_back(VE.getValueID(MDC->getValue()));
+    } else {
+      Record.push_back(VE.getTypeID(
+          llvm::Type::getMetadataTy(N->getContext())));
+      Record.push_back(VE.getMetadataID(MD));
+    }
+  }
+  Stream.EmitRecord(bitc::METADATA_OLD_NODE, Record, Abbrev);
+  Record.clear();
+}
+
+/*static void WriteMDLocation(const MDLocation *N, const llvm_2_9_func::ValueEnumerator &VE,
+                            BitstreamWriter &Stream,
+                            SmallVectorImpl<uint64_t> &Record,
+                            unsigned Abbrev) {
+  Record.push_back(N->isDistinct());
+  Record.push_back(N->getLine());
+  Record.push_back(N->getColumn());
+  Record.push_back(VE.getMetadataID(N->getScope()));
+  Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt()));
+
+  Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
+  Record.clear();
+}
+
+static void WriteGenericDebugNode(const GenericDebugNode *,
+                                  const llvm_2_9_func::ValueEnumerator &, BitstreamWriter &,
+                                  SmallVectorImpl<uint64_t> &, unsigned) {
+  llvm_unreachable("unimplemented");
+}*/
+
+static void WriteModuleMetadata(const Module *M,
+                                const llvm_2_9_func::ValueEnumerator &VE,
+                                BitstreamWriter &Stream) {
+  const auto &MDs = VE.getMDs();
+  if (MDs.empty() && M->named_metadata_empty())
+    return;
+
+  // RenderScript files *ALWAYS* have metadata!
+  Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
+  unsigned MDSAbbrev = 0;
+  if (VE.hasMDString()) {
+    // Abbrev for METADATA_STRING.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    MDSAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  unsigned MDLocationAbbrev = 0;
+  if (VE.hasDILocation()) {
+    // TODO(srhines): Should be unreachable for RenderScript.
+    // Abbrev for METADATA_LOCATION.
+    //
+    // Assume the column is usually under 128, and always output the inlined-at
+    // location (it's never more expensive than building an array size 1).
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    MDLocationAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  unsigned NameAbbrev = 0;
+  if (!M->named_metadata_empty()) {
+    // Abbrev for METADATA_NAME.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_NAME));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    NameAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  unsigned MDTupleAbbrev = 0;
+  //unsigned GenericDebugNodeAbbrev = 0;
+  SmallVector<uint64_t, 64> Record;
+  for (const Metadata *MD : MDs) {
+    if (const MDNode *N = dyn_cast<MDNode>(MD)) {
+      switch (N->getMetadataID()) {
+      default:
+        llvm_unreachable("Invalid MDNode subclass");
+#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)
+#define HANDLE_MDNODE_LEAF(CLASS)                                              \
+  case Metadata::CLASS##Kind:                                                  \
+    Write##CLASS(cast<CLASS>(N), VE, Stream, Record, CLASS##Abbrev);           \
+    continue;
+#include "llvm/IR/Metadata.def"
+      }
+    }
+    if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+      WriteValueAsMetadata(MDC, VE, Stream, Record);
+      continue;
+    }
+    const MDString *MDS = cast<MDString>(MD);
+    // Code: [strchar x N]
+    Record.append(MDS->bytes_begin(), MDS->bytes_end());
+
+    // Emit the finished record.
+    Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
+    Record.clear();
+  }
+
+  // Write named metadata.
+  for (const NamedMDNode &NMD : M->named_metadata()) {
+    // Write name.
+    StringRef Str = NMD.getName();
+    Record.append(Str.bytes_begin(), Str.bytes_end());
+    Stream.EmitRecord(bitc::METADATA_NAME, Record, NameAbbrev);
+    Record.clear();
+
+    // Write named metadata operands.
+    for (const MDNode *N : NMD.operands())
+      Record.push_back(VE.getMetadataID(N));
+    Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void WriteFunctionLocalMetadata(const Function &F,
+                                       const llvm_2_9_func::ValueEnumerator &VE,
+                                       BitstreamWriter &Stream) {
+  bool StartedMetadataBlock = false;
+  SmallVector<uint64_t, 64> Record;
+  const SmallVectorImpl<const LocalAsMetadata *> &MDs =
+      VE.getFunctionLocalMDs();
+  for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+    assert(MDs[i] && "Expected valid function-local metadata");
+    if (!StartedMetadataBlock) {
+      Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+      StartedMetadataBlock = true;
+    }
+    WriteValueAsMetadata(MDs[i], VE, Stream, Record);
+  }
+
+  if (StartedMetadataBlock)
+    Stream.ExitBlock();
+}
+
+static void WriteMetadataAttachment(const Function &F,
+                                    const llvm_2_9_func::ValueEnumerator &VE,
+                                    BitstreamWriter &Stream) {
+  Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Write metadata attachments
+  // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
+  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+         I != E; ++I) {
+      MDs.clear();
+      I->getAllMetadataOtherThanDebugLoc(MDs);
+
+      // If no metadata, ignore instruction.
+      if (MDs.empty()) continue;
+
+      Record.push_back(VE.getInstructionID(&*I));
+
+      for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+        Record.push_back(MDs[i].first);
+        Record.push_back(VE.getMetadataID(MDs[i].second));
+      }
+      Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
+      Record.clear();
+    }
+
+  Stream.ExitBlock();
+}
+
+static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
+  SmallVector<uint64_t, 64> Record;
+
+  // Write metadata kinds
+  // METADATA_KIND - [n x [id, name]]
+  SmallVector<StringRef, 4> Names;
+  M->getMDKindNames(Names);
+
+  if (Names.empty()) return;
+
+  Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
+  for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {
+    Record.push_back(MDKindID);
+    StringRef KName = Names[MDKindID];
+    Record.append(KName.begin(), KName.end());
+
+    Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void WriteConstants(unsigned FirstVal, unsigned LastVal,
+                           const llvm_2_9_func::ValueEnumerator &VE,
+                           BitstreamWriter &Stream, bool isGlobal) {
+  if (FirstVal == LastVal) return;
+
+  Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4);
+
+  unsigned AggregateAbbrev = 0;
+  unsigned String8Abbrev = 0;
+  unsigned CString7Abbrev = 0;
+  unsigned CString6Abbrev = 0;
+  // If this is a constant pool for the module, emit module-specific abbrevs.
+  if (isGlobal) {
+    // Abbrev for CST_CODE_AGGREGATE.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_AGGREGATE));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(LastVal+1)));
+    AggregateAbbrev = Stream.EmitAbbrev(Abbv);
+
+    // Abbrev for CST_CODE_STRING.
+    Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_STRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    String8Abbrev = Stream.EmitAbbrev(Abbv);
+    // Abbrev for CST_CODE_CSTRING.
+    Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
+    CString7Abbrev = Stream.EmitAbbrev(Abbv);
+    // Abbrev for CST_CODE_CSTRING.
+    Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    CString6Abbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  SmallVector<uint64_t, 64> Record;
+
+  const llvm_2_9_func::ValueEnumerator::ValueList &Vals = VE.getValues();
+  Type *LastTy = nullptr;
+  for (unsigned i = FirstVal; i != LastVal; ++i) {
+    const Value *V = Vals[i].first;
+    // If we need to switch types, do so now.
+    if (V->getType() != LastTy) {
+      LastTy = V->getType();
+      Record.push_back(VE.getTypeID(LastTy));
+      Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record,
+                        CONSTANTS_SETTYPE_ABBREV);
+      Record.clear();
+    }
+
+    if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
+      Record.push_back(unsigned(IA->hasSideEffects()) |
+                       unsigned(IA->isAlignStack()) << 1);
+
+      // Add the asm string.
+      const std::string &AsmStr = IA->getAsmString();
+      Record.push_back(AsmStr.size());
+      for (unsigned i = 0, e = AsmStr.size(); i != e; ++i)
+        Record.push_back(AsmStr[i]);
+
+      // Add the constraint string.
+      const std::string &ConstraintStr = IA->getConstraintString();
+      Record.push_back(ConstraintStr.size());
+      for (unsigned i = 0, e = ConstraintStr.size(); i != e; ++i)
+        Record.push_back(ConstraintStr[i]);
+      Stream.EmitRecord(bitc::CST_CODE_INLINEASM, Record);
+      Record.clear();
+      continue;
+    }
+    const Constant *C = cast<Constant>(V);
+    unsigned Code = -1U;
+    unsigned AbbrevToUse = 0;
+    if (C->isNullValue()) {
+      Code = bitc::CST_CODE_NULL;
+    } else if (isa<UndefValue>(C)) {
+      Code = bitc::CST_CODE_UNDEF;
+    } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
+      if (IV->getBitWidth() <= 64) {
+        uint64_t V = IV->getSExtValue();
+        if ((int64_t)V >= 0)
+          Record.push_back(V << 1);
+        else
+          Record.push_back((-V << 1) | 1);
+        Code = bitc::CST_CODE_INTEGER;
+        AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
+      } else {                             // Wide integers, > 64 bits in size.
+        // We have an arbitrary precision integer value to write whose
+        // bit width is > 64. However, in canonical unsigned integer
+        // format it is likely that the high bits are going to be zero.
+        // So, we only write the number of active words.
+        unsigned NWords = IV->getValue().getActiveWords();
+        const uint64_t *RawWords = IV->getValue().getRawData();
+        for (unsigned i = 0; i != NWords; ++i) {
+          int64_t V = RawWords[i];
+          if (V >= 0)
+            Record.push_back(V << 1);
+          else
+            Record.push_back((-V << 1) | 1);
+        }
+        Code = bitc::CST_CODE_WIDE_INTEGER;
+      }
+    } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
+      Code = bitc::CST_CODE_FLOAT;
+      Type *Ty = CFP->getType();
+      if (Ty->isFloatTy() || Ty->isDoubleTy()) {
+        Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
+      } else if (Ty->isX86_FP80Ty()) {
+        // api needed to prevent premature destruction
+        // bits are not in the same order as a normal i80 APInt, compensate.
+        APInt api = CFP->getValueAPF().bitcastToAPInt();
+        const uint64_t *p = api.getRawData();
+        Record.push_back((p[1] << 48) | (p[0] >> 16));
+        Record.push_back(p[0] & 0xffffLL);
+      } else if (Ty->isFP128Ty() || Ty->isPPC_FP128Ty()) {
+        APInt api = CFP->getValueAPF().bitcastToAPInt();
+        const uint64_t *p = api.getRawData();
+        Record.push_back(p[0]);
+        Record.push_back(p[1]);
+      } else {
+        assert (0 && "Unknown FP type!");
+      }
+    } else if (isa<ConstantDataSequential>(C) &&
+               cast<ConstantDataSequential>(C)->isString()) {
+      const ConstantDataSequential *Str = cast<ConstantDataSequential>(C);
+      // Emit constant strings specially.
+      unsigned NumElts = Str->getNumElements();
+      // If this is a null-terminated string, use the denser CSTRING encoding.
+      if (Str->isCString()) {
+        Code = bitc::CST_CODE_CSTRING;
+        --NumElts;  // Don't encode the null, which isn't allowed by char6.
+      } else {
+        Code = bitc::CST_CODE_STRING;
+        AbbrevToUse = String8Abbrev;
+      }
+      bool isCStr7 = Code == bitc::CST_CODE_CSTRING;
+      bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING;
+      for (unsigned i = 0; i != NumElts; ++i) {
+        unsigned char V = Str->getElementAsInteger(i);
+        Record.push_back(V);
+        isCStr7 &= (V & 128) == 0;
+        if (isCStrChar6)
+          isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
+      }
+
+      if (isCStrChar6)
+        AbbrevToUse = CString6Abbrev;
+      else if (isCStr7)
+        AbbrevToUse = CString7Abbrev;
+    } else if (const ConstantDataSequential *CDS =
+                  dyn_cast<ConstantDataSequential>(C)) {
+      // We must replace ConstantDataSequential's representation with the
+      // legacy ConstantArray/ConstantVector/ConstantStruct version.
+      // ValueEnumerator is similarly modified to mark the appropriate
+      // Constants as used (so they are emitted).
+      Code = bitc::CST_CODE_AGGREGATE;
+      for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+        Record.push_back(VE.getValueID(CDS->getElementAsConstant(i)));
+      AbbrevToUse = AggregateAbbrev;
+    } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) ||
+               isa<ConstantVector>(C)) {
+      Code = bitc::CST_CODE_AGGREGATE;
+      for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
+        Record.push_back(VE.getValueID(C->getOperand(i)));
+      AbbrevToUse = AggregateAbbrev;
+    } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+      switch (CE->getOpcode()) {
+      default:
+        if (Instruction::isCast(CE->getOpcode())) {
+          Code = bitc::CST_CODE_CE_CAST;
+          Record.push_back(GetEncodedCastOpcode(CE->getOpcode()));
+          Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+          Record.push_back(VE.getValueID(C->getOperand(0)));
+          AbbrevToUse = CONSTANTS_CE_CAST_Abbrev;
+        } else {
+          assert(CE->getNumOperands() == 2 && "Unknown constant expr!");
+          Code = bitc::CST_CODE_CE_BINOP;
+          Record.push_back(GetEncodedBinaryOpcode(CE->getOpcode()));
+          Record.push_back(VE.getValueID(C->getOperand(0)));
+          Record.push_back(VE.getValueID(C->getOperand(1)));
+          uint64_t Flags = GetOptimizationFlags(CE);
+          if (Flags != 0)
+            Record.push_back(Flags);
+        }
+        break;
+      case Instruction::GetElementPtr:
+        Code = bitc::CST_CODE_CE_GEP;
+        if (cast<GEPOperator>(C)->isInBounds())
+          Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
+        for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
+          Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
+          Record.push_back(VE.getValueID(C->getOperand(i)));
+        }
+        break;
+      case Instruction::Select:
+        Code = bitc::CST_CODE_CE_SELECT;
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(VE.getValueID(C->getOperand(2)));
+        break;
+      case Instruction::ExtractElement:
+        Code = bitc::CST_CODE_CE_EXTRACTELT;
+        Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        break;
+      case Instruction::InsertElement:
+        Code = bitc::CST_CODE_CE_INSERTELT;
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(VE.getValueID(C->getOperand(2)));
+        break;
+      case Instruction::ShuffleVector:
+        // If the return type and argument types are the same, this is a
+        // standard shufflevector instruction.  If the types are different,
+        // then the shuffle is widening or truncating the input vectors, and
+        // the argument type must also be encoded.
+        if (C->getType() == C->getOperand(0)->getType()) {
+          Code = bitc::CST_CODE_CE_SHUFFLEVEC;
+        } else {
+          Code = bitc::CST_CODE_CE_SHUFVEC_EX;
+          Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        }
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(VE.getValueID(C->getOperand(2)));
+        break;
+      case Instruction::ICmp:
+      case Instruction::FCmp:
+        Code = bitc::CST_CODE_CE_CMP;
+        Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(CE->getPredicate());
+        break;
+      }
+    } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
+      Code = bitc::CST_CODE_BLOCKADDRESS;
+      Record.push_back(VE.getTypeID(BA->getFunction()->getType()));
+      Record.push_back(VE.getValueID(BA->getFunction()));
+      Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock()));
+    } else {
+#ifndef NDEBUG
+      C->dump();
+#endif
+      llvm_unreachable("Unknown constant!");
+    }
+    Stream.EmitRecord(Code, Record, AbbrevToUse);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void WriteModuleConstants(const llvm_2_9_func::ValueEnumerator &VE,
+                                 BitstreamWriter &Stream) {
+  const llvm_2_9_func::ValueEnumerator::ValueList &Vals = VE.getValues();
+
+  // Find the first constant to emit, which is the first non-globalvalue value.
+  // We know globalvalues have been emitted by WriteModuleInfo.
+  for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+    if (!isa<GlobalValue>(Vals[i].first)) {
+      WriteConstants(i, Vals.size(), VE, Stream, true);
+      return;
+    }
+  }
+}
+
+/// PushValueAndType - The file has to encode both the value and type id for
+/// many values, because we need to know what type to create for forward
+/// references.  However, most operands are not forward references, so this type
+/// field is not needed.
+///
+/// This function adds V's value ID to Vals.  If the value ID is higher than the
+/// instruction ID, then it is a forward reference, and it also includes the
+/// type ID.
+static bool PushValueAndType(const Value *V, unsigned InstID,
+                             SmallVector<unsigned, 64> &Vals,
+                             llvm_2_9_func::ValueEnumerator &VE) {
+  unsigned ValID = VE.getValueID(V);
+  Vals.push_back(ValID);
+  if (ValID >= InstID) {
+    Vals.push_back(VE.getTypeID(V->getType()));
+    return true;
+  }
+  return false;
+}
+
+/// WriteInstruction - Emit an instruction to the specified stream.
+static void WriteInstruction(const Instruction &I, unsigned InstID,
+                             llvm_2_9_func::ValueEnumerator &VE,
+                             BitstreamWriter &Stream,
+                             SmallVector<unsigned, 64> &Vals) {
+  unsigned Code = 0;
+  unsigned AbbrevToUse = 0;
+  VE.setInstructionID(&I);
+  switch (I.getOpcode()) {
+  default:
+    if (Instruction::isCast(I.getOpcode())) {
+      Code = bitc::FUNC_CODE_INST_CAST;
+      if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+        AbbrevToUse = FUNCTION_INST_CAST_ABBREV;
+      Vals.push_back(VE.getTypeID(I.getType()));
+      Vals.push_back(GetEncodedCastOpcode(I.getOpcode()));
+    } else {
+      assert(isa<BinaryOperator>(I) && "Unknown instruction!");
+      Code = bitc::FUNC_CODE_INST_BINOP;
+      if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+        AbbrevToUse = FUNCTION_INST_BINOP_ABBREV;
+      Vals.push_back(VE.getValueID(I.getOperand(1)));
+      Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode()));
+      uint64_t Flags = GetOptimizationFlags(&I);
+      if (Flags != 0) {
+        if (AbbrevToUse == FUNCTION_INST_BINOP_ABBREV)
+          AbbrevToUse = FUNCTION_INST_BINOP_FLAGS_ABBREV;
+        Vals.push_back(Flags);
+      }
+    }
+    break;
+
+  case Instruction::GetElementPtr:
+    Code = bitc::FUNC_CODE_INST_GEP_OLD;
+    if (cast<GEPOperator>(&I)->isInBounds())
+      Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
+    for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
+      PushValueAndType(I.getOperand(i), InstID, Vals, VE);
+    break;
+  case Instruction::ExtractValue: {
+    Code = bitc::FUNC_CODE_INST_EXTRACTVAL;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    const ExtractValueInst *EVI = cast<ExtractValueInst>(&I);
+    for (const unsigned *i = EVI->idx_begin(), *e = EVI->idx_end(); i != e; ++i)
+      Vals.push_back(*i);
+    break;
+  }
+  case Instruction::InsertValue: {
+    Code = bitc::FUNC_CODE_INST_INSERTVAL;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    PushValueAndType(I.getOperand(1), InstID, Vals, VE);
+    const InsertValueInst *IVI = cast<InsertValueInst>(&I);
+    for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i)
+      Vals.push_back(*i);
+    break;
+  }
+  case Instruction::Select:
+    Code = bitc::FUNC_CODE_INST_VSELECT;
+    PushValueAndType(I.getOperand(1), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(2)));
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    break;
+  case Instruction::ExtractElement:
+    Code = bitc::FUNC_CODE_INST_EXTRACTELT;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    break;
+  case Instruction::InsertElement:
+    Code = bitc::FUNC_CODE_INST_INSERTELT;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    Vals.push_back(VE.getValueID(I.getOperand(2)));
+    break;
+  case Instruction::ShuffleVector:
+    Code = bitc::FUNC_CODE_INST_SHUFFLEVEC;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    Vals.push_back(VE.getValueID(I.getOperand(2)));
+    break;
+  case Instruction::ICmp:
+  case Instruction::FCmp:
+    // compare returning Int1Ty or vector of Int1Ty
+    Code = bitc::FUNC_CODE_INST_CMP2;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    Vals.push_back(cast<CmpInst>(I).getPredicate());
+    break;
+
+  case Instruction::Ret:
+    {
+      Code = bitc::FUNC_CODE_INST_RET;
+      unsigned NumOperands = I.getNumOperands();
+      if (NumOperands == 0)
+        AbbrevToUse = FUNCTION_INST_RET_VOID_ABBREV;
+      else if (NumOperands == 1) {
+        if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+          AbbrevToUse = FUNCTION_INST_RET_VAL_ABBREV;
+      } else {
+        for (unsigned i = 0, e = NumOperands; i != e; ++i)
+          PushValueAndType(I.getOperand(i), InstID, Vals, VE);
+      }
+    }
+    break;
+  case Instruction::Br:
+    {
+      Code = bitc::FUNC_CODE_INST_BR;
+      const BranchInst &II = cast<BranchInst>(I);
+      Vals.push_back(VE.getValueID(II.getSuccessor(0)));
+      if (II.isConditional()) {
+        Vals.push_back(VE.getValueID(II.getSuccessor(1)));
+        Vals.push_back(VE.getValueID(II.getCondition()));
+      }
+    }
+    break;
+  case Instruction::Switch:
+    {
+      Code = bitc::FUNC_CODE_INST_SWITCH;
+      const SwitchInst &SI = cast<SwitchInst>(I);
+      Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
+      Vals.push_back(VE.getValueID(SI.getCondition()));
+      Vals.push_back(VE.getValueID(SI.getDefaultDest()));
+      for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
+           i != e; ++i) {
+        Vals.push_back(VE.getValueID(i.getCaseValue()));
+        Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
+      }
+    }
+    break;
+  case Instruction::IndirectBr:
+    Code = bitc::FUNC_CODE_INST_INDIRECTBR;
+    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+    for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
+      Vals.push_back(VE.getValueID(I.getOperand(i)));
+    break;
+
+  case Instruction::Invoke: {
+    const InvokeInst *II = cast<InvokeInst>(&I);
+    const Value *Callee(II->getCalledValue());
+    PointerType *PTy = cast<PointerType>(Callee->getType());
+    FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+    Code = bitc::FUNC_CODE_INST_INVOKE;
+
+    Vals.push_back(VE.getAttributeID(II->getAttributes()));
+    Vals.push_back(II->getCallingConv());
+    Vals.push_back(VE.getValueID(II->getNormalDest()));
+    Vals.push_back(VE.getValueID(II->getUnwindDest()));
+    PushValueAndType(Callee, InstID, Vals, VE);
+
+    // Emit value #'s for the fixed parameters.
+    for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+      Vals.push_back(VE.getValueID(I.getOperand(i)));  // fixed param.
+
+    // Emit type/value pairs for varargs params.
+    if (FTy->isVarArg()) {
+      for (unsigned i = FTy->getNumParams(), e = I.getNumOperands()-3;
+           i != e; ++i)
+        PushValueAndType(I.getOperand(i), InstID, Vals, VE); // vararg
+    }
+    break;
+  }
+  case Instruction::Resume:
+    Code = bitc::FUNC_CODE_INST_RESUME;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    break;
+  case Instruction::Unreachable:
+    Code = bitc::FUNC_CODE_INST_UNREACHABLE;
+    AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV;
+    break;
+
+  case Instruction::PHI: {
+    const PHINode &PN = cast<PHINode>(I);
+    Code = bitc::FUNC_CODE_INST_PHI;
+    Vals.push_back(VE.getTypeID(PN.getType()));
+    for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+      Vals.push_back(VE.getValueID(PN.getIncomingValue(i)));
+      Vals.push_back(VE.getValueID(PN.getIncomingBlock(i)));
+    }
+    break;
+  }
+
+  case Instruction::LandingPad: {
+    const LandingPadInst &LP = cast<LandingPadInst>(I);
+    Code = bitc::FUNC_CODE_INST_LANDINGPAD_OLD;
+    Vals.push_back(VE.getTypeID(LP.getType()));
+    // TODO (rebase): is this fix enough?
+    // PushValueAndType(LP.getPersonalityFn(), InstID, Vals, VE);
+    Vals.push_back(LP.isCleanup());
+    Vals.push_back(LP.getNumClauses());
+    for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) {
+      if (LP.isCatch(I))
+        Vals.push_back(LandingPadInst::Catch);
+      else
+        Vals.push_back(LandingPadInst::Filter);
+      PushValueAndType(LP.getClause(I), InstID, Vals, VE);
+    }
+    break;
+  }
+
+  case Instruction::Alloca:
+    Code = bitc::FUNC_CODE_INST_ALLOCA;
+    Vals.push_back(VE.getTypeID(I.getType()));
+    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+    Vals.push_back(VE.getValueID(I.getOperand(0))); // size.
+    Vals.push_back(Log2_32(cast<AllocaInst>(I).getAlignment())+1);
+    break;
+
+  case Instruction::Load:
+    if (cast<LoadInst>(I).isAtomic()) {
+      Code = bitc::FUNC_CODE_INST_LOADATOMIC;
+      PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    } else {
+      Code = bitc::FUNC_CODE_INST_LOAD;
+      if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))  // ptr
+        AbbrevToUse = FUNCTION_INST_LOAD_ABBREV;
+    }
+    Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment())+1);
+    Vals.push_back(cast<LoadInst>(I).isVolatile());
+    if (cast<LoadInst>(I).isAtomic()) {
+      Vals.push_back(GetEncodedOrdering(cast<LoadInst>(I).getOrdering()));
+      Vals.push_back(GetEncodedSynchScope(cast<LoadInst>(I).getSynchScope()));
+    }
+    break;
+  case Instruction::Store:
+    if (cast<StoreInst>(I).isAtomic())
+      Code = bitc::FUNC_CODE_INST_STOREATOMIC;
+    else
+      Code = bitc::FUNC_CODE_INST_STORE_OLD;
+    PushValueAndType(I.getOperand(1), InstID, Vals, VE);  // ptrty + ptr
+    Vals.push_back(VE.getValueID(I.getOperand(0)));       // val.
+    Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1);
+    Vals.push_back(cast<StoreInst>(I).isVolatile());
+    if (cast<StoreInst>(I).isAtomic()) {
+      Vals.push_back(GetEncodedOrdering(cast<StoreInst>(I).getOrdering()));
+      Vals.push_back(GetEncodedSynchScope(cast<StoreInst>(I).getSynchScope()));
+    }
+    break;
+  case Instruction::AtomicCmpXchg:
+    Code = bitc::FUNC_CODE_INST_CMPXCHG;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);  // ptrty + ptr
+    Vals.push_back(VE.getValueID(I.getOperand(1)));       // cmp.
+    Vals.push_back(VE.getValueID(I.getOperand(2)));       // newval.
+    Vals.push_back(cast<AtomicCmpXchgInst>(I).isVolatile());
+    Vals.push_back(GetEncodedOrdering(
+                     cast<AtomicCmpXchgInst>(I).getSuccessOrdering()));
+    Vals.push_back(GetEncodedSynchScope(
+                     cast<AtomicCmpXchgInst>(I).getSynchScope()));
+    break;
+  case Instruction::AtomicRMW:
+    Code = bitc::FUNC_CODE_INST_ATOMICRMW;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);  // ptrty + ptr
+    Vals.push_back(VE.getValueID(I.getOperand(1)));       // val.
+    Vals.push_back(GetEncodedRMWOperation(
+                     cast<AtomicRMWInst>(I).getOperation()));
+    Vals.push_back(cast<AtomicRMWInst>(I).isVolatile());
+    Vals.push_back(GetEncodedOrdering(cast<AtomicRMWInst>(I).getOrdering()));
+    Vals.push_back(GetEncodedSynchScope(
+                     cast<AtomicRMWInst>(I).getSynchScope()));
+    break;
+  case Instruction::Fence:
+    Code = bitc::FUNC_CODE_INST_FENCE;
+    Vals.push_back(GetEncodedOrdering(cast<FenceInst>(I).getOrdering()));
+    Vals.push_back(GetEncodedSynchScope(cast<FenceInst>(I).getSynchScope()));
+    break;
+  case Instruction::Call: {
+    const CallInst &CI = cast<CallInst>(I);
+    PointerType *PTy = cast<PointerType>(CI.getCalledValue()->getType());
+    FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+
+    Code = bitc::FUNC_CODE_INST_CALL;
+
+    Vals.push_back(VE.getAttributeID(CI.getAttributes()));
+    Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()));
+    PushValueAndType(CI.getCalledValue(), InstID, Vals, VE);  // Callee
+
+    // Emit value #'s for the fixed parameters.
+    for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+      Vals.push_back(VE.getValueID(CI.getArgOperand(i)));  // fixed param.
+
+    // Emit type/value pairs for varargs params.
+    if (FTy->isVarArg()) {
+      for (unsigned i = FTy->getNumParams(), e = CI.getNumArgOperands();
+           i != e; ++i)
+        PushValueAndType(CI.getArgOperand(i), InstID, Vals, VE);  // varargs
+    }
+    break;
+  }
+  case Instruction::VAArg:
+    Code = bitc::FUNC_CODE_INST_VAARG;
+    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));   // valistty
+    Vals.push_back(VE.getValueID(I.getOperand(0))); // valist.
+    Vals.push_back(VE.getTypeID(I.getType())); // restype.
+    break;
+  }
+
+  Stream.EmitRecord(Code, Vals, AbbrevToUse);
+  Vals.clear();
+}
+
+// Emit names for globals/functions etc.
+static void WriteValueSymbolTable(const ValueSymbolTable &VST,
+                                  const llvm_2_9_func::ValueEnumerator &VE,
+                                  BitstreamWriter &Stream) {
+  if (VST.empty()) return;
+  Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4);
+
+  // FIXME: Set up the abbrev, we know how many values there are!
+  // FIXME: We know if the type names can use 7-bit ascii.
+  SmallVector<unsigned, 64> NameVals;
+
+  for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
+       SI != SE; ++SI) {
+
+    const ValueName &Name = *SI;
+
+    // Figure out the encoding to use for the name.
+    bool is7Bit = true;
+    bool isChar6 = true;
+    for (const char *C = Name.getKeyData(), *E = C+Name.getKeyLength();
+         C != E; ++C) {
+      if (isChar6)
+        isChar6 = BitCodeAbbrevOp::isChar6(*C);
+      if ((unsigned char)*C & 128) {
+        is7Bit = false;
+        break;  // don't bother scanning the rest.
+      }
+    }
+
+    unsigned AbbrevToUse = VST_ENTRY_8_ABBREV;
+
+    // VST_ENTRY:   [valueid, namechar x N]
+    // VST_BBENTRY: [bbid, namechar x N]
+    unsigned Code;
+    if (isa<BasicBlock>(SI->getValue())) {
+      Code = bitc::VST_CODE_BBENTRY;
+      if (isChar6)
+        AbbrevToUse = VST_BBENTRY_6_ABBREV;
+    } else {
+      Code = bitc::VST_CODE_ENTRY;
+      if (isChar6)
+        AbbrevToUse = VST_ENTRY_6_ABBREV;
+      else if (is7Bit)
+        AbbrevToUse = VST_ENTRY_7_ABBREV;
+    }
+
+    NameVals.push_back(VE.getValueID(SI->getValue()));
+    for (const char *P = Name.getKeyData(),
+         *E = Name.getKeyData()+Name.getKeyLength(); P != E; ++P)
+      NameVals.push_back((unsigned char)*P);
+
+    // Emit the finished record.
+    Stream.EmitRecord(Code, NameVals, AbbrevToUse);
+    NameVals.clear();
+  }
+  Stream.ExitBlock();
+}
+
+/// WriteFunction - Emit a function body to the module stream.
+static void WriteFunction(const Function &F, llvm_2_9_func::ValueEnumerator &VE,
+                          BitstreamWriter &Stream) {
+  Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4);
+  VE.incorporateFunction(F);
+
+  SmallVector<unsigned, 64> Vals;
+
+  // Emit the number of basic blocks, so the reader can create them ahead of
+  // time.
+  Vals.push_back(VE.getBasicBlocks().size());
+  Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals);
+  Vals.clear();
+
+  // If there are function-local constants, emit them now.
+  unsigned CstStart, CstEnd;
+  VE.getFunctionConstantRange(CstStart, CstEnd);
+  WriteConstants(CstStart, CstEnd, VE, Stream, false);
+
+  // If there is function-local metadata, emit it now.
+  WriteFunctionLocalMetadata(F, VE, Stream);
+
+  // Keep a running idea of what the instruction ID is.
+  unsigned InstID = CstEnd;
+
+  bool NeedsMetadataAttachment = false;
+
+  DILocation *LastDL = nullptr;
+
+  // Finally, emit all the instructions, in order.
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+         I != E; ++I) {
+      WriteInstruction(*I, InstID, VE, Stream, Vals);
+
+      if (!I->getType()->isVoidTy())
+        ++InstID;
+
+      // If the instruction has metadata, write a metadata attachment later.
+      NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
+
+      // If the instruction has a debug location, emit it.
+      DILocation *DL = I->getDebugLoc();
+      if (!DL)
+        continue;
+
+      if (DL == LastDL) {
+        // Just repeat the same debug loc as last time.
+        Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
+        continue;
+      }
+
+      Vals.push_back(DL->getLine());
+      Vals.push_back(DL->getColumn());
+      Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
+      Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
+      Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
+      Vals.clear();
+
+      // Fixme(pirama): The following line is missing from upstream
+      // https://llvm.org/bugs/show_bug.cgi?id=23436
+      LastDL = DL;
+    }
+
+  // Emit names for all the instructions etc.
+  WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
+
+  if (NeedsMetadataAttachment)
+    WriteMetadataAttachment(F, VE, Stream);
+  VE.purgeFunction();
+  Stream.ExitBlock();
+}
+
+// Emit blockinfo, which defines the standard abbreviations etc.
+static void WriteBlockInfo(const llvm_2_9_func::ValueEnumerator &VE,
+                           BitstreamWriter &Stream) {
+  // We only want to emit block info records for blocks that have multiple
+  // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK.  Other
+  // blocks can defined their abbrevs inline.
+  Stream.EnterBlockInfoBlock(2);
+
+  { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_ENTRY_8_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // 7-bit fixed width VST_ENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_ENTRY_7_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // 6-bit char6 VST_ENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_ENTRY_6_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // 6-bit char6 VST_BBENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_BBENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_BBENTRY_6_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+
+
+  { // SETTYPE abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                              Log2_32_Ceil(VE.getTypes().size()+1)));
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_SETTYPE_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // INTEGER abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_INTEGER));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_INTEGER_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // CE_CAST abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CE_CAST));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));  // cast opc
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,       // typeid
+                              Log2_32_Ceil(VE.getTypes().size()+1)));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));    // value id
+
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_CE_CAST_Abbrev)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // NULL abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_NULL));
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_NULL_Abbrev)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  // FIXME: This should only use space for first class types!
+
+  { // INST_LOAD abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_LOAD_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_BINOP abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_BINOP_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_BINOP_FLAGS abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // flags
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_BINOP_FLAGS_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_CAST abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));    // OpVal
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,       // dest ty
+                              Log2_32_Ceil(VE.getTypes().size()+1)));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));  // opc
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_CAST_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // INST_RET abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_RET_VOID_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_RET abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ValID
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_RET_VAL_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_UNREACHABLE abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE));
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  Stream.ExitBlock();
+}
+
+/// WriteModule - Emit the specified module to the bitstream.
+static void WriteModule(const Module *M, BitstreamWriter &Stream) {
+  Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
+
+  // Emit the version number if it is non-zero.
+  if (CurVersion) {
+    SmallVector<unsigned, 1> Vals;
+    Vals.push_back(CurVersion);
+    Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals);
+  }
+
+  // Analyze the module, enumerating globals, functions, etc.
+  llvm_2_9_func::ValueEnumerator VE(*M);
+
+  // Emit blockinfo, which defines the standard abbreviations etc.
+  WriteBlockInfo(VE, Stream);
+
+  // Emit information about parameter attributes.
+  WriteAttributeTable(VE, Stream);
+
+  // Emit information describing all of the types in the module.
+  WriteTypeTable(VE, Stream);
+
+  // Emit top-level description of module, including target triple, inline asm,
+  // descriptors for global variables, and function prototype info.
+  WriteModuleInfo(M, VE, Stream);
+
+  // Emit constants.
+  WriteModuleConstants(VE, Stream);
+
+  // Emit metadata.
+  WriteModuleMetadata(M, VE, Stream);
+
+  // Emit function bodies.
+  for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)
+    if (!F->isDeclaration())
+      WriteFunction(*F, VE, Stream);
+
+  // Emit metadata.
+  WriteModuleMetadataStore(M, Stream);
+
+  // Emit names for globals/functions etc.
+  WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream);
+
+  Stream.ExitBlock();
+}
+
+/// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a
+/// header and trailer to make it compatible with the system archiver.  To do
+/// this we emit the following header, and then emit a trailer that pads the
+/// file out to be a multiple of 16 bytes.
+///
+/// struct bc_header {
+///   uint32_t Magic;         // 0x0B17C0DE
+///   uint32_t Version;       // Version, currently always 0.
+///   uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+///   uint32_t BitcodeSize;   // Size of traditional bitcode file.
+///   uint32_t CPUType;       // CPU specifier.
+///   ... potentially more later ...
+/// };
+enum {
+  DarwinBCSizeFieldOffset = 3*4, // Offset to bitcode_size.
+  DarwinBCHeaderSize = 5*4
+};
+
+static void WriteInt32ToBuffer(uint32_t Value, SmallVectorImpl<char> &Buffer,
+                               uint32_t &Position) {
+  Buffer[Position + 0] = (unsigned char) (Value >>  0);
+  Buffer[Position + 1] = (unsigned char) (Value >>  8);
+  Buffer[Position + 2] = (unsigned char) (Value >> 16);
+  Buffer[Position + 3] = (unsigned char) (Value >> 24);
+  Position += 4;
+}
+
+static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
+                                         const Triple &TT) {
+  unsigned CPUType = ~0U;
+
+  // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*,
+  // armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. The CPUType is a magic
+  // number from /usr/include/mach/machine.h.  It is ok to reproduce the
+  // specific constants here because they are implicitly part of the Darwin ABI.
+  enum {
+    DARWIN_CPU_ARCH_ABI64      = 0x01000000,
+    DARWIN_CPU_TYPE_X86        = 7,
+    DARWIN_CPU_TYPE_ARM        = 12,
+    DARWIN_CPU_TYPE_POWERPC    = 18
+  };
+
+  Triple::ArchType Arch = TT.getArch();
+  if (Arch == Triple::x86_64)
+    CPUType = DARWIN_CPU_TYPE_X86 | DARWIN_CPU_ARCH_ABI64;
+  else if (Arch == Triple::x86)
+    CPUType = DARWIN_CPU_TYPE_X86;
+  else if (Arch == Triple::ppc)
+    CPUType = DARWIN_CPU_TYPE_POWERPC;
+  else if (Arch == Triple::ppc64)
+    CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64;
+  else if (Arch == Triple::arm || Arch == Triple::thumb)
+    CPUType = DARWIN_CPU_TYPE_ARM;
+
+  // Traditional Bitcode starts after header.
+  assert(Buffer.size() >= DarwinBCHeaderSize &&
+         "Expected header size to be reserved");
+  unsigned BCOffset = DarwinBCHeaderSize;
+  unsigned BCSize = Buffer.size()-DarwinBCHeaderSize;
+
+  // Write the magic and version.
+  unsigned Position = 0;
+  WriteInt32ToBuffer(0x0B17C0DE , Buffer, Position);
+  WriteInt32ToBuffer(0          , Buffer, Position); // Version.
+  WriteInt32ToBuffer(BCOffset   , Buffer, Position);
+  WriteInt32ToBuffer(BCSize     , Buffer, Position);
+  WriteInt32ToBuffer(CPUType    , Buffer, Position);
+
+  // If the file is not a multiple of 16 bytes, insert dummy padding.
+  while (Buffer.size() & 15)
+    Buffer.push_back(0);
+}
+
+/// WriteBitcodeToFile - Write the specified module to the specified output
+/// stream.
+void llvm_2_9_func::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
+  SmallVector<char, 1024> Buffer;
+  Buffer.reserve(256*1024);
+
+  // If this is darwin or another generic macho target, reserve space for the
+  // header.
+  Triple TT(M->getTargetTriple());
+  if (TT.isOSDarwin())
+    Buffer.insert(Buffer.begin(), DarwinBCHeaderSize, 0);
+
+  // Emit the module into the buffer.
+  {
+    BitstreamWriter Stream(Buffer);
+
+    // Emit the file header.
+    Stream.Emit((unsigned)'B', 8);
+    Stream.Emit((unsigned)'C', 8);
+    Stream.Emit(0x0, 4);
+    Stream.Emit(0xC, 4);
+    Stream.Emit(0xE, 4);
+    Stream.Emit(0xD, 4);
+
+    // Emit the module.
+    WriteModule(M, Stream);
+  }
+
+  if (TT.isOSDarwin())
+    EmitDarwinBCHeaderAndTrailer(Buffer, TT);
+
+  // Write the generated bitstream to "Out".
+  Out.write((char*)&Buffer.front(), Buffer.size());
+}
diff --git a/slang/BitWriter_2_9_func/BitcodeWriterPass.cpp b/slang/BitWriter_2_9_func/BitcodeWriterPass.cpp
new file mode 100644
index 0000000..fe807d3
--- /dev/null
+++ b/slang/BitWriter_2_9_func/BitcodeWriterPass.cpp
@@ -0,0 +1,46 @@
+//===--- Bitcode/Writer/BitcodeWriterPass.cpp - Bitcode Writer ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// BitcodeWriterPass implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReaderWriter_2_9_func.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+using namespace llvm;
+
+namespace {
+  class WriteBitcodePass : public ModulePass {
+    raw_ostream &OS; // raw_ostream to print on
+
+  public:
+    static char ID; // Pass identification, replacement for typeid
+    explicit WriteBitcodePass(raw_ostream &o)
+      : ModulePass(ID), OS(o) {}
+
+    const char *getPassName() const { return "Bitcode Writer"; }
+
+    bool runOnModule(Module &M) {
+      bool Changed = false;
+      llvm_2_9_func::WriteBitcodeToFile(&M, OS);
+      return Changed;
+    }
+  };
+}
+
+char WriteBitcodePass::ID = 0;
+
+/// createBitcodeWriterPass - Create and return a pass that writes the module
+/// to the specified ostream.
+llvm::ModulePass *llvm_2_9_func::createBitcodeWriterPass(llvm::raw_ostream &Str) {
+  return new WriteBitcodePass(Str);
+}
diff --git a/slang/BitWriter_2_9_func/ReaderWriter_2_9_func.h b/slang/BitWriter_2_9_func/ReaderWriter_2_9_func.h
new file mode 100644
index 0000000..24ecc49
--- /dev/null
+++ b/slang/BitWriter_2_9_func/ReaderWriter_2_9_func.h
@@ -0,0 +1,143 @@
+//===-- llvm/Bitcode/ReaderWriter.h - Bitcode reader/writers ----*- 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 interfaces to read and write LLVM bitcode files/streams.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_2_9_FUNC_H
+#define LLVM_BITCODE_2_9_FUNC_H
+
+#include <string>
+
+namespace llvm {
+  class Module;
+  class MemoryBuffer;
+  class ModulePass;
+  class BitstreamWriter;
+  class LLVMContext;
+  class raw_ostream;
+}  // End llvm namespace
+
+namespace llvm_2_9_func {
+  /// getLazyBitcodeModule - Read the header of the specified bitcode buffer
+  /// and prepare for lazy deserialization of function bodies.  If successful,
+  /// this takes ownership of 'buffer' and returns a non-null pointer.  On
+  /// error, this returns null, *does not* take ownership of Buffer, and fills
+  /// in *ErrMsg with an error description if ErrMsg is non-null.
+  llvm::Module *getLazyBitcodeModule(llvm::MemoryBuffer *Buffer,
+                               llvm::LLVMContext& Context,
+                               std::string *ErrMsg = 0);
+
+  /// getBitcodeTargetTriple - Read the header of the specified bitcode
+  /// buffer and extract just the triple information. If successful,
+  /// this returns a string and *does not* take ownership
+  /// of 'buffer'. On error, this returns "", and fills in *ErrMsg
+  /// if ErrMsg is non-null.
+  std::string getBitcodeTargetTriple(llvm::MemoryBuffer *Buffer,
+                                     llvm::LLVMContext& Context,
+                                     std::string *ErrMsg = 0);
+
+  /// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+  /// If an error occurs, this returns null and fills in *ErrMsg if it is
+  /// non-null.  This method *never* takes ownership of Buffer.
+  llvm::Module *ParseBitcodeFile(llvm::MemoryBuffer *Buffer, llvm::LLVMContext& Context,
+                           std::string *ErrMsg = 0);
+
+  /// WriteBitcodeToFile - Write the specified module to the specified
+  /// raw output stream.  For streams where it matters, the given stream
+  /// should be in "binary" mode.
+  void WriteBitcodeToFile(const llvm::Module *M, llvm::raw_ostream &Out);
+
+  /// createBitcodeWriterPass - Create and return a pass that writes the module
+  /// to the specified ostream.
+  llvm::ModulePass *createBitcodeWriterPass(llvm::raw_ostream &Str);
+
+
+  /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
+  /// for an LLVM IR bitcode wrapper.
+  ///
+  static inline bool isBitcodeWrapper(const unsigned char *BufPtr,
+                                      const unsigned char *BufEnd) {
+    // See if you can find the hidden message in the magic bytes :-).
+    // (Hint: it's a little-endian encoding.)
+    return BufPtr != BufEnd &&
+           BufPtr[0] == 0xDE &&
+           BufPtr[1] == 0xC0 &&
+           BufPtr[2] == 0x17 &&
+           BufPtr[3] == 0x0B;
+  }
+
+  /// isRawBitcode - Return true if the given bytes are the magic bytes for
+  /// raw LLVM IR bitcode (without a wrapper).
+  ///
+  static inline bool isRawBitcode(const unsigned char *BufPtr,
+                                  const unsigned char *BufEnd) {
+    // These bytes sort of have a hidden message, but it's not in
+    // little-endian this time, and it's a little redundant.
+    return BufPtr != BufEnd &&
+           BufPtr[0] == 'B' &&
+           BufPtr[1] == 'C' &&
+           BufPtr[2] == 0xc0 &&
+           BufPtr[3] == 0xde;
+  }
+
+  /// isBitcode - Return true if the given bytes are the magic bytes for
+  /// LLVM IR bitcode, either with or without a wrapper.
+  ///
+  static bool inline isBitcode(const unsigned char *BufPtr,
+                               const unsigned char *BufEnd) {
+    return isBitcodeWrapper(BufPtr, BufEnd) ||
+           isRawBitcode(BufPtr, BufEnd);
+  }
+
+  /// SkipBitcodeWrapperHeader - Some systems wrap bc files with a special
+  /// header for padding or other reasons.  The format of this header is:
+  ///
+  /// struct bc_header {
+  ///   uint32_t Magic;         // 0x0B17C0DE
+  ///   uint32_t Version;       // Version, currently always 0.
+  ///   uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+  ///   uint32_t BitcodeSize;   // Size of traditional bitcode file.
+  ///   ... potentially other gunk ...
+  /// };
+  ///
+  /// This function is called when we find a file with a matching magic number.
+  /// In this case, skip down to the subsection of the file that is actually a
+  /// BC file.
+  static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr,
+                                              unsigned char *&BufEnd) {
+    enum {
+      KnownHeaderSize = 4*4,  // Size of header we read.
+      OffsetField = 2*4,      // Offset in bytes to Offset field.
+      SizeField = 3*4         // Offset in bytes to Size field.
+    };
+
+    // Must contain the header!
+    if (BufEnd-BufPtr < KnownHeaderSize) return true;
+
+    unsigned Offset = ( BufPtr[OffsetField  ]        |
+                       (BufPtr[OffsetField+1] << 8)  |
+                       (BufPtr[OffsetField+2] << 16) |
+                       (BufPtr[OffsetField+3] << 24));
+    unsigned Size   = ( BufPtr[SizeField    ]        |
+                       (BufPtr[SizeField  +1] << 8)  |
+                       (BufPtr[SizeField  +2] << 16) |
+                       (BufPtr[SizeField  +3] << 24));
+
+    // Verify that Offset+Size fits in the file.
+    if (Offset+Size > unsigned(BufEnd-BufPtr))
+      return true;
+    BufPtr += Offset;
+    BufEnd = BufPtr+Size;
+    return false;
+  }
+}  // End llvm_2_9_func namespace
+
+#endif
diff --git a/slang/BitWriter_2_9_func/ValueEnumerator.cpp b/slang/BitWriter_2_9_func/ValueEnumerator.cpp
new file mode 100644
index 0000000..ce785da
--- /dev/null
+++ b/slang/BitWriter_2_9_func/ValueEnumerator.cpp
@@ -0,0 +1,546 @@
+//===-- ValueEnumerator.cpp - Number values and types for bitcode writer --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ValueEnumerator class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ValueEnumerator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+using namespace llvm;
+
+namespace llvm_2_9_func {
+
+static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
+  return V.first->getType()->isIntOrIntVectorTy();
+}
+
+/// ValueEnumerator - Enumerate module-level information.
+ValueEnumerator::ValueEnumerator(const llvm::Module &M)
+    : HasMDString(false), HasDILocation(false) {
+  // Enumerate the global variables.
+  for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I)
+    EnumerateValue(&*I);
+
+  // Enumerate the functions.
+  for (llvm::Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
+    EnumerateValue(&*I);
+    EnumerateAttributes(cast<Function>(I)->getAttributes());
+  }
+
+  // Enumerate the aliases.
+  for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
+       I != E; ++I)
+    EnumerateValue(&*I);
+
+  // Remember what is the cutoff between globalvalue's and other constants.
+  unsigned FirstConstant = Values.size();
+
+  // Enumerate the global variable initializers.
+  for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I)
+    if (I->hasInitializer())
+      EnumerateValue(I->getInitializer());
+
+  // Enumerate the aliasees.
+  for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
+       I != E; ++I)
+    EnumerateValue(I->getAliasee());
+
+  // Enumerate the metadata type.
+  //
+  // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode
+  // only encodes the metadata type when it's used as a value.
+  EnumerateType(Type::getMetadataTy(M.getContext()));
+
+  // Insert constants and metadata that are named at module level into the slot
+  // pool so that the module symbol table can refer to them...
+  EnumerateValueSymbolTable(M.getValueSymbolTable());
+  EnumerateNamedMetadata(M);
+
+  SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
+
+  // Enumerate types used by function bodies and argument lists.
+  for (const Function &F : M) {
+    for (const Argument &A : F.args())
+      EnumerateType(A.getType());
+
+    for (const BasicBlock &BB : F)
+      for (const Instruction &I : BB) {
+        for (const Use &Op : I.operands()) {
+          auto *MD = dyn_cast<MetadataAsValue>(&Op);
+          if (!MD) {
+            EnumerateOperandType(Op);
+            continue;
+          }
+
+          // Local metadata is enumerated during function-incorporation.
+          if (isa<LocalAsMetadata>(MD->getMetadata()))
+            continue;
+
+          EnumerateMetadata(MD->getMetadata());
+        }
+        EnumerateType(I.getType());
+        if (const CallInst *CI = dyn_cast<CallInst>(&I))
+          EnumerateAttributes(CI->getAttributes());
+        else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I))
+          EnumerateAttributes(II->getAttributes());
+
+        // Enumerate metadata attached with this instruction.
+        MDs.clear();
+        I.getAllMetadataOtherThanDebugLoc(MDs);
+        for (unsigned i = 0, e = MDs.size(); i != e; ++i)
+          EnumerateMetadata(MDs[i].second);
+
+        // Don't enumerate the location directly -- it has a special record
+        // type -- but enumerate its operands.
+        if (DILocation *L = I.getDebugLoc())
+          EnumerateMDNodeOperands(L);
+      }
+  }
+
+  // Optimize constant ordering.
+  OptimizeConstants(FirstConstant, Values.size());
+}
+
+unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
+  InstructionMapType::const_iterator I = InstructionMap.find(Inst);
+  assert(I != InstructionMap.end() && "Instruction is not mapped!");
+  return I->second;
+}
+
+void ValueEnumerator::setInstructionID(const Instruction *I) {
+  InstructionMap[I] = InstructionCount++;
+}
+
+unsigned ValueEnumerator::getValueID(const Value *V) const {
+  if (auto *MD = dyn_cast<MetadataAsValue>(V))
+    return getMetadataID(MD->getMetadata());
+
+  ValueMapType::const_iterator I = ValueMap.find(V);
+  assert(I != ValueMap.end() && "Value not in slotcalculator!");
+  return I->second-1;
+}
+
+void ValueEnumerator::dump() const {
+  print(dbgs(), ValueMap, "Default");
+  dbgs() << '\n';
+  print(dbgs(), MDValueMap, "MetaData");
+  dbgs() << '\n';
+}
+
+void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
+                            const char *Name) const {
+
+  OS << "Map Name: " << Name << "\n";
+  OS << "Size: " << Map.size() << "\n";
+  for (ValueMapType::const_iterator I = Map.begin(),
+         E = Map.end(); I != E; ++I) {
+
+    const Value *V = I->first;
+    if (V->hasName())
+      OS << "Value: " << V->getName();
+    else
+      OS << "Value: [null]\n";
+    V->dump();
+
+    OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
+    for (const Use &U : V->uses()) {
+      if (&U != &*V->use_begin())
+        OS << ",";
+      if(U->hasName())
+        OS << " " << U->getName();
+      else
+        OS << " [null]";
+
+    }
+    OS <<  "\n\n";
+  }
+}
+
+void ValueEnumerator::print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+                            const char *Name) const {
+
+  OS << "Map Name: " << Name << "\n";
+  OS << "Size: " << Map.size() << "\n";
+  for (auto I = Map.begin(), E = Map.end(); I != E; ++I) {
+    const llvm::Metadata *MD = I->first;
+    OS << "Metadata: slot = " << I->second << "\n";
+    MD->print(OS);
+  }
+}
+
+
+// Optimize constant ordering.
+namespace {
+  struct CstSortPredicate {
+    ValueEnumerator &VE;
+    explicit CstSortPredicate(ValueEnumerator &ve) : VE(ve) {}
+    bool operator()(const std::pair<const Value*, unsigned> &LHS,
+                    const std::pair<const Value*, unsigned> &RHS) {
+      // Sort by plane.
+      if (LHS.first->getType() != RHS.first->getType())
+        return VE.getTypeID(LHS.first->getType()) <
+               VE.getTypeID(RHS.first->getType());
+      // Then by frequency.
+      return LHS.second > RHS.second;
+    }
+  };
+}
+
+/// OptimizeConstants - Reorder constant pool for denser encoding.
+void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {
+  if (CstStart == CstEnd || CstStart+1 == CstEnd) return;
+
+  CstSortPredicate P(*this);
+  std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P);
+
+  // Ensure that integer and vector of integer constants are at the start of the
+  // constant pool.  This is important so that GEP structure indices come before
+  // gep constant exprs.
+  std::partition(Values.begin()+CstStart, Values.begin()+CstEnd,
+                 isIntOrIntVectorValue);
+
+  // Rebuild the modified portion of ValueMap.
+  for (; CstStart != CstEnd; ++CstStart)
+    ValueMap[Values[CstStart].first] = CstStart+1;
+}
+
+
+/// EnumerateValueSymbolTable - Insert all of the values in the specified symbol
+/// table into the values table.
+void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
+  for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end();
+       VI != VE; ++VI)
+    EnumerateValue(VI->getValue());
+}
+
+/// EnumerateNamedMetadata - Insert all of the values referenced by
+/// named metadata in the specified module.
+void ValueEnumerator::EnumerateNamedMetadata(const llvm::Module &M) {
+  for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
+                                             E = M.named_metadata_end();
+       I != E; ++I)
+    EnumerateNamedMDNode(&*I);
+}
+
+void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
+  for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i)
+    EnumerateMetadata(MD->getOperand(i));
+}
+
+/// EnumerateMDNodeOperands - Enumerate all non-function-local values
+/// and types referenced by the given MDNode.
+void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) {
+  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+    Metadata *MD = N->getOperand(i);
+    if (!MD)
+      continue;
+    assert(!isa<LocalAsMetadata>(MD) && "MDNodes cannot be function-local");
+    EnumerateMetadata(MD);
+  }
+}
+
+void ValueEnumerator::EnumerateMetadata(const llvm::Metadata *MD) {
+  assert(
+      (isa<MDNode>(MD) || isa<MDString>(MD) || isa<ConstantAsMetadata>(MD)) &&
+      "Invalid metadata kind");
+
+  // Insert a dummy ID to block the co-recursive call to
+  // EnumerateMDNodeOperands() from re-visiting MD in a cyclic graph.
+  //
+  // Return early if there's already an ID.
+  if (!MDValueMap.insert(std::make_pair(MD, 0)).second)
+    return;
+
+  // Visit operands first to minimize RAUW.
+  if (auto *N = dyn_cast<MDNode>(MD))
+    EnumerateMDNodeOperands(N);
+  else if (auto *C = dyn_cast<ConstantAsMetadata>(MD))
+    EnumerateValue(C->getValue());
+
+  HasMDString |= isa<MDString>(MD);
+  HasDILocation |= isa<DILocation>(MD);
+
+  // Replace the dummy ID inserted above with the correct one.  MDValueMap may
+  // have changed by inserting operands, so we need a fresh lookup here.
+  MDs.push_back(MD);
+  MDValueMap[MD] = MDs.size();
+}
+
+/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata
+/// information reachable from the metadata.
+void ValueEnumerator::EnumerateFunctionLocalMetadata(
+    const llvm::LocalAsMetadata *Local) {
+  // Check to see if it's already in!
+  unsigned &MDValueID = MDValueMap[Local];
+  if (MDValueID)
+    return;
+
+  MDs.push_back(Local);
+  MDValueID = MDs.size();
+
+  EnumerateValue(Local->getValue());
+
+  // Also, collect all function-local metadata for easy access.
+  FunctionLocalMDs.push_back(Local);
+}
+
+void ValueEnumerator::EnumerateValue(const Value *V) {
+  assert(!V->getType()->isVoidTy() && "Can't insert void values!");
+  assert(!isa<MetadataAsValue>(V) && "EnumerateValue doesn't handle Metadata!");
+
+  // Check to see if it's already in!
+  unsigned &ValueID = ValueMap[V];
+  if (ValueID) {
+    // Increment use count.
+    Values[ValueID-1].second++;
+    return;
+  }
+
+  // Enumerate the type of this value.
+  EnumerateType(V->getType());
+
+  if (const Constant *C = dyn_cast<Constant>(V)) {
+    if (isa<GlobalValue>(C)) {
+      // Initializers for globals are handled explicitly elsewhere.
+    } else if (C->getNumOperands()) {
+      // If a constant has operands, enumerate them.  This makes sure that if a
+      // constant has uses (for example an array of const ints), that they are
+      // inserted also.
+
+      // We prefer to enumerate them with values before we enumerate the user
+      // itself.  This makes it more likely that we can avoid forward references
+      // in the reader.  We know that there can be no cycles in the constants
+      // graph that don't go through a global variable.
+      for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
+           I != E; ++I)
+        if (!isa<BasicBlock>(*I)) // Don't enumerate BB operand to BlockAddress.
+          EnumerateValue(*I);
+
+      // Finally, add the value.  Doing this could make the ValueID reference be
+      // dangling, don't reuse it.
+      Values.push_back(std::make_pair(V, 1U));
+      ValueMap[V] = Values.size();
+      return;
+    } else if (const ConstantDataSequential *CDS =
+               dyn_cast<ConstantDataSequential>(C)) {
+      // For our legacy handling of the new ConstantDataSequential type, we
+      // need to enumerate the individual elements, as well as mark the
+      // outer constant as used.
+      for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+        EnumerateValue(CDS->getElementAsConstant(i));
+      Values.push_back(std::make_pair(V, 1U));
+      ValueMap[V] = Values.size();
+      return;
+    }
+  }
+
+  // Add the value.
+  Values.push_back(std::make_pair(V, 1U));
+  ValueID = Values.size();
+}
+
+
+void ValueEnumerator::EnumerateType(Type *Ty) {
+  unsigned *TypeID = &TypeMap[Ty];
+
+  // We've already seen this type.
+  if (*TypeID)
+    return;
+
+  // If it is a non-anonymous struct, mark the type as being visited so that we
+  // don't recursively visit it.  This is safe because we allow forward
+  // references of these in the bitcode reader.
+  if (StructType *STy = dyn_cast<StructType>(Ty))
+    if (!STy->isLiteral())
+      *TypeID = ~0U;
+
+  // Enumerate all of the subtypes before we enumerate this type.  This ensures
+  // that the type will be enumerated in an order that can be directly built.
+  for (Type *SubTy : Ty->subtypes())
+    EnumerateType(SubTy);
+
+  // Refresh the TypeID pointer in case the table rehashed.
+  TypeID = &TypeMap[Ty];
+
+  // Check to see if we got the pointer another way.  This can happen when
+  // enumerating recursive types that hit the base case deeper than they start.
+  //
+  // If this is actually a struct that we are treating as forward ref'able,
+  // then emit the definition now that all of its contents are available.
+  if (*TypeID && *TypeID != ~0U)
+    return;
+
+  // Add this type now that its contents are all happily enumerated.
+  Types.push_back(Ty);
+
+  *TypeID = Types.size();
+}
+
+// Enumerate the types for the specified value.  If the value is a constant,
+// walk through it, enumerating the types of the constant.
+void ValueEnumerator::EnumerateOperandType(const Value *V) {
+  EnumerateType(V->getType());
+
+  if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
+    assert(!isa<LocalAsMetadata>(MD->getMetadata()) &&
+           "Function-local metadata should be left for later");
+
+    EnumerateMetadata(MD->getMetadata());
+    return;
+  }
+
+  const Constant *C = dyn_cast<Constant>(V);
+  if (!C)
+    return;
+
+  // If this constant is already enumerated, ignore it, we know its type must
+  // be enumerated.
+  if (ValueMap.count(C))
+    return;
+
+  // This constant may have operands, make sure to enumerate the types in
+  // them.
+  for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
+    const Value *Op = C->getOperand(i);
+
+    // Don't enumerate basic blocks here, this happens as operands to
+    // blockaddress.
+    if (isa<BasicBlock>(Op))
+      continue;
+
+    EnumerateOperandType(Op);
+  }
+}
+
+void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
+  if (PAL.isEmpty()) return;  // null is always 0.
+
+  // Do a lookup.
+  unsigned &Entry = AttributeMap[PAL];
+  if (Entry == 0) {
+    // Never saw this before, add it.
+    Attribute.push_back(PAL);
+    Entry = Attribute.size();
+  }
+
+  // Do lookups for all attribute groups.
+  for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) {
+    AttributeSet AS = PAL.getSlotAttributes(i);
+    unsigned &Entry = AttributeGroupMap[AS];
+    if (Entry == 0) {
+      AttributeGroups.push_back(AS);
+      Entry = AttributeGroups.size();
+    }
+  }
+}
+
+void ValueEnumerator::incorporateFunction(const Function &F) {
+  InstructionCount = 0;
+  NumModuleValues = Values.size();
+  NumModuleMDs = MDs.size();
+
+  // Adding function arguments to the value table.
+  for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
+       I != E; ++I)
+    EnumerateValue(&*I);
+
+  FirstFuncConstantID = Values.size();
+
+  // Add all function-level constants to the value table.
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I)
+      for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
+           OI != E; ++OI) {
+        if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||
+            isa<InlineAsm>(*OI))
+          EnumerateValue(*OI);
+      }
+    BasicBlocks.push_back(&*BB);
+    ValueMap[&*BB] = BasicBlocks.size();
+  }
+
+  // Optimize the constant layout.
+  OptimizeConstants(FirstFuncConstantID, Values.size());
+
+  // Add the function's parameter attributes so they are available for use in
+  // the function's instruction.
+  EnumerateAttributes(F.getAttributes());
+
+  FirstInstID = Values.size();
+
+  SmallVector<llvm::LocalAsMetadata *, 8> FnLocalMDVector;
+  // Add all of the instructions.
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
+      for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
+           OI != E; ++OI) {
+        if (auto *MD = dyn_cast<llvm::MetadataAsValue>(&*OI))
+          if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata()))
+            // Enumerate metadata after the instructions they might refer to.
+            FnLocalMDVector.push_back(Local);
+      }
+
+      if (!I->getType()->isVoidTy())
+        EnumerateValue(&*I);
+    }
+  }
+
+  // Add all of the function-local metadata.
+  for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i)
+    EnumerateFunctionLocalMetadata(FnLocalMDVector[i]);
+}
+
+void ValueEnumerator::purgeFunction() {
+  /// Remove purged values from the ValueMap.
+  for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i)
+    ValueMap.erase(Values[i].first);
+  for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i)
+    MDValueMap.erase(MDs[i]);
+  for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
+    ValueMap.erase(BasicBlocks[i]);
+
+  Values.resize(NumModuleValues);
+  MDs.resize(NumModuleMDs);
+  BasicBlocks.clear();
+  FunctionLocalMDs.clear();
+}
+
+static void IncorporateFunctionInfoGlobalBBIDs(const Function *F,
+                                 DenseMap<const BasicBlock*, unsigned> &IDMap) {
+  unsigned Counter = 0;
+  for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+    IDMap[&*BB] = ++Counter;
+}
+
+/// getGlobalBasicBlockID - This returns the function-specific ID for the
+/// specified basic block.  This is relatively expensive information, so it
+/// should only be used by rare constructs such as address-of-label.
+unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const {
+  unsigned &Idx = GlobalBasicBlockIDs[BB];
+  if (Idx != 0)
+    return Idx-1;
+
+  IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs);
+  return getGlobalBasicBlockID(BB);
+}
+
+}  // end llvm_2_9_func namespace
diff --git a/slang/BitWriter_2_9_func/ValueEnumerator.h b/slang/BitWriter_2_9_func/ValueEnumerator.h
new file mode 100644
index 0000000..f26b986
--- /dev/null
+++ b/slang/BitWriter_2_9_func/ValueEnumerator.h
@@ -0,0 +1,195 @@
+//===-- Bitcode/Writer/ValueEnumerator.h - Number values --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class gives values and types Unique ID's.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef VALUE_ENUMERATOR_H
+#define VALUE_ENUMERATOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Attributes.h"
+#include <vector>
+
+namespace llvm {
+
+class Type;
+class Value;
+class Instruction;
+class BasicBlock;
+class Function;
+class Module;
+class Metadata;
+class LocalAsMetadata;
+class MDNode;
+class NamedMDNode;
+class AttributeSet;
+class ValueSymbolTable;
+class MDSymbolTable;
+class raw_ostream;
+
+}  // end llvm namespace
+
+namespace llvm_2_9_func {
+
+class ValueEnumerator {
+public:
+  typedef std::vector<llvm::Type*> TypeList;
+
+  // For each value, we remember its Value* and occurrence frequency.
+  typedef std::vector<std::pair<const llvm::Value*, unsigned> > ValueList;
+private:
+  typedef llvm::DenseMap<llvm::Type*, unsigned> TypeMapType;
+  TypeMapType TypeMap;
+  TypeList Types;
+
+  typedef llvm::DenseMap<const llvm::Value*, unsigned> ValueMapType;
+  ValueMapType ValueMap;
+  ValueList Values;
+
+
+  std::vector<const llvm::Metadata *> MDs;
+  llvm::SmallVector<const llvm::LocalAsMetadata *, 8> FunctionLocalMDs;
+  typedef llvm::DenseMap<const llvm::Metadata *, unsigned> MetadataMapType;
+  MetadataMapType MDValueMap;
+  bool HasMDString;
+  bool HasDILocation;
+
+  typedef llvm::DenseMap<llvm::AttributeSet, unsigned> AttributeGroupMapType;
+  AttributeGroupMapType AttributeGroupMap;
+  std::vector<llvm::AttributeSet> AttributeGroups;
+
+  typedef llvm::DenseMap<llvm::AttributeSet, unsigned> AttributeMapType;
+  AttributeMapType AttributeMap;
+  std::vector<llvm::AttributeSet> Attribute;
+
+  /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
+  /// the "getGlobalBasicBlockID" method.
+  mutable llvm::DenseMap<const llvm::BasicBlock*, unsigned> GlobalBasicBlockIDs;
+
+  typedef llvm::DenseMap<const llvm::Instruction*, unsigned> InstructionMapType;
+  InstructionMapType InstructionMap;
+  unsigned InstructionCount;
+
+  /// BasicBlocks - This contains all the basic blocks for the currently
+  /// incorporated function.  Their reverse mapping is stored in ValueMap.
+  std::vector<const llvm::BasicBlock*> BasicBlocks;
+
+  /// When a function is incorporated, this is the size of the Values list
+  /// before incorporation.
+  unsigned NumModuleValues;
+
+  /// When a function is incorporated, this is the size of the MDValues list
+  /// before incorporation.
+  unsigned NumModuleMDs;
+
+  unsigned FirstFuncConstantID;
+  unsigned FirstInstID;
+
+  ValueEnumerator(const ValueEnumerator &) = delete;
+  void operator=(const ValueEnumerator &) = delete;
+public:
+  explicit ValueEnumerator(const llvm::Module &M);
+
+  void dump() const;
+  void print(llvm::raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
+  void print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+             const char *Name) const;
+
+  unsigned getValueID(const llvm::Value *V) const;
+  unsigned getMetadataID(const llvm::Metadata *MD) const {
+    auto ID = getMetadataOrNullID(MD);
+    assert(ID != 0 && "Metadata not in slotcalculator!");
+    return ID - 1;
+  }
+  unsigned getMetadataOrNullID(const llvm::Metadata *MD) const {
+    return MDValueMap.lookup(MD);
+  }
+
+  bool hasMDString() const { return HasMDString; }
+  bool hasDILocation() const { return HasDILocation; }
+
+  unsigned getTypeID(llvm::Type *T) const {
+    TypeMapType::const_iterator I = TypeMap.find(T);
+    assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
+    return I->second-1;
+  }
+
+  unsigned getInstructionID(const llvm::Instruction *I) const;
+  void setInstructionID(const llvm::Instruction *I);
+
+  unsigned getAttributeID(llvm::AttributeSet PAL) const {
+    if (PAL.isEmpty()) return 0;  // Null maps to zero.
+    AttributeMapType::const_iterator I = AttributeMap.find(PAL);
+    assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!");
+    return I->second;
+  }
+
+  unsigned getAttributeGroupID(llvm::AttributeSet PAL) const {
+    if (PAL.isEmpty()) return 0;  // Null maps to zero.
+    AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL);
+    assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
+    return I->second;
+  }
+
+  /// getFunctionConstantRange - Return the range of values that corresponds to
+  /// function-local constants.
+  void getFunctionConstantRange(unsigned &Start, unsigned &End) const {
+    Start = FirstFuncConstantID;
+    End = FirstInstID;
+  }
+
+  const ValueList &getValues() const { return Values; }
+  const std::vector<const llvm::Metadata *> &getMDs() const { return MDs; }
+  const llvm::SmallVectorImpl<const llvm::LocalAsMetadata *> &getFunctionLocalMDs() const {
+    return FunctionLocalMDs;
+  }
+  const TypeList &getTypes() const { return Types; }
+  const std::vector<const llvm::BasicBlock*> &getBasicBlocks() const {
+    return BasicBlocks;
+  }
+  const std::vector<llvm::AttributeSet> &getAttributes() const {
+    return Attribute;
+  }
+  const std::vector<llvm::AttributeSet> &getAttributeGroups() const {
+    return AttributeGroups;
+  }
+
+  /// getGlobalBasicBlockID - This returns the function-specific ID for the
+  /// specified basic block.  This is relatively expensive information, so it
+  /// should only be used by rare constructs such as address-of-label.
+  unsigned getGlobalBasicBlockID(const llvm::BasicBlock *BB) const;
+
+  /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
+  /// use these two methods to get its data into the ValueEnumerator!
+  ///
+  void incorporateFunction(const llvm::Function &F);
+  void purgeFunction();
+
+private:
+  void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
+
+  void EnumerateMDNodeOperands(const llvm::MDNode *N);
+  void EnumerateMetadata(const llvm::Metadata *MD);
+  void EnumerateFunctionLocalMetadata(const llvm::LocalAsMetadata *Local);
+  void EnumerateNamedMDNode(const llvm::NamedMDNode *NMD);
+  void EnumerateValue(const llvm::Value *V);
+  void EnumerateType(llvm::Type *T);
+  void EnumerateOperandType(const llvm::Value *V);
+  void EnumerateAttributes(llvm::AttributeSet PAL);
+
+  void EnumerateValueSymbolTable(const llvm::ValueSymbolTable &ST);
+  void EnumerateNamedMetadata(const llvm::Module &M);
+};
+
+}  // End llvm_2_9_func namespace
+
+#endif
diff --git a/slang/BitWriter_3_2/Android.mk b/slang/BitWriter_3_2/Android.mk
new file mode 100644
index 0000000..743aeaf
--- /dev/null
+++ b/slang/BitWriter_3_2/Android.mk
@@ -0,0 +1,45 @@
+LOCAL_PATH:= $(call my-dir)
+
+LLVM_ROOT_PATH := $(LOCAL_PATH)/../../../../external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+
+bitcode_writer_3_2_SRC_FILES :=	\
+	BitcodeWriter.cpp	\
+	BitcodeWriterPass.cpp	\
+	ValueEnumerator.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS += $(local_cflags_for_slang)
+LOCAL_C_INCLUDES += frameworks/compile/slang
+
+LOCAL_SRC_FILES := $(bitcode_writer_3_2_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMBitWriter_3_2
+
+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
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS += $(local_cflags_for_slang)
+LOCAL_C_INCLUDES += frameworks/compile/slang
+
+LOCAL_SRC_FILES := $(bitcode_writer_3_2_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMBitWriter_3_2
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_ATTRIBUTES_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
+
+
diff --git a/slang/BitWriter_3_2/BitcodeWriter.cpp b/slang/BitWriter_3_2/BitcodeWriter.cpp
new file mode 100644
index 0000000..7618198
--- /dev/null
+++ b/slang/BitWriter_3_2/BitcodeWriter.cpp
@@ -0,0 +1,1876 @@
+//===--- Bitcode/Writer/BitcodeWriter.cpp - Bitcode Writer ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Bitcode writer implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReaderWriter_3_2.h"
+#include "legacy_bitcode.h"
+#include "ValueEnumerator.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/UseListOrder.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cctype>
+#include <map>
+using namespace llvm;
+
+/// These are manifest constants used by the bitcode writer. They do not need to
+/// be kept in sync with the reader, but need to be consistent within this file.
+enum {
+  // VALUE_SYMTAB_BLOCK abbrev id's.
+  VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+  VST_ENTRY_7_ABBREV,
+  VST_ENTRY_6_ABBREV,
+  VST_BBENTRY_6_ABBREV,
+
+  // CONSTANTS_BLOCK abbrev id's.
+  CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+  CONSTANTS_INTEGER_ABBREV,
+  CONSTANTS_CE_CAST_Abbrev,
+  CONSTANTS_NULL_Abbrev,
+
+  // FUNCTION_BLOCK abbrev id's.
+  FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+  FUNCTION_INST_BINOP_ABBREV,
+  FUNCTION_INST_BINOP_FLAGS_ABBREV,
+  FUNCTION_INST_CAST_ABBREV,
+  FUNCTION_INST_RET_VOID_ABBREV,
+  FUNCTION_INST_RET_VAL_ABBREV,
+  FUNCTION_INST_UNREACHABLE_ABBREV
+};
+
+static unsigned GetEncodedCastOpcode(unsigned Opcode) {
+  switch (Opcode) {
+  default: llvm_unreachable("Unknown cast instruction!");
+  case Instruction::Trunc   : return bitc::CAST_TRUNC;
+  case Instruction::ZExt    : return bitc::CAST_ZEXT;
+  case Instruction::SExt    : return bitc::CAST_SEXT;
+  case Instruction::FPToUI  : return bitc::CAST_FPTOUI;
+  case Instruction::FPToSI  : return bitc::CAST_FPTOSI;
+  case Instruction::UIToFP  : return bitc::CAST_UITOFP;
+  case Instruction::SIToFP  : return bitc::CAST_SITOFP;
+  case Instruction::FPTrunc : return bitc::CAST_FPTRUNC;
+  case Instruction::FPExt   : return bitc::CAST_FPEXT;
+  case Instruction::PtrToInt: return bitc::CAST_PTRTOINT;
+  case Instruction::IntToPtr: return bitc::CAST_INTTOPTR;
+  case Instruction::BitCast : return bitc::CAST_BITCAST;
+  }
+}
+
+static unsigned GetEncodedBinaryOpcode(unsigned Opcode) {
+  switch (Opcode) {
+  default: llvm_unreachable("Unknown binary instruction!");
+  case Instruction::Add:
+  case Instruction::FAdd: return bitc::BINOP_ADD;
+  case Instruction::Sub:
+  case Instruction::FSub: return bitc::BINOP_SUB;
+  case Instruction::Mul:
+  case Instruction::FMul: return bitc::BINOP_MUL;
+  case Instruction::UDiv: return bitc::BINOP_UDIV;
+  case Instruction::FDiv:
+  case Instruction::SDiv: return bitc::BINOP_SDIV;
+  case Instruction::URem: return bitc::BINOP_UREM;
+  case Instruction::FRem:
+  case Instruction::SRem: return bitc::BINOP_SREM;
+  case Instruction::Shl:  return bitc::BINOP_SHL;
+  case Instruction::LShr: return bitc::BINOP_LSHR;
+  case Instruction::AShr: return bitc::BINOP_ASHR;
+  case Instruction::And:  return bitc::BINOP_AND;
+  case Instruction::Or:   return bitc::BINOP_OR;
+  case Instruction::Xor:  return bitc::BINOP_XOR;
+  }
+}
+
+static unsigned GetEncodedRMWOperation(AtomicRMWInst::BinOp Op) {
+  switch (Op) {
+  default: llvm_unreachable("Unknown RMW operation!");
+  case AtomicRMWInst::Xchg: return bitc::RMW_XCHG;
+  case AtomicRMWInst::Add: return bitc::RMW_ADD;
+  case AtomicRMWInst::Sub: return bitc::RMW_SUB;
+  case AtomicRMWInst::And: return bitc::RMW_AND;
+  case AtomicRMWInst::Nand: return bitc::RMW_NAND;
+  case AtomicRMWInst::Or: return bitc::RMW_OR;
+  case AtomicRMWInst::Xor: return bitc::RMW_XOR;
+  case AtomicRMWInst::Max: return bitc::RMW_MAX;
+  case AtomicRMWInst::Min: return bitc::RMW_MIN;
+  case AtomicRMWInst::UMax: return bitc::RMW_UMAX;
+  case AtomicRMWInst::UMin: return bitc::RMW_UMIN;
+  }
+}
+
+static unsigned GetEncodedOrdering(AtomicOrdering Ordering) {
+  switch (Ordering) {
+  case NotAtomic: return bitc::ORDERING_NOTATOMIC;
+  case Unordered: return bitc::ORDERING_UNORDERED;
+  case Monotonic: return bitc::ORDERING_MONOTONIC;
+  case Acquire: return bitc::ORDERING_ACQUIRE;
+  case Release: return bitc::ORDERING_RELEASE;
+  case AcquireRelease: return bitc::ORDERING_ACQREL;
+  case SequentiallyConsistent: return bitc::ORDERING_SEQCST;
+  }
+  llvm_unreachable("Invalid ordering");
+}
+
+static unsigned GetEncodedSynchScope(SynchronizationScope SynchScope) {
+  switch (SynchScope) {
+  case SingleThread: return bitc::SYNCHSCOPE_SINGLETHREAD;
+  case CrossThread: return bitc::SYNCHSCOPE_CROSSTHREAD;
+  }
+  llvm_unreachable("Invalid synch scope");
+}
+
+static void WriteStringRecord(unsigned Code, StringRef Str,
+                              unsigned AbbrevToUse, BitstreamWriter &Stream) {
+  SmallVector<unsigned, 64> Vals;
+
+  // Code: [strchar x N]
+  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+    if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i]))
+      AbbrevToUse = 0;
+    Vals.push_back(Str[i]);
+  }
+
+  // Emit the finished record.
+  Stream.EmitRecord(Code, Vals, AbbrevToUse);
+}
+
+// Emit information about parameter attributes.
+static void WriteAttributeTable(const llvm_3_2::ValueEnumerator &VE,
+                                BitstreamWriter &Stream) {
+  const std::vector<AttributeSet> &Attrs = VE.getAttributes();
+  if (Attrs.empty()) return;
+
+  Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3);
+
+  SmallVector<uint64_t, 64> Record;
+  for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
+    const AttributeSet &A = Attrs[i];
+    for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) {
+      Record.push_back(A.getSlotIndex(i));
+      Record.push_back(encodeLLVMAttributesForBitcode(A, A.getSlotIndex(i)));
+    }
+
+    // This needs to use the 3.2 entry type
+    Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY_OLD, Record);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+/// WriteTypeTable - Write out the type table for a module.
+static void WriteTypeTable(const llvm_3_2::ValueEnumerator &VE,
+                           BitstreamWriter &Stream) {
+  const llvm_3_2::ValueEnumerator::TypeList &TypeList = VE.getTypes();
+
+  Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */);
+  SmallVector<uint64_t, 64> TypeVals;
+
+  uint64_t NumBits = Log2_32_Ceil(VE.getTypes().size()+1);
+
+  // Abbrev for TYPE_CODE_POINTER.
+  BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+  Abbv->Add(BitCodeAbbrevOp(0));  // Addrspace = 0
+  unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_FUNCTION.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // isvararg
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+  unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_STRUCT_ANON.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // ispacked
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+  unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_STRUCT_NAME.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+  unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_STRUCT_NAMED.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));  // ispacked
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+  unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Abbrev for TYPE_CODE_ARRAY.
+  Abbv = new BitCodeAbbrev();
+  Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY));
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // size
+  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits));
+
+  unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv);
+
+  // Emit an entry count so the reader can reserve space.
+  TypeVals.push_back(TypeList.size());
+  Stream.EmitRecord(bitc::TYPE_CODE_NUMENTRY, TypeVals);
+  TypeVals.clear();
+
+  // Loop over all of the types, emitting each in turn.
+  for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
+    Type *T = TypeList[i];
+    int AbbrevToUse = 0;
+    unsigned Code = 0;
+
+    switch (T->getTypeID()) {
+    default: llvm_unreachable("Unknown type!");
+    case Type::VoidTyID:      Code = bitc::TYPE_CODE_VOID;      break;
+    case Type::HalfTyID:      Code = bitc::TYPE_CODE_HALF;      break;
+    case Type::FloatTyID:     Code = bitc::TYPE_CODE_FLOAT;     break;
+    case Type::DoubleTyID:    Code = bitc::TYPE_CODE_DOUBLE;    break;
+    case Type::X86_FP80TyID:  Code = bitc::TYPE_CODE_X86_FP80;  break;
+    case Type::FP128TyID:     Code = bitc::TYPE_CODE_FP128;     break;
+    case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break;
+    case Type::LabelTyID:     Code = bitc::TYPE_CODE_LABEL;     break;
+    case Type::MetadataTyID:  Code = bitc::TYPE_CODE_METADATA;  break;
+    case Type::X86_MMXTyID:   Code = bitc::TYPE_CODE_X86_MMX;   break;
+    case Type::IntegerTyID:
+      // INTEGER: [width]
+      Code = bitc::TYPE_CODE_INTEGER;
+      TypeVals.push_back(cast<IntegerType>(T)->getBitWidth());
+      break;
+    case Type::PointerTyID: {
+      PointerType *PTy = cast<PointerType>(T);
+      // POINTER: [pointee type, address space]
+      Code = bitc::TYPE_CODE_POINTER;
+      TypeVals.push_back(VE.getTypeID(PTy->getElementType()));
+      unsigned AddressSpace = PTy->getAddressSpace();
+      TypeVals.push_back(AddressSpace);
+      if (AddressSpace == 0) AbbrevToUse = PtrAbbrev;
+      break;
+    }
+    case Type::FunctionTyID: {
+      FunctionType *FT = cast<FunctionType>(T);
+      // FUNCTION: [isvararg, retty, paramty x N]
+      Code = bitc::TYPE_CODE_FUNCTION;
+      TypeVals.push_back(FT->isVarArg());
+      TypeVals.push_back(VE.getTypeID(FT->getReturnType()));
+      for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i)
+        TypeVals.push_back(VE.getTypeID(FT->getParamType(i)));
+      AbbrevToUse = FunctionAbbrev;
+      break;
+    }
+    case Type::StructTyID: {
+      StructType *ST = cast<StructType>(T);
+      // STRUCT: [ispacked, eltty x N]
+      TypeVals.push_back(ST->isPacked());
+      // Output all of the element types.
+      for (StructType::element_iterator I = ST->element_begin(),
+           E = ST->element_end(); I != E; ++I)
+        TypeVals.push_back(VE.getTypeID(*I));
+
+      if (ST->isLiteral()) {
+        Code = bitc::TYPE_CODE_STRUCT_ANON;
+        AbbrevToUse = StructAnonAbbrev;
+      } else {
+        if (ST->isOpaque()) {
+          Code = bitc::TYPE_CODE_OPAQUE;
+        } else {
+          Code = bitc::TYPE_CODE_STRUCT_NAMED;
+          AbbrevToUse = StructNamedAbbrev;
+        }
+
+        // Emit the name if it is present.
+        if (!ST->getName().empty())
+          WriteStringRecord(bitc::TYPE_CODE_STRUCT_NAME, ST->getName(),
+                            StructNameAbbrev, Stream);
+      }
+      break;
+    }
+    case Type::ArrayTyID: {
+      ArrayType *AT = cast<ArrayType>(T);
+      // ARRAY: [numelts, eltty]
+      Code = bitc::TYPE_CODE_ARRAY;
+      TypeVals.push_back(AT->getNumElements());
+      TypeVals.push_back(VE.getTypeID(AT->getElementType()));
+      AbbrevToUse = ArrayAbbrev;
+      break;
+    }
+    case Type::VectorTyID: {
+      VectorType *VT = cast<VectorType>(T);
+      // VECTOR [numelts, eltty]
+      Code = bitc::TYPE_CODE_VECTOR;
+      TypeVals.push_back(VT->getNumElements());
+      TypeVals.push_back(VE.getTypeID(VT->getElementType()));
+      break;
+    }
+    }
+
+    // Emit the finished record.
+    Stream.EmitRecord(Code, TypeVals, AbbrevToUse);
+    TypeVals.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static unsigned getEncodedLinkage(const GlobalValue &GV) {
+  switch (GV.getLinkage()) {
+  case GlobalValue::ExternalLinkage:
+    return 0;
+  case GlobalValue::WeakAnyLinkage:
+    return 1;
+  case GlobalValue::AppendingLinkage:
+    return 2;
+  case GlobalValue::InternalLinkage:
+    return 3;
+  case GlobalValue::LinkOnceAnyLinkage:
+    return 4;
+  case GlobalValue::ExternalWeakLinkage:
+    return 7;
+  case GlobalValue::CommonLinkage:
+    return 8;
+  case GlobalValue::PrivateLinkage:
+    return 9;
+  case GlobalValue::WeakODRLinkage:
+    return 10;
+  case GlobalValue::LinkOnceODRLinkage:
+    return 11;
+  case GlobalValue::AvailableExternallyLinkage:
+    return 12;
+  }
+  llvm_unreachable("Invalid linkage");
+}
+
+static unsigned getEncodedVisibility(const GlobalValue &GV) {
+  switch (GV.getVisibility()) {
+  case GlobalValue::DefaultVisibility:   return 0;
+  case GlobalValue::HiddenVisibility:    return 1;
+  case GlobalValue::ProtectedVisibility: return 2;
+  }
+  llvm_unreachable("Invalid visibility");
+}
+
+static unsigned getEncodedThreadLocalMode(const GlobalVariable &GV) {
+  switch (GV.getThreadLocalMode()) {
+    case GlobalVariable::NotThreadLocal:         return 0;
+    case GlobalVariable::GeneralDynamicTLSModel: return 1;
+    case GlobalVariable::LocalDynamicTLSModel:   return 2;
+    case GlobalVariable::InitialExecTLSModel:    return 3;
+    case GlobalVariable::LocalExecTLSModel:      return 4;
+  }
+  llvm_unreachable("Invalid TLS model");
+}
+
+// Emit top-level description of module, including target triple, inline asm,
+// descriptors for global variables, and function prototype info.
+static void WriteModuleInfo(const Module *M,
+                            const llvm_3_2::ValueEnumerator &VE,
+                            BitstreamWriter &Stream) {
+  // Emit various pieces of data attached to a module.
+  if (!M->getTargetTriple().empty())
+    WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(),
+                      0/*TODO*/, Stream);
+  const std::string &DL = M->getDataLayoutStr();
+  if (!DL.empty())
+    WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/, Stream);
+  if (!M->getModuleInlineAsm().empty())
+    WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(),
+                      0/*TODO*/, Stream);
+
+  // Emit information about sections and GC, computing how many there are. Also
+  // compute the maximum alignment value.
+  std::map<std::string, unsigned> SectionMap;
+  std::map<std::string, unsigned> GCMap;
+  unsigned MaxAlignment = 0;
+  unsigned MaxGlobalType = 0;
+  for (const GlobalValue &GV : M->globals()) {
+    MaxAlignment = std::max(MaxAlignment, GV.getAlignment());
+    MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getType()));
+    if (GV.hasSection()) {
+      // Give section names unique ID's.
+      unsigned &Entry = SectionMap[GV.getSection()];
+      if (!Entry) {
+        WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV.getSection(),
+                          0/*TODO*/, Stream);
+        Entry = SectionMap.size();
+      }
+    }
+  }
+  for (const Function &F : *M) {
+    MaxAlignment = std::max(MaxAlignment, F.getAlignment());
+    if (F.hasSection()) {
+      // Give section names unique ID's.
+      unsigned &Entry = SectionMap[F.getSection()];
+      if (!Entry) {
+        WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F.getSection(),
+                          0/*TODO*/, Stream);
+        Entry = SectionMap.size();
+      }
+    }
+    if (F.hasGC()) {
+      // Same for GC names.
+      unsigned &Entry = GCMap[F.getGC()];
+      if (!Entry) {
+        WriteStringRecord(bitc::MODULE_CODE_GCNAME, F.getGC(),
+                          0/*TODO*/, Stream);
+        Entry = GCMap.size();
+      }
+    }
+  }
+
+  // Emit abbrev for globals, now that we know # sections and max alignment.
+  unsigned SimpleGVarAbbrev = 0;
+  if (!M->global_empty()) {
+    // Add an abbrev for common globals with no visibility or thread localness.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_GLOBALVAR));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                              Log2_32_Ceil(MaxGlobalType+1)));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));      // Constant.
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));        // Initializer.
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));      // Linkage.
+    if (MaxAlignment == 0)                                      // Alignment.
+      Abbv->Add(BitCodeAbbrevOp(0));
+    else {
+      unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1;
+      Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                               Log2_32_Ceil(MaxEncAlignment+1)));
+    }
+    if (SectionMap.empty())                                    // Section.
+      Abbv->Add(BitCodeAbbrevOp(0));
+    else
+      Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                               Log2_32_Ceil(SectionMap.size()+1)));
+    // Don't bother emitting vis + thread local.
+    SimpleGVarAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  // Emit the global variable information.
+  SmallVector<unsigned, 64> Vals;
+  for (const GlobalVariable &GV : M->globals()) {
+    unsigned AbbrevToUse = 0;
+
+    // GLOBALVAR: [type, isconst, initid,
+    //             linkage, alignment, section, visibility, threadlocal,
+    //             unnamed_addr]
+    Vals.push_back(VE.getTypeID(GV.getType()));
+    Vals.push_back(GV.isConstant());
+    Vals.push_back(GV.isDeclaration() ? 0 :
+                   (VE.getValueID(GV.getInitializer()) + 1));
+    Vals.push_back(getEncodedLinkage(GV));
+    Vals.push_back(Log2_32(GV.getAlignment())+1);
+    Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
+    if (GV.isThreadLocal() ||
+        GV.getVisibility() != GlobalValue::DefaultVisibility ||
+        GV.hasUnnamedAddr() || GV.isExternallyInitialized()) {
+      Vals.push_back(getEncodedVisibility(GV));
+      Vals.push_back(getEncodedThreadLocalMode(GV));
+      Vals.push_back(GV.hasUnnamedAddr());
+      Vals.push_back(GV.isExternallyInitialized());
+    } else {
+      AbbrevToUse = SimpleGVarAbbrev;
+    }
+
+    Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse);
+    Vals.clear();
+  }
+
+  // Emit the function proto information.
+  for (const Function &F : *M) {
+    // FUNCTION:  [type, callingconv, isproto, linkage, paramattrs, alignment,
+    //             section, visibility, gc, unnamed_addr]
+    Vals.push_back(VE.getTypeID(F.getType()));
+    Vals.push_back(F.getCallingConv());
+    Vals.push_back(F.isDeclaration());
+    Vals.push_back(getEncodedLinkage(F));
+    Vals.push_back(VE.getAttributeID(F.getAttributes()));
+    Vals.push_back(Log2_32(F.getAlignment())+1);
+    Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
+    Vals.push_back(getEncodedVisibility(F));
+    Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
+    Vals.push_back(F.hasUnnamedAddr());
+
+    unsigned AbbrevToUse = 0;
+    Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
+    Vals.clear();
+  }
+
+  // Emit the alias information.
+  for (const GlobalAlias &A : M->aliases()) {
+    // ALIAS: [alias type, aliasee val#, linkage, visibility]
+    Vals.push_back(VE.getTypeID(A.getType()));
+    Vals.push_back(VE.getValueID(A.getAliasee()));
+    Vals.push_back(getEncodedLinkage(A));
+    Vals.push_back(getEncodedVisibility(A));
+    unsigned AbbrevToUse = 0;
+    Stream.EmitRecord(bitc::MODULE_CODE_ALIAS_OLD, Vals, AbbrevToUse);
+    Vals.clear();
+  }
+}
+
+static uint64_t GetOptimizationFlags(const Value *V) {
+  uint64_t Flags = 0;
+
+  if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(V)) {
+    if (OBO->hasNoSignedWrap())
+      Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP;
+    if (OBO->hasNoUnsignedWrap())
+      Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP;
+  } else if (const auto *PEO = dyn_cast<PossiblyExactOperator>(V)) {
+    if (PEO->isExact())
+      Flags |= 1 << bitc::PEO_EXACT;
+  } else if (const auto *FPMO = dyn_cast<FPMathOperator>(V)) {
+    // FIXME(srhines): We don't handle fast math in llvm-rs-cc today.
+    if (false) {
+      if (FPMO->hasUnsafeAlgebra())
+        Flags |= FastMathFlags::UnsafeAlgebra;
+      if (FPMO->hasNoNaNs())
+        Flags |= FastMathFlags::NoNaNs;
+      if (FPMO->hasNoInfs())
+        Flags |= FastMathFlags::NoInfs;
+      if (FPMO->hasNoSignedZeros())
+        Flags |= FastMathFlags::NoSignedZeros;
+      if (FPMO->hasAllowReciprocal())
+        Flags |= FastMathFlags::AllowReciprocal;
+    }
+  }
+
+  return Flags;
+}
+
+static void WriteValueAsMetadata(const ValueAsMetadata *MD,
+                                 const llvm_3_2::ValueEnumerator &VE,
+                                 BitstreamWriter &Stream,
+                                 SmallVectorImpl<uint64_t> &Record) {
+  // Mimic an MDNode with a value as one operand.
+  Value *V = MD->getValue();
+  Record.push_back(VE.getTypeID(V->getType()));
+  Record.push_back(VE.getValueID(V));
+  Stream.EmitRecord(bitc::METADATA_OLD_NODE, Record, 0);
+  Record.clear();
+}
+
+static void WriteMDTuple(const MDTuple *N, const llvm_3_2::ValueEnumerator &VE,
+                         BitstreamWriter &Stream,
+                         SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
+  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+    Metadata *MD = N->getOperand(i);
+    assert(!(MD && isa<LocalAsMetadata>(MD)) &&
+           "Unexpected function-local metadata");
+    if (!MD) {
+      // TODO(srhines): I don't believe this case can exist for RS.
+      Record.push_back(VE.getTypeID(llvm::Type::getVoidTy(N->getContext())));
+      Record.push_back(0);
+    } else if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+      Record.push_back(VE.getTypeID(MDC->getType()));
+      Record.push_back(VE.getValueID(MDC->getValue()));
+    } else {
+      Record.push_back(VE.getTypeID(
+          llvm::Type::getMetadataTy(N->getContext())));
+      Record.push_back(VE.getMetadataID(MD));
+    }
+  }
+  Stream.EmitRecord(bitc::METADATA_OLD_NODE, Record, Abbrev);
+  Record.clear();
+}
+
+/*static void WriteMDLocation(const MDLocation *N, const llvm_3_2::ValueEnumerator &VE,
+                            BitstreamWriter &Stream,
+                            SmallVectorImpl<uint64_t> &Record,
+                            unsigned Abbrev) {
+  Record.push_back(N->isDistinct());
+  Record.push_back(N->getLine());
+  Record.push_back(N->getColumn());
+  Record.push_back(VE.getMetadataID(N->getScope()));
+  Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt()));
+
+  Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
+  Record.clear();
+}
+
+static void WriteGenericDebugNode(const GenericDebugNode *,
+                                  const llvm_3_2::ValueEnumerator &, BitstreamWriter &,
+                                  SmallVectorImpl<uint64_t> &, unsigned) {
+  llvm_unreachable("unimplemented");
+}*/
+
+static void WriteModuleMetadata(const Module *M,
+                                const llvm_3_2::ValueEnumerator &VE,
+                                BitstreamWriter &Stream) {
+  const auto &MDs = VE.getMDs();
+  if (MDs.empty() && M->named_metadata_empty())
+    return;
+
+  // RenderScript files *ALWAYS* have metadata!
+  Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
+  unsigned MDSAbbrev = 0;
+  if (VE.hasMDString()) {
+    // Abbrev for METADATA_STRING.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    MDSAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  unsigned MDLocationAbbrev = 0;
+  if (VE.hasDILocation()) {
+    // TODO(srhines): Should be unreachable for RenderScript.
+    // Abbrev for METADATA_LOCATION.
+    //
+    // Assume the column is usually under 128, and always output the inlined-at
+    // location (it's never more expensive than building an array size 1).
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    MDLocationAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  unsigned NameAbbrev = 0;
+  if (!M->named_metadata_empty()) {
+    // Abbrev for METADATA_NAME.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_NAME));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    NameAbbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  unsigned MDTupleAbbrev = 0;
+  //unsigned GenericDebugNodeAbbrev = 0;
+  SmallVector<uint64_t, 64> Record;
+  for (const Metadata *MD : MDs) {
+    if (const MDNode *N = dyn_cast<MDNode>(MD)) {
+      switch (N->getMetadataID()) {
+      default:
+        llvm_unreachable("Invalid MDNode subclass");
+#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)
+#define HANDLE_MDNODE_LEAF(CLASS)                                              \
+  case Metadata::CLASS##Kind:                                                  \
+    Write##CLASS(cast<CLASS>(N), VE, Stream, Record, CLASS##Abbrev);           \
+    continue;
+#include "llvm/IR/Metadata.def"
+      }
+    }
+    if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) {
+      WriteValueAsMetadata(MDC, VE, Stream, Record);
+      continue;
+    }
+    const MDString *MDS = cast<MDString>(MD);
+    // Code: [strchar x N]
+    Record.append(MDS->bytes_begin(), MDS->bytes_end());
+
+    // Emit the finished record.
+    Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev);
+    Record.clear();
+  }
+
+  // Write named metadata.
+  for (const NamedMDNode &NMD : M->named_metadata()) {
+    // Write name.
+    StringRef Str = NMD.getName();
+    Record.append(Str.bytes_begin(), Str.bytes_end());
+    Stream.EmitRecord(bitc::METADATA_NAME, Record, NameAbbrev);
+    Record.clear();
+
+    // Write named metadata operands.
+    for (const MDNode *N : NMD.operands())
+      Record.push_back(VE.getMetadataID(N));
+    Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void WriteFunctionLocalMetadata(const Function &F,
+                                       const llvm_3_2::ValueEnumerator &VE,
+                                       BitstreamWriter &Stream) {
+  bool StartedMetadataBlock = false;
+  SmallVector<uint64_t, 64> Record;
+  const SmallVectorImpl<const LocalAsMetadata *> &MDs =
+      VE.getFunctionLocalMDs();
+  for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+    assert(MDs[i] && "Expected valid function-local metadata");
+    if (!StartedMetadataBlock) {
+      Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+      StartedMetadataBlock = true;
+    }
+    WriteValueAsMetadata(MDs[i], VE, Stream, Record);
+  }
+
+  if (StartedMetadataBlock)
+    Stream.ExitBlock();
+}
+
+static void WriteMetadataAttachment(const Function &F,
+                                    const llvm_3_2::ValueEnumerator &VE,
+                                    BitstreamWriter &Stream) {
+  Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3);
+
+  SmallVector<uint64_t, 64> Record;
+
+  // Write metadata attachments
+  // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]]
+  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+         I != E; ++I) {
+      MDs.clear();
+      I->getAllMetadataOtherThanDebugLoc(MDs);
+
+      // If no metadata, ignore instruction.
+      if (MDs.empty()) continue;
+
+      Record.push_back(VE.getInstructionID(&*I));
+
+      for (unsigned i = 0, e = MDs.size(); i != e; ++i) {
+        Record.push_back(MDs[i].first);
+        Record.push_back(VE.getMetadataID(MDs[i].second));
+      }
+      Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0);
+      Record.clear();
+    }
+
+  Stream.ExitBlock();
+}
+
+static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
+  SmallVector<uint64_t, 64> Record;
+
+  // Write metadata kinds
+  // METADATA_KIND - [n x [id, name]]
+  SmallVector<StringRef, 4> Names;
+  M->getMDKindNames(Names);
+
+  if (Names.empty()) return;
+
+  Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
+
+  for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {
+    Record.push_back(MDKindID);
+    StringRef KName = Names[MDKindID];
+    Record.append(KName.begin(), KName.end());
+
+    Stream.EmitRecord(bitc::METADATA_KIND, Record, 0);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) {
+  if ((int64_t)V >= 0)
+    Vals.push_back(V << 1);
+  else
+    Vals.push_back((-V << 1) | 1);
+}
+
+static void WriteConstants(unsigned FirstVal, unsigned LastVal,
+                           const llvm_3_2::ValueEnumerator &VE,
+                           BitstreamWriter &Stream, bool isGlobal) {
+  if (FirstVal == LastVal) return;
+
+  Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4);
+
+  unsigned AggregateAbbrev = 0;
+  unsigned String8Abbrev = 0;
+  unsigned CString7Abbrev = 0;
+  unsigned CString6Abbrev = 0;
+  // If this is a constant pool for the module, emit module-specific abbrevs.
+  if (isGlobal) {
+    // Abbrev for CST_CODE_AGGREGATE.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_AGGREGATE));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(LastVal+1)));
+    AggregateAbbrev = Stream.EmitAbbrev(Abbv);
+
+    // Abbrev for CST_CODE_STRING.
+    Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_STRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    String8Abbrev = Stream.EmitAbbrev(Abbv);
+    // Abbrev for CST_CODE_CSTRING.
+    Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
+    CString7Abbrev = Stream.EmitAbbrev(Abbv);
+    // Abbrev for CST_CODE_CSTRING.
+    Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    CString6Abbrev = Stream.EmitAbbrev(Abbv);
+  }
+
+  SmallVector<uint64_t, 64> Record;
+
+  const llvm_3_2::ValueEnumerator::ValueList &Vals = VE.getValues();
+  Type *LastTy = nullptr;
+  for (unsigned i = FirstVal; i != LastVal; ++i) {
+    const Value *V = Vals[i].first;
+    // If we need to switch types, do so now.
+    if (V->getType() != LastTy) {
+      LastTy = V->getType();
+      Record.push_back(VE.getTypeID(LastTy));
+      Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record,
+                        CONSTANTS_SETTYPE_ABBREV);
+      Record.clear();
+    }
+
+    if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
+      Record.push_back(unsigned(IA->hasSideEffects()) |
+                       unsigned(IA->isAlignStack()) << 1 |
+                       unsigned(IA->getDialect()&1) << 2);
+
+      // Add the asm string.
+      const std::string &AsmStr = IA->getAsmString();
+      Record.push_back(AsmStr.size());
+      for (unsigned i = 0, e = AsmStr.size(); i != e; ++i)
+        Record.push_back(AsmStr[i]);
+
+      // Add the constraint string.
+      const std::string &ConstraintStr = IA->getConstraintString();
+      Record.push_back(ConstraintStr.size());
+      for (unsigned i = 0, e = ConstraintStr.size(); i != e; ++i)
+        Record.push_back(ConstraintStr[i]);
+      Stream.EmitRecord(bitc::CST_CODE_INLINEASM, Record);
+      Record.clear();
+      continue;
+    }
+    const Constant *C = cast<Constant>(V);
+    unsigned Code = -1U;
+    unsigned AbbrevToUse = 0;
+    if (C->isNullValue()) {
+      Code = bitc::CST_CODE_NULL;
+    } else if (isa<UndefValue>(C)) {
+      Code = bitc::CST_CODE_UNDEF;
+    } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
+      if (IV->getBitWidth() <= 64) {
+        uint64_t V = IV->getSExtValue();
+        emitSignedInt64(Record, V);
+        Code = bitc::CST_CODE_INTEGER;
+        AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
+      } else {                             // Wide integers, > 64 bits in size.
+        // We have an arbitrary precision integer value to write whose
+        // bit width is > 64. However, in canonical unsigned integer
+        // format it is likely that the high bits are going to be zero.
+        // So, we only write the number of active words.
+        unsigned NWords = IV->getValue().getActiveWords();
+        const uint64_t *RawWords = IV->getValue().getRawData();
+        for (unsigned i = 0; i != NWords; ++i) {
+          emitSignedInt64(Record, RawWords[i]);
+        }
+        Code = bitc::CST_CODE_WIDE_INTEGER;
+      }
+    } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
+      Code = bitc::CST_CODE_FLOAT;
+      Type *Ty = CFP->getType();
+      if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) {
+        Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
+      } else if (Ty->isX86_FP80Ty()) {
+        // api needed to prevent premature destruction
+        // bits are not in the same order as a normal i80 APInt, compensate.
+        APInt api = CFP->getValueAPF().bitcastToAPInt();
+        const uint64_t *p = api.getRawData();
+        Record.push_back((p[1] << 48) | (p[0] >> 16));
+        Record.push_back(p[0] & 0xffffLL);
+      } else if (Ty->isFP128Ty() || Ty->isPPC_FP128Ty()) {
+        APInt api = CFP->getValueAPF().bitcastToAPInt();
+        const uint64_t *p = api.getRawData();
+        Record.push_back(p[0]);
+        Record.push_back(p[1]);
+      } else {
+        assert (0 && "Unknown FP type!");
+      }
+    } else if (isa<ConstantDataSequential>(C) &&
+               cast<ConstantDataSequential>(C)->isString()) {
+      const ConstantDataSequential *Str = cast<ConstantDataSequential>(C);
+      // Emit constant strings specially.
+      unsigned NumElts = Str->getNumElements();
+      // If this is a null-terminated string, use the denser CSTRING encoding.
+      if (Str->isCString()) {
+        Code = bitc::CST_CODE_CSTRING;
+        --NumElts;  // Don't encode the null, which isn't allowed by char6.
+      } else {
+        Code = bitc::CST_CODE_STRING;
+        AbbrevToUse = String8Abbrev;
+      }
+      bool isCStr7 = Code == bitc::CST_CODE_CSTRING;
+      bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING;
+      for (unsigned i = 0; i != NumElts; ++i) {
+        unsigned char V = Str->getElementAsInteger(i);
+        Record.push_back(V);
+        isCStr7 &= (V & 128) == 0;
+        if (isCStrChar6)
+          isCStrChar6 = BitCodeAbbrevOp::isChar6(V);
+      }
+
+      if (isCStrChar6)
+        AbbrevToUse = CString6Abbrev;
+      else if (isCStr7)
+        AbbrevToUse = CString7Abbrev;
+    } else if (const ConstantDataSequential *CDS =
+                  dyn_cast<ConstantDataSequential>(C)) {
+      Code = bitc::CST_CODE_DATA;
+      Type *EltTy = CDS->getType()->getElementType();
+      if (isa<IntegerType>(EltTy)) {
+        for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+          Record.push_back(CDS->getElementAsInteger(i));
+      } else {
+        for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+          Record.push_back(
+              CDS->getElementAsAPFloat(i).bitcastToAPInt().getLimitedValue());
+      }
+    } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) ||
+               isa<ConstantVector>(C)) {
+      Code = bitc::CST_CODE_AGGREGATE;
+      for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
+        Record.push_back(VE.getValueID(C->getOperand(i)));
+      AbbrevToUse = AggregateAbbrev;
+    } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+      switch (CE->getOpcode()) {
+      default:
+        if (Instruction::isCast(CE->getOpcode())) {
+          Code = bitc::CST_CODE_CE_CAST;
+          Record.push_back(GetEncodedCastOpcode(CE->getOpcode()));
+          Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+          Record.push_back(VE.getValueID(C->getOperand(0)));
+          AbbrevToUse = CONSTANTS_CE_CAST_Abbrev;
+        } else {
+          assert(CE->getNumOperands() == 2 && "Unknown constant expr!");
+          Code = bitc::CST_CODE_CE_BINOP;
+          Record.push_back(GetEncodedBinaryOpcode(CE->getOpcode()));
+          Record.push_back(VE.getValueID(C->getOperand(0)));
+          Record.push_back(VE.getValueID(C->getOperand(1)));
+          uint64_t Flags = GetOptimizationFlags(CE);
+          if (Flags != 0)
+            Record.push_back(Flags);
+        }
+        break;
+      case Instruction::GetElementPtr:
+        Code = bitc::CST_CODE_CE_GEP;
+        if (cast<GEPOperator>(C)->isInBounds())
+          Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
+        for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
+          Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
+          Record.push_back(VE.getValueID(C->getOperand(i)));
+        }
+        break;
+      case Instruction::Select:
+        Code = bitc::CST_CODE_CE_SELECT;
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(VE.getValueID(C->getOperand(2)));
+        break;
+      case Instruction::ExtractElement:
+        Code = bitc::CST_CODE_CE_EXTRACTELT;
+        Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        break;
+      case Instruction::InsertElement:
+        Code = bitc::CST_CODE_CE_INSERTELT;
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(VE.getValueID(C->getOperand(2)));
+        break;
+      case Instruction::ShuffleVector:
+        // If the return type and argument types are the same, this is a
+        // standard shufflevector instruction.  If the types are different,
+        // then the shuffle is widening or truncating the input vectors, and
+        // the argument type must also be encoded.
+        if (C->getType() == C->getOperand(0)->getType()) {
+          Code = bitc::CST_CODE_CE_SHUFFLEVEC;
+        } else {
+          Code = bitc::CST_CODE_CE_SHUFVEC_EX;
+          Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        }
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(VE.getValueID(C->getOperand(2)));
+        break;
+      case Instruction::ICmp:
+      case Instruction::FCmp:
+        Code = bitc::CST_CODE_CE_CMP;
+        Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
+        Record.push_back(VE.getValueID(C->getOperand(0)));
+        Record.push_back(VE.getValueID(C->getOperand(1)));
+        Record.push_back(CE->getPredicate());
+        break;
+      }
+    } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
+      Code = bitc::CST_CODE_BLOCKADDRESS;
+      Record.push_back(VE.getTypeID(BA->getFunction()->getType()));
+      Record.push_back(VE.getValueID(BA->getFunction()));
+      Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock()));
+    } else {
+#ifndef NDEBUG
+      C->dump();
+#endif
+      llvm_unreachable("Unknown constant!");
+    }
+    Stream.EmitRecord(Code, Record, AbbrevToUse);
+    Record.clear();
+  }
+
+  Stream.ExitBlock();
+}
+
+static void WriteModuleConstants(const llvm_3_2::ValueEnumerator &VE,
+                                 BitstreamWriter &Stream) {
+  const llvm_3_2::ValueEnumerator::ValueList &Vals = VE.getValues();
+
+  // Find the first constant to emit, which is the first non-globalvalue value.
+  // We know globalvalues have been emitted by WriteModuleInfo.
+  for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+    if (!isa<GlobalValue>(Vals[i].first)) {
+      WriteConstants(i, Vals.size(), VE, Stream, true);
+      return;
+    }
+  }
+}
+
+/// PushValueAndType - The file has to encode both the value and type id for
+/// many values, because we need to know what type to create for forward
+/// references.  However, most operands are not forward references, so this type
+/// field is not needed.
+///
+/// This function adds V's value ID to Vals.  If the value ID is higher than the
+/// instruction ID, then it is a forward reference, and it also includes the
+/// type ID.
+static bool PushValueAndType(const Value *V, unsigned InstID,
+                             SmallVector<unsigned, 64> &Vals,
+                             llvm_3_2::ValueEnumerator &VE) {
+  unsigned ValID = VE.getValueID(V);
+  Vals.push_back(ValID);
+  if (ValID >= InstID) {
+    Vals.push_back(VE.getTypeID(V->getType()));
+    return true;
+  }
+  return false;
+}
+
+/// WriteInstruction - Emit an instruction to the specified stream.
+static void WriteInstruction(const Instruction &I, unsigned InstID,
+                             llvm_3_2::ValueEnumerator &VE,
+                             BitstreamWriter &Stream,
+                             SmallVector<unsigned, 64> &Vals) {
+  unsigned Code = 0;
+  unsigned AbbrevToUse = 0;
+  VE.setInstructionID(&I);
+  switch (I.getOpcode()) {
+  default:
+    if (Instruction::isCast(I.getOpcode())) {
+      Code = bitc::FUNC_CODE_INST_CAST;
+      if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+        AbbrevToUse = FUNCTION_INST_CAST_ABBREV;
+      Vals.push_back(VE.getTypeID(I.getType()));
+      Vals.push_back(GetEncodedCastOpcode(I.getOpcode()));
+    } else {
+      assert(isa<BinaryOperator>(I) && "Unknown instruction!");
+      Code = bitc::FUNC_CODE_INST_BINOP;
+      if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+        AbbrevToUse = FUNCTION_INST_BINOP_ABBREV;
+      Vals.push_back(VE.getValueID(I.getOperand(1)));
+      Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode()));
+      uint64_t Flags = GetOptimizationFlags(&I);
+      if (Flags != 0) {
+        if (AbbrevToUse == FUNCTION_INST_BINOP_ABBREV)
+          AbbrevToUse = FUNCTION_INST_BINOP_FLAGS_ABBREV;
+        Vals.push_back(Flags);
+      }
+    }
+    break;
+
+  case Instruction::GetElementPtr:
+    Code = bitc::FUNC_CODE_INST_GEP_OLD;
+    if (cast<GEPOperator>(&I)->isInBounds())
+      Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD;
+    for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
+      PushValueAndType(I.getOperand(i), InstID, Vals, VE);
+    break;
+  case Instruction::ExtractValue: {
+    Code = bitc::FUNC_CODE_INST_EXTRACTVAL;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    const ExtractValueInst *EVI = cast<ExtractValueInst>(&I);
+    for (const unsigned *i = EVI->idx_begin(), *e = EVI->idx_end(); i != e; ++i)
+      Vals.push_back(*i);
+    break;
+  }
+  case Instruction::InsertValue: {
+    Code = bitc::FUNC_CODE_INST_INSERTVAL;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    PushValueAndType(I.getOperand(1), InstID, Vals, VE);
+    const InsertValueInst *IVI = cast<InsertValueInst>(&I);
+    for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i)
+      Vals.push_back(*i);
+    break;
+  }
+  case Instruction::Select:
+    Code = bitc::FUNC_CODE_INST_VSELECT;
+    PushValueAndType(I.getOperand(1), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(2)));
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    break;
+  case Instruction::ExtractElement:
+    Code = bitc::FUNC_CODE_INST_EXTRACTELT;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    break;
+  case Instruction::InsertElement:
+    Code = bitc::FUNC_CODE_INST_INSERTELT;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    Vals.push_back(VE.getValueID(I.getOperand(2)));
+    break;
+  case Instruction::ShuffleVector:
+    Code = bitc::FUNC_CODE_INST_SHUFFLEVEC;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    Vals.push_back(VE.getValueID(I.getOperand(2)));
+    break;
+  case Instruction::ICmp:
+  case Instruction::FCmp:
+    // compare returning Int1Ty or vector of Int1Ty
+    Code = bitc::FUNC_CODE_INST_CMP2;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    Vals.push_back(VE.getValueID(I.getOperand(1)));
+    Vals.push_back(cast<CmpInst>(I).getPredicate());
+    break;
+
+  case Instruction::Ret:
+    {
+      Code = bitc::FUNC_CODE_INST_RET;
+      unsigned NumOperands = I.getNumOperands();
+      if (NumOperands == 0)
+        AbbrevToUse = FUNCTION_INST_RET_VOID_ABBREV;
+      else if (NumOperands == 1) {
+        if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))
+          AbbrevToUse = FUNCTION_INST_RET_VAL_ABBREV;
+      } else {
+        for (unsigned i = 0, e = NumOperands; i != e; ++i)
+          PushValueAndType(I.getOperand(i), InstID, Vals, VE);
+      }
+    }
+    break;
+  case Instruction::Br:
+    {
+      Code = bitc::FUNC_CODE_INST_BR;
+      const BranchInst &II = cast<BranchInst>(I);
+      Vals.push_back(VE.getValueID(II.getSuccessor(0)));
+      if (II.isConditional()) {
+        Vals.push_back(VE.getValueID(II.getSuccessor(1)));
+        Vals.push_back(VE.getValueID(II.getCondition()));
+      }
+    }
+    break;
+  case Instruction::Switch:
+    {
+      Code = bitc::FUNC_CODE_INST_SWITCH;
+      const SwitchInst &SI = cast<SwitchInst>(I);
+      Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
+      Vals.push_back(VE.getValueID(SI.getCondition()));
+      Vals.push_back(VE.getValueID(SI.getDefaultDest()));
+      for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
+           i != e; ++i) {
+        Vals.push_back(VE.getValueID(i.getCaseValue()));
+        Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
+      }
+    }
+    break;
+  case Instruction::IndirectBr:
+    Code = bitc::FUNC_CODE_INST_INDIRECTBR;
+    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+    for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
+      Vals.push_back(VE.getValueID(I.getOperand(i)));
+    break;
+
+  case Instruction::Invoke: {
+    const InvokeInst *II = cast<InvokeInst>(&I);
+    const Value *Callee(II->getCalledValue());
+    PointerType *PTy = cast<PointerType>(Callee->getType());
+    FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+    Code = bitc::FUNC_CODE_INST_INVOKE;
+
+    Vals.push_back(VE.getAttributeID(II->getAttributes()));
+    Vals.push_back(II->getCallingConv());
+    Vals.push_back(VE.getValueID(II->getNormalDest()));
+    Vals.push_back(VE.getValueID(II->getUnwindDest()));
+    PushValueAndType(Callee, InstID, Vals, VE);
+
+    // Emit value #'s for the fixed parameters.
+    for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+      Vals.push_back(VE.getValueID(I.getOperand(i)));  // fixed param.
+
+    // Emit type/value pairs for varargs params.
+    if (FTy->isVarArg()) {
+      for (unsigned i = FTy->getNumParams(), e = I.getNumOperands()-3;
+           i != e; ++i)
+        PushValueAndType(I.getOperand(i), InstID, Vals, VE); // vararg
+    }
+    break;
+  }
+  case Instruction::Resume:
+    Code = bitc::FUNC_CODE_INST_RESUME;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    break;
+  case Instruction::Unreachable:
+    Code = bitc::FUNC_CODE_INST_UNREACHABLE;
+    AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV;
+    break;
+
+  case Instruction::PHI: {
+    const PHINode &PN = cast<PHINode>(I);
+    Code = bitc::FUNC_CODE_INST_PHI;
+    Vals.push_back(VE.getTypeID(PN.getType()));
+    for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+      Vals.push_back(VE.getValueID(PN.getIncomingValue(i)));
+      Vals.push_back(VE.getValueID(PN.getIncomingBlock(i)));
+    }
+    break;
+  }
+
+  case Instruction::LandingPad: {
+    const LandingPadInst &LP = cast<LandingPadInst>(I);
+    Code = bitc::FUNC_CODE_INST_LANDINGPAD_OLD;
+    Vals.push_back(VE.getTypeID(LP.getType()));
+    // TODO (rebase): is this fix enough?
+    // PushValueAndType(LP.getPersonalityFn(), InstID, Vals, VE);
+    Vals.push_back(LP.isCleanup());
+    Vals.push_back(LP.getNumClauses());
+    for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) {
+      if (LP.isCatch(I))
+        Vals.push_back(LandingPadInst::Catch);
+      else
+        Vals.push_back(LandingPadInst::Filter);
+      PushValueAndType(LP.getClause(I), InstID, Vals, VE);
+    }
+    break;
+  }
+
+  case Instruction::Alloca: {
+    Code = bitc::FUNC_CODE_INST_ALLOCA;
+    Vals.push_back(VE.getTypeID(I.getType()));
+    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
+    Vals.push_back(VE.getValueID(I.getOperand(0))); // size.
+    Vals.push_back(Log2_32(cast<AllocaInst>(I).getAlignment())+1);
+    break;
+  }
+
+  case Instruction::Load:
+    if (cast<LoadInst>(I).isAtomic()) {
+      Code = bitc::FUNC_CODE_INST_LOADATOMIC;
+      PushValueAndType(I.getOperand(0), InstID, Vals, VE);
+    } else {
+      Code = bitc::FUNC_CODE_INST_LOAD;
+      if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE))  // ptr
+        AbbrevToUse = FUNCTION_INST_LOAD_ABBREV;
+    }
+    Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment())+1);
+    Vals.push_back(cast<LoadInst>(I).isVolatile());
+    if (cast<LoadInst>(I).isAtomic()) {
+      Vals.push_back(GetEncodedOrdering(cast<LoadInst>(I).getOrdering()));
+      Vals.push_back(GetEncodedSynchScope(cast<LoadInst>(I).getSynchScope()));
+    }
+    break;
+  case Instruction::Store:
+    if (cast<StoreInst>(I).isAtomic())
+      Code = bitc::FUNC_CODE_INST_STOREATOMIC;
+    else
+      Code = bitc::FUNC_CODE_INST_STORE_OLD;
+    PushValueAndType(I.getOperand(1), InstID, Vals, VE);  // ptrty + ptr
+    Vals.push_back(VE.getValueID(I.getOperand(0)));       // val.
+    Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1);
+    Vals.push_back(cast<StoreInst>(I).isVolatile());
+    if (cast<StoreInst>(I).isAtomic()) {
+      Vals.push_back(GetEncodedOrdering(cast<StoreInst>(I).getOrdering()));
+      Vals.push_back(GetEncodedSynchScope(cast<StoreInst>(I).getSynchScope()));
+    }
+    break;
+  case Instruction::AtomicCmpXchg:
+    Code = bitc::FUNC_CODE_INST_CMPXCHG;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);  // ptrty + ptr
+    Vals.push_back(VE.getValueID(I.getOperand(1)));       // cmp.
+    Vals.push_back(VE.getValueID(I.getOperand(2)));       // newval.
+    Vals.push_back(cast<AtomicCmpXchgInst>(I).isVolatile());
+    Vals.push_back(GetEncodedOrdering(
+                     cast<AtomicCmpXchgInst>(I).getSuccessOrdering()));
+    Vals.push_back(GetEncodedSynchScope(
+                     cast<AtomicCmpXchgInst>(I).getSynchScope()));
+    break;
+  case Instruction::AtomicRMW:
+    Code = bitc::FUNC_CODE_INST_ATOMICRMW;
+    PushValueAndType(I.getOperand(0), InstID, Vals, VE);  // ptrty + ptr
+    Vals.push_back(VE.getValueID(I.getOperand(1)));       // val.
+    Vals.push_back(GetEncodedRMWOperation(
+                     cast<AtomicRMWInst>(I).getOperation()));
+    Vals.push_back(cast<AtomicRMWInst>(I).isVolatile());
+    Vals.push_back(GetEncodedOrdering(cast<AtomicRMWInst>(I).getOrdering()));
+    Vals.push_back(GetEncodedSynchScope(
+                     cast<AtomicRMWInst>(I).getSynchScope()));
+    break;
+  case Instruction::Fence:
+    Code = bitc::FUNC_CODE_INST_FENCE;
+    Vals.push_back(GetEncodedOrdering(cast<FenceInst>(I).getOrdering()));
+    Vals.push_back(GetEncodedSynchScope(cast<FenceInst>(I).getSynchScope()));
+    break;
+  case Instruction::Call: {
+    const CallInst &CI = cast<CallInst>(I);
+    PointerType *PTy = cast<PointerType>(CI.getCalledValue()->getType());
+    FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+
+    Code = bitc::FUNC_CODE_INST_CALL;
+
+    Vals.push_back(VE.getAttributeID(CI.getAttributes()));
+    Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()));
+    PushValueAndType(CI.getCalledValue(), InstID, Vals, VE);  // Callee
+
+    // Emit value #'s for the fixed parameters.
+    for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+      Vals.push_back(VE.getValueID(CI.getArgOperand(i)));  // fixed param.
+
+    // Emit type/value pairs for varargs params.
+    if (FTy->isVarArg()) {
+      for (unsigned i = FTy->getNumParams(), e = CI.getNumArgOperands();
+           i != e; ++i)
+        PushValueAndType(CI.getArgOperand(i), InstID, Vals, VE);  // varargs
+    }
+    break;
+  }
+  case Instruction::VAArg:
+    Code = bitc::FUNC_CODE_INST_VAARG;
+    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));   // valistty
+    Vals.push_back(VE.getValueID(I.getOperand(0))); // valist.
+    Vals.push_back(VE.getTypeID(I.getType())); // restype.
+    break;
+  }
+
+  Stream.EmitRecord(Code, Vals, AbbrevToUse);
+  Vals.clear();
+}
+
+// Emit names for globals/functions etc.
+static void WriteValueSymbolTable(const ValueSymbolTable &VST,
+                                  const llvm_3_2::ValueEnumerator &VE,
+                                  BitstreamWriter &Stream) {
+  if (VST.empty()) return;
+  Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4);
+
+  // FIXME: Set up the abbrev, we know how many values there are!
+  // FIXME: We know if the type names can use 7-bit ascii.
+  SmallVector<unsigned, 64> NameVals;
+
+  for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end();
+       SI != SE; ++SI) {
+
+    const ValueName &Name = *SI;
+
+    // Figure out the encoding to use for the name.
+    bool is7Bit = true;
+    bool isChar6 = true;
+    for (const char *C = Name.getKeyData(), *E = C+Name.getKeyLength();
+         C != E; ++C) {
+      if (isChar6)
+        isChar6 = BitCodeAbbrevOp::isChar6(*C);
+      if ((unsigned char)*C & 128) {
+        is7Bit = false;
+        break;  // don't bother scanning the rest.
+      }
+    }
+
+    unsigned AbbrevToUse = VST_ENTRY_8_ABBREV;
+
+    // VST_ENTRY:   [valueid, namechar x N]
+    // VST_BBENTRY: [bbid, namechar x N]
+    unsigned Code;
+    if (isa<BasicBlock>(SI->getValue())) {
+      Code = bitc::VST_CODE_BBENTRY;
+      if (isChar6)
+        AbbrevToUse = VST_BBENTRY_6_ABBREV;
+    } else {
+      Code = bitc::VST_CODE_ENTRY;
+      if (isChar6)
+        AbbrevToUse = VST_ENTRY_6_ABBREV;
+      else if (is7Bit)
+        AbbrevToUse = VST_ENTRY_7_ABBREV;
+    }
+
+    NameVals.push_back(VE.getValueID(SI->getValue()));
+    for (const char *P = Name.getKeyData(),
+         *E = Name.getKeyData()+Name.getKeyLength(); P != E; ++P)
+      NameVals.push_back((unsigned char)*P);
+
+    // Emit the finished record.
+    Stream.EmitRecord(Code, NameVals, AbbrevToUse);
+    NameVals.clear();
+  }
+  Stream.ExitBlock();
+}
+
+static void WriteUseList(llvm_3_2::ValueEnumerator &VE, UseListOrder &&Order,
+                         BitstreamWriter &Stream) {
+  assert(Order.Shuffle.size() >= 2 && "Shuffle too small");
+  unsigned Code;
+  if (isa<BasicBlock>(Order.V))
+    Code = bitc::USELIST_CODE_BB;
+  else
+    Code = bitc::USELIST_CODE_DEFAULT;
+
+  SmallVector<uint64_t, 64> Record;
+  for (unsigned I : Order.Shuffle)
+    Record.push_back(I);
+  Record.push_back(VE.getValueID(Order.V));
+  Stream.EmitRecord(Code, Record);
+}
+
+static void WriteUseListBlock(const Function *F, llvm_3_2::ValueEnumerator &VE,
+                              BitstreamWriter &Stream) {
+  auto hasMore = [&]() {
+    return !VE.UseListOrders.empty() && VE.UseListOrders.back().F == F;
+  };
+  if (!hasMore())
+    // Nothing to do.
+    return;
+
+  Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3);
+  while (hasMore()) {
+    WriteUseList(VE, std::move(VE.UseListOrders.back()), Stream);
+    VE.UseListOrders.pop_back();
+  }
+  Stream.ExitBlock();
+}
+
+/// WriteFunction - Emit a function body to the module stream.
+static void WriteFunction(const Function &F, llvm_3_2::ValueEnumerator &VE,
+                          BitstreamWriter &Stream) {
+  Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4);
+  VE.incorporateFunction(F);
+
+  SmallVector<unsigned, 64> Vals;
+
+  // Emit the number of basic blocks, so the reader can create them ahead of
+  // time.
+  Vals.push_back(VE.getBasicBlocks().size());
+  Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals);
+  Vals.clear();
+
+  // If there are function-local constants, emit them now.
+  unsigned CstStart, CstEnd;
+  VE.getFunctionConstantRange(CstStart, CstEnd);
+  WriteConstants(CstStart, CstEnd, VE, Stream, false);
+
+  // If there is function-local metadata, emit it now.
+  WriteFunctionLocalMetadata(F, VE, Stream);
+
+  // Keep a running idea of what the instruction ID is.
+  unsigned InstID = CstEnd;
+
+  bool NeedsMetadataAttachment = false;
+
+  DILocation *LastDL = nullptr;
+
+  // Finally, emit all the instructions, in order.
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+         I != E; ++I) {
+      WriteInstruction(*I, InstID, VE, Stream, Vals);
+
+      if (!I->getType()->isVoidTy())
+        ++InstID;
+
+      // If the instruction has metadata, write a metadata attachment later.
+      NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
+
+      // If the instruction has a debug location, emit it.
+      DILocation *DL = I->getDebugLoc();
+      if (!DL)
+        continue;
+
+      if (DL == LastDL) {
+        // Just repeat the same debug loc as last time.
+        Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals);
+        continue;
+      }
+
+      Vals.push_back(DL->getLine());
+      Vals.push_back(DL->getColumn());
+      Vals.push_back(VE.getMetadataOrNullID(DL->getScope()));
+      Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt()));
+      Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals);
+      Vals.clear();
+
+      // Fixme(pirama): The following line is missing from upstream
+      // https://llvm.org/bugs/show_bug.cgi?id=23436
+      LastDL = DL;
+    }
+
+  // Emit names for all the instructions etc.
+  WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
+
+  if (NeedsMetadataAttachment)
+    WriteMetadataAttachment(F, VE, Stream);
+  if (false)
+    WriteUseListBlock(&F, VE, Stream);
+  VE.purgeFunction();
+  Stream.ExitBlock();
+}
+
+// Emit blockinfo, which defines the standard abbreviations etc.
+static void WriteBlockInfo(const llvm_3_2::ValueEnumerator &VE,
+                           BitstreamWriter &Stream) {
+  // We only want to emit block info records for blocks that have multiple
+  // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK.  Other
+  // blocks can defined their abbrevs inline.
+  Stream.EnterBlockInfoBlock(2);
+
+  { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_ENTRY_8_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // 7-bit fixed width VST_ENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_ENTRY_7_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // 6-bit char6 VST_ENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_ENTRY_6_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // 6-bit char6 VST_BBENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_BBENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_BBENTRY_6_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+
+
+  { // SETTYPE abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
+                              Log2_32_Ceil(VE.getTypes().size()+1)));
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_SETTYPE_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // INTEGER abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_INTEGER));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_INTEGER_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // CE_CAST abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CE_CAST));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));  // cast opc
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,       // typeid
+                              Log2_32_Ceil(VE.getTypes().size()+1)));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));    // value id
+
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_CE_CAST_Abbrev)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // NULL abbrev for CONSTANTS_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_NULL));
+    if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID,
+                                   Abbv) != CONSTANTS_NULL_Abbrev)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  // FIXME: This should only use space for first class types!
+
+  { // INST_LOAD abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_LOAD_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_BINOP abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_BINOP_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_BINOP_FLAGS abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // flags
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_BINOP_FLAGS_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_CAST abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));    // OpVal
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,       // dest ty
+                              Log2_32_Ceil(VE.getTypes().size()+1)));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));  // opc
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_CAST_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  { // INST_RET abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_RET_VOID_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_RET abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ValID
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_RET_VAL_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+  { // INST_UNREACHABLE abbrev for FUNCTION_BLOCK.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE));
+    if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID,
+                                   Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
+
+  Stream.ExitBlock();
+}
+
+/// WriteModule - Emit the specified module to the bitstream.
+static void WriteModule(const Module *M, BitstreamWriter &Stream) {
+  Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
+
+  SmallVector<unsigned, 1> Vals;
+  // TODO(srhines): RenderScript is always version 0 for now.
+  unsigned CurVersion = 0;
+  if (CurVersion) {
+    Vals.push_back(CurVersion);
+    Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals);
+  }
+
+  // Analyze the module, enumerating globals, functions, etc.
+  llvm_3_2::ValueEnumerator VE(*M);
+
+  // Emit blockinfo, which defines the standard abbreviations etc.
+  WriteBlockInfo(VE, Stream);
+
+  // Emit information about parameter attributes.
+  WriteAttributeTable(VE, Stream);
+
+  // Emit information describing all of the types in the module.
+  WriteTypeTable(VE, Stream);
+
+  // Emit top-level description of module, including target triple, inline asm,
+  // descriptors for global variables, and function prototype info.
+  WriteModuleInfo(M, VE, Stream);
+
+  // Emit constants.
+  WriteModuleConstants(VE, Stream);
+
+  // Emit metadata.
+  WriteModuleMetadata(M, VE, Stream);
+
+  // Emit metadata.
+  WriteModuleMetadataStore(M, Stream);
+
+  // Emit names for globals/functions etc.
+  WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream);
+
+  // Emit module-level use-lists.
+  if (false)
+    WriteUseListBlock(nullptr, VE, Stream);
+
+  // Emit function bodies.
+  for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)
+    if (!F->isDeclaration())
+      WriteFunction(*F, VE, Stream);
+
+  Stream.ExitBlock();
+}
+
+/// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a
+/// header and trailer to make it compatible with the system archiver.  To do
+/// this we emit the following header, and then emit a trailer that pads the
+/// file out to be a multiple of 16 bytes.
+///
+/// struct bc_header {
+///   uint32_t Magic;         // 0x0B17C0DE
+///   uint32_t Version;       // Version, currently always 0.
+///   uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+///   uint32_t BitcodeSize;   // Size of traditional bitcode file.
+///   uint32_t CPUType;       // CPU specifier.
+///   ... potentially more later ...
+/// };
+enum {
+  DarwinBCSizeFieldOffset = 3*4, // Offset to bitcode_size.
+  DarwinBCHeaderSize = 5*4
+};
+
+static void WriteInt32ToBuffer(uint32_t Value, SmallVectorImpl<char> &Buffer,
+                               uint32_t &Position) {
+  Buffer[Position + 0] = (unsigned char) (Value >>  0);
+  Buffer[Position + 1] = (unsigned char) (Value >>  8);
+  Buffer[Position + 2] = (unsigned char) (Value >> 16);
+  Buffer[Position + 3] = (unsigned char) (Value >> 24);
+  Position += 4;
+}
+
+static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
+                                         const Triple &TT) {
+  unsigned CPUType = ~0U;
+
+  // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*,
+  // armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. The CPUType is a magic
+  // number from /usr/include/mach/machine.h.  It is ok to reproduce the
+  // specific constants here because they are implicitly part of the Darwin ABI.
+  enum {
+    DARWIN_CPU_ARCH_ABI64      = 0x01000000,
+    DARWIN_CPU_TYPE_X86        = 7,
+    DARWIN_CPU_TYPE_ARM        = 12,
+    DARWIN_CPU_TYPE_POWERPC    = 18
+  };
+
+  Triple::ArchType Arch = TT.getArch();
+  if (Arch == Triple::x86_64)
+    CPUType = DARWIN_CPU_TYPE_X86 | DARWIN_CPU_ARCH_ABI64;
+  else if (Arch == Triple::x86)
+    CPUType = DARWIN_CPU_TYPE_X86;
+  else if (Arch == Triple::ppc)
+    CPUType = DARWIN_CPU_TYPE_POWERPC;
+  else if (Arch == Triple::ppc64)
+    CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64;
+  else if (Arch == Triple::arm || Arch == Triple::thumb)
+    CPUType = DARWIN_CPU_TYPE_ARM;
+
+  // Traditional Bitcode starts after header.
+  assert(Buffer.size() >= DarwinBCHeaderSize &&
+         "Expected header size to be reserved");
+  unsigned BCOffset = DarwinBCHeaderSize;
+  unsigned BCSize = Buffer.size()-DarwinBCHeaderSize;
+
+  // Write the magic and version.
+  unsigned Position = 0;
+  WriteInt32ToBuffer(0x0B17C0DE , Buffer, Position);
+  WriteInt32ToBuffer(0          , Buffer, Position); // Version.
+  WriteInt32ToBuffer(BCOffset   , Buffer, Position);
+  WriteInt32ToBuffer(BCSize     , Buffer, Position);
+  WriteInt32ToBuffer(CPUType    , Buffer, Position);
+
+  // If the file is not a multiple of 16 bytes, insert dummy padding.
+  while (Buffer.size() & 15)
+    Buffer.push_back(0);
+}
+
+/// WriteBitcodeToFile - Write the specified module to the specified output
+/// stream.
+void llvm_3_2::WriteBitcodeToFile(const Module *M, raw_ostream &Out) {
+  SmallVector<char, 0> Buffer;
+  Buffer.reserve(256*1024);
+
+  // If this is darwin or another generic macho target, reserve space for the
+  // header.
+  Triple TT(M->getTargetTriple());
+  if (TT.isOSDarwin())
+    Buffer.insert(Buffer.begin(), DarwinBCHeaderSize, 0);
+
+  // Emit the module into the buffer.
+  {
+    BitstreamWriter Stream(Buffer);
+
+    // Emit the file header.
+    Stream.Emit((unsigned)'B', 8);
+    Stream.Emit((unsigned)'C', 8);
+    Stream.Emit(0x0, 4);
+    Stream.Emit(0xC, 4);
+    Stream.Emit(0xE, 4);
+    Stream.Emit(0xD, 4);
+
+    // Emit the module.
+    WriteModule(M, Stream);
+  }
+
+  if (TT.isOSDarwin())
+    EmitDarwinBCHeaderAndTrailer(Buffer, TT);
+
+  // Write the generated bitstream to "Out".
+  Out.write((char*)&Buffer.front(), Buffer.size());
+}
diff --git a/slang/BitWriter_3_2/BitcodeWriterPass.cpp b/slang/BitWriter_3_2/BitcodeWriterPass.cpp
new file mode 100644
index 0000000..cc105c9
--- /dev/null
+++ b/slang/BitWriter_3_2/BitcodeWriterPass.cpp
@@ -0,0 +1,46 @@
+//===--- Bitcode/Writer/BitcodeWriterPass.cpp - Bitcode Writer ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// BitcodeWriterPass implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReaderWriter_3_2.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+using namespace llvm;
+
+namespace {
+  class WriteBitcodePass : public ModulePass {
+    raw_ostream &OS; // raw_ostream to print on
+
+  public:
+    static char ID; // Pass identification, replacement for typeid
+    explicit WriteBitcodePass(raw_ostream &o)
+      : ModulePass(ID), OS(o) {}
+    
+    const char *getPassName() const { return "Bitcode Writer"; }
+    
+    bool runOnModule(Module &M) {
+      bool Changed = false;
+      llvm_3_2::WriteBitcodeToFile(&M, OS);
+      return Changed;
+    }
+  };
+}
+
+char WriteBitcodePass::ID = 0;
+
+/// createBitcodeWriterPass - Create and return a pass that writes the module
+/// to the specified ostream.
+ModulePass *llvm_3_2::createBitcodeWriterPass(raw_ostream &Str) {
+  return new WriteBitcodePass(Str);
+}
diff --git a/slang/BitWriter_3_2/ReaderWriter_3_2.h b/slang/BitWriter_3_2/ReaderWriter_3_2.h
new file mode 100644
index 0000000..d192ad6
--- /dev/null
+++ b/slang/BitWriter_3_2/ReaderWriter_3_2.h
@@ -0,0 +1,143 @@
+//===-- llvm/Bitcode/ReaderWriter.h - Bitcode reader/writers ----*- 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 interfaces to read and write LLVM bitcode files/streams.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_3_2_H
+#define LLVM_BITCODE_3_2_H
+
+#include <string>
+
+namespace llvm {
+  class Module;
+  class MemoryBuffer;
+  class ModulePass;
+  class BitstreamWriter;
+  class LLVMContext;
+  class raw_ostream;
+}  // End llvm namespace
+
+namespace llvm_3_2 {
+  /// getLazyBitcodeModule - Read the header of the specified bitcode buffer
+  /// and prepare for lazy deserialization of function bodies.  If successful,
+  /// this takes ownership of 'buffer' and returns a non-null pointer.  On
+  /// error, this returns null, *does not* take ownership of Buffer, and fills
+  /// in *ErrMsg with an error description if ErrMsg is non-null.
+  llvm::Module *getLazyBitcodeModule(llvm::MemoryBuffer *Buffer,
+                               llvm::LLVMContext& Context,
+                               std::string *ErrMsg = 0);
+
+  /// getBitcodeTargetTriple - Read the header of the specified bitcode
+  /// buffer and extract just the triple information. If successful,
+  /// this returns a string and *does not* take ownership
+  /// of 'buffer'. On error, this returns "", and fills in *ErrMsg
+  /// if ErrMsg is non-null.
+  std::string getBitcodeTargetTriple(llvm::MemoryBuffer *Buffer,
+                                     llvm::LLVMContext& Context,
+                                     std::string *ErrMsg = 0);
+
+  /// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+  /// If an error occurs, this returns null and fills in *ErrMsg if it is
+  /// non-null.  This method *never* takes ownership of Buffer.
+  llvm::Module *ParseBitcodeFile(llvm::MemoryBuffer *Buffer, llvm::LLVMContext& Context,
+                           std::string *ErrMsg = 0);
+
+  /// WriteBitcodeToFile - Write the specified module to the specified
+  /// raw output stream.  For streams where it matters, the given stream
+  /// should be in "binary" mode.
+  void WriteBitcodeToFile(const llvm::Module *M, llvm::raw_ostream &Out);
+
+  /// createBitcodeWriterPass - Create and return a pass that writes the module
+  /// to the specified ostream.
+  llvm::ModulePass *createBitcodeWriterPass(llvm::raw_ostream &Str);
+
+
+  /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
+  /// for an LLVM IR bitcode wrapper.
+  ///
+  static inline bool isBitcodeWrapper(const unsigned char *BufPtr,
+                                      const unsigned char *BufEnd) {
+    // See if you can find the hidden message in the magic bytes :-).
+    // (Hint: it's a little-endian encoding.)
+    return BufPtr != BufEnd &&
+           BufPtr[0] == 0xDE &&
+           BufPtr[1] == 0xC0 &&
+           BufPtr[2] == 0x17 &&
+           BufPtr[3] == 0x0B;
+  }
+
+  /// isRawBitcode - Return true if the given bytes are the magic bytes for
+  /// raw LLVM IR bitcode (without a wrapper).
+  ///
+  static inline bool isRawBitcode(const unsigned char *BufPtr,
+                                  const unsigned char *BufEnd) {
+    // These bytes sort of have a hidden message, but it's not in
+    // little-endian this time, and it's a little redundant.
+    return BufPtr != BufEnd &&
+           BufPtr[0] == 'B' &&
+           BufPtr[1] == 'C' &&
+           BufPtr[2] == 0xc0 &&
+           BufPtr[3] == 0xde;
+  }
+
+  /// isBitcode - Return true if the given bytes are the magic bytes for
+  /// LLVM IR bitcode, either with or without a wrapper.
+  ///
+  static bool inline isBitcode(const unsigned char *BufPtr,
+                               const unsigned char *BufEnd) {
+    return isBitcodeWrapper(BufPtr, BufEnd) ||
+           isRawBitcode(BufPtr, BufEnd);
+  }
+
+  /// SkipBitcodeWrapperHeader - Some systems wrap bc files with a special
+  /// header for padding or other reasons.  The format of this header is:
+  ///
+  /// struct bc_header {
+  ///   uint32_t Magic;         // 0x0B17C0DE
+  ///   uint32_t Version;       // Version, currently always 0.
+  ///   uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+  ///   uint32_t BitcodeSize;   // Size of traditional bitcode file.
+  ///   ... potentially other gunk ...
+  /// };
+  ///
+  /// This function is called when we find a file with a matching magic number.
+  /// In this case, skip down to the subsection of the file that is actually a
+  /// BC file.
+  static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr,
+                                              unsigned char *&BufEnd) {
+    enum {
+      KnownHeaderSize = 4*4,  // Size of header we read.
+      OffsetField = 2*4,      // Offset in bytes to Offset field.
+      SizeField = 3*4         // Offset in bytes to Size field.
+    };
+
+    // Must contain the header!
+    if (BufEnd-BufPtr < KnownHeaderSize) return true;
+
+    unsigned Offset = ( BufPtr[OffsetField  ]        |
+                       (BufPtr[OffsetField+1] << 8)  |
+                       (BufPtr[OffsetField+2] << 16) |
+                       (BufPtr[OffsetField+3] << 24));
+    unsigned Size   = ( BufPtr[SizeField    ]        |
+                       (BufPtr[SizeField  +1] << 8)  |
+                       (BufPtr[SizeField  +2] << 16) |
+                       (BufPtr[SizeField  +3] << 24));
+
+    // Verify that Offset+Size fits in the file.
+    if (Offset+Size > unsigned(BufEnd-BufPtr))
+      return true;
+    BufPtr += Offset;
+    BufEnd = BufPtr+Size;
+    return false;
+  }
+}  // End llvm_3_2 namespace
+
+#endif
diff --git a/slang/BitWriter_3_2/ValueEnumerator.cpp b/slang/BitWriter_3_2/ValueEnumerator.cpp
new file mode 100644
index 0000000..4ce2ec6
--- /dev/null
+++ b/slang/BitWriter_3_2/ValueEnumerator.cpp
@@ -0,0 +1,546 @@
+//===-- ValueEnumerator.cpp - Number values and types for bitcode writer --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ValueEnumerator class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ValueEnumerator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+using namespace llvm;
+
+namespace llvm_3_2 {
+
+static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
+  return V.first->getType()->isIntOrIntVectorTy();
+}
+
+/// ValueEnumerator - Enumerate module-level information.
+ValueEnumerator::ValueEnumerator(const llvm::Module &M)
+    : HasMDString(false), HasDILocation(false) {
+  // Enumerate the global variables.
+  for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I)
+    EnumerateValue(&*I);
+
+  // Enumerate the functions.
+  for (llvm::Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
+    EnumerateValue(&*I);
+    EnumerateAttributes(cast<Function>(I)->getAttributes());
+  }
+
+  // Enumerate the aliases.
+  for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
+       I != E; ++I)
+    EnumerateValue(&*I);
+
+  // Remember what is the cutoff between globalvalue's and other constants.
+  unsigned FirstConstant = Values.size();
+
+  // Enumerate the global variable initializers.
+  for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+       I != E; ++I)
+    if (I->hasInitializer())
+      EnumerateValue(I->getInitializer());
+
+  // Enumerate the aliasees.
+  for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
+       I != E; ++I)
+    EnumerateValue(I->getAliasee());
+
+  // Enumerate the metadata type.
+  //
+  // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode
+  // only encodes the metadata type when it's used as a value.
+  EnumerateType(Type::getMetadataTy(M.getContext()));
+
+  // Insert constants and metadata that are named at module level into the slot
+  // pool so that the module symbol table can refer to them...
+  EnumerateValueSymbolTable(M.getValueSymbolTable());
+  EnumerateNamedMetadata(M);
+
+  SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
+
+  // Enumerate types used by function bodies and argument lists.
+  for (const Function &F : M) {
+    for (const Argument &A : F.args())
+      EnumerateType(A.getType());
+
+    for (const BasicBlock &BB : F)
+      for (const Instruction &I : BB) {
+        for (const Use &Op : I.operands()) {
+          auto *MD = dyn_cast<MetadataAsValue>(&Op);
+          if (!MD) {
+            EnumerateOperandType(Op);
+            continue;
+          }
+
+          // Local metadata is enumerated during function-incorporation.
+          if (isa<LocalAsMetadata>(MD->getMetadata()))
+            continue;
+
+          EnumerateMetadata(MD->getMetadata());
+        }
+        EnumerateType(I.getType());
+        if (const CallInst *CI = dyn_cast<CallInst>(&I))
+          EnumerateAttributes(CI->getAttributes());
+        else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I))
+          EnumerateAttributes(II->getAttributes());
+
+        // Enumerate metadata attached with this instruction.
+        MDs.clear();
+        I.getAllMetadataOtherThanDebugLoc(MDs);
+        for (unsigned i = 0, e = MDs.size(); i != e; ++i)
+          EnumerateMetadata(MDs[i].second);
+
+        // Don't enumerate the location directly -- it has a special record
+        // type -- but enumerate its operands.
+        if (DILocation *L = I.getDebugLoc())
+          EnumerateMDNodeOperands(L);
+      }
+  }
+
+  // Optimize constant ordering.
+  OptimizeConstants(FirstConstant, Values.size());
+}
+
+unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
+  InstructionMapType::const_iterator I = InstructionMap.find(Inst);
+  assert(I != InstructionMap.end() && "Instruction is not mapped!");
+  return I->second;
+}
+
+void ValueEnumerator::setInstructionID(const Instruction *I) {
+  InstructionMap[I] = InstructionCount++;
+}
+
+unsigned ValueEnumerator::getValueID(const Value *V) const {
+  if (auto *MD = dyn_cast<MetadataAsValue>(V))
+    return getMetadataID(MD->getMetadata());
+
+  ValueMapType::const_iterator I = ValueMap.find(V);
+  assert(I != ValueMap.end() && "Value not in slotcalculator!");
+  return I->second-1;
+}
+
+void ValueEnumerator::dump() const {
+  print(dbgs(), ValueMap, "Default");
+  dbgs() << '\n';
+  print(dbgs(), MDValueMap, "MetaData");
+  dbgs() << '\n';
+}
+
+void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
+                            const char *Name) const {
+
+  OS << "Map Name: " << Name << "\n";
+  OS << "Size: " << Map.size() << "\n";
+  for (ValueMapType::const_iterator I = Map.begin(),
+         E = Map.end(); I != E; ++I) {
+
+    const Value *V = I->first;
+    if (V->hasName())
+      OS << "Value: " << V->getName();
+    else
+      OS << "Value: [null]\n";
+    V->dump();
+
+    OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):";
+    for (const Use &U : V->uses()) {
+      if (&U != &*V->use_begin())
+        OS << ",";
+      if(U->hasName())
+        OS << " " << U->getName();
+      else
+        OS << " [null]";
+
+    }
+    OS <<  "\n\n";
+  }
+}
+
+void ValueEnumerator::print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+                            const char *Name) const {
+
+  OS << "Map Name: " << Name << "\n";
+  OS << "Size: " << Map.size() << "\n";
+  for (auto I = Map.begin(), E = Map.end(); I != E; ++I) {
+    const llvm::Metadata *MD = I->first;
+    OS << "Metadata: slot = " << I->second << "\n";
+    MD->print(OS);
+  }
+}
+
+
+// Optimize constant ordering.
+namespace {
+  struct CstSortPredicate {
+    ValueEnumerator &VE;
+    explicit CstSortPredicate(ValueEnumerator &ve) : VE(ve) {}
+    bool operator()(const std::pair<const Value*, unsigned> &LHS,
+                    const std::pair<const Value*, unsigned> &RHS) {
+      // Sort by plane.
+      if (LHS.first->getType() != RHS.first->getType())
+        return VE.getTypeID(LHS.first->getType()) <
+               VE.getTypeID(RHS.first->getType());
+      // Then by frequency.
+      return LHS.second > RHS.second;
+    }
+  };
+}
+
+/// OptimizeConstants - Reorder constant pool for denser encoding.
+void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {
+  if (CstStart == CstEnd || CstStart+1 == CstEnd) return;
+
+  CstSortPredicate P(*this);
+  std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P);
+
+  // Ensure that integer and vector of integer constants are at the start of the
+  // constant pool.  This is important so that GEP structure indices come before
+  // gep constant exprs.
+  std::partition(Values.begin()+CstStart, Values.begin()+CstEnd,
+                 isIntOrIntVectorValue);
+
+  // Rebuild the modified portion of ValueMap.
+  for (; CstStart != CstEnd; ++CstStart)
+    ValueMap[Values[CstStart].first] = CstStart+1;
+}
+
+
+/// EnumerateValueSymbolTable - Insert all of the values in the specified symbol
+/// table into the values table.
+void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
+  for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end();
+       VI != VE; ++VI)
+    EnumerateValue(VI->getValue());
+}
+
+/// EnumerateNamedMetadata - Insert all of the values referenced by
+/// named metadata in the specified module.
+void ValueEnumerator::EnumerateNamedMetadata(const llvm::Module &M) {
+  for (llvm::Module::const_named_metadata_iterator I = M.named_metadata_begin(),
+                                             E = M.named_metadata_end();
+       I != E; ++I)
+    EnumerateNamedMDNode(&*I);
+}
+
+void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
+  for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i)
+    EnumerateMetadata(MD->getOperand(i));
+}
+
+/// EnumerateMDNodeOperands - Enumerate all non-function-local values
+/// and types referenced by the given MDNode.
+void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) {
+  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+    Metadata *MD = N->getOperand(i);
+    if (!MD)
+      continue;
+    assert(!isa<LocalAsMetadata>(MD) && "MDNodes cannot be function-local");
+    EnumerateMetadata(MD);
+  }
+}
+
+void ValueEnumerator::EnumerateMetadata(const llvm::Metadata *MD) {
+  assert(
+      (isa<MDNode>(MD) || isa<MDString>(MD) || isa<ConstantAsMetadata>(MD)) &&
+      "Invalid metadata kind");
+
+  // Insert a dummy ID to block the co-recursive call to
+  // EnumerateMDNodeOperands() from re-visiting MD in a cyclic graph.
+  //
+  // Return early if there's already an ID.
+  if (!MDValueMap.insert(std::make_pair(MD, 0)).second)
+    return;
+
+  // Visit operands first to minimize RAUW.
+  if (auto *N = dyn_cast<MDNode>(MD))
+    EnumerateMDNodeOperands(N);
+  else if (auto *C = dyn_cast<ConstantAsMetadata>(MD))
+    EnumerateValue(C->getValue());
+
+  HasMDString |= isa<MDString>(MD);
+  HasDILocation |= isa<DILocation>(MD);
+
+  // Replace the dummy ID inserted above with the correct one.  MDValueMap may
+  // have changed by inserting operands, so we need a fresh lookup here.
+  MDs.push_back(MD);
+  MDValueMap[MD] = MDs.size();
+}
+
+/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata
+/// information reachable from the metadata.
+void ValueEnumerator::EnumerateFunctionLocalMetadata(
+    const llvm::LocalAsMetadata *Local) {
+  // Check to see if it's already in!
+  unsigned &MDValueID = MDValueMap[Local];
+  if (MDValueID)
+    return;
+
+  MDs.push_back(Local);
+  MDValueID = MDs.size();
+
+  EnumerateValue(Local->getValue());
+
+  // Also, collect all function-local metadata for easy access.
+  FunctionLocalMDs.push_back(Local);
+}
+
+void ValueEnumerator::EnumerateValue(const Value *V) {
+  assert(!V->getType()->isVoidTy() && "Can't insert void values!");
+  assert(!isa<MetadataAsValue>(V) && "EnumerateValue doesn't handle Metadata!");
+
+  // Check to see if it's already in!
+  unsigned &ValueID = ValueMap[V];
+  if (ValueID) {
+    // Increment use count.
+    Values[ValueID-1].second++;
+    return;
+  }
+
+  // Enumerate the type of this value.
+  EnumerateType(V->getType());
+
+  if (const Constant *C = dyn_cast<Constant>(V)) {
+    if (isa<GlobalValue>(C)) {
+      // Initializers for globals are handled explicitly elsewhere.
+    } else if (C->getNumOperands()) {
+      // If a constant has operands, enumerate them.  This makes sure that if a
+      // constant has uses (for example an array of const ints), that they are
+      // inserted also.
+
+      // We prefer to enumerate them with values before we enumerate the user
+      // itself.  This makes it more likely that we can avoid forward references
+      // in the reader.  We know that there can be no cycles in the constants
+      // graph that don't go through a global variable.
+      for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
+           I != E; ++I)
+        if (!isa<BasicBlock>(*I)) // Don't enumerate BB operand to BlockAddress.
+          EnumerateValue(*I);
+
+      // Finally, add the value.  Doing this could make the ValueID reference be
+      // dangling, don't reuse it.
+      Values.push_back(std::make_pair(V, 1U));
+      ValueMap[V] = Values.size();
+      return;
+    } else if (const ConstantDataSequential *CDS =
+               dyn_cast<ConstantDataSequential>(C)) {
+      // For our legacy handling of the new ConstantDataSequential type, we
+      // need to enumerate the individual elements, as well as mark the
+      // outer constant as used.
+      for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+        EnumerateValue(CDS->getElementAsConstant(i));
+      Values.push_back(std::make_pair(V, 1U));
+      ValueMap[V] = Values.size();
+      return;
+    }
+  }
+
+  // Add the value.
+  Values.push_back(std::make_pair(V, 1U));
+  ValueID = Values.size();
+}
+
+
+void ValueEnumerator::EnumerateType(Type *Ty) {
+  unsigned *TypeID = &TypeMap[Ty];
+
+  // We've already seen this type.
+  if (*TypeID)
+    return;
+
+  // If it is a non-anonymous struct, mark the type as being visited so that we
+  // don't recursively visit it.  This is safe because we allow forward
+  // references of these in the bitcode reader.
+  if (StructType *STy = dyn_cast<StructType>(Ty))
+    if (!STy->isLiteral())
+      *TypeID = ~0U;
+
+  // Enumerate all of the subtypes before we enumerate this type.  This ensures
+  // that the type will be enumerated in an order that can be directly built.
+  for (Type *SubTy : Ty->subtypes())
+    EnumerateType(SubTy);
+
+  // Refresh the TypeID pointer in case the table rehashed.
+  TypeID = &TypeMap[Ty];
+
+  // Check to see if we got the pointer another way.  This can happen when
+  // enumerating recursive types that hit the base case deeper than they start.
+  //
+  // If this is actually a struct that we are treating as forward ref'able,
+  // then emit the definition now that all of its contents are available.
+  if (*TypeID && *TypeID != ~0U)
+    return;
+
+  // Add this type now that its contents are all happily enumerated.
+  Types.push_back(Ty);
+
+  *TypeID = Types.size();
+}
+
+// Enumerate the types for the specified value.  If the value is a constant,
+// walk through it, enumerating the types of the constant.
+void ValueEnumerator::EnumerateOperandType(const Value *V) {
+  EnumerateType(V->getType());
+
+  if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
+    assert(!isa<LocalAsMetadata>(MD->getMetadata()) &&
+           "Function-local metadata should be left for later");
+
+    EnumerateMetadata(MD->getMetadata());
+    return;
+  }
+
+  const Constant *C = dyn_cast<Constant>(V);
+  if (!C)
+    return;
+
+  // If this constant is already enumerated, ignore it, we know its type must
+  // be enumerated.
+  if (ValueMap.count(C))
+    return;
+
+  // This constant may have operands, make sure to enumerate the types in
+  // them.
+  for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
+    const Value *Op = C->getOperand(i);
+
+    // Don't enumerate basic blocks here, this happens as operands to
+    // blockaddress.
+    if (isa<BasicBlock>(Op))
+      continue;
+
+    EnumerateOperandType(Op);
+  }
+}
+
+void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) {
+  if (PAL.isEmpty()) return;  // null is always 0.
+
+  // Do a lookup.
+  unsigned &Entry = AttributeMap[PAL];
+  if (Entry == 0) {
+    // Never saw this before, add it.
+    Attribute.push_back(PAL);
+    Entry = Attribute.size();
+  }
+
+  // Do lookups for all attribute groups.
+  for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) {
+    AttributeSet AS = PAL.getSlotAttributes(i);
+    unsigned &Entry = AttributeGroupMap[AS];
+    if (Entry == 0) {
+      AttributeGroups.push_back(AS);
+      Entry = AttributeGroups.size();
+    }
+  }
+}
+
+void ValueEnumerator::incorporateFunction(const Function &F) {
+  InstructionCount = 0;
+  NumModuleValues = Values.size();
+  NumModuleMDs = MDs.size();
+
+  // Adding function arguments to the value table.
+  for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
+       I != E; ++I)
+    EnumerateValue(&*I);
+
+  FirstFuncConstantID = Values.size();
+
+  // Add all function-level constants to the value table.
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I)
+      for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
+           OI != E; ++OI) {
+        if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||
+            isa<InlineAsm>(*OI))
+          EnumerateValue(*OI);
+      }
+    BasicBlocks.push_back(&*BB);
+    ValueMap[&*BB] = BasicBlocks.size();
+  }
+
+  // Optimize the constant layout.
+  OptimizeConstants(FirstFuncConstantID, Values.size());
+
+  // Add the function's parameter attributes so they are available for use in
+  // the function's instruction.
+  EnumerateAttributes(F.getAttributes());
+
+  FirstInstID = Values.size();
+
+  SmallVector<llvm::LocalAsMetadata *, 8> FnLocalMDVector;
+  // Add all of the instructions.
+  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
+      for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
+           OI != E; ++OI) {
+        if (auto *MD = dyn_cast<llvm::MetadataAsValue>(&*OI))
+          if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata()))
+            // Enumerate metadata after the instructions they might refer to.
+            FnLocalMDVector.push_back(Local);
+      }
+
+      if (!I->getType()->isVoidTy())
+        EnumerateValue(&*I);
+    }
+  }
+
+  // Add all of the function-local metadata.
+  for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i)
+    EnumerateFunctionLocalMetadata(FnLocalMDVector[i]);
+}
+
+void ValueEnumerator::purgeFunction() {
+  /// Remove purged values from the ValueMap.
+  for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i)
+    ValueMap.erase(Values[i].first);
+  for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i)
+    MDValueMap.erase(MDs[i]);
+  for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
+    ValueMap.erase(BasicBlocks[i]);
+
+  Values.resize(NumModuleValues);
+  MDs.resize(NumModuleMDs);
+  BasicBlocks.clear();
+  FunctionLocalMDs.clear();
+}
+
+static void IncorporateFunctionInfoGlobalBBIDs(const Function *F,
+                                 DenseMap<const BasicBlock*, unsigned> &IDMap) {
+  unsigned Counter = 0;
+  for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+    IDMap[&*BB] = ++Counter;
+}
+
+/// getGlobalBasicBlockID - This returns the function-specific ID for the
+/// specified basic block.  This is relatively expensive information, so it
+/// should only be used by rare constructs such as address-of-label.
+unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const {
+  unsigned &Idx = GlobalBasicBlockIDs[BB];
+  if (Idx != 0)
+    return Idx-1;
+
+  IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs);
+  return getGlobalBasicBlockID(BB);
+}
+
+}  // end llvm_3_2 namespace
diff --git a/slang/BitWriter_3_2/ValueEnumerator.h b/slang/BitWriter_3_2/ValueEnumerator.h
new file mode 100644
index 0000000..124272f
--- /dev/null
+++ b/slang/BitWriter_3_2/ValueEnumerator.h
@@ -0,0 +1,198 @@
+//===-- Bitcode/Writer/ValueEnumerator.h - Number values --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class gives values and types Unique ID's.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef VALUE_ENUMERATOR_H
+#define VALUE_ENUMERATOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/UseListOrder.h"
+#include <vector>
+
+namespace llvm {
+
+class Type;
+class Value;
+class Instruction;
+class BasicBlock;
+class Function;
+class Module;
+class Metadata;
+class LocalAsMetadata;
+class MDNode;
+class NamedMDNode;
+class AttributeSet;
+class ValueSymbolTable;
+class MDSymbolTable;
+class raw_ostream;
+
+}  // end llvm namespace
+
+namespace llvm_3_2 {
+
+class ValueEnumerator {
+public:
+  typedef std::vector<llvm::Type*> TypeList;
+
+  // For each value, we remember its Value* and occurrence frequency.
+  typedef std::vector<std::pair<const llvm::Value*, unsigned> > ValueList;
+
+  llvm::UseListOrderStack UseListOrders;
+private:
+  typedef llvm::DenseMap<llvm::Type*, unsigned> TypeMapType;
+  TypeMapType TypeMap;
+  TypeList Types;
+
+  typedef llvm::DenseMap<const llvm::Value*, unsigned> ValueMapType;
+  ValueMapType ValueMap;
+  ValueList Values;
+
+
+  std::vector<const llvm::Metadata *> MDs;
+  llvm::SmallVector<const llvm::LocalAsMetadata *, 8> FunctionLocalMDs;
+  typedef llvm::DenseMap<const llvm::Metadata *, unsigned> MetadataMapType;
+  MetadataMapType MDValueMap;
+  bool HasMDString;
+  bool HasDILocation;
+
+  typedef llvm::DenseMap<llvm::AttributeSet, unsigned> AttributeGroupMapType;
+  AttributeGroupMapType AttributeGroupMap;
+  std::vector<llvm::AttributeSet> AttributeGroups;
+
+  typedef llvm::DenseMap<llvm::AttributeSet, unsigned> AttributeMapType;
+  AttributeMapType AttributeMap;
+  std::vector<llvm::AttributeSet> Attribute;
+
+  /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
+  /// the "getGlobalBasicBlockID" method.
+  mutable llvm::DenseMap<const llvm::BasicBlock*, unsigned> GlobalBasicBlockIDs;
+
+  typedef llvm::DenseMap<const llvm::Instruction*, unsigned> InstructionMapType;
+  InstructionMapType InstructionMap;
+  unsigned InstructionCount;
+
+  /// BasicBlocks - This contains all the basic blocks for the currently
+  /// incorporated function.  Their reverse mapping is stored in ValueMap.
+  std::vector<const llvm::BasicBlock*> BasicBlocks;
+
+  /// When a function is incorporated, this is the size of the Values list
+  /// before incorporation.
+  unsigned NumModuleValues;
+
+  /// When a function is incorporated, this is the size of the MDValues list
+  /// before incorporation.
+  unsigned NumModuleMDs;
+
+  unsigned FirstFuncConstantID;
+  unsigned FirstInstID;
+
+  ValueEnumerator(const ValueEnumerator &) = delete;
+  void operator=(const ValueEnumerator &) = delete;
+public:
+  explicit ValueEnumerator(const llvm::Module &M);
+
+  void dump() const;
+  void print(llvm::raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
+  void print(llvm::raw_ostream &OS, const MetadataMapType &Map,
+             const char *Name) const;
+
+  unsigned getValueID(const llvm::Value *V) const;
+  unsigned getMetadataID(const llvm::Metadata *MD) const {
+    auto ID = getMetadataOrNullID(MD);
+    assert(ID != 0 && "Metadata not in slotcalculator!");
+    return ID - 1;
+  }
+  unsigned getMetadataOrNullID(const llvm::Metadata *MD) const {
+    return MDValueMap.lookup(MD);
+  }
+
+  bool hasMDString() const { return HasMDString; }
+  bool hasDILocation() const { return HasDILocation; }
+
+  unsigned getTypeID(llvm::Type *T) const {
+    TypeMapType::const_iterator I = TypeMap.find(T);
+    assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
+    return I->second-1;
+  }
+
+  unsigned getInstructionID(const llvm::Instruction *I) const;
+  void setInstructionID(const llvm::Instruction *I);
+
+  unsigned getAttributeID(llvm::AttributeSet PAL) const {
+    if (PAL.isEmpty()) return 0;  // Null maps to zero.
+    AttributeMapType::const_iterator I = AttributeMap.find(PAL);
+    assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!");
+    return I->second;
+  }
+
+  unsigned getAttributeGroupID(llvm::AttributeSet PAL) const {
+    if (PAL.isEmpty()) return 0;  // Null maps to zero.
+    AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL);
+    assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
+    return I->second;
+  }
+
+  /// getFunctionConstantRange - Return the range of values that corresponds to
+  /// function-local constants.
+  void getFunctionConstantRange(unsigned &Start, unsigned &End) const {
+    Start = FirstFuncConstantID;
+    End = FirstInstID;
+  }
+
+  const ValueList &getValues() const { return Values; }
+  const std::vector<const llvm::Metadata *> &getMDs() const { return MDs; }
+  const llvm::SmallVectorImpl<const llvm::LocalAsMetadata *> &getFunctionLocalMDs() const {
+    return FunctionLocalMDs;
+  }
+  const TypeList &getTypes() const { return Types; }
+  const std::vector<const llvm::BasicBlock*> &getBasicBlocks() const {
+    return BasicBlocks;
+  }
+  const std::vector<llvm::AttributeSet> &getAttributes() const {
+    return Attribute;
+  }
+  const std::vector<llvm::AttributeSet> &getAttributeGroups() const {
+    return AttributeGroups;
+  }
+
+  /// getGlobalBasicBlockID - This returns the function-specific ID for the
+  /// specified basic block.  This is relatively expensive information, so it
+  /// should only be used by rare constructs such as address-of-label.
+  unsigned getGlobalBasicBlockID(const llvm::BasicBlock *BB) const;
+
+  /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
+  /// use these two methods to get its data into the ValueEnumerator!
+  ///
+  void incorporateFunction(const llvm::Function &F);
+  void purgeFunction();
+
+private:
+  void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
+
+  void EnumerateMDNodeOperands(const llvm::MDNode *N);
+  void EnumerateMetadata(const llvm::Metadata *MD);
+  void EnumerateFunctionLocalMetadata(const llvm::LocalAsMetadata *Local);
+  void EnumerateNamedMDNode(const llvm::NamedMDNode *NMD);
+  void EnumerateValue(const llvm::Value *V);
+  void EnumerateType(llvm::Type *T);
+  void EnumerateOperandType(const llvm::Value *V);
+  void EnumerateAttributes(llvm::AttributeSet PAL);
+
+  void EnumerateValueSymbolTable(const llvm::ValueSymbolTable &ST);
+  void EnumerateNamedMetadata(const llvm::Module &M);
+};
+
+}  // End llvm_3_2 namespace
+
+#endif
diff --git a/slang/MODULE_LICENSE_APACHE2 b/slang/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/slang/MODULE_LICENSE_APACHE2
diff --git a/slang/NOTICE b/slang/NOTICE
new file mode 100644
index 0000000..485fde9
--- /dev/null
+++ b/slang/NOTICE
@@ -0,0 +1,339 @@
+=========================
+NOTICE file for slang.git
+=========================
+
+   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 file for external/clang (clang.git).
+Note: libclang*.a are statically linked.
+===========================================
+
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2007-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.
+
+==============================================================================
+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
+-------             ---------
+<none yet>
+
+
+
+=========================================
+NOTICE file for external/llvm (llvm.git).
+Note: libLLVM*.a are statically linked.
+=========================================
+
+==============================================================================
+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}
diff --git a/slang/README.html b/slang/README.html
new file mode 100644
index 0000000..4ace7c6
--- /dev/null
+++ b/slang/README.html
@@ -0,0 +1,626 @@
+<?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>llvm-rs-cc: Compiler for Renderscript language</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="llvm-rs-cc-compiler-for-renderscript-language">
+<h1 class="title">llvm-rs-cc: Compiler for Renderscript language</h1>
+
+<div class="section" id="introduction">
+<h1>Introduction</h1>
+<p>llvm-rs-cc compiles a program in the Renderscript language to generate the
+following files:</p>
+<ul class="simple">
+<li>Bitcode file. Note that the bitcode here denotes the LLVM (Low-Level
+Virtual Machine) bitcode representation, which will be consumed on
+an Android device by libbcc (in
+platform/frameworks/compile/libbcc.git) to generate device-specific
+executables.</li>
+<li>Reflected APIs for Java. As a result, Android's Java developers can
+invoke those APIs from their code.</li>
+</ul>
+<p>Note that although Renderscript is C99-like, we enhance it with several
+distinct, effective features for Android programming. We will use
+some examples to illustrate these features.</p>
+<p>llvm-rs-cc is run on the host and performs many aggressive optimizations.
+As a result, libbcc on the device can be lightweight and focus on
+machine-dependent code generation for some input bitcode.</p>
+<p>llvm-rs-cc is a driver on top of libslang. The architecture of
+libslang and libbcc is depicted in the following figure:</p>
+<pre class="literal-block">
+libslang   libbcc
+    |   \   |
+    |    \  |
+ clang     llvm
+</pre>
+</div>
+<div class="section" id="usage">
+<h1>Usage</h1>
+<ul>
+<li><p class="first"><em>-o $(PRIVATE_RS_OUTPUT_DIR)/res/raw</em></p>
+<p>This option specifies the directory for outputting a .bc file.</p>
+</li>
+<li><p class="first"><em>-p $(PRIVATE_RS_OUTPUT_DIR)/src</em></p>
+<p>The option <em>-p</em> denotes the directory for outputting the reflected Java files.</p>
+</li>
+<li><p class="first"><em>-d $(PRIVATE_RS_OUTPUT_DIR)</em></p>
+<p>This option <em>-d</em> sets the directory for writing dependence information.</p>
+</li>
+<li><p class="first"><em>-MD</em></p>
+<p>Note that <em>-MD</em> will tell llvm-rs-cc to output dependence information.</p>
+</li>
+<li><p class="first"><em>-a $(EXTRA_TARGETS)</em></p>
+<p>Specifies additional target dependencies.</p>
+</li>
+</ul>
+</div>
+<div class="section" id="example-command">
+<h1>Example Command</h1>
+<p>First:</p>
+<pre class="literal-block">
+$ cd &lt;Android_Root_Directory&gt;
+</pre>
+<p>Using frameworks/base/tests/RenderScriptTests/Fountain as a simple app in both
+Java and Renderscript, we can find the following command line in the build
+log:</p>
+<pre class="literal-block">
+$ out/host/linux-x86/bin/llvm-rs-cc \
+  -o out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/res/raw \
+  -p out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/src \
+  -d out/target/common/obj/APPS/Fountain_intermediates/src/renderscript \
+  -a out/target/common/obj/APPS/Fountain_intermediates/src/RenderScript.stamp \
+  -MD \
+  -I frameworks/base/libs/rs/scriptc \
+  -I external/clang/lib/Headers \
+  frameworks/base/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs
+</pre>
+<p>This command will generate:</p>
+<ul class="simple">
+<li><strong>fountain.bc</strong></li>
+<li><strong>ScriptC_fountain.java</strong></li>
+<li><strong>ScriptField_Point.java</strong></li>
+</ul>
+<p>The <strong>Script*.java</strong> files above will be documented below.</p>
+</div>
+<div class="section" id="example-program-fountain-rs">
+<h1>Example Program: fountain.rs</h1>
+<p>fountain.rs is in the Renderscript language, which is based on the standard
+C99. However, llvm-rs-cc goes beyond &quot;clang -std=c99&quot; and provides the
+following important features:</p>
+</div>
+<div class="section" id="pragma">
+<h1>1. Pragma</h1>
+<ul>
+<li><p class="first"><em>#pragma rs java_package_name([PACKAGE_NAME])</em></p>
+<p>The ScriptC_[SCRIPT_NAME].java has to be packaged so that Java
+developers can invoke those APIs.</p>
+<p>To do that, a Renderscript programmer should specify the package name, so
+that llvm-rs-cc knows the package expression and hence the directory
+for outputting ScriptC_[SCRIPT_NAME].java.</p>
+<p>In fountain.rs, we have:</p>
+<pre class="literal-block">
+#pragma rs java_package_name(com.android.fountain)
+</pre>
+<p>In ScriptC_fountain.java, we have:</p>
+<pre class="literal-block">
+package com.android.fountain
+</pre>
+<p>Note that the ScriptC_fountain.java will be generated inside
+./com/android/fountain/.</p>
+</li>
+<li><p class="first">#pragma version(1)</p>
+<p>This pragma is for evolving the language. Currently we are at
+version 1 of the language.</p>
+</li>
+</ul>
+</div>
+<div class="section" id="basic-reflection-export-variables-and-functions">
+<h1>2. Basic Reflection: Export Variables and Functions</h1>
+<p>llvm-rs-cc automatically exports the &quot;externalizable and defined&quot; functions and
+variables to Android's Java side. That is, scripts are accessible from
+Java.</p>
+<p>For instance, for:</p>
+<pre class="literal-block">
+int foo = 0;
+</pre>
+<p>In ScriptC_fountain.java, llvm-rs-cc will reflect the following methods:</p>
+<pre class="literal-block">
+void set_foo(int v)...
+
+int get_foo()...
+</pre>
+<p>This access takes the form of generated classes which provide access
+to the functions and global variables within a script. In summary,
+global variables and functions within a script that are not declared
+static will generate get, set, or invoke methods.  This provides a way
+to set the data within a script and call its functions.</p>
+<p>Take the addParticles function in fountain.rs as an example:</p>
+<pre class="literal-block">
+void addParticles(int rate, float x, float y, int index, bool newColor) {
+  ...
+}
+</pre>
+<p>llvm-rs-cc will genearte ScriptC_fountain.java as follows:</p>
+<pre class="literal-block">
+void invoke_addParticles(int rate, float x, float y,
+                         int index, bool newColor) {
+  ...
+}
+</pre>
+</div>
+<div class="section" id="export-user-defined-structs">
+<h1>3. Export User-Defined Structs</h1>
+<p>In fountain.rs, we have:</p>
+<pre class="literal-block">
+typedef struct __attribute__((packed, aligned(4))) Point {
+  float2 delta;
+  float2 position;
+  uchar4 color;
+} Point_t;
+
+Point_t *point;
+</pre>
+<p>llvm-rs-cc generates one ScriptField*.java file for each user-defined
+struct. In this case, llvm-rs-cc will reflect two files,
+ScriptC_fountain.java and ScriptField_Point.java.</p>
+<p>Note that when the type of an exportable variable is a structure, Renderscript
+developers should avoid using anonymous structs. This is because llvm-rs-cc
+uses the struct name to identify the file, instead of the typedef name.</p>
+<p>For the generated Java files, using ScriptC_fountain.java as an
+example we also have:</p>
+<pre class="literal-block">
+void bind_point(ScriptField_Point v)
+</pre>
+<p>This binds your object with the allocated memory.</p>
+<p>You can bind the struct(e.g., Point), using the setter and getter
+methods in ScriptField_Point.java.</p>
+<p>After binding, you can access the object with this method:</p>
+<pre class="literal-block">
+ScriptField_Point get_point()
+</pre>
+<p>In ScriptField_Point_s.java:</p>
+<pre class="literal-block">
+...
+// Copying the Item, which is the object that stores every
+// fields of struct, to the *index*\-th entry of byte array.
+//
+// In general, this method would not be invoked directly
+// but is used to implement the setter.
+void copyToArray(Item i, int index)
+
+// The setter of Item array,
+// index: the index of the Item array
+// copyNow: If true, it will be copied to the *index*\-th entry
+// of byte array.
+void set(Item i, int index, boolean copyNow)
+
+// The getter of Item array, which gets the *index*-th element
+// of byte array.
+Item get(int index)
+
+set_delta(int index, Float2 v, boolean copyNow)
+
+// The following is the individual setters and getters of
+// each field of a struct.
+public void set_delta(int index, Float2 v, boolean copyNow)
+public void set_position(int index, Float2 v, boolean copyNow)
+public void set_color(int index, Short4 v, boolean copyNow)
+public Float2 get_delta(int index)
+public Float2 get_position(int index)
+public Short4 get_color(int index)
+
+// Copying all Item array to byte array (i.e., memory allocation).
+void copyAll()
+...
+</pre>
+</div>
+<div class="section" id="summary-of-the-java-reflection-above">
+<h1>4. Summary of the Java Reflection above</h1>
+<p>This section summarizes the high-level design of Renderscript's reflection.</p>
+<ul>
+<li><p class="first">In terms of a script's global functions, they can be called from Java.
+These calls operate asynchronously and no assumptions should be made
+on whether a function called will have actually completed operation.  If it
+is necessary to wait for a function to complete, the Java application
+may call the runtime finish() method, which will wait for all the script
+threads to complete pending operations.  A few special functions can also
+exist:</p>
+<ul>
+<li><p class="first">The function <strong>init</strong> (if present) will be called once after the script
+is loaded.  This is useful to initialize data or anything else the
+script may need before it can be used.  The init function may not depend
+on globals initialized from Java as it will be called before these
+can be initialized. The function signature for init must be:</p>
+<pre class="literal-block">
+void init(void);
+</pre>
+</li>
+<li><p class="first">The function <strong>root</strong> is a special function for graphics.  This function
+will be called when a script must redraw its contents.  No
+assumptions should be made as to when this function will be
+called.  It will only be called if the script is bound as a graphics root.
+Calls to this function will be synchronized with data updates and
+other invocations from Java.  Thus the script will not change due
+to external influence in the middle of running <strong>root</strong>.  The return value
+indicates to the runtime when the function should be called again to
+redraw in the future.  A return value of 0 indicates that no
+redraw is necessary until something changes on the Java side.  Any
+positive integer indicates a time in milliseconds that the runtime should
+wait before calling root again to render another frame.  The function
+signature for a graphics root functions is as follows:</p>
+<pre class="literal-block">
+int root(void);
+</pre>
+</li>
+<li><p class="first">It is also possible to create a purely compute-based <strong>root</strong> function.
+Such a function has the following signature:</p>
+<pre class="literal-block">
+void root(const T1 *in, T2 *out, const T3 *usrData, uint32_t x, uint32_t y);
+</pre>
+<p>T1, T2, and T3 represent any supported Renderscript type.  Any parameters
+above can be omitted, although at least one of in/out must be present.
+If both in and out are present, root must only be invoked with types of
+the same exact dimensionality (i.e. matching X and Y values for dimension).
+This root function is accessible through the Renderscript language
+construct <strong>forEach</strong>.  We also reflect a Java version to access this
+function as <strong>forEach_root</strong> (for API levels of 14+).  An example of this
+can be seen in the Android SDK sample for HelloCompute.</p>
+</li>
+<li><p class="first">The function <strong>.rs.dtor</strong> is a function that is sometimes generated by
+llvm-rs-cc.  This function cleans up any global variable that contains
+(or is) a reference counted Renderscript object type (such as an
+rs_allocation, rs_font, or rs_script).  This function will be invoked
+implicitly by the Renderscript runtime during script teardown.</p>
+</li>
+</ul>
+</li>
+<li><p class="first">In terms of a script's global data, global variables can be written
+from Java.  The Java instance will cache the value or object set and
+provide return methods to retrieve this value.  If a script updates
+the value, this update will not propagate back to the Java class.
+Initializers, if present, will also initialize the cached Java value.
+This provides a convenient way to declare constants within a script and
+make them accessible to the Java runtime.  If the script declares a
+variable const, only the get methods will be generated.</p>
+<p>Globals within a script are considered local to the script.  They
+cannot be accessed by other scripts and are in effect always 'static'
+in the traditional C sense.  Static here is used to control if
+accessors are generated.  Static continues to mean <em>not
+externally visible</em> and thus prevents the generation of
+accessors.  Globals are persistent across invocations of a script and
+thus may be used to hold data from run to run.</p>
+<p>Globals of two types may be reflected into the Java class.  The first
+type is basic non-pointer types.  Types defined in rs_types.rsh may also be
+used.  For the non-pointer class, get and set methods are generated for
+Java.  Globals of single pointer types behave differently.  These may
+use more complex types.  Simple structures composed of the types in
+rs_types.rsh may also be used.  These globals generate bind points in
+Java.  If the type is a structure they also generate an appropriate
+<strong>Field</strong> class that is used to pack and unpack the contents of the
+structure.  Binding an allocation in Java effectively sets the
+pointer in the script.  Bind points marked const indicate to the
+runtime that the script will not modify the contents of an allocation.
+This may allow the runtime to make more effective use of threads.</p>
+</li>
+</ul>
+</div>
+<div class="section" id="vector-types">
+<h1>5. Vector Types</h1>
+<p>Vector types such as float2, float4, and uint4 are included to support
+vector processing in environments where the processors provide vector
+instructions.</p>
+<p>On non-vector systems the same code will continue to run but without
+the performance advantage.  Function overloading is also supported.
+This allows the runtime to support vector version of the basic math
+routines without the need for special naming.  For instance,</p>
+<ul class="simple">
+<li><em>float sin(float);</em></li>
+<li><em>float2 sin(float2);</em></li>
+<li><em>float3 sin(float3);</em></li>
+<li><em>float4 sin(float4);</em></li>
+</ul>
+</div>
+</div>
+</body>
+</html>
diff --git a/slang/README.rst b/slang/README.rst
new file mode 100644
index 0000000..972292e
--- /dev/null
+++ b/slang/README.rst
@@ -0,0 +1,343 @@
+==============================================
+llvm-rs-cc: Compiler for Renderscript language
+==============================================
+
+
+Introduction
+------------
+
+llvm-rs-cc compiles a program in the Renderscript language to generate the
+following files:
+
+* Bitcode file. Note that the bitcode here denotes the LLVM (Low-Level
+  Virtual Machine) bitcode representation, which will be consumed on
+  an Android device by libbcc (in
+  platform/frameworks/compile/libbcc.git) to generate device-specific
+  executables.
+
+* Reflected APIs for Java. As a result, Android's Java developers can
+  invoke those APIs from their code.
+
+Note that although Renderscript is C99-like, we enhance it with several
+distinct, effective features for Android programming. We will use
+some examples to illustrate these features.
+
+llvm-rs-cc is run on the host and performs many aggressive optimizations.
+As a result, libbcc on the device can be lightweight and focus on
+machine-dependent code generation for some input bitcode.
+
+llvm-rs-cc is a driver on top of libslang. The architecture of
+libslang and libbcc is depicted in the following figure::
+
+    libslang   libbcc
+        |   \   |
+        |    \  |
+     clang     llvm
+
+
+Usage
+-----
+
+* *-o $(PRIVATE_RS_OUTPUT_DIR)/res/raw*
+
+  This option specifies the directory for outputting a .bc file.
+
+* *-p $(PRIVATE_RS_OUTPUT_DIR)/src*
+
+  The option *-p* denotes the directory for outputting the reflected Java files.
+
+* *-d $(PRIVATE_RS_OUTPUT_DIR)*
+
+  This option *-d* sets the directory for writing dependence information.
+
+* *-MD*
+
+  Note that *-MD* will tell llvm-rs-cc to output dependence information.
+
+* *-a $(EXTRA_TARGETS)*
+
+  Specifies additional target dependencies.
+
+Example Command
+---------------
+
+First::
+
+  $ cd <Android_Root_Directory>
+
+Using frameworks/base/tests/RenderScriptTests/Fountain as a simple app in both
+Java and Renderscript, we can find the following command line in the build
+log::
+
+  $ out/host/linux-x86/bin/llvm-rs-cc \
+    -o out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/res/raw \
+    -p out/target/common/obj/APPS/Fountain_intermediates/src/renderscript/src \
+    -d out/target/common/obj/APPS/Fountain_intermediates/src/renderscript \
+    -a out/target/common/obj/APPS/Fountain_intermediates/src/RenderScript.stamp \
+    -MD \
+    -I frameworks/base/libs/rs/scriptc \
+    -I external/clang/lib/Headers \
+    frameworks/base/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs
+
+This command will generate:
+
+* **fountain.bc**
+
+* **ScriptC_fountain.java**
+
+* **ScriptField_Point.java**
+
+The **Script\*.java** files above will be documented below.
+
+
+Example Program: fountain.rs
+----------------------------
+
+fountain.rs is in the Renderscript language, which is based on the standard
+C99. However, llvm-rs-cc goes beyond "clang -std=c99" and provides the
+following important features:
+
+1. Pragma
+---------
+
+* *#pragma rs java_package_name([PACKAGE_NAME])*
+
+  The ScriptC_[SCRIPT_NAME].java has to be packaged so that Java
+  developers can invoke those APIs.
+
+  To do that, a Renderscript programmer should specify the package name, so
+  that llvm-rs-cc knows the package expression and hence the directory
+  for outputting ScriptC_[SCRIPT_NAME].java.
+
+  In fountain.rs, we have::
+
+    #pragma rs java_package_name(com.android.fountain)
+
+  In ScriptC_fountain.java, we have::
+
+    package com.android.fountain
+
+  Note that the ScriptC_fountain.java will be generated inside
+  ./com/android/fountain/.
+
+* #pragma version(1)
+
+  This pragma is for evolving the language. Currently we are at
+  version 1 of the language.
+
+
+2. Basic Reflection: Export Variables and Functions
+---------------------------------------------------
+
+llvm-rs-cc automatically exports the "externalizable and defined" functions and
+variables to Android's Java side. That is, scripts are accessible from
+Java.
+
+For instance, for::
+
+  int foo = 0;
+
+In ScriptC_fountain.java, llvm-rs-cc will reflect the following methods::
+
+  void set_foo(int v)...
+
+  int get_foo()...
+
+This access takes the form of generated classes which provide access
+to the functions and global variables within a script. In summary,
+global variables and functions within a script that are not declared
+static will generate get, set, or invoke methods.  This provides a way
+to set the data within a script and call its functions.
+
+Take the addParticles function in fountain.rs as an example::
+
+  void addParticles(int rate, float x, float y, int index, bool newColor) {
+    ...
+  }
+
+llvm-rs-cc will genearte ScriptC_fountain.java as follows::
+
+  void invoke_addParticles(int rate, float x, float y,
+                           int index, bool newColor) {
+    ...
+  }
+
+
+3. Export User-Defined Structs
+------------------------------
+
+In fountain.rs, we have::
+
+  typedef struct __attribute__((packed, aligned(4))) Point {
+    float2 delta;
+    float2 position;
+    uchar4 color;
+  } Point_t;
+
+  Point_t *point;
+
+llvm-rs-cc generates one ScriptField*.java file for each user-defined
+struct. In this case, llvm-rs-cc will reflect two files,
+ScriptC_fountain.java and ScriptField_Point.java.
+
+Note that when the type of an exportable variable is a structure, Renderscript
+developers should avoid using anonymous structs. This is because llvm-rs-cc
+uses the struct name to identify the file, instead of the typedef name.
+
+For the generated Java files, using ScriptC_fountain.java as an
+example we also have::
+
+  void bind_point(ScriptField_Point v)
+
+This binds your object with the allocated memory.
+
+You can bind the struct(e.g., Point), using the setter and getter
+methods in ScriptField_Point.java.
+
+After binding, you can access the object with this method::
+
+  ScriptField_Point get_point()
+
+In ScriptField_Point_s.java::
+
+    ...
+    // Copying the Item, which is the object that stores every
+    // fields of struct, to the *index*\-th entry of byte array.
+    //
+    // In general, this method would not be invoked directly
+    // but is used to implement the setter.
+    void copyToArray(Item i, int index)
+
+    // The setter of Item array,
+    // index: the index of the Item array
+    // copyNow: If true, it will be copied to the *index*\-th entry
+    // of byte array.
+    void set(Item i, int index, boolean copyNow)
+
+    // The getter of Item array, which gets the *index*-th element
+    // of byte array.
+    Item get(int index)
+
+    set_delta(int index, Float2 v, boolean copyNow)
+
+    // The following is the individual setters and getters of
+    // each field of a struct.
+    public void set_delta(int index, Float2 v, boolean copyNow)
+    public void set_position(int index, Float2 v, boolean copyNow)
+    public void set_color(int index, Short4 v, boolean copyNow)
+    public Float2 get_delta(int index)
+    public Float2 get_position(int index)
+    public Short4 get_color(int index)
+
+    // Copying all Item array to byte array (i.e., memory allocation).
+    void copyAll()
+    ...
+
+
+4. Summary of the Java Reflection above
+---------------------------------------
+
+This section summarizes the high-level design of Renderscript's reflection.
+
+* In terms of a script's global functions, they can be called from Java.
+  These calls operate asynchronously and no assumptions should be made
+  on whether a function called will have actually completed operation.  If it
+  is necessary to wait for a function to complete, the Java application
+  may call the runtime finish() method, which will wait for all the script
+  threads to complete pending operations.  A few special functions can also
+  exist:
+
+  * The function **init** (if present) will be called once after the script
+    is loaded.  This is useful to initialize data or anything else the
+    script may need before it can be used.  The init function may not depend
+    on globals initialized from Java as it will be called before these
+    can be initialized. The function signature for init must be::
+
+      void init(void);
+
+  * The function **root** is a special function for graphics.  This function
+    will be called when a script must redraw its contents.  No
+    assumptions should be made as to when this function will be
+    called.  It will only be called if the script is bound as a graphics root.
+    Calls to this function will be synchronized with data updates and
+    other invocations from Java.  Thus the script will not change due
+    to external influence in the middle of running **root**.  The return value
+    indicates to the runtime when the function should be called again to
+    redraw in the future.  A return value of 0 indicates that no
+    redraw is necessary until something changes on the Java side.  Any
+    positive integer indicates a time in milliseconds that the runtime should
+    wait before calling root again to render another frame.  The function
+    signature for a graphics root functions is as follows::
+
+      int root(void);
+
+  * It is also possible to create a purely compute-based **root** function.
+    Such a function has the following signature::
+
+      void root(const T1 *in, T2 *out, const T3 *usrData, uint32_t x, uint32_t y);
+
+    T1, T2, and T3 represent any supported Renderscript type.  Any parameters
+    above can be omitted, although at least one of in/out must be present.
+    If both in and out are present, root must only be invoked with types of
+    the same exact dimensionality (i.e. matching X and Y values for dimension).
+    This root function is accessible through the Renderscript language
+    construct **forEach**.  We also reflect a Java version to access this
+    function as **forEach_root** (for API levels of 14+).  An example of this
+    can be seen in the Android SDK sample for HelloCompute.
+
+  * The function **.rs.dtor** is a function that is sometimes generated by
+    llvm-rs-cc.  This function cleans up any global variable that contains
+    (or is) a reference counted Renderscript object type (such as an
+    rs_allocation, rs_font, or rs_script).  This function will be invoked
+    implicitly by the Renderscript runtime during script teardown.
+
+* In terms of a script's global data, global variables can be written
+  from Java.  The Java instance will cache the value or object set and
+  provide return methods to retrieve this value.  If a script updates
+  the value, this update will not propagate back to the Java class.
+  Initializers, if present, will also initialize the cached Java value.
+  This provides a convenient way to declare constants within a script and
+  make them accessible to the Java runtime.  If the script declares a
+  variable const, only the get methods will be generated.
+
+  Globals within a script are considered local to the script.  They
+  cannot be accessed by other scripts and are in effect always 'static'
+  in the traditional C sense.  Static here is used to control if
+  accessors are generated.  Static continues to mean *not
+  externally visible* and thus prevents the generation of
+  accessors.  Globals are persistent across invocations of a script and
+  thus may be used to hold data from run to run.
+
+  Globals of two types may be reflected into the Java class.  The first
+  type is basic non-pointer types.  Types defined in rs_types.rsh may also be
+  used.  For the non-pointer class, get and set methods are generated for
+  Java.  Globals of single pointer types behave differently.  These may
+  use more complex types.  Simple structures composed of the types in
+  rs_types.rsh may also be used.  These globals generate bind points in
+  Java.  If the type is a structure they also generate an appropriate
+  **Field** class that is used to pack and unpack the contents of the
+  structure.  Binding an allocation in Java effectively sets the
+  pointer in the script.  Bind points marked const indicate to the
+  runtime that the script will not modify the contents of an allocation.
+  This may allow the runtime to make more effective use of threads.
+
+
+5. Vector Types
+---------------
+
+Vector types such as float2, float4, and uint4 are included to support
+vector processing in environments where the processors provide vector
+instructions.
+
+On non-vector systems the same code will continue to run but without
+the performance advantage.  Function overloading is also supported.
+This allows the runtime to support vector version of the basic math
+routines without the need for special naming.  For instance,
+
+* *float sin(float);*
+
+* *float2 sin(float2);*
+
+* *float3 sin(float3);*
+
+* *float4 sin(float4);*
diff --git a/slang/RSCCOptions.td b/slang/RSCCOptions.td
new file mode 100644
index 0000000..2339cd7
--- /dev/null
+++ b/slang/RSCCOptions.td
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the options accepted by llvm-rs-cc.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the common option parsing interfaces.
+include "llvm/Option/OptParser.td"
+
+//===----------------------------------------------------------------------===//
+// Target Options
+//===----------------------------------------------------------------------===//
+
+def target_api : Separate<["-"], "target-api">,
+  HelpText<"Specify target API level (e.g. 14)">;
+def target_api_EQ : Joined<["-"], "target-api=">, Alias<target_api>;
+
+//===----------------------------------------------------------------------===//
+// Header Search Options
+//===----------------------------------------------------------------------===//
+
+def I : JoinedOrSeparate<["-"], "I">, MetaVarName<"<directory>">,
+  HelpText<"Add directory to include search path">;
+def _I : Separate<["-", "--"], "include-path">, MetaVarName<"<directory>">, Alias<I>;
+
+//===----------------------------------------------------------------------===//
+// Frontend Options
+//===----------------------------------------------------------------------===//
+
+def o : Separate<["-"], "o">, MetaVarName<"<directory>">,
+  HelpText<"Specify output directory">;
+
+def Output_Type_Group : OptionGroup<"<output type group>">;
+let Group = Output_Type_Group in {
+
+def emit_asm : Flag<["-"], "emit-asm">,
+  HelpText<"Emit target assembly files">;
+def _emit_asm : Flag<["-"], "S">, Alias<emit_asm>;
+def emit_llvm : Flag<["-"], "emit-llvm">,
+  HelpText<"Build ASTs then convert to LLVM, emit .ll file">;
+def emit_bc : Flag<["-"], "emit-bc">,
+  HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
+def emit_nothing : Flag<["-"], "emit-nothing">,
+  HelpText<"Build ASTs then convert to LLVM, but emit nothing">;
+}
+
+def m32 : Flag<["-"], "m32">, HelpText<"Emit 32-bit code (only for C++, unless eng build)">;
+def m64 : Flag<["-"], "m64">, HelpText<"Emit 64-bit code (only for C++, unless eng build)">;
+
+def emit_g : Flag<["-"], "g">,
+  HelpText<"Emit LLVM Debug Metadata">;
+
+def optimization_level : JoinedOrSeparate<["-"], "O">, MetaVarName<"<optimization-level>">,
+  HelpText<"<optimization-level> can be one of '0' or '3' (default)">;
+
+def allow_rs_prefix : Flag<["-"], "allow-rs-prefix">,
+  HelpText<"Allow user-defined function prefixed with 'rs'">;
+
+def java_reflection_path_base : Separate<["-"], "java-reflection-path-base">,
+  MetaVarName<"<directory>">,
+  HelpText<"Base directory for output reflected Java files">;
+def _java_reflection_path_base : Separate<["-"], "p">,
+  Alias<java_reflection_path_base>;
+def java_reflection_package_name : Separate<["-"], "java-reflection-package-name">,
+  HelpText<"Specify the package name that reflected Java files belong to">;
+def _java_reflection_package_name : Separate<["-"], "j">,
+  Alias<java_reflection_package_name>;
+
+def bitcode_storage : Separate<["-"], "bitcode-storage">,
+  MetaVarName<"<value>">, HelpText<"<value> should be 'ar' or 'jc'">;
+def _bitcode_storage : Separate<["-"], "s">, Alias<bitcode_storage>;
+
+def rs_package_name : Separate<["-"], "rs-package-name">,
+  MetaVarName<"<package_name>">,
+  HelpText<"package name for referencing RS classes">;
+def rs_package_name_EQ : Joined<["-"], "rs-package-name=">, Alias<rs_package_name>;
+
+def W : Joined<["-"], "W">, HelpText<"Enable the specified warning">;
+def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">;
+
+//===----------------------------------------------------------------------===//
+// Dependency Output Options
+//===----------------------------------------------------------------------===//
+
+def M_Group : OptionGroup<"M group>">;
+let Group = M_Group in {
+
+  def MD : Flag<["-"], "MD">, HelpText<"Emit .d dependency files">;
+  def MP : Flag<["-"], "MP">, HelpText<"Also emit phony target for dependency files">;
+
+  def M : Flag<["-"], "M">;
+  def emit_dep : Flag<["-"], "emit-dep">, Alias<M>;
+}
+
+def output_dep_dir : Separate<["-"], "output-dep-dir">, MetaVarName<"<directory>">,
+  HelpText<"Specify output directory for dependencies output">;
+def _output_dep_dir : Separate<["-"], "d">, Alias<output_dep_dir>;
+
+def additional_dep_target: Separate<["-"], "additional-dep-target">,
+  HelpText<"Additional targets to show up in dependencies output">;
+def _additional_dep_target : Separate<["-"], "a">, Alias<additional_dep_target>;
+
+//===----------------------------------------------------------------------===//
+// Reflection Options
+//===----------------------------------------------------------------------===//
+
+def reflect_cpp : Flag<["-"], "reflect-c++">,
+  HelpText<"Reflect C++ classes">;
+
+//===----------------------------------------------------------------------===//
+// Diagnostic Options
+//===----------------------------------------------------------------------===//
+
+def ast_print : Flag<["-"], "ast-print">,
+  HelpText<"Print clang AST prior to llvm IR generation">;
+
+def debug : Flag<["-"], "debug">,
+  HelpText<"Enable debug output">;
+
+def print_after_all : Flag<["-"], "print-after-all">,
+  HelpText<"Print llvm IR after each pass">;
+def print_before_all : Flag<["-"], "print-before-all">,
+  HelpText<"Print llvm IR before each pass">;
+
+//===----------------------------------------------------------------------===//
+// Misc Options
+//===----------------------------------------------------------------------===//
+
+def verbose : Flag<["-"], "v">,
+  HelpText<"Display verbose information during the compilation">;
+def _verbose : Flag<["-"], "verbose">, Alias<verbose>;
+def __verbose : Flag<["--"], "verbose">, Alias<verbose>;
+
+def help : Flag<["-"], "help">,
+  HelpText<"Print this help text">;
+def _help : Flag<["--"], "help">, Alias<help>;
+def __help : Flag<["-"], "h">, Alias<help>;
+
+def version : Flag<["-"], "version">,
+  HelpText<"Print the assembler version">;
+def _version : Flag<["--"], "version">, Alias<version>;
+
+// Compatible with old slang
+def no_link : Flag<["-"], "no-link">;  // currently no effect
diff --git a/slang/legacy_bitcode.h b/slang/legacy_bitcode.h
new file mode 100644
index 0000000..5d45a1b
--- /dev/null
+++ b/slang/legacy_bitcode.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#include "llvm/IR/Attributes.h"
+
+// Shared functionality for legacy function attribute encoding.
+static inline uint64_t encodeLLVMAttributesForBitcode(llvm::AttributeSet A,
+                                                      unsigned i) {
+  uint64_t EncodedAttrs = A.Raw(i) & 0xffff;
+  if (A.hasAttribute(i, llvm::Attribute::Alignment)) {
+    // The alignment is stored as an actual power of 2 value (instead of the
+    // compressed log2 form). It occupies bits 31-16 inclusive.
+    EncodedAttrs |= (A.getParamAlignment(i) << 16);
+  }
+  // There are only 12 remaining attributes (bits 21-32), hence our 0xfff mask.
+  EncodedAttrs |= (A.Raw(i) & (0xfffull << 21))  << 11;
+  return EncodedAttrs;
+}
+
diff --git a/slang/lit-tests/P_alloc_in_struct/alloc_in_struct.rs b/slang/lit-tests/P_alloc_in_struct/alloc_in_struct.rs
new file mode 100644
index 0000000..24742fb
--- /dev/null
+++ b/slang/lit-tests/P_alloc_in_struct/alloc_in_struct.rs
@@ -0,0 +1,11 @@
+// RUN: %Slang %s
+// RUN: %rs-filecheck-wrapper %s
+// CHECK: define void @.rs.dtor()
+
+#pragma version(1)
+#pragma rs java_package_name(alloc_in_struct)
+
+struct s {
+    rs_allocation a;
+} myStruct;
+
diff --git a/slang/lit-tests/P_array_init/array_init.rs b/slang/lit-tests/P_array_init/array_init.rs
new file mode 100644
index 0000000..f4465db
--- /dev/null
+++ b/slang/lit-tests/P_array_init/array_init.rs
@@ -0,0 +1,30 @@
+// RUN: %Slang %s
+// RUN: %rs-filecheck-wrapper %s
+// CHECK: @ic = constant i32 99, align 4
+// CHECK: @ica = global [2 x i32] [i32 99, i32 1000], align 4
+// CHECK: @fa = global [4 x float] [float 1.000000e+00, float 0x4023FFF2E0000000, float 0.000000e+00, float 0.000000e+00], align 4
+// CHECK: @da = global [2 x double] [double 7.000000e+00, double 8.888880e+00], align 8
+// CHECK: @ca = global [4 x i8] c"a\07bc", align 1
+// CHECK: @sa = global [4 x i16] [i16 1, i16 1, i16 2, i16 3], align 2
+// CHECK: @ia = global [4 x i32] [i32 5, i32 8, i32 0, i32 0], align 4
+// CHECK: @la = global [2 x i64] [i64 13, i64 21], align 8
+// CHECK: @lla = global [4 x i64] [i64 34, i64 0, i64 0, i64 0], align 8
+// CHECK: @ba = global [3 x i8] c"\01\00\00", align 1
+
+
+#pragma version(1)
+#pragma rs java_package_name(array_init)
+
+const int ic = 99;
+
+int ica[2] = {ic, 1000};
+
+float fa[4] = {1.0, 9.9999f};
+double da[2] = {7.0, 8.88888};
+char ca[4] = {'a', 7, 'b', 'c'};
+short sa[4] = {1, 1, 2, 3};
+int ia[4] = {5, 8};
+long la[2] = {13, 21};
+long long lla[4] = {34};
+bool ba[3] = {true, false};
+
diff --git a/slang/lit-tests/P_compute/compute.rs b/slang/lit-tests/P_compute/compute.rs
new file mode 100644
index 0000000..49405b8
--- /dev/null
+++ b/slang/lit-tests/P_compute/compute.rs
@@ -0,0 +1,18 @@
+// RUN: %Slang %s
+// RUN: %rs-filecheck-wrapper %s
+// CHECK: define void @root(
+// CHECK: define void @foo(
+// CHECK: define void @.helper_bar(
+
+#pragma version(1)
+#pragma rs java_package_name(compute)
+
+void root(const int *ain, int *aout, const void *usrData,
+          uint32_t x, uint32_t y) {
+}
+
+void bar(int i, float f) {
+}
+
+void foo (int *p) {
+}
diff --git a/slang/lit-tests/P_ref_count/ref_count.rs b/slang/lit-tests/P_ref_count/ref_count.rs
new file mode 100644
index 0000000..0f5d612
--- /dev/null
+++ b/slang/lit-tests/P_ref_count/ref_count.rs
@@ -0,0 +1,21 @@
+// RUN: %Slang %s
+// RUN: %rs-filecheck-wrapper %s
+// CHECK: call void @_Z13rsClearObjectP10rs_element(%struct.rs_element{{.*}}* nonnull %.rs.tmp{{[0-9]+}})
+// CHECK: call void @_Z11rsSetObjectP10rs_elementS_(%struct.rs_element{{.*}}* nonnull %.rs.retval{{[0-9]+}}, {{.*}})
+
+#pragma version(1)
+#pragma rs java_package_name(ref_count)
+
+static rs_element bar() {
+  rs_element x = {0};
+  return x;
+}
+
+void entrypoint() {
+  rs_element e = bar();
+  if (rsIsObject(e)) {
+    rsDebug("good object", 0);
+  }
+}
+
+
diff --git a/slang/lit-tests/README b/slang/lit-tests/README
new file mode 100644
index 0000000..78fea67
--- /dev/null
+++ b/slang/lit-tests/README
@@ -0,0 +1,42 @@
+
+Summary
+=======
+This directory contains tests for Slang that use the 'llvm-lit' testing tool.
+Each testcase is a separate .rs file, and comments inside the testcase are
+used to verify certain strings are present in the output bitcode files.
+
+Prerequisites
+=============
+To run the tests, you must have the android build environment variables
+set (i.e. source build/envsetup.sh; lunch). You must also have on your path:
+- Android version of llvm-lit (currently in libbcc/tests/debuginfo)
+- FileCheck (utility from llvm)
+- llvm-rs-cc (slang frontend compiler)
+
+If you are unable to run the tests, try using the "--debug" option to llvm-lit.
+
+When debugging failures, the "-v" option will print to stdout the details of
+the failure. Note that tests marked as "Expected Fail" (XFAIL) will not print
+failure information, even with -v.
+
+Customizing
+===========
+The tools lit and FileCheck are fairly flexible, and could be used to validate
+more than just emitted bitcode. For example, with some changes to the testcases
+and the helper shell-script rs-filecheck-wrapper.sh, it should be possible to
+write tests that verify the emitted Java code.
+
+Running
+=======
+To execute all the tests from this directory, use the Android llvm-lit tool
+from libbcc:
+$ ../../libbcc/tests/debuginfo/llvm-lit .
+
+The tool can be run from any directory.
+-j controls the number of parallel test executions
+-v enables additional verbosity (useful when examining unexpected failures)
+
+Adding new tests
+================
+To add new tests, just add .rs files to a test directory with similar
+RUN/CHECK directives in comments as the existing tests.
diff --git a/slang/lit-tests/bitcode_wrapper/bitcode_wrapper_test.ll b/slang/lit-tests/bitcode_wrapper/bitcode_wrapper_test.ll
new file mode 100644
index 0000000..77e32c0
--- /dev/null
+++ b/slang/lit-tests/bitcode_wrapper/bitcode_wrapper_test.ll
@@ -0,0 +1,51 @@
+; This test assembles this file to bitcode with all supported target
+; API versions, then checks that the bitcode file was generated and
+; has the right magic number.
+
+; RUN: %llvm-rs-as -target-api 11 %s -o %t11
+; RUN: xxd -ps -l 4 %t11 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 12 %s -o %t12
+; RUN: xxd -ps -l 4 %t12 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 13 %s -o %t13
+; RUN: xxd -ps -l 4 %t13 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 14 %s -o %t14
+; RUN: xxd -ps -l 4 %t14 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 15 %s -o %t15
+; RUN: xxd -ps -l 4 %t15 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 16 %s -o %t16
+; RUN: xxd -ps -l 4 %t16 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 17 %s -o %t17
+; RUN: xxd -ps -l 4 %t17 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 18 %s -o %t18
+; RUN: xxd -ps -l 4 %t18 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 19 %s -o %t19
+; RUN: xxd -ps -l 4 %t19 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 20 %s -o %t20
+; RUN: xxd -ps -l 4 %t20 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 21 %s -o %t21
+; RUN: xxd -ps -l 4 %t21 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 22 %s -o %t22
+; RUN: xxd -ps -l 4 %t22 | FileCheck %s
+; RUN: %llvm-rs-as -target-api 23 %s -o %t23
+; RUN: xxd -ps -l 4 %t23 | FileCheck %s
+
+; RUN: %llvm-rs-as -target-api 0 %s -o %t0
+; RUN: xxd -ps -l 4 %t0 | FileCheck %s
+
+; Check for the magic number.
+
+; CHECK: dec0170b
+
+; ModuleID = 'kernel.bc'
+target datalayout = "e-p:32:32-i64:64-v128:64:128-n32-S64"
+target triple = "armv7-none-linux-gnueabi"
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+!\23pragma = !{!3, !4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 4}
+!2 = !{!"clang version 3.6 "}
+!3 = !{!"version", !"1"}
+!4 = !{!"java_package_name", !"foo"}
diff --git a/slang/lit-tests/debug/debug_disabled.rs b/slang/lit-tests/debug/debug_disabled.rs
new file mode 100644
index 0000000..d3ddd57
--- /dev/null
+++ b/slang/lit-tests/debug/debug_disabled.rs
@@ -0,0 +1,10 @@
+// RUN: %Slang %s
+// RUN: %rs-filecheck-wrapper %s
+// CHECK-NOT: DILocation
+
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int *aout, const void *usrData,
+          uint32_t x, uint32_t y) {
+}
diff --git a/slang/lit-tests/debug/debug_enabled.rs b/slang/lit-tests/debug/debug_enabled.rs
new file mode 100644
index 0000000..7f2856a
--- /dev/null
+++ b/slang/lit-tests/debug/debug_enabled.rs
@@ -0,0 +1,10 @@
+// RUN: %Slang -g %s
+// RUN: %rs-filecheck-wrapper %s
+// CHECK: DILocation
+
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int *aout, const void *usrData,
+          uint32_t x, uint32_t y) {
+}
diff --git a/slang/lit-tests/lit.cfg b/slang/lit-tests/lit.cfg
new file mode 100644
index 0000000..7d14bc8
--- /dev/null
+++ b/slang/lit-tests/lit.cfg
@@ -0,0 +1,74 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'slang_lit_tests'
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.rs', '.ll']
+
+# testFormat: The test format to use to interpret tests.
+import lit.formats
+config.test_format = lit.formats.ShTest()
+
+# Get the base build directory for the android source tree from environment.
+config.base_path = os.getenv('ANDROID_BUILD_TOP')
+
+# test_source_root: The path where tests are located (default is the test suite
+# root).
+config.test_source_root = None
+
+# test_exec_root: The path where tests are located (default is the test suite
+# root).
+config.test_exec_root = os.path.join(config.base_path, 'out', 'tests', 'slang', 'lit-tests')
+
+# target_triple: Used by ShTest and TclTest formats for XFAIL checks.
+config.target_triple = 'slang'
+
+def inferTool(binary_name, env_var, PATH):
+    # Determine which tool to use.
+    tool = os.getenv(env_var)
+
+    # If the user set the overriding environment variable, use it
+    if tool and os.path.isfile(tool):
+        return tool
+
+    # Otherwise look in the path.
+    import lit.util
+    tool = lit.util.which(binary_name, PATH)
+
+    if not tool:
+        lit_config.fatal("couldn't find " + binary_name + " program in " + PATH + " , try setting "
+                         + env_var + " in your environment")
+
+    return os.path.abspath(tool)
+
+config.slang = inferTool('llvm-rs-cc', 'SLANG', os.path.join(os.getenv('ANDROID_HOST_OUT'), 'bin')).replace('\\', '/')
+config.llvm_rs_as = inferTool('llvm-rs-as', 'LLVM_RS_AS', os.path.join(os.getenv('ANDROID_HOST_OUT'), 'bin')).replace('\\', '/')
+
+config.filecheck = inferTool('FileCheck', 'FILECHECK', config.environment['PATH'])
+config.rs_filecheck_wrapper = inferTool('rs-filecheck-wrapper.sh', 'RS_FILECHECK_WRAPPER', os.path.join(config.base_path, 'frameworks', 'compile', 'slang', 'lit-tests'))
+config.scriptc_filecheck_wrapper = inferTool('scriptc-filecheck-wrapper.sh', 'SCRIPTC_FILECHECK_WRAPPER', os.path.join(config.base_path, 'frameworks', 'compile', 'slang', 'lit-tests'))
+
+# Use most up-to-date headers for includes.
+config.slang_includes = "-I " + os.path.join(config.base_path, 'frameworks', 'rs', 'scriptc') + " " \
+                      + "-I " + os.path.join(config.base_path, 'external', 'clang', 'lib', 'Headers')
+
+config.slang_options = "-emit-llvm -o " + config.test_exec_root \
+                     + " -output-dep-dir " + config.test_exec_root \
+                     + " -java-reflection-path-base " + config.test_exec_root
+
+if not lit_config.quiet:
+    lit_config.note('using slang: %r' % config.slang)
+    lit_config.note('using llvm-rs-as: %r' % config.llvm_rs_as)
+    lit_config.note('using FileCheck: %r' % config.filecheck)
+    lit_config.note('using rs-filecheck-wrapper.sh: %r' % config.rs_filecheck_wrapper)
+    lit_config.note('using output directory: %r' % config.test_exec_root)
+
+# Tools configuration substitutions
+config.substitutions.append( ('%Slang', ' ' + config.slang + ' ' + config.slang_includes + ' ' + config.slang_options ) )
+config.substitutions.append( ('%llvm-rs-as', config.llvm_rs_as) )
+config.substitutions.append( ('%rs-filecheck-wrapper', ' ' + config.rs_filecheck_wrapper + ' ' + config.test_exec_root + ' ' + config.filecheck + ' ') )
+config.substitutions.append( ('%scriptc-filecheck-wrapper', ' ' + config.scriptc_filecheck_wrapper + ' --output=' + config.test_exec_root + ' --filecheck=' + config.filecheck + ' ') )
+lit_config.note(config.substitutions)
diff --git a/slang/lit-tests/opt/locals_opt_0.rs b/slang/lit-tests/opt/locals_opt_0.rs
new file mode 100644
index 0000000..1c1f7de
--- /dev/null
+++ b/slang/lit-tests/opt/locals_opt_0.rs
@@ -0,0 +1,45 @@
+// RUN: %Slang -O 0 %s
+// RUN: %rs-filecheck-wrapper %s
+// CHECK: define internal i32 @main(
+// CHECK: %f = alloca float,
+// CHECK: %pf = alloca float*,
+// CHECK: %ppn = alloca i32**,
+
+struct float_struct {
+  float f;
+  float f2[2];
+} compound_float;
+
+static
+int main(int argc, char* argv[])
+{
+  float f = 0.f;
+  float *pf = &f;
+
+  double d[2][2] = {{0, 1}, {2, 3.0}};
+  struct float_struct s;
+
+  unsigned short us = -1;
+  const unsigned long l = (unsigned long) -1.0e8f;
+
+  {
+    int** ppn = 0;
+    if (ppn) {
+      return -1;
+    }
+  }
+
+  s.f = 10e-4f;
+  s.f2[0] = 1e4f;
+  s.f2[1] = 100.5f;
+
+  double result = pf[0] * d[1][1] * s.f * us * l;
+  return (result == 0 ? 0 : -1);
+}
+
+void the_main() {
+  main(0, 0);
+}
+
+#pragma version(1)
+#pragma rs java_package_name(foo)
diff --git a/slang/lit-tests/opt/locals_opt_3.rs b/slang/lit-tests/opt/locals_opt_3.rs
new file mode 100644
index 0000000..e90a538
--- /dev/null
+++ b/slang/lit-tests/opt/locals_opt_3.rs
@@ -0,0 +1,45 @@
+// RUN: %Slang -O 3 %s
+// RUN: %rs-filecheck-wrapper %s
+// CHECK-NOT: define internal i32 @main(
+// CHECK-NOT: %f = alloca float,
+// CHECK-NOT: %pf = alloca float*,
+// CHECK-NOT: %ppn = alloca i32**,
+
+struct float_struct {
+  float f;
+  float f2[2];
+} compound_float;
+
+static
+int main(int argc, char* argv[])
+{
+  float f = 0.f;
+  float *pf = &f;
+
+  double d[2][2] = {{0, 1}, {2, 3.0}};
+  struct float_struct s;
+
+  unsigned short us = -1;
+  const unsigned long l = (unsigned long) -1.0e8f;
+
+  {
+    int** ppn = 0;
+    if (ppn) {
+      return -1;
+    }
+  }
+
+  s.f = 10e-4f;
+  s.f2[0] = 1e4f;
+  s.f2[1] = 100.5f;
+
+  double result = pf[0] * d[1][1] * s.f * us * l;
+  return (result == 0 ? 0 : -1);
+}
+
+void the_main() {
+  main(0, 0);
+}
+
+#pragma version(1)
+#pragma rs java_package_name(foo)
diff --git a/slang/lit-tests/opt/locals_opt_default.rs b/slang/lit-tests/opt/locals_opt_default.rs
new file mode 100644
index 0000000..f491956
--- /dev/null
+++ b/slang/lit-tests/opt/locals_opt_default.rs
@@ -0,0 +1,48 @@
+// RUN: %Slang %s
+// RUN: %rs-filecheck-wrapper %s
+// CHECK-NOT: define internal i32 @main(
+// CHECK-NOT: %f = alloca float,
+// CHECK-NOT: %pf = alloca float*,
+// CHECK-NOT: %ppn = alloca i32**,
+
+// This test case should behave identically to locals_opt_3.rs.
+
+struct float_struct {
+  float f;
+  float f2[2];
+} compound_float;
+
+
+static
+int main(int argc, char* argv[])
+{
+  float f = 0.f;
+  float *pf = &f;
+
+  double d[2][2] = {{0, 1}, {2, 3.0}};
+  struct float_struct s;
+
+  unsigned short us = -1;
+  const unsigned long l = (unsigned long) -1.0e8f;
+
+  {
+    int** ppn = 0;
+    if (ppn) {
+      return -1;
+    }
+  }
+
+  s.f = 10e-4f;
+  s.f2[0] = 1e4f;
+  s.f2[1] = 100.5f;
+
+  double result = pf[0] * d[1][1] * s.f * us * l;
+  return (result == 0 ? 0 : -1);
+}
+
+void the_main() {
+  main(0, 0);
+}
+
+#pragma version(1)
+#pragma rs java_package_name(foo)
diff --git a/slang/lit-tests/rs-filecheck-wrapper.sh b/slang/lit-tests/rs-filecheck-wrapper.sh
new file mode 100755
index 0000000..8f6d718
--- /dev/null
+++ b/slang/lit-tests/rs-filecheck-wrapper.sh
@@ -0,0 +1,14 @@
+#!/bin/bash -e
+
+# RS Invocation script to FileCheck
+# Usage: rs-filecheck-wrapper.sh <output-directory> <path-to-FileCheck> <source>
+
+OUTDIR=$1
+FILECHECK=$2
+SOURCEFILE=$3
+
+FILECHECK_INPUTFILE=`basename $SOURCEFILE | sed 's/\.rs\$/.ll/'`
+
+# This runs FileCheck on both the 32 bit and the 64 bit bitcode files.
+$FILECHECK -input-file $OUTDIR/bc32/$FILECHECK_INPUTFILE $SOURCEFILE
+$FILECHECK -input-file $OUTDIR/bc64/$FILECHECK_INPUTFILE $SOURCEFILE
diff --git a/slang/lit-tests/run-lit-tests.sh b/slang/lit-tests/run-lit-tests.sh
new file mode 100755
index 0000000..28a9696
--- /dev/null
+++ b/slang/lit-tests/run-lit-tests.sh
@@ -0,0 +1,6 @@
+#!/bin/bash -e
+
+LIT_PATH=$ANDROID_BUILD_TOP/frameworks/compile/libbcc/tests/debuginfo/llvm-lit
+TESTS=$ANDROID_BUILD_TOP/frameworks/compile/slang/lit-tests
+
+$LIT_PATH $TESTS $@
diff --git a/slang/lit-tests/scriptc-filecheck-wrapper.sh b/slang/lit-tests/scriptc-filecheck-wrapper.sh
new file mode 100755
index 0000000..7e16872
--- /dev/null
+++ b/slang/lit-tests/scriptc-filecheck-wrapper.sh
@@ -0,0 +1,76 @@
+#!/bin/bash -e
+
+# RS Invocation script to FileCheck, used to check generated Java
+# files or C++ files. This assumes that the .rs source file has the
+# Java package name "foo".
+
+print_help() {
+  help_str="Usage: %s --output=<output-dir> \
+--filecheck=<path-to-filecheck> \
+--lang=[Java/C++] \
+<.rs file>\n"
+
+  printf "$help_str" $0
+}
+
+for arg in "$@"
+do
+  case $arg in
+  --output=*)
+    outdir="${arg#*=}"
+    ;;
+  --filecheck*)
+    filecheck="${arg#*=}"
+    ;;
+  --lang*)
+    lang="${arg#*=}"
+    ;;
+  --help)
+    print_help
+    exit 0
+    ;;
+  *)
+    rsfile="$arg"
+    ;;
+  esac
+done
+
+if [[ (-z $outdir) || (-z $filecheck) || (-z $rsfile) ]]
+then
+  print_help
+  exit 1
+fi
+
+if [[ ! -f $rsfile ]]
+then
+  echo "Input file $rsfile doesn't exist"
+  exit 1
+fi
+
+rsfile_basename=$(basename "$rsfile")
+
+if [[ $lang == "Java" ]]
+then
+  filecheck_inputfile=foo/ScriptC_${rsfile_basename%.*}.java
+elif [[ $lang == "C++" ]]
+then
+  filecheck_inputfile=ScriptC_${rsfile_basename%.*}.h
+else
+  echo Unknown language "$lang"
+  print_help
+  exit 1
+fi
+
+if [[ ! -f $filecheck ]]
+then
+  echo "No file at supplied FileCheck path $filecheck"
+  exit 1
+fi
+
+if [[ ! -f $outdir/$filecheck_inputfile ]]
+then
+  echo "Input file $outdir/$filecheck_inputfile doesn't exist"
+  exit 1
+fi
+
+"$filecheck" -input-file "$outdir"/$filecheck_inputfile "$rsfile"
diff --git a/slang/llvm-rs-as.cpp b/slang/llvm-rs-as.cpp
new file mode 100644
index 0000000..5f3a901
--- /dev/null
+++ b/slang/llvm-rs-as.cpp
@@ -0,0 +1,149 @@
+//===--- llvm-as.cpp - The low-level LLVM assembler -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This utility may be invoked in the following manner:
+//   llvm-as --help         - Output information about command line switches
+//   llvm-as [options]      - Read LLVM asm from stdin, write bitcode to stdout
+//   llvm-as [options] x.ll - Read LLVM asm from the x.ll file, write bitcode
+//                            to the x.bc file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/Support/ToolOutputFile.h"
+
+#include "slang_bitcode_gen.h"
+#include "slang_version.h"
+
+#include <memory>
+using namespace llvm;
+
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input .llvm file>"), cl::init("-"));
+
+static cl::opt<std::string>
+OutputFilename("o", cl::desc("Override output filename"),
+               cl::value_desc("filename"));
+
+static cl::opt<bool>
+Force("f", cl::desc("Enable binary output on terminals"));
+
+static cl::opt<bool>
+DisableOutput("disable-output", cl::desc("Disable output"), cl::init(false));
+
+static cl::opt<uint32_t>
+TargetAPI("target-api", cl::desc("Specify RenderScript target API version "
+                                 "(0 = development API) (default is 0)"),
+          cl::init(0));
+
+static cl::opt<bool>
+DumpAsm("d", cl::desc("Print assembly as parsed"), cl::Hidden);
+
+static cl::opt<bool>
+DisableVerify("disable-verify", cl::Hidden,
+              cl::desc("Do not run verifier on input LLVM (dangerous!)"));
+
+
+static void WriteOutputFile(const Module *M, uint32_t ModuleTargetAPI) {
+  // Infer the output filename if needed.
+  if (OutputFilename.empty()) {
+    if (InputFilename == "-") {
+      OutputFilename = "-";
+    } else {
+      std::string IFN = InputFilename;
+      int Len = IFN.length();
+      if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') {
+        // Source ends in .ll
+        OutputFilename = std::string(IFN.begin(), IFN.end()-3);
+      } else {
+        OutputFilename = IFN;   // Append a .bc to it
+      }
+      OutputFilename += ".bc";
+    }
+  }
+
+  std::error_code EC;
+  std::unique_ptr<tool_output_file> Out
+  (new tool_output_file(OutputFilename.c_str(), EC, llvm::sys::fs::F_None));
+  if (EC) {
+    // TODO(srhines): This isn't actually very specific and needs cleanup.
+    errs() << EC.message() << '\n';
+    exit(1);
+  }
+
+  if (Force || !CheckBitcodeOutputToConsole(Out->os(), true)) {
+    slang::writeBitcode(Out->os(), *M,
+        /* TargetAPI = */ ModuleTargetAPI,
+        /* OptimizationLevel = */ 3,
+        /* GenerateDebugInfo = */ false);
+
+    if (!Out->os().has_error()) {
+      // Declare success.
+      Out->keep();
+    }
+  }
+}
+
+int main(int argc, char **argv) {
+  // Print a stack trace if we signal out.
+  sys::PrintStackTraceOnErrorSignal();
+  PrettyStackTraceProgram X(argc, argv);
+  LLVMContext &Context = getGlobalContext();
+  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
+  cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n");
+
+  // Check target API.
+  uint32_t ActualTargetAPI = (TargetAPI == 0) ? RS_DEVELOPMENT_API : TargetAPI;
+
+  if (ActualTargetAPI != RS_DEVELOPMENT_API &&
+      (ActualTargetAPI < SLANG_MINIMUM_TARGET_API ||
+       ActualTargetAPI > SLANG_MAXIMUM_TARGET_API)) {
+    errs() << "target API level '" << ActualTargetAPI << "' is out of range "
+           << "('" << SLANG_MINIMUM_TARGET_API << "' - '"
+           << SLANG_MAXIMUM_TARGET_API << "')\n";
+    return 1;
+  }
+
+  // Parse the file now...
+  SMDiagnostic Err;
+  std::unique_ptr<Module> M(parseAssemblyFile(InputFilename, Err, Context));
+  if (M.get() == 0) {
+    Err.print(argv[0], errs());
+    return 1;
+  }
+
+  if (!DisableVerify) {
+    std::string Err;
+    raw_string_ostream stream(Err);
+    if (verifyModule(*M.get(), &stream)) {
+      errs() << argv[0]
+             << ": assembly parsed, but does not verify as correct!\n";
+      errs() << Err;
+      return 1;
+    }
+  }
+
+  if (DumpAsm) errs() << "Here's the assembly:\n" << *M.get();
+
+  if (!DisableOutput)
+    WriteOutputFile(M.get(), ActualTargetAPI);
+
+  return 0;
+}
diff --git a/slang/llvm-rs-cc.cpp b/slang/llvm-rs-cc.cpp
new file mode 100644
index 0000000..5da6315
--- /dev/null
+++ b/slang/llvm-rs-cc.cpp
@@ -0,0 +1,302 @@
+/*
+ * 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.
+ */
+
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Frontend/Utils.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+
+#include "llvm/Option/OptTable.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/StringSaver.h"
+#include "llvm/Target/TargetMachine.h"
+
+#include "os_sep.h"
+#include "rs_cc_options.h"
+#include "slang.h"
+#include "slang_assert.h"
+#include "slang_diagnostic_buffer.h"
+#include "slang_rs_reflect_utils.h"
+
+#include <list>
+#include <set>
+#include <string>
+
+namespace {
+class StringSet {
+public:
+  const char *save(const char *Str) {
+    return Strings.save(Str);
+  }
+
+  StringSet() : Strings(A), A() {}
+
+  llvm::StringSaver & getStringSaver() { return Strings; }
+
+private:
+  llvm::StringSaver Strings;
+  llvm::BumpPtrAllocator A;
+};
+}
+
+static const char *DetermineOutputFile(const std::string &OutputDir,
+                                       const std::string &PathSuffix,
+                                       const char *InputFile,
+                                       slang::Slang::OutputType OutputType,
+                                       StringSet *SavedStrings) {
+  if (OutputType == slang::Slang::OT_Nothing)
+    return "/dev/null";
+
+  std::string OutputFile(OutputDir);
+
+  // Append '/' to Opts.mBitcodeOutputDir if not presents
+  if (!OutputFile.empty() &&
+      (OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR)
+    OutputFile.append(1, OS_PATH_SEPARATOR);
+
+  if (!PathSuffix.empty()) {
+    OutputFile.append(PathSuffix);
+    OutputFile.append(1, OS_PATH_SEPARATOR);
+  }
+
+  if (OutputType == slang::Slang::OT_Dependency) {
+    // The build system wants the .d file name stem to be exactly the same as
+    // the source .rs file, instead of the .bc file.
+    OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile));
+  } else {
+    OutputFile.append(
+        slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile));
+  }
+
+  switch (OutputType) {
+    case slang::Slang::OT_Dependency: {
+      OutputFile.append(".d");
+      break;
+    }
+    case slang::Slang::OT_Assembly: {
+      OutputFile.append(".S");
+      break;
+    }
+    case slang::Slang::OT_LLVMAssembly: {
+      OutputFile.append(".ll");
+      break;
+    }
+    case slang::Slang::OT_Object: {
+      OutputFile.append(".o");
+      break;
+    }
+    case slang::Slang::OT_Bitcode: {
+      OutputFile.append(".bc");
+      break;
+    }
+    case slang::Slang::OT_Nothing:
+    default: {
+      slangAssert(false && "Invalid output type!");
+    }
+  }
+
+  return SavedStrings->save(OutputFile.c_str());
+}
+
+typedef std::list<std::pair<const char*, const char*> > NamePairList;
+
+/*
+ * Compile the Inputs.
+ *
+ * Returns 0 on success and nonzero on failure.
+ *
+ * IOFiles - list of (foo.rs, foo.bc) pairs of input/output files.
+ * IOFiles32 - list of input/output pairs for 32-bit compilation.
+ * Inputs - input filenames.
+ * Opts - options controlling compilation.
+ * DiagEngine - Clang diagnostic engine (for creating diagnostics).
+ * DiagClient - Slang diagnostic consumer (collects and displays diagnostics).
+ * SavedStrings - expanded strings copied from argv source input files.
+ *
+ * We populate IOFiles dynamically while working through the list of Inputs.
+ * On any 64-bit compilation, we pass back in the 32-bit pairs of files as
+ * IOFiles32. This allows the 64-bit compiler to later bundle up both the
+ * 32-bit and 64-bit bitcode outputs to be included in the final reflected
+ * source code that is emitted.
+ */
+static void makeFileList(NamePairList *IOFiles, NamePairList *DepFiles,
+    const llvm::SmallVector<const char*, 16> &Inputs, slang::RSCCOptions &Opts,
+    StringSet *SavedStrings) {
+  std::string PathSuffix = "";
+  // In our mixed 32/64-bit path, we need to suffix our files differently for
+  // both 32-bit and 64-bit versions.
+  if (Opts.mEmit3264) {
+    if (Opts.mBitWidth == 64) {
+      PathSuffix = "bc64";
+    } else {
+      PathSuffix = "bc32";
+    }
+  }
+
+  for (int i = 0, e = Inputs.size(); i != e; i++) {
+    const char *InputFile = Inputs[i];
+
+    const char *BCOutputFile = DetermineOutputFile(Opts.mBitcodeOutputDir,
+                                                   PathSuffix, InputFile,
+                                                   Opts.mOutputType,
+                                                   SavedStrings);
+    const char *OutputFile = BCOutputFile;
+
+    if (Opts.mEmitDependency) {
+      // The dependency file is always emitted without a PathSuffix.
+      // Collisions between 32-bit and 64-bit files don't make a difference,
+      // because they share the same sources/dependencies.
+      const char *DepOutputFile =
+          DetermineOutputFile(Opts.mDependencyOutputDir, "", InputFile,
+                              slang::Slang::OT_Dependency, SavedStrings);
+      if (Opts.mOutputType == slang::Slang::OT_Dependency) {
+        OutputFile = DepOutputFile;
+      }
+
+      DepFiles->push_back(std::make_pair(BCOutputFile, DepOutputFile));
+    }
+
+    IOFiles->push_back(std::make_pair(InputFile, OutputFile));
+  }
+}
+
+#define str(s) #s
+#define wrap_str(s) str(s)
+static void llvm_rs_cc_VersionPrinter() {
+  llvm::raw_ostream &OS = llvm::outs();
+  OS << "llvm-rs-cc: Renderscript compiler\n"
+     << "  (http://developer.android.com/guide/topics/renderscript)\n"
+     << "  based on LLVM (http://llvm.org):\n";
+  OS << "  Target APIs: " << SLANG_MINIMUM_TARGET_API << " - "
+     << SLANG_MAXIMUM_TARGET_API;
+  OS << "\n  Build type: " << wrap_str(TARGET_BUILD_VARIANT);
+#ifndef __DISABLE_ASSERTS
+  OS << " with assertions";
+#endif
+  OS << ".\n";
+}
+#undef wrap_str
+#undef str
+
+static void LLVMErrorHandler(void *UserData, const std::string &Message,
+                             bool GenCrashDialog) {
+  clang::DiagnosticsEngine *DiagEngine =
+      static_cast<clang::DiagnosticsEngine *>(UserData);
+
+  DiagEngine->Report(clang::diag::err_fe_error_backend) << Message;
+
+  // Run the interrupt handlers to make sure any special cleanups get done, in
+  // particular that we remove files registered with RemoveFileOnSignal.
+  llvm::sys::RunInterruptHandlers();
+
+  exit(1);
+}
+
+int main(int argc, const char **argv) {
+  llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+  LLVMInitializeARMTargetInfo();
+  LLVMInitializeARMTarget();
+  LLVMInitializeARMAsmPrinter();
+
+  StringSet SavedStrings; // Keeps track of strings to be destroyed at the end.
+
+  // Parse the command line arguments and respond to show help & version
+  // commands.
+  llvm::SmallVector<const char *, 16> Inputs;
+  slang::RSCCOptions Opts;
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts =
+      new clang::DiagnosticOptions();
+  if (!slang::ParseArguments(llvm::makeArrayRef(argv, argc), Inputs, Opts,
+                             *DiagOpts, SavedStrings.getStringSaver())) {
+    // Exits when there's any error occurred during parsing the arguments
+    return 1;
+  }
+  if (Opts.mShowHelp) {
+    std::unique_ptr<llvm::opt::OptTable> OptTbl(slang::createRSCCOptTable());
+    const std::string Argv0 = llvm::sys::path::stem(argv[0]);
+    OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(),
+                      "Renderscript source compiler");
+    return 0;
+  }
+  if (Opts.mShowVersion) {
+    llvm_rs_cc_VersionPrinter();
+    return 0;
+  }
+
+  // Initialize the diagnostic objects
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
+      new clang::DiagnosticIDs());
+  slang::DiagnosticBuffer DiagsBuffer;
+  clang::DiagnosticsEngine DiagEngine(DiagIDs, &*DiagOpts, &DiagsBuffer, false);
+  clang::ProcessWarningOptions(DiagEngine, *DiagOpts);
+  (void)DiagEngine.setSeverityForGroup(clang::diag::Flavor::WarningOrError,
+                                       "implicit-function-declaration",
+                                       clang::diag::Severity::Error);
+
+  // Report error if no input file
+  if (Inputs.empty()) {
+    DiagEngine.Report(clang::diag::err_drv_no_input_files);
+    llvm::errs() << DiagsBuffer.str();
+    return 1;
+  }
+
+  llvm::install_fatal_error_handler(LLVMErrorHandler, &DiagEngine);
+
+  // Compile the 32 bit version
+  NamePairList IOFiles32;
+  NamePairList DepFiles32;
+  makeFileList(&IOFiles32, &DepFiles32, Inputs, Opts, &SavedStrings);
+
+  int CompileFailed = 0;
+  // Handle 32-bit case for Java and C++ reflection.
+  // For Java, both 32bit and 64bit will be generated.
+  // For C++, either 64bit or 32bit will be generated based on the target.
+  if (Opts.mEmit3264 || Opts.mBitWidth == 32) {
+      std::unique_ptr<slang::Slang> Compiler(
+          new slang::Slang(32, &DiagEngine, &DiagsBuffer));
+      CompileFailed =
+          !Compiler->compile(IOFiles32, IOFiles32, DepFiles32, Opts, *DiagOpts);
+  }
+
+  // Handle the 64-bit case too!
+  bool needEmit64 = Opts.mEmit3264 || Opts.mBitWidth == 64;
+  if (needEmit64 && !CompileFailed) {
+    Opts.mBitWidth = 64;
+    NamePairList IOFiles64;
+    NamePairList DepFiles64;
+    makeFileList(&IOFiles64, &DepFiles64, Inputs, Opts, &SavedStrings);
+
+    std::unique_ptr<slang::Slang> Compiler(
+        new slang::Slang(64, &DiagEngine, &DiagsBuffer));
+    CompileFailed =
+        !Compiler->compile(IOFiles64, IOFiles32, DepFiles64, Opts, *DiagOpts);
+  }
+
+  llvm::errs() << DiagsBuffer.str();
+  llvm::remove_fatal_error_handler();
+  return CompileFailed;
+}
diff --git a/slang/os_sep.h b/slang/os_sep.h
new file mode 100644
index 0000000..832e8fe
--- /dev/null
+++ b/slang/os_sep.h
@@ -0,0 +1,33 @@
+/*
+ * 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 _FRAMEWORKS_COMPILE_SLANG_OS_SEP_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_OS_SEP_H_
+
+#ifdef USE_MINGW
+/* Define the default path separator for the platform. */
+#define OS_PATH_SEPARATOR     '\\'
+#define OS_PATH_SEPARATOR_STR "\\"
+
+#else /* not USE_MINGW */
+
+/* Define the default path separator for the platform. */
+#define OS_PATH_SEPARATOR     '/'
+#define OS_PATH_SEPARATOR_STR "/"
+
+#endif
+
+#endif  // _FRAMEWORKS_COMPILE_SLANG_NO_SEP_H_  NOLINT
diff --git a/slang/rs_cc_options.cpp b/slang/rs_cc_options.cpp
new file mode 100644
index 0000000..8c8ae58
--- /dev/null
+++ b/slang/rs_cc_options.cpp
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2014, 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 "clang/Basic/DiagnosticOptions.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Frontend/Utils.h"
+
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Support/CommandLine.h"
+
+#include "rs_cc_options.h"
+#include "slang.h"
+#include "slang_assert.h"
+
+#include <cstdlib>
+#include <string>
+#include <utility>
+#include <vector>
+
+enum {
+  OPT_INVALID = 0,  // This is not an option ID.
+#define PREFIX(NAME, VALUE)
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+               HELPTEXT, METAVAR)                                             \
+  OPT_##ID,
+#include "RSCCOptions.inc"
+  LastOption
+#undef OPTION
+#undef PREFIX
+};
+
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+               HELPTEXT, METAVAR)
+#include "RSCCOptions.inc"
+#undef OPTION
+#undef PREFIX
+
+static const llvm::opt::OptTable::Info RSCCInfoTable[] = {
+#define PREFIX(NAME, VALUE)
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
+               HELPTEXT, METAVAR)                                              \
+  {                                                                            \
+    PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
+        PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS                      \
+  }                                                                            \
+  ,
+#include "RSCCOptions.inc"
+#undef OPTION
+#undef PREFIX
+};
+
+namespace {
+
+class RSCCOptTable : public llvm::opt::OptTable {
+ public:
+  RSCCOptTable()
+      : OptTable(llvm::makeArrayRef(RSCCInfoTable)) {}
+};
+}
+
+namespace slang {
+
+llvm::opt::OptTable *createRSCCOptTable() { return new RSCCOptTable(); }
+
+// This function is similar to
+// clang/lib/Frontend/CompilerInvocation::CreateFromArgs.
+bool ParseArguments(const llvm::ArrayRef<const char *> &ArgsIn,
+                    llvm::SmallVectorImpl<const char *> &Inputs,
+                    RSCCOptions &Opts, clang::DiagnosticOptions &DiagOpts,
+                    llvm::StringSaver &StringSaver) {
+  // We use a different diagnostic engine for argument parsing from the rest of
+  // the work.  This mimics what's done in clang.  I believe it is so the
+  // argument parsing errors are well formatted while the full errors can be
+  // influenced by command line arguments.
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> ArgumentParseDiagOpts(
+      new clang::DiagnosticOptions());
+  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
+      new clang::DiagnosticIDs());
+  DiagnosticBuffer DiagsBuffer;
+  clang::DiagnosticsEngine DiagEngine(DiagIDs, &*ArgumentParseDiagOpts,
+                                      &DiagsBuffer, false);
+
+  // Populate a vector with the command line arguments, expanding command files
+  // that have been included via the '@' argument.
+  llvm::SmallVector<const char *, 256> ArgVector;
+  // Skip over the command name, or we will mistakenly process it as a source file.
+  ArgVector.append(ArgsIn.slice(1).begin(), ArgsIn.end());
+  llvm::cl::ExpandResponseFiles(StringSaver, llvm::cl::TokenizeGNUCommandLine,
+                                ArgVector, false);
+
+  std::unique_ptr<llvm::opt::OptTable> OptParser(createRSCCOptTable());
+  unsigned MissingArgIndex = 0;
+  unsigned MissingArgCount = 0;
+  llvm::opt::InputArgList Args =
+      OptParser->ParseArgs(ArgVector, MissingArgIndex, MissingArgCount);
+
+  // Check for missing argument error.
+  if (MissingArgCount) {
+    DiagEngine.Report(clang::diag::err_drv_missing_argument)
+        << Args.getArgString(MissingArgIndex) << MissingArgCount;
+  }
+
+  // Issue errors on unknown arguments.
+  for (llvm::opt::arg_iterator it = Args.filtered_begin(OPT_UNKNOWN),
+                               ie = Args.filtered_end();
+       it != ie; ++it) {
+    DiagEngine.Report(clang::diag::err_drv_unknown_argument)
+        << (*it)->getAsString(Args);
+  }
+
+  DiagOpts.IgnoreWarnings = Args.hasArg(OPT_w);
+  DiagOpts.Warnings = Args.getAllArgValues(OPT_W);
+
+  // Always turn off warnings for empty initializers, since we really want to
+  // employ/encourage this extension for zero-initialization of structures.
+  DiagOpts.Warnings.push_back("no-gnu-empty-initializer");
+
+  for (llvm::opt::ArgList::const_iterator it = Args.begin(), ie = Args.end();
+       it != ie; ++it) {
+    const llvm::opt::Arg *A = *it;
+    if (A->getOption().getKind() == llvm::opt::Option::InputClass)
+      Inputs.push_back(A->getValue());
+  }
+
+  Opts.mIncludePaths = Args.getAllArgValues(OPT_I);
+
+  Opts.mBitcodeOutputDir = Args.getLastArgValue(OPT_o);
+
+  if (const llvm::opt::Arg *A = Args.getLastArg(OPT_M_Group)) {
+    switch (A->getOption().getID()) {
+    case OPT_M: {
+      Opts.mEmitDependency = true;
+      Opts.mOutputType = Slang::OT_Dependency;
+      break;
+    }
+    case OPT_MD: {
+      Opts.mEmitDependency = true;
+      Opts.mOutputType = Slang::OT_Bitcode;
+      break;
+    }
+    case OPT_MP: {
+      Opts.mEmitDependency = true;
+      Opts.mOutputType = Slang::OT_Bitcode;
+      Opts.mEmitPhonyDependency = true;
+      break;
+    }
+    default: { slangAssert(false && "Invalid option in M group!"); }
+    }
+  }
+
+  if (const llvm::opt::Arg *A = Args.getLastArg(OPT_Output_Type_Group)) {
+    switch (A->getOption().getID()) {
+    case OPT_emit_asm: {
+      Opts.mOutputType = Slang::OT_Assembly;
+      break;
+    }
+    case OPT_emit_llvm: {
+      Opts.mOutputType = Slang::OT_LLVMAssembly;
+      break;
+    }
+    case OPT_emit_bc: {
+      Opts.mOutputType = Slang::OT_Bitcode;
+      break;
+    }
+    case OPT_emit_nothing: {
+      Opts.mOutputType = Slang::OT_Nothing;
+      break;
+    }
+    default: { slangAssert(false && "Invalid option in output type group!"); }
+    }
+  }
+
+  if (Opts.mEmitDependency && ((Opts.mOutputType != Slang::OT_Bitcode) &&
+                               (Opts.mOutputType != Slang::OT_Dependency)))
+    DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with)
+        << Args.getLastArg(OPT_M_Group)->getAsString(Args)
+        << Args.getLastArg(OPT_Output_Type_Group)->getAsString(Args);
+
+  Opts.mAllowRSPrefix = Args.hasArg(OPT_allow_rs_prefix);
+
+  Opts.mJavaReflectionPathBase =
+      Args.getLastArgValue(OPT_java_reflection_path_base);
+  Opts.mJavaReflectionPackageName =
+      Args.getLastArgValue(OPT_java_reflection_package_name);
+
+  Opts.mRSPackageName = Args.getLastArgValue(OPT_rs_package_name);
+
+  llvm::StringRef BitcodeStorageValue =
+      Args.getLastArgValue(OPT_bitcode_storage);
+  if (BitcodeStorageValue == "ar")
+    Opts.mBitcodeStorage = BCST_APK_RESOURCE;
+  else if (BitcodeStorageValue == "jc")
+    Opts.mBitcodeStorage = BCST_JAVA_CODE;
+  else if (!BitcodeStorageValue.empty())
+    DiagEngine.Report(clang::diag::err_drv_invalid_value)
+        << OptParser->getOptionName(OPT_bitcode_storage) << BitcodeStorageValue;
+
+  llvm::opt::Arg *lastBitwidthArg = Args.getLastArg(OPT_m32, OPT_m64);
+  if (Args.hasArg(OPT_reflect_cpp)) {
+    Opts.mBitcodeStorage = BCST_CPP_CODE;
+    // mJavaReflectionPathBase can be set for C++ reflected builds.
+    // Set it to the standard mBitcodeOutputDir (via -o) by default.
+    if (Opts.mJavaReflectionPathBase.empty()) {
+      Opts.mJavaReflectionPathBase = Opts.mBitcodeOutputDir;
+    }
+
+    // Check for bitwidth arguments.
+    if (lastBitwidthArg) {
+      if (lastBitwidthArg->getOption().matches(OPT_m32)) {
+        Opts.mBitWidth = 32;
+      } else {
+        Opts.mBitWidth = 64;
+      }
+    }
+  } else if (lastBitwidthArg) {
+      // -m32/-m64 are forbidden for non-C++ reflection paths for non-eng builds
+      // (they would make it too easy for a developer to accidentally create and
+      // release an APK that has 32-bit or 64-bit bitcode but not both).
+#ifdef __ENABLE_INTERNAL_OPTIONS
+      if (lastBitwidthArg->getOption().matches(OPT_m32)) {
+        Opts.mBitWidth = 32;
+      } else {
+        Opts.mBitWidth = 64;
+      }
+      Opts.mEmit3264 = false;
+#else
+      DiagEngine.Report(
+          DiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
+                                     "cannot use -m32/-m64 without specifying "
+                                     "C++ reflection (-reflect-c++)"));
+#endif
+  }
+
+  Opts.mDependencyOutputDir =
+      Args.getLastArgValue(OPT_output_dep_dir, Opts.mBitcodeOutputDir);
+  Opts.mAdditionalDepTargets = Args.getAllArgValues(OPT_additional_dep_target);
+
+  Opts.mShowHelp = Args.hasArg(OPT_help);
+  Opts.mShowVersion = Args.hasArg(OPT_version);
+  Opts.mDebugEmission = Args.hasArg(OPT_emit_g);
+  Opts.mVerbose = Args.hasArg(OPT_verbose);
+  Opts.mASTPrint = Args.hasArg(OPT_ast_print);
+
+  // Delegate options
+
+  std::vector<std::string> DelegatedStrings;
+  for (int Opt : std::vector<unsigned>{OPT_debug, OPT_print_after_all, OPT_print_before_all}) {
+    if (Args.hasArg(Opt)) {
+      // TODO: Don't assume that the option begins with "-"; determine this programmatically instead.
+      DelegatedStrings.push_back(std::string("-") + std::string(OptParser->getOptionName(Opt)));
+      slangAssert(OptParser->getOptionKind(Opt) == llvm::opt::Option::FlagClass);
+    }
+  }
+  if (DelegatedStrings.size()) {
+    std::vector<const char *> DelegatedCStrs;
+    DelegatedCStrs.push_back(*ArgVector.data()); // program name
+    std::for_each(DelegatedStrings.cbegin(), DelegatedStrings.cend(),
+                  [&DelegatedCStrs](const std::string &String) { DelegatedCStrs.push_back(String.c_str()); });
+    llvm::cl::ParseCommandLineOptions(DelegatedCStrs.size(), DelegatedCStrs.data());
+  }
+
+  // If we are emitting both 32-bit and 64-bit bitcode, we must embed it.
+
+  size_t OptLevel =
+      clang::getLastArgIntValue(Args, OPT_optimization_level, 3, DiagEngine);
+
+  Opts.mOptimizationLevel =
+      OptLevel == 0 ? llvm::CodeGenOpt::None : llvm::CodeGenOpt::Aggressive;
+
+  Opts.mTargetAPI =
+      clang::getLastArgIntValue(Args, OPT_target_api, RS_VERSION, DiagEngine);
+
+  if (Opts.mTargetAPI == 0) {
+    Opts.mTargetAPI = UINT_MAX;
+  }
+
+  if ((Opts.mTargetAPI < 21) || (Opts.mBitcodeStorage == BCST_CPP_CODE))
+    Opts.mEmit3264 = false;
+  if (Opts.mEmit3264)
+    Opts.mBitcodeStorage = BCST_JAVA_CODE;
+
+  if (DiagEngine.hasErrorOccurred()) {
+    llvm::errs() << DiagsBuffer.str();
+    return false;
+  }
+
+  return true;
+}
+}
diff --git a/slang/rs_cc_options.h b/slang/rs_cc_options.h
new file mode 100644
index 0000000..cc60560
--- /dev/null
+++ b/slang/rs_cc_options.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2014, 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_SLANG_RS_CC_OPTIONS_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_RS_CC_OPTIONS_H_
+
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Option/OptTable.h"
+
+#include "slang.h"
+#include "slang_rs_reflect_utils.h"
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace cl {
+class StringSaver;
+}
+namespace opt {
+class OptTable;
+}
+}
+
+namespace slang {
+
+// Options for the RenderScript compiler llvm-rs-cc
+class RSCCOptions {
+ public:
+  // User-defined include paths.
+  std::vector<std::string> mIncludePaths;
+
+  // The output directory for writing the bitcode files
+  // (i.e. out/target/common/obj/APPS/.../src/renderscript/res/raw).
+  std::string mBitcodeOutputDir;
+
+  // Type of file to emit (bitcode, dependency, ...).
+  slang::Slang::OutputType mOutputType;
+
+  // Allow user-defined functions prefixed with 'rs'.
+  bool mAllowRSPrefix;
+
+  // 32-bit or 64-bit target
+  uint32_t mBitWidth;
+
+  // The path for storing reflected Java source files
+  // (i.e. out/target/common/obj/APPS/.../src/renderscript/src).
+  std::string mJavaReflectionPathBase;
+
+  // Force package name. This may override the package name specified by a
+  // #pragma in the .rs file.
+  std::string mJavaReflectionPackageName;
+
+  // Force the RS package name to use. This can override the default value of
+  // "android.renderscript" used for the standard RS APIs.
+  std::string mRSPackageName;
+
+  // Where to store the generated bitcode (resource, Java source, C++ source).
+  slang::BitCodeStorageType mBitcodeStorage;
+
+  // Emit output dependency file for each input file.
+  bool mEmitDependency;
+
+  // Emit phony targets for each header dependency, which can avoid make errors
+  // when the header gets deleted. See -MP option of cc.
+  bool mEmitPhonyDependency;
+
+  // The output directory for writing dependency files
+  // (i.e. out/target/common/obj/APPS/.../src/renderscript).
+  std::string mDependencyOutputDir;
+
+  // User-defined files added to the dependencies (i.e. for adding fake
+  // dependency files like RenderScript.stamp).
+  std::vector<std::string> mAdditionalDepTargets;
+
+  bool mShowHelp;     // Show the -help text.
+  bool mShowVersion;  // Show the -version text.
+
+  // The target API we are generating code for (see slang_version.h).
+  unsigned int mTargetAPI;
+
+  // Enable emission of debugging symbols.
+  bool mDebugEmission;
+
+  // The optimization level used in CodeGen, and encoded in emitted bitcode.
+  llvm::CodeGenOpt::Level mOptimizationLevel;
+
+  // Display verbose information about the compilation on stdout.
+  bool mVerbose;
+
+  // Display AST.
+  bool mASTPrint;
+
+  // Emit both 32-bit and 64-bit bitcode (embedded in the reflected sources).
+  bool mEmit3264;
+
+  RSCCOptions() {
+    mOutputType = slang::Slang::OT_Bitcode;
+    mBitWidth = 32;
+    mBitcodeStorage = slang::BCST_APK_RESOURCE;
+    mEmitDependency = 0;
+    mEmitPhonyDependency = 0;
+    mShowHelp = 0;
+    mShowVersion = 0;
+    mTargetAPI = RS_VERSION;
+    mDebugEmission = 0;
+    mOptimizationLevel = llvm::CodeGenOpt::Aggressive;
+    mVerbose = false;
+    mASTPrint = false;
+    mEmit3264 = true;
+  }
+};
+
+/* Return a valid OptTable (useful for dumping help information)
+ */
+llvm::opt::OptTable *createRSCCOptTable();
+
+/* Parse ArgVector and return a list of Inputs (source files) and Opts
+ * (options affecting the compilation of those source files).
+ *
+ * \param ArgVector - the input arguments to llvm-rs-cc
+ * \param Inputs - returned list of actual input source filenames
+ * \param Opts - returned options after command line has been processed
+ * \param DiagEngine - input for issuing warnings/errors on arguments
+ */
+
+bool ParseArguments(const llvm::ArrayRef<const char *> &ArgsIn,
+                    llvm::SmallVectorImpl<const char *> &Inputs,
+                    RSCCOptions &Opts, clang::DiagnosticOptions &DiagOpts,
+                    llvm::StringSaver &StringSaver);
+
+} // namespace slang
+
+#endif  // _FRAMEWORKS_COMPILE_SLANG_RS_CC_OPTIONS_H_
diff --git a/slang/rs_version.mk b/slang/rs_version.mk
new file mode 100644
index 0000000..63b8822
--- /dev/null
+++ b/slang/rs_version.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2014 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.
+#
+
+RS_VERSION := 24
+RS_VERSION_DEFINE := -DRS_VERSION=$(RS_VERSION)
+
+# Use RS_VERSION_DEFINE as part of your LOCAL_CFLAGS to have the proper value.
+# LOCAL_CFLAGS += $(RS_VERSION_DEFINE)
+
diff --git a/slang/slang.cpp b/slang/slang.cpp
new file mode 100644
index 0000000..164fd3d
--- /dev/null
+++ b/slang/slang.cpp
@@ -0,0 +1,789 @@
+/*
+ * Copyright 2010, 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 "slang.h"
+
+#include <stdlib.h>
+
+#include <cstring>
+#include <list>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+
+#include "clang/Frontend/DependencyOutputOptions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/PCHContainerOperations.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Frontend/Utils.h"
+
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PreprocessorOptions.h"
+
+#include "clang/Parse/ParseAST.h"
+
+#include "clang/Sema/SemaDiagnostic.h"
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+
+#include "llvm/Bitcode/ReaderWriter.h"
+
+// More force linking
+#include "llvm/Linker/Linker.h"
+
+// Force linking all passes/vmcore stuffs to libslang.so
+#include "llvm/LinkAllIR.h"
+#include "llvm/LinkAllPasses.h"
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ToolOutputFile.h"
+
+#include "os_sep.h"
+#include "rs_cc_options.h"
+#include "slang_assert.h"
+#include "slang_backend.h"
+
+#include "slang_rs_context.h"
+#include "slang_rs_export_type.h"
+
+#include "slang_rs_reflection.h"
+#include "slang_rs_reflection_cpp.h"
+
+
+namespace {
+
+static const char *kRSTriple32 = "armv7-none-linux-gnueabi";
+static const char *kRSTriple64 = "aarch64-none-linux-gnueabi";
+
+}  // namespace
+
+namespace slang {
+
+
+#define FS_SUFFIX  "fs"
+
+#define RS_HEADER_SUFFIX  "rsh"
+
+/* RS_HEADER_ENTRY(name) */
+#define ENUM_RS_HEADER()  \
+  RS_HEADER_ENTRY(rs_allocation_create) \
+  RS_HEADER_ENTRY(rs_allocation_data) \
+  RS_HEADER_ENTRY(rs_atomic) \
+  RS_HEADER_ENTRY(rs_convert) \
+  RS_HEADER_ENTRY(rs_core) \
+  RS_HEADER_ENTRY(rs_debug) \
+  RS_HEADER_ENTRY(rs_for_each) \
+  RS_HEADER_ENTRY(rs_graphics) \
+  RS_HEADER_ENTRY(rs_graphics_types) \
+  RS_HEADER_ENTRY(rs_io) \
+  RS_HEADER_ENTRY(rs_math) \
+  RS_HEADER_ENTRY(rs_matrix) \
+  RS_HEADER_ENTRY(rs_object_info) \
+  RS_HEADER_ENTRY(rs_object_types) \
+  RS_HEADER_ENTRY(rs_quaternion) \
+  RS_HEADER_ENTRY(rs_time) \
+  RS_HEADER_ENTRY(rs_value_types) \
+  RS_HEADER_ENTRY(rs_vector_math) \
+
+
+// The named of metadata node that pragma resides (should be synced with
+// bcc.cpp)
+const llvm::StringRef Slang::PragmaMetadataName = "#pragma";
+
+static inline llvm::tool_output_file *
+OpenOutputFile(const char *OutputFile,
+               llvm::sys::fs::OpenFlags Flags,
+               std::error_code &EC,
+               clang::DiagnosticsEngine *DiagEngine) {
+  slangAssert((OutputFile != nullptr) &&
+              (DiagEngine != nullptr) && "Invalid parameter!");
+
+  EC = llvm::sys::fs::create_directories(
+      llvm::sys::path::parent_path(OutputFile));
+  if (!EC) {
+    llvm::tool_output_file *F =
+          new llvm::tool_output_file(OutputFile, EC, Flags);
+    if (F != nullptr)
+      return F;
+  }
+
+  // Report error here.
+  DiagEngine->Report(clang::diag::err_fe_error_opening)
+    << OutputFile << EC.message();
+
+  return nullptr;
+}
+
+void Slang::createTarget(uint32_t BitWidth) {
+  std::vector<std::string> features;
+
+  if (BitWidth == 64) {
+    mTargetOpts->Triple = kRSTriple64;
+  } else {
+    mTargetOpts->Triple = kRSTriple32;
+    // Treat long as a 64-bit type for our 32-bit RS code.
+    features.push_back("+long64");
+    mTargetOpts->FeaturesAsWritten = features;
+  }
+
+  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagEngine,
+                                                    mTargetOpts));
+}
+
+void Slang::createFileManager() {
+  mFileSysOpt.reset(new clang::FileSystemOptions());
+  mFileMgr.reset(new clang::FileManager(*mFileSysOpt));
+}
+
+void Slang::createSourceManager() {
+  mSourceMgr.reset(new clang::SourceManager(*mDiagEngine, *mFileMgr));
+}
+
+void Slang::createPreprocessor() {
+  // Default only search header file in current dir
+  clang::HeaderSearch *HeaderInfo = new clang::HeaderSearch(&getHeaderSearchOpts(),
+                                                            *mSourceMgr,
+                                                            *mDiagEngine,
+                                                            LangOpts,
+                                                            mTarget.get());
+
+  mPP.reset(new clang::Preprocessor(&getPreprocessorOpts(),
+                                    *mDiagEngine,
+                                    LangOpts,
+                                    *mSourceMgr,
+                                    *HeaderInfo,
+                                    *this,
+                                    nullptr,
+                                    /* OwnsHeaderSearch = */true));
+  // Initialize the preprocessor
+  mPP->Initialize(getTargetInfo());
+  clang::FrontendOptions FEOpts;
+
+  auto *Reader = mPCHContainerOperations->getReaderOrNull(
+      getHeaderSearchOpts().ModuleFormat);
+  clang::InitializePreprocessor(*mPP, getPreprocessorOpts(), *Reader, FEOpts);
+
+  clang::ApplyHeaderSearchOptions(*HeaderInfo, getHeaderSearchOpts(), LangOpts,
+      mPP->getTargetInfo().getTriple());
+
+  mPragmas.clear();
+
+  std::vector<clang::DirectoryLookup> SearchList;
+  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
+    if (const clang::DirectoryEntry *DE =
+            mFileMgr->getDirectory(mIncludePaths[i])) {
+      SearchList.push_back(clang::DirectoryLookup(DE,
+                                                  clang::SrcMgr::C_System,
+                                                  false));
+    }
+  }
+
+  HeaderInfo->SetSearchPaths(SearchList,
+                             /* angledDirIdx = */1,
+                             /* systemDixIdx = */1,
+                             /* noCurDirSearch = */false);
+
+  initPreprocessor();
+}
+
+void Slang::createASTContext() {
+  mASTContext.reset(
+      new clang::ASTContext(LangOpts, *mSourceMgr, mPP->getIdentifierTable(),
+                            mPP->getSelectorTable(), mPP->getBuiltinInfo()));
+  mASTContext->InitBuiltinTypes(getTargetInfo());
+  initASTContext();
+}
+
+clang::ASTConsumer *
+Slang::createBackend(const RSCCOptions &Opts, const clang::CodeGenOptions &CodeGenOpts,
+                     llvm::raw_ostream *OS, OutputType OT) {
+  auto *B = new Backend(mRSContext, &getDiagnostics(), Opts,
+                        getHeaderSearchOpts(), getPreprocessorOpts(),
+                        CodeGenOpts, getTargetOptions(), &mPragmas, OS, OT,
+                        getSourceManager(), mAllowRSPrefix, mIsFilterscript);
+  B->Initialize(getASTContext());
+  return B;
+}
+
+Slang::Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine,
+             DiagnosticBuffer *DiagClient)
+    : mDiagEngine(DiagEngine), mDiagClient(DiagClient),
+      mTargetOpts(new clang::TargetOptions()),
+      mHSOpts(new clang::HeaderSearchOptions()),
+      mPPOpts(new clang::PreprocessorOptions()),
+      mPCHContainerOperations(std::make_shared<clang::PCHContainerOperations>()),
+      mOT(OT_Default), mRSContext(nullptr), mAllowRSPrefix(false), mTargetAPI(0),
+      mVerbose(false), mIsFilterscript(false) {
+  // Please refer to include/clang/Basic/LangOptions.h to setup
+  // the options.
+  LangOpts.RTTI = 0;  // Turn off the RTTI information support
+  LangOpts.LineComment = 1;
+  LangOpts.C99 = 1;
+  LangOpts.Renderscript = 1;
+  LangOpts.LaxVectorConversions = 0;  // Do not bitcast vectors!
+  LangOpts.CharIsSigned = 1;  // Signed char is our default.
+
+  CodeGenOpts.OptimizationLevel = 3;
+
+  // We must set StackRealignment, because the default is for the actual
+  // Clang driver to pass this option (-mstackrealign) directly to cc1.
+  // Since we don't use Clang's driver, we need to similarly supply it.
+  // If StackRealignment is zero (i.e. the option wasn't set), then the
+  // backend assumes that it can't adjust the stack in any way, which breaks
+  // alignment for vector loads/stores.
+  CodeGenOpts.StackRealignment = 1;
+
+  createTarget(BitWidth);
+  createFileManager();
+  createSourceManager();
+}
+
+Slang::~Slang() {
+  delete mRSContext;
+  for (ReflectedDefinitionListTy::iterator I = ReflectedDefinitions.begin(),
+                                           E = ReflectedDefinitions.end();
+       I != E; I++) {
+    delete I->getValue().first;
+  }
+}
+
+clang::ModuleLoadResult Slang::loadModule(
+    clang::SourceLocation ImportLoc,
+    clang::ModuleIdPath Path,
+    clang::Module::NameVisibilityKind Visibility,
+    bool IsInclusionDirective) {
+  slangAssert(0 && "Not implemented");
+  return clang::ModuleLoadResult();
+}
+
+bool Slang::setInputSource(llvm::StringRef InputFile) {
+  mInputFileName = InputFile.str();
+
+  mSourceMgr->clearIDTables();
+
+  const clang::FileEntry *File = mFileMgr->getFile(InputFile);
+  if (File) {
+    mSourceMgr->setMainFileID(mSourceMgr->createFileID(File,
+        clang::SourceLocation(), clang::SrcMgr::C_User));
+  }
+
+  if (mSourceMgr->getMainFileID().isInvalid()) {
+    mDiagEngine->Report(clang::diag::err_fe_error_reading) << InputFile;
+    return false;
+  }
+
+  return true;
+}
+
+bool Slang::setOutput(const char *OutputFile) {
+  std::error_code EC;
+  llvm::tool_output_file *OS = nullptr;
+
+  switch (mOT) {
+    case OT_Dependency:
+    case OT_Assembly:
+    case OT_LLVMAssembly: {
+      OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine);
+      break;
+    }
+    case OT_Nothing: {
+      break;
+    }
+    case OT_Object:
+    case OT_Bitcode: {
+      OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_None, EC, mDiagEngine);
+      break;
+    }
+    default: {
+      llvm_unreachable("Unknown compiler output type");
+    }
+  }
+
+  if (EC)
+    return false;
+
+  mOS.reset(OS);
+
+  mOutputFileName = OutputFile;
+
+  return true;
+}
+
+bool Slang::setDepOutput(const char *OutputFile) {
+  std::error_code EC;
+
+  mDOS.reset(
+      OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine));
+  if (EC || (mDOS.get() == nullptr))
+    return false;
+
+  mDepOutputFileName = OutputFile;
+
+  return true;
+}
+
+int Slang::generateDepFile(bool PhonyTarget) {
+  if (mDiagEngine->hasErrorOccurred())
+    return 1;
+  if (mDOS.get() == nullptr)
+    return 1;
+
+  // Initialize options for generating dependency file
+  clang::DependencyOutputOptions DepOpts;
+  DepOpts.IncludeSystemHeaders = 1;
+  if (PhonyTarget)
+    DepOpts.UsePhonyTargets = 1;
+  DepOpts.OutputFile = mDepOutputFileName;
+  DepOpts.Targets = mAdditionalDepTargets;
+  DepOpts.Targets.push_back(mDepTargetBCFileName);
+  for (std::vector<std::string>::const_iterator
+           I = mGeneratedFileNames.begin(), E = mGeneratedFileNames.end();
+       I != E;
+       I++) {
+    DepOpts.Targets.push_back(*I);
+  }
+  mGeneratedFileNames.clear();
+
+  // Per-compilation needed initialization
+  createPreprocessor();
+  clang::DependencyFileGenerator::CreateAndAttachToPreprocessor(*mPP.get(), DepOpts);
+
+  // Inform the diagnostic client we are processing a source file
+  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
+
+  // Go through the source file (no operations necessary)
+  clang::Token Tok;
+  mPP->EnterMainSourceFile();
+  do {
+    mPP->Lex(Tok);
+  } while (Tok.isNot(clang::tok::eof));
+
+  mPP->EndSourceFile();
+
+  // Declare success if no error
+  if (!mDiagEngine->hasErrorOccurred())
+    mDOS->keep();
+
+  // Clean up after compilation
+  mPP.reset();
+  mDOS.reset();
+
+  return mDiagEngine->hasErrorOccurred() ? 1 : 0;
+}
+
+int Slang::compile(const RSCCOptions &Opts) {
+  if (mDiagEngine->hasErrorOccurred())
+    return 1;
+  if (mOS.get() == nullptr)
+    return 1;
+
+  // Here is per-compilation needed initialization
+  createPreprocessor();
+  createASTContext();
+
+  mBackend.reset(createBackend(Opts, CodeGenOpts, &mOS->os(), mOT));
+
+  // Inform the diagnostic client we are processing a source file
+  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
+
+  // The core of the slang compiler
+  ParseAST(*mPP, mBackend.get(), *mASTContext);
+
+  // Inform the diagnostic client we are done with previous source file
+  mDiagClient->EndSourceFile();
+
+  // Declare success if no error
+  if (!mDiagEngine->hasErrorOccurred())
+    mOS->keep();
+
+  // The compilation ended, clear
+  mBackend.reset();
+  mOS.reset();
+
+  return mDiagEngine->hasErrorOccurred() ? 1 : 0;
+}
+
+void Slang::setDebugMetadataEmission(bool EmitDebug) {
+  if (EmitDebug)
+    CodeGenOpts.setDebugInfo(clang::CodeGenOptions::FullDebugInfo);
+  else
+    CodeGenOpts.setDebugInfo(clang::CodeGenOptions::NoDebugInfo);
+}
+
+void Slang::setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel) {
+  CodeGenOpts.OptimizationLevel = OptimizationLevel;
+}
+
+bool Slang::isFilterscript(const char *Filename) {
+  const char *c = strrchr(Filename, '.');
+  if (c && !strncmp(FS_SUFFIX, c + 1, strlen(FS_SUFFIX) + 1)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool Slang::generateJavaBitcodeAccessor(const std::string &OutputPathBase,
+                                          const std::string &PackageName,
+                                          const std::string *LicenseNote) {
+  RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
+
+  BCAccessorContext.rsFileName = getInputFileName().c_str();
+  BCAccessorContext.bc32FileName = mOutput32FileName.c_str();
+  BCAccessorContext.bc64FileName = mOutputFileName.c_str();
+  BCAccessorContext.reflectPath = OutputPathBase.c_str();
+  BCAccessorContext.packageName = PackageName.c_str();
+  BCAccessorContext.licenseNote = LicenseNote;
+  BCAccessorContext.bcStorage = BCST_JAVA_CODE;   // Must be BCST_JAVA_CODE
+  BCAccessorContext.verbose = false;
+
+  return RSSlangReflectUtils::GenerateJavaBitCodeAccessor(BCAccessorContext);
+}
+
+bool Slang::checkODR(const char *CurInputFile) {
+  for (RSContext::ExportableList::iterator I = mRSContext->exportable_begin(),
+          E = mRSContext->exportable_end();
+       I != E;
+       I++) {
+    RSExportable *RSE = *I;
+    if (RSE->getKind() != RSExportable::EX_TYPE)
+      continue;
+
+    RSExportType *ET = static_cast<RSExportType *>(RSE);
+    if (ET->getClass() != RSExportType::ExportClassRecord)
+      continue;
+
+    RSExportRecordType *ERT = static_cast<RSExportRecordType *>(ET);
+
+    // Artificial record types (create by us not by user in the source) always
+    // conforms the ODR.
+    if (ERT->isArtificial())
+      continue;
+
+    // Key to lookup ERT in ReflectedDefinitions
+    llvm::StringRef RDKey(ERT->getName());
+    ReflectedDefinitionListTy::const_iterator RD =
+        ReflectedDefinitions.find(RDKey);
+
+    if (RD != ReflectedDefinitions.end()) {
+      const RSExportRecordType *Reflected = RD->getValue().first;
+      // There's a record (struct) with the same name reflected before. Enforce
+      // ODR checking - the Reflected must hold *exactly* the same "definition"
+      // as the one defined previously. We say two record types A and B have the
+      // same definition iff:
+      //
+      //  struct A {              struct B {
+      //    Type(a1) a1,            Type(b1) b1,
+      //    Type(a2) a2,            Type(b1) b2,
+      //    ...                     ...
+      //    Type(aN) aN             Type(b3) b3,
+      //  };                      }
+      //  Cond. #1. They have same number of fields, i.e., N = M;
+      //  Cond. #2. for (i := 1 to N)
+      //              Type(ai) = Type(bi) must hold;
+      //  Cond. #3. for (i := 1 to N)
+      //              Name(ai) = Name(bi) must hold;
+      //
+      // where,
+      //  Type(F) = the type of field F and
+      //  Name(F) = the field name.
+
+      bool PassODR = false;
+      // Cond. #1 and Cond. #2
+      if (Reflected->equals(ERT)) {
+        // Cond #3.
+        RSExportRecordType::const_field_iterator AI = Reflected->fields_begin(),
+                                                 BI = ERT->fields_begin();
+
+        for (unsigned i = 0, e = Reflected->getFields().size(); i != e; i++) {
+          if ((*AI)->getName() != (*BI)->getName())
+            break;
+          AI++;
+          BI++;
+        }
+        PassODR = (AI == (Reflected->fields_end()));
+      }
+
+      if (!PassODR) {
+        unsigned DiagID = mDiagEngine->getCustomDiagID(
+            clang::DiagnosticsEngine::Error,
+            "type '%0' in different translation unit (%1 v.s. %2) "
+            "has incompatible type definition");
+        getDiagnostics().Report(DiagID) << Reflected->getName()
+                                        << getInputFileName()
+                                        << RD->getValue().second;
+        return false;
+      }
+    } else {
+      llvm::StringMapEntry<ReflectedDefinitionTy> *ME =
+          llvm::StringMapEntry<ReflectedDefinitionTy>::Create(RDKey);
+      ME->setValue(std::make_pair(ERT, CurInputFile));
+
+      if (!ReflectedDefinitions.insert(ME)) {
+        slangAssert(false && "Type shouldn't be in map yet!");
+      }
+
+      // Take the ownership of ERT such that it won't be freed in ~RSContext().
+      ERT->keep();
+    }
+  }
+  return true;
+}
+
+void Slang::initPreprocessor() {
+  clang::Preprocessor &PP = getPreprocessor();
+
+  std::stringstream RSH;
+  RSH << PP.getPredefines();
+  RSH << "#define RS_VERSION " << mTargetAPI << "\n";
+  RSH << "#include \"rs_core." RS_HEADER_SUFFIX "\"\n";
+  PP.setPredefines(RSH.str());
+}
+
+void Slang::initASTContext() {
+  mRSContext = new RSContext(getPreprocessor(),
+                             getASTContext(),
+                             getTargetInfo(),
+                             &mPragmas,
+                             mTargetAPI,
+                             mVerbose);
+}
+
+bool Slang::IsRSHeaderFile(const char *File) {
+#define RS_HEADER_ENTRY(name)  \
+  if (::strcmp(File, #name "." RS_HEADER_SUFFIX) == 0)  \
+    return true;
+ENUM_RS_HEADER()
+#undef RS_HEADER_ENTRY
+  return false;
+}
+
+bool Slang::IsLocInRSHeaderFile(const clang::SourceLocation &Loc,
+                                  const clang::SourceManager &SourceMgr) {
+  clang::FullSourceLoc FSL(Loc, SourceMgr);
+  clang::PresumedLoc PLoc = SourceMgr.getPresumedLoc(FSL);
+
+  const char *Filename = PLoc.getFilename();
+  if (!Filename) {
+    return false;
+  } else {
+    return IsRSHeaderFile(llvm::sys::path::filename(Filename).data());
+  }
+}
+
+bool Slang::compile(
+    const std::list<std::pair<const char*, const char*> > &IOFiles64,
+    const std::list<std::pair<const char*, const char*> > &IOFiles32,
+    const std::list<std::pair<const char*, const char*> > &DepFiles,
+    const RSCCOptions &Opts,
+    clang::DiagnosticOptions &DiagOpts) {
+  if (IOFiles32.empty())
+    return true;
+
+  if (Opts.mEmitDependency && (DepFiles.size() != IOFiles32.size())) {
+    unsigned DiagID = mDiagEngine->getCustomDiagID(
+        clang::DiagnosticsEngine::Error,
+        "invalid parameter for output dependencies files.");
+    getDiagnostics().Report(DiagID);
+    return false;
+  }
+
+  if (Opts.mEmit3264 && (IOFiles64.size() != IOFiles32.size())) {
+    slangAssert(false && "Should have equal number of 32/64-bit files");
+    return false;
+  }
+
+  std::string RealPackageName;
+
+  const char *InputFile, *Output64File, *Output32File, *BCOutputFile,
+             *DepOutputFile;
+
+  setIncludePaths(Opts.mIncludePaths);
+  setOutputType(Opts.mOutputType);
+  if (Opts.mEmitDependency) {
+    setAdditionalDepTargets(Opts.mAdditionalDepTargets);
+  }
+
+  setDebugMetadataEmission(Opts.mDebugEmission);
+
+  setOptimizationLevel(Opts.mOptimizationLevel);
+
+  mAllowRSPrefix = Opts.mAllowRSPrefix;
+
+  mTargetAPI = Opts.mTargetAPI;
+  if (mTargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
+      (mTargetAPI < SLANG_MINIMUM_TARGET_API ||
+       mTargetAPI > SLANG_MAXIMUM_TARGET_API)) {
+    unsigned DiagID = mDiagEngine->getCustomDiagID(
+        clang::DiagnosticsEngine::Error,
+        "target API level '%0' is out of range ('%1' - '%2')");
+    getDiagnostics().Report(DiagID) << mTargetAPI << SLANG_MINIMUM_TARGET_API
+                                    << SLANG_MAXIMUM_TARGET_API;
+    return false;
+  }
+
+  if (mTargetAPI >= SLANG_M_TARGET_API) {
+    LangOpts.NativeHalfArgsAndReturns = 1;
+    LangOpts.NativeHalfType = 1;
+    LangOpts.HalfArgsAndReturns = 1;
+  }
+
+  mVerbose = Opts.mVerbose;
+
+  // Skip generation of warnings a second time if we are doing more than just
+  // a single pass over the input file.
+  bool SuppressAllWarnings = (Opts.mOutputType != Slang::OT_Dependency);
+
+  std::list<std::pair<const char*, const char*> >::const_iterator
+      IOFile64Iter = IOFiles64.begin(),
+      IOFile32Iter = IOFiles32.begin(),
+      DepFileIter = DepFiles.begin();
+
+  for (unsigned i = 0, e = IOFiles32.size(); i != e; i++) {
+    InputFile = IOFile64Iter->first;
+    Output64File = IOFile64Iter->second;
+    Output32File = IOFile32Iter->second;
+
+    if (!setInputSource(InputFile))
+      return false;
+
+    if (!setOutput(Output64File))
+      return false;
+
+    // For use with 64-bit compilation/reflection. This only sets the filename of
+    // the 32-bit bitcode file, and doesn't actually verify it already exists.
+    mOutput32FileName = Output32File;
+
+    mIsFilterscript = isFilterscript(InputFile);
+
+    CodeGenOpts.MainFileName = mInputFileName;
+
+    if (Slang::compile(Opts) > 0)
+      return false;
+
+    if (!Opts.mJavaReflectionPackageName.empty()) {
+      mRSContext->setReflectJavaPackageName(Opts.mJavaReflectionPackageName);
+    }
+    const std::string &RealPackageName =
+        mRSContext->getReflectJavaPackageName();
+
+    bool doReflection = true;
+    if (Opts.mEmit3264 && (Opts.mBitWidth == 32)) {
+      // Skip reflection on the 32-bit path if we are going to emit it on the
+      // 64-bit path.
+      doReflection = false;
+    }
+    if (Opts.mOutputType != Slang::OT_Dependency && doReflection) {
+
+      if (Opts.mBitcodeStorage == BCST_CPP_CODE) {
+        const std::string &outputFileName = (Opts.mBitWidth == 64) ?
+                                            mOutputFileName : mOutput32FileName;
+        RSReflectionCpp R(mRSContext, Opts.mJavaReflectionPathBase,
+                          getInputFileName(), outputFileName);
+        if (!R.reflect()) {
+            return false;
+        }
+      } else {
+        if (!Opts.mRSPackageName.empty()) {
+          mRSContext->setRSPackageName(Opts.mRSPackageName);
+        }
+
+        std::vector<std::string> generatedFileNames;
+        RSReflectionJava R(mRSContext, &generatedFileNames,
+                           Opts.mJavaReflectionPathBase, getInputFileName(),
+                           mOutputFileName,
+                           Opts.mBitcodeStorage == BCST_JAVA_CODE);
+        if (!R.reflect()) {
+          // TODO Is this needed or will the error message have been printed
+          // already? and why not for the C++ case?
+          fprintf(stderr, "RSContext::reflectToJava : failed to do reflection "
+                          "(%s)\n",
+                  R.getLastError());
+          return false;
+        }
+
+        for (std::vector<std::string>::const_iterator
+                 I = generatedFileNames.begin(), E = generatedFileNames.end();
+             I != E;
+             I++) {
+          std::string ReflectedName = RSSlangReflectUtils::ComputePackagedPath(
+              Opts.mJavaReflectionPathBase.c_str(),
+              (RealPackageName + OS_PATH_SEPARATOR_STR + *I).c_str());
+          appendGeneratedFileName(ReflectedName + ".java");
+        }
+
+        if ((Opts.mOutputType == Slang::OT_Bitcode) &&
+            (Opts.mBitcodeStorage == BCST_JAVA_CODE) &&
+            !generateJavaBitcodeAccessor(Opts.mJavaReflectionPathBase,
+                                         RealPackageName.c_str(),
+                                         mRSContext->getLicenseNote())) {
+          return false;
+        }
+      }
+    }
+
+    if (Opts.mEmitDependency) {
+      BCOutputFile = DepFileIter->first;
+      DepOutputFile = DepFileIter->second;
+
+      setDepTargetBC(BCOutputFile);
+
+      if (!setDepOutput(DepOutputFile))
+        return false;
+
+      if (SuppressAllWarnings) {
+        getDiagnostics().setSuppressAllDiagnostics(true);
+      }
+      if (generateDepFile(Opts.mEmitPhonyDependency) > 0)
+        return false;
+      if (SuppressAllWarnings) {
+        getDiagnostics().setSuppressAllDiagnostics(false);
+      }
+
+      DepFileIter++;
+    }
+
+    if (!checkODR(InputFile))
+      return false;
+
+    IOFile64Iter++;
+    IOFile32Iter++;
+  }
+  return true;
+}
+
+}  // namespace slang
diff --git a/slang/slang.h b/slang/slang.h
new file mode 100644
index 0000000..faf6f8a
--- /dev/null
+++ b/slang/slang.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2010, 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_SLANG_SLANG_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_H_
+
+#include <cstdio>
+#include <list>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "llvm/ADT/StringMap.h"
+
+#include "slang_rs_reflect_utils.h"
+#include "slang_version.h"
+
+// Terrible workaround for TargetOptions.h not using llvm::RefCountedBase!
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+using llvm::RefCountedBase;
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Lex/ModuleLoader.h"
+
+#include "llvm/ADT/StringRef.h"
+
+#include "llvm/Target/TargetMachine.h"
+
+#include "slang_diagnostic_buffer.h"
+#include "slang_pragma_list.h"
+
+namespace llvm {
+  class tool_output_file;
+}
+
+namespace clang {
+  class ASTConsumer;
+  class ASTContext;
+  class Backend;
+  class CodeGenOptions;
+  class Diagnostic;
+  class DiagnosticsEngine;
+  class FileManager;
+  class FileSystemOptions;
+  class HeaderSearchOptions;
+  class LangOptions;
+  class PCHContainerOperations;
+  class Preprocessor;
+  class PreprocessorOptions;
+  class SourceManager;
+  class TargetInfo;
+}  // namespace clang
+
+namespace slang {
+
+class RSCCOptions;
+class RSContext;
+class RSExportRecordType;
+
+class Slang : public clang::ModuleLoader {
+ public:
+  enum OutputType {
+    OT_Dependency,
+    OT_Assembly,
+    OT_LLVMAssembly,
+    OT_Bitcode,
+    OT_Nothing,
+    OT_Object,
+
+    OT_Default = OT_Bitcode
+  };
+
+ private:
+  // Language options (define the language feature for compiler such as C99)
+  clang::LangOptions LangOpts;
+  // Code generation options for the compiler
+  clang::CodeGenOptions CodeGenOpts;
+
+  // Returns true if this is a Filterscript file.
+  static bool isFilterscript(const char *Filename);
+
+  // Diagnostics Engine (Producer and Diagnostics Reporter)
+  clang::DiagnosticsEngine *mDiagEngine;
+
+  // Diagnostics Consumer
+  // NOTE: The ownership is taken by mDiagEngine after creation.
+  DiagnosticBuffer *mDiagClient;
+
+  // The target being compiled for
+  std::shared_ptr<clang::TargetOptions> mTargetOpts;
+  std::unique_ptr<clang::TargetInfo> mTarget;
+  void createTarget(uint32_t BitWidth);
+
+  // File manager (for prepocessor doing the job such as header file search)
+  std::unique_ptr<clang::FileManager> mFileMgr;
+  std::unique_ptr<clang::FileSystemOptions> mFileSysOpt;
+  void createFileManager();
+
+  // Source manager (responsible for the source code handling)
+  std::unique_ptr<clang::SourceManager> mSourceMgr;
+  void createSourceManager();
+
+  // Preprocessor (source code preprocessor)
+  std::unique_ptr<clang::Preprocessor> mPP;
+  void createPreprocessor();
+
+  // AST context (the context to hold long-lived AST nodes)
+  std::unique_ptr<clang::ASTContext> mASTContext;
+  void createASTContext();
+
+  // AST consumer, responsible for code generation
+  std::unique_ptr<clang::ASTConsumer> mBackend;
+
+  // Options for includes
+  llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> mHSOpts;
+
+  // Options for the preprocessor (but not header includes)
+  llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions> mPPOpts;
+
+  // Module provider (probably not necessary, but keeps us more consistent
+  // with regular Clang.
+  std::shared_ptr<clang::PCHContainerOperations> mPCHContainerOperations;
+
+  // File names
+  std::string mInputFileName;
+  std::string mOutputFileName;
+  std::string mOutput32FileName;
+
+  std::string mDepOutputFileName;
+  std::string mDepTargetBCFileName;
+  std::vector<std::string> mAdditionalDepTargets;
+
+  OutputType mOT;
+
+  // Output stream
+  std::unique_ptr<llvm::tool_output_file> mOS;
+
+  // Dependency output stream
+  std::unique_ptr<llvm::tool_output_file> mDOS;
+
+  std::vector<std::string> mIncludePaths;
+
+  // Context for Renderscript
+  RSContext *mRSContext;
+
+  bool mAllowRSPrefix;
+
+  unsigned int mTargetAPI;
+
+  bool mVerbose;
+
+  bool mIsFilterscript;
+
+  // Collect generated filenames (without the .java) for dependency generation
+  std::vector<std::string> mGeneratedFileNames;
+
+  PragmaList mPragmas;
+
+  // FIXME: Should be std::list<RSExportable *> here. But currently we only
+  //        check ODR on record type.
+  //
+  // ReflectedDefinitions maps record type name to a pair:
+  //  <its RSExportRecordType instance,
+  //   the first file contains this record type definition>
+  typedef std::pair<RSExportRecordType*, const char*> ReflectedDefinitionTy;
+  typedef llvm::StringMap<ReflectedDefinitionTy> ReflectedDefinitionListTy;
+  ReflectedDefinitionListTy ReflectedDefinitions;
+
+  bool generateJavaBitcodeAccessor(const std::string &OutputPathBase,
+                                   const std::string &PackageName,
+                                   const std::string *LicenseNote);
+
+  // CurInputFile is the pointer to a char array holding the input filename
+  // and is valid before compile() ends.
+  bool checkODR(const char *CurInputFile);
+
+  clang::DiagnosticsEngine &getDiagnostics() { return *mDiagEngine; }
+  clang::TargetInfo const &getTargetInfo() const { return *mTarget; }
+  clang::FileManager &getFileManager() { return *mFileMgr; }
+  clang::SourceManager &getSourceManager() { return *mSourceMgr; }
+  clang::Preprocessor &getPreprocessor() { return *mPP; }
+  clang::ASTContext &getASTContext() { return *mASTContext; }
+  clang::HeaderSearchOptions &getHeaderSearchOpts() { return *mHSOpts; }
+  clang::PreprocessorOptions &getPreprocessorOpts() { return *mPPOpts; }
+
+  inline clang::TargetOptions const &getTargetOptions() const
+    { return *mTargetOpts.get(); }
+
+  void initPreprocessor();
+  void initASTContext();
+
+  clang::ASTConsumer *createBackend(const RSCCOptions &Opts,
+                                    const clang::CodeGenOptions &CodeGenOpts,
+                                    llvm::raw_ostream *OS,
+                                    OutputType OT);
+
+ public:
+  static const llvm::StringRef PragmaMetadataName;
+
+  static void GlobalInitialization();
+
+  static bool IsRSHeaderFile(const char *File);
+  // FIXME: Determine whether a location is in RS header (i.e., one of the RS
+  //        built-in APIs) should only need its names (we need a "list" of RS
+  //        built-in APIs).
+  static bool IsLocInRSHeaderFile(const clang::SourceLocation &Loc,
+                                  const clang::SourceManager &SourceMgr);
+
+  Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine,
+        DiagnosticBuffer *DiagClient);
+
+  virtual ~Slang();
+
+  bool setInputSource(llvm::StringRef InputFile);
+
+  std::string const &getInputFileName() const { return mInputFileName; }
+
+  void setIncludePaths(const std::vector<std::string> &IncludePaths) {
+    mIncludePaths = IncludePaths;
+  }
+
+  void setOutputType(OutputType OT) { mOT = OT; }
+
+  bool setOutput(const char *OutputFile);
+
+  bool setDepOutput(const char *OutputFile);
+
+  void setDepTargetBC(const char *TargetBCFile) {
+    mDepTargetBCFileName = TargetBCFile;
+  }
+
+  void setAdditionalDepTargets(
+      std::vector<std::string> const &AdditionalDepTargets) {
+    mAdditionalDepTargets = AdditionalDepTargets;
+  }
+
+  void appendGeneratedFileName(std::string const &GeneratedFileName) {
+    mGeneratedFileNames.push_back(GeneratedFileName);
+  }
+
+  int generateDepFile(bool PhonyTarget);
+
+  int compile(const RSCCOptions &Opts);
+
+  char const *getErrorMessage() { return mDiagClient->str().c_str(); }
+
+  void setDebugMetadataEmission(bool EmitDebug);
+
+  void setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel);
+
+  // Compile bunch of RS files given in the llvm-rs-cc arguments. Return true if
+  // all given input files are successfully compiled without errors.
+  //
+  // @IOFiles - List of pairs of <input file path, output file path>.
+  //
+  // @DepFiles - List of pairs of <output dep. file path, dependent bitcode
+  //             target>. If @OutputDep is true, this parameter must be given
+  //             with the same number of pairs given in @IOFiles.
+  //
+  // @Opts - Selection of options defined from invoking llvm-rs-cc
+  bool
+  compile(const std::list<std::pair<const char *, const char *>> &IOFiles64,
+          const std::list<std::pair<const char *, const char *>> &IOFiles32,
+          const std::list<std::pair<const char *, const char *>> &DepFiles,
+          const RSCCOptions &Opts,
+          clang::DiagnosticOptions &DiagOpts);
+
+  clang::ModuleLoadResult loadModule(clang::SourceLocation ImportLoc,
+                                     clang::ModuleIdPath Path,
+                                     clang::Module::NameVisibilityKind VK,
+                                     bool IsInclusionDirective) override;
+
+  void makeModuleVisible(clang::Module *Mod,
+                         clang::Module::NameVisibilityKind Visibility,
+                         clang::SourceLocation ImportLoc) override {}
+
+  clang::GlobalModuleIndex *
+  loadGlobalModuleIndex(clang::SourceLocation TriggerLoc) override {
+    // We don't support C++ modules for RenderScript.
+    return nullptr;
+  }
+
+  bool lookupMissingImports(llvm::StringRef Name,
+                            clang::SourceLocation TriggerLoc) override {
+    // We don't support C++ modules for RenderScript.
+    return false;
+  }
+};
+
+} // namespace slang
+
+#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_H_  NOLINT
diff --git a/slang/slang_assert.h b/slang/slang_assert.h
new file mode 100644
index 0000000..c3ea84f
--- /dev/null
+++ b/slang/slang_assert.h
@@ -0,0 +1,40 @@
+/*
+ * 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 _FRAMEWORKS_COMPILE_SLANG_SLANG_ASSERT_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_ASSERT_H_
+
+#include <cstdlib>
+#include <cstdio>
+
+#ifdef __DISABLE_ASSERTS
+#define slangAssert(v) do {} while (0)
+#else
+#define __ABORT_ON_FAILURES 1
+#define slangAssert(v)                                        \
+  do {                                                        \
+    if (!(v)) {                                               \
+      fprintf(stderr, "slangAssert failed at %s:%d - '%s'\n", \
+          __FILE__, __LINE__, #v);                            \
+      if (__ABORT_ON_FAILURES) {                              \
+        abort();                                              \
+      }                                                       \
+    }                                                         \
+  } while (0)
+#endif  // __DISABLE_ASSERTS
+
+
+#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_ASSERT_H_  NOLINT
diff --git a/slang/slang_backend.cpp b/slang/slang_backend.cpp
new file mode 100644
index 0000000..81de4fd
--- /dev/null
+++ b/slang/slang_backend.cpp
@@ -0,0 +1,911 @@
+/*
+ * 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.
+ */
+
+#include "slang_backend.h"
+
+#include <string>
+#include <vector>
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+
+#include "clang/CodeGen/ModuleBuilder.h"
+
+#include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/StringExtras.h"
+
+#include "llvm/Bitcode/ReaderWriter.h"
+
+#include "llvm/CodeGen/RegAllocRegistry.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
+
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/TargetRegistry.h"
+
+#include "llvm/MC/SubtargetFeature.h"
+
+#include "slang_assert.h"
+#include "slang.h"
+#include "slang_bitcode_gen.h"
+#include "slang_rs_context.h"
+#include "slang_rs_export_foreach.h"
+#include "slang_rs_export_func.h"
+#include "slang_rs_export_reduce.h"
+#include "slang_rs_export_type.h"
+#include "slang_rs_export_var.h"
+#include "slang_rs_metadata.h"
+
+#include "rs_cc_options.h"
+
+#include "strip_unknown_attributes.h"
+
+namespace slang {
+
+void Backend::CreateFunctionPasses() {
+  if (!mPerFunctionPasses) {
+    mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule);
+
+    llvm::PassManagerBuilder PMBuilder;
+    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
+    PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
+  }
+}
+
+void Backend::CreateModulePasses() {
+  if (!mPerModulePasses) {
+    mPerModulePasses = new llvm::legacy::PassManager();
+
+    llvm::PassManagerBuilder PMBuilder;
+    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
+    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
+    if (mCodeGenOpts.UnitAtATime) {
+      PMBuilder.DisableUnitAtATime = 0;
+    } else {
+      PMBuilder.DisableUnitAtATime = 1;
+    }
+
+    if (mCodeGenOpts.UnrollLoops) {
+      PMBuilder.DisableUnrollLoops = 0;
+    } else {
+      PMBuilder.DisableUnrollLoops = 1;
+    }
+
+    PMBuilder.populateModulePassManager(*mPerModulePasses);
+    // Add a pass to strip off unknown/unsupported attributes.
+    mPerModulePasses->add(createStripUnknownAttributesPass());
+  }
+}
+
+bool Backend::CreateCodeGenPasses() {
+  if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
+    return true;
+
+  // Now we add passes for code emitting
+  if (mCodeGenPasses) {
+    return true;
+  } else {
+    mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule);
+  }
+
+  // Create the TargetMachine for generating code.
+  std::string Triple = mpModule->getTargetTriple();
+
+  std::string Error;
+  const llvm::Target* TargetInfo =
+      llvm::TargetRegistry::lookupTarget(Triple, Error);
+  if (TargetInfo == nullptr) {
+    mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
+    return false;
+  }
+
+  // Target Machine Options
+  llvm::TargetOptions Options;
+
+  // Use soft-float ABI for ARM (which is the target used by Slang during code
+  // generation).  Codegen still uses hardware FPU by default.  To use software
+  // floating point, add 'soft-float' feature to FeaturesStr below.
+  Options.FloatABIType = llvm::FloatABI::Soft;
+
+  // BCC needs all unknown symbols resolved at compilation time. So we don't
+  // need any relocation model.
+  llvm::Reloc::Model RM = llvm::Reloc::Static;
+
+  // This is set for the linker (specify how large of the virtual addresses we
+  // can access for all unknown symbols.)
+  llvm::CodeModel::Model CM;
+  if (mpModule->getDataLayout().getPointerSize() == 4) {
+    CM = llvm::CodeModel::Small;
+  } else {
+    // The target may have pointer size greater than 32 (e.g. x86_64
+    // architecture) may need large data address model
+    CM = llvm::CodeModel::Medium;
+  }
+
+  // Setup feature string
+  std::string FeaturesStr;
+  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
+    llvm::SubtargetFeatures Features;
+
+    for (std::vector<std::string>::const_iterator
+             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
+         I != E;
+         I++)
+      Features.AddFeature(*I);
+
+    FeaturesStr = Features.getString();
+  }
+
+  llvm::TargetMachine *TM =
+    TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
+                                    Options, RM, CM);
+
+  // Register allocation policy:
+  //  createFastRegisterAllocator: fast but bad quality
+  //  createGreedyRegisterAllocator: not so fast but good quality
+  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
+                                     llvm::createFastRegisterAllocator :
+                                     llvm::createGreedyRegisterAllocator);
+
+  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
+  if (mCodeGenOpts.OptimizationLevel == 0) {
+    OptLevel = llvm::CodeGenOpt::None;
+  } else if (mCodeGenOpts.OptimizationLevel == 3) {
+    OptLevel = llvm::CodeGenOpt::Aggressive;
+  }
+
+  llvm::TargetMachine::CodeGenFileType CGFT =
+      llvm::TargetMachine::CGFT_AssemblyFile;
+  if (mOT == Slang::OT_Object) {
+    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
+  }
+  if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream,
+                              CGFT, OptLevel)) {
+    mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
+    return false;
+  }
+
+  return true;
+}
+
+Backend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine,
+                 const RSCCOptions &Opts,
+                 const clang::HeaderSearchOptions &HeaderSearchOpts,
+                 const clang::PreprocessorOptions &PreprocessorOpts,
+                 const clang::CodeGenOptions &CodeGenOpts,
+                 const clang::TargetOptions &TargetOpts, PragmaList *Pragmas,
+                 llvm::raw_ostream *OS, Slang::OutputType OT,
+                 clang::SourceManager &SourceMgr, bool AllowRSPrefix,
+                 bool IsFilterscript)
+    : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS),
+      mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr),
+      mPerModulePasses(nullptr), mCodeGenPasses(nullptr),
+      mBufferOutStream(*mpOS), mContext(Context),
+      mSourceMgr(SourceMgr), mASTPrint(Opts.mASTPrint), mAllowRSPrefix(AllowRSPrefix),
+      mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr),
+      mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr),
+      mExportForEachSignatureMetadata(nullptr),
+      mExportReduceMetadata(nullptr),
+      mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr),
+      mRefCount(mContext->getASTContext()),
+      mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
+      mForEachHandler(Context),
+      mLLVMContext(llvm::getGlobalContext()), mDiagEngine(*DiagEngine),
+      mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
+  mGen = CreateLLVMCodeGen(mDiagEngine, "", HeaderSearchOpts, PreprocessorOpts,
+      mCodeGenOpts, mLLVMContext);
+}
+
+void Backend::Initialize(clang::ASTContext &Ctx) {
+  mGen->Initialize(Ctx);
+
+  mpModule = mGen->GetModule();
+}
+
+void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
+  HandleTranslationUnitPre(Ctx);
+
+  if (mASTPrint)
+    Ctx.getTranslationUnitDecl()->dump();
+
+  mGen->HandleTranslationUnit(Ctx);
+
+  // Here, we complete a translation unit (whole translation unit is now in LLVM
+  // IR). Now, interact with LLVM backend to generate actual machine code (asm
+  // or machine code, whatever.)
+
+  // Silently ignore if we weren't initialized for some reason.
+  if (!mpModule)
+    return;
+
+  llvm::Module *M = mGen->ReleaseModule();
+  if (!M) {
+    // The module has been released by IR gen on failures, do not double free.
+    mpModule = nullptr;
+    return;
+  }
+
+  slangAssert(mpModule == M &&
+              "Unexpected module change during LLVM IR generation");
+
+  // Insert #pragma information into metadata section of module
+  if (!mPragmas->empty()) {
+    llvm::NamedMDNode *PragmaMetadata =
+        mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
+    for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
+         I != E;
+         I++) {
+      llvm::SmallVector<llvm::Metadata*, 2> Pragma;
+      // Name goes first
+      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
+      // And then value
+      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
+
+      // Create MDNode and insert into PragmaMetadata
+      PragmaMetadata->addOperand(
+          llvm::MDNode::get(mLLVMContext, Pragma));
+    }
+  }
+
+  HandleTranslationUnitPost(mpModule);
+
+  // Create passes for optimization and code emission
+
+  // Create and run per-function passes
+  CreateFunctionPasses();
+  if (mPerFunctionPasses) {
+    mPerFunctionPasses->doInitialization();
+
+    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
+         I != E;
+         I++)
+      if (!I->isDeclaration())
+        mPerFunctionPasses->run(*I);
+
+    mPerFunctionPasses->doFinalization();
+  }
+
+  // Create and run module passes
+  CreateModulePasses();
+  if (mPerModulePasses)
+    mPerModulePasses->run(*mpModule);
+
+  switch (mOT) {
+    case Slang::OT_Assembly:
+    case Slang::OT_Object: {
+      if (!CreateCodeGenPasses())
+        return;
+
+      mCodeGenPasses->doInitialization();
+
+      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
+          I != E;
+          I++)
+        if (!I->isDeclaration())
+          mCodeGenPasses->run(*I);
+
+      mCodeGenPasses->doFinalization();
+      break;
+    }
+    case Slang::OT_LLVMAssembly: {
+      llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
+      LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream));
+      LLEmitPM->run(*mpModule);
+      break;
+    }
+    case Slang::OT_Bitcode: {
+      writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(),
+                   mCodeGenOpts.OptimizationLevel, mCodeGenOpts.getDebugInfo());
+      break;
+    }
+    case Slang::OT_Nothing: {
+      return;
+    }
+    default: {
+      slangAssert(false && "Unknown output type");
+    }
+  }
+}
+
+void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
+  mGen->HandleTagDeclDefinition(D);
+}
+
+void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
+  mGen->CompleteTentativeDefinition(D);
+}
+
+Backend::~Backend() {
+  delete mpModule;
+  delete mGen;
+  delete mPerFunctionPasses;
+  delete mPerModulePasses;
+  delete mCodeGenPasses;
+}
+
+// 1) Add zero initialization of local RS object types
+void Backend::AnnotateFunction(clang::FunctionDecl *FD) {
+  if (FD &&
+      FD->hasBody() &&
+      !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
+    mRefCount.Init();
+    mRefCount.SetDeclContext(FD);
+    mRefCount.Visit(FD->getBody());
+  }
+}
+
+bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
+  // Find and remember the types for rs_allocation and rs_script_call_t so
+  // they can be used later for translating rsForEach() calls.
+  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
+       (mContext->getAllocationType().isNull() ||
+        mContext->getScriptCallType().isNull()) &&
+       I != E; I++) {
+    if (clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(*I)) {
+      clang::StringRef TypeName = TD->getName();
+      if (TypeName.equals("rs_allocation")) {
+        mContext->setAllocationType(TD);
+      } else if (TypeName.equals("rs_script_call_t")) {
+        mContext->setScriptCallType(TD);
+      }
+    }
+  }
+
+  // Disallow user-defined functions with prefix "rs"
+  if (!mAllowRSPrefix) {
+    // Iterate all function declarations in the program.
+    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
+         I != E; I++) {
+      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
+      if (FD == nullptr)
+        continue;
+      if (!FD->getName().startswith("rs"))  // Check prefix
+        continue;
+      if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
+        mContext->ReportError(FD->getLocation(),
+                              "invalid function name prefix, "
+                              "\"rs\" is reserved: '%0'")
+            << FD->getName();
+    }
+  }
+
+  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
+    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
+    if (FD) {
+      // Handle forward reference from pragma (see
+      // RSReducePragmaHandler::HandlePragma for backward reference).
+      mContext->markUsedByReducePragma(FD, RSContext::CheckNameYes);
+      if (FD->isGlobal()) {
+        // Check that we don't have any array parameters being misinterpreted as
+        // kernel pointers due to the C type system's array to pointer decay.
+        size_t numParams = FD->getNumParams();
+        for (size_t i = 0; i < numParams; i++) {
+          const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
+          clang::QualType QT = PVD->getOriginalType();
+          if (QT->isArrayType()) {
+            mContext->ReportError(
+                PVD->getTypeSpecStartLoc(),
+                "exported function parameters may not have array type: %0")
+                << QT;
+          }
+        }
+        AnnotateFunction(FD);
+      }
+    }
+
+    if (getTargetAPI() >= SLANG_FEATURE_SINGLE_SOURCE_API) {
+      if (FD && FD->hasBody() &&
+          !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
+        if (FD->hasAttr<clang::KernelAttr>()) {
+          // Log functions with attribute "kernel" by their names, and assign
+          // them slot numbers. Any other function cannot be used in a
+          // rsForEach() or rsForEachWithOptions() call, including old-style
+          // kernel functions which are defined without the "kernel" attribute.
+          mContext->addForEach(FD);
+        }
+        // Look for any kernel launch calls and translate them into using the
+        // internal API.
+        // Report a compiler error on kernel launches inside a kernel.
+        mForEachHandler.handleForEachCalls(FD, getTargetAPI());
+      }
+    }
+  }
+
+  return mGen->HandleTopLevelDecl(D);
+}
+
+void Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
+  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
+
+  if (!mContext->processReducePragmas(this))
+    return;
+
+  // If we have an invalid RS/FS AST, don't check further.
+  if (!mASTChecker.Validate()) {
+    return;
+  }
+
+  if (mIsFilterscript) {
+    mContext->addPragma("rs_fp_relaxed", "");
+  }
+
+  int version = mContext->getVersion();
+  if (version == 0) {
+    // Not setting a version is an error
+    mDiagEngine.Report(
+        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
+        mDiagEngine.getCustomDiagID(
+            clang::DiagnosticsEngine::Error,
+            "missing pragma for version in source file"));
+  } else {
+    slangAssert(version == 1);
+  }
+
+  if (mContext->getReflectJavaPackageName().empty()) {
+    mDiagEngine.Report(
+        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
+        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
+                                    "missing \"#pragma rs "
+                                    "java_package_name(com.foo.bar)\" "
+                                    "in source file"));
+    return;
+  }
+
+  // Create a static global destructor if necessary (to handle RS object
+  // runtime cleanup).
+  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
+  if (FD) {
+    HandleTopLevelDecl(clang::DeclGroupRef(FD));
+  }
+
+  // Process any static function declarations
+  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
+          E = TUDecl->decls_end(); I != E; I++) {
+    if ((I->getKind() >= clang::Decl::firstFunction) &&
+        (I->getKind() <= clang::Decl::lastFunction)) {
+      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
+      if (FD && !FD->isGlobal()) {
+        AnnotateFunction(FD);
+      }
+    }
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void Backend::dumpExportVarInfo(llvm::Module *M) {
+  int slotCount = 0;
+  if (mExportVarMetadata == nullptr)
+    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
+
+  llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
+
+  // We emit slot information (#rs_object_slots) for any reference counted
+  // RS type or pointer (which can also be bound).
+
+  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
+          E = mContext->export_vars_end();
+       I != E;
+       I++) {
+    const RSExportVar *EV = *I;
+    const RSExportType *ET = EV->getType();
+    bool countsAsRSObject = false;
+
+    // Variable name
+    ExportVarInfo.push_back(
+        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
+
+    // Type name
+    switch (ET->getClass()) {
+      case RSExportType::ExportClassPrimitive: {
+        const RSExportPrimitiveType *PT =
+            static_cast<const RSExportPrimitiveType*>(ET);
+        ExportVarInfo.push_back(
+            llvm::MDString::get(
+              mLLVMContext, llvm::utostr_32(PT->getType())));
+        if (PT->isRSObjectType()) {
+          countsAsRSObject = true;
+        }
+        break;
+      }
+      case RSExportType::ExportClassPointer: {
+        ExportVarInfo.push_back(
+            llvm::MDString::get(
+              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
+                ->getPointeeType()->getName()).c_str()));
+        break;
+      }
+      case RSExportType::ExportClassMatrix: {
+        ExportVarInfo.push_back(
+            llvm::MDString::get(
+              mLLVMContext, llvm::utostr_32(
+                  /* TODO Strange value.  This pushes just a number, quite
+                   * different than the other cases.  What is this used for?
+                   * These are the metadata values that some partner drivers
+                   * want to reference (for TBAA, etc.). We may want to look
+                   * at whether these provide any reasonable value (or have
+                   * distinct enough values to actually depend on).
+                   */
+                DataTypeRSMatrix2x2 +
+                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
+        break;
+      }
+      case RSExportType::ExportClassVector:
+      case RSExportType::ExportClassConstantArray:
+      case RSExportType::ExportClassRecord: {
+        ExportVarInfo.push_back(
+            llvm::MDString::get(mLLVMContext,
+              EV->getType()->getName().c_str()));
+        break;
+      }
+    }
+
+    mExportVarMetadata->addOperand(
+        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
+    ExportVarInfo.clear();
+
+    if (mRSObjectSlotsMetadata == nullptr) {
+      mRSObjectSlotsMetadata =
+          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
+    }
+
+    if (countsAsRSObject) {
+      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
+          llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
+    }
+
+    slotCount++;
+  }
+}
+
+void Backend::dumpExportFunctionInfo(llvm::Module *M) {
+  if (mExportFuncMetadata == nullptr)
+    mExportFuncMetadata =
+        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
+
+  llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
+
+  for (RSContext::const_export_func_iterator
+          I = mContext->export_funcs_begin(),
+          E = mContext->export_funcs_end();
+       I != E;
+       I++) {
+    const RSExportFunc *EF = *I;
+
+    // Function name
+    if (!EF->hasParam()) {
+      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
+                                                   EF->getName().c_str()));
+    } else {
+      llvm::Function *F = M->getFunction(EF->getName());
+      llvm::Function *HelperFunction;
+      const std::string HelperFunctionName(".helper_" + EF->getName());
+
+      slangAssert(F && "Function marked as exported disappeared in Bitcode");
+
+      // Create helper function
+      {
+        llvm::StructType *HelperFunctionParameterTy = nullptr;
+        std::vector<bool> isStructInput;
+
+        if (!F->getArgumentList().empty()) {
+          std::vector<llvm::Type*> HelperFunctionParameterTys;
+          for (llvm::Function::arg_iterator AI = F->arg_begin(),
+                   AE = F->arg_end(); AI != AE; AI++) {
+              if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
+                  HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
+                  isStructInput.push_back(true);
+              } else {
+                  HelperFunctionParameterTys.push_back(AI->getType());
+                  isStructInput.push_back(false);
+              }
+          }
+          HelperFunctionParameterTy =
+              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
+        }
+
+        if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
+          fprintf(stderr, "Failed to export function %s: parameter type "
+                          "mismatch during creation of helper function.\n",
+                  EF->getName().c_str());
+
+          const RSExportRecordType *Expected = EF->getParamPacketType();
+          if (Expected) {
+            fprintf(stderr, "Expected:\n");
+            Expected->getLLVMType()->dump();
+          }
+          if (HelperFunctionParameterTy) {
+            fprintf(stderr, "Got:\n");
+            HelperFunctionParameterTy->dump();
+          }
+        }
+
+        std::vector<llvm::Type*> Params;
+        if (HelperFunctionParameterTy) {
+          llvm::PointerType *HelperFunctionParameterTyP =
+              llvm::PointerType::getUnqual(HelperFunctionParameterTy);
+          Params.push_back(HelperFunctionParameterTyP);
+        }
+
+        llvm::FunctionType * HelperFunctionType =
+            llvm::FunctionType::get(F->getReturnType(),
+                                    Params,
+                                    /* IsVarArgs = */false);
+
+        HelperFunction =
+            llvm::Function::Create(HelperFunctionType,
+                                   llvm::GlobalValue::ExternalLinkage,
+                                   HelperFunctionName,
+                                   M);
+
+        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
+        HelperFunction->setCallingConv(F->getCallingConv());
+
+        // Create helper function body
+        {
+          llvm::Argument *HelperFunctionParameter =
+              &(*HelperFunction->arg_begin());
+          llvm::BasicBlock *BB =
+              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
+          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
+          llvm::SmallVector<llvm::Value*, 6> Params;
+          llvm::Value *Idx[2];
+
+          Idx[0] =
+              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
+
+          // getelementptr and load instruction for all elements in
+          // parameter .p
+          for (size_t i = 0; i < EF->getNumParameters(); i++) {
+            // getelementptr
+            Idx[1] = llvm::ConstantInt::get(
+              llvm::Type::getInt32Ty(mLLVMContext), i);
+
+            llvm::Value *Ptr = NULL;
+
+            Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
+
+            // Load is only required for non-struct ptrs
+            if (isStructInput[i]) {
+                Params.push_back(Ptr);
+            } else {
+                llvm::Value *V = IB->CreateLoad(Ptr);
+                Params.push_back(V);
+            }
+          }
+
+          // Call and pass the all elements as parameter to F
+          llvm::CallInst *CI = IB->CreateCall(F, Params);
+
+          CI->setCallingConv(F->getCallingConv());
+
+          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) {
+            IB->CreateRetVoid();
+          } else {
+            IB->CreateRet(CI);
+          }
+
+          delete IB;
+        }
+      }
+
+      ExportFuncInfo.push_back(
+          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
+    }
+
+    mExportFuncMetadata->addOperand(
+        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
+    ExportFuncInfo.clear();
+  }
+}
+
+void Backend::dumpExportForEachInfo(llvm::Module *M) {
+  if (mExportForEachNameMetadata == nullptr) {
+    mExportForEachNameMetadata =
+        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
+  }
+  if (mExportForEachSignatureMetadata == nullptr) {
+    mExportForEachSignatureMetadata =
+        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
+  }
+
+  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
+  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
+
+  for (RSContext::const_export_foreach_iterator
+          I = mContext->export_foreach_begin(),
+          E = mContext->export_foreach_end();
+       I != E;
+       I++) {
+    const RSExportForEach *EFE = *I;
+
+    ExportForEachName.push_back(
+        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
+
+    mExportForEachNameMetadata->addOperand(
+        llvm::MDNode::get(mLLVMContext, ExportForEachName));
+    ExportForEachName.clear();
+
+    ExportForEachInfo.push_back(
+        llvm::MDString::get(mLLVMContext,
+                            llvm::utostr_32(EFE->getSignatureMetadata())));
+
+    mExportForEachSignatureMetadata->addOperand(
+        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
+    ExportForEachInfo.clear();
+  }
+}
+
+void Backend::dumpExportReduceInfo(llvm::Module *M) {
+  if (!mExportReduceMetadata) {
+    mExportReduceMetadata =
+      M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN);
+  }
+
+  llvm::SmallVector<llvm::Metadata *, 6> ExportReduceInfo;
+  // Add operand to ExportReduceInfo, padding out missing operands with
+  // nullptr.
+  auto addOperand = [&ExportReduceInfo](uint32_t Idx, llvm::Metadata *N) {
+    while (Idx > ExportReduceInfo.size())
+      ExportReduceInfo.push_back(nullptr);
+    ExportReduceInfo.push_back(N);
+  };
+  // Add string operand to ExportReduceInfo, padding out missing operands
+  // with nullptr.
+  // If string is empty, then do not add it unless Always is true.
+  auto addString = [&addOperand, this](uint32_t Idx, const std::string &S,
+                                       bool Always = true) {
+    if (Always || !S.empty())
+      addOperand(Idx, llvm::MDString::get(mLLVMContext, S));
+  };
+
+  // Add the description of the reduction kernels to the metadata node.
+  for (auto I = mContext->export_reduce_begin(),
+            E = mContext->export_reduce_end();
+       I != E; ++I) {
+    ExportReduceInfo.clear();
+
+    int Idx = 0;
+
+    addString(Idx++, (*I)->getNameReduce());
+
+    addOperand(Idx++, llvm::MDString::get(mLLVMContext, llvm::utostr_32((*I)->getAccumulatorTypeSize())));
+
+    llvm::SmallVector<llvm::Metadata *, 2> Accumulator;
+    Accumulator.push_back(
+      llvm::MDString::get(mLLVMContext, (*I)->getNameAccumulator()));
+    Accumulator.push_back(llvm::MDString::get(
+      mLLVMContext,
+      llvm::utostr_32((*I)->getAccumulatorSignatureMetadata())));
+    addOperand(Idx++, llvm::MDTuple::get(mLLVMContext, Accumulator));
+
+    addString(Idx++, (*I)->getNameInitializer(), false);
+    addString(Idx++, (*I)->getNameCombiner(), false);
+    addString(Idx++, (*I)->getNameOutConverter(), false);
+    addString(Idx++, (*I)->getNameHalter(), false);
+
+    mExportReduceMetadata->addOperand(
+      llvm::MDTuple::get(mLLVMContext, ExportReduceInfo));
+  }
+}
+
+void Backend::dumpExportTypeInfo(llvm::Module *M) {
+  llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
+
+  for (RSContext::const_export_type_iterator
+          I = mContext->export_types_begin(),
+          E = mContext->export_types_end();
+       I != E;
+       I++) {
+    // First, dump type name list to export
+    const RSExportType *ET = I->getValue();
+
+    ExportTypeInfo.clear();
+    // Type name
+    ExportTypeInfo.push_back(
+        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
+
+    if (ET->getClass() == RSExportType::ExportClassRecord) {
+      const RSExportRecordType *ERT =
+          static_cast<const RSExportRecordType*>(ET);
+
+      if (mExportTypeMetadata == nullptr)
+        mExportTypeMetadata =
+            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
+
+      mExportTypeMetadata->addOperand(
+          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
+
+      // Now, export struct field information to %[struct name]
+      std::string StructInfoMetadataName("%");
+      StructInfoMetadataName.append(ET->getName());
+      llvm::NamedMDNode *StructInfoMetadata =
+          M->getOrInsertNamedMetadata(StructInfoMetadataName);
+      llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
+
+      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
+                  "Metadata with same name was created before");
+      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
+              FE = ERT->fields_end();
+           FI != FE;
+           FI++) {
+        const RSExportRecordType::Field *F = *FI;
+
+        // 1. field name
+        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
+                                                F->getName().c_str()));
+
+        // 2. field type name
+        FieldInfo.push_back(
+            llvm::MDString::get(mLLVMContext,
+                                F->getType()->getName().c_str()));
+
+        StructInfoMetadata->addOperand(
+            llvm::MDNode::get(mLLVMContext, FieldInfo));
+        FieldInfo.clear();
+      }
+    }   // ET->getClass() == RSExportType::ExportClassRecord
+  }
+}
+
+void Backend::HandleTranslationUnitPost(llvm::Module *M) {
+
+  if (!mContext->is64Bit()) {
+    M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
+  }
+
+  if (!mContext->processExports())
+    return;
+
+  if (mContext->hasExportVar())
+    dumpExportVarInfo(M);
+
+  if (mContext->hasExportFunc())
+    dumpExportFunctionInfo(M);
+
+  if (mContext->hasExportForEach())
+    dumpExportForEachInfo(M);
+
+  if (mContext->hasExportReduce())
+    dumpExportReduceInfo(M);
+
+  if (mContext->hasExportType())
+    dumpExportTypeInfo(M);
+}
+
+}  // namespace slang
diff --git a/slang/slang_backend.h b/slang/slang_backend.h
new file mode 100644
index 0000000..38aa1e4
--- /dev/null
+++ b/slang/slang_backend.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2010, 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_SLANG_SLANG_BACKEND_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_BACKEND_H_
+
+#include "clang/AST/ASTConsumer.h"
+
+#include "llvm/IR/LegacyPassManager.h"
+
+#include "llvm/Support/raw_ostream.h"
+
+#include "slang.h"
+#include "slang_pragma_list.h"
+#include "slang_rs_check_ast.h"
+#include "slang_rs_foreach_lowering.h"
+#include "slang_rs_object_ref_count.h"
+#include "slang_version.h"
+
+namespace llvm {
+  class buffer_ostream;
+  class LLVMContext;
+  class NamedMDNode;
+  class Module;
+}
+
+namespace clang {
+  class ASTConsumer;
+  class ASTContext;
+  class CodeGenOptions;
+  class CodeGenerator;
+  class DeclGroupRef;
+  class DiagnosticsEngine;
+  class FunctionDecl;
+  class HeaderSearchOptions;
+  class PreprocessorOptions;
+  class TagDecl;
+  class TargetOptions;
+  class VarDecl;
+}
+
+namespace slang {
+
+class RSContext;
+
+class Backend : public clang::ASTConsumer {
+ private:
+  const clang::TargetOptions &mTargetOpts;
+
+  llvm::Module *mpModule;
+
+  // Output stream
+  llvm::raw_ostream *mpOS;
+  Slang::OutputType mOT;
+
+  // This helps us translate Clang AST using into LLVM IR
+  clang::CodeGenerator *mGen;
+
+  // Passes
+
+  // Passes apply on function scope in a translation unit
+  llvm::legacy::FunctionPassManager *mPerFunctionPasses;
+  // Passes apply on module scope
+  llvm::legacy::PassManager *mPerModulePasses;
+  // Passes for code emission
+  llvm::legacy::FunctionPassManager *mCodeGenPasses;
+
+  llvm::buffer_ostream mBufferOutStream;
+
+  void CreateFunctionPasses();
+  void CreateModulePasses();
+  bool CreateCodeGenPasses();
+
+  RSContext *mContext;
+
+  clang::SourceManager &mSourceMgr;
+
+  bool mASTPrint;
+
+  bool mAllowRSPrefix;
+
+  bool mIsFilterscript;
+
+  llvm::NamedMDNode *mExportVarMetadata;
+  llvm::NamedMDNode *mExportFuncMetadata;
+  llvm::NamedMDNode *mExportForEachNameMetadata;
+  llvm::NamedMDNode *mExportForEachSignatureMetadata;
+  llvm::NamedMDNode *mExportReduceMetadata;
+  llvm::NamedMDNode *mExportTypeMetadata;
+  llvm::NamedMDNode *mRSObjectSlotsMetadata;
+
+  RSObjectRefCount mRefCount;
+
+  RSCheckAST mASTChecker;
+
+  RSForEachLowering mForEachHandler;
+
+  void AnnotateFunction(clang::FunctionDecl *FD);
+
+  void dumpExportVarInfo(llvm::Module *M);
+  void dumpExportFunctionInfo(llvm::Module *M);
+  void dumpExportForEachInfo(llvm::Module *M);
+  void dumpExportReduceInfo(llvm::Module *M);
+  void dumpExportTypeInfo(llvm::Module *M);
+
+  // Translates any rsForEach() or rsForEachWithOptions() calls inside the body
+  // of FD to lower-level runtime calls to rsForEachInternal(), if FD is not a
+  // kernel function itself, as indicated by isKernel being false. If isKernel
+  // is true, reports an error on any calls to rsForEach() or
+  // rsForEachWithOptions().
+  void LowerRSForEachCall(clang::FunctionDecl* FD, bool isKernel);
+
+ protected:
+  llvm::LLVMContext &mLLVMContext;
+  clang::DiagnosticsEngine &mDiagEngine;
+  const clang::CodeGenOptions &mCodeGenOpts;
+
+  PragmaList *mPragmas;
+
+  unsigned int getTargetAPI() const { return mContext->getTargetAPI(); }
+
+  // TODO These are no longer virtual from base.  Look into merging into caller.
+
+  // This handler will be invoked before Clang translates @Ctx to LLVM IR. This
+  // give you an opportunity to modified the IR in AST level (scope information,
+  // unoptimized IR, etc.). After the return from this method, slang will start
+  // translate @Ctx into LLVM IR. One should not operate on @Ctx afterwards
+  // since the changes applied on that never reflects to the LLVM module used
+  // in the final codegen.
+  void HandleTranslationUnitPre(clang::ASTContext &Ctx);
+
+  // This handler will be invoked when Clang have converted AST tree to LLVM IR.
+  // The @M contains the resulting LLVM IR tree. After the return from this
+  // method, slang will start doing optimization and code generation for @M.
+  void HandleTranslationUnitPost(llvm::Module *M);
+
+ public:
+  Backend(RSContext *Context,
+            clang::DiagnosticsEngine *DiagEngine,
+            const RSCCOptions &Opts,
+            const clang::HeaderSearchOptions &HeaderSearchOpts,
+            const clang::PreprocessorOptions &PreprocessorOpts,
+            const clang::CodeGenOptions &CodeGenOpts,
+            const clang::TargetOptions &TargetOpts,
+            PragmaList *Pragmas,
+            llvm::raw_ostream *OS,
+            Slang::OutputType OT,
+            clang::SourceManager &SourceMgr,
+            bool AllowRSPrefix,
+            bool IsFilterscript);
+
+  virtual ~Backend();
+
+  // Initialize - This is called to initialize the consumer, providing the
+  // ASTContext.
+  void Initialize(clang::ASTContext &Ctx) override;
+
+  // TODO Clean up what should be private, protected
+  // TODO Also clean up the include files
+
+  // HandleTopLevelDecl - Handle the specified top-level declaration.  This is
+  // called by the parser to process every top-level Decl*. Note that D can be
+  // the head of a chain of Decls (e.g. for `int a, b` the chain will have two
+  // elements). Use Decl::getNextDeclarator() to walk the chain.
+  bool HandleTopLevelDecl(clang::DeclGroupRef D) override;
+
+  // HandleTranslationUnit - This method is called when the ASTs for entire
+  // translation unit have been parsed.
+  void HandleTranslationUnit(clang::ASTContext &Ctx) override;
+
+  // HandleTagDeclDefinition - This callback is invoked each time a TagDecl
+  // (e.g. struct, union, enum, class) is completed.  This allows the client to
+  // hack on the type, which can occur at any point in the file (because these
+  // can be defined in declspecs).
+  void HandleTagDeclDefinition(clang::TagDecl *D) override;
+
+  // CompleteTentativeDefinition - Callback invoked at the end of a translation
+  // unit to notify the consumer that the given tentative definition should be
+  // completed.
+  void CompleteTentativeDefinition(clang::VarDecl *D) override;
+};
+
+}   // namespace slang
+
+#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_BACKEND_H_  NOLINT
diff --git a/slang/slang_bitcode_gen.cpp b/slang/slang_bitcode_gen.cpp
new file mode 100644
index 0000000..dc0eb8d
--- /dev/null
+++ b/slang/slang_bitcode_gen.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+#include "bcinfo/BitcodeWrapper.h"
+
+#include "llvm/Support/raw_ostream.h"
+
+#include "BitWriter_2_9/ReaderWriter_2_9.h"
+#include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
+#include "BitWriter_3_2/ReaderWriter_3_2.h"
+
+#include "slang_assert.h"
+#include "slang_bitcode_gen.h"
+#include "slang_version.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+
+namespace slang {
+
+void writeBitcode(llvm::raw_ostream &Out,
+                  const llvm::Module &M,
+                  uint32_t TargetAPI,
+                  uint32_t OptimizationLevel,
+                  bool GenerateDebugInfo) {
+  std::string BitcodeStr;
+  llvm::raw_string_ostream Bitcode(BitcodeStr);
+
+  // The older bitcode writers will produce invalid bitcode if the -g
+  // flag is set using WriteBitcodeToFile. As such we use the ToT writer
+  // when -g is set. However, this will produce a bitcode file linked to
+  // this version of LLVM as the debug info format can change between
+  // versions.
+  // If bcc receives a bitcode file with a format of debug info
+  // which is either ahead or behind the version it is expecting it will
+  // fail the verification stage. Failing this stage results in the bitcode
+  // loader returning null and the compiler will terminate abruptly. Bitcode
+  // files with debug info are as such only capable of targeting devices with
+  // LLVM libraries with the same debug info version as the version of slang
+  // which was used to compile the file. This is due to the fact that LLVM
+  // offers no backwards or forwards compatibility guarantee for its debug
+  // bitcode. At the moment the only practical guarantee which can be made
+  // is that the debug bitcode emitted by any slang will work with the bcc
+  // version which was newest at the time when llvm-rs-cc was built.
+  if (GenerateDebugInfo) {
+    llvm::WriteBitcodeToFile(&M, Bitcode);
+  } else {
+    // Create the bitcode.
+    switch (TargetAPI) {
+    case SLANG_HC_TARGET_API:
+    case SLANG_HC_MR1_TARGET_API:
+    case SLANG_HC_MR2_TARGET_API: {
+      // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
+      llvm_2_9::WriteBitcodeToFile(&M, Bitcode);
+      break;
+    }
+    case SLANG_ICS_TARGET_API:
+    case SLANG_ICS_MR1_TARGET_API: {
+      // ICS targets must use the LLVM 2.9_func BitcodeWriter
+      llvm_2_9_func::WriteBitcodeToFile(&M, Bitcode);
+      break;
+    }
+    default: {
+      if (TargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
+          (TargetAPI < SLANG_MINIMUM_TARGET_API ||
+           TargetAPI > SLANG_MAXIMUM_TARGET_API)) {
+        slangAssert(false && "Invalid target API value");
+      }
+      // Switch to the 3.2 BitcodeWriter by default, and don't use
+      // LLVM's included BitcodeWriter at all (for now).
+      llvm_3_2::WriteBitcodeToFile(&M, Bitcode);
+      break;
+    }
+    }
+  }
+
+  const uint32_t CompilerVersion = SlangVersion::CURRENT;
+
+  // Create the bitcode wrapper.
+  bcinfo::AndroidBitcodeWrapper Wrapper;
+  size_t ActualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
+        &Wrapper, Bitcode.str().length(), TargetAPI,
+        CompilerVersion, OptimizationLevel);
+
+  slangAssert(ActualWrapperLen > 0);
+
+  // Write out the file.
+  Out.write(reinterpret_cast<char*>(&Wrapper), ActualWrapperLen);
+  Out << Bitcode.str();
+}
+
+}  // namespace slang
diff --git a/slang/slang_bitcode_gen.h b/slang/slang_bitcode_gen.h
new file mode 100644
index 0000000..b1f97c9
--- /dev/null
+++ b/slang/slang_bitcode_gen.h
@@ -0,0 +1,39 @@
+/*
+ * 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 _FRAMEWORKS_COMPILE_SLANG_SLANG_BITCODE_GEN_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_BITCODE_GEN_H_
+
+#include <cstdint>
+
+namespace llvm {
+  class raw_ostream;
+  class Module;
+}
+
+namespace slang {
+
+// Write out the LLVM bitcode for a module, encased in a wrapper
+// containing RS version information.
+void writeBitcode(llvm::raw_ostream &Out,
+                  const llvm::Module &M,
+                  uint32_t TargetAPI,
+                  uint32_t OptimizationLevel,
+                  bool GenerateDebugInfo);
+
+} // end namespace slang
+
+#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_BITCODE_GEN_H_  NOLINT
diff --git a/slang/slang_diagnostic_buffer.cpp b/slang/slang_diagnostic_buffer.cpp
new file mode 100644
index 0000000..d6afabf
--- /dev/null
+++ b/slang/slang_diagnostic_buffer.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010, 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 "slang_diagnostic_buffer.h"
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+
+#include "llvm/ADT/SmallString.h"
+
+#include "slang_assert.h"
+
+namespace slang {
+
+DiagnosticBuffer::DiagnosticBuffer()
+  : mSOS(new llvm::raw_string_ostream(mDiags)) {
+}
+
+DiagnosticBuffer::~DiagnosticBuffer() {
+}
+
+void DiagnosticBuffer::HandleDiagnostic(
+    clang::DiagnosticsEngine::Level DiagLevel,
+    clang::Diagnostic const &Info) {
+  clang::SourceLocation const &SrcLoc = Info.getLocation();
+
+  std::string Message;
+  llvm::raw_string_ostream stream(Message);
+
+  if (SrcLoc.isValid()) {
+    SrcLoc.print(stream, Info.getSourceManager());
+    stream << ": ";
+  }
+
+  switch (DiagLevel) {
+    case clang::DiagnosticsEngine::Note: {
+      stream << "note: ";
+      break;
+    }
+    case clang::DiagnosticsEngine::Warning: {
+      stream << "warning: ";
+      break;
+    }
+    case clang::DiagnosticsEngine::Error: {
+      stream << "error: ";
+      break;
+    }
+    case clang::DiagnosticsEngine::Fatal: {
+      stream << "fatal: ";
+      break;
+    }
+    default: {
+      slangAssert(0 && "Diagnostic not handled during diagnostic buffering!");
+    }
+  }
+  // 100 is enough for storing general diagnosis Message
+  llvm::SmallString<100> Buf;
+  Info.FormatDiagnostic(Buf);
+  stream << Buf.str() << '\n';
+  stream.flush();
+
+  if (mIncludedMessages.find(Message) == mIncludedMessages.end()) {
+    mIncludedMessages.insert(Message);
+    (*mSOS) << Message;
+  }
+}
+
+}  // namespace slang
diff --git a/slang/slang_diagnostic_buffer.h b/slang/slang_diagnostic_buffer.h
new file mode 100644
index 0000000..500f345
--- /dev/null
+++ b/slang/slang_diagnostic_buffer.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010, 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_SLANG_SLANG_DIAGNOSTIC_BUFFER_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_DIAGNOSTIC_BUFFER_H_
+
+#include <set>
+#include <string>
+
+#include "clang/Basic/Diagnostic.h"
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+  class raw_string_ostream;
+}
+
+namespace slang {
+
+// The diagnostics consumer instance (for reading the processed diagnostics)
+class DiagnosticBuffer : public clang::DiagnosticConsumer {
+private:
+  // We keed track of the messages that have been already added to this
+  // diagnostic buffer, to avoid duplicates.  This can happen because for a
+  // given script we'll usually compile for both 32 and 64 bit targets.
+  std::set<std::string> mIncludedMessages;
+  std::string mDiags;
+  std::unique_ptr<llvm::raw_string_ostream> mSOS;
+
+public:
+  DiagnosticBuffer();
+  virtual ~DiagnosticBuffer();
+
+  virtual void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
+                                const clang::Diagnostic &Info) override;
+
+  inline const std::string &str() const {
+    mSOS->flush();
+    return mDiags;
+  }
+
+  inline void reset() {
+    mIncludedMessages.clear();
+    mSOS.reset();
+    mDiags.clear();
+  }
+};
+
+}  // namespace slang
+
+#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_DIAGNOSTIC_BUFFER_H_  NOLINT
diff --git a/slang/slang_pragma_list.h b/slang/slang_pragma_list.h
new file mode 100644
index 0000000..a972b56
--- /dev/null
+++ b/slang/slang_pragma_list.h
@@ -0,0 +1,30 @@
+/*
+ * 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 _FRAMEWORKS_COMPILE_SLANG_SLANG_PRAGMA_LIST_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_PRAGMA_LIST_H_
+
+#include <list>
+#include <string>
+#include <utility>
+
+namespace slang {
+
+typedef std::list< std::pair<std::string, std::string> > PragmaList;
+
+}  // namespace slang
+
+#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_PRAGMA_LIST_H_  NOLINT
diff --git a/slang/slang_rs_ast_replace.cpp b/slang/slang_rs_ast_replace.cpp
new file mode 100644
index 0000000..92e1428
--- /dev/null
+++ b/slang/slang_rs_ast_replace.cpp
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+
+#include "slang_rs_ast_replace.h"
+
+#include "slang_assert.h"
+
+#include "llvm/Support/Casting.h"
+
+namespace slang {
+
+void RSASTReplace::ReplaceStmt(
+    clang::Stmt *OuterStmt,
+    clang::Stmt *OldStmt,
+    clang::Stmt *NewStmt) {
+  mOldStmt = OldStmt;
+  mNewStmt = NewStmt;
+  mOuterStmt = OuterStmt;
+
+  // This simplifies use in various Stmt visitor passes where the only
+  // valid type is an Expr.
+  mOldExpr = llvm::dyn_cast<clang::Expr>(OldStmt);
+  if (mOldExpr) {
+    mNewExpr = llvm::dyn_cast<clang::Expr>(NewStmt);
+  }
+  Visit(mOuterStmt);
+}
+
+void RSASTReplace::ReplaceInCompoundStmt(clang::CompoundStmt *CS) {
+  clang::Stmt **UpdatedStmtList = new clang::Stmt*[CS->size()];
+
+  unsigned UpdatedStmtCount = 0;
+  clang::CompoundStmt::body_iterator bI = CS->body_begin();
+  clang::CompoundStmt::body_iterator bE = CS->body_end();
+
+  for ( ; bI != bE; bI++) {
+    if (matchesStmt(*bI)) {
+      UpdatedStmtList[UpdatedStmtCount++] = mNewStmt;
+    } else {
+      UpdatedStmtList[UpdatedStmtCount++] = *bI;
+    }
+  }
+
+  CS->setStmts(C, llvm::makeArrayRef(UpdatedStmtList, UpdatedStmtCount));
+
+  delete [] UpdatedStmtList;
+}
+
+void RSASTReplace::VisitStmt(clang::Stmt *S) {
+  // This function does the actual iteration through all sub-Stmt's within
+  // a given Stmt. Note that this function is skipped by all of the other
+  // Visit* functions if we have already found a higher-level match.
+  for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end();
+       I != E;
+       I++) {
+    if (clang::Stmt *Child = *I) {
+      if (!matchesStmt(Child)) {
+        Visit(Child);
+      }
+    }
+  }
+}
+
+void RSASTReplace::VisitCompoundStmt(clang::CompoundStmt *CS) {
+  VisitStmt(CS);
+  ReplaceInCompoundStmt(CS);
+}
+
+void RSASTReplace::VisitCaseStmt(clang::CaseStmt *CS) {
+  if (matchesStmt(CS->getSubStmt())) {
+    CS->setSubStmt(mNewStmt);
+  } else {
+    VisitStmt(CS);
+  }
+}
+
+void RSASTReplace::VisitDeclStmt(clang::DeclStmt* DS) {
+  VisitStmt(DS);
+  for (clang::Decl* D : DS->decls()) {
+    clang::VarDecl* VD;
+    if ((VD = llvm::dyn_cast<clang::VarDecl>(D))) {
+      if (matchesExpr(VD->getInit())) {
+        VD->setInit(mNewExpr);
+      }
+    }
+  }
+}
+
+void RSASTReplace::VisitDefaultStmt(clang::DefaultStmt *DS) {
+  if (matchesStmt(DS->getSubStmt())) {
+    DS->setSubStmt(mNewStmt);
+  } else {
+    VisitStmt(DS);
+  }
+}
+
+void RSASTReplace::VisitDoStmt(clang::DoStmt *DS) {
+  if (matchesExpr(DS->getCond())) {
+    DS->setCond(mNewExpr);
+  } else if (matchesStmt(DS->getBody())) {
+    DS->setBody(mNewStmt);
+  } else {
+    VisitStmt(DS);
+  }
+}
+
+void RSASTReplace::VisitForStmt(clang::ForStmt *FS) {
+  if (matchesStmt(FS->getInit())) {
+    FS->setInit(mNewStmt);
+  } else if (matchesExpr(FS->getCond())) {
+    FS->setCond(mNewExpr);
+  } else if (matchesExpr(FS->getInc())) {
+    FS->setInc(mNewExpr);
+  } else if (matchesStmt(FS->getBody())) {
+    FS->setBody(mNewStmt);
+  } else {
+    VisitStmt(FS);
+  }
+}
+
+void RSASTReplace::VisitIfStmt(clang::IfStmt *IS) {
+  if (matchesExpr(IS->getCond())) {
+    IS->setCond(mNewExpr);
+  } else if (matchesStmt(IS->getThen())) {
+    IS->setThen(mNewStmt);
+  } else if (matchesStmt(IS->getElse())) {
+    IS->setElse(mNewStmt);
+  } else {
+    VisitStmt(IS);
+  }
+}
+
+void RSASTReplace::VisitSwitchCase(clang::SwitchCase *SC) {
+  slangAssert(false && "Both case and default have specialized handlers");
+  VisitStmt(SC);
+}
+
+void RSASTReplace::VisitSwitchStmt(clang::SwitchStmt *SS) {
+  if (matchesExpr(SS->getCond())) {
+    SS->setCond(mNewExpr);
+  } else {
+    VisitStmt(SS);
+  }
+}
+
+void RSASTReplace::VisitWhileStmt(clang::WhileStmt *WS) {
+  if (matchesExpr(WS->getCond())) {
+    WS->setCond(mNewExpr);
+  } else if (matchesStmt(WS->getBody())) {
+    WS->setBody(mNewStmt);
+  } else {
+    VisitStmt(WS);
+  }
+}
+
+}  // namespace slang
diff --git a/slang/slang_rs_ast_replace.h b/slang/slang_rs_ast_replace.h
new file mode 100644
index 0000000..58f9bd9
--- /dev/null
+++ b/slang/slang_rs_ast_replace.h
@@ -0,0 +1,89 @@
+/*
+ * 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 _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_AST_REPLACE_H_  // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_AST_REPLACE_H_
+
+#include "clang/AST/StmtVisitor.h"
+
+#include "slang_assert.h"
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+  class Diagnostic;
+  class Expr;
+  class Stmt;
+}
+
+namespace slang {
+
+class RSASTReplace : public clang::StmtVisitor<RSASTReplace> {
+ private:
+  const clang::ASTContext &C;
+  clang::Stmt *mOu