1fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner//===-- Bitcode/Writer/ValueEnumerator.h - Number values --------*- C++ -*-===//
2fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner//
3fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner//                     The LLVM Compiler Infrastructure
4fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner//
8fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner//===----------------------------------------------------------------------===//
9fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner//
10fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner// This class gives values and types Unique ID's.
11fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner//
12fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner//===----------------------------------------------------------------------===//
13fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_LIB_BITCODE_WRITER_VALUEENUMERATOR_H
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_LIB_BITCODE_WRITER_VALUEENUMERATOR_H
16fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
17fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner#include "llvm/ADT/DenseMap.h"
186209869f83979319e2e5791382f09b83e54191e0Devang Patel#include "llvm/ADT/SmallVector.h"
19c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/ADT/UniqueVector.h"
200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Attributes.h"
2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/IR/UseListOrder.h"
22fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner#include <vector>
23fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
24fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattnernamespace llvm {
25fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
26fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattnerclass Type;
27c59c0afd7d24480f5a23d8fd6764ecfd6d4424ccChris Lattnerclass Value;
28e8e0213cc3daa2d0457c22e4c12e6973f21fc942Devang Patelclass Instruction;
29c59c0afd7d24480f5a23d8fd6764ecfd6d4424ccChris Lattnerclass BasicBlock;
30c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesclass Comdat;
31fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattnerclass Function;
32c59c0afd7d24480f5a23d8fd6764ecfd6d4424ccChris Lattnerclass Module;
33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass Metadata;
34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass LocalAsMetadata;
356209869f83979319e2e5791382f09b83e54191e0Devang Patelclass MDNode;
368fba578be72dc98497508dec053e966858571f6aDevang Patelclass NamedMDNode;
3799faa3b4ec6d03ac7808fe4ff3fbf3d04e375502Bill Wendlingclass AttributeSet;
38fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattnerclass ValueSymbolTable;
390386f01e061513094504bc11f8352a40173cada7Devang Patelclass MDSymbolTable;
404e6c03fc3de8885b9a0a0b8069123b86d4834f08Chad Rosierclass raw_ostream;
41fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
42fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattnerclass ValueEnumerator {
43fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattnerpublic:
44db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  typedef std::vector<Type*> TypeList;
45fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
46fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  // For each value, we remember its Value* and occurrence frequency.
47fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  typedef std::vector<std::pair<const Value*, unsigned> > ValueList;
4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  UseListOrderStack UseListOrders;
5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
51fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattnerprivate:
52db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  typedef DenseMap<Type*, unsigned> TypeMapType;
53fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  TypeMapType TypeMap;
542edd22b959f0d8f897cce397730a881c708e474aChris Lattner  TypeList Types;
55fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
56fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  typedef DenseMap<const Value*, unsigned> ValueMapType;
57fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  ValueMapType ValueMap;
582edd22b959f0d8f897cce397730a881c708e474aChris Lattner  ValueList Values;
59c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
60c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  typedef UniqueVector<const Comdat *> ComdatSetType;
61c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  ComdatSetType Comdats;
62c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::vector<const Metadata *> MDs;
64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SmallVector<const LocalAsMetadata *, 8> FunctionLocalMDs;
65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  typedef DenseMap<const Metadata *, unsigned> MetadataMapType;
66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MetadataMapType MDValueMap;
67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool HasMDString;
68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool HasMDLocation;
69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool HasGenericDebugNode;
702c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  bool ShouldPreserveUseListOrder;
71170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
72e9229a6a9614cbde1bff2bd6ffae3b7336db5702Bill Wendling  typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
73e9229a6a9614cbde1bff2bd6ffae3b7336db5702Bill Wendling  AttributeGroupMapType AttributeGroupMap;
74e9229a6a9614cbde1bff2bd6ffae3b7336db5702Bill Wendling  std::vector<AttributeSet> AttributeGroups;
758c2e77f895301967bf37d04e905fb1f069ec91b2Bill Wendling
76105ea3d49d4a458af8779ae7f144f00d19c4168fBill Wendling  typedef DenseMap<AttributeSet, unsigned> AttributeMapType;
770598866c052147c31b808391f58434ce3dbfb838Devang Patel  AttributeMapType AttributeMap;
78034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  std::vector<AttributeSet> Attribute;
79170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
80837e04a8bf13712a4a8ae279daab65a048b21f7dChris Lattner  /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
81837e04a8bf13712a4a8ae279daab65a048b21f7dChris Lattner  /// the "getGlobalBasicBlockID" method.
82837e04a8bf13712a4a8ae279daab65a048b21f7dChris Lattner  mutable DenseMap<const BasicBlock*, unsigned> GlobalBasicBlockIDs;
83170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
84e8e0213cc3daa2d0457c22e4c12e6973f21fc942Devang Patel  typedef DenseMap<const Instruction*, unsigned> InstructionMapType;
85e8e0213cc3daa2d0457c22e4c12e6973f21fc942Devang Patel  InstructionMapType InstructionMap;
86e8e0213cc3daa2d0457c22e4c12e6973f21fc942Devang Patel  unsigned InstructionCount;
87e8e0213cc3daa2d0457c22e4c12e6973f21fc942Devang Patel
88c59c0afd7d24480f5a23d8fd6764ecfd6d4424ccChris Lattner  /// BasicBlocks - This contains all the basic blocks for the currently
89c59c0afd7d24480f5a23d8fd6764ecfd6d4424ccChris Lattner  /// incorporated function.  Their reverse mapping is stored in ValueMap.
90c59c0afd7d24480f5a23d8fd6764ecfd6d4424ccChris Lattner  std::vector<const BasicBlock*> BasicBlocks;
91170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
928d35c79f273b74df1e95b4472620e31e81342037Chris Lattner  /// When a function is incorporated, this is the size of the Values list
938d35c79f273b74df1e95b4472620e31e81342037Chris Lattner  /// before incorporation.
94b9d0c2a6a0ef5e19b2d30180ce7d6a10ffa1f5c5Chris Lattner  unsigned NumModuleValues;
95309b3af547a60bedd74daa2a94ebd3d3ed5f06e9Dan Gohman
96309b3af547a60bedd74daa2a94ebd3d3ed5f06e9Dan Gohman  /// When a function is incorporated, this is the size of the MDValues list
97309b3af547a60bedd74daa2a94ebd3d3ed5f06e9Dan Gohman  /// before incorporation.
98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned NumModuleMDs;
99309b3af547a60bedd74daa2a94ebd3d3ed5f06e9Dan Gohman
100b9d0c2a6a0ef5e19b2d30180ce7d6a10ffa1f5c5Chris Lattner  unsigned FirstFuncConstantID;
101b9d0c2a6a0ef5e19b2d30180ce7d6a10ffa1f5c5Chris Lattner  unsigned FirstInstID;
10286a1c32e67b23c5e9e42dff9eb86e99ba15bb42fCraig Topper
103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ValueEnumerator(const ValueEnumerator &) = delete;
104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void operator=(const ValueEnumerator &) = delete;
105fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattnerpublic:
1062c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  ValueEnumerator(const Module &M, bool ShouldPreserveUseListOrder);
107fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
1084e6c03fc3de8885b9a0a0b8069123b86d4834f08Chad Rosier  void dump() const;
1094e6c03fc3de8885b9a0a0b8069123b86d4834f08Chad Rosier  void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void print(raw_ostream &OS, const MetadataMapType &Map,
111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines             const char *Name) const;
1124e6c03fc3de8885b9a0a0b8069123b86d4834f08Chad Rosier
113d5ac40457b62f37f0abfb1d61064f7c7300e91eeDevang Patel  unsigned getValueID(const Value *V) const;
114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned getMetadataID(const Metadata *MD) const {
115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    auto ID = getMetadataOrNullID(MD);
116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(ID != 0 && "Metadata not in slotcalculator!");
117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return ID - 1;
118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned getMetadataOrNullID(const Metadata *MD) const {
120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return MDValueMap.lookup(MD);
121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool hasMDString() const { return HasMDString; }
124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool hasMDLocation() const { return HasMDLocation; }
125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool hasGenericDebugNode() const { return HasGenericDebugNode; }
126d5ac40457b62f37f0abfb1d61064f7c7300e91eeDevang Patel
1272c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  bool shouldPreserveUseListOrder() const { return ShouldPreserveUseListOrder; }
1282c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
129db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  unsigned getTypeID(Type *T) const {
130fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner    TypeMapType::const_iterator I = TypeMap.find(T);
131fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner    assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
132fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner    return I->second-1;
133fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  }
134e8e0213cc3daa2d0457c22e4c12e6973f21fc942Devang Patel
135e8e0213cc3daa2d0457c22e4c12e6973f21fc942Devang Patel  unsigned getInstructionID(const Instruction *I) const;
136e8e0213cc3daa2d0457c22e4c12e6973f21fc942Devang Patel  void setInstructionID(const Instruction *I);
137e8e0213cc3daa2d0457c22e4c12e6973f21fc942Devang Patel
138e9229a6a9614cbde1bff2bd6ffae3b7336db5702Bill Wendling  unsigned getAttributeID(AttributeSet PAL) const {
13958d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner    if (PAL.isEmpty()) return 0;  // Null maps to zero.
140105ea3d49d4a458af8779ae7f144f00d19c4168fBill Wendling    AttributeMapType::const_iterator I = AttributeMap.find(PAL);
1410598866c052147c31b808391f58434ce3dbfb838Devang Patel    assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!");
14250954f5cba406a88011cc8ade3ceb4235830f907Chris Lattner    return I->second;
14350954f5cba406a88011cc8ade3ceb4235830f907Chris Lattner  }
144fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
145e9229a6a9614cbde1bff2bd6ffae3b7336db5702Bill Wendling  unsigned getAttributeGroupID(AttributeSet PAL) const {
1468c2e77f895301967bf37d04e905fb1f069ec91b2Bill Wendling    if (PAL.isEmpty()) return 0;  // Null maps to zero.
147e9229a6a9614cbde1bff2bd6ffae3b7336db5702Bill Wendling    AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL);
148e9229a6a9614cbde1bff2bd6ffae3b7336db5702Bill Wendling    assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
1498c2e77f895301967bf37d04e905fb1f069ec91b2Bill Wendling    return I->second;
1508c2e77f895301967bf37d04e905fb1f069ec91b2Bill Wendling  }
1518c2e77f895301967bf37d04e905fb1f069ec91b2Bill Wendling
152b9d0c2a6a0ef5e19b2d30180ce7d6a10ffa1f5c5Chris Lattner  /// getFunctionConstantRange - Return the range of values that corresponds to
153b9d0c2a6a0ef5e19b2d30180ce7d6a10ffa1f5c5Chris Lattner  /// function-local constants.
154b9d0c2a6a0ef5e19b2d30180ce7d6a10ffa1f5c5Chris Lattner  void getFunctionConstantRange(unsigned &Start, unsigned &End) const {
155b9d0c2a6a0ef5e19b2d30180ce7d6a10ffa1f5c5Chris Lattner    Start = FirstFuncConstantID;
156b9d0c2a6a0ef5e19b2d30180ce7d6a10ffa1f5c5Chris Lattner    End = FirstInstID;
157b9d0c2a6a0ef5e19b2d30180ce7d6a10ffa1f5c5Chris Lattner  }
158170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
1592edd22b959f0d8f897cce397730a881c708e474aChris Lattner  const ValueList &getValues() const { return Values; }
160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const std::vector<const Metadata *> &getMDs() const { return MDs; }
161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const SmallVectorImpl<const LocalAsMetadata *> &getFunctionLocalMDs() const {
1626209869f83979319e2e5791382f09b83e54191e0Devang Patel    return FunctionLocalMDs;
1636209869f83979319e2e5791382f09b83e54191e0Devang Patel  }
164fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  const TypeList &getTypes() const { return Types; }
165c59c0afd7d24480f5a23d8fd6764ecfd6d4424ccChris Lattner  const std::vector<const BasicBlock*> &getBasicBlocks() const {
166170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey    return BasicBlocks;
167c59c0afd7d24480f5a23d8fd6764ecfd6d4424ccChris Lattner  }
16899faa3b4ec6d03ac7808fe4ff3fbf3d04e375502Bill Wendling  const std::vector<AttributeSet> &getAttributes() const {
169034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    return Attribute;
17050954f5cba406a88011cc8ade3ceb4235830f907Chris Lattner  }
171e9229a6a9614cbde1bff2bd6ffae3b7336db5702Bill Wendling  const std::vector<AttributeSet> &getAttributeGroups() const {
172e9229a6a9614cbde1bff2bd6ffae3b7336db5702Bill Wendling    return AttributeGroups;
1738c2e77f895301967bf37d04e905fb1f069ec91b2Bill Wendling  }
174170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  const ComdatSetType &getComdats() const { return Comdats; }
176c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  unsigned getComdatID(const Comdat *C) const;
177c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
178837e04a8bf13712a4a8ae279daab65a048b21f7dChris Lattner  /// getGlobalBasicBlockID - This returns the function-specific ID for the
179837e04a8bf13712a4a8ae279daab65a048b21f7dChris Lattner  /// specified basic block.  This is relatively expensive information, so it
180837e04a8bf13712a4a8ae279daab65a048b21f7dChris Lattner  /// should only be used by rare constructs such as address-of-label.
181837e04a8bf13712a4a8ae279daab65a048b21f7dChris Lattner  unsigned getGlobalBasicBlockID(const BasicBlock *BB) const;
182fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
1836a0c04dff288b7eaa0459cc7419159765bb5a0b9Chad Rosier  /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
184fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  /// use these two methods to get its data into the ValueEnumerator!
185fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  ///
1866a0c04dff288b7eaa0459cc7419159765bb5a0b9Chad Rosier  void incorporateFunction(const Function &F);
1876a0c04dff288b7eaa0459cc7419159765bb5a0b9Chad Rosier  void purgeFunction();
188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint64_t computeBitsRequiredForTypeIndicies() const;
189fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
190fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattnerprivate:
1916da91d3c2c138eb1d9739701a1314ba3580df897Chris Lattner  void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
192170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
193309b3af547a60bedd74daa2a94ebd3d3ed5f06e9Dan Gohman  void EnumerateMDNodeOperands(const MDNode *N);
194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void EnumerateMetadata(const Metadata *MD);
195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void EnumerateFunctionLocalMetadata(const LocalAsMetadata *Local);
1968fba578be72dc98497508dec053e966858571f6aDevang Patel  void EnumerateNamedMDNode(const NamedMDNode *NMD);
197d7e6457c3faf6c5530a4c8224e2dfcf91b57093bVictor Hernandez  void EnumerateValue(const Value *V);
198db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  void EnumerateType(Type *T);
199d7e6457c3faf6c5530a4c8224e2dfcf91b57093bVictor Hernandez  void EnumerateOperandType(const Value *V);
200105ea3d49d4a458af8779ae7f144f00d19c4168fBill Wendling  void EnumerateAttributes(AttributeSet PAL);
201170a15e98dc6900df1ae40d03c5f0622d792fb45Joe Abbey
202fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner  void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void EnumerateNamedMetadata(const Module &M);
204fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner};
205fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
206fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner} // End llvm namespace
207fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner
208fd57cecd2cb3ac726942e0101de6a82dc5a958a6Chris Lattner#endif
209