1803a5f6ecb1823280f80e3c4459aa58627d0484cChris Lattner//===- CodeGenTarget.h - Target Class Wrapper -------------------*- C++ -*-===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
301d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//                     The LLVM Compiler Infrastructure
401d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//
53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source
63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details.
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
801d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//===----------------------------------------------------------------------===//
945872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner//
10803a5f6ecb1823280f80e3c4459aa58627d0484cChris Lattner// This file defines wrappers for the Target class and related global
11803a5f6ecb1823280f80e3c4459aa58627d0484cChris Lattner// functionality.  This makes it easier to access the data and provides a single
1261131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger// place that needs to check it for validity.  All of these classes abort
1361131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger// on error conditions.
1445872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner//
1545872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner//===----------------------------------------------------------------------===//
1645872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_UTILS_TABLEGEN_CODEGENTARGET_H
1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_UTILS_TABLEGEN_CODEGENTARGET_H
1945872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
20ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner#include "CodeGenInstruction.h"
214ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "CodeGenRegisters.h"
22e14d2e210dc7fe28009f44818a057622a73322e4Chris Lattner#include "llvm/Support/raw_ostream.h"
234ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/TableGen/Record.h"
248a17870da491b9598418fce180857515208b7393Dan Gohman#include <algorithm>
25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
26d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
27d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
281fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattnerstruct CodeGenRegister;
292661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trickclass CodeGenSchedModels;
308850a1bcef0c2a785f918395fe0a05054914b349Chris Lattnerclass CodeGenTarget;
3145872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
3294b3040fef9475c74b877fb32cb45200cea273bbEvan Cheng// SelectionDAG node properties.
3328873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang//  SDNPMemOperand: indicates that a node touches memory and therefore must
3428873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang//                  have an associated memory operand that describes the access.
35c8478d8b12c2d7e4cea32d0c9940f5cac2baa4ddChris Lattnerenum SDNP {
36510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach  SDNPCommutative,
37510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach  SDNPAssociative,
38c8478d8b12c2d7e4cea32d0c9940f5cac2baa4ddChris Lattner  SDNPHasChain,
39036609bd7d42ed1f57865969e059eb7d1eb6c392Chris Lattner  SDNPOutGlue,
40036609bd7d42ed1f57865969e059eb7d1eb6c392Chris Lattner  SDNPInGlue,
41036609bd7d42ed1f57865969e059eb7d1eb6c392Chris Lattner  SDNPOptInGlue,
42710e995889c71812743f3f33861c24273f4569a7Chris Lattner  SDNPMayLoad,
43bc0b9f70ae072d695e0eb7ceb729b3306b0679feChris Lattner  SDNPMayStore,
4428873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang  SDNPSideEffect,
45e8cabf3c2eb835f9189a39c810654d9bd302f7eeChris Lattner  SDNPMemOperand,
4652a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner  SDNPVariadic,
4752a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner  SDNPWantRoot,
4852a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner  SDNPWantParent
49c8478d8b12c2d7e4cea32d0c9940f5cac2baa4ddChris Lattner};
5094b3040fef9475c74b877fb32cb45200cea273bbEvan Cheng
51825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson/// getValueType - Return the MVT::SimpleValueType that the specified TableGen
5283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands/// record corresponds to.
53825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen AndersonMVT::SimpleValueType getValueType(Record *Rec);
5445872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
55de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarStringRef getName(MVT::SimpleValueType T);
56de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarStringRef getEnumName(MVT::SimpleValueType T);
5745872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
586cefb77a7073057fecd721ae141140d75ce76512Chris Lattner/// getQualifiedName - Return the name of the specified record, with a
596cefb77a7073057fecd721ae141140d75ce76512Chris Lattner/// namespace qualifier if the record contains one.
606cefb77a7073057fecd721ae141140d75ce76512Chris Lattnerstd::string getQualifiedName(const Record *R);
61510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach
6245872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner/// CodeGenTarget - This class corresponds to the Target class in the .td files.
6345872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner///
6445872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattnerclass CodeGenTarget {
6567db883487fca3472fdde51e931657e22d4d0495Chris Lattner  RecordKeeper &Records;
6645872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner  Record *TargetRec;
6745872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  mutable DenseMap<const Record*,
69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   std::unique_ptr<CodeGenInstruction>> Instructions;
70ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  mutable std::unique_ptr<CodeGenRegBank> RegBank;
71bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson  mutable std::vector<Record*> RegAltNameIndices;
7226369a930c523b75fe8f4ba18456ff86f68d5612Jakob Stoklund Olesen  mutable SmallVector<MVT::SimpleValueType, 8> LegalValueTypes;
73bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson  void ReadRegAltNameIndices() const;
74056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner  void ReadInstructions() const;
75e9f4ba8dd47de9da2a98db3bbe25b54d5a9607f1Chris Lattner  void ReadLegalValueTypes() const;
76510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach
77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  mutable std::unique_ptr<CodeGenSchedModels> SchedModels;
782661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick
796a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner  mutable std::vector<const CodeGenInstruction*> InstrsByEnum;
8045872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattnerpublic:
8167db883487fca3472fdde51e931657e22d4d0495Chris Lattner  CodeGenTarget(RecordKeeper &Records);
822661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  ~CodeGenTarget();
8345872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
8445872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner  Record *getTargetRecord() const { return TargetRec; }
8545872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner  const std::string &getName() const;
8645872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
871e0ee4bc38e9cdc7e7ac49968527e2c05f927904Dan Gohman  /// getInstNamespace - Return the target-specific instruction namespace.
881e0ee4bc38e9cdc7e7ac49968527e2c05f927904Dan Gohman  ///
891e0ee4bc38e9cdc7e7ac49968527e2c05f927904Dan Gohman  std::string getInstNamespace() const;
901e0ee4bc38e9cdc7e7ac49968527e2c05f927904Dan Gohman
91175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner  /// getInstructionSet - Return the InstructionSet object.
92ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner  ///
9345872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner  Record *getInstructionSet() const;
9445872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
950e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  /// getAsmParser - Return the AssemblyParser definition for this target.
960e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  ///
970e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  Record *getAsmParser() const;
980e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
990dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  /// getAsmParserVariant - Return the AssmblyParserVariant definition for
1000dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  /// this target.
1010dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  ///
1020dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  Record *getAsmParserVariant(unsigned i) const;
1030dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel
1042661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  /// getAsmParserVariantCount - Return the AssmblyParserVariant definition
1050dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  /// available for this target.
1060dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  ///
1070dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel  unsigned getAsmParserVariantCount() const;
1080dbcadaa2fdf7038431931bab090f4467d8e308fDevang Patel
109175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner  /// getAsmWriter - Return the AssemblyWriter definition for this target.
110175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner  ///
111175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner  Record *getAsmWriter() const;
112175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner
113dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  /// getRegBank - Return the register bank description.
114dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  CodeGenRegBank &getRegBank() const;
115dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
116ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner  /// getRegisterByName - If there is a register with the specific AsmName,
117ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner  /// return it.
118ec6f096c36f4144ff9b3b24c2939720cdcbb7bccChris Lattner  const CodeGenRegister *getRegisterByName(StringRef Name) const;
119ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner
120bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson  const std::vector<Record*> &getRegAltNameIndices() const {
121bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    if (RegAltNameIndices.empty()) ReadRegAltNameIndices();
122bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson    return RegAltNameIndices;
123bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson  }
124bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson
125ddb395463c08b39090bbee4ed22433f5990a6331Nate Begeman  const CodeGenRegisterClass &getRegisterClass(Record *R) const {
1267b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    return *getRegBank().getRegClass(R);
1275c4736a3da04795ba8d04e152e151afd6942e2f1Chris Lattner  }
12844a65fa552ed61cf9dba8f68f59b05e5137e6b01Evan Cheng
12983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  /// getRegisterVTs - Find the union of all possible SimpleValueTypes for the
13044a65fa552ed61cf9dba8f68f59b05e5137e6b01Evan Cheng  /// specified physical register.
1312cacec55f947c716b058a39038889550d7e39b3cChris Lattner  std::vector<MVT::SimpleValueType> getRegisterVTs(Record *R) const;
132510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach
13326369a930c523b75fe8f4ba18456ff86f68d5612Jakob Stoklund Olesen  ArrayRef<MVT::SimpleValueType> getLegalValueTypes() const {
134e9f4ba8dd47de9da2a98db3bbe25b54d5a9607f1Chris Lattner    if (LegalValueTypes.empty()) ReadLegalValueTypes();
135e9f4ba8dd47de9da2a98db3bbe25b54d5a9607f1Chris Lattner    return LegalValueTypes;
136e9f4ba8dd47de9da2a98db3bbe25b54d5a9607f1Chris Lattner  }
137510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach
138e9f4ba8dd47de9da2a98db3bbe25b54d5a9607f1Chris Lattner  /// isLegalValueType - Return true if the specified value type is natively
139e9f4ba8dd47de9da2a98db3bbe25b54d5a9607f1Chris Lattner  /// supported by the target (i.e. there are registers that directly hold it).
140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  bool isLegalValueType(MVT::SimpleValueType VT) const {
14126369a930c523b75fe8f4ba18456ff86f68d5612Jakob Stoklund Olesen    ArrayRef<MVT::SimpleValueType> LegalVTs = getLegalValueTypes();
142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return std::find(LegalVTs.begin(), LegalVTs.end(), VT) != LegalVTs.end();
143e9f4ba8dd47de9da2a98db3bbe25b54d5a9607f1Chris Lattner  }
144056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner
1452661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick  CodeGenSchedModels &getSchedModels() const;
1462661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick
147b61e09de6d0cd7241ddc6dee3efef416552eec3bChris Lattnerprivate:
148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DenseMap<const Record*, std::unique_ptr<CodeGenInstruction>> &
149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  getInstructions() const {
150ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner    if (Instructions.empty()) ReadInstructions();
151ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner    return Instructions;
152ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner  }
153f30187a36324fb75042d9ffd20c3fb70aff7763dChris Lattnerpublic:
154510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach
155e14d2e210dc7fe28009f44818a057622a73322e4Chris Lattner  CodeGenInstruction &getInstruction(const Record *InstRec) const {
156e14d2e210dc7fe28009f44818a057622a73322e4Chris Lattner    if (Instructions.empty()) ReadInstructions();
157ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    auto I = Instructions.find(InstRec);
158e14d2e210dc7fe28009f44818a057622a73322e4Chris Lattner    assert(I != Instructions.end() && "Not an instruction");
159e14d2e210dc7fe28009f44818a057622a73322e4Chris Lattner    return *I->second;
160e14d2e210dc7fe28009f44818a057622a73322e4Chris Lattner  }
161a974b20cae7691361f2be5b27fbc1658855ed96cChris Lattner
162d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner  /// getInstructionsByEnumValue - Return all of the instructions defined by the
163d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner  /// target, ordered by their enum value.
164de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ArrayRef<const CodeGenInstruction *>
1656a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner  getInstructionsByEnumValue() const {
166f65027842e82027dd6e8020586a299aaa548e355Chris Lattner    if (InstrsByEnum.empty()) ComputeInstrsByEnum();
167f65027842e82027dd6e8020586a299aaa548e355Chris Lattner    return InstrsByEnum;
168f65027842e82027dd6e8020586a299aaa548e355Chris Lattner  }
169d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner
170de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  typedef ArrayRef<const CodeGenInstruction *>::const_iterator inst_iterator;
1716a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner  inst_iterator inst_begin() const{return getInstructionsByEnumValue().begin();}
1726a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner  inst_iterator inst_end() const { return getInstructionsByEnumValue().end(); }
173510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach
174510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach
17535e83cc970e2ed99c8087e0c6b99f8a3618c279bMisha Brukman  /// isLittleEndianEncoding - are instruction bit patterns defined as  [0..n]?
17635e83cc970e2ed99c8087e0c6b99f8a3618c279bMisha Brukman  ///
17735e83cc970e2ed99c8087e0c6b99f8a3618c279bMisha Brukman  bool isLittleEndianEncoding() const;
178510207cb1e7427df711ac85002cab622f67bdf7cJim Grosbach
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// encodings, reverse the bit order of all instructions.
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void reverseBitsForLittleEndianEncoding();
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
183f104bf65b9d748618d23caa37b2407fe9c2b174cJakob Stoklund Olesen  /// guessInstructionProperties - should we just guess unset instruction
184f104bf65b9d748618d23caa37b2407fe9c2b174cJakob Stoklund Olesen  /// properties?
185f104bf65b9d748618d23caa37b2407fe9c2b174cJakob Stoklund Olesen  bool guessInstructionProperties() const;
186f104bf65b9d748618d23caa37b2407fe9c2b174cJakob Stoklund Olesen
187f65027842e82027dd6e8020586a299aaa548e355Chris Lattnerprivate:
1886a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner  void ComputeInstrsByEnum() const;
18945872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner};
19045872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner
1910fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng/// ComplexPattern - ComplexPattern info, corresponding to the ComplexPattern
1920fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng/// tablegen class in TargetSelectionDAG.td
1930fc71988900e600f3ef5b13d9682e2bbab92811dEvan Chengclass ComplexPattern {
194825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  MVT::SimpleValueType Ty;
1950fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng  unsigned NumOperands;
1960fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng  std::string SelectFunc;
1973aa39f439a0971a2502b2c728a8006becaf96601Evan Cheng  std::vector<Record*> RootNodes;
1988535624739e55ab7424eadf792e1a3b4123421c7Christopher Lamb  unsigned Properties; // Node properties
1990fc71988900e600f3ef5b13d9682e2bbab92811dEvan Chengpublic:
200c128b3e74eaba34a8f6d2b8c3dc19861b9cbd901Chris Lattner  ComplexPattern() : NumOperands(0) {}
2010fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng  ComplexPattern(Record *R);
2020fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng
203825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  MVT::SimpleValueType getValueType() const { return Ty; }
2040fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng  unsigned getNumOperands() const { return NumOperands; }
2050fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng  const std::string &getSelectFunc() const { return SelectFunc; }
2063aa39f439a0971a2502b2c728a8006becaf96601Evan Cheng  const std::vector<Record*> &getRootNodes() const {
2073aa39f439a0971a2502b2c728a8006becaf96601Evan Cheng    return RootNodes;
2080fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng  }
20994b3040fef9475c74b877fb32cb45200cea273bbEvan Cheng  bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
2100fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng};
2110fc71988900e600f3ef5b13d9682e2bbab92811dEvan Cheng
212d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
213d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
21445872079672a4fb500fdcb9c77b23e3e550c8f97Chris Lattner#endif
215