diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
new file mode 100644
index 0000000..77fb643
--- /dev/null
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -0,0 +1,1905 @@
+//===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineModuleInfo.h"
+
+#include "llvm/Constants.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Streams.h"
+using namespace llvm;
+using namespace llvm::dwarf;
+
+// Handle the Pass registration stuff necessary to use TargetData's.
+namespace {
+  RegisterPass<MachineModuleInfo> X("machinemoduleinfo", "Module Information");
+}
+char MachineModuleInfo::ID = 0;
+
+//===----------------------------------------------------------------------===//
+
+/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the
+/// specified value in their initializer somewhere.
+static void
+getGlobalVariablesUsing(Value *V, std::vector<GlobalVariable*> &Result) {
+  // Scan though value users.
+  for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
+    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I)) {
+      // If the user is a GlobalVariable then add to result.
+      Result.push_back(GV);
+    } else if (Constant *C = dyn_cast<Constant>(*I)) {
+      // If the user is a constant variable then scan its users
+      getGlobalVariablesUsing(C, Result);
+    }
+  }
+}
+
+/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
+/// named GlobalVariable.
+static std::vector<GlobalVariable*>
+getGlobalVariablesUsing(Module &M, const std::string &RootName) {
+  std::vector<GlobalVariable*> Result;  // GlobalVariables matching criteria.
+  
+  std::vector<const Type*> FieldTypes;
+  FieldTypes.push_back(Type::Int32Ty);
+  FieldTypes.push_back(Type::Int32Ty);
+
+  // Get the GlobalVariable root.
+  GlobalVariable *UseRoot = M.getGlobalVariable(RootName,
+                                                StructType::get(FieldTypes));
+
+  // If present and linkonce then scan for users.
+  if (UseRoot && UseRoot->hasLinkOnceLinkage()) {
+    getGlobalVariablesUsing(UseRoot, Result);
+  }
+  
+  return Result;
+}
+  
+/// isStringValue - Return true if the given value can be coerced to a string.
+///
+static bool isStringValue(Value *V) {
+  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
+    if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
+      ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
+      return Init->isString();
+    }
+  } else if (Constant *C = dyn_cast<Constant>(V)) {
+    if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
+      return isStringValue(GV);
+    else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+      if (CE->getOpcode() == Instruction::GetElementPtr) {
+        if (CE->getNumOperands() == 3 &&
+            cast<Constant>(CE->getOperand(1))->isNullValue() &&
+            isa<ConstantInt>(CE->getOperand(2))) {
+          return isStringValue(CE->getOperand(0));
+        }
+      }
+    }
+  }
+  return false;
+}
+
+/// getGlobalVariable - Return either a direct or cast Global value.
+///
+static GlobalVariable *getGlobalVariable(Value *V) {
+  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
+    return GV;
+  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+    if (CE->getOpcode() == Instruction::BitCast) {
+      return dyn_cast<GlobalVariable>(CE->getOperand(0));
+    }
+  }
+  return NULL;
+}
+
+/// isGlobalVariable - Return true if the given value can be coerced to a
+/// GlobalVariable.
+static bool isGlobalVariable(Value *V) {
+  if (isa<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) {
+    return true;
+  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+    if (CE->getOpcode() == Instruction::BitCast) {
+      return isa<GlobalVariable>(CE->getOperand(0));
+    }
+  }
+  return false;
+}
+
+/// getUIntOperand - Return ith operand if it is an unsigned integer.
+///
+static ConstantInt *getUIntOperand(GlobalVariable *GV, unsigned i) {
+  // Make sure the GlobalVariable has an initializer.
+  if (!GV->hasInitializer()) return NULL;
+  
+  // Get the initializer constant.
+  ConstantStruct *CI = dyn_cast<ConstantStruct>(GV->getInitializer());
+  if (!CI) return NULL;
+  
+  // Check if there is at least i + 1 operands.
+  unsigned N = CI->getNumOperands();
+  if (i >= N) return NULL;
+
+  // Check constant.
+  return dyn_cast<ConstantInt>(CI->getOperand(i));
+}
+
+//===----------------------------------------------------------------------===//
+
+/// ApplyToFields - Target the visitor to each field of the debug information
+/// descriptor.
+void DIVisitor::ApplyToFields(DebugInfoDesc *DD) {
+  DD->ApplyToFields(this);
+}
+
+//===----------------------------------------------------------------------===//
+/// DICountVisitor - This DIVisitor counts all the fields in the supplied debug
+/// the supplied DebugInfoDesc.
+class DICountVisitor : public DIVisitor {
+private:
+  unsigned Count;                       // Running count of fields.
+  
+public:
+  DICountVisitor() : DIVisitor(), Count(0) {}
+  
+  // Accessors.
+  unsigned getCount() const { return Count; }
+  
+  /// Apply - Count each of the fields.
+  ///
+  virtual void Apply(int &Field)             { ++Count; }
+  virtual void Apply(unsigned &Field)        { ++Count; }
+  virtual void Apply(int64_t &Field)         { ++Count; }
+  virtual void Apply(uint64_t &Field)        { ++Count; }
+  virtual void Apply(bool &Field)            { ++Count; }
+  virtual void Apply(std::string &Field)     { ++Count; }
+  virtual void Apply(DebugInfoDesc *&Field)  { ++Count; }
+  virtual void Apply(GlobalVariable *&Field) { ++Count; }
+  virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
+    ++Count;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// DIDeserializeVisitor - This DIVisitor deserializes all the fields in the
+/// supplied DebugInfoDesc.
+class DIDeserializeVisitor : public DIVisitor {
+private:
+  DIDeserializer &DR;                   // Active deserializer.
+  unsigned I;                           // Current operand index.
+  ConstantStruct *CI;                   // GlobalVariable constant initializer.
+
+public:
+  DIDeserializeVisitor(DIDeserializer &D, GlobalVariable *GV)
+  : DIVisitor()
+  , DR(D)
+  , I(0)
+  , CI(cast<ConstantStruct>(GV->getInitializer()))
+  {}
+  
+  /// Apply - Set the value of each of the fields.
+  ///
+  virtual void Apply(int &Field) {
+    Constant *C = CI->getOperand(I++);
+    Field = cast<ConstantInt>(C)->getSExtValue();
+  }
+  virtual void Apply(unsigned &Field) {
+    Constant *C = CI->getOperand(I++);
+    Field = cast<ConstantInt>(C)->getZExtValue();
+  }
+  virtual void Apply(int64_t &Field) {
+    Constant *C = CI->getOperand(I++);
+    Field = cast<ConstantInt>(C)->getSExtValue();
+  }
+  virtual void Apply(uint64_t &Field) {
+    Constant *C = CI->getOperand(I++);
+    Field = cast<ConstantInt>(C)->getZExtValue();
+  }
+  virtual void Apply(bool &Field) {
+    Constant *C = CI->getOperand(I++);
+    Field = cast<ConstantInt>(C)->getZExtValue();
+  }
+  virtual void Apply(std::string &Field) {
+    Constant *C = CI->getOperand(I++);
+    Field = C->getStringValue();
+  }
+  virtual void Apply(DebugInfoDesc *&Field) {
+    Constant *C = CI->getOperand(I++);
+    Field = DR.Deserialize(C);
+  }
+  virtual void Apply(GlobalVariable *&Field) {
+    Constant *C = CI->getOperand(I++);
+    Field = getGlobalVariable(C);
+  }
+  virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
+    Field.resize(0);
+    Constant *C = CI->getOperand(I++);
+    GlobalVariable *GV = getGlobalVariable(C);
+    if (GV->hasInitializer()) {
+      if (ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer())) {
+        for (unsigned i = 0, N = CA->getNumOperands(); i < N; ++i) {
+          GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i));
+          DebugInfoDesc *DE = DR.Deserialize(GVE);
+          Field.push_back(DE);
+        }
+      } else if (GV->getInitializer()->isNullValue()) {
+        if (const ArrayType *T =
+            dyn_cast<ArrayType>(GV->getType()->getElementType())) {
+          Field.resize(T->getNumElements());
+        }
+      }
+    }
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// DISerializeVisitor - This DIVisitor serializes all the fields in
+/// the supplied DebugInfoDesc.
+class DISerializeVisitor : public DIVisitor {
+private:
+  DISerializer &SR;                     // Active serializer.
+  std::vector<Constant*> &Elements;     // Element accumulator.
+  
+public:
+  DISerializeVisitor(DISerializer &S, std::vector<Constant*> &E)
+  : DIVisitor()
+  , SR(S)
+  , Elements(E)
+  {}
+  
+  /// Apply - Set the value of each of the fields.
+  ///
+  virtual void Apply(int &Field) {
+    Elements.push_back(ConstantInt::get(Type::Int32Ty, int32_t(Field)));
+  }
+  virtual void Apply(unsigned &Field) {
+    Elements.push_back(ConstantInt::get(Type::Int32Ty, uint32_t(Field)));
+  }
+  virtual void Apply(int64_t &Field) {
+    Elements.push_back(ConstantInt::get(Type::Int64Ty, int64_t(Field)));
+  }
+  virtual void Apply(uint64_t &Field) {
+    Elements.push_back(ConstantInt::get(Type::Int64Ty, uint64_t(Field)));
+  }
+  virtual void Apply(bool &Field) {
+    Elements.push_back(ConstantInt::get(Type::Int1Ty, Field));
+  }
+  virtual void Apply(std::string &Field) {
+      Elements.push_back(SR.getString(Field));
+  }
+  virtual void Apply(DebugInfoDesc *&Field) {
+    GlobalVariable *GV = NULL;
+    
+    // If non-NULL then convert to global.
+    if (Field) GV = SR.Serialize(Field);
+    
+    // FIXME - At some point should use specific type.
+    const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+    
+    if (GV) {
+      // Set to pointer to global.
+      Elements.push_back(ConstantExpr::getBitCast(GV, EmptyTy));
+    } else {
+      // Use NULL.
+      Elements.push_back(ConstantPointerNull::get(EmptyTy));
+    }
+  }
+  virtual void Apply(GlobalVariable *&Field) {
+    const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+    if (Field) {
+      Elements.push_back(ConstantExpr::getBitCast(Field, EmptyTy));
+    } else {
+      Elements.push_back(ConstantPointerNull::get(EmptyTy));
+    }
+  }
+  virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
+    const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+    unsigned N = Field.size();
+    ArrayType *AT = ArrayType::get(EmptyTy, N);
+    std::vector<Constant *> ArrayElements;
+
+    for (unsigned i = 0, N = Field.size(); i < N; ++i) {
+      if (DebugInfoDesc *Element = Field[i]) {
+        GlobalVariable *GVE = SR.Serialize(Element);
+        Constant *CE = ConstantExpr::getBitCast(GVE, EmptyTy);
+        ArrayElements.push_back(cast<Constant>(CE));
+      } else {
+        ArrayElements.push_back(ConstantPointerNull::get(EmptyTy));
+      }
+    }
+    
+    Constant *CA = ConstantArray::get(AT, ArrayElements);
+    GlobalVariable *CAGV = new GlobalVariable(AT, true,
+                                              GlobalValue::InternalLinkage,
+                                              CA, "llvm.dbg.array",
+                                              SR.getModule());
+    CAGV->setSection("llvm.metadata");
+    Constant *CAE = ConstantExpr::getBitCast(CAGV, EmptyTy);
+    Elements.push_back(CAE);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// DIGetTypesVisitor - This DIVisitor gathers all the field types in
+/// the supplied DebugInfoDesc.
+class DIGetTypesVisitor : public DIVisitor {
+private:
+  DISerializer &SR;                     // Active serializer.
+  std::vector<const Type*> &Fields;     // Type accumulator.
+  
+public:
+  DIGetTypesVisitor(DISerializer &S, std::vector<const Type*> &F)
+  : DIVisitor()
+  , SR(S)
+  , Fields(F)
+  {}
+  
+  /// Apply - Set the value of each of the fields.
+  ///
+  virtual void Apply(int &Field) {
+    Fields.push_back(Type::Int32Ty);
+  }
+  virtual void Apply(unsigned &Field) {
+    Fields.push_back(Type::Int32Ty);
+  }
+  virtual void Apply(int64_t &Field) {
+    Fields.push_back(Type::Int64Ty);
+  }
+  virtual void Apply(uint64_t &Field) {
+    Fields.push_back(Type::Int64Ty);
+  }
+  virtual void Apply(bool &Field) {
+    Fields.push_back(Type::Int1Ty);
+  }
+  virtual void Apply(std::string &Field) {
+    Fields.push_back(SR.getStrPtrType());
+  }
+  virtual void Apply(DebugInfoDesc *&Field) {
+    // FIXME - At some point should use specific type.
+    const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+    Fields.push_back(EmptyTy);
+  }
+  virtual void Apply(GlobalVariable *&Field) {
+    const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+    Fields.push_back(EmptyTy);
+  }
+  virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
+    const PointerType *EmptyTy = SR.getEmptyStructPtrType();
+    Fields.push_back(EmptyTy);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// DIVerifyVisitor - This DIVisitor verifies all the field types against
+/// a constant initializer.
+class DIVerifyVisitor : public DIVisitor {
+private:
+  DIVerifier &VR;                       // Active verifier.
+  bool IsValid;                         // Validity status.
+  unsigned I;                           // Current operand index.
+  ConstantStruct *CI;                   // GlobalVariable constant initializer.
+  
+public:
+  DIVerifyVisitor(DIVerifier &V, GlobalVariable *GV)
+  : DIVisitor()
+  , VR(V)
+  , IsValid(true)
+  , I(0)
+  , CI(cast<ConstantStruct>(GV->getInitializer()))
+  {
+  }
+  
+  // Accessors.
+  bool isValid() const { return IsValid; }
+  
+  /// Apply - Set the value of each of the fields.
+  ///
+  virtual void Apply(int &Field) {
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid && isa<ConstantInt>(C);
+  }
+  virtual void Apply(unsigned &Field) {
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid && isa<ConstantInt>(C);
+  }
+  virtual void Apply(int64_t &Field) {
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid && isa<ConstantInt>(C);
+  }
+  virtual void Apply(uint64_t &Field) {
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid && isa<ConstantInt>(C);
+  }
+  virtual void Apply(bool &Field) {
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid && isa<ConstantInt>(C) && C->getType() == Type::Int1Ty;
+  }
+  virtual void Apply(std::string &Field) {
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid &&
+              (!C || isStringValue(C) || C->isNullValue());
+  }
+  virtual void Apply(DebugInfoDesc *&Field) {
+    // FIXME - Prepare the correct descriptor.
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid && isGlobalVariable(C);
+  }
+  virtual void Apply(GlobalVariable *&Field) {
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid && isGlobalVariable(C);
+  }
+  virtual void Apply(std::vector<DebugInfoDesc *> &Field) {
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid && isGlobalVariable(C);
+    if (!IsValid) return;
+
+    GlobalVariable *GV = getGlobalVariable(C);
+    IsValid = IsValid && GV && GV->hasInitializer();
+    if (!IsValid) return;
+    
+    ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer());
+    IsValid = IsValid && CA;
+    if (!IsValid) return;
+
+    for (unsigned i = 0, N = CA->getNumOperands(); IsValid && i < N; ++i) {
+      IsValid = IsValid && isGlobalVariable(CA->getOperand(i));
+      if (!IsValid) return;
+    
+      GlobalVariable *GVE = getGlobalVariable(CA->getOperand(i));
+      VR.Verify(GVE);
+    }
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+
+/// TagFromGlobal - Returns the tag number from a debug info descriptor
+/// GlobalVariable.   Return DIIValid if operand is not an unsigned int. 
+unsigned DebugInfoDesc::TagFromGlobal(GlobalVariable *GV) {
+  ConstantInt *C = getUIntOperand(GV, 0);
+  return C ? ((unsigned)C->getZExtValue() & ~LLVMDebugVersionMask) :
+             (unsigned)DW_TAG_invalid;
+}
+
+/// VersionFromGlobal - Returns the version number from a debug info
+/// descriptor GlobalVariable.  Return DIIValid if operand is not an unsigned
+/// int.
+unsigned  DebugInfoDesc::VersionFromGlobal(GlobalVariable *GV) {
+  ConstantInt *C = getUIntOperand(GV, 0);
+  return C ? ((unsigned)C->getZExtValue() & LLVMDebugVersionMask) :
+             (unsigned)DW_TAG_invalid;
+}
+
+/// DescFactory - Create an instance of debug info descriptor based on Tag.
+/// Return NULL if not a recognized Tag.
+DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) {
+  switch (Tag) {
+  case DW_TAG_anchor:           return new AnchorDesc();
+  case DW_TAG_compile_unit:     return new CompileUnitDesc();
+  case DW_TAG_variable:         return new GlobalVariableDesc();
+  case DW_TAG_subprogram:       return new SubprogramDesc();
+  case DW_TAG_lexical_block:    return new BlockDesc();
+  case DW_TAG_base_type:        return new BasicTypeDesc();
+  case DW_TAG_typedef:
+  case DW_TAG_pointer_type:        
+  case DW_TAG_reference_type:
+  case DW_TAG_const_type:
+  case DW_TAG_volatile_type:        
+  case DW_TAG_restrict_type:
+  case DW_TAG_member:
+  case DW_TAG_inheritance:      return new DerivedTypeDesc(Tag);
+  case DW_TAG_array_type:
+  case DW_TAG_structure_type:
+  case DW_TAG_union_type:
+  case DW_TAG_enumeration_type:
+  case DW_TAG_vector_type:
+  case DW_TAG_subroutine_type:  return new CompositeTypeDesc(Tag);
+  case DW_TAG_subrange_type:    return new SubrangeDesc();
+  case DW_TAG_enumerator:       return new EnumeratorDesc();
+  case DW_TAG_return_variable:
+  case DW_TAG_arg_variable:
+  case DW_TAG_auto_variable:    return new VariableDesc(Tag);
+  default: break;
+  }
+  return NULL;
+}
+
+/// getLinkage - get linkage appropriate for this type of descriptor.
+///
+GlobalValue::LinkageTypes DebugInfoDesc::getLinkage() const {
+  return GlobalValue::InternalLinkage;
+}
+
+/// ApplyToFields - Target the vistor to the fields of the descriptor.
+///
+void DebugInfoDesc::ApplyToFields(DIVisitor *Visitor) {
+  Visitor->Apply(Tag);
+}
+
+//===----------------------------------------------------------------------===//
+
+AnchorDesc::AnchorDesc()
+: DebugInfoDesc(DW_TAG_anchor)
+, AnchorTag(0)
+{}
+AnchorDesc::AnchorDesc(AnchoredDesc *D)
+: DebugInfoDesc(DW_TAG_anchor)
+, AnchorTag(D->getTag())
+{}
+
+// Implement isa/cast/dyncast.
+bool AnchorDesc::classof(const DebugInfoDesc *D) {
+  return D->getTag() == DW_TAG_anchor;
+}
+  
+/// getLinkage - get linkage appropriate for this type of descriptor.
+///
+GlobalValue::LinkageTypes AnchorDesc::getLinkage() const {
+  return GlobalValue::LinkOnceLinkage;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the TransUnitDesc.
+///
+void AnchorDesc::ApplyToFields(DIVisitor *Visitor) {
+  DebugInfoDesc::ApplyToFields(Visitor);
+  
+  Visitor->Apply(AnchorTag);
+}
+
+/// getDescString - Return a string used to compose global names and labels. A
+/// A global variable name needs to be defined for each debug descriptor that is
+/// anchored. NOTE: that each global variable named here also needs to be added
+/// to the list of names left external in the internalizer.
+///   ExternalNames.insert("llvm.dbg.compile_units");
+///   ExternalNames.insert("llvm.dbg.global_variables");
+///   ExternalNames.insert("llvm.dbg.subprograms");
+const char *AnchorDesc::getDescString() const {
+  switch (AnchorTag) {
+  case DW_TAG_compile_unit: return CompileUnitDesc::AnchorString;
+  case DW_TAG_variable:     return GlobalVariableDesc::AnchorString;
+  case DW_TAG_subprogram:   return SubprogramDesc::AnchorString;
+  default: break;
+  }
+
+  assert(0 && "Tag does not have a case for anchor string");
+  return "";
+}
+
+/// getTypeString - Return a string used to label this descriptors type.
+///
+const char *AnchorDesc::getTypeString() const {
+  return "llvm.dbg.anchor.type";
+}
+
+#ifndef NDEBUG
+void AnchorDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "AnchorTag(" << AnchorTag << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+AnchoredDesc::AnchoredDesc(unsigned T)
+: DebugInfoDesc(T)
+, Anchor(NULL)
+{}
+
+/// ApplyToFields - Target the visitor to the fields of the AnchoredDesc.
+///
+void AnchoredDesc::ApplyToFields(DIVisitor *Visitor) {
+  DebugInfoDesc::ApplyToFields(Visitor);
+
+  Visitor->Apply(Anchor);
+}
+
+//===----------------------------------------------------------------------===//
+
+CompileUnitDesc::CompileUnitDesc()
+: AnchoredDesc(DW_TAG_compile_unit)
+, Language(0)
+, FileName("")
+, Directory("")
+, Producer("")
+{}
+
+// Implement isa/cast/dyncast.
+bool CompileUnitDesc::classof(const DebugInfoDesc *D) {
+  return D->getTag() == DW_TAG_compile_unit;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc.
+///
+void CompileUnitDesc::ApplyToFields(DIVisitor *Visitor) {
+  AnchoredDesc::ApplyToFields(Visitor);
+  
+  // Handle cases out of sync with compiler.
+  if (getVersion() == 0) {
+    unsigned DebugVersion;
+    Visitor->Apply(DebugVersion);
+  }
+
+  Visitor->Apply(Language);
+  Visitor->Apply(FileName);
+  Visitor->Apply(Directory);
+  Visitor->Apply(Producer);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *CompileUnitDesc::getDescString() const {
+  return "llvm.dbg.compile_unit";
+}
+
+/// getTypeString - Return a string used to label this descriptors type.
+///
+const char *CompileUnitDesc::getTypeString() const {
+  return "llvm.dbg.compile_unit.type";
+}
+
+/// getAnchorString - Return a string used to label this descriptor's anchor.
+///
+const char *CompileUnitDesc::AnchorString = "llvm.dbg.compile_units";
+const char *CompileUnitDesc::getAnchorString() const {
+  return AnchorString;
+}
+
+#ifndef NDEBUG
+void CompileUnitDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Anchor(" << getAnchor() << "), "
+       << "Language(" << Language << "), "
+       << "FileName(\"" << FileName << "\"), "
+       << "Directory(\"" << Directory << "\"), "
+       << "Producer(\"" << Producer << "\")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+TypeDesc::TypeDesc(unsigned T)
+: DebugInfoDesc(T)
+, Context(NULL)
+, Name("")
+, File(NULL)
+, Line(0)
+, Size(0)
+, Align(0)
+, Offset(0)
+, Flags(0)
+{}
+
+/// ApplyToFields - Target the visitor to the fields of the TypeDesc.
+///
+void TypeDesc::ApplyToFields(DIVisitor *Visitor) {
+  DebugInfoDesc::ApplyToFields(Visitor);
+  
+  Visitor->Apply(Context);
+  Visitor->Apply(Name);
+  Visitor->Apply(File);
+  Visitor->Apply(Line);
+  Visitor->Apply(Size);
+  Visitor->Apply(Align);
+  Visitor->Apply(Offset);
+  if (getVersion() > LLVMDebugVersion4) Visitor->Apply(Flags);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *TypeDesc::getDescString() const {
+  return "llvm.dbg.type";
+}
+
+/// getTypeString - Return a string used to label this descriptor's type.
+///
+const char *TypeDesc::getTypeString() const {
+  return "llvm.dbg.type.type";
+}
+
+#ifndef NDEBUG
+void TypeDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Context(" << Context << "), "
+       << "Name(\"" << Name << "\"), "
+       << "File(" << File << "), "
+       << "Line(" << Line << "), "
+       << "Size(" << Size << "), "
+       << "Align(" << Align << "), "
+       << "Offset(" << Offset << "), "
+       << "Flags(" << Flags << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+BasicTypeDesc::BasicTypeDesc()
+: TypeDesc(DW_TAG_base_type)
+, Encoding(0)
+{}
+
+// Implement isa/cast/dyncast.
+bool BasicTypeDesc::classof(const DebugInfoDesc *D) {
+  return D->getTag() == DW_TAG_base_type;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc.
+///
+void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) {
+  TypeDesc::ApplyToFields(Visitor);
+  
+  Visitor->Apply(Encoding);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *BasicTypeDesc::getDescString() const {
+  return "llvm.dbg.basictype";
+}
+
+/// getTypeString - Return a string used to label this descriptor's type.
+///
+const char *BasicTypeDesc::getTypeString() const {
+  return "llvm.dbg.basictype.type";
+}
+
+#ifndef NDEBUG
+void BasicTypeDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Context(" << getContext() << "), "
+       << "Name(\"" << getName() << "\"), "
+       << "Size(" << getSize() << "), "
+       << "Encoding(" << Encoding << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+DerivedTypeDesc::DerivedTypeDesc(unsigned T)
+: TypeDesc(T)
+, FromType(NULL)
+{}
+
+// Implement isa/cast/dyncast.
+bool DerivedTypeDesc::classof(const DebugInfoDesc *D) {
+  unsigned T =  D->getTag();
+  switch (T) {
+  case DW_TAG_typedef:
+  case DW_TAG_pointer_type:
+  case DW_TAG_reference_type:
+  case DW_TAG_const_type:
+  case DW_TAG_volatile_type:
+  case DW_TAG_restrict_type:
+  case DW_TAG_member:
+  case DW_TAG_inheritance:
+    return true;
+  default: break;
+  }
+  return false;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc.
+///
+void DerivedTypeDesc::ApplyToFields(DIVisitor *Visitor) {
+  TypeDesc::ApplyToFields(Visitor);
+  
+  Visitor->Apply(FromType);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *DerivedTypeDesc::getDescString() const {
+  return "llvm.dbg.derivedtype";
+}
+
+/// getTypeString - Return a string used to label this descriptor's type.
+///
+const char *DerivedTypeDesc::getTypeString() const {
+  return "llvm.dbg.derivedtype.type";
+}
+
+#ifndef NDEBUG
+void DerivedTypeDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Context(" << getContext() << "), "
+       << "Name(\"" << getName() << "\"), "
+       << "Size(" << getSize() << "), "
+       << "File(" << getFile() << "), "
+       << "Line(" << getLine() << "), "
+       << "FromType(" << FromType << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+CompositeTypeDesc::CompositeTypeDesc(unsigned T)
+: DerivedTypeDesc(T)
+, Elements()
+{}
+  
+// Implement isa/cast/dyncast.
+bool CompositeTypeDesc::classof(const DebugInfoDesc *D) {
+  unsigned T =  D->getTag();
+  switch (T) {
+  case DW_TAG_array_type:
+  case DW_TAG_structure_type:
+  case DW_TAG_union_type:
+  case DW_TAG_enumeration_type:
+  case DW_TAG_vector_type:
+  case DW_TAG_subroutine_type:
+    return true;
+  default: break;
+  }
+  return false;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc.
+///
+void CompositeTypeDesc::ApplyToFields(DIVisitor *Visitor) {
+  DerivedTypeDesc::ApplyToFields(Visitor);  
+
+  Visitor->Apply(Elements);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *CompositeTypeDesc::getDescString() const {
+  return "llvm.dbg.compositetype";
+}
+
+/// getTypeString - Return a string used to label this descriptor's type.
+///
+const char *CompositeTypeDesc::getTypeString() const {
+  return "llvm.dbg.compositetype.type";
+}
+
+#ifndef NDEBUG
+void CompositeTypeDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Context(" << getContext() << "), "
+       << "Name(\"" << getName() << "\"), "
+       << "Size(" << getSize() << "), "
+       << "File(" << getFile() << "), "
+       << "Line(" << getLine() << "), "
+       << "FromType(" << getFromType() << "), "
+       << "Elements.size(" << Elements.size() << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+SubrangeDesc::SubrangeDesc()
+: DebugInfoDesc(DW_TAG_subrange_type)
+, Lo(0)
+, Hi(0)
+{}
+
+// Implement isa/cast/dyncast.
+bool SubrangeDesc::classof(const DebugInfoDesc *D) {
+  return D->getTag() == DW_TAG_subrange_type;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the SubrangeDesc.
+///
+void SubrangeDesc::ApplyToFields(DIVisitor *Visitor) {
+  DebugInfoDesc::ApplyToFields(Visitor);
+
+  Visitor->Apply(Lo);
+  Visitor->Apply(Hi);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *SubrangeDesc::getDescString() const {
+  return "llvm.dbg.subrange";
+}
+  
+/// getTypeString - Return a string used to label this descriptor's type.
+///
+const char *SubrangeDesc::getTypeString() const {
+  return "llvm.dbg.subrange.type";
+}
+
+#ifndef NDEBUG
+void SubrangeDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Lo(" << Lo << "), "
+       << "Hi(" << Hi << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+EnumeratorDesc::EnumeratorDesc()
+: DebugInfoDesc(DW_TAG_enumerator)
+, Name("")
+, Value(0)
+{}
+
+// Implement isa/cast/dyncast.
+bool EnumeratorDesc::classof(const DebugInfoDesc *D) {
+  return D->getTag() == DW_TAG_enumerator;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc.
+///
+void EnumeratorDesc::ApplyToFields(DIVisitor *Visitor) {
+  DebugInfoDesc::ApplyToFields(Visitor);
+
+  Visitor->Apply(Name);
+  Visitor->Apply(Value);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *EnumeratorDesc::getDescString() const {
+  return "llvm.dbg.enumerator";
+}
+  
+/// getTypeString - Return a string used to label this descriptor's type.
+///
+const char *EnumeratorDesc::getTypeString() const {
+  return "llvm.dbg.enumerator.type";
+}
+
+#ifndef NDEBUG
+void EnumeratorDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Name(" << Name << "), "
+       << "Value(" << Value << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+VariableDesc::VariableDesc(unsigned T)
+: DebugInfoDesc(T)
+, Context(NULL)
+, Name("")
+, File(NULL)
+, Line(0)
+, TyDesc(0)
+{}
+
+// Implement isa/cast/dyncast.
+bool VariableDesc::classof(const DebugInfoDesc *D) {
+  unsigned T =  D->getTag();
+  switch (T) {
+  case DW_TAG_auto_variable:
+  case DW_TAG_arg_variable:
+  case DW_TAG_return_variable:
+    return true;
+  default: break;
+  }
+  return false;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the VariableDesc.
+///
+void VariableDesc::ApplyToFields(DIVisitor *Visitor) {
+  DebugInfoDesc::ApplyToFields(Visitor);
+  
+  Visitor->Apply(Context);
+  Visitor->Apply(Name);
+  Visitor->Apply(File);
+  Visitor->Apply(Line);
+  Visitor->Apply(TyDesc);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *VariableDesc::getDescString() const {
+  return "llvm.dbg.variable";
+}
+
+/// getTypeString - Return a string used to label this descriptor's type.
+///
+const char *VariableDesc::getTypeString() const {
+  return "llvm.dbg.variable.type";
+}
+
+#ifndef NDEBUG
+void VariableDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Context(" << Context << "), "
+       << "Name(\"" << Name << "\"), "
+       << "File(" << File << "), "
+       << "Line(" << Line << "), "
+       << "TyDesc(" << TyDesc << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+GlobalDesc::GlobalDesc(unsigned T)
+: AnchoredDesc(T)
+, Context(0)
+, Name("")
+, FullName("")
+, LinkageName("")
+, File(NULL)
+, Line(0)
+, TyDesc(NULL)
+, IsStatic(false)
+, IsDefinition(false)
+{}
+
+/// ApplyToFields - Target the visitor to the fields of the global.
+///
+void GlobalDesc::ApplyToFields(DIVisitor *Visitor) {
+  AnchoredDesc::ApplyToFields(Visitor);
+
+  Visitor->Apply(Context);
+  Visitor->Apply(Name);
+  Visitor->Apply(FullName);
+  Visitor->Apply(LinkageName);
+  Visitor->Apply(File);
+  Visitor->Apply(Line);
+  Visitor->Apply(TyDesc);
+  Visitor->Apply(IsStatic);
+  Visitor->Apply(IsDefinition);
+}
+
+//===----------------------------------------------------------------------===//
+
+GlobalVariableDesc::GlobalVariableDesc()
+: GlobalDesc(DW_TAG_variable)
+, Global(NULL)
+{}
+
+// Implement isa/cast/dyncast.
+bool GlobalVariableDesc::classof(const DebugInfoDesc *D) {
+  return D->getTag() == DW_TAG_variable; 
+}
+
+/// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc.
+///
+void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) {
+  GlobalDesc::ApplyToFields(Visitor);
+
+  Visitor->Apply(Global);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *GlobalVariableDesc::getDescString() const {
+  return "llvm.dbg.global_variable";
+}
+
+/// getTypeString - Return a string used to label this descriptors type.
+///
+const char *GlobalVariableDesc::getTypeString() const {
+  return "llvm.dbg.global_variable.type";
+}
+
+/// getAnchorString - Return a string used to label this descriptor's anchor.
+///
+const char *GlobalVariableDesc::AnchorString = "llvm.dbg.global_variables";
+const char *GlobalVariableDesc::getAnchorString() const {
+  return AnchorString;
+}
+
+#ifndef NDEBUG
+void GlobalVariableDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Anchor(" << getAnchor() << "), "
+       << "Name(\"" << getName() << "\"), "
+       << "FullName(\"" << getFullName() << "\"), "
+       << "LinkageName(\"" << getLinkageName() << "\"), "
+       << "File(" << getFile() << "),"
+       << "Line(" << getLine() << "),"
+       << "Type(" << getType() << "), "
+       << "IsStatic(" << (isStatic() ? "true" : "false") << "), "
+       << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), "
+       << "Global(" << Global << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+SubprogramDesc::SubprogramDesc()
+: GlobalDesc(DW_TAG_subprogram)
+{}
+
+// Implement isa/cast/dyncast.
+bool SubprogramDesc::classof(const DebugInfoDesc *D) {
+  return D->getTag() == DW_TAG_subprogram;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the
+/// SubprogramDesc.
+void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) {
+  GlobalDesc::ApplyToFields(Visitor);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *SubprogramDesc::getDescString() const {
+  return "llvm.dbg.subprogram";
+}
+
+/// getTypeString - Return a string used to label this descriptors type.
+///
+const char *SubprogramDesc::getTypeString() const {
+  return "llvm.dbg.subprogram.type";
+}
+
+/// getAnchorString - Return a string used to label this descriptor's anchor.
+///
+const char *SubprogramDesc::AnchorString = "llvm.dbg.subprograms";
+const char *SubprogramDesc::getAnchorString() const {
+  return AnchorString;
+}
+
+#ifndef NDEBUG
+void SubprogramDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "), "
+       << "Anchor(" << getAnchor() << "), "
+       << "Name(\"" << getName() << "\"), "
+       << "FullName(\"" << getFullName() << "\"), "
+       << "LinkageName(\"" << getLinkageName() << "\"), "
+       << "File(" << getFile() << "),"
+       << "Line(" << getLine() << "),"
+       << "Type(" << getType() << "), "
+       << "IsStatic(" << (isStatic() ? "true" : "false") << "), "
+       << "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+BlockDesc::BlockDesc()
+: DebugInfoDesc(DW_TAG_lexical_block)
+, Context(NULL)
+{}
+
+// Implement isa/cast/dyncast.
+bool BlockDesc::classof(const DebugInfoDesc *D) {
+  return D->getTag() == DW_TAG_lexical_block;
+}
+
+/// ApplyToFields - Target the visitor to the fields of the BlockDesc.
+///
+void BlockDesc::ApplyToFields(DIVisitor *Visitor) {
+  DebugInfoDesc::ApplyToFields(Visitor);
+
+  Visitor->Apply(Context);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *BlockDesc::getDescString() const {
+  return "llvm.dbg.block";
+}
+
+/// getTypeString - Return a string used to label this descriptors type.
+///
+const char *BlockDesc::getTypeString() const {
+  return "llvm.dbg.block.type";
+}
+
+#ifndef NDEBUG
+void BlockDesc::dump() {
+  cerr << getDescString() << " "
+       << "Version(" << getVersion() << "), "
+       << "Tag(" << getTag() << "),"
+       << "Context(" << Context << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+DebugInfoDesc *DIDeserializer::Deserialize(Value *V) {
+  return Deserialize(getGlobalVariable(V));
+}
+DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) {
+  // Handle NULL.
+  if (!GV) return NULL;
+
+  // Check to see if it has been already deserialized.
+  DebugInfoDesc *&Slot = GlobalDescs[GV];
+  if (Slot) return Slot;
+
+  // Get the Tag from the global.
+  unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
+  
+  // Create an empty instance of the correct sort.
+  Slot = DebugInfoDesc::DescFactory(Tag);
+  
+  // If not a user defined descriptor.
+  if (Slot) {
+    // Deserialize the fields.
+    DIDeserializeVisitor DRAM(*this, GV);
+    DRAM.ApplyToFields(Slot);
+  }
+  
+  return Slot;
+}
+
+//===----------------------------------------------------------------------===//
+
+/// getStrPtrType - Return a "sbyte *" type.
+///
+const PointerType *DISerializer::getStrPtrType() {
+  // If not already defined.
+  if (!StrPtrTy) {
+    // Construct the pointer to signed bytes.
+    StrPtrTy = PointerType::get(Type::Int8Ty);
+  }
+  
+  return StrPtrTy;
+}
+
+/// getEmptyStructPtrType - Return a "{ }*" type.
+///
+const PointerType *DISerializer::getEmptyStructPtrType() {
+  // If not already defined.
+  if (!EmptyStructPtrTy) {
+    // Construct the empty structure type.
+    const StructType *EmptyStructTy =
+                                    StructType::get(std::vector<const Type*>());
+    // Construct the pointer to empty structure type.
+    EmptyStructPtrTy = PointerType::get(EmptyStructTy);
+  }
+  
+  return EmptyStructPtrTy;
+}
+
+/// getTagType - Return the type describing the specified descriptor (via tag.)
+///
+const StructType *DISerializer::getTagType(DebugInfoDesc *DD) {
+  // Attempt to get the previously defined type.
+  StructType *&Ty = TagTypes[DD->getTag()];
+  
+  // If not already defined.
+  if (!Ty) {
+    // Set up fields vector.
+    std::vector<const Type*> Fields;
+    // Get types of fields.
+    DIGetTypesVisitor GTAM(*this, Fields);
+    GTAM.ApplyToFields(DD);
+
+    // Construct structured type.
+    Ty = StructType::get(Fields);
+    
+    // Register type name with module.
+    M->addTypeName(DD->getTypeString(), Ty);
+  }
+  
+  return Ty;
+}
+
+/// getString - Construct the string as constant string global.
+///
+Constant *DISerializer::getString(const std::string &String) {
+  // Check string cache for previous edition.
+  Constant *&Slot = StringCache[String];
+  // Return Constant if previously defined.
+  if (Slot) return Slot;
+  // If empty string then use a sbyte* null instead.
+  if (String.empty()) {
+    Slot = ConstantPointerNull::get(getStrPtrType());
+  } else {
+    // Construct string as an llvm constant.
+    Constant *ConstStr = ConstantArray::get(String);
+    // Otherwise create and return a new string global.
+    GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true,
+                                               GlobalVariable::InternalLinkage,
+                                               ConstStr, ".str", M);
+    StrGV->setSection("llvm.metadata");
+    // Convert to generic string pointer.
+    Slot = ConstantExpr::getBitCast(StrGV, getStrPtrType());
+  }
+  return Slot;
+  
+}
+
+/// Serialize - Recursively cast the specified descriptor into a GlobalVariable
+/// so that it can be serialized to a .bc or .ll file.
+GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) {
+  // Check if the DebugInfoDesc is already in the map.
+  GlobalVariable *&Slot = DescGlobals[DD];
+  
+  // See if DebugInfoDesc exists, if so return prior GlobalVariable.
+  if (Slot) return Slot;
+  
+  // Get the type associated with the Tag.
+  const StructType *Ty = getTagType(DD);
+
+  // Create the GlobalVariable early to prevent infinite recursion.
+  GlobalVariable *GV = new GlobalVariable(Ty, true, DD->getLinkage(),
+                                          NULL, DD->getDescString(), M);
+  GV->setSection("llvm.metadata");
+
+  // Insert new GlobalVariable in DescGlobals map.
+  Slot = GV;
+ 
+  // Set up elements vector
+  std::vector<Constant*> Elements;
+  // Add fields.
+  DISerializeVisitor SRAM(*this, Elements);
+  SRAM.ApplyToFields(DD);
+  
+  // Set the globals initializer.
+  GV->setInitializer(ConstantStruct::get(Ty, Elements));
+  
+  return GV;
+}
+
+//===----------------------------------------------------------------------===//
+
+/// Verify - Return true if the GlobalVariable appears to be a valid
+/// serialization of a DebugInfoDesc.
+bool DIVerifier::Verify(Value *V) {
+  return !V || Verify(getGlobalVariable(V));
+}
+bool DIVerifier::Verify(GlobalVariable *GV) {
+  // NULLs are valid.
+  if (!GV) return true;
+  
+  // Check prior validity.
+  unsigned &ValiditySlot = Validity[GV];
+  
+  // If visited before then use old state.
+  if (ValiditySlot) return ValiditySlot == Valid;
+  
+  // Assume validity for the time being (recursion.)
+  ValiditySlot = Valid;
+  
+  // Make sure the global is internal or link once (anchor.)
+  if (GV->getLinkage() != GlobalValue::InternalLinkage &&
+      GV->getLinkage() != GlobalValue::LinkOnceLinkage) {
+    ValiditySlot = Invalid;
+    return false;
+  }
+
+  // Get the Tag.
+  unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
+  
+  // Check for user defined descriptors.
+  if (Tag == DW_TAG_invalid) {
+    ValiditySlot = Valid;
+    return true;
+  }
+  
+  // Get the Version.
+  unsigned Version = DebugInfoDesc::VersionFromGlobal(GV);
+  
+  // Check for version mismatch.
+  if (Version != LLVMDebugVersion) {
+    ValiditySlot = Invalid;
+    return false;
+  }
+
+  // Construct an empty DebugInfoDesc.
+  DebugInfoDesc *DD = DebugInfoDesc::DescFactory(Tag);
+  
+  // Allow for user defined descriptors.
+  if (!DD) return true;
+  
+  // Get the initializer constant.
+  ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
+  
+  // Get the operand count.
+  unsigned N = CI->getNumOperands();
+  
+  // Get the field count.
+  unsigned &CountSlot = Counts[Tag];
+  if (!CountSlot) {
+    // Check the operand count to the field count
+    DICountVisitor CTAM;
+    CTAM.ApplyToFields(DD);
+    CountSlot = CTAM.getCount();
+  }
+  
+  // Field count must be at most equal operand count.
+  if (CountSlot >  N) {
+    delete DD;
+    ValiditySlot = Invalid;
+    return false;
+  }
+  
+  // Check each field for valid type.
+  DIVerifyVisitor VRAM(*this, GV);
+  VRAM.ApplyToFields(DD);
+  
+  // Release empty DebugInfoDesc.
+  delete DD;
+  
+  // If fields are not valid.
+  if (!VRAM.isValid()) {
+    ValiditySlot = Invalid;
+    return false;
+  }
+  
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
+
+DebugScope::~DebugScope() {
+  for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i];
+  for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j];
+}
+
+//===----------------------------------------------------------------------===//
+
+MachineModuleInfo::MachineModuleInfo()
+: ImmutablePass((intptr_t)&ID)
+, DR()
+, VR()
+, CompileUnits()
+, Directories()
+, SourceFiles()
+, Lines()
+, LabelIDList()
+, ScopeMap()
+, RootScope(NULL)
+, FrameMoves()
+, LandingPads()
+, Personalities()
+, CallsEHReturn(0)
+, CallsUnwindInit(0)
+{
+  // Always emit "no personality" info
+  Personalities.push_back(NULL);
+}
+MachineModuleInfo::~MachineModuleInfo() {
+
+}
+
+/// doInitialization - Initialize the state for a new module.
+///
+bool MachineModuleInfo::doInitialization() {
+  return false;
+}
+
+/// doFinalization - Tear down the state after completion of a module.
+///
+bool MachineModuleInfo::doFinalization() {
+  return false;
+}
+
+/// BeginFunction - Begin gathering function meta information.
+///
+void MachineModuleInfo::BeginFunction(MachineFunction *MF) {
+  // Coming soon.
+}
+
+/// EndFunction - Discard function meta information.
+///
+void MachineModuleInfo::EndFunction() {
+  // Clean up scope information.
+  if (RootScope) {
+    delete RootScope;
+    ScopeMap.clear();
+    RootScope = NULL;
+  }
+  
+  // Clean up line info.
+  Lines.clear();
+
+  // Clean up frame info.
+  FrameMoves.clear();
+  
+  // Clean up exception info.
+  LandingPads.clear();
+  TypeInfos.clear();
+  FilterIds.clear();
+  FilterEnds.clear();
+  CallsEHReturn = 0;
+  CallsUnwindInit = 0;
+}
+
+/// getDescFor - Convert a Value to a debug information descriptor.
+///
+// FIXME - use new Value type when available.
+DebugInfoDesc *MachineModuleInfo::getDescFor(Value *V) {
+  return DR.Deserialize(V);
+}
+
+/// Verify - Verify that a Value is debug information descriptor.
+///
+bool MachineModuleInfo::Verify(Value *V) {
+  return VR.Verify(V);
+}
+
+/// AnalyzeModule - Scan the module for global debug information.
+///
+void MachineModuleInfo::AnalyzeModule(Module &M) {
+  SetupCompileUnits(M);
+}
+
+/// needsFrameInfo - Returns true if we need to gather callee-saved register
+/// move info for the frame.
+bool MachineModuleInfo::needsFrameInfo() const {
+  return hasDebugInfo() || ExceptionHandling;
+}
+
+/// SetupCompileUnits - Set up the unique vector of compile units.
+///
+void MachineModuleInfo::SetupCompileUnits(Module &M) {
+  std::vector<CompileUnitDesc *>CU = getAnchoredDescriptors<CompileUnitDesc>(M);
+  
+  for (unsigned i = 0, N = CU.size(); i < N; i++) {
+    CompileUnits.insert(CU[i]);
+  }
+}
+
+/// getCompileUnits - Return a vector of debug compile units.
+///
+const UniqueVector<CompileUnitDesc *> MachineModuleInfo::getCompileUnits()const{
+  return CompileUnits;
+}
+
+/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
+/// named GlobalVariable.
+std::vector<GlobalVariable*>
+MachineModuleInfo::getGlobalVariablesUsing(Module &M,
+                                           const std::string &RootName) {
+  return ::getGlobalVariablesUsing(M, RootName);
+}
+
+/// RecordLabel - Records location information and associates it with a
+/// debug label.  Returns a unique label ID used to generate a label and 
+/// provide correspondence to the source line list.
+unsigned MachineModuleInfo::RecordLabel(unsigned Line, unsigned Column,
+                                       unsigned Source) {
+  unsigned ID = NextLabelID();
+  Lines.push_back(SourceLineInfo(Line, Column, Source, ID));
+  return ID;
+}
+
+/// RecordSource - Register a source file with debug info. Returns an source
+/// ID.
+unsigned MachineModuleInfo::RecordSource(const std::string &Directory,
+                                         const std::string &Source) {
+  unsigned DirectoryID = Directories.insert(Directory);
+  return SourceFiles.insert(SourceFileInfo(DirectoryID, Source));
+}
+unsigned MachineModuleInfo::RecordSource(const CompileUnitDesc *CompileUnit) {
+  return RecordSource(CompileUnit->getDirectory(),
+                      CompileUnit->getFileName());
+}
+
+/// RecordRegionStart - Indicate the start of a region.
+///
+unsigned MachineModuleInfo::RecordRegionStart(Value *V) {
+  // FIXME - need to be able to handle split scopes because of bb cloning.
+  DebugInfoDesc *ScopeDesc = DR.Deserialize(V);
+  DebugScope *Scope = getOrCreateScope(ScopeDesc);
+  unsigned ID = NextLabelID();
+  if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID);
+  return ID;
+}
+
+/// RecordRegionEnd - Indicate the end of a region.
+///
+unsigned MachineModuleInfo::RecordRegionEnd(Value *V) {
+  // FIXME - need to be able to handle split scopes because of bb cloning.
+  DebugInfoDesc *ScopeDesc = DR.Deserialize(V);
+  DebugScope *Scope = getOrCreateScope(ScopeDesc);
+  unsigned ID = NextLabelID();
+  Scope->setEndLabelID(ID);
+  return ID;
+}
+
+/// RecordVariable - Indicate the declaration of  a local variable.
+///
+void MachineModuleInfo::RecordVariable(Value *V, unsigned FrameIndex) {
+  VariableDesc *VD = cast<VariableDesc>(DR.Deserialize(V));
+  DebugScope *Scope = getOrCreateScope(VD->getContext());
+  DebugVariable *DV = new DebugVariable(VD, FrameIndex);
+  Scope->AddVariable(DV);
+}
+
+/// getOrCreateScope - Returns the scope associated with the given descriptor.
+///
+DebugScope *MachineModuleInfo::getOrCreateScope(DebugInfoDesc *ScopeDesc) {
+  DebugScope *&Slot = ScopeMap[ScopeDesc];
+  if (!Slot) {
+    // FIXME - breaks down when the context is an inlined function.
+    DebugInfoDesc *ParentDesc = NULL;
+    if (BlockDesc *Block = dyn_cast<BlockDesc>(ScopeDesc)) {
+      ParentDesc = Block->getContext();
+    }
+    DebugScope *Parent = ParentDesc ? getOrCreateScope(ParentDesc) : NULL;
+    Slot = new DebugScope(Parent, ScopeDesc);
+    if (Parent) {
+      Parent->AddScope(Slot);
+    } else if (RootScope) {
+      // FIXME - Add inlined function scopes to the root so we can delete
+      // them later.  Long term, handle inlined functions properly.
+      RootScope->AddScope(Slot);
+    } else {
+      // First function is top level function.
+      RootScope = Slot;
+    }
+  }
+  return Slot;
+}
+
+//===-EH-------------------------------------------------------------------===//
+
+/// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
+/// specified MachineBasicBlock.
+LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
+    (MachineBasicBlock *LandingPad) {
+  unsigned N = LandingPads.size();
+  for (unsigned i = 0; i < N; ++i) {
+    LandingPadInfo &LP = LandingPads[i];
+    if (LP.LandingPadBlock == LandingPad)
+      return LP;
+  }
+  
+  LandingPads.push_back(LandingPadInfo(LandingPad));
+  return LandingPads[N];
+}
+
+/// addInvoke - Provide the begin and end labels of an invoke style call and
+/// associate it with a try landing pad block.
+void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
+                                  unsigned BeginLabel, unsigned EndLabel) {
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  LP.BeginLabels.push_back(BeginLabel);
+  LP.EndLabels.push_back(EndLabel);
+}
+
+/// addLandingPad - Provide the label of a try LandingPad block.
+///
+unsigned MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
+  unsigned LandingPadLabel = NextLabelID();
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  LP.LandingPadLabel = LandingPadLabel;  
+  return LandingPadLabel;
+}
+
+/// addPersonality - Provide the personality function for the exception
+/// information.
+void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
+                                       Function *Personality) {
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  LP.Personality = Personality;
+
+  for (unsigned i = 0; i < Personalities.size(); ++i)
+    if (Personalities[i] == Personality)
+      return;
+  
+  Personalities.push_back(Personality);
+}
+
+/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
+///
+void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad,
+                                        std::vector<GlobalVariable *> &TyInfo) {
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  for (unsigned N = TyInfo.size(); N; --N)
+    LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
+}
+
+/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
+///
+void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad,
+                                        std::vector<GlobalVariable *> &TyInfo) {
+  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+  std::vector<unsigned> IdsInFilter (TyInfo.size());
+  for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
+    IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
+  LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
+}
+
+/// TidyLandingPads - Remap landing pad labels and remove any deleted landing
+/// pads.
+void MachineModuleInfo::TidyLandingPads() {
+  for (unsigned i = 0; i != LandingPads.size(); ) {
+    LandingPadInfo &LandingPad = LandingPads[i];
+    LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
+
+    if (!LandingPad.LandingPadBlock)
+      // Must not have cleanups if no landing pad.
+      LandingPad.TypeIds.clear();
+
+    // Special case: we *should* emit LPs with null LP MBB. This indicates
+    // "rethrow" case.
+    if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
+      LandingPads.erase(LandingPads.begin() + i);
+      continue;
+    }
+          
+    for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) {
+      unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]);
+      unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]);
+            
+          
+      if (!BeginLabel || !EndLabel) {
+        LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
+        LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
+        continue;
+      }
+
+      LandingPad.BeginLabels[j] = BeginLabel;
+      LandingPad.EndLabels[j] = EndLabel;
+      ++j;
+    }
+    
+    ++i;
+  }
+}
+
+/// getTypeIDFor - Return the type id for the specified typeinfo.  This is 
+/// function wide.
+unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
+  for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
+    if (TypeInfos[i] == TI) return i + 1;
+
+  TypeInfos.push_back(TI);
+  return TypeInfos.size();
+}
+
+/// getFilterIDFor - Return the filter id for the specified typeinfos.  This is
+/// function wide.
+int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
+  // If the new filter coincides with the tail of an existing filter, then
+  // re-use the existing filter.  Folding filters more than this requires
+  // re-ordering filters and/or their elements - probably not worth it.
+  for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
+       E = FilterEnds.end(); I != E; ++I) {
+    unsigned i = *I, j = TyIds.size();
+
+    while (i && j)
+      if (FilterIds[--i] != TyIds[--j])
+        goto try_next;
+
+    if (!j)
+      // The new filter coincides with range [i, end) of the existing filter.
+      return -(1 + i);
+
+try_next:;
+  }
+
+  // Add the new filter.
+  int FilterID = -(1 + FilterIds.size());
+  FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
+  for (unsigned I = 0, N = TyIds.size(); I != N; ++I)
+    FilterIds.push_back(TyIds[I]);
+  FilterEnds.push_back(FilterIds.size());
+  FilterIds.push_back(0); // terminator
+  return FilterID;
+}
+
+/// getPersonality - Return the personality function for the current function.
+Function *MachineModuleInfo::getPersonality() const {
+  // FIXME: Until PR1414 will be fixed, we're using 1 personality function per
+  // function
+  return !LandingPads.empty() ? LandingPads[0].Personality : NULL;
+}
+
+/// getPersonalityIndex - Return unique index for current personality
+/// function. NULL personality function should always get zero index.
+unsigned MachineModuleInfo::getPersonalityIndex() const {
+  const Function* Personality = NULL;
+  
+  // Scan landing pads. If there is at least one non-NULL personality - use it.
+  for (unsigned i = 0; i != LandingPads.size(); ++i)
+    if (LandingPads[i].Personality) {
+      Personality = LandingPads[i].Personality;
+      break;
+    }
+  
+  for (unsigned i = 0; i < Personalities.size(); ++i) {
+    if (Personalities[i] == Personality)
+      return i;
+  }
+
+  // This should never happen
+  assert(0 && "Personality function should be set!");
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+/// DebugLabelFolding pass - This pass prunes out redundant labels.  This allows
+/// a info consumer to determine if the range of two labels is empty, by seeing
+/// if the labels map to the same reduced label.
+
+namespace llvm {
+
+struct DebugLabelFolder : public MachineFunctionPass {
+  static char ID;
+  DebugLabelFolder() : MachineFunctionPass((intptr_t)&ID) {}
+
+  virtual bool runOnMachineFunction(MachineFunction &MF);
+  virtual const char *getPassName() const { return "Label Folder"; }
+};
+
+char DebugLabelFolder::ID = 0;
+
+bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) {
+  // Get machine module info.
+  MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
+  if (!MMI) return false;
+  // Get target instruction info.
+  const TargetInstrInfo *TII = MF.getTarget().getInstrInfo();
+  if (!TII) return false;
+  
+  // Track if change is made.
+  bool MadeChange = false;
+  // No prior label to begin.
+  unsigned PriorLabel = 0;
+  
+  // Iterate through basic blocks.
+  for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
+       BB != E; ++BB) {
+    // Iterate through instructions.
+    for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
+      // Is it a label.
+      if ((unsigned)I->getOpcode() == TargetInstrInfo::LABEL) {
+        // The label ID # is always operand #0, an immediate.
+        unsigned NextLabel = I->getOperand(0).getImm();
+        
+        // If there was an immediate prior label.
+        if (PriorLabel) {
+          // Remap the current label to prior label.
+          MMI->RemapLabel(NextLabel, PriorLabel);
+          // Delete the current label.
+          I = BB->erase(I);
+          // Indicate a change has been made.
+          MadeChange = true;
+          continue;
+        } else {
+          // Start a new round.
+          PriorLabel = NextLabel;
+        }
+       } else {
+        // No consecutive labels.
+        PriorLabel = 0;
+      }
+      
+      ++I;
+    }
+  }
+  
+  return MadeChange;
+}
+
+FunctionPass *createDebugLabelFoldingPass() { return new DebugLabelFolder(); }
+
+}
+
